Merge branches 'clk-renesas', 'clk-cleanup' and 'clk-determine-divider' into clk...
authorStephen Boyd <sboyd@kernel.org>
Wed, 1 Sep 2021 22:25:15 +0000 (15:25 -0700)
committerStephen Boyd <sboyd@kernel.org>
Wed, 1 Sep 2021 22:25:15 +0000 (15:25 -0700)
 - Migrate some clk drivers to clk_divider_ops.determine_rate

* clk-renesas:
  clk: renesas: Make CLK_R9A06G032 invisible
  clk: renesas: r9a07g044: Add entry for fixed clock P0_DIV2
  dt-bindings: clock: r9a07g044-cpg: Add entry for P0_DIV2 core clock
  clk: renesas: r9a07g044: Add clock and reset entries for ADC
  clk: renesas: r9a07g044: Add clock and reset entries for CANFD
  clk: renesas: Rename renesas-rzg2l-cpg.[ch] to rzg2l-cpg.[ch]
  clk: renesas: r9a07g044: Add GPIO clock and reset entries
  clk: renesas: r9a07g044: Add SSIF-2 clock and reset entries
  clk: renesas: r9a07g044: Add USB clocks/resets
  clk: renesas: r9a07g044: Add DMAC clocks/resets
  clk: renesas: r9a07g044: Add I2C clocks/resets
  clk: renesas: r8a779a0: Add the DSI clocks
  clk: renesas: r8a779a0: Add the DU clock
  clk: renesas: rzg2: Rename i2c-dvfs to iic-pmic
  clk: renesas: rzg2l: Fix off-by-one check in rzg2l_cpg_clk_src_twocell_get()
  clk: renesas: rzg2l: Avoid mixing error pointers and NULL
  clk: renesas: rzg2l: Fix a double free on error
  clk: renesas: rzg2l: Fix return value and unused assignment
  clk: renesas: rzg2l: Remove unneeded semicolon

* clk-cleanup:
  clk: palmas: Add a missing SPDX license header
  clk: Align provider-specific CLK_* bit definitions

* clk-determine-divider:
  clk: stm32mp1: Switch to clk_divider.determine_rate
  clk: stm32h7: Switch to clk_divider.determine_rate
  clk: stm32f4: Switch to clk_divider.determine_rate
  clk: bcm2835: Switch to clk_divider.determine_rate
  clk: divider: Implement and wire up .determine_rate by default

566 files changed:
Documentation/ABI/testing/sysfs-ptp
Documentation/dev-tools/kunit/running_tips.rst
Documentation/devicetree/bindings/arm/mediatek/mediatek,audsys.txt
Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.txt
Documentation/devicetree/bindings/arm/mediatek/mediatek,mt8192-clock.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/arm/mediatek/mediatek,mt8192-sys-clock.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/clock/brcm,iproc-clocks.yaml
Documentation/devicetree/bindings/clock/qcom,a53pll.yaml
Documentation/devicetree/bindings/clock/qcom,gcc-sm6115.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/clock/qcom,gcc-sm6350.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/clock/qcom,gcc.yaml
Documentation/devicetree/bindings/clock/qcom,gpucc.yaml
Documentation/devicetree/bindings/clock/qcom,mmcc.yaml
Documentation/devicetree/bindings/clock/qcom,rpmcc.txt
Documentation/devicetree/bindings/clock/qcom,rpmhcc.yaml
Documentation/devicetree/bindings/clock/qcom,sc7280-dispcc.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/clock/qcom,videocc.yaml
Documentation/devicetree/bindings/display/renesas,du.yaml
Documentation/devicetree/bindings/hwmon/adt7475.yaml
Documentation/devicetree/bindings/iommu/arm,smmu.yaml
Documentation/devicetree/bindings/iommu/rockchip,iommu.yaml
Documentation/devicetree/bindings/memory-controllers/arm,pl353-smc.yaml
Documentation/devicetree/bindings/mtd/brcm,brcmnand.yaml
Documentation/devicetree/bindings/net/dsa/nxp,sja1105.yaml
Documentation/devicetree/bindings/net/gpmc-eth.txt
Documentation/devicetree/bindings/net/smsc,lan9115.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/net/smsc911x.txt [deleted file]
Documentation/devicetree/bindings/phy/ti,phy-j721e-wiz.yaml
Documentation/devicetree/bindings/regulator/mps,mpq7920.yaml
Documentation/devicetree/bindings/regulator/nxp,pf8x00-regulator.yaml
Documentation/devicetree/bindings/rtc/faraday,ftrtc010.yaml
Documentation/devicetree/bindings/spi/spi-controller.yaml
Documentation/devicetree/bindings/usb/nxp,isp1760.yaml
Documentation/driver-api/early-userspace/early_userspace_support.rst
Documentation/features/core/thread-info-in-task/arch-support.txt [new file with mode: 0644]
Documentation/features/time/arch-tick-broadcast/arch-support.txt
Documentation/filesystems/ramfs-rootfs-initramfs.rst
Documentation/networking/ethtool-netlink.rst
Documentation/networking/nf_conntrack-sysctl.rst
Documentation/networking/tipc.rst
Documentation/translations/zh_CN/process/2.Process.rst
LICENSES/dual/CC-BY-4.0
MAINTAINERS
Makefile
arch/arm/Kconfig
arch/arm/boot/dts/aspeed-bmc-asrock-e3c246d4i.dts
arch/arm/boot/dts/aspeed-bmc-ibm-everest.dts
arch/arm/boot/dts/aspeed-bmc-ibm-rainier.dts
arch/arm/boot/dts/aspeed-bmc-opp-tacoma.dts
arch/arm/boot/dts/qcom-apq8060-dragonboard.dts
arch/arm/boot/dts/versatile-ab.dts
arch/arm/boot/dts/versatile-pb.dts
arch/arm/configs/integrator_defconfig
arch/arm/configs/multi_v7_defconfig
arch/arm/configs/realview_defconfig
arch/arm/configs/shmobile_defconfig
arch/arm/configs/u8500_defconfig
arch/arm/configs/versatile_defconfig
arch/arm/configs/vexpress_defconfig
arch/arm64/Kconfig
arch/arm64/boot/dts/nvidia/tegra194.dtsi
arch/arm64/boot/dts/renesas/r9a07g044.dtsi
arch/arm64/include/asm/cache.h
arch/arm64/include/asm/smp_plat.h
arch/arm64/kernel/Makefile
arch/arm64/kernel/cpufeature.c
arch/arm64/kernel/entry-common.c
arch/arm64/kernel/mte.c
arch/arm64/lib/copy_from_user.S
arch/arm64/lib/copy_in_user.S
arch/arm64/lib/copy_to_user.S
arch/arm64/lib/strlen.S
arch/mips/include/asm/fpu.h
arch/mips/mm/tlbex.c
arch/powerpc/platforms/powermac/smp.c
arch/s390/kernel/uprobes.c
arch/x86/kvm/cpuid.c
arch/x86/kvm/mmu/mmu.c
arch/x86/kvm/mmu/paging.h [new file with mode: 0644]
arch/x86/kvm/mmu/paging_tmpl.h
arch/x86/kvm/mmu/spte.h
arch/x86/kvm/svm/nested.c
arch/x86/kvm/svm/sev.c
arch/x86/kvm/svm/svm.c
arch/x86/kvm/svm/svm.h
arch/x86/kvm/vmx/vmx.h
arch/x86/kvm/x86.c
arch/x86/net/bpf_jit_comp.c
drivers/acpi/acpi_lpss.c
drivers/base/power/clock_ops.c
drivers/base/power/runtime.c
drivers/block/nbd.c
drivers/block/paride/pd.c
drivers/block/xen-blkfront.c
drivers/char/powernv-op-panel.c
drivers/clk/clk-lmk04832.c
drivers/clk/clk-palmas.c
drivers/clk/mediatek/Kconfig
drivers/clk/mediatek/Makefile
drivers/clk/mediatek/clk-cpumux.c
drivers/clk/mediatek/clk-mt8192-aud.c [new file with mode: 0644]
drivers/clk/mediatek/clk-mt8192-cam.c [new file with mode: 0644]
drivers/clk/mediatek/clk-mt8192-img.c [new file with mode: 0644]
drivers/clk/mediatek/clk-mt8192-imp_iic_wrap.c [new file with mode: 0644]
drivers/clk/mediatek/clk-mt8192-ipe.c [new file with mode: 0644]
drivers/clk/mediatek/clk-mt8192-mdp.c [new file with mode: 0644]
drivers/clk/mediatek/clk-mt8192-mfg.c [new file with mode: 0644]
drivers/clk/mediatek/clk-mt8192-mm.c [new file with mode: 0644]
drivers/clk/mediatek/clk-mt8192-msdc.c [new file with mode: 0644]
drivers/clk/mediatek/clk-mt8192-scp_adsp.c [new file with mode: 0644]
drivers/clk/mediatek/clk-mt8192-vdec.c [new file with mode: 0644]
drivers/clk/mediatek/clk-mt8192-venc.c [new file with mode: 0644]
drivers/clk/mediatek/clk-mt8192.c [new file with mode: 0644]
drivers/clk/mediatek/clk-mtk.c
drivers/clk/mediatek/clk-mtk.h
drivers/clk/mediatek/clk-mux.c
drivers/clk/mediatek/clk-mux.h
drivers/clk/mediatek/clk-pll.c
drivers/clk/mediatek/reset.c
drivers/clk/qcom/Kconfig
drivers/clk/qcom/Makefile
drivers/clk/qcom/a53-pll.c
drivers/clk/qcom/apcs-msm8916.c
drivers/clk/qcom/camcc-sc7180.c
drivers/clk/qcom/clk-rpmh.c
drivers/clk/qcom/clk-smd-rpm.c
drivers/clk/qcom/dispcc-sc7280.c [new file with mode: 0644]
drivers/clk/qcom/dispcc-sm8250.c
drivers/clk/qcom/gcc-msm8953.c [new file with mode: 0644]
drivers/clk/qcom/gcc-sdm660.c
drivers/clk/qcom/gcc-sm6115.c [new file with mode: 0644]
drivers/clk/qcom/gcc-sm6350.c [new file with mode: 0644]
drivers/clk/qcom/gpucc-sc7280.c [new file with mode: 0644]
drivers/clk/qcom/gpucc-sm8150.c
drivers/clk/qcom/lpass-gfm-sm8250.c
drivers/clk/qcom/lpasscorecc-sc7180.c
drivers/clk/qcom/mmcc-msm8994.c [new file with mode: 0644]
drivers/clk/qcom/mss-sc7180.c
drivers/clk/qcom/q6sstop-qcs404.c
drivers/clk/qcom/turingcc-qcs404.c
drivers/clk/qcom/videocc-sc7280.c [new file with mode: 0644]
drivers/clk/renesas/Kconfig
drivers/clk/renesas/Makefile
drivers/clk/renesas/r8a774a1-cpg-mssr.c
drivers/clk/renesas/r8a774b1-cpg-mssr.c
drivers/clk/renesas/r8a774c0-cpg-mssr.c
drivers/clk/renesas/r8a774e1-cpg-mssr.c
drivers/clk/renesas/r8a779a0-cpg-mssr.c
drivers/clk/renesas/r9a07g044-cpg.c
drivers/clk/renesas/renesas-rzg2l-cpg.c [deleted file]
drivers/clk/renesas/renesas-rzg2l-cpg.h [deleted file]
drivers/clk/renesas/rzg2l-cpg.c [new file with mode: 0644]
drivers/clk/renesas/rzg2l-cpg.h [new file with mode: 0644]
drivers/clk/socfpga/clk-agilex.c
drivers/clk/x86/Makefile
drivers/clk/x86/clk-lpss-atom.c [new file with mode: 0644]
drivers/clk/x86/clk-lpt.c [deleted file]
drivers/cpufreq/longhaul.c
drivers/dma-buf/sync_file.c
drivers/dma/ipu/ipu_idmac.c
drivers/dma/mpc512x_dma.c
drivers/dma/ti/k3-udma.c
drivers/edac/Kconfig
drivers/firmware/arm_ffa/bus.c
drivers/firmware/arm_ffa/driver.c
drivers/firmware/arm_scmi/bus.c
drivers/firmware/arm_scmi/driver.c
drivers/firmware/arm_scmi/notify.c
drivers/firmware/arm_scmi/sensors.c
drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h
drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c
drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c
drivers/gpu/drm/amd/amdgpu/amdgpu_ras.h
drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
drivers/gpu/drm/amd/amdgpu/dce_virtual.c
drivers/gpu/drm/amd/amdgpu/mxgpu_ai.c
drivers/gpu/drm/amd/amdgpu/mxgpu_nv.c
drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
drivers/gpu/drm/amd/amdkfd/kfd_process.c
drivers/gpu/drm/amd/amdkfd/kfd_svm.c
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
drivers/gpu/drm/amd/display/dc/clk_mgr/dcn31/dcn31_smu.c
drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hwseq.c
drivers/gpu/drm/amd/include/asic_reg/mp/mp_13_0_1_offset.h [deleted file]
drivers/gpu/drm/amd/include/asic_reg/mp/mp_13_0_1_sh_mask.h [deleted file]
drivers/gpu/drm/amd/pm/inc/smu_v13_0.h
drivers/gpu/drm/amd/pm/inc/smu_v13_0_1.h [deleted file]
drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c
drivers/gpu/drm/amd/pm/swsmu/smu13/Makefile
drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c
drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_1.c [deleted file]
drivers/gpu/drm/amd/pm/swsmu/smu13/yellow_carp_ppt.c
drivers/gpu/drm/i915/gem/i915_gem_shrinker.c
drivers/gpu/drm/i915/gt/gen8_ppgtt.c
drivers/gpu/drm/i915/gt/intel_ggtt_fencing.c
drivers/gpu/drm/msm/msm_gem.c
drivers/gpu/drm/panel/panel-novatek-nt35510.c
drivers/gpu/drm/qxl/qxl_ttm.c
drivers/gpu/drm/ttm/ttm_range_manager.c
drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
drivers/gpu/drm/vmwgfx/vmwgfx_mob.c
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
drivers/iommu/arm/arm-smmu/qcom_iommu.c
drivers/iommu/intel/iommu.c
drivers/iommu/rockchip-iommu.c
drivers/mmc/host/jz4740_mmc.c
drivers/mtd/chips/cfi_util.c
drivers/net/bonding/bond_main.c
drivers/net/caif/Kconfig
drivers/net/caif/Makefile
drivers/net/caif/caif_hsi.c [deleted file]
drivers/net/dsa/microchip/ksz_common.c
drivers/net/dsa/mv88e6xxx/chip.c
drivers/net/dsa/mv88e6xxx/serdes.c
drivers/net/dsa/sja1105/sja1105_main.c
drivers/net/ethernet/atheros/atl1c/atl1c_hw.c
drivers/net/ethernet/broadcom/genet/bcmgenet.c
drivers/net/ethernet/broadcom/genet/bcmgenet_wol.c
drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.c
drivers/net/ethernet/google/gve/gve_main.c
drivers/net/ethernet/google/gve/gve_rx_dqo.c
drivers/net/ethernet/ibm/ibmvnic.c
drivers/net/ethernet/intel/e1000e/netdev.c
drivers/net/ethernet/intel/fm10k/fm10k_pci.c
drivers/net/ethernet/intel/iavf/iavf_main.c
drivers/net/ethernet/intel/igb/igb_main.c
drivers/net/ethernet/intel/igc/igc.h
drivers/net/ethernet/intel/igc/igc_main.c
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
drivers/net/ethernet/intel/ixgbevf/ipsec.c
drivers/net/ethernet/marvell/mvneta.c
drivers/net/ethernet/marvell/octeontx2/af/cgx.c
drivers/net/ethernet/marvell/octeontx2/af/cgx.h
drivers/net/ethernet/marvell/octeontx2/af/lmac_common.h
drivers/net/ethernet/marvell/octeontx2/af/mbox.h
drivers/net/ethernet/marvell/octeontx2/af/rvu.c
drivers/net/ethernet/marvell/octeontx2/af/rvu.h
drivers/net/ethernet/marvell/octeontx2/af/rvu_cgx.c
drivers/net/ethernet/marvell/octeontx2/af/rvu_cn10k.c
drivers/net/ethernet/marvell/octeontx2/af/rvu_debugfs.c
drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c
drivers/net/ethernet/marvell/octeontx2/af/rvu_reg.h
drivers/net/ethernet/marvell/octeontx2/af/rvu_struct.h
drivers/net/ethernet/marvell/octeontx2/nic/Makefile
drivers/net/ethernet/marvell/octeontx2/nic/cn10k.c
drivers/net/ethernet/marvell/octeontx2/nic/cn10k.h
drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c
drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h
drivers/net/ethernet/marvell/octeontx2/nic/otx2_dmac_flt.c [new file with mode: 0644]
drivers/net/ethernet/marvell/octeontx2/nic/otx2_flows.c
drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c
drivers/net/ethernet/marvell/octeontx2/nic/otx2_tc.c
drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.h
drivers/net/ethernet/marvell/octeontx2/nic/otx2_vf.c
drivers/net/ethernet/microchip/sparx5/Kconfig
drivers/net/ethernet/moxa/moxart_ether.c
drivers/net/ethernet/mscc/ocelot_net.c
drivers/net/ethernet/netronome/nfp/flower/conntrack.c
drivers/net/ethernet/qualcomm/emac/emac.c
drivers/net/ethernet/sfc/efx_channels.c
drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c
drivers/net/ethernet/stmicro/stmmac/stmmac.h
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c
drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c
drivers/net/ethernet/ti/tlan.c
drivers/net/fddi/defza.c
drivers/net/netdevsim/ipsec.c
drivers/net/phy/marvell10g.c
drivers/net/usb/asix_devices.c
drivers/net/virtio_net.c
drivers/net/vmxnet3/vmxnet3_ethtool.c
drivers/net/wan/hdlc_cisco.c
drivers/net/wan/hdlc_fr.c
drivers/net/wan/hdlc_ppp.c
drivers/net/wan/hdlc_raw.c
drivers/net/wan/hdlc_raw_eth.c
drivers/net/wan/hdlc_x25.c
drivers/net/wireless/mediatek/mt76/mt7921/main.c
drivers/net/wireless/mediatek/mt76/mt7921/mcu.c
drivers/net/wwan/iosm/iosm_ipc_imem_ops.c
drivers/net/wwan/iosm/iosm_ipc_imem_ops.h
drivers/net/wwan/iosm/iosm_ipc_mux_codec.c
drivers/net/wwan/iosm/iosm_ipc_uevent.c
drivers/net/wwan/iosm/iosm_ipc_wwan.c
drivers/nvme/host/pci.c
drivers/nvme/host/tcp.c
drivers/pci/proc.c
drivers/power/supply/ab8500_fg.c
drivers/power/supply/abx500_chargalg.c
drivers/ptp/Makefile
drivers/ptp/ptp_clock.c
drivers/ptp/ptp_private.h
drivers/ptp/ptp_sysfs.c
drivers/ptp/ptp_vclock.c [new file with mode: 0644]
drivers/pwm/pwm-berlin.c
drivers/pwm/pwm-ep93xx.c
drivers/pwm/pwm-spear.c
drivers/pwm/pwm-sprd.c
drivers/pwm/pwm-tiecap.c
drivers/s390/char/tape_char.c
drivers/s390/net/ctcm_fsms.c
drivers/s390/net/qeth_l3_main.c
drivers/s390/scsi/zfcp_sysfs.c
drivers/scsi/arm/fas216.c
drivers/scsi/hosts.c
drivers/scsi/libsas/sas_discover.c
drivers/scsi/mpi3mr/mpi3mr_fw.c
drivers/scsi/pm8001/pm8001_ctl.c
drivers/scsi/pm8001/pm8001_hwi.c
drivers/scsi/pm8001/pm8001_init.c
drivers/scsi/pm8001/pm8001_sas.c
drivers/scsi/pm8001/pm80xx_hwi.c
drivers/scsi/scsi_lib.c
drivers/scsi/sd.c
drivers/scsi/ufs/ufshcd.h
drivers/usb/gadget/udc/fsl_qe_udc.c
drivers/video/fbdev/core/fbmem.c
drivers/video/fbdev/xilinxfb.c
fs/btrfs/block-group.c
fs/btrfs/block-group.h
fs/btrfs/ctree.c
fs/btrfs/inode.c
fs/btrfs/transaction.c
fs/btrfs/transaction.h
fs/btrfs/tree-log.c
fs/btrfs/volumes.c
fs/btrfs/volumes.h
fs/cifs/cifs_dfs_ref.c
fs/cifs/cifsglob.h
fs/cifs/connect.c
fs/cifs/dns_resolve.c
fs/cifs/dns_resolve.h
fs/cifs/misc.c
fs/cifs/smb2ops.c
fs/cifs/smb2pdu.h
fs/configfs/file.c
fs/fcntl.c
fs/fs_context.c
fs/hfs/bfind.c
fs/hfs/bnode.c
fs/hfs/btree.h
fs/hfs/super.c
fs/io_uring.c
fs/iomap/buffered-io.c
fs/iomap/seek.c
fs/vboxsf/dir.c
fs/vboxsf/file.c
fs/vboxsf/vfsmod.h
fs/xfs/libxfs/xfs_ag.c
fs/xfs/libxfs/xfs_attr.c
fs/xfs/libxfs/xfs_ialloc.c
fs/xfs/libxfs/xfs_ialloc.h
fs/xfs/libxfs/xfs_inode_buf.c
fs/xfs/libxfs/xfs_trans_inode.c
fs/xfs/scrub/inode.c
fs/xfs/xfs_inode.c
fs/xfs/xfs_ioctl.c
fs/xfs/xfs_rtalloc.c
fs/zonefs/super.c
include/dt-bindings/clock/mt8192-clk.h [new file with mode: 0644]
include/dt-bindings/clock/qcom,dispcc-sc7280.h [new file with mode: 0644]
include/dt-bindings/clock/qcom,gcc-msm8953.h [new file with mode: 0644]
include/dt-bindings/clock/qcom,gcc-sc7280.h
include/dt-bindings/clock/qcom,gcc-sm6115.h [new file with mode: 0644]
include/dt-bindings/clock/qcom,gcc-sm6350.h [new file with mode: 0644]
include/dt-bindings/clock/qcom,gpucc-sc7280.h [new file with mode: 0644]
include/dt-bindings/clock/qcom,mmcc-msm8994.h [new file with mode: 0644]
include/dt-bindings/clock/qcom,rpmcc.h
include/dt-bindings/clock/qcom,rpmh.h
include/dt-bindings/clock/qcom,videocc-sc7280.h [new file with mode: 0644]
include/dt-bindings/clock/r9a07g044-cpg.h
include/linux/bpf.h
include/linux/clk-provider.h
include/linux/ethtool.h
include/linux/fs_context.h
include/linux/kasan.h
include/linux/marvell_phy.h
include/linux/migrate.h
include/linux/mm.h
include/linux/platform_data/x86/clk-lpss.h
include/linux/pm_clock.h
include/linux/pm_runtime.h
include/linux/ptp_clock_kernel.h
include/linux/rmap.h
include/linux/scmi_protocol.h
include/linux/scpi_protocol.h
include/linux/soc/qcom/smd-rpm.h
include/linux/stmmac.h
include/math-emu/op-common.h
include/net/bonding.h
include/net/busy_poll.h
include/net/caif/caif_hsi.h [deleted file]
include/net/dst_metadata.h
include/net/ip6_route.h
include/net/mptcp.h
include/net/netfilter/nf_conntrack_core.h
include/net/netns/conntrack.h
include/net/sctp/constants.h
include/net/sock.h
include/net/tcp.h
include/soc/tegra/mc.h
include/uapi/linux/ethtool_netlink.h
include/uapi/linux/net_tstamp.h
include/uapi/linux/netfilter/nfnetlink_log.h
include/uapi/linux/netfilter/nfnetlink_queue.h
init/Kconfig
kernel/bpf/core.c
kernel/bpf/devmap.c
kernel/bpf/verifier.c
kernel/cgroup/cgroup-v1.c
kernel/debug/gdbstub.c
kernel/rcu/refscale.c
kernel/rcu/tasks.h
kernel/rcu/tree_stall.h
kernel/scftorture.c
kernel/trace/trace_events_hist.c
lib/test_hmm.c
mm/hugetlb.c
mm/kasan/kasan.h
mm/migrate.c
mm/page_alloc.c
mm/rmap.c
mm/slab.h
mm/slub.c
mm/util.c
net/802/garp.c
net/802/mrp.c
net/bridge/br_if.c
net/bridge/br_multicast.c
net/core/dev.c
net/core/skbuff.c
net/core/sock.c
net/dsa/switch.c
net/ethtool/Makefile
net/ethtool/common.c
net/ethtool/netlink.c
net/ethtool/netlink.h
net/ethtool/phc_vclocks.c [new file with mode: 0644]
net/ipv4/fib_frontend.c
net/ipv4/inet_diag.c
net/ipv4/ip_tunnel.c
net/ipv4/ipmr.c
net/ipv4/raw_diag.c
net/ipv4/tcp.c
net/ipv4/tcp_input.c
net/ipv4/tcp_ipv4.c
net/ipv4/tcp_output.c
net/ipv4/udp.c
net/ipv4/udp_diag.c
net/ipv4/udp_offload.c
net/ipv6/ip6_output.c
net/ipv6/tcp_ipv6.c
net/ipv6/udp.c
net/ipv6/xfrm6_output.c
net/iucv/iucv.c
net/mptcp/mib.c
net/mptcp/mib.h
net/mptcp/mptcp_diag.c
net/mptcp/options.c
net/mptcp/protocol.c
net/mptcp/protocol.h
net/mptcp/sockopt.c
net/mptcp/subflow.c
net/mptcp/syncookies.c
net/ncsi/Kconfig
net/ncsi/internal.h
net/ncsi/ncsi-manage.c
net/ncsi/ncsi-rsp.c
net/netfilter/nf_conntrack_core.c
net/netfilter/nf_conntrack_netlink.c
net/netfilter/nf_conntrack_proto.c
net/netfilter/nf_conntrack_proto_gre.c
net/netfilter/nf_conntrack_proto_tcp.c
net/netfilter/nf_conntrack_standalone.c
net/netfilter/nf_tables_api.c
net/netfilter/nft_last.c
net/netlink/af_netlink.c
net/openvswitch/flow_table.c
net/sched/act_ct.c
net/sched/sch_taprio.c
net/sctp/diag.c
net/sctp/protocol.c
net/sctp/sm_make_chunk.c
net/sctp/transport.c
net/socket.c
net/unix/diag.c
samples/bpf/Makefile
samples/bpf/xdpsock_user.c
scripts/Makefile.build
scripts/setlocalversion
scripts/spdxcheck.py
sound/soc/mediatek/mt8183/mt8183-dai-adda.c
tools/arch/arm64/include/uapi/asm/unistd.h
tools/bpf/Makefile
tools/bpf/bpftool/jit_disasm.c
tools/bpf/runqslower/runqslower.bpf.c
tools/include/linux/kconfig.h
tools/include/uapi/asm-generic/unistd.h
tools/lib/bpf/libbpf.c
tools/perf/arch/x86/entry/syscalls/syscall_64.tbl
tools/perf/builtin-inject.c
tools/perf/builtin-report.c
tools/perf/builtin-sched.c
tools/perf/builtin-script.c
tools/perf/builtin-stat.c
tools/perf/builtin-trace.c
tools/perf/tests/bpf.c
tools/perf/tests/event_update.c
tools/perf/tests/evsel-roundtrip-name.c
tools/perf/tests/maps.c
tools/perf/tests/parse-events.c
tools/perf/tests/perf-time-to-tsc.c
tools/perf/tests/topology.c
tools/perf/util/cs-etm.c
tools/perf/util/data.c
tools/perf/util/dso.c
tools/perf/util/dwarf-aux.c
tools/perf/util/dwarf-aux.h
tools/perf/util/env.c
tools/perf/util/lzma.c
tools/perf/util/map.c
tools/perf/util/pfm.c
tools/perf/util/pmu.c
tools/perf/util/probe-event.c
tools/perf/util/probe-event.h
tools/perf/util/probe-file.c
tools/perf/util/probe-finder.c
tools/perf/util/probe-finder.h
tools/perf/util/session.c
tools/perf/util/sort.c
tools/perf/util/sort.h
tools/perf/util/stat-display.c
tools/testing/kunit/kunit.py
tools/testing/kunit/kunit_kernel.py
tools/testing/kunit/kunit_parser.py
tools/testing/kunit/kunit_tool_test.py
tools/testing/kunit/test_data/test_is_test_passed-no_tests_run.log [deleted file]
tools/testing/kunit/test_data/test_is_test_passed-no_tests_run_no_header.log [new file with mode: 0644]
tools/testing/kunit/test_data/test_is_test_passed-no_tests_run_with_header.log [new file with mode: 0644]
tools/testing/selftests/bpf/prog_tests/tailcalls.c
tools/testing/selftests/bpf/progs/tailcall_bpf2bpf4.c
tools/testing/selftests/kvm/include/kvm_util.h
tools/testing/selftests/kvm/lib/aarch64/processor.c
tools/testing/selftests/kvm/lib/guest_modes.c
tools/testing/selftests/kvm/lib/kvm_util.c
tools/testing/selftests/kvm/set_memory_region_test.c
tools/testing/selftests/kvm/x86_64/hyperv_features.c
tools/testing/selftests/kvm/x86_64/mmu_role_test.c
tools/testing/selftests/kvm/x86_64/smm_test.c
tools/testing/selftests/memory-hotplug/mem-on-off-test.sh
tools/testing/selftests/net/icmp_redirect.sh
tools/testing/selftests/net/mptcp/mptcp_join.sh
tools/testing/selftests/net/timestamping.c
tools/testing/selftests/netfilter/Makefile
tools/testing/selftests/netfilter/conntrack_tcp_unreplied.sh [new file with mode: 0755]
virt/kvm/coalesced_mmio.c
virt/kvm/kvm_main.c

index 2363ad8..d378f57 100644 (file)
@@ -33,6 +33,13 @@ Description:
                frequency adjustment value (a positive integer) in
                parts per billion.
 
+What:          /sys/class/ptp/ptpN/max_vclocks
+Date:          May 2021
+Contact:       Yangbo Lu <yangbo.lu@nxp.com>
+Description:
+               This file contains the maximum number of ptp vclocks.
+               Write integer to re-configure it.
+
 What:          /sys/class/ptp/ptpN/n_alarms
 Date:          September 2010
 Contact:       Richard Cochran <richardcochran@gmail.com>
@@ -61,6 +68,19 @@ Description:
                This file contains the number of programmable pins
                offered by the PTP hardware clock.
 
+What:          /sys/class/ptp/ptpN/n_vclocks
+Date:          May 2021
+Contact:       Yangbo Lu <yangbo.lu@nxp.com>
+Description:
+               This file contains the number of virtual PTP clocks in
+               use.  By default, the value is 0 meaning that only the
+               physical clock is in use.  Setting the value creates
+               the corresponding number of virtual clocks and causes
+               the physical clock to become free running.  Setting the
+               value back to 0 deletes the virtual clocks and
+               switches the physical clock back to normal, adjustable
+               operation.
+
 What:          /sys/class/ptp/ptpN/pins
 Date:          March 2014
 Contact:       Richard Cochran <richardcochran@gmail.com>
index 7d99386..d1626d5 100644 (file)
@@ -86,19 +86,7 @@ Generating code coverage reports under UML
 .. note::
        TODO(brendanhiggins@google.com): There are various issues with UML and
        versions of gcc 7 and up. You're likely to run into missing ``.gcda``
-       files or compile errors. We know one `faulty GCC commit
-       <https://github.com/gcc-mirror/gcc/commit/8c9434c2f9358b8b8bad2c1990edf10a21645f9d>`_
-       but not how we'd go about getting this fixed. The compile errors still
-       need some investigation.
-
-.. note::
-       TODO(brendanhiggins@google.com): for recent versions of Linux
-       (5.10-5.12, maybe earlier), there's a bug with gcov counters not being
-       flushed in UML. This translates to very low (<1%) reported coverage. This is
-       related to the above issue and can be worked around by replacing the
-       one call to ``uml_abort()`` (it's in ``os_dump_core()``) with a plain
-       ``exit()``.
-
+       files or compile errors.
 
 This is different from the "normal" way of getting coverage information that is
 documented in Documentation/dev-tools/gcov.rst.
index b32d374..699776b 100644 (file)
@@ -13,6 +13,7 @@ Required Properties:
        - "mediatek,mt7623-audsys", "mediatek,mt2701-audsys", "syscon"
        - "mediatek,mt8167-audiosys", "syscon"
        - "mediatek,mt8183-audiosys", "syscon"
+       - "mediatek,mt8192-audsys", "syscon"
        - "mediatek,mt8516-audsys", "syscon"
 - #clock-cells: Must be 1
 
index 78c5073..9712a68 100644 (file)
@@ -16,6 +16,7 @@ Required Properties:
        - "mediatek,mt8167-mmsys", "syscon"
        - "mediatek,mt8173-mmsys", "syscon"
        - "mediatek,mt8183-mmsys", "syscon"
+       - "mediatek,mt8192-mmsys", "syscon"
 - #clock-cells: Must be 1
 
 For the clock control, the mmsys controller uses the common clk binding from
diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,mt8192-clock.yaml b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mt8192-clock.yaml
new file mode 100644 (file)
index 0000000..c8c67c0
--- /dev/null
@@ -0,0 +1,199 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: "http://devicetree.org/schemas/arm/mediatek/mediatek,mt8192-clock.yaml#"
+$schema: "http://devicetree.org/meta-schemas/core.yaml#"
+
+title: MediaTek Functional Clock Controller for MT8192
+
+maintainers:
+  - Chun-Jie Chen <chun-jie.chen@mediatek.com>
+
+description:
+  The Mediatek functional clock controller provides various clocks on MT8192.
+
+properties:
+  compatible:
+    items:
+      - enum:
+          - mediatek,mt8192-scp_adsp
+          - mediatek,mt8192-imp_iic_wrap_c
+          - mediatek,mt8192-imp_iic_wrap_e
+          - mediatek,mt8192-imp_iic_wrap_s
+          - mediatek,mt8192-imp_iic_wrap_ws
+          - mediatek,mt8192-imp_iic_wrap_w
+          - mediatek,mt8192-imp_iic_wrap_n
+          - mediatek,mt8192-msdc_top
+          - mediatek,mt8192-msdc
+          - mediatek,mt8192-mfgcfg
+          - mediatek,mt8192-imgsys
+          - mediatek,mt8192-imgsys2
+          - mediatek,mt8192-vdecsys_soc
+          - mediatek,mt8192-vdecsys
+          - mediatek,mt8192-vencsys
+          - mediatek,mt8192-camsys
+          - mediatek,mt8192-camsys_rawa
+          - mediatek,mt8192-camsys_rawb
+          - mediatek,mt8192-camsys_rawc
+          - mediatek,mt8192-ipesys
+          - mediatek,mt8192-mdpsys
+
+  reg:
+    maxItems: 1
+
+  '#clock-cells':
+    const: 1
+
+required:
+  - compatible
+  - reg
+
+additionalProperties: false
+
+examples:
+  - |
+    scp_adsp: clock-controller@10720000 {
+        compatible = "mediatek,mt8192-scp_adsp";
+        reg = <0x10720000 0x1000>;
+        #clock-cells = <1>;
+    };
+
+  - |
+    imp_iic_wrap_c: clock-controller@11007000 {
+        compatible = "mediatek,mt8192-imp_iic_wrap_c";
+        reg = <0x11007000 0x1000>;
+        #clock-cells = <1>;
+    };
+
+  - |
+    imp_iic_wrap_e: clock-controller@11cb1000 {
+        compatible = "mediatek,mt8192-imp_iic_wrap_e";
+        reg = <0x11cb1000 0x1000>;
+        #clock-cells = <1>;
+    };
+
+  - |
+    imp_iic_wrap_s: clock-controller@11d03000 {
+        compatible = "mediatek,mt8192-imp_iic_wrap_s";
+        reg = <0x11d03000 0x1000>;
+        #clock-cells = <1>;
+    };
+
+  - |
+    imp_iic_wrap_ws: clock-controller@11d23000 {
+        compatible = "mediatek,mt8192-imp_iic_wrap_ws";
+        reg = <0x11d23000 0x1000>;
+        #clock-cells = <1>;
+    };
+
+  - |
+    imp_iic_wrap_w: clock-controller@11e01000 {
+        compatible = "mediatek,mt8192-imp_iic_wrap_w";
+        reg = <0x11e01000 0x1000>;
+        #clock-cells = <1>;
+    };
+
+  - |
+    imp_iic_wrap_n: clock-controller@11f02000 {
+        compatible = "mediatek,mt8192-imp_iic_wrap_n";
+        reg = <0x11f02000 0x1000>;
+        #clock-cells = <1>;
+    };
+
+  - |
+    msdc_top: clock-controller@11f10000 {
+        compatible = "mediatek,mt8192-msdc_top";
+        reg = <0x11f10000 0x1000>;
+        #clock-cells = <1>;
+    };
+
+  - |
+    msdc: clock-controller@11f60000 {
+        compatible = "mediatek,mt8192-msdc";
+        reg = <0x11f60000 0x1000>;
+        #clock-cells = <1>;
+    };
+
+  - |
+    mfgcfg: clock-controller@13fbf000 {
+        compatible = "mediatek,mt8192-mfgcfg";
+        reg = <0x13fbf000 0x1000>;
+        #clock-cells = <1>;
+    };
+
+  - |
+    imgsys: clock-controller@15020000 {
+        compatible = "mediatek,mt8192-imgsys";
+        reg = <0x15020000 0x1000>;
+        #clock-cells = <1>;
+    };
+
+  - |
+    imgsys2: clock-controller@15820000 {
+        compatible = "mediatek,mt8192-imgsys2";
+        reg = <0x15820000 0x1000>;
+        #clock-cells = <1>;
+    };
+
+  - |
+    vdecsys_soc: clock-controller@1600f000 {
+        compatible = "mediatek,mt8192-vdecsys_soc";
+        reg = <0x1600f000 0x1000>;
+        #clock-cells = <1>;
+    };
+
+  - |
+    vdecsys: clock-controller@1602f000 {
+        compatible = "mediatek,mt8192-vdecsys";
+        reg = <0x1602f000 0x1000>;
+        #clock-cells = <1>;
+    };
+
+  - |
+    vencsys: clock-controller@17000000 {
+        compatible = "mediatek,mt8192-vencsys";
+        reg = <0x17000000 0x1000>;
+        #clock-cells = <1>;
+    };
+
+  - |
+    camsys: clock-controller@1a000000 {
+        compatible = "mediatek,mt8192-camsys";
+        reg = <0x1a000000 0x1000>;
+        #clock-cells = <1>;
+    };
+
+  - |
+    camsys_rawa: clock-controller@1a04f000 {
+        compatible = "mediatek,mt8192-camsys_rawa";
+        reg = <0x1a04f000 0x1000>;
+        #clock-cells = <1>;
+    };
+
+  - |
+    camsys_rawb: clock-controller@1a06f000 {
+        compatible = "mediatek,mt8192-camsys_rawb";
+        reg = <0x1a06f000 0x1000>;
+        #clock-cells = <1>;
+    };
+
+  - |
+    camsys_rawc: clock-controller@1a08f000 {
+        compatible = "mediatek,mt8192-camsys_rawc";
+        reg = <0x1a08f000 0x1000>;
+        #clock-cells = <1>;
+    };
+
+  - |
+    ipesys: clock-controller@1b000000 {
+        compatible = "mediatek,mt8192-ipesys";
+        reg = <0x1b000000 0x1000>;
+        #clock-cells = <1>;
+    };
+
+  - |
+    mdpsys: clock-controller@1f000000 {
+        compatible = "mediatek,mt8192-mdpsys";
+        reg = <0x1f000000 0x1000>;
+        #clock-cells = <1>;
+    };
diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,mt8192-sys-clock.yaml b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mt8192-sys-clock.yaml
new file mode 100644 (file)
index 0000000..5705bcf
--- /dev/null
@@ -0,0 +1,65 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: "http://devicetree.org/schemas/arm/mediatek/mediatek,mt8192-sys-clock.yaml#"
+$schema: "http://devicetree.org/meta-schemas/core.yaml#"
+
+title: MediaTek System Clock Controller for MT8192
+
+maintainers:
+  - Chun-Jie Chen <chun-jie.chen@mediatek.com>
+
+description:
+  The Mediatek system clock controller provides various clocks and system configuration
+  like reset and bus protection on MT8192.
+
+properties:
+  compatible:
+    items:
+      - enum:
+          - mediatek,mt8192-topckgen
+          - mediatek,mt8192-infracfg
+          - mediatek,mt8192-pericfg
+          - mediatek,mt8192-apmixedsys
+      - const: syscon
+
+  reg:
+    maxItems: 1
+
+  '#clock-cells':
+    const: 1
+
+required:
+  - compatible
+  - reg
+
+additionalProperties: false
+
+examples:
+  - |
+    topckgen: syscon@10000000 {
+        compatible = "mediatek,mt8192-topckgen", "syscon";
+        reg = <0x10000000 0x1000>;
+        #clock-cells = <1>;
+    };
+
+  - |
+    infracfg: syscon@10001000 {
+        compatible = "mediatek,mt8192-infracfg", "syscon";
+        reg = <0x10001000 0x1000>;
+        #clock-cells = <1>;
+    };
+
+  - |
+    pericfg: syscon@10003000 {
+        compatible = "mediatek,mt8192-pericfg", "syscon";
+        reg = <0x10003000 0x1000>;
+        #clock-cells = <1>;
+    };
+
+  - |
+    apmixedsys: syscon@1000c000 {
+        compatible = "mediatek,mt8192-apmixedsys", "syscon";
+        reg = <0x1000c000 0x1000>;
+        #clock-cells = <1>;
+    };
index 8dc7b40..1174c9a 100644 (file)
@@ -50,7 +50,6 @@ properties:
 
   reg:
     minItems: 1
-    maxItems: 3
     items:
       - description: base register
       - description: power register
index db3d0ea..fbd7584 100644 (file)
@@ -18,6 +18,7 @@ properties:
     enum:
       - qcom,ipq6018-a53pll
       - qcom,msm8916-a53pll
+      - qcom,msm8939-a53pll
 
   reg:
     maxItems: 1
@@ -33,6 +34,8 @@ properties:
     items:
       - const: xo
 
+  operating-points-v2: true
+
 required:
   - compatible
   - reg
diff --git a/Documentation/devicetree/bindings/clock/qcom,gcc-sm6115.yaml b/Documentation/devicetree/bindings/clock/qcom,gcc-sm6115.yaml
new file mode 100644 (file)
index 0000000..26050da
--- /dev/null
@@ -0,0 +1,72 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/qcom,gcc-sm6115.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Qualcomm Global Clock & Reset Controller Binding for SM6115 and SM4250
+
+maintainers:
+  - Iskren Chernev <iskren.chernev@gmail.com>
+
+description: |
+  Qualcomm global clock control module which supports the clocks, resets and
+  power domains on SM4250/6115.
+
+  See also:
+  - dt-bindings/clock/qcom,gcc-sm6115.h
+
+properties:
+  compatible:
+    const: qcom,gcc-sm6115
+
+  clocks:
+    items:
+      - description: Board XO source
+      - description: Sleep clock source
+
+  clock-names:
+    items:
+      - const: bi_tcxo
+      - const: sleep_clk
+
+  '#clock-cells':
+    const: 1
+
+  '#reset-cells':
+    const: 1
+
+  '#power-domain-cells':
+    const: 1
+
+  reg:
+    maxItems: 1
+
+  protected-clocks:
+    description:
+      Protected clock specifier list as per common clock binding.
+
+required:
+  - compatible
+  - clocks
+  - clock-names
+  - reg
+  - '#clock-cells'
+  - '#reset-cells'
+  - '#power-domain-cells'
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/qcom,rpmcc.h>
+    clock-controller@1400000 {
+        compatible = "qcom,gcc-sm6115";
+        reg = <0x01400000 0x1f0000>;
+        #clock-cells = <1>;
+        #reset-cells = <1>;
+        #power-domain-cells = <1>;
+        clock-names = "bi_tcxo", "sleep_clk";
+        clocks = <&rpmcc RPM_SMD_XO_CLK_SRC>, <&sleep_clk>;
+    };
+...
diff --git a/Documentation/devicetree/bindings/clock/qcom,gcc-sm6350.yaml b/Documentation/devicetree/bindings/clock/qcom,gcc-sm6350.yaml
new file mode 100644 (file)
index 0000000..20926cd
--- /dev/null
@@ -0,0 +1,76 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/qcom,gcc-sm6350.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Qualcomm Global Clock & Reset Controller Binding for SM6350
+
+maintainers:
+  - Konrad Dybcio <konrad.dybcio@somainline.org>
+
+description: |
+  Qualcomm global clock control module which supports the clocks, resets and
+  power domains on SM6350.
+
+  See also:
+  - dt-bindings/clock/qcom,gcc-sm6350.h
+
+properties:
+  compatible:
+    const: qcom,gcc-sm6350
+
+  clocks:
+    items:
+      - description: Board XO source
+      - description: Board active XO source
+      - description: Sleep clock source
+
+  clock-names:
+    items:
+      - const: bi_tcxo
+      - const: bi_tcxo_ao
+      - const: sleep_clk
+
+  '#clock-cells':
+    const: 1
+
+  '#reset-cells':
+    const: 1
+
+  '#power-domain-cells':
+    const: 1
+
+  reg:
+    maxItems: 1
+
+  protected-clocks:
+    description:
+      Protected clock specifier list as per common clock binding.
+
+required:
+  - compatible
+  - clocks
+  - clock-names
+  - reg
+  - '#clock-cells'
+  - '#reset-cells'
+  - '#power-domain-cells'
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/qcom,rpmh.h>
+    clock-controller@100000 {
+      compatible = "qcom,gcc-sm6350";
+      reg = <0x00100000 0x1f0000>;
+      clocks = <&rpmhcc RPMH_CXO_CLK>,
+               <&rpmhcc RPMH_CXO_CLK_A>,
+               <&sleep_clk>;
+      clock-names = "bi_tcxo", "bi_tcxo_ao", "sleep_clk";
+      #clock-cells = <1>;
+      #reset-cells = <1>;
+      #power-domain-cells = <1>;
+    };
+...
index 8453eed..2f20f8a 100644 (file)
@@ -23,6 +23,7 @@ description: |
   - dt-bindings/clock/qcom,gcc-ipq806x.h (qcom,gcc-ipq8064)
   - dt-bindings/reset/qcom,gcc-ipq806x.h (qcom,gcc-ipq8064)
   - dt-bindings/clock/qcom,gcc-msm8939.h
+  - dt-bindings/clock/qcom,gcc-msm8953.h
   - dt-bindings/reset/qcom,gcc-msm8939.h
   - dt-bindings/clock/qcom,gcc-msm8660.h
   - dt-bindings/reset/qcom,gcc-msm8660.h
@@ -46,6 +47,7 @@ properties:
       - qcom,gcc-msm8660
       - qcom,gcc-msm8916
       - qcom,gcc-msm8939
+      - qcom,gcc-msm8953
       - qcom,gcc-msm8960
       - qcom,gcc-msm8974
       - qcom,gcc-msm8974pro
index df943c4..46dff46 100644 (file)
@@ -1,4 +1,4 @@
-# SPDX-License-Identifier: GPL-2.0-only
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
 %YAML 1.2
 ---
 $id: http://devicetree.org/schemas/clock/qcom,gpucc.yaml#
@@ -11,11 +11,12 @@ maintainers:
 
 description: |
   Qualcomm graphics clock control module which supports the clocks, resets and
-  power domains on SDM845/SC7180/SM8150/SM8250.
+  power domains on Qualcomm SoCs.
 
   See also:
     dt-bindings/clock/qcom,gpucc-sdm845.h
     dt-bindings/clock/qcom,gpucc-sc7180.h
+    dt-bindings/clock/qcom,gpucc-sc7280.h
     dt-bindings/clock/qcom,gpucc-sm8150.h
     dt-bindings/clock/qcom,gpucc-sm8250.h
 
@@ -24,6 +25,8 @@ properties:
     enum:
       - qcom,sdm845-gpucc
       - qcom,sc7180-gpucc
+      - qcom,sc7280-gpucc
+      - qcom,sc8180x-gpucc
       - qcom,sm8150-gpucc
       - qcom,sm8250-gpucc
 
index 8b0b1c5..68fdc3d 100644 (file)
@@ -22,6 +22,8 @@ properties:
       - qcom,mmcc-msm8660
       - qcom,mmcc-msm8960
       - qcom,mmcc-msm8974
+      - qcom,mmcc-msm8992
+      - qcom,mmcc-msm8994
       - qcom,mmcc-msm8996
       - qcom,mmcc-msm8998
       - qcom,mmcc-sdm630
index 6cf5a7e..a487788 100644 (file)
@@ -10,11 +10,13 @@ Required properties :
 - compatible : shall contain only one of the following. The generic
                compatible "qcom,rpmcc" should be also included.
 
+                       "qcom,rpmcc-mdm9607", "qcom,rpmcc"
                        "qcom,rpmcc-msm8660", "qcom,rpmcc"
                        "qcom,rpmcc-apq8060", "qcom,rpmcc"
                        "qcom,rpmcc-msm8226", "qcom,rpmcc"
                        "qcom,rpmcc-msm8916", "qcom,rpmcc"
                        "qcom,rpmcc-msm8936", "qcom,rpmcc"
+                       "qcom,rpmcc-msm8953", "qcom,rpmcc"
                        "qcom,rpmcc-msm8974", "qcom,rpmcc"
                        "qcom,rpmcc-msm8976", "qcom,rpmcc"
                        "qcom,rpmcc-apq8064", "qcom,rpmcc"
@@ -25,6 +27,8 @@ Required properties :
                        "qcom,rpmcc-msm8998", "qcom,rpmcc"
                        "qcom,rpmcc-qcs404", "qcom,rpmcc"
                        "qcom,rpmcc-sdm660", "qcom,rpmcc"
+                       "qcom,rpmcc-sm6115", "qcom,rpmcc"
+                       "qcom,rpmcc-sm6125", "qcom,rpmcc"
 
 - #clock-cells : shall contain 1
 
index 9ea0b3f..7221297 100644 (file)
@@ -22,6 +22,7 @@ properties:
       - qcom,sc8180x-rpmh-clk
       - qcom,sdm845-rpmh-clk
       - qcom,sdx55-rpmh-clk
+      - qcom,sm6350-rpmh-clk
       - qcom,sm8150-rpmh-clk
       - qcom,sm8250-rpmh-clk
       - qcom,sm8350-rpmh-clk
diff --git a/Documentation/devicetree/bindings/clock/qcom,sc7280-dispcc.yaml b/Documentation/devicetree/bindings/clock/qcom,sc7280-dispcc.yaml
new file mode 100644 (file)
index 0000000..2178666
--- /dev/null
@@ -0,0 +1,94 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/qcom,sc7280-dispcc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Qualcomm Display Clock & Reset Controller Binding for SC7280
+
+maintainers:
+  - Taniya Das <tdas@codeaurora.org>
+
+description: |
+  Qualcomm display clock control module which supports the clocks, resets and
+  power domains on SC7280.
+
+  See also dt-bindings/clock/qcom,dispcc-sc7280.h.
+
+properties:
+  compatible:
+    const: qcom,sc7280-dispcc
+
+  clocks:
+    items:
+      - description: Board XO source
+      - description: GPLL0 source from GCC
+      - description: Byte clock from DSI PHY
+      - description: Pixel clock from DSI PHY
+      - description: Link clock from DP PHY
+      - description: VCO DIV clock from DP PHY
+      - description: Link clock from EDP PHY
+      - description: VCO DIV clock from EDP PHY
+
+  clock-names:
+    items:
+      - const: bi_tcxo
+      - const: gcc_disp_gpll0_clk
+      - const: dsi0_phy_pll_out_byteclk
+      - const: dsi0_phy_pll_out_dsiclk
+      - const: dp_phy_pll_link_clk
+      - const: dp_phy_pll_vco_div_clk
+      - const: edp_phy_pll_link_clk
+      - const: edp_phy_pll_vco_div_clk
+
+  '#clock-cells':
+    const: 1
+
+  '#reset-cells':
+    const: 1
+
+  '#power-domain-cells':
+    const: 1
+
+  reg:
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - clock-names
+  - '#clock-cells'
+  - '#reset-cells'
+  - '#power-domain-cells'
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/qcom,gcc-sc7280.h>
+    #include <dt-bindings/clock/qcom,rpmh.h>
+    clock-controller@af00000 {
+      compatible = "qcom,sc7280-dispcc";
+      reg = <0x0af00000 0x200000>;
+      clocks = <&rpmhcc RPMH_CXO_CLK>,
+               <&gcc GCC_DISP_GPLL0_CLK_SRC>,
+               <&dsi_phy 0>,
+               <&dsi_phy 1>,
+               <&dp_phy 0>,
+               <&dp_phy 1>,
+               <&edp_phy 0>,
+               <&edp_phy 1>;
+      clock-names = "bi_tcxo",
+                    "gcc_disp_gpll0_clk",
+                    "dsi0_phy_pll_out_byteclk",
+                    "dsi0_phy_pll_out_dsiclk",
+                    "dp_phy_pll_link_clk",
+                    "dp_phy_pll_vco_div_clk",
+                    "edp_phy_pll_link_clk",
+                    "edp_phy_pll_vco_div_clk";
+      #clock-cells = <1>;
+      #reset-cells = <1>;
+      #power-domain-cells = <1>;
+    };
+...
index 5672029..0d224f1 100644 (file)
@@ -1,4 +1,4 @@
-# SPDX-License-Identifier: GPL-2.0-only
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
 %YAML 1.2
 ---
 $id: http://devicetree.org/schemas/clock/qcom,videocc.yaml#
@@ -11,10 +11,11 @@ maintainers:
 
 description: |
   Qualcomm video clock control module which supports the clocks, resets and
-  power domains on SDM845/SC7180/SM8150/SM8250.
+  power domains on Qualcomm SoCs.
 
   See also:
     dt-bindings/clock/qcom,videocc-sc7180.h
+    dt-bindings/clock/qcom,videocc-sc7280.h
     dt-bindings/clock/qcom,videocc-sdm845.h
     dt-bindings/clock/qcom,videocc-sm8150.h
     dt-bindings/clock/qcom,videocc-sm8250.h
@@ -23,6 +24,7 @@ properties:
   compatible:
     enum:
       - qcom,sc7180-videocc
+      - qcom,sc7280-videocc
       - qcom,sdm845-videocc
       - qcom,sm8150-videocc
       - qcom,sm8250-videocc
index ad0ec9f..7d9c083 100644 (file)
@@ -39,17 +39,7 @@ properties:
   reg:
     maxItems: 1
 
-patternProperties:
-  "^adi,bypass-attenuator-in[0-4]$":
-    description: |
-      Configures bypassing the individual voltage input attenuator. If
-      set to 1 the attenuator is bypassed if set to 0 the attenuator is
-      not bypassed. If the property is absent then the attenuator
-      retains it's configuration from the bios/bootloader.
-    $ref: /schemas/types.yaml#/definitions/uint32
-    enum: [0, 1]
-
-  "^adi,pwm-active-state$":
+  adi,pwm-active-state:
     description: |
       Integer array, represents the active state of the pwm outputs If set to 0
       the pwm uses a logic low output for 100% duty cycle. If set to 1 the pwm
@@ -61,6 +51,16 @@ patternProperties:
       enum: [0, 1]
       default: 1
 
+patternProperties:
+  "^adi,bypass-attenuator-in[0-4]$":
+    description: |
+      Configures bypassing the individual voltage input attenuator. If
+      set to 1 the attenuator is bypassed if set to 0 the attenuator is
+      not bypassed. If the property is absent then the attenuator
+      retains it's configuration from the bios/bootloader.
+    $ref: /schemas/types.yaml#/definitions/uint32
+    enum: [0, 1]
+
 required:
   - compatible
   - reg
index 1181b59..03f2b2d 100644 (file)
@@ -52,16 +52,14 @@ properties:
         items:
           - const: marvell,ap806-smmu-500
           - const: arm,mmu-500
-      - description: NVIDIA SoCs that program two ARM MMU-500s identically
-        items:
       - description: NVIDIA SoCs that require memory controller interaction
           and may program multiple ARM MMU-500s identically with the memory
           controller interleaving translations between multiple instances
           for improved performance.
         items:
           - enum:
-              - const: nvidia,tegra194-smmu
-              - const: nvidia,tegra186-smmu
+              - nvidia,tegra194-smmu
+              - nvidia,tegra186-smmu
           - const: nvidia,smmu-500
       - items:
           - const: arm,mmu-500
index d2e28a9..ba9124f 100644 (file)
@@ -28,14 +28,12 @@ properties:
       - description: configuration registers for MMU instance 0
       - description: configuration registers for MMU instance 1
     minItems: 1
-    maxItems: 2
 
   interrupts:
     items:
       - description: interruption for MMU instance 0
       - description: interruption for MMU instance 1
     minItems: 1
-    maxItems: 2
 
   clocks:
     items:
index 7a63c85..01c9acf 100644 (file)
@@ -57,7 +57,6 @@ properties:
 
   ranges:
     minItems: 1
-    maxItems: 3
     description: |
       Memory bus areas for interacting with the devices. Reflects
       the memory layout with four integer values following:
index e5f1a33..dd5a649 100644 (file)
@@ -84,7 +84,6 @@ properties:
 
   interrupts:
     minItems: 1
-    maxItems: 3
     items:
       - description: NAND CTLRDY interrupt
       - description: FLASH_DMA_DONE if flash DMA is available
@@ -92,7 +91,6 @@ properties:
 
   interrupt-names:
     minItems: 1
-    maxItems: 3
     items:
       - const: nand_ctlrdy
       - const: flash_dma_done
@@ -148,8 +146,6 @@ allOf:
     then:
       properties:
         reg-names:
-          minItems: 2
-          maxItems: 2
           items:
             - const: nand
             - const: nand-int-base
@@ -161,8 +157,6 @@ allOf:
     then:
       properties:
         reg-names:
-          minItems: 3
-          maxItems: 3
           items:
             - const: nand
             - const: nand-int-base
@@ -175,8 +169,6 @@ allOf:
     then:
       properties:
         reg-names:
-          minItems: 3
-          maxItems: 3
           items:
             - const: nand
             - const: iproc-idm
index 0b8a05d..f978f87 100644 (file)
@@ -67,8 +67,8 @@ properties:
           reg:
             oneOf:
               - enum:
-                - 0
-                - 1
+                  - 0
+                  - 1
 
         required:
           - compatible
index f7da3d7..3282106 100644 (file)
@@ -13,7 +13,7 @@ Documentation/devicetree/bindings/memory-controllers/omap-gpmc.txt
 
 For the properties relevant to the ethernet controller connected to the GPMC
 refer to the binding documentation of the device. For example, the documentation
-for the SMSC 911x is Documentation/devicetree/bindings/net/smsc911x.txt
+for the SMSC 911x is Documentation/devicetree/bindings/net/smsc,lan9115.yaml
 
 Child nodes need to specify the GPMC bus address width using the "bank-width"
 property but is possible that an ethernet controller also has a property to
diff --git a/Documentation/devicetree/bindings/net/smsc,lan9115.yaml b/Documentation/devicetree/bindings/net/smsc,lan9115.yaml
new file mode 100644 (file)
index 0000000..f86667c
--- /dev/null
@@ -0,0 +1,110 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/net/smsc,lan9115.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Smart Mixed-Signal Connectivity (SMSC) LAN911x/912x Controller
+
+maintainers:
+  - Shawn Guo <shawnguo@kernel.org>
+
+allOf:
+  - $ref: ethernet-controller.yaml#
+
+properties:
+  compatible:
+    oneOf:
+      - const: smsc,lan9115
+      - items:
+          - enum:
+              - smsc,lan89218
+              - smsc,lan9117
+              - smsc,lan9118
+              - smsc,lan9220
+              - smsc,lan9221
+          - const: smsc,lan9115
+
+  reg:
+    maxItems: 1
+
+  reg-shift: true
+
+  reg-io-width:
+    enum: [ 2, 4 ]
+    default: 2
+
+  interrupts:
+    minItems: 1
+    items:
+      - description:
+          LAN interrupt line
+      - description:
+          Optional PME (power management event) interrupt that is able to wake
+          up the host system with a 50ms pulse on network activity
+
+  clocks:
+    maxItems: 1
+
+  phy-mode: true
+
+  smsc,irq-active-high:
+    type: boolean
+    description: Indicates the IRQ polarity is active-high
+
+  smsc,irq-push-pull:
+    type: boolean
+    description: Indicates the IRQ type is push-pull
+
+  smsc,force-internal-phy:
+    type: boolean
+    description: Forces SMSC LAN controller to use internal PHY
+
+  smsc,force-external-phy:
+    type: boolean
+    description: Forces SMSC LAN controller to use external PHY
+
+  smsc,save-mac-address:
+    type: boolean
+    description:
+      Indicates that MAC address needs to be saved before resetting the
+      controller
+
+  reset-gpios:
+    maxItems: 1
+    description:
+      A GPIO line connected to the RESET (active low) signal of the device.
+      On many systems this is wired high so the device goes out of reset at
+      power-on, but if it is under program control, this optional GPIO can
+      wake up in response to it.
+
+  vdd33a-supply:
+    description: 3.3V analog power supply
+
+  vddvario-supply:
+    description: IO logic power supply
+
+required:
+  - compatible
+  - reg
+  - interrupts
+
+# There are lots of bus-specific properties ("qcom,*", "samsung,*", "fsl,*",
+# "gpmc,*", ...) to be found, that actually depend on the compatible value of
+# the parent node.
+additionalProperties: true
+
+examples:
+  - |
+    #include <dt-bindings/gpio/gpio.h>
+
+    ethernet@f4000000 {
+            compatible = "smsc,lan9220", "smsc,lan9115";
+            reg = <0xf4000000 0x2000000>;
+            phy-mode = "mii";
+            interrupt-parent = <&gpio1>;
+            interrupts = <31>, <32>;
+            reset-gpios = <&gpio1 30 GPIO_ACTIVE_LOW>;
+            reg-io-width = <4>;
+            smsc,irq-push-pull;
+    };
diff --git a/Documentation/devicetree/bindings/net/smsc911x.txt b/Documentation/devicetree/bindings/net/smsc911x.txt
deleted file mode 100644 (file)
index acfafc8..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-* Smart Mixed-Signal Connectivity (SMSC) LAN911x/912x Controller
-
-Required properties:
-- compatible : Should be "smsc,lan<model>", "smsc,lan9115"
-- reg : Address and length of the io space for SMSC LAN
-- interrupts : one or two interrupt specifiers
-  - The first interrupt is the SMSC LAN interrupt line
-  - The second interrupt (if present) is the PME (power
-    management event) interrupt that is able to wake up the host
-     system with a 50ms pulse on network activity
-- phy-mode : See ethernet.txt file in the same directory
-
-Optional properties:
-- reg-shift : Specify the quantity to shift the register offsets by
-- reg-io-width : Specify the size (in bytes) of the IO accesses that
-  should be performed on the device.  Valid value for SMSC LAN is
-  2 or 4.  If it's omitted or invalid, the size would be 2.
-- smsc,irq-active-high : Indicates the IRQ polarity is active-high
-- smsc,irq-push-pull : Indicates the IRQ type is push-pull
-- smsc,force-internal-phy : Forces SMSC LAN controller to use
-  internal PHY
-- smsc,force-external-phy : Forces SMSC LAN controller to use
-  external PHY
-- smsc,save-mac-address : Indicates that mac address needs to be saved
-  before resetting the controller
-- reset-gpios : a GPIO line connected to the RESET (active low) signal
-  of the device. On many systems this is wired high so the device goes
-  out of reset at power-on, but if it is under program control, this
-  optional GPIO can wake up in response to it.
-- vdd33a-supply, vddvario-supply : 3.3V analog and IO logic power supplies
-
-Examples:
-
-lan9220@f4000000 {
-       compatible = "smsc,lan9220", "smsc,lan9115";
-       reg = <0xf4000000 0x2000000>;
-       phy-mode = "mii";
-       interrupt-parent = <&gpio1>;
-       interrupts = <31>, <32>;
-       reset-gpios = <&gpio1 30 GPIO_ACTIVE_LOW>;
-       reg-io-width = <4>;
-       smsc,irq-push-pull;
-};
index 5272b6f..dcd6390 100644 (file)
@@ -77,6 +77,34 @@ properties:
       Type-C spec states minimum CC pin debounce of 100 ms and maximum
       of 200 ms. However, some solutions might need more than 200 ms.
 
+  refclk-dig:
+    type: object
+    description: |
+      WIZ node should have subnode for refclk_dig to select the reference
+      clock source for the reference clock used in the PHY and PMA digital
+      logic.
+    properties:
+      clocks:
+        minItems: 2
+        maxItems: 4
+        description: Phandle to two (Torrent) or four (Sierra) clock nodes representing
+          the inputs to refclk_dig
+
+      "#clock-cells":
+        const: 0
+
+      assigned-clocks:
+        maxItems: 1
+
+      assigned-clock-parents:
+        maxItems: 1
+
+    required:
+      - clocks
+      - "#clock-cells"
+      - assigned-clocks
+      - assigned-clock-parents
+
 patternProperties:
   "^pll[0|1]-refclk$":
     type: object
@@ -121,34 +149,6 @@ patternProperties:
       - clocks
       - "#clock-cells"
 
-  "^refclk-dig$":
-    type: object
-    description: |
-      WIZ node should have subnode for refclk_dig to select the reference
-      clock source for the reference clock used in the PHY and PMA digital
-      logic.
-    properties:
-      clocks:
-        minItems: 2
-        maxItems: 4
-        description: Phandle to two (Torrent) or four (Sierra) clock nodes representing
-          the inputs to refclk_dig
-
-      "#clock-cells":
-        const: 0
-
-      assigned-clocks:
-        maxItems: 1
-
-      assigned-clock-parents:
-        maxItems: 1
-
-    required:
-      - clocks
-      - "#clock-cells"
-      - assigned-clocks
-      - assigned-clock-parents
-
   "^serdes@[0-9a-f]+$":
     type: object
     description: |
index 12b8963..c2e8c54 100644 (file)
@@ -36,12 +36,12 @@ properties:
           switching frequency must be one of following corresponding value
           1.1MHz, 1.65MHz, 2.2MHz, 2.75MHz
 
-    patternProperties:
-      "^ldo[1-4]$":
+      ldortc:
         type: object
         $ref: regulator.yaml#
 
-      "^ldortc$":
+    patternProperties:
+      "^ldo[1-4]$":
         type: object
         $ref: regulator.yaml#
 
index 8761437..aabf50f 100644 (file)
@@ -83,7 +83,8 @@ properties:
 
         unevaluatedProperties: false
 
-      "^vsnvs$":
+    properties:
+      vsnvs:
         type: object
         $ref: regulator.yaml#
         description:
index 657c13b..056d42d 100644 (file)
@@ -30,7 +30,6 @@ properties:
     maxItems: 1
 
   clocks:
-    minItems: 2
     items:
       - description: PCLK clocks
       - description: EXTCLK clocks. Faraday calls it CLK1HZ and says the clock
index faef4f6..8246891 100644 (file)
@@ -79,22 +79,7 @@ properties:
     description:
       The SPI controller acts as a slave, instead of a master.
 
-allOf:
-  - if:
-      not:
-        required:
-          - spi-slave
-    then:
-      properties:
-        "#address-cells":
-          const: 1
-    else:
-      properties:
-        "#address-cells":
-          const: 0
-
-patternProperties:
-  "^slave$":
+  slave:
     type: object
 
     properties:
@@ -105,6 +90,7 @@ patternProperties:
     required:
       - compatible
 
+patternProperties:
   "^.*@[0-9a-f]+$":
     type: object
 
@@ -180,6 +166,20 @@ patternProperties:
       - compatible
       - reg
 
+allOf:
+  - if:
+      not:
+        required:
+          - spi-slave
+    then:
+      properties:
+        "#address-cells":
+          const: 1
+    else:
+      properties:
+        "#address-cells":
+          const: 0
+
 additionalProperties: true
 
 examples:
index a88f99a..f238848 100644 (file)
@@ -25,14 +25,12 @@ properties:
 
   interrupts:
     minItems: 1
-    maxItems: 2
     items:
       - description: Host controller interrupt
       - description: Device controller interrupt in isp1761
 
   interrupt-names:
     minItems: 1
-    maxItems: 2
     items:
       - const: host
       - const: peripheral
index 8a58c61..61bdeac 100644 (file)
@@ -69,17 +69,17 @@ early userspace image can be built by an unprivileged user.
 
 As a technical note, when directories and files are specified, the
 entire CONFIG_INITRAMFS_SOURCE is passed to
-usr/gen_initramfs_list.sh.  This means that CONFIG_INITRAMFS_SOURCE
+usr/gen_initramfs.sh.  This means that CONFIG_INITRAMFS_SOURCE
 can really be interpreted as any legal argument to
-gen_initramfs_list.sh.  If a directory is specified as an argument then
+gen_initramfs.sh.  If a directory is specified as an argument then
 the contents are scanned, uid/gid translation is performed, and
 usr/gen_init_cpio file directives are output.  If a directory is
-specified as an argument to usr/gen_initramfs_list.sh then the
+specified as an argument to usr/gen_initramfs.sh then the
 contents of the file are simply copied to the output.  All of the output
 directives from directory scanning and file contents copying are
 processed by usr/gen_init_cpio.
 
-See also 'usr/gen_initramfs_list.sh -h'.
+See also 'usr/gen_initramfs.sh -h'.
 
 Where's this all leading?
 =========================
diff --git a/Documentation/features/core/thread-info-in-task/arch-support.txt b/Documentation/features/core/thread-info-in-task/arch-support.txt
new file mode 100644 (file)
index 0000000..9f0259b
--- /dev/null
@@ -0,0 +1,32 @@
+#
+# Feature name:          thread-info-in-task
+#         Kconfig:       THREAD_INFO_IN_TASK
+#         description:   arch makes use of the core kernel facility to embedd thread_info in task_struct
+#
+    -----------------------
+    |         arch |status|
+    -----------------------
+    |       alpha: | TODO |
+    |         arc: | TODO |
+    |         arm: | TODO |
+    |       arm64: |  ok  |
+    |        csky: | TODO |
+    |       h8300: | TODO |
+    |     hexagon: | TODO |
+    |        ia64: | TODO |
+    |        m68k: | TODO |
+    |  microblaze: | TODO |
+    |        mips: | TODO |
+    |       nds32: |  ok  |
+    |       nios2: | TODO |
+    |    openrisc: | TODO |
+    |      parisc: | TODO |
+    |     powerpc: |  ok  |
+    |       riscv: |  ok  |
+    |        s390: |  ok  |
+    |          sh: | TODO |
+    |       sparc: | TODO |
+    |          um: | TODO |
+    |         x86: |  ok  |
+    |      xtensa: | TODO |
+    -----------------------
index 8639fe8..8dcaab0 100644 (file)
@@ -22,7 +22,7 @@
     |    openrisc: | TODO |
     |      parisc: | TODO |
     |     powerpc: |  ok  |
-    |       riscv: | TODO |
+    |       riscv: |  ok  |
     |        s390: | TODO |
     |          sh: |  ok  |
     |       sparc: | TODO |
index 4598b0d..1649606 100644 (file)
@@ -170,7 +170,7 @@ Documentation/driver-api/early-userspace/early_userspace_support.rst for more de
 The kernel does not depend on external cpio tools.  If you specify a
 directory instead of a configuration file, the kernel's build infrastructure
 creates a configuration file from that directory (usr/Makefile calls
-usr/gen_initramfs_list.sh), and proceeds to package up that directory
+usr/gen_initramfs.sh), and proceeds to package up that directory
 using the config file (by feeding it to usr/gen_init_cpio, which is created
 from usr/gen_init_cpio.c).  The kernel's build-time cpio creation code is
 entirely self-contained, and the kernel's boot-time extractor is also
index 6ea91e4..c86628e 100644 (file)
@@ -212,6 +212,7 @@ Userspace to kernel:
   ``ETHTOOL_MSG_FEC_SET``               set FEC settings
   ``ETHTOOL_MSG_MODULE_EEPROM_GET``     read SFP module EEPROM
   ``ETHTOOL_MSG_STATS_GET``             get standard statistics
+  ``ETHTOOL_MSG_PHC_VCLOCKS_GET``       get PHC virtual clocks info
   ===================================== ================================
 
 Kernel to userspace:
@@ -250,6 +251,7 @@ Kernel to userspace:
   ``ETHTOOL_MSG_FEC_NTF``                  FEC settings
   ``ETHTOOL_MSG_MODULE_EEPROM_GET_REPLY``  read SFP module EEPROM
   ``ETHTOOL_MSG_STATS_GET_REPLY``          standard statistics
+  ``ETHTOOL_MSG_PHC_VCLOCKS_GET_REPLY``    PHC virtual clocks info
   ======================================== =================================
 
 ``GET`` requests are sent by userspace applications to retrieve device
@@ -1477,6 +1479,25 @@ Low and high bounds are inclusive, for example:
  etherStatsPkts512to1023Octets 512  1023
  ============================= ==== ====
 
+PHC_VCLOCKS_GET
+===============
+
+Query device PHC virtual clocks information.
+
+Request contents:
+
+  ====================================  ======  ==========================
+  ``ETHTOOL_A_PHC_VCLOCKS_HEADER``      nested  request header
+  ====================================  ======  ==========================
+
+Kernel response contents:
+
+  ====================================  ======  ==========================
+  ``ETHTOOL_A_PHC_VCLOCKS_HEADER``      nested  reply header
+  ``ETHTOOL_A_PHC_VCLOCKS_NUM``         u32     PHC virtual clocks number
+  ``ETHTOOL_A_PHC_VCLOCKS_INDEX``       s32     PHC index array
+  ====================================  ======  ==========================
+
 Request translation
 ===================
 
@@ -1575,4 +1596,5 @@ are netlink only.
   n/a                                 ``ETHTOOL_MSG_CABLE_TEST_ACT``
   n/a                                 ``ETHTOOL_MSG_CABLE_TEST_TDR_ACT``
   n/a                                 ``ETHTOOL_MSG_TUNNEL_INFO_GET``
+  n/a                                 ``ETHTOOL_MSG_PHC_VCLOCKS_GET``
   =================================== =====================================
index 0467b30..d31ed6c 100644 (file)
@@ -110,6 +110,12 @@ nf_conntrack_tcp_be_liberal - BOOLEAN
        Be conservative in what you do, be liberal in what you accept from others.
        If it's non-zero, we mark only out of window RST segments as INVALID.
 
+nf_conntrack_tcp_ignore_invalid_rst - BOOLEAN
+       - 0 - disabled (default)
+       - 1 - enabled
+
+       If it's 1, we don't mark out of window RST segments as INVALID.
+
 nf_conntrack_tcp_loose - BOOLEAN
        - 0 - disabled
        - not 0 - enabled (default)
index 76775f2..ab63d29 100644 (file)
 Linux Kernel TIPC
 =================
 
-TIPC (Transparent Inter Process Communication) is a protocol that is
-specially designed for intra-cluster communication.
+Introduction
+============
 
-For more information about TIPC, see http://tipc.sourceforge.net.
+TIPC (Transparent Inter Process Communication) is a protocol that is specially
+designed for intra-cluster communication. It can be configured to transmit
+messages either on UDP or directly across Ethernet. Message delivery is
+sequence guaranteed, loss free and flow controlled. Latency times are shorter
+than with any other known protocol, while maximal throughput is comparable to
+that of TCP.
+
+TIPC Features
+-------------
+
+- Cluster wide IPC service
+
+  Have you ever wished you had the convenience of Unix Domain Sockets even when
+  transmitting data between cluster nodes? Where you yourself determine the
+  addresses you want to bind to and use? Where you don't have to perform DNS
+  lookups and worry about IP addresses? Where you don't have to start timers
+  to monitor the continuous existence of peer sockets? And yet without the
+  downsides of that socket type, such as the risk of lingering inodes?
+
+  Welcome to the Transparent Inter Process Communication service, TIPC in short,
+  which gives you all of this, and a lot more.
+
+- Service Addressing
+
+  A fundamental concept in TIPC is that of Service Addressing which makes it
+  possible for a programmer to chose his own address, bind it to a server
+  socket and let client programs use only that address for sending messages.
+
+- Service Tracking
+
+  A client wanting to wait for the availability of a server, uses the Service
+  Tracking mechanism to subscribe for binding and unbinding/close events for
+  sockets with the associated service address.
+
+  The service tracking mechanism can also be used for Cluster Topology Tracking,
+  i.e., subscribing for availability/non-availability of cluster nodes.
+
+  Likewise, the service tracking mechanism can be used for Cluster Connectivity
+  Tracking, i.e., subscribing for up/down events for individual links between
+  cluster nodes.
+
+- Transmission Modes
+
+  Using a service address, a client can send datagram messages to a server socket.
+
+  Using the same address type, it can establish a connection towards an accepting
+  server socket.
+
+  It can also use a service address to create and join a Communication Group,
+  which is the TIPC manifestation of a brokerless message bus.
+
+  Multicast with very good performance and scalability is available both in
+  datagram mode and in communication group mode.
+
+- Inter Node Links
+
+  Communication between any two nodes in a cluster is maintained by one or two
+  Inter Node Links, which both guarantee data traffic integrity and monitor
+  the peer node's availability.
+
+- Cluster Scalability
+
+  By applying the Overlapping Ring Monitoring algorithm on the inter node links
+  it is possible to scale TIPC clusters up to 1000 nodes with a maintained
+  neighbor failure discovery time of 1-2 seconds. For smaller clusters this
+  time can be made much shorter.
+
+- Neighbor Discovery
+
+  Neighbor Node Discovery in the cluster is done by Ethernet broadcast or UDP
+  multicast, when any of those services are available. If not, configured peer
+  IP addresses can be used.
+
+- Configuration
+
+  When running TIPC in single node mode no configuration whatsoever is needed.
+  When running in cluster mode TIPC must as a minimum be given a node address
+  (before Linux 4.17) and told which interface to attach to. The "tipc"
+  configuration tool makes is possible to add and maintain many more
+  configuration parameters.
+
+- Performance
+
+  TIPC message transfer latency times are better than in any other known protocol.
+  Maximal byte throughput for inter-node connections is still somewhat lower than
+  for TCP, while they are superior for intra-node and inter-container throughput
+  on the same host.
+
+- Language Support
+
+  The TIPC user API has support for C, Python, Perl, Ruby, D and Go.
+
+More Information
+----------------
+
+- How to set up TIPC:
+
+  http://tipc.io/getting_started.html
+
+- How to program with TIPC:
+
+  http://tipc.io/programming.html
+
+- How to contribute to TIPC:
+
+- http://tipc.io/contacts.html
+
+- More details about TIPC specification:
+
+  http://tipc.io/protocol.html
+
+
+Implementation
+==============
+
+TIPC is implemented as a kernel module in net/tipc/ directory.
 
 TIPC Base Types
 ---------------
index 229629e..4a6ed02 100644 (file)
@@ -47,7 +47,7 @@
 (顺便说一句,值得注意的是,合并窗口期间集成的更改并不是凭空产生的;它们是经
 提前收集、测试和分级的。稍后将详细描述该过程的工作方式。)
 
-合并窗口持续大约两周。在这段时间结束时,LinusTorvalds将声明窗口已关闭,并
+合并窗口持续大约两周。在这段时间结束时,Linus Torvalds将声明窗口已关闭,并
 释放第一个“rc”内核。例如,对于目标为5.6的内核,在合并窗口结束时发生的释放
 将被称为5.6-rc1。-rc1 版本是一个信号,表示合并新特性的时间已经过去,稳定下一
 个内核的时间已经到来。
@@ -168,7 +168,7 @@ Greg Kroah-Hartman领导。稳定团队将使用5.x.y编号方案不定期地发
 补丁如何进入内核
 ----------------
 
-只有一个人可以将补丁合并到主线内核存储库中:LinusTorvalds。但是,在进入
+只有一个人可以将补丁合并到主线内核存储库中:Linus Torvalds。但是,在进入
 2.6.38内核的9500多个补丁中,只有112个(大约1.3%)是由Linus自己直接选择的。
 内核项目已经发展到一个没有一个开发人员可以在没有支持的情况下检查和选择每个
 补丁的规模。内核开发人员处理这种增长的方式是使用围绕信任链构建的助理系统。
index 45a81b8..869cad3 100644 (file)
@@ -392,7 +392,7 @@ Section 8 -- Interpretation.
 Creative Commons is not a party to its public
 licenses. Notwithstanding, Creative Commons may elect to apply one of
 its public licenses to material it publishes and in those instances
-will be considered the “Licensor.” The text of the Creative Commons
+will be considered the "Licensor." The text of the Creative Commons
 public licenses is dedicated to the public domain under the CC0 Public
 Domain Dedication. Except for the limited purpose of indicating that
 material is shared under a Creative Commons public license or as
index a61f4f3..6c8be73 100644 (file)
@@ -933,6 +933,7 @@ F:  drivers/video/fbdev/geode/
 
 AMD IOMMU (AMD-VI)
 M:     Joerg Roedel <joro@8bytes.org>
+R:     Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
 L:     iommu@lists.linux-foundation.org
 S:     Maintained
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu.git
@@ -15009,6 +15010,13 @@ F:     drivers/net/phy/dp83640*
 F:     drivers/ptp/*
 F:     include/linux/ptp_cl*
 
+PTP VIRTUAL CLOCK SUPPORT
+M:     Yangbo Lu <yangbo.lu@nxp.com>
+L:     netdev@vger.kernel.org
+S:     Maintained
+F:     drivers/ptp/ptp_vclock.c
+F:     net/ethtool/phc_vclocks.c
+
 PTRACE SUPPORT
 M:     Oleg Nesterov <oleg@redhat.com>
 S:     Maintained
index c3f9bd1..e4f5895 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -2,7 +2,7 @@
 VERSION = 5
 PATCHLEVEL = 14
 SUBLEVEL = 0
-EXTRAVERSION = -rc1
+EXTRAVERSION = -rc2
 NAME = Opossums on Parade
 
 # *DOCUMENTATION*
@@ -728,11 +728,12 @@ $(KCONFIG_CONFIG):
 # This exploits the 'multi-target pattern rule' trick.
 # The syncconfig should be executed only once to make all the targets.
 # (Note: use the grouped target '&:' when we bump to GNU Make 4.3)
-quiet_cmd_syncconfig = SYNC    $@
-      cmd_syncconfig = $(MAKE) -f $(srctree)/Makefile syncconfig
-
+#
+# Do not use $(call cmd,...) here. That would suppress prompts from syncconfig,
+# so you cannot notice that Kconfig is waiting for the user input.
 %/config/auto.conf %/config/auto.conf.cmd %/generated/autoconf.h: $(KCONFIG_CONFIG)
-       +$(call cmd,syncconfig)
+       $(Q)$(kecho) "  SYNC    $@"
+       $(Q)$(MAKE) -f $(srctree)/Makefile syncconfig
 else # !may-sync-config
 # External modules and some install targets need include/generated/autoconf.h
 # and include/config/auto.conf but do not care if they are up-to-date.
@@ -802,7 +803,7 @@ else
 # Warn about unmarked fall-throughs in switch statement.
 # Disabled for clang while comment to attribute conversion happens and
 # https://github.com/ClangBuiltLinux/linux/issues/636 is discussed.
-KBUILD_CFLAGS += $(call cc-option,-Wimplicit-fallthrough,)
+KBUILD_CFLAGS += $(call cc-option,-Wimplicit-fallthrough=5,)
 endif
 
 # These warnings generated too much noise in a regular build.
index 3ea1c41..82f908f 100644 (file)
@@ -395,7 +395,7 @@ config ARCH_IXP4XX
        select IXP4XX_IRQ
        select IXP4XX_TIMER
        # With the new PCI driver this is not needed
-       select NEED_MACH_IO_H if PCI_IXP4XX_LEGACY
+       select NEED_MACH_IO_H if IXP4XX_PCI_LEGACY
        select USB_EHCI_BIG_ENDIAN_DESC
        select USB_EHCI_BIG_ENDIAN_MMIO
        help
index 33e413c..9b4cf5e 100644 (file)
@@ -4,6 +4,7 @@
 #include "aspeed-g5.dtsi"
 #include <dt-bindings/gpio/aspeed-gpio.h>
 #include <dt-bindings/i2c/i2c.h>
+#include <dt-bindings/interrupt-controller/irq.h>
 
 /{
        model = "ASRock E3C246D4I BMC";
@@ -73,7 +74,8 @@
 
 &vuart {
        status = "okay";
-       aspeed,sirq-active-high;
+       aspeed,lpc-io-reg = <0x2f8>;
+       aspeed,lpc-interrupts = <3 IRQ_TYPE_LEVEL_HIGH>;
 };
 
 &mac0 {
index d26a9e1..aa24cac 100644 (file)
                reg = <0x69>;
        };
 
-       power-supply@6a {
+       power-supply@6b {
                compatible = "ibm,cffps";
-               reg = <0x6a>;
+               reg = <0x6b>;
        };
 
-       power-supply@6b {
+       power-supply@6d {
                compatible = "ibm,cffps";
-               reg = <0x6b>;
+               reg = <0x6d>;
        };
 };
 
 
 &emmc {
        status = "okay";
+       clk-phase-mmc-hs200 = <180>, <180>;
 };
 
 &fsim0 {
index 941c048..481d0ee 100644 (file)
        /*W0-W7*/       "","","","","","","","",
        /*X0-X7*/       "","","","","","","","",
        /*Y0-Y7*/       "","","","","","","","",
-       /*Z0-Z7*/       "","","","","","","","",
-       /*AA0-AA7*/     "","","","","","","","",
-       /*AB0-AB7*/     "","","","","","","","",
-       /*AC0-AC7*/     "","","","","","","","";
+       /*Z0-Z7*/       "","","","","","","","";
 
        pin_mclr_vpp {
                gpio-hog;
index e863ec0..e33153d 100644 (file)
        /*W0-W7*/       "","","","","","","","",
        /*X0-X7*/       "","","","","","","","",
        /*Y0-Y7*/       "","","","","","","","",
-       /*Z0-Z7*/       "","","","","","","","",
-       /*AA0-AA7*/     "","","","","","","","",
-       /*AB0-AB7*/     "","","","","","","","",
-       /*AC0-AC7*/     "","","","","","","","";
+       /*Z0-Z7*/       "","","","","","","","";
 };
 
 &fmc {
 
 &emmc {
        status = "okay";
+       clk-phase-mmc-hs200 = <36>, <270>;
 };
 
 &fsim0 {
index dace8ff..0a4ffd1 100644 (file)
                         * EBI2. This has a 25MHz chrystal next to it, so no
                         * clocking is needed.
                         */
-                       ethernet-ebi2@2,0 {
+                       ethernet@2,0 {
                                compatible = "smsc,lan9221", "smsc,lan9115";
                                reg = <2 0x0 0x100>;
                                /*
                                phy-mode = "mii";
                                reg-io-width = <2>;
                                smsc,force-external-phy;
-                               /* IRQ on edge falling = active low */
-                               smsc,irq-active-low;
                                smsc,irq-push-pull;
 
                                /*
index 37bd41f..151c022 100644 (file)
                #size-cells = <1>;
                ranges;
 
-               vic: intc@10140000 {
+               vic: interrupt-controller@10140000 {
                        compatible = "arm,versatile-vic";
                        interrupt-controller;
                        #interrupt-cells = <1>;
                        reg = <0x10140000 0x1000>;
-                       clear-mask = <0xffffffff>;
                        valid-mask = <0xffffffff>;
                };
 
-               sic: intc@10003000 {
+               sic: interrupt-controller@10003000 {
                        compatible = "arm,versatile-sic";
                        interrupt-controller;
                        #interrupt-cells = <1>;
index 06a0fdf..e7e751a 100644 (file)
@@ -7,7 +7,7 @@
 
        amba {
                /* The Versatile PB is using more SIC IRQ lines than the AB */
-               sic: intc@10003000 {
+               sic: interrupt-controller@10003000 {
                        clear-mask = <0xffffffff>;
                        /*
                         * Valid interrupt lines mask according to
index b06e537..4dfe321 100644 (file)
@@ -57,10 +57,7 @@ CONFIG_DRM=y
 CONFIG_DRM_DISPLAY_CONNECTOR=y
 CONFIG_DRM_SIMPLE_BRIDGE=y
 CONFIG_DRM_PL111=y
-CONFIG_FB_MODE_HELPERS=y
-CONFIG_FB_MATROX=y
-CONFIG_FB_MATROX_MILLENIUM=y
-CONFIG_FB_MATROX_MYSTIQUE=y
+CONFIG_FB=y
 CONFIG_BACKLIGHT_CLASS_DEVICE=y
 # CONFIG_VGA_CONSOLE is not set
 CONFIG_LOGO=y
index 52a0400..d9abaae 100644 (file)
@@ -821,7 +821,7 @@ CONFIG_USB_ISP1760=y
 CONFIG_USB_HSIC_USB3503=y
 CONFIG_AB8500_USB=y
 CONFIG_KEYSTONE_USB_PHY=m
-CONFIG_NOP_USB_XCEIV=m
+CONFIG_NOP_USB_XCEIV=y
 CONFIG_AM335X_PHY_USB=m
 CONFIG_TWL6030_USB=m
 CONFIG_USB_GPIO_VBUS=y
index 483c400..4c01e31 100644 (file)
@@ -64,11 +64,9 @@ CONFIG_DRM_PANEL_SIMPLE=y
 CONFIG_DRM_DISPLAY_CONNECTOR=y
 CONFIG_DRM_SIMPLE_BRIDGE=y
 CONFIG_DRM_PL111=y
-CONFIG_FB_MODE_HELPERS=y
+CONFIG_FB=y
 CONFIG_BACKLIGHT_CLASS_DEVICE=y
 CONFIG_LOGO=y
-# CONFIG_LOGO_LINUX_MONO is not set
-# CONFIG_LOGO_LINUX_VGA16 is not set
 CONFIG_SOUND=y
 CONFIG_SND=y
 # CONFIG_SND_DRIVERS is not set
index 66c8b09..d9a27e4 100644 (file)
@@ -135,6 +135,7 @@ CONFIG_DRM_SII902X=y
 CONFIG_DRM_SIMPLE_BRIDGE=y
 CONFIG_DRM_I2C_ADV7511=y
 CONFIG_DRM_I2C_ADV7511_AUDIO=y
+CONFIG_FB=y
 CONFIG_FB_SH_MOBILE_LCDC=y
 CONFIG_BACKLIGHT_PWM=y
 CONFIG_BACKLIGHT_AS3711=y
index dbb1ef6..3b30913 100644 (file)
@@ -61,6 +61,10 @@ CONFIG_INPUT_TOUCHSCREEN=y
 CONFIG_TOUCHSCREEN_ATMEL_MXT=y
 CONFIG_TOUCHSCREEN_BU21013=y
 CONFIG_TOUCHSCREEN_CY8CTMA140=y
+CONFIG_TOUCHSCREEN_CYTTSP_CORE=y
+CONFIG_TOUCHSCREEN_CYTTSP_SPI=y
+CONFIG_TOUCHSCREEN_MMS114=y
+CONFIG_TOUCHSCREEN_ZINITIX=y
 CONFIG_INPUT_MISC=y
 CONFIG_INPUT_AB8500_PONKEY=y
 CONFIG_INPUT_GPIO_VIBRA=y
@@ -100,6 +104,7 @@ CONFIG_DRM_PANEL_SAMSUNG_S6E63M0_DSI=y
 CONFIG_DRM_PANEL_SONY_ACX424AKP=y
 CONFIG_DRM_LIMA=y
 CONFIG_DRM_MCDE=y
+CONFIG_FB=y
 CONFIG_BACKLIGHT_CLASS_DEVICE=y
 CONFIG_BACKLIGHT_KTD253=y
 CONFIG_BACKLIGHT_GPIO=y
index e7ecfb3..b703f47 100644 (file)
@@ -60,7 +60,7 @@ CONFIG_DRM_PANEL_SIMPLE=y
 CONFIG_DRM_DISPLAY_CONNECTOR=y
 CONFIG_DRM_SIMPLE_BRIDGE=y
 CONFIG_DRM_PL111=y
-CONFIG_FB_MODE_HELPERS=y
+CONFIG_FB=y
 CONFIG_BACKLIGHT_CLASS_DEVICE=y
 CONFIG_LOGO=y
 CONFIG_SOUND=y
@@ -88,8 +88,6 @@ CONFIG_NFSD=y
 CONFIG_NFSD_V3=y
 CONFIG_NLS_CODEPAGE_850=m
 CONFIG_NLS_ISO8859_1=m
-CONFIG_FONTS=y
-CONFIG_FONT_ACORN_8x8=y
 CONFIG_MAGIC_SYSRQ=y
 CONFIG_DEBUG_FS=y
 CONFIG_DEBUG_KERNEL=y
index 4479369..b5e246d 100644 (file)
@@ -11,9 +11,6 @@ CONFIG_CPUSETS=y
 # CONFIG_NET_NS is not set
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_PROFILING=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_BLK_DEV_BSG is not set
 CONFIG_ARCH_VEXPRESS=y
 CONFIG_ARCH_VEXPRESS_DCSCB=y
 CONFIG_ARCH_VEXPRESS_TC2_PM=y
@@ -23,14 +20,17 @@ CONFIG_MCPM=y
 CONFIG_VMSPLIT_2G=y
 CONFIG_NR_CPUS=8
 CONFIG_ARM_PSCI=y
-CONFIG_CMA=y
 CONFIG_ZBOOT_ROM_TEXT=0x0
 CONFIG_ZBOOT_ROM_BSS=0x0
 CONFIG_CMDLINE="console=ttyAMA0"
 CONFIG_CPU_IDLE=y
 CONFIG_VFP=y
 CONFIG_NEON=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_BLK_DEV_BSG is not set
 # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_CMA=y
 CONFIG_NET=y
 CONFIG_PACKET=y
 CONFIG_UNIX=y
@@ -43,7 +43,6 @@ CONFIG_IP_PNP_BOOTP=y
 CONFIG_NET_9P=y
 CONFIG_NET_9P_VIRTIO=y
 CONFIG_DEVTMPFS=y
-CONFIG_DMA_CMA=y
 CONFIG_MTD=y
 CONFIG_MTD_CMDLINE_PARTS=y
 CONFIG_MTD_BLOCK=y
@@ -59,7 +58,6 @@ CONFIG_VIRTIO_BLK=y
 CONFIG_BLK_DEV_SD=y
 CONFIG_SCSI_VIRTIO=y
 CONFIG_ATA=y
-# CONFIG_SATA_PMP is not set
 CONFIG_NETDEVICES=y
 CONFIG_VIRTIO_NET=y
 CONFIG_SMC91X=y
@@ -81,11 +79,9 @@ CONFIG_DRM=y
 CONFIG_DRM_PANEL_SIMPLE=y
 CONFIG_DRM_SII902X=y
 CONFIG_DRM_PL111=y
-CONFIG_FB_MODE_HELPERS=y
+CONFIG_FB=y
 CONFIG_BACKLIGHT_CLASS_DEVICE=y
 CONFIG_LOGO=y
-# CONFIG_LOGO_LINUX_MONO is not set
-# CONFIG_LOGO_LINUX_VGA16 is not set
 CONFIG_SOUND=y
 CONFIG_SND=y
 # CONFIG_SND_DRIVERS is not set
@@ -136,10 +132,11 @@ CONFIG_ROOT_NFS=y
 CONFIG_9P_FS=y
 CONFIG_NLS_CODEPAGE_437=y
 CONFIG_NLS_ISO8859_1=y
+# CONFIG_CRYPTO_HW is not set
+CONFIG_DMA_CMA=y
 CONFIG_DEBUG_INFO=y
 CONFIG_MAGIC_SYSRQ=y
 CONFIG_DEBUG_KERNEL=y
 CONFIG_DETECT_HUNG_TASK=y
 # CONFIG_SCHED_DEBUG is not set
 CONFIG_DEBUG_USER=y
-# CONFIG_CRYPTO_HW is not set
index e07e7de..b5b13a9 100644 (file)
@@ -1605,7 +1605,8 @@ config ARM64_BTI_KERNEL
        depends on CC_HAS_BRANCH_PROT_PAC_RET_BTI
        # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94697
        depends on !CC_IS_GCC || GCC_VERSION >= 100100
-       depends on !(CC_IS_CLANG && GCOV_KERNEL)
+       # https://github.com/llvm/llvm-project/commit/a88c722e687e6780dcd6a58718350dc76fcc4cc9
+       depends on !CC_IS_CLANG || CLANG_VERSION >= 120000
        depends on (!FUNCTION_GRAPH_TRACER || DYNAMIC_FTRACE_WITH_REGS)
        help
          Build the kernel with Branch Target Identification annotations
index b7d5328..076d5ef 100644 (file)
                                 <&bpmp TEGRA194_CLK_XUSB_SS>,
                                 <&bpmp TEGRA194_CLK_XUSB_FS>;
                        clock-names = "dev", "ss", "ss_src", "fs_src";
+                       interconnects = <&mc TEGRA194_MEMORY_CLIENT_XUSB_DEVR &emc>,
+                                       <&mc TEGRA194_MEMORY_CLIENT_XUSB_DEVW &emc>;
+                       interconnect-names = "dma-mem", "write";
+                       iommus = <&smmu TEGRA194_SID_XUSB_DEV>;
                        power-domains = <&bpmp TEGRA194_POWER_DOMAIN_XUSBB>,
                                        <&bpmp TEGRA194_POWER_DOMAIN_XUSBA>;
                        power-domain-names = "dev", "ss";
                                      "xusb_ss", "xusb_ss_src", "xusb_hs_src",
                                      "xusb_fs_src", "pll_u_480m", "clk_m",
                                      "pll_e";
+                       interconnects = <&mc TEGRA194_MEMORY_CLIENT_XUSB_HOSTR &emc>,
+                                       <&mc TEGRA194_MEMORY_CLIENT_XUSB_HOSTW &emc>;
+                       interconnect-names = "dma-mem", "write";
+                       iommus = <&smmu TEGRA194_SID_XUSB_HOST>;
 
                        power-domains = <&bpmp TEGRA194_POWER_DOMAIN_XUSBC>,
                                        <&bpmp TEGRA194_POWER_DOMAIN_XUSBA>;
                 * for 8x and 11.025x sample rate streams.
                 */
                assigned-clock-rates = <258000000>;
+
+               interconnects = <&mc TEGRA194_MEMORY_CLIENT_APEDMAR &emc>,
+                               <&mc TEGRA194_MEMORY_CLIENT_APEDMAW &emc>;
+               interconnect-names = "dma-mem", "write";
+               iommus = <&smmu TEGRA194_SID_APE>;
        };
 
        tcu: tcu {
index 734c8ad..01482d2 100644 (file)
                                     <GIC_SPI 384 IRQ_TYPE_LEVEL_HIGH>;
                        interrupt-names = "eri", "rxi", "txi",
                                          "bri", "dri", "tei";
-                       clocks = <&cpg CPG_MOD R9A07G044_CLK_SCIF0>;
+                       clocks = <&cpg CPG_MOD R9A07G044_SCIF0_CLK_PCK>;
                        clock-names = "fck";
                        power-domains = <&cpg>;
-                       resets = <&cpg R9A07G044_CLK_SCIF0>;
+                       resets = <&cpg R9A07G044_SCIF0_RST_SYSTEM_N>;
                        status = "disabled";
                };
 
index a9c0716..a074459 100644 (file)
@@ -47,7 +47,7 @@
  * cache before the transfer is done, causing old data to be seen by
  * the CPU.
  */
-#define ARCH_DMA_MINALIGN      L1_CACHE_BYTES
+#define ARCH_DMA_MINALIGN      (128)
 
 #ifdef CONFIG_KASAN_SW_TAGS
 #define ARCH_SLAB_MINALIGN     (1ULL << KASAN_SHADOW_SCALE_SHIFT)
index 99ad77d..97ddc6c 100644 (file)
@@ -10,6 +10,7 @@
 
 #include <linux/cpumask.h>
 
+#include <asm/smp.h>
 #include <asm/types.h>
 
 struct mpidr_hash {
index cce3085..3f1490b 100644 (file)
@@ -17,7 +17,7 @@ CFLAGS_syscall.o      += -fno-stack-protector
 # It's not safe to invoke KCOV when portions of the kernel environment aren't
 # available or are out-of-sync with HW state. Since `noinstr` doesn't always
 # inhibit KCOV instrumentation, disable it for the entire compilation unit.
-KCOV_INSTRUMENT_entry.o := n
+KCOV_INSTRUMENT_entry-common.o := n
 KCOV_INSTRUMENT_idle.o := n
 
 # Object file lists.
index 125d5c9..0ead8bf 100644 (file)
@@ -81,6 +81,7 @@
 #include <asm/mmu_context.h>
 #include <asm/mte.h>
 #include <asm/processor.h>
+#include <asm/smp.h>
 #include <asm/sysreg.h>
 #include <asm/traps.h>
 #include <asm/virt.h>
index 12ce14a..db8b2e2 100644 (file)
@@ -604,7 +604,7 @@ asmlinkage void noinstr el0t_64_fiq_handler(struct pt_regs *regs)
        __el0_fiq_handler_common(regs);
 }
 
-static void __el0_error_handler_common(struct pt_regs *regs)
+static void noinstr __el0_error_handler_common(struct pt_regs *regs)
 {
        unsigned long esr = read_sysreg(esr_el1);
 
index 69b3fde..36f51b0 100644 (file)
@@ -193,18 +193,6 @@ void mte_check_tfsr_el1(void)
 }
 #endif
 
-static void update_gcr_el1_excl(u64 excl)
-{
-
-       /*
-        * Note that the mask controlled by the user via prctl() is an
-        * include while GCR_EL1 accepts an exclude mask.
-        * No need for ISB since this only affects EL0 currently, implicit
-        * with ERET.
-        */
-       sysreg_clear_set_s(SYS_GCR_EL1, SYS_GCR_EL1_EXCL_MASK, excl);
-}
-
 static void set_gcr_el1_excl(u64 excl)
 {
        current->thread.gcr_user_excl = excl;
@@ -265,7 +253,8 @@ void mte_suspend_exit(void)
        if (!system_supports_mte())
                return;
 
-       update_gcr_el1_excl(gcr_kernel_excl);
+       sysreg_clear_set_s(SYS_GCR_EL1, SYS_GCR_EL1_EXCL_MASK, gcr_kernel_excl);
+       isb();
 }
 
 long set_mte_ctrl(struct task_struct *task, unsigned long arg)
index 95cd62d..2cf999e 100644 (file)
@@ -29,7 +29,7 @@
        .endm
 
        .macro ldrh1 reg, ptr, val
-       user_ldst 9998f, ldtrh, \reg, \ptr, \val
+       user_ldst 9997f, ldtrh, \reg, \ptr, \val
        .endm
 
        .macro strh1 reg, ptr, val
@@ -37,7 +37,7 @@
        .endm
 
        .macro ldr1 reg, ptr, val
-       user_ldst 9998f, ldtr, \reg, \ptr, \val
+       user_ldst 9997f, ldtr, \reg, \ptr, \val
        .endm
 
        .macro str1 reg, ptr, val
@@ -45,7 +45,7 @@
        .endm
 
        .macro ldp1 reg1, reg2, ptr, val
-       user_ldp 9998f, \reg1, \reg2, \ptr, \val
+       user_ldp 9997f, \reg1, \reg2, \ptr, \val
        .endm
 
        .macro stp1 reg1, reg2, ptr, val
        .endm
 
 end    .req    x5
+srcin  .req    x15
 SYM_FUNC_START(__arch_copy_from_user)
        add     end, x0, x2
+       mov     srcin, x1
 #include "copy_template.S"
        mov     x0, #0                          // Nothing to copy
        ret
@@ -63,6 +65,11 @@ EXPORT_SYMBOL(__arch_copy_from_user)
 
        .section .fixup,"ax"
        .align  2
+9997:  cmp     dst, dstin
+       b.ne    9998f
+       // Before being absolutely sure we couldn't copy anything, try harder
+USER(9998f, ldtrb tmp1w, [srcin])
+       strb    tmp1w, [dst], #1
 9998:  sub     x0, end, dst                    // bytes not copied
        ret
        .previous
index 1f61cd0..dbea379 100644 (file)
        .endm
 
        .macro ldrh1 reg, ptr, val
-       user_ldst 9998f, ldtrh, \reg, \ptr, \val
+       user_ldst 9997f, ldtrh, \reg, \ptr, \val
        .endm
 
        .macro strh1 reg, ptr, val
-       user_ldst 9998f, sttrh, \reg, \ptr, \val
+       user_ldst 9997f, sttrh, \reg, \ptr, \val
        .endm
 
        .macro ldr1 reg, ptr, val
-       user_ldst 9998f, ldtr, \reg, \ptr, \val
+       user_ldst 9997f, ldtr, \reg, \ptr, \val
        .endm
 
        .macro str1 reg, ptr, val
-       user_ldst 9998f, sttr, \reg, \ptr, \val
+       user_ldst 9997f, sttr, \reg, \ptr, \val
        .endm
 
        .macro ldp1 reg1, reg2, ptr, val
-       user_ldp 9998f, \reg1, \reg2, \ptr, \val
+       user_ldp 9997f, \reg1, \reg2, \ptr, \val
        .endm
 
        .macro stp1 reg1, reg2, ptr, val
-       user_stp 9998f, \reg1, \reg2, \ptr, \val
+       user_stp 9997f, \reg1, \reg2, \ptr, \val
        .endm
 
 end    .req    x5
-
+srcin  .req    x15
 SYM_FUNC_START(__arch_copy_in_user)
        add     end, x0, x2
+       mov     srcin, x1
 #include "copy_template.S"
        mov     x0, #0
        ret
@@ -65,6 +66,12 @@ EXPORT_SYMBOL(__arch_copy_in_user)
 
        .section .fixup,"ax"
        .align  2
+9997:  cmp     dst, dstin
+       b.ne    9998f
+       // Before being absolutely sure we couldn't copy anything, try harder
+USER(9998f, ldtrb tmp1w, [srcin])
+USER(9998f, sttrb tmp1w, [dst])
+       add     dst, dst, #1
 9998:  sub     x0, end, dst                    // bytes not copied
        ret
        .previous
index 043da90..9f380ee 100644 (file)
@@ -32,7 +32,7 @@
        .endm
 
        .macro strh1 reg, ptr, val
-       user_ldst 9998f, sttrh, \reg, \ptr, \val
+       user_ldst 9997f, sttrh, \reg, \ptr, \val
        .endm
 
        .macro ldr1 reg, ptr, val
@@ -40,7 +40,7 @@
        .endm
 
        .macro str1 reg, ptr, val
-       user_ldst 9998f, sttr, \reg, \ptr, \val
+       user_ldst 9997f, sttr, \reg, \ptr, \val
        .endm
 
        .macro ldp1 reg1, reg2, ptr, val
        .endm
 
        .macro stp1 reg1, reg2, ptr, val
-       user_stp 9998f, \reg1, \reg2, \ptr, \val
+       user_stp 9997f, \reg1, \reg2, \ptr, \val
        .endm
 
 end    .req    x5
+srcin  .req    x15
 SYM_FUNC_START(__arch_copy_to_user)
        add     end, x0, x2
+       mov     srcin, x1
 #include "copy_template.S"
        mov     x0, #0
        ret
@@ -62,6 +64,12 @@ EXPORT_SYMBOL(__arch_copy_to_user)
 
        .section .fixup,"ax"
        .align  2
+9997:  cmp     dst, dstin
+       b.ne    9998f
+       // Before being absolutely sure we couldn't copy anything, try harder
+       ldrb    tmp1w, [srcin]
+USER(9998f, sttrb tmp1w, [dst])
+       add     dst, dst, #1
 9998:  sub     x0, end, dst                    // bytes not copied
        ret
        .previous
index 35fbdb7..1648790 100644 (file)
@@ -8,6 +8,7 @@
 
 #include <linux/linkage.h>
 #include <asm/assembler.h>
+#include <asm/mte-def.h>
 
 /* Assumptions:
  *
 #define REP8_7f 0x7f7f7f7f7f7f7f7f
 #define REP8_80 0x8080808080808080
 
+/*
+ * When KASAN_HW_TAGS is in use, memory is checked at MTE_GRANULE_SIZE
+ * (16-byte) granularity, and we must ensure that no access straddles this
+ * alignment boundary.
+ */
+#ifdef CONFIG_KASAN_HW_TAGS
+#define MIN_PAGE_SIZE MTE_GRANULE_SIZE
+#else
 #define MIN_PAGE_SIZE 4096
+#endif
 
        /* Since strings are short on average, we check the first 16 bytes
           of the string for a NUL character.  In order to do an unaligned ldp
index 08f9dd6..86310d6 100644 (file)
@@ -76,7 +76,7 @@ static inline int __enable_fpu(enum fpu_mode mode)
                /* we only have a 32-bit FPU */
                return SIGFPE;
 #endif
-               fallthrough;
+               /* fallthrough */
        case FPU_32BIT:
                if (cpu_has_fre) {
                        /* clear FRE */
index cd4afcd..9adad24 100644 (file)
@@ -1383,6 +1383,7 @@ static void build_r4000_tlb_refill_handler(void)
        switch (boot_cpu_type()) {
        default:
                if (sizeof(long) == 4) {
+               fallthrough;
        case CPU_LOONGSON2EF:
                /* Loongson2 ebase is different than r4k, we have more space */
                        if ((p - tlb_handler) > 64)
@@ -2169,6 +2170,7 @@ static void build_r4000_tlb_load_handler(void)
                default:
                        if (cpu_has_mips_r2_exec_hazard) {
                                uasm_i_ehb(&p);
+                       fallthrough;
 
                case CPU_CAVIUM_OCTEON:
                case CPU_CAVIUM_OCTEON_PLUS:
index bdfea6d..3256a31 100644 (file)
@@ -146,6 +146,7 @@ static inline void psurge_clr_ipi(int cpu)
                switch(psurge_type) {
                case PSURGE_DUAL:
                        out_8(psurge_sec_intr, ~0);
+                       break;
                case PSURGE_NONE:
                        break;
                default:
index bbf8622..bd3ef12 100644 (file)
@@ -126,6 +126,7 @@ int arch_uprobe_exception_notify(struct notifier_block *self, unsigned long val,
        case DIE_SSTEP:
                if (uprobe_post_sstep_notifier(regs))
                        return NOTIFY_STOP;
+               break;
        default:
                break;
        }
index c42613c..739be5d 100644 (file)
@@ -765,7 +765,8 @@ static inline int __do_cpuid_func(struct kvm_cpuid_array *array, u32 function)
 
                edx.split.num_counters_fixed = min(cap.num_counters_fixed, MAX_FIXED_COUNTERS);
                edx.split.bit_width_fixed = cap.bit_width_fixed;
-               edx.split.anythread_deprecated = 1;
+               if (cap.version)
+                       edx.split.anythread_deprecated = 1;
                edx.split.reserved1 = 0;
                edx.split.reserved2 = 0;
 
@@ -940,8 +941,21 @@ static inline int __do_cpuid_func(struct kvm_cpuid_array *array, u32 function)
                unsigned virt_as = max((entry->eax >> 8) & 0xff, 48U);
                unsigned phys_as = entry->eax & 0xff;
 
-               if (!g_phys_as)
+               /*
+                * If TDP (NPT) is disabled use the adjusted host MAXPHYADDR as
+                * the guest operates in the same PA space as the host, i.e.
+                * reductions in MAXPHYADDR for memory encryption affect shadow
+                * paging, too.
+                *
+                * If TDP is enabled but an explicit guest MAXPHYADDR is not
+                * provided, use the raw bare metal MAXPHYADDR as reductions to
+                * the HPAs do not affect GPAs.
+                */
+               if (!tdp_enabled)
+                       g_phys_as = boot_cpu_data.x86_phys_bits;
+               else if (!g_phys_as)
                        g_phys_as = phys_as;
+
                entry->eax = g_phys_as | (virt_as << 8);
                entry->edx = 0;
                cpuid_entry_override(entry, CPUID_8000_0008_EBX);
@@ -964,12 +978,18 @@ static inline int __do_cpuid_func(struct kvm_cpuid_array *array, u32 function)
        case 0x8000001a:
        case 0x8000001e:
                break;
-       /* Support memory encryption cpuid if host supports it */
        case 0x8000001F:
-               if (!kvm_cpu_cap_has(X86_FEATURE_SEV))
+               if (!kvm_cpu_cap_has(X86_FEATURE_SEV)) {
                        entry->eax = entry->ebx = entry->ecx = entry->edx = 0;
-               else
+               } else {
                        cpuid_entry_override(entry, CPUID_8000_001F_EAX);
+
+                       /*
+                        * Enumerate '0' for "PA bits reduction", the adjusted
+                        * MAXPHYADDR is enumerated directly (see 0x80000008).
+                        */
+                       entry->ebx &= ~GENMASK(11, 6);
+               }
                break;
        /*Add support for Centaur's CPUID instruction*/
        case 0xC0000000:
index 845d114..66f7f5b 100644 (file)
@@ -53,6 +53,8 @@
 #include <asm/kvm_page_track.h>
 #include "trace.h"
 
+#include "paging.h"
+
 extern bool itlb_multihit_kvm_mitigation;
 
 int __read_mostly nx_huge_pages = -1;
diff --git a/arch/x86/kvm/mmu/paging.h b/arch/x86/kvm/mmu/paging.h
new file mode 100644 (file)
index 0000000..de8ab32
--- /dev/null
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/* Shadow paging constants/helpers that don't need to be #undef'd. */
+#ifndef __KVM_X86_PAGING_H
+#define __KVM_X86_PAGING_H
+
+#define GUEST_PT64_BASE_ADDR_MASK (((1ULL << 52) - 1) & ~(u64)(PAGE_SIZE-1))
+#define PT64_LVL_ADDR_MASK(level) \
+       (GUEST_PT64_BASE_ADDR_MASK & ~((1ULL << (PAGE_SHIFT + (((level) - 1) \
+                                               * PT64_LEVEL_BITS))) - 1))
+#define PT64_LVL_OFFSET_MASK(level) \
+       (GUEST_PT64_BASE_ADDR_MASK & ((1ULL << (PAGE_SHIFT + (((level) - 1) \
+                                               * PT64_LEVEL_BITS))) - 1))
+#endif /* __KVM_X86_PAGING_H */
+
index 490a028..ee044d3 100644 (file)
@@ -24,7 +24,7 @@
        #define pt_element_t u64
        #define guest_walker guest_walker64
        #define FNAME(name) paging##64_##name
-       #define PT_BASE_ADDR_MASK PT64_BASE_ADDR_MASK
+       #define PT_BASE_ADDR_MASK GUEST_PT64_BASE_ADDR_MASK
        #define PT_LVL_ADDR_MASK(lvl) PT64_LVL_ADDR_MASK(lvl)
        #define PT_LVL_OFFSET_MASK(lvl) PT64_LVL_OFFSET_MASK(lvl)
        #define PT_INDEX(addr, level) PT64_INDEX(addr, level)
@@ -57,7 +57,7 @@
        #define pt_element_t u64
        #define guest_walker guest_walkerEPT
        #define FNAME(name) ept_##name
-       #define PT_BASE_ADDR_MASK PT64_BASE_ADDR_MASK
+       #define PT_BASE_ADDR_MASK GUEST_PT64_BASE_ADDR_MASK
        #define PT_LVL_ADDR_MASK(lvl) PT64_LVL_ADDR_MASK(lvl)
        #define PT_LVL_OFFSET_MASK(lvl) PT64_LVL_OFFSET_MASK(lvl)
        #define PT_INDEX(addr, level) PT64_INDEX(addr, level)
index 7a5ce93..eb7b227 100644 (file)
@@ -38,12 +38,6 @@ static_assert(SPTE_TDP_AD_ENABLED_MASK == 0);
 #else
 #define PT64_BASE_ADDR_MASK (((1ULL << 52) - 1) & ~(u64)(PAGE_SIZE-1))
 #endif
-#define PT64_LVL_ADDR_MASK(level) \
-       (PT64_BASE_ADDR_MASK & ~((1ULL << (PAGE_SHIFT + (((level) - 1) \
-                                               * PT64_LEVEL_BITS))) - 1))
-#define PT64_LVL_OFFSET_MASK(level) \
-       (PT64_BASE_ADDR_MASK & ((1ULL << (PAGE_SHIFT + (((level) - 1) \
-                                               * PT64_LEVEL_BITS))) - 1))
 
 #define PT64_PERM_MASK (PT_PRESENT_MASK | PT_WRITABLE_MASK | shadow_user_mask \
                        | shadow_x_mask | shadow_nx_mask | shadow_me_mask)
index 21d03e3..3bd09c5 100644 (file)
@@ -154,6 +154,10 @@ void recalc_intercepts(struct vcpu_svm *svm)
 
        for (i = 0; i < MAX_INTERCEPT; i++)
                c->intercepts[i] |= g->intercepts[i];
+
+       /* If SMI is not intercepted, ignore guest SMI intercept as well  */
+       if (!intercept_smi)
+               vmcb_clr_intercept(c, INTERCEPT_SMI);
 }
 
 static void copy_vmcb_control_area(struct vmcb_control_area *dst,
@@ -304,8 +308,8 @@ static bool nested_vmcb_valid_sregs(struct kvm_vcpu *vcpu,
        return true;
 }
 
-static void nested_load_control_from_vmcb12(struct vcpu_svm *svm,
-                                           struct vmcb_control_area *control)
+void nested_load_control_from_vmcb12(struct vcpu_svm *svm,
+                                    struct vmcb_control_area *control)
 {
        copy_vmcb_control_area(&svm->nested.ctl, control);
 
@@ -618,6 +622,11 @@ int nested_svm_vmrun(struct kvm_vcpu *vcpu)
        struct kvm_host_map map;
        u64 vmcb12_gpa;
 
+       if (!svm->nested.hsave_msr) {
+               kvm_inject_gp(vcpu, 0);
+               return 1;
+       }
+
        if (is_smm(vcpu)) {
                kvm_queue_exception(vcpu, UD_VECTOR);
                return 1;
@@ -692,6 +701,27 @@ out:
        return ret;
 }
 
+/* Copy state save area fields which are handled by VMRUN */
+void svm_copy_vmrun_state(struct vmcb_save_area *from_save,
+                         struct vmcb_save_area *to_save)
+{
+       to_save->es = from_save->es;
+       to_save->cs = from_save->cs;
+       to_save->ss = from_save->ss;
+       to_save->ds = from_save->ds;
+       to_save->gdtr = from_save->gdtr;
+       to_save->idtr = from_save->idtr;
+       to_save->rflags = from_save->rflags | X86_EFLAGS_FIXED;
+       to_save->efer = from_save->efer;
+       to_save->cr0 = from_save->cr0;
+       to_save->cr3 = from_save->cr3;
+       to_save->cr4 = from_save->cr4;
+       to_save->rax = from_save->rax;
+       to_save->rsp = from_save->rsp;
+       to_save->rip = from_save->rip;
+       to_save->cpl = 0;
+}
+
 void nested_svm_vmloadsave(struct vmcb *from_vmcb, struct vmcb *to_vmcb)
 {
        to_vmcb->save.fs = from_vmcb->save.fs;
@@ -1355,28 +1385,11 @@ static int svm_set_nested_state(struct kvm_vcpu *vcpu,
 
        svm->nested.vmcb12_gpa = kvm_state->hdr.svm.vmcb_pa;
 
-       svm->vmcb01.ptr->save.es = save->es;
-       svm->vmcb01.ptr->save.cs = save->cs;
-       svm->vmcb01.ptr->save.ss = save->ss;
-       svm->vmcb01.ptr->save.ds = save->ds;
-       svm->vmcb01.ptr->save.gdtr = save->gdtr;
-       svm->vmcb01.ptr->save.idtr = save->idtr;
-       svm->vmcb01.ptr->save.rflags = save->rflags | X86_EFLAGS_FIXED;
-       svm->vmcb01.ptr->save.efer = save->efer;
-       svm->vmcb01.ptr->save.cr0 = save->cr0;
-       svm->vmcb01.ptr->save.cr3 = save->cr3;
-       svm->vmcb01.ptr->save.cr4 = save->cr4;
-       svm->vmcb01.ptr->save.rax = save->rax;
-       svm->vmcb01.ptr->save.rsp = save->rsp;
-       svm->vmcb01.ptr->save.rip = save->rip;
-       svm->vmcb01.ptr->save.cpl = 0;
-
+       svm_copy_vmrun_state(save, &svm->vmcb01.ptr->save);
        nested_load_control_from_vmcb12(svm, ctl);
 
        svm_switch_vmcb(svm, &svm->nested.vmcb02);
-
        nested_vmcb02_prepare_control(svm);
-
        kvm_make_request(KVM_REQ_GET_NESTED_STATE_PAGES, vcpu);
        ret = 0;
 out_free:
index 62926f1..6710d9e 100644 (file)
@@ -1272,8 +1272,8 @@ static int sev_send_update_data(struct kvm *kvm, struct kvm_sev_cmd *argp)
        /* Pin guest memory */
        guest_page = sev_pin_memory(kvm, params.guest_uaddr & PAGE_MASK,
                                    PAGE_SIZE, &n, 0);
-       if (!guest_page)
-               return -EFAULT;
+       if (IS_ERR(guest_page))
+               return PTR_ERR(guest_page);
 
        /* allocate memory for header and transport buffer */
        ret = -ENOMEM;
@@ -1310,8 +1310,9 @@ static int sev_send_update_data(struct kvm *kvm, struct kvm_sev_cmd *argp)
        }
 
        /* Copy packet header to userspace. */
-       ret = copy_to_user((void __user *)(uintptr_t)params.hdr_uaddr, hdr,
-                               params.hdr_len);
+       if (copy_to_user((void __user *)(uintptr_t)params.hdr_uaddr, hdr,
+                        params.hdr_len))
+               ret = -EFAULT;
 
 e_free_trans_data:
        kfree(trans_data);
@@ -1463,11 +1464,12 @@ static int sev_receive_update_data(struct kvm *kvm, struct kvm_sev_cmd *argp)
        data.trans_len = params.trans_len;
 
        /* Pin guest memory */
-       ret = -EFAULT;
        guest_page = sev_pin_memory(kvm, params.guest_uaddr & PAGE_MASK,
                                    PAGE_SIZE, &n, 0);
-       if (!guest_page)
+       if (IS_ERR(guest_page)) {
+               ret = PTR_ERR(guest_page);
                goto e_free_trans;
+       }
 
        /* The RECEIVE_UPDATE_DATA command requires C-bit to be always set. */
        data.guest_address = (page_to_pfn(guest_page[0]) << PAGE_SHIFT) + offset;
index 8834822..664d20f 100644 (file)
@@ -198,6 +198,11 @@ module_param(avic, bool, 0444);
 bool __read_mostly dump_invalid_vmcb;
 module_param(dump_invalid_vmcb, bool, 0644);
 
+
+bool intercept_smi = true;
+module_param(intercept_smi, bool, 0444);
+
+
 static bool svm_gp_erratum_intercept = true;
 
 static u8 rsm_ins_bytes[] = "\x0f\xaa";
@@ -1185,7 +1190,10 @@ static void init_vmcb(struct kvm_vcpu *vcpu)
 
        svm_set_intercept(svm, INTERCEPT_INTR);
        svm_set_intercept(svm, INTERCEPT_NMI);
-       svm_set_intercept(svm, INTERCEPT_SMI);
+
+       if (intercept_smi)
+               svm_set_intercept(svm, INTERCEPT_SMI);
+
        svm_set_intercept(svm, INTERCEPT_SELECTIVE_CR0);
        svm_set_intercept(svm, INTERCEPT_RDPMC);
        svm_set_intercept(svm, INTERCEPT_CPUID);
@@ -1923,7 +1931,7 @@ static int npf_interception(struct kvm_vcpu *vcpu)
 {
        struct vcpu_svm *svm = to_svm(vcpu);
 
-       u64 fault_address = __sme_clr(svm->vmcb->control.exit_info_2);
+       u64 fault_address = svm->vmcb->control.exit_info_2;
        u64 error_code = svm->vmcb->control.exit_info_1;
 
        trace_kvm_page_fault(fault_address, error_code);
@@ -2106,6 +2114,11 @@ static int nmi_interception(struct kvm_vcpu *vcpu)
        return 1;
 }
 
+static int smi_interception(struct kvm_vcpu *vcpu)
+{
+       return 1;
+}
+
 static int intr_interception(struct kvm_vcpu *vcpu)
 {
        ++vcpu->stat.irq_exits;
@@ -2941,7 +2954,16 @@ static int svm_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr)
                        svm_disable_lbrv(vcpu);
                break;
        case MSR_VM_HSAVE_PA:
-               svm->nested.hsave_msr = data;
+               /*
+                * Old kernels did not validate the value written to
+                * MSR_VM_HSAVE_PA.  Allow KVM_SET_MSR to set an invalid
+                * value to allow live migrating buggy or malicious guests
+                * originating from those kernels.
+                */
+               if (!msr->host_initiated && !page_address_valid(vcpu, data))
+                       return 1;
+
+               svm->nested.hsave_msr = data & PAGE_MASK;
                break;
        case MSR_VM_CR:
                return svm_set_vm_cr(vcpu, data);
@@ -3080,8 +3102,7 @@ static int (*const svm_exit_handlers[])(struct kvm_vcpu *vcpu) = {
        [SVM_EXIT_EXCP_BASE + GP_VECTOR]        = gp_interception,
        [SVM_EXIT_INTR]                         = intr_interception,
        [SVM_EXIT_NMI]                          = nmi_interception,
-       [SVM_EXIT_SMI]                          = kvm_emulate_as_nop,
-       [SVM_EXIT_INIT]                         = kvm_emulate_as_nop,
+       [SVM_EXIT_SMI]                          = smi_interception,
        [SVM_EXIT_VINTR]                        = interrupt_window_interception,
        [SVM_EXIT_RDPMC]                        = kvm_emulate_rdpmc,
        [SVM_EXIT_CPUID]                        = kvm_emulate_cpuid,
@@ -4288,6 +4309,7 @@ static int svm_smi_allowed(struct kvm_vcpu *vcpu, bool for_injection)
 static int svm_enter_smm(struct kvm_vcpu *vcpu, char *smstate)
 {
        struct vcpu_svm *svm = to_svm(vcpu);
+       struct kvm_host_map map_save;
        int ret;
 
        if (is_guest_mode(vcpu)) {
@@ -4303,6 +4325,29 @@ static int svm_enter_smm(struct kvm_vcpu *vcpu, char *smstate)
                ret = nested_svm_vmexit(svm);
                if (ret)
                        return ret;
+
+               /*
+                * KVM uses VMCB01 to store L1 host state while L2 runs but
+                * VMCB01 is going to be used during SMM and thus the state will
+                * be lost. Temporary save non-VMLOAD/VMSAVE state to the host save
+                * area pointed to by MSR_VM_HSAVE_PA. APM guarantees that the
+                * format of the area is identical to guest save area offsetted
+                * by 0x400 (matches the offset of 'struct vmcb_save_area'
+                * within 'struct vmcb'). Note: HSAVE area may also be used by
+                * L1 hypervisor to save additional host context (e.g. KVM does
+                * that, see svm_prepare_guest_switch()) which must be
+                * preserved.
+                */
+               if (kvm_vcpu_map(vcpu, gpa_to_gfn(svm->nested.hsave_msr),
+                                &map_save) == -EINVAL)
+                       return 1;
+
+               BUILD_BUG_ON(offsetof(struct vmcb, save) != 0x400);
+
+               svm_copy_vmrun_state(&svm->vmcb01.ptr->save,
+                                    map_save.hva + 0x400);
+
+               kvm_vcpu_unmap(vcpu, &map_save, true);
        }
        return 0;
 }
@@ -4310,13 +4355,14 @@ static int svm_enter_smm(struct kvm_vcpu *vcpu, char *smstate)
 static int svm_leave_smm(struct kvm_vcpu *vcpu, const char *smstate)
 {
        struct vcpu_svm *svm = to_svm(vcpu);
-       struct kvm_host_map map;
+       struct kvm_host_map map, map_save;
        int ret = 0;
 
        if (guest_cpuid_has(vcpu, X86_FEATURE_LM)) {
                u64 saved_efer = GET_SMSTATE(u64, smstate, 0x7ed0);
                u64 guest = GET_SMSTATE(u64, smstate, 0x7ed8);
                u64 vmcb12_gpa = GET_SMSTATE(u64, smstate, 0x7ee0);
+               struct vmcb *vmcb12;
 
                if (guest) {
                        if (!guest_cpuid_has(vcpu, X86_FEATURE_SVM))
@@ -4332,8 +4378,25 @@ static int svm_leave_smm(struct kvm_vcpu *vcpu, const char *smstate)
                        if (svm_allocate_nested(svm))
                                return 1;
 
-                       ret = enter_svm_guest_mode(vcpu, vmcb12_gpa, map.hva);
+                       vmcb12 = map.hva;
+
+                       nested_load_control_from_vmcb12(svm, &vmcb12->control);
+
+                       ret = enter_svm_guest_mode(vcpu, vmcb12_gpa, vmcb12);
                        kvm_vcpu_unmap(vcpu, &map, true);
+
+                       /*
+                        * Restore L1 host state from L1 HSAVE area as VMCB01 was
+                        * used during SMM (see svm_enter_smm())
+                        */
+                       if (kvm_vcpu_map(vcpu, gpa_to_gfn(svm->nested.hsave_msr),
+                                        &map_save) == -EINVAL)
+                               return 1;
+
+                       svm_copy_vmrun_state(map_save.hva + 0x400,
+                                            &svm->vmcb01.ptr->save);
+
+                       kvm_vcpu_unmap(vcpu, &map_save, true);
                }
        }
 
index f89b623..7e20907 100644 (file)
@@ -31,6 +31,7 @@
 #define MSRPM_OFFSETS  16
 extern u32 msrpm_offsets[MSRPM_OFFSETS] __read_mostly;
 extern bool npt_enabled;
+extern bool intercept_smi;
 
 /*
  * Clean bits in VMCB.
@@ -463,6 +464,8 @@ void svm_leave_nested(struct vcpu_svm *svm);
 void svm_free_nested(struct vcpu_svm *svm);
 int svm_allocate_nested(struct vcpu_svm *svm);
 int nested_svm_vmrun(struct kvm_vcpu *vcpu);
+void svm_copy_vmrun_state(struct vmcb_save_area *from_save,
+                         struct vmcb_save_area *to_save);
 void nested_svm_vmloadsave(struct vmcb *from_vmcb, struct vmcb *to_vmcb);
 int nested_svm_vmexit(struct vcpu_svm *svm);
 
@@ -479,6 +482,8 @@ int nested_svm_check_permissions(struct kvm_vcpu *vcpu);
 int nested_svm_check_exception(struct vcpu_svm *svm, unsigned nr,
                               bool has_error_code, u32 error_code);
 int nested_svm_exit_special(struct vcpu_svm *svm);
+void nested_load_control_from_vmcb12(struct vcpu_svm *svm,
+                                    struct vmcb_control_area *control);
 void nested_sync_control_from_vmcb02(struct vcpu_svm *svm);
 void nested_vmcb02_compute_g_pat(struct vcpu_svm *svm);
 void svm_switch_vmcb(struct vcpu_svm *svm, struct kvm_vmcb_info *target_vmcb);
index 3979a94..db88ed4 100644 (file)
@@ -14,8 +14,6 @@
 #include "vmx_ops.h"
 #include "cpuid.h"
 
-extern const u32 vmx_msr_index[];
-
 #define MSR_TYPE_R     1
 #define MSR_TYPE_W     2
 #define MSR_TYPE_RW    3
index c6dc1b4..a4fd106 100644 (file)
@@ -9601,6 +9601,8 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu)
                set_debugreg(vcpu->arch.eff_db[3], 3);
                set_debugreg(vcpu->arch.dr6, 6);
                vcpu->arch.switch_db_regs &= ~KVM_DEBUGREG_RELOAD;
+       } else if (unlikely(hw_breakpoint_active())) {
+               set_debugreg(0, 7);
        }
 
        for (;;) {
@@ -10985,9 +10987,6 @@ int kvm_arch_hardware_setup(void *opaque)
        int r;
 
        rdmsrl_safe(MSR_EFER, &host_efer);
-       if (WARN_ON_ONCE(boot_cpu_has(X86_FEATURE_NX) &&
-                        !(host_efer & EFER_NX)))
-               return -EIO;
 
        if (boot_cpu_has(X86_FEATURE_XSAVES))
                rdmsrl(MSR_IA32_XSS, host_xss);
index e835164..4b95145 100644 (file)
@@ -570,6 +570,9 @@ static void bpf_tail_call_direct_fixup(struct bpf_prog *prog)
 
        for (i = 0; i < prog->aux->size_poke_tab; i++) {
                poke = &prog->aux->poke_tab[i];
+               if (poke->aux && poke->aux != prog->aux)
+                       continue;
+
                WARN_ON_ONCE(READ_ONCE(poke->tailcall_target_stable));
 
                if (poke->reason != BPF_POKE_REASON_TAIL_CALL)
index 894b7e6..7f16307 100644 (file)
@@ -385,7 +385,9 @@ static struct platform_device *lpss_clk_dev;
 
 static inline void lpt_register_clock_device(void)
 {
-       lpss_clk_dev = platform_device_register_simple("clk-lpt", -1, NULL, 0);
+       lpss_clk_dev = platform_device_register_simple("clk-lpss-atom",
+                                                      PLATFORM_DEVID_NONE,
+                                                      NULL, 0);
 }
 
 static int register_device_clock(struct acpi_device *adev,
@@ -1337,7 +1339,7 @@ void __init acpi_lpss_init(void)
        const struct x86_cpu_id *id;
        int ret;
 
-       ret = lpt_clk_init();
+       ret = lpss_atom_clk_init();
        if (ret)
                return;
 
index 0251f3e..4110c19 100644 (file)
@@ -519,6 +519,23 @@ void pm_clk_destroy(struct device *dev)
 }
 EXPORT_SYMBOL_GPL(pm_clk_destroy);
 
+static void pm_clk_destroy_action(void *data)
+{
+       pm_clk_destroy(data);
+}
+
+int devm_pm_clk_create(struct device *dev)
+{
+       int ret;
+
+       ret = pm_clk_create(dev);
+       if (ret)
+               return ret;
+
+       return devm_add_action_or_reset(dev, pm_clk_destroy_action, dev);
+}
+EXPORT_SYMBOL_GPL(devm_pm_clk_create);
+
 /**
  * pm_clk_suspend - Disable clocks in a device's PM clock list.
  * @dev: Device to disable the clocks for.
index 8a66eaf..ec94049 100644 (file)
@@ -1447,6 +1447,23 @@ void pm_runtime_enable(struct device *dev)
 }
 EXPORT_SYMBOL_GPL(pm_runtime_enable);
 
+static void pm_runtime_disable_action(void *data)
+{
+       pm_runtime_disable(data);
+}
+
+/**
+ * devm_pm_runtime_enable - devres-enabled version of pm_runtime_enable.
+ * @dev: Device to handle.
+ */
+int devm_pm_runtime_enable(struct device *dev)
+{
+       pm_runtime_enable(dev);
+
+       return devm_add_action_or_reset(dev, pm_runtime_disable_action, dev);
+}
+EXPORT_SYMBOL_GPL(devm_pm_runtime_enable);
+
 /**
  * pm_runtime_forbid - Block runtime PM of a device.
  * @dev: Device to handle.
index b7d6637..c383179 100644 (file)
@@ -239,8 +239,8 @@ static void nbd_dev_remove(struct nbd_device *nbd)
 
        if (disk) {
                del_gendisk(disk);
-               blk_mq_free_tag_set(&nbd->tag_set);
                blk_cleanup_disk(disk);
+               blk_mq_free_tag_set(&nbd->tag_set);
        }
 
        /*
index 3b2b8e8..9b32989 100644 (file)
@@ -1014,8 +1014,8 @@ static void __exit pd_exit(void)
                if (p) {
                        disk->gd = NULL;
                        del_gendisk(p);
-                       blk_mq_free_tag_set(&disk->tag_set);
                        blk_cleanup_disk(p);
+                       blk_mq_free_tag_set(&disk->tag_set);
                        pi_release(disk->pi);
                }
        }
index 8d49f8f..d83fee2 100644 (file)
@@ -502,34 +502,21 @@ static int blkif_getgeo(struct block_device *bd, struct hd_geometry *hg)
 static int blkif_ioctl(struct block_device *bdev, fmode_t mode,
                       unsigned command, unsigned long argument)
 {
-       struct blkfront_info *info = bdev->bd_disk->private_data;
        int i;
 
-       dev_dbg(&info->xbdev->dev, "command: 0x%x, argument: 0x%lx\n",
-               command, (long)argument);
-
        switch (command) {
        case CDROMMULTISESSION:
-               dev_dbg(&info->xbdev->dev, "FIXME: support multisession CDs later\n");
                for (i = 0; i < sizeof(struct cdrom_multisession); i++)
                        if (put_user(0, (char __user *)(argument + i)))
                                return -EFAULT;
                return 0;
-
-       case CDROM_GET_CAPABILITY: {
-               struct gendisk *gd = info->gd;
-               if (gd->flags & GENHD_FL_CD)
+       case CDROM_GET_CAPABILITY:
+               if (bdev->bd_disk->flags & GENHD_FL_CD)
                        return 0;
                return -EINVAL;
-       }
-
        default:
-               /*printk(KERN_ALERT "ioctl %08x not supported by Xen blkdev\n",
-                 command);*/
-               return -EINVAL; /* same return as native Linux */
+               return -EINVAL;
        }
-
-       return 0;
 }
 
 static unsigned long blkif_ring_get_request(struct blkfront_ring_info *rinfo,
@@ -1177,36 +1164,6 @@ out_release_minors:
        return err;
 }
 
-static void xlvbd_release_gendisk(struct blkfront_info *info)
-{
-       unsigned int minor, nr_minors, i;
-       struct blkfront_ring_info *rinfo;
-
-       if (info->rq == NULL)
-               return;
-
-       /* No more blkif_request(). */
-       blk_mq_stop_hw_queues(info->rq);
-
-       for_each_rinfo(info, rinfo, i) {
-               /* No more gnttab callback work. */
-               gnttab_cancel_free_callback(&rinfo->callback);
-
-               /* Flush gnttab callback work. Must be done with no locks held. */
-               flush_work(&rinfo->work);
-       }
-
-       del_gendisk(info->gd);
-
-       minor = info->gd->first_minor;
-       nr_minors = info->gd->minors;
-       xlbd_release_minors(minor, nr_minors);
-
-       blk_cleanup_disk(info->gd);
-       info->gd = NULL;
-       blk_mq_free_tag_set(&info->tag_set);
-}
-
 /* Already hold rinfo->ring_lock. */
 static inline void kick_pending_request_queues_locked(struct blkfront_ring_info *rinfo)
 {
@@ -1756,12 +1713,6 @@ abort_transaction:
        return err;
 }
 
-static void free_info(struct blkfront_info *info)
-{
-       list_del(&info->info_list);
-       kfree(info);
-}
-
 /* Common code used when first setting up, and when resuming. */
 static int talk_to_blkback(struct xenbus_device *dev,
                           struct blkfront_info *info)
@@ -1880,13 +1831,6 @@ again:
                xenbus_dev_fatal(dev, err, "%s", message);
  destroy_blkring:
        blkif_free(info, 0);
-
-       mutex_lock(&blkfront_mutex);
-       free_info(info);
-       mutex_unlock(&blkfront_mutex);
-
-       dev_set_drvdata(&dev->dev, NULL);
-
        return err;
 }
 
@@ -2126,38 +2070,26 @@ static int blkfront_resume(struct xenbus_device *dev)
 static void blkfront_closing(struct blkfront_info *info)
 {
        struct xenbus_device *xbdev = info->xbdev;
-       struct block_device *bdev = NULL;
-
-       mutex_lock(&info->mutex);
+       struct blkfront_ring_info *rinfo;
+       unsigned int i;
 
-       if (xbdev->state == XenbusStateClosing) {
-               mutex_unlock(&info->mutex);
+       if (xbdev->state == XenbusStateClosing)
                return;
-       }
 
-       if (info->gd)
-               bdev = bdgrab(info->gd->part0);
-
-       mutex_unlock(&info->mutex);
-
-       if (!bdev) {
-               xenbus_frontend_closed(xbdev);
-               return;
-       }
+       /* No more blkif_request(). */
+       blk_mq_stop_hw_queues(info->rq);
+       blk_set_queue_dying(info->rq);
+       set_capacity(info->gd, 0);
 
-       mutex_lock(&bdev->bd_disk->open_mutex);
+       for_each_rinfo(info, rinfo, i) {
+               /* No more gnttab callback work. */
+               gnttab_cancel_free_callback(&rinfo->callback);
 
-       if (bdev->bd_openers) {
-               xenbus_dev_error(xbdev, -EBUSY,
-                                "Device in use; refusing to close");
-               xenbus_switch_state(xbdev, XenbusStateClosing);
-       } else {
-               xlvbd_release_gendisk(info);
-               xenbus_frontend_closed(xbdev);
+               /* Flush gnttab callback work. Must be done with no locks held. */
+               flush_work(&rinfo->work);
        }
 
-       mutex_unlock(&bdev->bd_disk->open_mutex);
-       bdput(bdev);
+       xenbus_frontend_closed(xbdev);
 }
 
 static void blkfront_setup_discard(struct blkfront_info *info)
@@ -2472,8 +2404,7 @@ static void blkback_changed(struct xenbus_device *dev,
                        break;
                fallthrough;
        case XenbusStateClosing:
-               if (info)
-                       blkfront_closing(info);
+               blkfront_closing(info);
                break;
        }
 }
@@ -2481,56 +2412,21 @@ static void blkback_changed(struct xenbus_device *dev,
 static int blkfront_remove(struct xenbus_device *xbdev)
 {
        struct blkfront_info *info = dev_get_drvdata(&xbdev->dev);
-       struct block_device *bdev = NULL;
-       struct gendisk *disk;
 
        dev_dbg(&xbdev->dev, "%s removed", xbdev->nodename);
 
-       if (!info)
-               return 0;
-
-       blkif_free(info, 0);
-
-       mutex_lock(&info->mutex);
-
-       disk = info->gd;
-       if (disk)
-               bdev = bdgrab(disk->part0);
-
-       info->xbdev = NULL;
-       mutex_unlock(&info->mutex);
-
-       if (!bdev) {
-               mutex_lock(&blkfront_mutex);
-               free_info(info);
-               mutex_unlock(&blkfront_mutex);
-               return 0;
-       }
-
-       /*
-        * The xbdev was removed before we reached the Closed
-        * state. See if it's safe to remove the disk. If the bdev
-        * isn't closed yet, we let release take care of it.
-        */
-
-       mutex_lock(&disk->open_mutex);
-       info = disk->private_data;
-
-       dev_warn(disk_to_dev(disk),
-                "%s was hot-unplugged, %d stale handles\n",
-                xbdev->nodename, bdev->bd_openers);
+       del_gendisk(info->gd);
 
-       if (info && !bdev->bd_openers) {
-               xlvbd_release_gendisk(info);
-               disk->private_data = NULL;
-               mutex_lock(&blkfront_mutex);
-               free_info(info);
-               mutex_unlock(&blkfront_mutex);
-       }
+       mutex_lock(&blkfront_mutex);
+       list_del(&info->info_list);
+       mutex_unlock(&blkfront_mutex);
 
-       mutex_unlock(&disk->open_mutex);
-       bdput(bdev);
+       blkif_free(info, 0);
+       xlbd_release_minors(info->gd->first_minor, info->gd->minors);
+       blk_cleanup_disk(info->gd);
+       blk_mq_free_tag_set(&info->tag_set);
 
+       kfree(info);
        return 0;
 }
 
@@ -2541,77 +2437,9 @@ static int blkfront_is_ready(struct xenbus_device *dev)
        return info->is_ready && info->xbdev;
 }
 
-static int blkif_open(struct block_device *bdev, fmode_t mode)
-{
-       struct gendisk *disk = bdev->bd_disk;
-       struct blkfront_info *info;
-       int err = 0;
-
-       mutex_lock(&blkfront_mutex);
-
-       info = disk->private_data;
-       if (!info) {
-               /* xbdev gone */
-               err = -ERESTARTSYS;
-               goto out;
-       }
-
-       mutex_lock(&info->mutex);
-
-       if (!info->gd)
-               /* xbdev is closed */
-               err = -ERESTARTSYS;
-
-       mutex_unlock(&info->mutex);
-
-out:
-       mutex_unlock(&blkfront_mutex);
-       return err;
-}
-
-static void blkif_release(struct gendisk *disk, fmode_t mode)
-{
-       struct blkfront_info *info = disk->private_data;
-       struct xenbus_device *xbdev;
-
-       mutex_lock(&blkfront_mutex);
-       if (disk->part0->bd_openers)
-               goto out_mutex;
-
-       /*
-        * Check if we have been instructed to close. We will have
-        * deferred this request, because the bdev was still open.
-        */
-
-       mutex_lock(&info->mutex);
-       xbdev = info->xbdev;
-
-       if (xbdev && xbdev->state == XenbusStateClosing) {
-               /* pending switch to state closed */
-               dev_info(disk_to_dev(disk), "releasing disk\n");
-               xlvbd_release_gendisk(info);
-               xenbus_frontend_closed(info->xbdev);
-       }
-
-       mutex_unlock(&info->mutex);
-
-       if (!xbdev) {
-               /* sudden device removal */
-               dev_info(disk_to_dev(disk), "releasing disk\n");
-               xlvbd_release_gendisk(info);
-               disk->private_data = NULL;
-               free_info(info);
-       }
-
-out_mutex:
-       mutex_unlock(&blkfront_mutex);
-}
-
 static const struct block_device_operations xlvbd_block_fops =
 {
        .owner = THIS_MODULE,
-       .open = blkif_open,
-       .release = blkif_release,
        .getgeo = blkif_getgeo,
        .ioctl = blkif_ioctl,
        .compat_ioctl = blkdev_compat_ptr_ioctl,
index 027484e..3c99696 100644 (file)
@@ -75,6 +75,7 @@ static int __op_panel_update_display(void)
                                rc);
                        break;
                }
+               break;
        case OPAL_SUCCESS:
                break;
        default:
index c7a3a02..8f02c0b 100644 (file)
@@ -269,23 +269,14 @@ static bool lmk04832_regmap_rd_regs(struct device *dev, unsigned int reg)
 {
        switch (reg) {
        case LMK04832_REG_RST3W ... LMK04832_REG_ID_MASKREV:
-               fallthrough;
        case LMK04832_REG_ID_VNDR_MSB:
-               fallthrough;
        case LMK04832_REG_ID_VNDR_LSB:
-               fallthrough;
        case LMK04832_REG_CLKOUT_CTRL0(0) ... LMK04832_REG_PLL2_DLD_CNT_LSB:
-               fallthrough;
        case LMK04832_REG_PLL2_LD:
-               fallthrough;
        case LMK04832_REG_PLL2_PD:
-               fallthrough;
        case LMK04832_REG_PLL1R_RST:
-               fallthrough;
        case LMK04832_REG_CLR_PLL_LOST ... LMK04832_REG_RB_DAC_VAL_LSB:
-               fallthrough;
        case LMK04832_REG_RB_HOLDOVER:
-               fallthrough;
        case LMK04832_REG_SPI_LOCK:
                return true;
        default:
@@ -297,27 +288,18 @@ static bool lmk04832_regmap_wr_regs(struct device *dev, unsigned int reg)
 {
        switch (reg) {
        case LMK04832_REG_RST3W:
-               fallthrough;
        case LMK04832_REG_POWERDOWN:
                return true;
        case LMK04832_REG_ID_DEV_TYPE ... LMK04832_REG_ID_MASKREV:
-               fallthrough;
        case LMK04832_REG_ID_VNDR_MSB:
-               fallthrough;
        case LMK04832_REG_ID_VNDR_LSB:
                return false;
        case LMK04832_REG_CLKOUT_CTRL0(0) ... LMK04832_REG_PLL2_DLD_CNT_LSB:
-               fallthrough;
        case LMK04832_REG_PLL2_LD:
-               fallthrough;
        case LMK04832_REG_PLL2_PD:
-               fallthrough;
        case LMK04832_REG_PLL1R_RST:
-               fallthrough;
        case LMK04832_REG_CLR_PLL_LOST ... LMK04832_REG_RB_DAC_VAL_LSB:
-               fallthrough;
        case LMK04832_REG_RB_HOLDOVER:
-               fallthrough;
        case LMK04832_REG_SPI_LOCK:
                return true;
        default:
index e41a3a9..b8c3d0d 100644 (file)
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Clock driver for Palmas device.
  *
@@ -6,15 +7,6 @@
  *
  * Author:     Laxman Dewangan <ldewangan@nvidia.com>
  *             Peter Ujfalusi <peter.ujfalusi@ti.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation version 2.
- *
- * This program is distributed "as is" WITHOUT ANY WARRANTY of any kind,
- * whether express or implied; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
  */
 
 #include <linux/clk.h>
index 886e2d9..439b7c8 100644 (file)
@@ -362,41 +362,36 @@ config COMMON_CLK_MT8167
 
 config COMMON_CLK_MT8167_AUDSYS
        bool "Clock driver for MediaTek MT8167 audsys"
-       depends on (ARCH_MEDIATEK && ARM64) || COMPILE_TEST
-       select COMMON_CLK_MEDIATEK
-       default ARCH_MEDIATEK
+       depends on COMMON_CLK_MT8167
+       default COMMON_CLK_MT8167
        help
          This driver supports MediaTek MT8167 audsys clocks.
 
 config COMMON_CLK_MT8167_IMGSYS
        bool "Clock driver for MediaTek MT8167 imgsys"
-       depends on (ARCH_MEDIATEK && ARM64) || COMPILE_TEST
-       select COMMON_CLK_MEDIATEK
-       default ARCH_MEDIATEK
+       depends on COMMON_CLK_MT8167
+       default COMMON_CLK_MT8167
        help
          This driver supports MediaTek MT8167 imgsys clocks.
 
 config COMMON_CLK_MT8167_MFGCFG
        bool "Clock driver for MediaTek MT8167 mfgcfg"
-       depends on (ARCH_MEDIATEK && ARM64) || COMPILE_TEST
-       select COMMON_CLK_MEDIATEK
-       default ARCH_MEDIATEK
+       depends on COMMON_CLK_MT8167
+       default COMMON_CLK_MT8167
        help
          This driver supports MediaTek MT8167 mfgcfg clocks.
 
 config COMMON_CLK_MT8167_MMSYS
        bool "Clock driver for MediaTek MT8167 mmsys"
-       depends on (ARCH_MEDIATEK && ARM64) || COMPILE_TEST
-       select COMMON_CLK_MEDIATEK
-       default ARCH_MEDIATEK
+       depends on COMMON_CLK_MT8167
+       default COMMON_CLK_MT8167
        help
          This driver supports MediaTek MT8167 mmsys clocks.
 
 config COMMON_CLK_MT8167_VDECSYS
        bool "Clock driver for MediaTek MT8167 vdecsys"
-       depends on (ARCH_MEDIATEK && ARM64) || COMPILE_TEST
-       select COMMON_CLK_MEDIATEK
-       default ARCH_MEDIATEK
+       depends on COMMON_CLK_MT8167
+       default COMMON_CLK_MT8167
        help
          This driver supports MediaTek MT8167 vdecsys clocks.
 
@@ -500,6 +495,86 @@ config COMMON_CLK_MT8183_VENCSYS
        help
          This driver supports MediaTek MT8183 vencsys clocks.
 
+config COMMON_CLK_MT8192
+       bool "Clock driver for MediaTek MT8192"
+       depends on ARM64 || COMPILE_TEST
+       select COMMON_CLK_MEDIATEK
+       default ARM64
+       help
+         This driver supports MediaTek MT8192 basic clocks.
+
+config COMMON_CLK_MT8192_AUDSYS
+       bool "Clock driver for MediaTek MT8192 audsys"
+       depends on COMMON_CLK_MT8192
+       help
+         This driver supports MediaTek MT8192 audsys clocks.
+
+config COMMON_CLK_MT8192_CAMSYS
+       bool "Clock driver for MediaTek MT8192 camsys"
+       depends on COMMON_CLK_MT8192
+       help
+         This driver supports MediaTek MT8192 camsys and camsys_raw clocks.
+
+config COMMON_CLK_MT8192_IMGSYS
+       bool "Clock driver for MediaTek MT8192 imgsys"
+       depends on COMMON_CLK_MT8192
+       help
+         This driver supports MediaTek MT8192 imgsys and imgsys2 clocks.
+
+config COMMON_CLK_MT8192_IMP_IIC_WRAP
+       bool "Clock driver for MediaTek MT8192 imp_iic_wrap"
+       depends on COMMON_CLK_MT8192
+       help
+         This driver supports MediaTek MT8192 imp_iic_wrap clocks.
+
+config COMMON_CLK_MT8192_IPESYS
+       bool "Clock driver for MediaTek MT8192 ipesys"
+       depends on COMMON_CLK_MT8192
+       help
+         This driver supports MediaTek MT8192 ipesys clocks.
+
+config COMMON_CLK_MT8192_MDPSYS
+       bool "Clock driver for MediaTek MT8192 mdpsys"
+       depends on COMMON_CLK_MT8192
+       help
+         This driver supports MediaTek MT8192 mdpsys clocks.
+
+config COMMON_CLK_MT8192_MFGCFG
+       bool "Clock driver for MediaTek MT8192 mfgcfg"
+       depends on COMMON_CLK_MT8192
+       help
+         This driver supports MediaTek MT8192 mfgcfg clocks.
+
+config COMMON_CLK_MT8192_MMSYS
+       bool "Clock driver for MediaTek MT8192 mmsys"
+       depends on COMMON_CLK_MT8192
+       help
+         This driver supports MediaTek MT8192 mmsys clocks.
+
+config COMMON_CLK_MT8192_MSDC
+       bool "Clock driver for MediaTek MT8192 msdc"
+       depends on COMMON_CLK_MT8192
+       help
+         This driver supports MediaTek MT8192 msdc and msdc_top clocks.
+
+config COMMON_CLK_MT8192_SCP_ADSP
+       bool "Clock driver for MediaTek MT8192 scp_adsp"
+       depends on COMMON_CLK_MT8192
+       help
+         This driver supports MediaTek MT8192 scp_adsp clocks.
+
+config COMMON_CLK_MT8192_VDECSYS
+       bool "Clock driver for MediaTek MT8192 vdecsys"
+       depends on COMMON_CLK_MT8192
+       help
+         This driver supports MediaTek MT8192 vdecsys and vdecsys_soc clocks.
+
+config COMMON_CLK_MT8192_VENCSYS
+       bool "Clock driver for MediaTek MT8192 vencsys"
+       depends on COMMON_CLK_MT8192
+       help
+         This driver supports MediaTek MT8192 vencsys clocks.
+
 config COMMON_CLK_MT8516
        bool "Clock driver for MediaTek MT8516"
        depends on ARCH_MEDIATEK || COMPILE_TEST
index 3b0c2be..15bc045 100644 (file)
@@ -67,5 +67,18 @@ obj-$(CONFIG_COMMON_CLK_MT8183_MFGCFG) += clk-mt8183-mfgcfg.o
 obj-$(CONFIG_COMMON_CLK_MT8183_MMSYS) += clk-mt8183-mm.o
 obj-$(CONFIG_COMMON_CLK_MT8183_VDECSYS) += clk-mt8183-vdec.o
 obj-$(CONFIG_COMMON_CLK_MT8183_VENCSYS) += clk-mt8183-venc.o
+obj-$(CONFIG_COMMON_CLK_MT8192) += clk-mt8192.o
+obj-$(CONFIG_COMMON_CLK_MT8192_AUDSYS) += clk-mt8192-aud.o
+obj-$(CONFIG_COMMON_CLK_MT8192_CAMSYS) += clk-mt8192-cam.o
+obj-$(CONFIG_COMMON_CLK_MT8192_IMGSYS) += clk-mt8192-img.o
+obj-$(CONFIG_COMMON_CLK_MT8192_IMP_IIC_WRAP) += clk-mt8192-imp_iic_wrap.o
+obj-$(CONFIG_COMMON_CLK_MT8192_IPESYS) += clk-mt8192-ipe.o
+obj-$(CONFIG_COMMON_CLK_MT8192_MDPSYS) += clk-mt8192-mdp.o
+obj-$(CONFIG_COMMON_CLK_MT8192_MFGCFG) += clk-mt8192-mfg.o
+obj-$(CONFIG_COMMON_CLK_MT8192_MMSYS) += clk-mt8192-mm.o
+obj-$(CONFIG_COMMON_CLK_MT8192_MSDC) += clk-mt8192-msdc.o
+obj-$(CONFIG_COMMON_CLK_MT8192_SCP_ADSP) += clk-mt8192-scp_adsp.o
+obj-$(CONFIG_COMMON_CLK_MT8192_VDECSYS) += clk-mt8192-vdec.o
+obj-$(CONFIG_COMMON_CLK_MT8192_VENCSYS) += clk-mt8192-venc.o
 obj-$(CONFIG_COMMON_CLK_MT8516) += clk-mt8516.o
 obj-$(CONFIG_COMMON_CLK_MT8516_AUDSYS) += clk-mt8516-aud.o
index 79fe090..61eeae4 100644 (file)
@@ -84,7 +84,7 @@ int mtk_clk_register_cpumuxes(struct device_node *node,
        struct clk *clk;
        struct regmap *regmap;
 
-       regmap = syscon_node_to_regmap(node);
+       regmap = device_node_to_regmap(node);
        if (IS_ERR(regmap)) {
                pr_err("Cannot find regmap for %pOF: %ld\n", node,
                       PTR_ERR(regmap));
diff --git a/drivers/clk/mediatek/clk-mt8192-aud.c b/drivers/clk/mediatek/clk-mt8192-aud.c
new file mode 100644 (file)
index 0000000..f28d566
--- /dev/null
@@ -0,0 +1,118 @@
+// SPDX-License-Identifier: GPL-2.0-only
+//
+// Copyright (c) 2021 MediaTek Inc.
+// Author: Chun-Jie Chen <chun-jie.chen@mediatek.com>
+
+#include <linux/clk-provider.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+
+#include "clk-mtk.h"
+#include "clk-gate.h"
+
+#include <dt-bindings/clock/mt8192-clk.h>
+
+static const struct mtk_gate_regs aud0_cg_regs = {
+       .set_ofs = 0x0,
+       .clr_ofs = 0x0,
+       .sta_ofs = 0x0,
+};
+
+static const struct mtk_gate_regs aud1_cg_regs = {
+       .set_ofs = 0x4,
+       .clr_ofs = 0x4,
+       .sta_ofs = 0x4,
+};
+
+static const struct mtk_gate_regs aud2_cg_regs = {
+       .set_ofs = 0x8,
+       .clr_ofs = 0x8,
+       .sta_ofs = 0x8,
+};
+
+#define GATE_AUD0(_id, _name, _parent, _shift) \
+       GATE_MTK(_id, _name, _parent, &aud0_cg_regs, _shift, &mtk_clk_gate_ops_no_setclr)
+
+#define GATE_AUD1(_id, _name, _parent, _shift) \
+       GATE_MTK(_id, _name, _parent, &aud1_cg_regs, _shift, &mtk_clk_gate_ops_no_setclr)
+
+#define GATE_AUD2(_id, _name, _parent, _shift) \
+       GATE_MTK(_id, _name, _parent, &aud2_cg_regs, _shift, &mtk_clk_gate_ops_no_setclr)
+
+static const struct mtk_gate aud_clks[] = {
+       /* AUD0 */
+       GATE_AUD0(CLK_AUD_AFE, "aud_afe", "audio_sel", 2),
+       GATE_AUD0(CLK_AUD_22M, "aud_22m", "aud_engen1_sel", 8),
+       GATE_AUD0(CLK_AUD_24M, "aud_24m", "aud_engen2_sel", 9),
+       GATE_AUD0(CLK_AUD_APLL2_TUNER, "aud_apll2_tuner", "aud_engen2_sel", 18),
+       GATE_AUD0(CLK_AUD_APLL_TUNER, "aud_apll_tuner", "aud_engen1_sel", 19),
+       GATE_AUD0(CLK_AUD_TDM, "aud_tdm", "aud_1_sel", 20),
+       GATE_AUD0(CLK_AUD_ADC, "aud_adc", "audio_sel", 24),
+       GATE_AUD0(CLK_AUD_DAC, "aud_dac", "audio_sel", 25),
+       GATE_AUD0(CLK_AUD_DAC_PREDIS, "aud_dac_predis", "audio_sel", 26),
+       GATE_AUD0(CLK_AUD_TML, "aud_tml", "audio_sel", 27),
+       GATE_AUD0(CLK_AUD_NLE, "aud_nle", "audio_sel", 28),
+       /* AUD1 */
+       GATE_AUD1(CLK_AUD_I2S1_B, "aud_i2s1_b", "audio_sel", 4),
+       GATE_AUD1(CLK_AUD_I2S2_B, "aud_i2s2_b", "audio_sel", 5),
+       GATE_AUD1(CLK_AUD_I2S3_B, "aud_i2s3_b", "audio_sel", 6),
+       GATE_AUD1(CLK_AUD_I2S4_B, "aud_i2s4_b", "audio_sel", 7),
+       GATE_AUD1(CLK_AUD_CONNSYS_I2S_ASRC, "aud_connsys_i2s_asrc", "audio_sel", 12),
+       GATE_AUD1(CLK_AUD_GENERAL1_ASRC, "aud_general1_asrc", "audio_sel", 13),
+       GATE_AUD1(CLK_AUD_GENERAL2_ASRC, "aud_general2_asrc", "audio_sel", 14),
+       GATE_AUD1(CLK_AUD_DAC_HIRES, "aud_dac_hires", "audio_h_sel", 15),
+       GATE_AUD1(CLK_AUD_ADC_HIRES, "aud_adc_hires", "audio_h_sel", 16),
+       GATE_AUD1(CLK_AUD_ADC_HIRES_TML, "aud_adc_hires_tml", "audio_h_sel", 17),
+       GATE_AUD1(CLK_AUD_ADDA6_ADC, "aud_adda6_adc", "audio_sel", 20),
+       GATE_AUD1(CLK_AUD_ADDA6_ADC_HIRES, "aud_adda6_adc_hires", "audio_h_sel", 21),
+       GATE_AUD1(CLK_AUD_3RD_DAC, "aud_3rd_dac", "audio_sel", 28),
+       GATE_AUD1(CLK_AUD_3RD_DAC_PREDIS, "aud_3rd_dac_predis", "audio_sel", 29),
+       GATE_AUD1(CLK_AUD_3RD_DAC_TML, "aud_3rd_dac_tml", "audio_sel", 30),
+       GATE_AUD1(CLK_AUD_3RD_DAC_HIRES, "aud_3rd_dac_hires", "audio_h_sel", 31),
+       /* AUD2 */
+       GATE_AUD2(CLK_AUD_I2S5_B, "aud_i2s5_b", "audio_sel", 0),
+       GATE_AUD2(CLK_AUD_I2S6_B, "aud_i2s6_b", "audio_sel", 1),
+       GATE_AUD2(CLK_AUD_I2S7_B, "aud_i2s7_b", "audio_sel", 2),
+       GATE_AUD2(CLK_AUD_I2S8_B, "aud_i2s8_b", "audio_sel", 3),
+       GATE_AUD2(CLK_AUD_I2S9_B, "aud_i2s9_b", "audio_sel", 4),
+};
+
+static int clk_mt8192_aud_probe(struct platform_device *pdev)
+{
+       struct clk_onecell_data *clk_data;
+       struct device_node *node = pdev->dev.of_node;
+       int r;
+
+       clk_data = mtk_alloc_clk_data(CLK_AUD_NR_CLK);
+       if (!clk_data)
+               return -ENOMEM;
+
+       r = mtk_clk_register_gates(node, aud_clks, ARRAY_SIZE(aud_clks), clk_data);
+       if (r)
+               return r;
+
+       r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+       if (r)
+               return r;
+
+       r = devm_of_platform_populate(&pdev->dev);
+       if (r)
+               of_clk_del_provider(node);
+
+       return r;
+}
+
+static const struct of_device_id of_match_clk_mt8192_aud[] = {
+       { .compatible = "mediatek,mt8192-audsys", },
+       {}
+};
+
+static struct platform_driver clk_mt8192_aud_drv = {
+       .probe = clk_mt8192_aud_probe,
+       .driver = {
+               .name = "clk-mt8192-aud",
+               .of_match_table = of_match_clk_mt8192_aud,
+       },
+};
+
+builtin_platform_driver(clk_mt8192_aud_drv);
diff --git a/drivers/clk/mediatek/clk-mt8192-cam.c b/drivers/clk/mediatek/clk-mt8192-cam.c
new file mode 100644 (file)
index 0000000..fc74cd8
--- /dev/null
@@ -0,0 +1,107 @@
+// SPDX-License-Identifier: GPL-2.0-only
+//
+// Copyright (c) 2021 MediaTek Inc.
+// Author: Chun-Jie Chen <chun-jie.chen@mediatek.com>
+
+#include <linux/clk-provider.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+
+#include "clk-mtk.h"
+#include "clk-gate.h"
+
+#include <dt-bindings/clock/mt8192-clk.h>
+
+static const struct mtk_gate_regs cam_cg_regs = {
+       .set_ofs = 0x4,
+       .clr_ofs = 0x8,
+       .sta_ofs = 0x0,
+};
+
+#define GATE_CAM(_id, _name, _parent, _shift)  \
+       GATE_MTK(_id, _name, _parent, &cam_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
+
+static const struct mtk_gate cam_clks[] = {
+       GATE_CAM(CLK_CAM_LARB13, "cam_larb13", "cam_sel", 0),
+       GATE_CAM(CLK_CAM_DFP_VAD, "cam_dfp_vad", "cam_sel", 1),
+       GATE_CAM(CLK_CAM_LARB14, "cam_larb14", "cam_sel", 2),
+       GATE_CAM(CLK_CAM_CAM, "cam_cam", "cam_sel", 6),
+       GATE_CAM(CLK_CAM_CAMTG, "cam_camtg", "cam_sel", 7),
+       GATE_CAM(CLK_CAM_SENINF, "cam_seninf", "cam_sel", 8),
+       GATE_CAM(CLK_CAM_CAMSV0, "cam_camsv0", "cam_sel", 9),
+       GATE_CAM(CLK_CAM_CAMSV1, "cam_camsv1", "cam_sel", 10),
+       GATE_CAM(CLK_CAM_CAMSV2, "cam_camsv2", "cam_sel", 11),
+       GATE_CAM(CLK_CAM_CAMSV3, "cam_camsv3", "cam_sel", 12),
+       GATE_CAM(CLK_CAM_CCU0, "cam_ccu0", "cam_sel", 13),
+       GATE_CAM(CLK_CAM_CCU1, "cam_ccu1", "cam_sel", 14),
+       GATE_CAM(CLK_CAM_MRAW0, "cam_mraw0", "cam_sel", 15),
+       GATE_CAM(CLK_CAM_FAKE_ENG, "cam_fake_eng", "cam_sel", 17),
+       GATE_CAM(CLK_CAM_CCU_GALS, "cam_ccu_gals", "cam_sel", 18),
+       GATE_CAM(CLK_CAM_CAM2MM_GALS, "cam2mm_gals", "cam_sel", 19),
+};
+
+static const struct mtk_gate cam_rawa_clks[] = {
+       GATE_CAM(CLK_CAM_RAWA_LARBX, "cam_rawa_larbx", "cam_sel", 0),
+       GATE_CAM(CLK_CAM_RAWA_CAM, "cam_rawa_cam", "cam_sel", 1),
+       GATE_CAM(CLK_CAM_RAWA_CAMTG, "cam_rawa_camtg", "cam_sel", 2),
+};
+
+static const struct mtk_gate cam_rawb_clks[] = {
+       GATE_CAM(CLK_CAM_RAWB_LARBX, "cam_rawb_larbx", "cam_sel", 0),
+       GATE_CAM(CLK_CAM_RAWB_CAM, "cam_rawb_cam", "cam_sel", 1),
+       GATE_CAM(CLK_CAM_RAWB_CAMTG, "cam_rawb_camtg", "cam_sel", 2),
+};
+
+static const struct mtk_gate cam_rawc_clks[] = {
+       GATE_CAM(CLK_CAM_RAWC_LARBX, "cam_rawc_larbx", "cam_sel", 0),
+       GATE_CAM(CLK_CAM_RAWC_CAM, "cam_rawc_cam", "cam_sel", 1),
+       GATE_CAM(CLK_CAM_RAWC_CAMTG, "cam_rawc_camtg", "cam_sel", 2),
+};
+
+static const struct mtk_clk_desc cam_desc = {
+       .clks = cam_clks,
+       .num_clks = ARRAY_SIZE(cam_clks),
+};
+
+static const struct mtk_clk_desc cam_rawa_desc = {
+       .clks = cam_rawa_clks,
+       .num_clks = ARRAY_SIZE(cam_rawa_clks),
+};
+
+static const struct mtk_clk_desc cam_rawb_desc = {
+       .clks = cam_rawb_clks,
+       .num_clks = ARRAY_SIZE(cam_rawb_clks),
+};
+
+static const struct mtk_clk_desc cam_rawc_desc = {
+       .clks = cam_rawc_clks,
+       .num_clks = ARRAY_SIZE(cam_rawc_clks),
+};
+
+static const struct of_device_id of_match_clk_mt8192_cam[] = {
+       {
+               .compatible = "mediatek,mt8192-camsys",
+               .data = &cam_desc,
+       }, {
+               .compatible = "mediatek,mt8192-camsys_rawa",
+               .data = &cam_rawa_desc,
+       }, {
+               .compatible = "mediatek,mt8192-camsys_rawb",
+               .data = &cam_rawb_desc,
+       }, {
+               .compatible = "mediatek,mt8192-camsys_rawc",
+               .data = &cam_rawc_desc,
+       }, {
+               /* sentinel */
+       }
+};
+
+static struct platform_driver clk_mt8192_cam_drv = {
+       .probe = mtk_clk_simple_probe,
+       .driver = {
+               .name = "clk-mt8192-cam",
+               .of_match_table = of_match_clk_mt8192_cam,
+       },
+};
+
+builtin_platform_driver(clk_mt8192_cam_drv);
diff --git a/drivers/clk/mediatek/clk-mt8192-img.c b/drivers/clk/mediatek/clk-mt8192-img.c
new file mode 100644 (file)
index 0000000..7ce3abe
--- /dev/null
@@ -0,0 +1,70 @@
+// SPDX-License-Identifier: GPL-2.0-only
+//
+// Copyright (c) 2021 MediaTek Inc.
+// Author: Chun-Jie Chen <chun-jie.chen@mediatek.com>
+
+#include <linux/clk-provider.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+
+#include "clk-mtk.h"
+#include "clk-gate.h"
+
+#include <dt-bindings/clock/mt8192-clk.h>
+
+static const struct mtk_gate_regs img_cg_regs = {
+       .set_ofs = 0x4,
+       .clr_ofs = 0x8,
+       .sta_ofs = 0x0,
+};
+
+#define GATE_IMG(_id, _name, _parent, _shift)  \
+       GATE_MTK(_id, _name, _parent, &img_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
+
+static const struct mtk_gate img_clks[] = {
+       GATE_IMG(CLK_IMG_LARB9, "img_larb9", "img1_sel", 0),
+       GATE_IMG(CLK_IMG_LARB10, "img_larb10", "img1_sel", 1),
+       GATE_IMG(CLK_IMG_DIP, "img_dip", "img1_sel", 2),
+       GATE_IMG(CLK_IMG_GALS, "img_gals", "img1_sel", 12),
+};
+
+static const struct mtk_gate img2_clks[] = {
+       GATE_IMG(CLK_IMG2_LARB11, "img2_larb11", "img1_sel", 0),
+       GATE_IMG(CLK_IMG2_LARB12, "img2_larb12", "img1_sel", 1),
+       GATE_IMG(CLK_IMG2_MFB, "img2_mfb", "img1_sel", 6),
+       GATE_IMG(CLK_IMG2_WPE, "img2_wpe", "img1_sel", 7),
+       GATE_IMG(CLK_IMG2_MSS, "img2_mss", "img1_sel", 8),
+       GATE_IMG(CLK_IMG2_GALS, "img2_gals", "img1_sel", 12),
+};
+
+static const struct mtk_clk_desc img_desc = {
+       .clks = img_clks,
+       .num_clks = ARRAY_SIZE(img_clks),
+};
+
+static const struct mtk_clk_desc img2_desc = {
+       .clks = img2_clks,
+       .num_clks = ARRAY_SIZE(img2_clks),
+};
+
+static const struct of_device_id of_match_clk_mt8192_img[] = {
+       {
+               .compatible = "mediatek,mt8192-imgsys",
+               .data = &img_desc,
+       }, {
+               .compatible = "mediatek,mt8192-imgsys2",
+               .data = &img2_desc,
+       }, {
+               /* sentinel */
+       }
+};
+
+static struct platform_driver clk_mt8192_img_drv = {
+       .probe = mtk_clk_simple_probe,
+       .driver = {
+               .name = "clk-mt8192-img",
+               .of_match_table = of_match_clk_mt8192_img,
+       },
+};
+
+builtin_platform_driver(clk_mt8192_img_drv);
diff --git a/drivers/clk/mediatek/clk-mt8192-imp_iic_wrap.c b/drivers/clk/mediatek/clk-mt8192-imp_iic_wrap.c
new file mode 100644 (file)
index 0000000..700356a
--- /dev/null
@@ -0,0 +1,119 @@
+// SPDX-License-Identifier: GPL-2.0-only
+//
+// Copyright (c) 2021 MediaTek Inc.
+// Author: Chun-Jie Chen <chun-jie.chen@mediatek.com>
+
+#include <linux/clk-provider.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+
+#include "clk-mtk.h"
+#include "clk-gate.h"
+
+#include <dt-bindings/clock/mt8192-clk.h>
+
+static const struct mtk_gate_regs imp_iic_wrap_cg_regs = {
+       .set_ofs = 0xe08,
+       .clr_ofs = 0xe04,
+       .sta_ofs = 0xe00,
+};
+
+#define GATE_IMP_IIC_WRAP(_id, _name, _parent, _shift)                 \
+       GATE_MTK_FLAGS(_id, _name, _parent, &imp_iic_wrap_cg_regs, _shift,      \
+               &mtk_clk_gate_ops_setclr, CLK_OPS_PARENT_ENABLE)
+
+static const struct mtk_gate imp_iic_wrap_c_clks[] = {
+       GATE_IMP_IIC_WRAP(CLK_IMP_IIC_WRAP_C_I2C10, "imp_iic_wrap_c_i2c10", "infra_i2c0", 0),
+       GATE_IMP_IIC_WRAP(CLK_IMP_IIC_WRAP_C_I2C11, "imp_iic_wrap_c_i2c11", "infra_i2c0", 1),
+       GATE_IMP_IIC_WRAP(CLK_IMP_IIC_WRAP_C_I2C12, "imp_iic_wrap_c_i2c12", "infra_i2c0", 2),
+       GATE_IMP_IIC_WRAP(CLK_IMP_IIC_WRAP_C_I2C13, "imp_iic_wrap_c_i2c13", "infra_i2c0", 3),
+};
+
+static const struct mtk_gate imp_iic_wrap_e_clks[] = {
+       GATE_IMP_IIC_WRAP(CLK_IMP_IIC_WRAP_E_I2C3, "imp_iic_wrap_e_i2c3", "infra_i2c0", 0),
+};
+
+static const struct mtk_gate imp_iic_wrap_n_clks[] = {
+       GATE_IMP_IIC_WRAP(CLK_IMP_IIC_WRAP_N_I2C0, "imp_iic_wrap_n_i2c0", "infra_i2c0", 0),
+       GATE_IMP_IIC_WRAP(CLK_IMP_IIC_WRAP_N_I2C6, "imp_iic_wrap_n_i2c6", "infra_i2c0", 1),
+};
+
+static const struct mtk_gate imp_iic_wrap_s_clks[] = {
+       GATE_IMP_IIC_WRAP(CLK_IMP_IIC_WRAP_S_I2C7, "imp_iic_wrap_s_i2c7", "infra_i2c0", 0),
+       GATE_IMP_IIC_WRAP(CLK_IMP_IIC_WRAP_S_I2C8, "imp_iic_wrap_s_i2c8", "infra_i2c0", 1),
+       GATE_IMP_IIC_WRAP(CLK_IMP_IIC_WRAP_S_I2C9, "imp_iic_wrap_s_i2c9", "infra_i2c0", 2),
+};
+
+static const struct mtk_gate imp_iic_wrap_w_clks[] = {
+       GATE_IMP_IIC_WRAP(CLK_IMP_IIC_WRAP_W_I2C5, "imp_iic_wrap_w_i2c5", "infra_i2c0", 0),
+};
+
+static const struct mtk_gate imp_iic_wrap_ws_clks[] = {
+       GATE_IMP_IIC_WRAP(CLK_IMP_IIC_WRAP_WS_I2C1, "imp_iic_wrap_ws_i2c1", "infra_i2c0", 0),
+       GATE_IMP_IIC_WRAP(CLK_IMP_IIC_WRAP_WS_I2C2, "imp_iic_wrap_ws_i2c2", "infra_i2c0", 1),
+       GATE_IMP_IIC_WRAP(CLK_IMP_IIC_WRAP_WS_I2C4, "imp_iic_wrap_ws_i2c4", "infra_i2c0", 2),
+};
+
+static const struct mtk_clk_desc imp_iic_wrap_c_desc = {
+       .clks = imp_iic_wrap_c_clks,
+       .num_clks = ARRAY_SIZE(imp_iic_wrap_c_clks),
+};
+
+static const struct mtk_clk_desc imp_iic_wrap_e_desc = {
+       .clks = imp_iic_wrap_e_clks,
+       .num_clks = ARRAY_SIZE(imp_iic_wrap_e_clks),
+};
+
+static const struct mtk_clk_desc imp_iic_wrap_n_desc = {
+       .clks = imp_iic_wrap_n_clks,
+       .num_clks = ARRAY_SIZE(imp_iic_wrap_n_clks),
+};
+
+static const struct mtk_clk_desc imp_iic_wrap_s_desc = {
+       .clks = imp_iic_wrap_s_clks,
+       .num_clks = ARRAY_SIZE(imp_iic_wrap_s_clks),
+};
+
+static const struct mtk_clk_desc imp_iic_wrap_w_desc = {
+       .clks = imp_iic_wrap_w_clks,
+       .num_clks = ARRAY_SIZE(imp_iic_wrap_w_clks),
+};
+
+static const struct mtk_clk_desc imp_iic_wrap_ws_desc = {
+       .clks = imp_iic_wrap_ws_clks,
+       .num_clks = ARRAY_SIZE(imp_iic_wrap_ws_clks),
+};
+
+static const struct of_device_id of_match_clk_mt8192_imp_iic_wrap[] = {
+       {
+               .compatible = "mediatek,mt8192-imp_iic_wrap_c",
+               .data = &imp_iic_wrap_c_desc,
+       }, {
+               .compatible = "mediatek,mt8192-imp_iic_wrap_e",
+               .data = &imp_iic_wrap_e_desc,
+       }, {
+               .compatible = "mediatek,mt8192-imp_iic_wrap_n",
+               .data = &imp_iic_wrap_n_desc,
+       }, {
+               .compatible = "mediatek,mt8192-imp_iic_wrap_s",
+               .data = &imp_iic_wrap_s_desc,
+       }, {
+               .compatible = "mediatek,mt8192-imp_iic_wrap_w",
+               .data = &imp_iic_wrap_w_desc,
+       }, {
+               .compatible = "mediatek,mt8192-imp_iic_wrap_ws",
+               .data = &imp_iic_wrap_ws_desc,
+       }, {
+               /* sentinel */
+       }
+};
+
+static struct platform_driver clk_mt8192_imp_iic_wrap_drv = {
+       .probe = mtk_clk_simple_probe,
+       .driver = {
+               .name = "clk-mt8192-imp_iic_wrap",
+               .of_match_table = of_match_clk_mt8192_imp_iic_wrap,
+       },
+};
+
+builtin_platform_driver(clk_mt8192_imp_iic_wrap_drv);
diff --git a/drivers/clk/mediatek/clk-mt8192-ipe.c b/drivers/clk/mediatek/clk-mt8192-ipe.c
new file mode 100644 (file)
index 0000000..730d91b
--- /dev/null
@@ -0,0 +1,57 @@
+// SPDX-License-Identifier: GPL-2.0-only
+//
+// Copyright (c) 2021 MediaTek Inc.
+// Author: Chun-Jie Chen <chun-jie.chen@mediatek.com>
+
+#include <linux/clk-provider.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+
+#include "clk-mtk.h"
+#include "clk-gate.h"
+
+#include <dt-bindings/clock/mt8192-clk.h>
+
+static const struct mtk_gate_regs ipe_cg_regs = {
+       .set_ofs = 0x4,
+       .clr_ofs = 0x8,
+       .sta_ofs = 0x0,
+};
+
+#define GATE_IPE(_id, _name, _parent, _shift)  \
+       GATE_MTK(_id, _name, _parent, &ipe_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
+
+static const struct mtk_gate ipe_clks[] = {
+       GATE_IPE(CLK_IPE_LARB19, "ipe_larb19", "ipe_sel", 0),
+       GATE_IPE(CLK_IPE_LARB20, "ipe_larb20", "ipe_sel", 1),
+       GATE_IPE(CLK_IPE_SMI_SUBCOM, "ipe_smi_subcom", "ipe_sel", 2),
+       GATE_IPE(CLK_IPE_FD, "ipe_fd", "ipe_sel", 3),
+       GATE_IPE(CLK_IPE_FE, "ipe_fe", "ipe_sel", 4),
+       GATE_IPE(CLK_IPE_RSC, "ipe_rsc", "ipe_sel", 5),
+       GATE_IPE(CLK_IPE_DPE, "ipe_dpe", "ipe_sel", 6),
+       GATE_IPE(CLK_IPE_GALS, "ipe_gals", "ipe_sel", 8),
+};
+
+static const struct mtk_clk_desc ipe_desc = {
+       .clks = ipe_clks,
+       .num_clks = ARRAY_SIZE(ipe_clks),
+};
+
+static const struct of_device_id of_match_clk_mt8192_ipe[] = {
+       {
+               .compatible = "mediatek,mt8192-ipesys",
+               .data = &ipe_desc,
+       }, {
+               /* sentinel */
+       }
+};
+
+static struct platform_driver clk_mt8192_ipe_drv = {
+       .probe = mtk_clk_simple_probe,
+       .driver = {
+               .name = "clk-mt8192-ipe",
+               .of_match_table = of_match_clk_mt8192_ipe,
+       },
+};
+
+builtin_platform_driver(clk_mt8192_ipe_drv);
diff --git a/drivers/clk/mediatek/clk-mt8192-mdp.c b/drivers/clk/mediatek/clk-mt8192-mdp.c
new file mode 100644 (file)
index 0000000..93c87ae
--- /dev/null
@@ -0,0 +1,82 @@
+// SPDX-License-Identifier: GPL-2.0-only
+//
+// Copyright (c) 2021 MediaTek Inc.
+// Author: Chun-Jie Chen <chun-jie.chen@mediatek.com>
+
+#include <linux/clk-provider.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+
+#include "clk-mtk.h"
+#include "clk-gate.h"
+
+#include <dt-bindings/clock/mt8192-clk.h>
+
+static const struct mtk_gate_regs mdp0_cg_regs = {
+       .set_ofs = 0x104,
+       .clr_ofs = 0x108,
+       .sta_ofs = 0x100,
+};
+
+static const struct mtk_gate_regs mdp1_cg_regs = {
+       .set_ofs = 0x124,
+       .clr_ofs = 0x128,
+       .sta_ofs = 0x120,
+};
+
+#define GATE_MDP0(_id, _name, _parent, _shift) \
+       GATE_MTK(_id, _name, _parent, &mdp0_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
+
+#define GATE_MDP1(_id, _name, _parent, _shift) \
+       GATE_MTK(_id, _name, _parent, &mdp1_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
+
+static const struct mtk_gate mdp_clks[] = {
+       /* MDP0 */
+       GATE_MDP0(CLK_MDP_RDMA0, "mdp_mdp_rdma0", "mdp_sel", 0),
+       GATE_MDP0(CLK_MDP_TDSHP0, "mdp_mdp_tdshp0", "mdp_sel", 1),
+       GATE_MDP0(CLK_MDP_IMG_DL_ASYNC0, "mdp_img_dl_async0", "mdp_sel", 2),
+       GATE_MDP0(CLK_MDP_IMG_DL_ASYNC1, "mdp_img_dl_async1", "mdp_sel", 3),
+       GATE_MDP0(CLK_MDP_RDMA1, "mdp_mdp_rdma1", "mdp_sel", 4),
+       GATE_MDP0(CLK_MDP_TDSHP1, "mdp_mdp_tdshp1", "mdp_sel", 5),
+       GATE_MDP0(CLK_MDP_SMI0, "mdp_smi0", "mdp_sel", 6),
+       GATE_MDP0(CLK_MDP_APB_BUS, "mdp_apb_bus", "mdp_sel", 7),
+       GATE_MDP0(CLK_MDP_WROT0, "mdp_mdp_wrot0", "mdp_sel", 8),
+       GATE_MDP0(CLK_MDP_RSZ0, "mdp_mdp_rsz0", "mdp_sel", 9),
+       GATE_MDP0(CLK_MDP_HDR0, "mdp_mdp_hdr0", "mdp_sel", 10),
+       GATE_MDP0(CLK_MDP_MUTEX0, "mdp_mdp_mutex0", "mdp_sel", 11),
+       GATE_MDP0(CLK_MDP_WROT1, "mdp_mdp_wrot1", "mdp_sel", 12),
+       GATE_MDP0(CLK_MDP_RSZ1, "mdp_mdp_rsz1", "mdp_sel", 13),
+       GATE_MDP0(CLK_MDP_HDR1, "mdp_mdp_hdr1", "mdp_sel", 14),
+       GATE_MDP0(CLK_MDP_FAKE_ENG0, "mdp_mdp_fake_eng0", "mdp_sel", 15),
+       GATE_MDP0(CLK_MDP_AAL0, "mdp_mdp_aal0", "mdp_sel", 16),
+       GATE_MDP0(CLK_MDP_AAL1, "mdp_mdp_aal1", "mdp_sel", 17),
+       GATE_MDP0(CLK_MDP_COLOR0, "mdp_mdp_color0", "mdp_sel", 18),
+       GATE_MDP0(CLK_MDP_COLOR1, "mdp_mdp_color1", "mdp_sel", 19),
+       /* MDP1 */
+       GATE_MDP1(CLK_MDP_IMG_DL_RELAY0_ASYNC0, "mdp_img_dl_relay0_async0", "mdp_sel", 0),
+       GATE_MDP1(CLK_MDP_IMG_DL_RELAY1_ASYNC1, "mdp_img_dl_relay1_async1", "mdp_sel", 8),
+};
+
+static const struct mtk_clk_desc mdp_desc = {
+       .clks = mdp_clks,
+       .num_clks = ARRAY_SIZE(mdp_clks),
+};
+
+static const struct of_device_id of_match_clk_mt8192_mdp[] = {
+       {
+               .compatible = "mediatek,mt8192-mdpsys",
+               .data = &mdp_desc,
+       }, {
+               /* sentinel */
+       }
+};
+
+static struct platform_driver clk_mt8192_mdp_drv = {
+       .probe = mtk_clk_simple_probe,
+       .driver = {
+               .name = "clk-mt8192-mdp",
+               .of_match_table = of_match_clk_mt8192_mdp,
+       },
+};
+
+builtin_platform_driver(clk_mt8192_mdp_drv);
diff --git a/drivers/clk/mediatek/clk-mt8192-mfg.c b/drivers/clk/mediatek/clk-mt8192-mfg.c
new file mode 100644 (file)
index 0000000..3bbc746
--- /dev/null
@@ -0,0 +1,50 @@
+// SPDX-License-Identifier: GPL-2.0-only
+//
+// Copyright (c) 2021 MediaTek Inc.
+// Author: Chun-Jie Chen <chun-jie.chen@mediatek.com>
+
+#include <linux/clk-provider.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+
+#include "clk-mtk.h"
+#include "clk-gate.h"
+
+#include <dt-bindings/clock/mt8192-clk.h>
+
+static const struct mtk_gate_regs mfg_cg_regs = {
+       .set_ofs = 0x4,
+       .clr_ofs = 0x8,
+       .sta_ofs = 0x0,
+};
+
+#define GATE_MFG(_id, _name, _parent, _shift)  \
+       GATE_MTK(_id, _name, _parent, &mfg_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
+
+static const struct mtk_gate mfg_clks[] = {
+       GATE_MFG(CLK_MFG_BG3D, "mfg_bg3d", "mfg_pll_sel", 0),
+};
+
+static const struct mtk_clk_desc mfg_desc = {
+       .clks = mfg_clks,
+       .num_clks = ARRAY_SIZE(mfg_clks),
+};
+
+static const struct of_device_id of_match_clk_mt8192_mfg[] = {
+       {
+               .compatible = "mediatek,mt8192-mfgcfg",
+               .data = &mfg_desc,
+       }, {
+               /* sentinel */
+       }
+};
+
+static struct platform_driver clk_mt8192_mfg_drv = {
+       .probe = mtk_clk_simple_probe,
+       .driver = {
+               .name = "clk-mt8192-mfg",
+               .of_match_table = of_match_clk_mt8192_mfg,
+       },
+};
+
+builtin_platform_driver(clk_mt8192_mfg_drv);
diff --git a/drivers/clk/mediatek/clk-mt8192-mm.c b/drivers/clk/mediatek/clk-mt8192-mm.c
new file mode 100644 (file)
index 0000000..4a0b4c4
--- /dev/null
@@ -0,0 +1,108 @@
+// SPDX-License-Identifier: GPL-2.0-only
+//
+// Copyright (c) 2021 MediaTek Inc.
+// Author: Chun-Jie Chen <chun-jie.chen@mediatek.com>
+
+#include <linux/clk-provider.h>
+#include <linux/platform_device.h>
+
+#include "clk-mtk.h"
+#include "clk-gate.h"
+
+#include <dt-bindings/clock/mt8192-clk.h>
+
+static const struct mtk_gate_regs mm0_cg_regs = {
+       .set_ofs = 0x104,
+       .clr_ofs = 0x108,
+       .sta_ofs = 0x100,
+};
+
+static const struct mtk_gate_regs mm1_cg_regs = {
+       .set_ofs = 0x114,
+       .clr_ofs = 0x118,
+       .sta_ofs = 0x110,
+};
+
+static const struct mtk_gate_regs mm2_cg_regs = {
+       .set_ofs = 0x1a4,
+       .clr_ofs = 0x1a8,
+       .sta_ofs = 0x1a0,
+};
+
+#define GATE_MM0(_id, _name, _parent, _shift)  \
+       GATE_MTK(_id, _name, _parent, &mm0_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
+
+#define GATE_MM1(_id, _name, _parent, _shift)  \
+       GATE_MTK(_id, _name, _parent, &mm1_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
+
+#define GATE_MM2(_id, _name, _parent, _shift)  \
+       GATE_MTK(_id, _name, _parent, &mm2_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
+
+static const struct mtk_gate mm_clks[] = {
+       /* MM0 */
+       GATE_MM0(CLK_MM_DISP_MUTEX0, "mm_disp_mutex0", "disp_sel", 0),
+       GATE_MM0(CLK_MM_DISP_CONFIG, "mm_disp_config", "disp_sel", 1),
+       GATE_MM0(CLK_MM_DISP_OVL0, "mm_disp_ovl0", "disp_sel", 2),
+       GATE_MM0(CLK_MM_DISP_RDMA0, "mm_disp_rdma0", "disp_sel", 3),
+       GATE_MM0(CLK_MM_DISP_OVL0_2L, "mm_disp_ovl0_2l", "disp_sel", 4),
+       GATE_MM0(CLK_MM_DISP_WDMA0, "mm_disp_wdma0", "disp_sel", 5),
+       GATE_MM0(CLK_MM_DISP_UFBC_WDMA0, "mm_disp_ufbc_wdma0", "disp_sel", 6),
+       GATE_MM0(CLK_MM_DISP_RSZ0, "mm_disp_rsz0", "disp_sel", 7),
+       GATE_MM0(CLK_MM_DISP_AAL0, "mm_disp_aal0", "disp_sel", 8),
+       GATE_MM0(CLK_MM_DISP_CCORR0, "mm_disp_ccorr0", "disp_sel", 9),
+       GATE_MM0(CLK_MM_DISP_DITHER0, "mm_disp_dither0", "disp_sel", 10),
+       GATE_MM0(CLK_MM_SMI_INFRA, "mm_smi_infra", "disp_sel", 11),
+       GATE_MM0(CLK_MM_DISP_GAMMA0, "mm_disp_gamma0", "disp_sel", 12),
+       GATE_MM0(CLK_MM_DISP_POSTMASK0, "mm_disp_postmask0", "disp_sel", 13),
+       GATE_MM0(CLK_MM_DISP_DSC_WRAP0, "mm_disp_dsc_wrap0", "disp_sel", 14),
+       GATE_MM0(CLK_MM_DSI0, "mm_dsi0", "disp_sel", 15),
+       GATE_MM0(CLK_MM_DISP_COLOR0, "mm_disp_color0", "disp_sel", 16),
+       GATE_MM0(CLK_MM_SMI_COMMON, "mm_smi_common", "disp_sel", 17),
+       GATE_MM0(CLK_MM_DISP_FAKE_ENG0, "mm_disp_fake_eng0", "disp_sel", 18),
+       GATE_MM0(CLK_MM_DISP_FAKE_ENG1, "mm_disp_fake_eng1", "disp_sel", 19),
+       GATE_MM0(CLK_MM_MDP_TDSHP4, "mm_mdp_tdshp4", "disp_sel", 20),
+       GATE_MM0(CLK_MM_MDP_RSZ4, "mm_mdp_rsz4", "disp_sel", 21),
+       GATE_MM0(CLK_MM_MDP_AAL4, "mm_mdp_aal4", "disp_sel", 22),
+       GATE_MM0(CLK_MM_MDP_HDR4, "mm_mdp_hdr4", "disp_sel", 23),
+       GATE_MM0(CLK_MM_MDP_RDMA4, "mm_mdp_rdma4", "disp_sel", 24),
+       GATE_MM0(CLK_MM_MDP_COLOR4, "mm_mdp_color4", "disp_sel", 25),
+       GATE_MM0(CLK_MM_DISP_Y2R0, "mm_disp_y2r0", "disp_sel", 26),
+       GATE_MM0(CLK_MM_SMI_GALS, "mm_smi_gals", "disp_sel", 27),
+       GATE_MM0(CLK_MM_DISP_OVL2_2L, "mm_disp_ovl2_2l", "disp_sel", 28),
+       GATE_MM0(CLK_MM_DISP_RDMA4, "mm_disp_rdma4", "disp_sel", 29),
+       GATE_MM0(CLK_MM_DISP_DPI0, "mm_disp_dpi0", "disp_sel", 30),
+       /* MM1 */
+       GATE_MM1(CLK_MM_SMI_IOMMU, "mm_smi_iommu", "disp_sel", 0),
+       /* MM2 */
+       GATE_MM2(CLK_MM_DSI_DSI0, "mm_dsi_dsi0", "disp_sel", 0),
+       GATE_MM2(CLK_MM_DPI_DPI0, "mm_dpi_dpi0", "dpi_sel", 8),
+       GATE_MM2(CLK_MM_26MHZ, "mm_26mhz", "clk26m", 24),
+       GATE_MM2(CLK_MM_32KHZ, "mm_32khz", "clk32k", 25),
+};
+
+static int clk_mt8192_mm_probe(struct platform_device *pdev)
+{
+       struct device *dev = &pdev->dev;
+       struct device_node *node = dev->parent->of_node;
+       struct clk_onecell_data *clk_data;
+       int r;
+
+       clk_data = mtk_alloc_clk_data(CLK_MM_NR_CLK);
+       if (!clk_data)
+               return -ENOMEM;
+
+       r = mtk_clk_register_gates(node, mm_clks, ARRAY_SIZE(mm_clks), clk_data);
+       if (r)
+               return r;
+
+       return of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+}
+
+static struct platform_driver clk_mt8192_mm_drv = {
+       .probe = clk_mt8192_mm_probe,
+       .driver = {
+               .name = "clk-mt8192-mm",
+       },
+};
+
+builtin_platform_driver(clk_mt8192_mm_drv);
diff --git a/drivers/clk/mediatek/clk-mt8192-msdc.c b/drivers/clk/mediatek/clk-mt8192-msdc.c
new file mode 100644 (file)
index 0000000..87c3b79
--- /dev/null
@@ -0,0 +1,85 @@
+// SPDX-License-Identifier: GPL-2.0-only
+//
+// Copyright (c) 2021 MediaTek Inc.
+// Author: Chun-Jie Chen <chun-jie.chen@mediatek.com>
+
+#include <linux/clk-provider.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+
+#include "clk-mtk.h"
+#include "clk-gate.h"
+
+#include <dt-bindings/clock/mt8192-clk.h>
+
+static const struct mtk_gate_regs msdc_cg_regs = {
+       .set_ofs = 0xb4,
+       .clr_ofs = 0xb4,
+       .sta_ofs = 0xb4,
+};
+
+static const struct mtk_gate_regs msdc_top_cg_regs = {
+       .set_ofs = 0x0,
+       .clr_ofs = 0x0,
+       .sta_ofs = 0x0,
+};
+
+#define GATE_MSDC(_id, _name, _parent, _shift) \
+       GATE_MTK(_id, _name, _parent, &msdc_cg_regs, _shift, &mtk_clk_gate_ops_no_setclr_inv)
+
+#define GATE_MSDC_TOP(_id, _name, _parent, _shift)     \
+       GATE_MTK(_id, _name, _parent, &msdc_top_cg_regs, _shift, &mtk_clk_gate_ops_no_setclr_inv)
+
+static const struct mtk_gate msdc_clks[] = {
+       GATE_MSDC(CLK_MSDC_AXI_WRAP, "msdc_axi_wrap", "axi_sel", 22),
+};
+
+static const struct mtk_gate msdc_top_clks[] = {
+       GATE_MSDC_TOP(CLK_MSDC_TOP_AES_0P, "msdc_top_aes_0p", "aes_msdcfde_sel", 0),
+       GATE_MSDC_TOP(CLK_MSDC_TOP_SRC_0P, "msdc_top_src_0p", "infra_msdc0_src", 1),
+       GATE_MSDC_TOP(CLK_MSDC_TOP_SRC_1P, "msdc_top_src_1p", "infra_msdc1_src", 2),
+       GATE_MSDC_TOP(CLK_MSDC_TOP_SRC_2P, "msdc_top_src_2p", "infra_msdc2_src", 3),
+       GATE_MSDC_TOP(CLK_MSDC_TOP_P_MSDC0, "msdc_top_p_msdc0", "axi_sel", 4),
+       GATE_MSDC_TOP(CLK_MSDC_TOP_P_MSDC1, "msdc_top_p_msdc1", "axi_sel", 5),
+       GATE_MSDC_TOP(CLK_MSDC_TOP_P_MSDC2, "msdc_top_p_msdc2", "axi_sel", 6),
+       GATE_MSDC_TOP(CLK_MSDC_TOP_P_CFG, "msdc_top_p_cfg", "axi_sel", 7),
+       GATE_MSDC_TOP(CLK_MSDC_TOP_AXI, "msdc_top_axi", "axi_sel", 8),
+       GATE_MSDC_TOP(CLK_MSDC_TOP_H_MST_0P, "msdc_top_h_mst_0p", "infra_msdc0", 9),
+       GATE_MSDC_TOP(CLK_MSDC_TOP_H_MST_1P, "msdc_top_h_mst_1p", "infra_msdc1", 10),
+       GATE_MSDC_TOP(CLK_MSDC_TOP_H_MST_2P, "msdc_top_h_mst_2p", "infra_msdc2", 11),
+       GATE_MSDC_TOP(CLK_MSDC_TOP_MEM_OFF_DLY_26M, "msdc_top_mem_off_dly_26m", "clk26m", 12),
+       GATE_MSDC_TOP(CLK_MSDC_TOP_32K, "msdc_top_32k", "clk32k", 13),
+       GATE_MSDC_TOP(CLK_MSDC_TOP_AHB2AXI_BRG_AXI, "msdc_top_ahb2axi_brg_axi", "axi_sel", 14),
+};
+
+static const struct mtk_clk_desc msdc_desc = {
+       .clks = msdc_clks,
+       .num_clks = ARRAY_SIZE(msdc_clks),
+};
+
+static const struct mtk_clk_desc msdc_top_desc = {
+       .clks = msdc_top_clks,
+       .num_clks = ARRAY_SIZE(msdc_top_clks),
+};
+
+static const struct of_device_id of_match_clk_mt8192_msdc[] = {
+       {
+               .compatible = "mediatek,mt8192-msdc",
+               .data = &msdc_desc,
+       }, {
+               .compatible = "mediatek,mt8192-msdc_top",
+               .data = &msdc_top_desc,
+       }, {
+               /* sentinel */
+       }
+};
+
+static struct platform_driver clk_mt8192_msdc_drv = {
+       .probe = mtk_clk_simple_probe,
+       .driver = {
+               .name = "clk-mt8192-msdc",
+               .of_match_table = of_match_clk_mt8192_msdc,
+       },
+};
+
+builtin_platform_driver(clk_mt8192_msdc_drv);
diff --git a/drivers/clk/mediatek/clk-mt8192-scp_adsp.c b/drivers/clk/mediatek/clk-mt8192-scp_adsp.c
new file mode 100644 (file)
index 0000000..58725d7
--- /dev/null
@@ -0,0 +1,50 @@
+// SPDX-License-Identifier: GPL-2.0-only
+//
+// Copyright (c) 2021 MediaTek Inc.
+// Author: Chun-Jie Chen <chun-jie.chen@mediatek.com>
+
+#include <linux/clk-provider.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+
+#include "clk-mtk.h"
+#include "clk-gate.h"
+
+#include <dt-bindings/clock/mt8192-clk.h>
+
+static const struct mtk_gate_regs scp_adsp_cg_regs = {
+       .set_ofs = 0x180,
+       .clr_ofs = 0x180,
+       .sta_ofs = 0x180,
+};
+
+#define GATE_SCP_ADSP(_id, _name, _parent, _shift)     \
+       GATE_MTK(_id, _name, _parent, &scp_adsp_cg_regs, _shift, &mtk_clk_gate_ops_no_setclr)
+
+static const struct mtk_gate scp_adsp_clks[] = {
+       GATE_SCP_ADSP(CLK_SCP_ADSP_AUDIODSP, "scp_adsp_audiodsp", "adsp_sel", 0),
+};
+
+static const struct mtk_clk_desc scp_adsp_desc = {
+       .clks = scp_adsp_clks,
+       .num_clks = ARRAY_SIZE(scp_adsp_clks),
+};
+
+static const struct of_device_id of_match_clk_mt8192_scp_adsp[] = {
+       {
+               .compatible = "mediatek,mt8192-scp_adsp",
+               .data = &scp_adsp_desc,
+       }, {
+               /* sentinel */
+       }
+};
+
+static struct platform_driver clk_mt8192_scp_adsp_drv = {
+       .probe = mtk_clk_simple_probe,
+       .driver = {
+               .name = "clk-mt8192-scp_adsp",
+               .of_match_table = of_match_clk_mt8192_scp_adsp,
+       },
+};
+
+builtin_platform_driver(clk_mt8192_scp_adsp_drv);
diff --git a/drivers/clk/mediatek/clk-mt8192-vdec.c b/drivers/clk/mediatek/clk-mt8192-vdec.c
new file mode 100644 (file)
index 0000000..b1d95cf
--- /dev/null
@@ -0,0 +1,94 @@
+// SPDX-License-Identifier: GPL-2.0-only
+//
+// Copyright (c) 2021 MediaTek Inc.
+// Author: Chun-Jie Chen <chun-jie.chen@mediatek.com>
+
+#include <linux/clk-provider.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+
+#include "clk-mtk.h"
+#include "clk-gate.h"
+
+#include <dt-bindings/clock/mt8192-clk.h>
+
+static const struct mtk_gate_regs vdec0_cg_regs = {
+       .set_ofs = 0x0,
+       .clr_ofs = 0x4,
+       .sta_ofs = 0x0,
+};
+
+static const struct mtk_gate_regs vdec1_cg_regs = {
+       .set_ofs = 0x200,
+       .clr_ofs = 0x204,
+       .sta_ofs = 0x200,
+};
+
+static const struct mtk_gate_regs vdec2_cg_regs = {
+       .set_ofs = 0x8,
+       .clr_ofs = 0xc,
+       .sta_ofs = 0x8,
+};
+
+#define GATE_VDEC0(_id, _name, _parent, _shift)        \
+       GATE_MTK(_id, _name, _parent, &vdec0_cg_regs, _shift, &mtk_clk_gate_ops_setclr_inv)
+
+#define GATE_VDEC1(_id, _name, _parent, _shift)        \
+       GATE_MTK(_id, _name, _parent, &vdec1_cg_regs, _shift, &mtk_clk_gate_ops_setclr_inv)
+
+#define GATE_VDEC2(_id, _name, _parent, _shift)        \
+       GATE_MTK(_id, _name, _parent, &vdec2_cg_regs, _shift, &mtk_clk_gate_ops_setclr_inv)
+
+static const struct mtk_gate vdec_clks[] = {
+       /* VDEC0 */
+       GATE_VDEC0(CLK_VDEC_VDEC, "vdec_vdec", "vdec_sel", 0),
+       GATE_VDEC0(CLK_VDEC_ACTIVE, "vdec_active", "vdec_sel", 4),
+       /* VDEC1 */
+       GATE_VDEC1(CLK_VDEC_LAT, "vdec_lat", "vdec_sel", 0),
+       GATE_VDEC1(CLK_VDEC_LAT_ACTIVE, "vdec_lat_active", "vdec_sel", 4),
+       /* VDEC2 */
+       GATE_VDEC2(CLK_VDEC_LARB1, "vdec_larb1", "vdec_sel", 0),
+};
+
+static const struct mtk_gate vdec_soc_clks[] = {
+       /* VDEC_SOC0 */
+       GATE_VDEC0(CLK_VDEC_SOC_VDEC, "vdec_soc_vdec", "vdec_sel", 0),
+       GATE_VDEC0(CLK_VDEC_SOC_VDEC_ACTIVE, "vdec_soc_vdec_active", "vdec_sel", 4),
+       /* VDEC_SOC1 */
+       GATE_VDEC1(CLK_VDEC_SOC_LAT, "vdec_soc_lat", "vdec_sel", 0),
+       GATE_VDEC1(CLK_VDEC_SOC_LAT_ACTIVE, "vdec_soc_lat_active", "vdec_sel", 4),
+       /* VDEC_SOC2 */
+       GATE_VDEC2(CLK_VDEC_SOC_LARB1, "vdec_soc_larb1", "vdec_sel", 0),
+};
+
+static const struct mtk_clk_desc vdec_desc = {
+       .clks = vdec_clks,
+       .num_clks = ARRAY_SIZE(vdec_clks),
+};
+
+static const struct mtk_clk_desc vdec_soc_desc = {
+       .clks = vdec_soc_clks,
+       .num_clks = ARRAY_SIZE(vdec_soc_clks),
+};
+
+static const struct of_device_id of_match_clk_mt8192_vdec[] = {
+       {
+               .compatible = "mediatek,mt8192-vdecsys",
+               .data = &vdec_desc,
+       }, {
+               .compatible = "mediatek,mt8192-vdecsys_soc",
+               .data = &vdec_soc_desc,
+       }, {
+               /* sentinel */
+       }
+};
+
+static struct platform_driver clk_mt8192_vdec_drv = {
+       .probe = mtk_clk_simple_probe,
+       .driver = {
+               .name = "clk-mt8192-vdec",
+               .of_match_table = of_match_clk_mt8192_vdec,
+       },
+};
+
+builtin_platform_driver(clk_mt8192_vdec_drv);
diff --git a/drivers/clk/mediatek/clk-mt8192-venc.c b/drivers/clk/mediatek/clk-mt8192-venc.c
new file mode 100644 (file)
index 0000000..c0d867b
--- /dev/null
@@ -0,0 +1,53 @@
+// SPDX-License-Identifier: GPL-2.0-only
+//
+// Copyright (c) 2021 MediaTek Inc.
+// Author: Chun-Jie Chen <chun-jie.chen@mediatek.com>
+
+#include <linux/clk-provider.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+
+#include "clk-mtk.h"
+#include "clk-gate.h"
+
+#include <dt-bindings/clock/mt8192-clk.h>
+
+static const struct mtk_gate_regs venc_cg_regs = {
+       .set_ofs = 0x4,
+       .clr_ofs = 0x8,
+       .sta_ofs = 0x0,
+};
+
+#define GATE_VENC(_id, _name, _parent, _shift) \
+       GATE_MTK(_id, _name, _parent, &venc_cg_regs, _shift, &mtk_clk_gate_ops_setclr_inv)
+
+static const struct mtk_gate venc_clks[] = {
+       GATE_VENC(CLK_VENC_SET0_LARB, "venc_set0_larb", "venc_sel", 0),
+       GATE_VENC(CLK_VENC_SET1_VENC, "venc_set1_venc", "venc_sel", 4),
+       GATE_VENC(CLK_VENC_SET2_JPGENC, "venc_set2_jpgenc", "venc_sel", 8),
+       GATE_VENC(CLK_VENC_SET5_GALS, "venc_set5_gals", "venc_sel", 28),
+};
+
+static const struct mtk_clk_desc venc_desc = {
+       .clks = venc_clks,
+       .num_clks = ARRAY_SIZE(venc_clks),
+};
+
+static const struct of_device_id of_match_clk_mt8192_venc[] = {
+       {
+               .compatible = "mediatek,mt8192-vencsys",
+               .data = &venc_desc,
+       }, {
+               /* sentinel */
+       }
+};
+
+static struct platform_driver clk_mt8192_venc_drv = {
+       .probe = mtk_clk_simple_probe,
+       .driver = {
+               .name = "clk-mt8192-venc",
+               .of_match_table = of_match_clk_mt8192_venc,
+       },
+};
+
+builtin_platform_driver(clk_mt8192_venc_drv);
diff --git a/drivers/clk/mediatek/clk-mt8192.c b/drivers/clk/mediatek/clk-mt8192.c
new file mode 100644 (file)
index 0000000..cbc7c6d
--- /dev/null
@@ -0,0 +1,1326 @@
+// SPDX-License-Identifier: GPL-2.0-only
+//
+// Copyright (c) 2021 MediaTek Inc.
+// Author: Chun-Jie Chen <chun-jie.chen@mediatek.com>
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/mfd/syscon.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+#include "clk-mtk.h"
+#include "clk-mux.h"
+#include "clk-gate.h"
+
+#include <dt-bindings/clock/mt8192-clk.h>
+
+static DEFINE_SPINLOCK(mt8192_clk_lock);
+
+static const struct mtk_fixed_clk top_fixed_clks[] = {
+       FIXED_CLK(CLK_TOP_ULPOSC, "ulposc", NULL, 260000000),
+};
+
+static const struct mtk_fixed_factor top_early_divs[] = {
+       FACTOR(CLK_TOP_CSW_F26M_D2, "csw_f26m_d2", "clk26m", 1, 2),
+};
+
+static const struct mtk_fixed_factor top_divs[] = {
+       FACTOR(CLK_TOP_MAINPLL_D3, "mainpll_d3", "mainpll", 1, 3),
+       FACTOR(CLK_TOP_MAINPLL_D4, "mainpll_d4", "mainpll", 1, 4),
+       FACTOR(CLK_TOP_MAINPLL_D4_D2, "mainpll_d4_d2", "mainpll_d4", 1, 2),
+       FACTOR(CLK_TOP_MAINPLL_D4_D4, "mainpll_d4_d4", "mainpll_d4", 1, 4),
+       FACTOR(CLK_TOP_MAINPLL_D4_D8, "mainpll_d4_d8", "mainpll_d4", 1, 8),
+       FACTOR(CLK_TOP_MAINPLL_D4_D16, "mainpll_d4_d16", "mainpll_d4", 1, 16),
+       FACTOR(CLK_TOP_MAINPLL_D5, "mainpll_d5", "mainpll", 1, 5),
+       FACTOR(CLK_TOP_MAINPLL_D5_D2, "mainpll_d5_d2", "mainpll_d5", 1, 2),
+       FACTOR(CLK_TOP_MAINPLL_D5_D4, "mainpll_d5_d4", "mainpll_d5", 1, 4),
+       FACTOR(CLK_TOP_MAINPLL_D5_D8, "mainpll_d5_d8", "mainpll_d5", 1, 8),
+       FACTOR(CLK_TOP_MAINPLL_D6, "mainpll_d6", "mainpll", 1, 6),
+       FACTOR(CLK_TOP_MAINPLL_D6_D2, "mainpll_d6_d2", "mainpll_d6", 1, 2),
+       FACTOR(CLK_TOP_MAINPLL_D6_D4, "mainpll_d6_d4", "mainpll_d6", 1, 4),
+       FACTOR(CLK_TOP_MAINPLL_D7, "mainpll_d7", "mainpll", 1, 7),
+       FACTOR(CLK_TOP_MAINPLL_D7_D2, "mainpll_d7_d2", "mainpll_d7", 1, 2),
+       FACTOR(CLK_TOP_MAINPLL_D7_D4, "mainpll_d7_d4", "mainpll_d7", 1, 4),
+       FACTOR(CLK_TOP_MAINPLL_D7_D8, "mainpll_d7_d8", "mainpll_d7", 1, 8),
+       FACTOR(CLK_TOP_UNIVPLL_D3, "univpll_d3", "univpll", 1, 3),
+       FACTOR(CLK_TOP_UNIVPLL_D4, "univpll_d4", "univpll", 1, 4),
+       FACTOR(CLK_TOP_UNIVPLL_D4_D2, "univpll_d4_d2", "univpll_d4", 1, 2),
+       FACTOR(CLK_TOP_UNIVPLL_D4_D4, "univpll_d4_d4", "univpll_d4", 1, 4),
+       FACTOR(CLK_TOP_UNIVPLL_D4_D8, "univpll_d4_d8", "univpll_d4", 1, 8),
+       FACTOR(CLK_TOP_UNIVPLL_D5, "univpll_d5", "univpll", 1, 5),
+       FACTOR(CLK_TOP_UNIVPLL_D5_D2, "univpll_d5_d2", "univpll_d5", 1, 2),
+       FACTOR(CLK_TOP_UNIVPLL_D5_D4, "univpll_d5_d4", "univpll_d5", 1, 4),
+       FACTOR(CLK_TOP_UNIVPLL_D5_D8, "univpll_d5_d8", "univpll_d5", 1, 8),
+       FACTOR(CLK_TOP_UNIVPLL_D6, "univpll_d6", "univpll", 1, 6),
+       FACTOR(CLK_TOP_UNIVPLL_D6_D2, "univpll_d6_d2", "univpll_d6", 1, 2),
+       FACTOR(CLK_TOP_UNIVPLL_D6_D4, "univpll_d6_d4", "univpll_d6", 1, 4),
+       FACTOR(CLK_TOP_UNIVPLL_D6_D8, "univpll_d6_d8", "univpll_d6", 1, 8),
+       FACTOR(CLK_TOP_UNIVPLL_D6_D16, "univpll_d6_d16", "univpll_d6", 1, 16),
+       FACTOR(CLK_TOP_UNIVPLL_D7, "univpll_d7", "univpll", 1, 7),
+       FACTOR(CLK_TOP_APLL1, "apll1_ck", "apll1", 1, 1),
+       FACTOR(CLK_TOP_APLL1_D2, "apll1_d2", "apll1", 1, 2),
+       FACTOR(CLK_TOP_APLL1_D4, "apll1_d4", "apll1", 1, 4),
+       FACTOR(CLK_TOP_APLL1_D8, "apll1_d8", "apll1", 1, 8),
+       FACTOR(CLK_TOP_APLL2, "apll2_ck", "apll2", 1, 1),
+       FACTOR(CLK_TOP_APLL2_D2, "apll2_d2", "apll2", 1, 2),
+       FACTOR(CLK_TOP_APLL2_D4, "apll2_d4", "apll2", 1, 4),
+       FACTOR(CLK_TOP_APLL2_D8, "apll2_d8", "apll2", 1, 8),
+       FACTOR(CLK_TOP_MMPLL_D4, "mmpll_d4", "mmpll", 1, 4),
+       FACTOR(CLK_TOP_MMPLL_D4_D2, "mmpll_d4_d2", "mmpll_d4", 1, 2),
+       FACTOR(CLK_TOP_MMPLL_D5, "mmpll_d5", "mmpll", 1, 5),
+       FACTOR(CLK_TOP_MMPLL_D5_D2, "mmpll_d5_d2", "mmpll_d5", 1, 2),
+       FACTOR(CLK_TOP_MMPLL_D6, "mmpll_d6", "mmpll", 1, 6),
+       FACTOR(CLK_TOP_MMPLL_D6_D2, "mmpll_d6_d2", "mmpll_d6", 1, 2),
+       FACTOR(CLK_TOP_MMPLL_D7, "mmpll_d7", "mmpll", 1, 7),
+       FACTOR(CLK_TOP_MMPLL_D9, "mmpll_d9", "mmpll", 1, 9),
+       FACTOR(CLK_TOP_APUPLL, "apupll_ck", "apupll", 1, 2),
+       FACTOR(CLK_TOP_NPUPLL, "npupll_ck", "npupll", 1, 1),
+       FACTOR(CLK_TOP_TVDPLL, "tvdpll_ck", "tvdpll", 1, 1),
+       FACTOR(CLK_TOP_TVDPLL_D2, "tvdpll_d2", "tvdpll", 1, 2),
+       FACTOR(CLK_TOP_TVDPLL_D4, "tvdpll_d4", "tvdpll", 1, 4),
+       FACTOR(CLK_TOP_TVDPLL_D8, "tvdpll_d8", "tvdpll", 1, 8),
+       FACTOR(CLK_TOP_TVDPLL_D16, "tvdpll_d16", "tvdpll", 1, 16),
+       FACTOR(CLK_TOP_MSDCPLL, "msdcpll_ck", "msdcpll", 1, 1),
+       FACTOR(CLK_TOP_MSDCPLL_D2, "msdcpll_d2", "msdcpll", 1, 2),
+       FACTOR(CLK_TOP_MSDCPLL_D4, "msdcpll_d4", "msdcpll", 1, 4),
+       FACTOR(CLK_TOP_OSC_D2, "osc_d2", "ulposc", 1, 2),
+       FACTOR(CLK_TOP_OSC_D4, "osc_d4", "ulposc", 1, 4),
+       FACTOR(CLK_TOP_OSC_D8, "osc_d8", "ulposc", 1, 8),
+       FACTOR(CLK_TOP_OSC_D10, "osc_d10", "ulposc", 1, 10),
+       FACTOR(CLK_TOP_OSC_D16, "osc_d16", "ulposc", 1, 16),
+       FACTOR(CLK_TOP_OSC_D20, "osc_d20", "ulposc", 1, 20),
+       FACTOR(CLK_TOP_ADSPPLL, "adsppll_ck", "adsppll", 1, 1),
+       FACTOR(CLK_TOP_UNIVPLL_192M, "univpll_192m", "univpll", 1, 13),
+       FACTOR(CLK_TOP_UNIVPLL_192M_D2, "univpll_192m_d2", "univpll_192m", 1, 2),
+       FACTOR(CLK_TOP_UNIVPLL_192M_D4, "univpll_192m_d4", "univpll_192m", 1, 4),
+       FACTOR(CLK_TOP_UNIVPLL_192M_D8, "univpll_192m_d8", "univpll_192m", 1, 8),
+       FACTOR(CLK_TOP_UNIVPLL_192M_D16, "univpll_192m_d16", "univpll_192m", 1, 16),
+       FACTOR(CLK_TOP_UNIVPLL_192M_D32, "univpll_192m_d32", "univpll_192m", 1, 32),
+};
+
+static const char * const axi_parents[] = {
+       "clk26m",
+       "mainpll_d4_d4",
+       "mainpll_d7_d2",
+       "mainpll_d4_d2",
+       "mainpll_d5_d2",
+       "mainpll_d6_d2",
+       "osc_d4"
+};
+
+static const char * const spm_parents[] = {
+       "clk26m",
+       "osc_d10",
+       "mainpll_d7_d4",
+       "clk32k"
+};
+
+static const char * const scp_parents[] = {
+       "clk26m",
+       "univpll_d5",
+       "mainpll_d6_d2",
+       "mainpll_d6",
+       "univpll_d6",
+       "mainpll_d4_d2",
+       "mainpll_d5_d2",
+       "univpll_d4_d2"
+};
+
+static const char * const bus_aximem_parents[] = {
+       "clk26m",
+       "mainpll_d7_d2",
+       "mainpll_d4_d2",
+       "mainpll_d5_d2",
+       "mainpll_d6"
+};
+
+static const char * const disp_parents[] = {
+       "clk26m",
+       "univpll_d6_d2",
+       "mainpll_d5_d2",
+       "mmpll_d6_d2",
+       "univpll_d5_d2",
+       "univpll_d4_d2",
+       "mmpll_d7",
+       "univpll_d6",
+       "mainpll_d4",
+       "mmpll_d5_d2"
+};
+
+static const char * const mdp_parents[] = {
+       "clk26m",
+       "mainpll_d5_d2",
+       "mmpll_d6_d2",
+       "mainpll_d4_d2",
+       "mmpll_d4_d2",
+       "mainpll_d6",
+       "univpll_d6",
+       "mainpll_d4",
+       "tvdpll_ck",
+       "univpll_d4",
+       "mmpll_d5_d2"
+};
+
+static const char * const img1_parents[] = {
+       "clk26m",
+       "univpll_d4",
+       "tvdpll_ck",
+       "mainpll_d4",
+       "univpll_d5",
+       "mmpll_d6",
+       "univpll_d6",
+       "mainpll_d6",
+       "mmpll_d4_d2",
+       "mainpll_d4_d2",
+       "mmpll_d6_d2",
+       "mmpll_d5_d2"
+};
+
+static const char * const img2_parents[] = {
+       "clk26m",
+       "univpll_d4",
+       "tvdpll_ck",
+       "mainpll_d4",
+       "univpll_d5",
+       "mmpll_d6",
+       "univpll_d6",
+       "mainpll_d6",
+       "mmpll_d4_d2",
+       "mainpll_d4_d2",
+       "mmpll_d6_d2",
+       "mmpll_d5_d2"
+};
+
+static const char * const ipe_parents[] = {
+       "clk26m",
+       "mainpll_d4",
+       "mmpll_d6",
+       "univpll_d6",
+       "mainpll_d6",
+       "univpll_d4_d2",
+       "mainpll_d4_d2",
+       "mmpll_d6_d2",
+       "mmpll_d5_d2"
+};
+
+static const char * const dpe_parents[] = {
+       "clk26m",
+       "mainpll_d4",
+       "mmpll_d6",
+       "univpll_d6",
+       "mainpll_d6",
+       "univpll_d4_d2",
+       "univpll_d5_d2",
+       "mmpll_d6_d2"
+};
+
+static const char * const cam_parents[] = {
+       "clk26m",
+       "mainpll_d4",
+       "mmpll_d6",
+       "univpll_d4",
+       "univpll_d5",
+       "univpll_d6",
+       "mmpll_d7",
+       "univpll_d4_d2",
+       "mainpll_d4_d2",
+       "univpll_d6_d2"
+};
+
+static const char * const ccu_parents[] = {
+       "clk26m",
+       "mainpll_d4",
+       "mmpll_d6",
+       "mainpll_d6",
+       "mmpll_d7",
+       "univpll_d4_d2",
+       "mmpll_d6_d2",
+       "mmpll_d5_d2",
+       "univpll_d5",
+       "univpll_d6_d2"
+};
+
+static const char * const dsp7_parents[] = {
+       "clk26m",
+       "mainpll_d4_d2",
+       "mainpll_d6",
+       "mmpll_d6",
+       "univpll_d5",
+       "mmpll_d5",
+       "univpll_d4",
+       "mmpll_d4"
+};
+
+static const char * const mfg_ref_parents[] = {
+       "clk26m",
+       "clk26m",
+       "univpll_d6",
+       "mainpll_d5_d2"
+};
+
+static const char * const mfg_pll_parents[] = {
+       "mfg_ref_sel",
+       "mfgpll"
+};
+
+static const char * const camtg_parents[] = {
+       "clk26m",
+       "univpll_192m_d8",
+       "univpll_d6_d8",
+       "univpll_192m_d4",
+       "univpll_d6_d16",
+       "csw_f26m_d2",
+       "univpll_192m_d16",
+       "univpll_192m_d32"
+};
+
+static const char * const camtg2_parents[] = {
+       "clk26m",
+       "univpll_192m_d8",
+       "univpll_d6_d8",
+       "univpll_192m_d4",
+       "univpll_d6_d16",
+       "csw_f26m_d2",
+       "univpll_192m_d16",
+       "univpll_192m_d32"
+};
+
+static const char * const camtg3_parents[] = {
+       "clk26m",
+       "univpll_192m_d8",
+       "univpll_d6_d8",
+       "univpll_192m_d4",
+       "univpll_d6_d16",
+       "csw_f26m_d2",
+       "univpll_192m_d16",
+       "univpll_192m_d32"
+};
+
+static const char * const camtg4_parents[] = {
+       "clk26m",
+       "univpll_192m_d8",
+       "univpll_d6_d8",
+       "univpll_192m_d4",
+       "univpll_d6_d16",
+       "csw_f26m_d2",
+       "univpll_192m_d16",
+       "univpll_192m_d32"
+};
+
+static const char * const camtg5_parents[] = {
+       "clk26m",
+       "univpll_192m_d8",
+       "univpll_d6_d8",
+       "univpll_192m_d4",
+       "univpll_d6_d16",
+       "csw_f26m_d2",
+       "univpll_192m_d16",
+       "univpll_192m_d32"
+};
+
+static const char * const camtg6_parents[] = {
+       "clk26m",
+       "univpll_192m_d8",
+       "univpll_d6_d8",
+       "univpll_192m_d4",
+       "univpll_d6_d16",
+       "csw_f26m_d2",
+       "univpll_192m_d16",
+       "univpll_192m_d32"
+};
+
+static const char * const uart_parents[] = {
+       "clk26m",
+       "univpll_d6_d8"
+};
+
+static const char * const spi_parents[] = {
+       "clk26m",
+       "mainpll_d5_d4",
+       "mainpll_d6_d4",
+       "msdcpll_d4"
+};
+
+static const char * const msdc50_0_h_parents[] = {
+       "clk26m",
+       "mainpll_d4_d2",
+       "mainpll_d6_d2"
+};
+
+static const char * const msdc50_0_parents[] = {
+       "clk26m",
+       "msdcpll_ck",
+       "msdcpll_d2",
+       "univpll_d4_d4",
+       "mainpll_d6_d2",
+       "univpll_d4_d2"
+};
+
+static const char * const msdc30_1_parents[] = {
+       "clk26m",
+       "univpll_d6_d2",
+       "mainpll_d6_d2",
+       "mainpll_d7_d2",
+       "msdcpll_d2"
+};
+
+static const char * const msdc30_2_parents[] = {
+       "clk26m",
+       "univpll_d6_d2",
+       "mainpll_d6_d2",
+       "mainpll_d7_d2",
+       "msdcpll_d2"
+};
+
+static const char * const audio_parents[] = {
+       "clk26m",
+       "mainpll_d5_d8",
+       "mainpll_d7_d8",
+       "mainpll_d4_d16"
+};
+
+static const char * const aud_intbus_parents[] = {
+       "clk26m",
+       "mainpll_d4_d4",
+       "mainpll_d7_d4"
+};
+
+static const char * const pwrap_ulposc_parents[] = {
+       "osc_d10",
+       "clk26m",
+       "osc_d4",
+       "osc_d8",
+       "osc_d16"
+};
+
+static const char * const atb_parents[] = {
+       "clk26m",
+       "mainpll_d4_d2",
+       "mainpll_d5_d2"
+};
+
+static const char * const dpi_parents[] = {
+       "clk26m",
+       "tvdpll_d2",
+       "tvdpll_d4",
+       "tvdpll_d8",
+       "tvdpll_d16"
+};
+
+static const char * const scam_parents[] = {
+       "clk26m",
+       "mainpll_d5_d4"
+};
+
+static const char * const disp_pwm_parents[] = {
+       "clk26m",
+       "univpll_d6_d4",
+       "osc_d2",
+       "osc_d4",
+       "osc_d16"
+};
+
+static const char * const usb_top_parents[] = {
+       "clk26m",
+       "univpll_d5_d4",
+       "univpll_d6_d4",
+       "univpll_d5_d2"
+};
+
+static const char * const ssusb_xhci_parents[] = {
+       "clk26m",
+       "univpll_d5_d4",
+       "univpll_d6_d4",
+       "univpll_d5_d2"
+};
+
+static const char * const i2c_parents[] = {
+       "clk26m",
+       "mainpll_d4_d8",
+       "univpll_d5_d4"
+};
+
+static const char * const seninf_parents[] = {
+       "clk26m",
+       "univpll_d4_d4",
+       "univpll_d6_d2",
+       "univpll_d4_d2",
+       "univpll_d7",
+       "univpll_d6",
+       "mmpll_d6",
+       "univpll_d5"
+};
+
+static const char * const seninf1_parents[] = {
+       "clk26m",
+       "univpll_d4_d4",
+       "univpll_d6_d2",
+       "univpll_d4_d2",
+       "univpll_d7",
+       "univpll_d6",
+       "mmpll_d6",
+       "univpll_d5"
+};
+
+static const char * const seninf2_parents[] = {
+       "clk26m",
+       "univpll_d4_d4",
+       "univpll_d6_d2",
+       "univpll_d4_d2",
+       "univpll_d7",
+       "univpll_d6",
+       "mmpll_d6",
+       "univpll_d5"
+};
+
+static const char * const seninf3_parents[] = {
+       "clk26m",
+       "univpll_d4_d4",
+       "univpll_d6_d2",
+       "univpll_d4_d2",
+       "univpll_d7",
+       "univpll_d6",
+       "mmpll_d6",
+       "univpll_d5"
+};
+
+static const char * const tl_parents[] = {
+       "clk26m",
+       "univpll_192m_d2",
+       "mainpll_d6_d4"
+};
+
+static const char * const dxcc_parents[] = {
+       "clk26m",
+       "mainpll_d4_d2",
+       "mainpll_d4_d4",
+       "mainpll_d4_d8"
+};
+
+static const char * const aud_engen1_parents[] = {
+       "clk26m",
+       "apll1_d2",
+       "apll1_d4",
+       "apll1_d8"
+};
+
+static const char * const aud_engen2_parents[] = {
+       "clk26m",
+       "apll2_d2",
+       "apll2_d4",
+       "apll2_d8"
+};
+
+static const char * const aes_ufsfde_parents[] = {
+       "clk26m",
+       "mainpll_d4",
+       "mainpll_d4_d2",
+       "mainpll_d6",
+       "mainpll_d4_d4",
+       "univpll_d4_d2",
+       "univpll_d6"
+};
+
+static const char * const ufs_parents[] = {
+       "clk26m",
+       "mainpll_d4_d4",
+       "mainpll_d4_d8",
+       "univpll_d4_d4",
+       "mainpll_d6_d2",
+       "mainpll_d5_d2",
+       "msdcpll_d2"
+};
+
+static const char * const aud_1_parents[] = {
+       "clk26m",
+       "apll1_ck"
+};
+
+static const char * const aud_2_parents[] = {
+       "clk26m",
+       "apll2_ck"
+};
+
+static const char * const adsp_parents[] = {
+       "clk26m",
+       "mainpll_d6",
+       "mainpll_d5_d2",
+       "univpll_d4_d4",
+       "univpll_d4",
+       "univpll_d6",
+       "ulposc",
+       "adsppll_ck"
+};
+
+static const char * const dpmaif_main_parents[] = {
+       "clk26m",
+       "univpll_d4_d4",
+       "mainpll_d6",
+       "mainpll_d4_d2",
+       "univpll_d4_d2"
+};
+
+static const char * const venc_parents[] = {
+       "clk26m",
+       "mmpll_d7",
+       "mainpll_d6",
+       "univpll_d4_d2",
+       "mainpll_d4_d2",
+       "univpll_d6",
+       "mmpll_d6",
+       "mainpll_d5_d2",
+       "mainpll_d6_d2",
+       "mmpll_d9",
+       "univpll_d4_d4",
+       "mainpll_d4",
+       "univpll_d4",
+       "univpll_d5",
+       "univpll_d5_d2",
+       "mainpll_d5"
+};
+
+static const char * const vdec_parents[] = {
+       "clk26m",
+       "univpll_192m_d2",
+       "univpll_d5_d4",
+       "mainpll_d5",
+       "mainpll_d5_d2",
+       "mmpll_d6_d2",
+       "univpll_d5_d2",
+       "mainpll_d4_d2",
+       "univpll_d4_d2",
+       "univpll_d7",
+       "mmpll_d7",
+       "mmpll_d6",
+       "univpll_d5",
+       "mainpll_d4",
+       "univpll_d4",
+       "univpll_d6"
+};
+
+static const char * const camtm_parents[] = {
+       "clk26m",
+       "univpll_d7",
+       "univpll_d6_d2",
+       "univpll_d4_d2"
+};
+
+static const char * const pwm_parents[] = {
+       "clk26m",
+       "univpll_d4_d8"
+};
+
+static const char * const audio_h_parents[] = {
+       "clk26m",
+       "univpll_d7",
+       "apll1_ck",
+       "apll2_ck"
+};
+
+static const char * const spmi_mst_parents[] = {
+       "clk26m",
+       "csw_f26m_d2",
+       "osc_d8",
+       "osc_d10",
+       "osc_d16",
+       "osc_d20",
+       "clk32k"
+};
+
+static const char * const aes_msdcfde_parents[] = {
+       "clk26m",
+       "mainpll_d4_d2",
+       "mainpll_d6",
+       "mainpll_d4_d4",
+       "univpll_d4_d2",
+       "univpll_d6"
+};
+
+static const char * const sflash_parents[] = {
+       "clk26m",
+       "mainpll_d7_d8",
+       "univpll_d6_d8",
+       "univpll_d5_d8"
+};
+
+static const char * const apll_i2s0_m_parents[] = {
+       "aud_1_sel",
+       "aud_2_sel"
+};
+
+static const char * const apll_i2s1_m_parents[] = {
+       "aud_1_sel",
+       "aud_2_sel"
+};
+
+static const char * const apll_i2s2_m_parents[] = {
+       "aud_1_sel",
+       "aud_2_sel"
+};
+
+static const char * const apll_i2s3_m_parents[] = {
+       "aud_1_sel",
+       "aud_2_sel"
+};
+
+static const char * const apll_i2s4_m_parents[] = {
+       "aud_1_sel",
+       "aud_2_sel"
+};
+
+static const char * const apll_i2s5_m_parents[] = {
+       "aud_1_sel",
+       "aud_2_sel"
+};
+
+static const char * const apll_i2s6_m_parents[] = {
+       "aud_1_sel",
+       "aud_2_sel"
+};
+
+static const char * const apll_i2s7_m_parents[] = {
+       "aud_1_sel",
+       "aud_2_sel"
+};
+
+static const char * const apll_i2s8_m_parents[] = {
+       "aud_1_sel",
+       "aud_2_sel"
+};
+
+static const char * const apll_i2s9_m_parents[] = {
+       "aud_1_sel",
+       "aud_2_sel"
+};
+
+/*
+ * CRITICAL CLOCK:
+ * axi_sel is the main bus clock of whole SOC.
+ * spm_sel is the clock of the always-on co-processor.
+ * bus_aximem_sel is clock of the bus that access emi.
+ */
+static const struct mtk_mux top_mtk_muxes[] = {
+       /* CLK_CFG_0 */
+       MUX_GATE_CLR_SET_UPD_FLAGS(CLK_TOP_AXI_SEL, "axi_sel",
+                                  axi_parents, 0x010, 0x014, 0x018, 0, 3, 7, 0x004, 0,
+                                  CLK_IS_CRITICAL),
+       MUX_GATE_CLR_SET_UPD_FLAGS(CLK_TOP_SPM_SEL, "spm_sel",
+                                  spm_parents, 0x010, 0x014, 0x018, 8, 2, 15, 0x004, 1,
+                                  CLK_IS_CRITICAL),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_SCP_SEL, "scp_sel",
+                            scp_parents, 0x010, 0x014, 0x018, 16, 3, 23, 0x004, 2),
+       MUX_GATE_CLR_SET_UPD_FLAGS(CLK_TOP_BUS_AXIMEM_SEL, "bus_aximem_sel",
+                                  bus_aximem_parents, 0x010, 0x014, 0x018, 24, 3, 31, 0x004, 3,
+                                  CLK_IS_CRITICAL),
+       /* CLK_CFG_1 */
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_DISP_SEL, "disp_sel",
+                            disp_parents, 0x020, 0x024, 0x028, 0, 4, 7, 0x004, 4),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_MDP_SEL, "mdp_sel",
+                            mdp_parents, 0x020, 0x024, 0x028, 8, 4, 15, 0x004, 5),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_IMG1_SEL, "img1_sel",
+                            img1_parents, 0x020, 0x024, 0x028, 16, 4, 23, 0x004, 6),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_IMG2_SEL, "img2_sel",
+                            img2_parents, 0x020, 0x024, 0x028, 24, 4, 31, 0x004, 7),
+       /* CLK_CFG_2 */
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_IPE_SEL, "ipe_sel",
+                            ipe_parents, 0x030, 0x034, 0x038, 0, 4, 7, 0x004, 8),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_DPE_SEL, "dpe_sel",
+                            dpe_parents, 0x030, 0x034, 0x038, 8, 3, 15, 0x004, 9),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_CAM_SEL, "cam_sel",
+                            cam_parents, 0x030, 0x034, 0x038, 16, 4, 23, 0x004, 10),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_CCU_SEL, "ccu_sel",
+                            ccu_parents, 0x030, 0x034, 0x038, 24, 4, 31, 0x004, 11),
+       /* CLK_CFG_4 */
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_DSP7_SEL, "dsp7_sel",
+                            dsp7_parents, 0x050, 0x054, 0x058, 0, 3, 7, 0x004, 16),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_MFG_REF_SEL, "mfg_ref_sel",
+                            mfg_ref_parents, 0x050, 0x054, 0x058, 16, 2, 23, 0x004, 18),
+       MUX_CLR_SET_UPD(CLK_TOP_MFG_PLL_SEL, "mfg_pll_sel",
+                       mfg_pll_parents, 0x050, 0x054, 0x058, 18, 1, -1, -1),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_CAMTG_SEL, "camtg_sel",
+                            camtg_parents, 0x050, 0x054, 0x058, 24, 3, 31, 0x004, 19),
+       /* CLK_CFG_5 */
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_CAMTG2_SEL, "camtg2_sel",
+                            camtg2_parents, 0x060, 0x064, 0x068, 0, 3, 7, 0x004, 20),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_CAMTG3_SEL, "camtg3_sel",
+                            camtg3_parents, 0x060, 0x064, 0x068, 8, 3, 15, 0x004, 21),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_CAMTG4_SEL, "camtg4_sel",
+                            camtg4_parents, 0x060, 0x064, 0x068, 16, 3, 23, 0x004, 22),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_CAMTG5_SEL, "camtg5_sel",
+                            camtg5_parents, 0x060, 0x064, 0x068, 24, 3, 31, 0x004, 23),
+       /* CLK_CFG_6 */
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_CAMTG6_SEL, "camtg6_sel",
+                            camtg6_parents, 0x070, 0x074, 0x078, 0, 3, 7, 0x004, 24),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_UART_SEL, "uart_sel",
+                            uart_parents, 0x070, 0x074, 0x078, 8, 1, 15, 0x004, 25),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_SPI_SEL, "spi_sel",
+                            spi_parents, 0x070, 0x074, 0x078, 16, 2, 23, 0x004, 26),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_MSDC50_0_H_SEL, "msdc50_0_h_sel",
+                            msdc50_0_h_parents, 0x070, 0x074, 0x078, 24, 2, 31, 0x004, 27),
+       /* CLK_CFG_7 */
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_MSDC50_0_SEL, "msdc50_0_sel",
+                            msdc50_0_parents, 0x080, 0x084, 0x088, 0, 3, 7, 0x004, 28),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_MSDC30_1_SEL, "msdc30_1_sel",
+                            msdc30_1_parents, 0x080, 0x084, 0x088, 8, 3, 15, 0x004, 29),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_MSDC30_2_SEL, "msdc30_2_sel",
+                            msdc30_2_parents, 0x080, 0x084, 0x088, 16, 3, 23, 0x004, 30),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_AUDIO_SEL, "audio_sel",
+                            audio_parents, 0x080, 0x084, 0x088, 24, 2, 31, 0x008, 0),
+       /* CLK_CFG_8 */
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_AUD_INTBUS_SEL, "aud_intbus_sel",
+                            aud_intbus_parents, 0x090, 0x094, 0x098, 0, 2, 7, 0x008, 1),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_PWRAP_ULPOSC_SEL, "pwrap_ulposc_sel",
+                            pwrap_ulposc_parents, 0x090, 0x094, 0x098, 8, 3, 15, 0x008, 2),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_ATB_SEL, "atb_sel",
+                            atb_parents, 0x090, 0x094, 0x098, 16, 2, 23, 0x008, 3),
+       /* CLK_CFG_9 */
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_DPI_SEL, "dpi_sel",
+                            dpi_parents, 0x0a0, 0x0a4, 0x0a8, 0, 3, 7, 0x008, 5),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_SCAM_SEL, "scam_sel",
+                            scam_parents, 0x0a0, 0x0a4, 0x0a8, 8, 1, 15, 0x008, 6),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_DISP_PWM_SEL, "disp_pwm_sel",
+                            disp_pwm_parents, 0x0a0, 0x0a4, 0x0a8, 16, 3, 23, 0x008, 7),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_USB_TOP_SEL, "usb_top_sel",
+                            usb_top_parents, 0x0a0, 0x0a4, 0x0a8, 24, 2, 31, 0x008, 8),
+       /* CLK_CFG_10 */
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_SSUSB_XHCI_SEL, "ssusb_xhci_sel",
+                            ssusb_xhci_parents, 0x0b0, 0x0b4, 0x0b8, 0, 2, 7, 0x008, 9),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_I2C_SEL, "i2c_sel",
+                            i2c_parents, 0x0b0, 0x0b4, 0x0b8, 8, 2, 15, 0x008, 10),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_SENINF_SEL, "seninf_sel",
+                            seninf_parents, 0x0b0, 0x0b4, 0x0b8, 16, 3, 23, 0x008, 11),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_SENINF1_SEL, "seninf1_sel",
+                            seninf1_parents, 0x0b0, 0x0b4, 0x0b8, 24, 3, 31, 0x008, 12),
+       /* CLK_CFG_11 */
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_SENINF2_SEL, "seninf2_sel",
+                            seninf2_parents, 0x0c0, 0x0c4, 0x0c8, 0, 3, 7, 0x008, 13),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_SENINF3_SEL, "seninf3_sel",
+                            seninf3_parents, 0x0c0, 0x0c4, 0x0c8, 8, 3, 15, 0x008, 14),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_TL_SEL, "tl_sel",
+                            tl_parents, 0x0c0, 0x0c4, 0x0c8, 16, 2, 23, 0x008, 15),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_DXCC_SEL, "dxcc_sel",
+                            dxcc_parents, 0x0c0, 0x0c4, 0x0c8, 24, 2, 31, 0x008, 16),
+       /* CLK_CFG_12 */
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_AUD_ENGEN1_SEL, "aud_engen1_sel",
+                            aud_engen1_parents, 0x0d0, 0x0d4, 0x0d8, 0, 2, 7, 0x008, 17),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_AUD_ENGEN2_SEL, "aud_engen2_sel",
+                            aud_engen2_parents, 0x0d0, 0x0d4, 0x0d8, 8, 2, 15, 0x008, 18),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_AES_UFSFDE_SEL, "aes_ufsfde_sel",
+                            aes_ufsfde_parents, 0x0d0, 0x0d4, 0x0d8, 16, 3, 23, 0x008, 19),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_UFS_SEL, "ufs_sel",
+                            ufs_parents, 0x0d0, 0x0d4, 0x0d8, 24, 3, 31, 0x008, 20),
+       /* CLK_CFG_13 */
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_AUD_1_SEL, "aud_1_sel",
+                            aud_1_parents, 0x0e0, 0x0e4, 0x0e8, 0, 1, 7, 0x008, 21),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_AUD_2_SEL, "aud_2_sel",
+                            aud_2_parents, 0x0e0, 0x0e4, 0x0e8, 8, 1, 15, 0x008, 22),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_ADSP_SEL, "adsp_sel",
+                            adsp_parents, 0x0e0, 0x0e4, 0x0e8, 16, 3, 23, 0x008, 23),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_DPMAIF_MAIN_SEL, "dpmaif_main_sel",
+                            dpmaif_main_parents, 0x0e0, 0x0e4, 0x0e8, 24, 3, 31, 0x008, 24),
+       /* CLK_CFG_14 */
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_VENC_SEL, "venc_sel",
+                            venc_parents, 0x0f0, 0x0f4, 0x0f8, 0, 4, 7, 0x008, 25),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_VDEC_SEL, "vdec_sel",
+                            vdec_parents, 0x0f0, 0x0f4, 0x0f8, 8, 4, 15, 0x008, 26),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_CAMTM_SEL, "camtm_sel",
+                            camtm_parents, 0x0f0, 0x0f4, 0x0f8, 16, 2, 23, 0x008, 27),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_PWM_SEL, "pwm_sel",
+                            pwm_parents, 0x0f0, 0x0f4, 0x0f8, 24, 1, 31, 0x008, 28),
+       /* CLK_CFG_15 */
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_AUDIO_H_SEL, "audio_h_sel",
+                            audio_h_parents, 0x100, 0x104, 0x108, 0, 2, 7, 0x008, 29),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_SPMI_MST_SEL, "spmi_mst_sel",
+                            spmi_mst_parents, 0x100, 0x104, 0x108, 8, 3, 15, 0x008, 30),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_AES_MSDCFDE_SEL, "aes_msdcfde_sel",
+                            aes_msdcfde_parents, 0x100, 0x104, 0x108, 24, 3, 31, 0x00c, 1),
+       /* CLK_CFG_16 */
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_SFLASH_SEL, "sflash_sel",
+                            sflash_parents, 0x110, 0x114, 0x118, 8, 2, 15, 0x00c, 3),
+};
+
+static struct mtk_composite top_muxes[] = {
+       /* CLK_AUDDIV_0 */
+       MUX(CLK_TOP_APLL_I2S0_M_SEL, "apll_i2s0_m_sel", apll_i2s0_m_parents, 0x320, 16, 1),
+       MUX(CLK_TOP_APLL_I2S1_M_SEL, "apll_i2s1_m_sel", apll_i2s1_m_parents, 0x320, 17, 1),
+       MUX(CLK_TOP_APLL_I2S2_M_SEL, "apll_i2s2_m_sel", apll_i2s2_m_parents, 0x320, 18, 1),
+       MUX(CLK_TOP_APLL_I2S3_M_SEL, "apll_i2s3_m_sel", apll_i2s3_m_parents, 0x320, 19, 1),
+       MUX(CLK_TOP_APLL_I2S4_M_SEL, "apll_i2s4_m_sel", apll_i2s4_m_parents, 0x320, 20, 1),
+       MUX(CLK_TOP_APLL_I2S5_M_SEL, "apll_i2s5_m_sel", apll_i2s5_m_parents, 0x320, 21, 1),
+       MUX(CLK_TOP_APLL_I2S6_M_SEL, "apll_i2s6_m_sel", apll_i2s6_m_parents, 0x320, 22, 1),
+       MUX(CLK_TOP_APLL_I2S7_M_SEL, "apll_i2s7_m_sel", apll_i2s7_m_parents, 0x320, 23, 1),
+       MUX(CLK_TOP_APLL_I2S8_M_SEL, "apll_i2s8_m_sel", apll_i2s8_m_parents, 0x320, 24, 1),
+       MUX(CLK_TOP_APLL_I2S9_M_SEL, "apll_i2s9_m_sel", apll_i2s9_m_parents, 0x320, 25, 1),
+};
+
+static const struct mtk_composite top_adj_divs[] = {
+       DIV_GATE(CLK_TOP_APLL12_DIV0, "apll12_div0", "apll_i2s0_m_sel", 0x320, 0, 0x328, 8, 0),
+       DIV_GATE(CLK_TOP_APLL12_DIV1, "apll12_div1", "apll_i2s1_m_sel", 0x320, 1, 0x328, 8, 8),
+       DIV_GATE(CLK_TOP_APLL12_DIV2, "apll12_div2", "apll_i2s2_m_sel", 0x320, 2, 0x328, 8, 16),
+       DIV_GATE(CLK_TOP_APLL12_DIV3, "apll12_div3", "apll_i2s3_m_sel", 0x320, 3, 0x328, 8, 24),
+       DIV_GATE(CLK_TOP_APLL12_DIV4, "apll12_div4", "apll_i2s4_m_sel", 0x320, 4, 0x334, 8, 0),
+       DIV_GATE(CLK_TOP_APLL12_DIVB, "apll12_divb", "apll12_div4", 0x320, 5, 0x334, 8, 8),
+       DIV_GATE(CLK_TOP_APLL12_DIV5, "apll12_div5", "apll_i2s5_m_sel", 0x320, 6, 0x334, 8, 16),
+       DIV_GATE(CLK_TOP_APLL12_DIV6, "apll12_div6", "apll_i2s6_m_sel", 0x320, 7, 0x334, 8, 24),
+       DIV_GATE(CLK_TOP_APLL12_DIV7, "apll12_div7", "apll_i2s7_m_sel", 0x320, 8, 0x338, 8, 0),
+       DIV_GATE(CLK_TOP_APLL12_DIV8, "apll12_div8", "apll_i2s8_m_sel", 0x320, 9, 0x338, 8, 8),
+       DIV_GATE(CLK_TOP_APLL12_DIV9, "apll12_div9", "apll_i2s9_m_sel", 0x320, 10, 0x338, 8, 16),
+};
+
+static const struct mtk_gate_regs apmixed_cg_regs = {
+       .set_ofs = 0x14,
+       .clr_ofs = 0x14,
+       .sta_ofs = 0x14,
+};
+
+#define GATE_APMIXED(_id, _name, _parent, _shift)      \
+       GATE_MTK(_id, _name, _parent, &apmixed_cg_regs, _shift, &mtk_clk_gate_ops_no_setclr_inv)
+
+static const struct mtk_gate apmixed_clks[] = {
+       GATE_APMIXED(CLK_APMIXED_MIPID26M, "mipid26m", "clk26m", 16),
+};
+
+static const struct mtk_gate_regs infra0_cg_regs = {
+       .set_ofs = 0x80,
+       .clr_ofs = 0x84,
+       .sta_ofs = 0x90,
+};
+
+static const struct mtk_gate_regs infra1_cg_regs = {
+       .set_ofs = 0x88,
+       .clr_ofs = 0x8c,
+       .sta_ofs = 0x94,
+};
+
+static const struct mtk_gate_regs infra2_cg_regs = {
+       .set_ofs = 0xa4,
+       .clr_ofs = 0xa8,
+       .sta_ofs = 0xac,
+};
+
+static const struct mtk_gate_regs infra3_cg_regs = {
+       .set_ofs = 0xc0,
+       .clr_ofs = 0xc4,
+       .sta_ofs = 0xc8,
+};
+
+static const struct mtk_gate_regs infra4_cg_regs = {
+       .set_ofs = 0xd0,
+       .clr_ofs = 0xd4,
+       .sta_ofs = 0xd8,
+};
+
+static const struct mtk_gate_regs infra5_cg_regs = {
+       .set_ofs = 0xe0,
+       .clr_ofs = 0xe4,
+       .sta_ofs = 0xe8,
+};
+
+#define GATE_INFRA0(_id, _name, _parent, _shift)       \
+       GATE_MTK(_id, _name, _parent, &infra0_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
+
+#define GATE_INFRA1_FLAGS(_id, _name, _parent, _shift, _flag)          \
+       GATE_MTK_FLAGS(_id, _name, _parent, &infra1_cg_regs, _shift,    \
+               &mtk_clk_gate_ops_setclr, _flag)
+
+#define GATE_INFRA1(_id, _name, _parent, _shift)       \
+       GATE_INFRA1_FLAGS(_id, _name, _parent, _shift, 0)
+
+#define GATE_INFRA2(_id, _name, _parent, _shift)       \
+       GATE_MTK(_id, _name, _parent, &infra2_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
+
+#define GATE_INFRA3_FLAGS(_id, _name, _parent, _shift, _flag)          \
+       GATE_MTK_FLAGS(_id, _name, _parent, &infra3_cg_regs, _shift,    \
+               &mtk_clk_gate_ops_setclr, _flag)
+
+#define GATE_INFRA3(_id, _name, _parent, _shift)       \
+       GATE_INFRA3_FLAGS(_id, _name, _parent, _shift, 0)
+
+#define GATE_INFRA4(_id, _name, _parent, _shift)       \
+       GATE_MTK(_id, _name, _parent, &infra4_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
+
+#define GATE_INFRA5_FLAGS(_id, _name, _parent, _shift, _flag)          \
+       GATE_MTK_FLAGS(_id, _name, _parent, &infra5_cg_regs, _shift,    \
+               &mtk_clk_gate_ops_setclr, _flag)
+
+#define GATE_INFRA5(_id, _name, _parent, _shift)       \
+       GATE_INFRA5_FLAGS(_id, _name, _parent, _shift, 0)
+
+/*
+ * CRITICAL CLOCK:
+ * infra_133m and infra_66m are main peripheral bus clocks of SOC.
+ * infra_device_apc and infra_device_apc_sync are for device access permission control module.
+ */
+static const struct mtk_gate infra_clks[] = {
+       /* INFRA0 */
+       GATE_INFRA0(CLK_INFRA_PMIC_TMR, "infra_pmic_tmr", "pwrap_ulposc_sel", 0),
+       GATE_INFRA0(CLK_INFRA_PMIC_AP, "infra_pmic_ap", "pwrap_ulposc_sel", 1),
+       GATE_INFRA0(CLK_INFRA_PMIC_MD, "infra_pmic_md", "pwrap_ulposc_sel", 2),
+       GATE_INFRA0(CLK_INFRA_PMIC_CONN, "infra_pmic_conn", "pwrap_ulposc_sel", 3),
+       GATE_INFRA0(CLK_INFRA_SCPSYS, "infra_scpsys", "scp_sel", 4),
+       GATE_INFRA0(CLK_INFRA_SEJ, "infra_sej", "axi_sel", 5),
+       GATE_INFRA0(CLK_INFRA_APXGPT, "infra_apxgpt", "axi_sel", 6),
+       GATE_INFRA0(CLK_INFRA_GCE, "infra_gce", "axi_sel", 8),
+       GATE_INFRA0(CLK_INFRA_GCE2, "infra_gce2", "axi_sel", 9),
+       GATE_INFRA0(CLK_INFRA_THERM, "infra_therm", "axi_sel", 10),
+       GATE_INFRA0(CLK_INFRA_I2C0, "infra_i2c0", "i2c_sel", 11),
+       GATE_INFRA0(CLK_INFRA_AP_DMA_PSEUDO, "infra_ap_dma_pseudo", "axi_sel", 12),
+       GATE_INFRA0(CLK_INFRA_I2C2, "infra_i2c2", "i2c_sel", 13),
+       GATE_INFRA0(CLK_INFRA_I2C3, "infra_i2c3", "i2c_sel", 14),
+       GATE_INFRA0(CLK_INFRA_PWM_H, "infra_pwm_h", "axi_sel", 15),
+       GATE_INFRA0(CLK_INFRA_PWM1, "infra_pwm1", "pwm_sel", 16),
+       GATE_INFRA0(CLK_INFRA_PWM2, "infra_pwm2", "pwm_sel", 17),
+       GATE_INFRA0(CLK_INFRA_PWM3, "infra_pwm3", "pwm_sel", 18),
+       GATE_INFRA0(CLK_INFRA_PWM4, "infra_pwm4", "pwm_sel", 19),
+       GATE_INFRA0(CLK_INFRA_PWM, "infra_pwm", "pwm_sel", 21),
+       GATE_INFRA0(CLK_INFRA_UART0, "infra_uart0", "uart_sel", 22),
+       GATE_INFRA0(CLK_INFRA_UART1, "infra_uart1", "uart_sel", 23),
+       GATE_INFRA0(CLK_INFRA_UART2, "infra_uart2", "uart_sel", 24),
+       GATE_INFRA0(CLK_INFRA_UART3, "infra_uart3", "uart_sel", 25),
+       GATE_INFRA0(CLK_INFRA_GCE_26M, "infra_gce_26m", "axi_sel", 27),
+       GATE_INFRA0(CLK_INFRA_CQ_DMA_FPC, "infra_cq_dma_fpc", "axi_sel", 28),
+       GATE_INFRA0(CLK_INFRA_BTIF, "infra_btif", "axi_sel", 31),
+       /* INFRA1 */
+       GATE_INFRA1(CLK_INFRA_SPI0, "infra_spi0", "spi_sel", 1),
+       GATE_INFRA1(CLK_INFRA_MSDC0, "infra_msdc0", "msdc50_0_h_sel", 2),
+       GATE_INFRA1(CLK_INFRA_MSDC1, "infra_msdc1", "msdc50_0_h_sel", 4),
+       GATE_INFRA1(CLK_INFRA_MSDC2, "infra_msdc2", "msdc50_0_h_sel", 5),
+       GATE_INFRA1(CLK_INFRA_MSDC0_SRC, "infra_msdc0_src", "msdc50_0_sel", 6),
+       GATE_INFRA1(CLK_INFRA_GCPU, "infra_gcpu", "axi_sel", 8),
+       GATE_INFRA1(CLK_INFRA_TRNG, "infra_trng", "axi_sel", 9),
+       GATE_INFRA1(CLK_INFRA_AUXADC, "infra_auxadc", "clk26m", 10),
+       GATE_INFRA1(CLK_INFRA_CPUM, "infra_cpum", "axi_sel", 11),
+       GATE_INFRA1(CLK_INFRA_CCIF1_AP, "infra_ccif1_ap", "axi_sel", 12),
+       GATE_INFRA1(CLK_INFRA_CCIF1_MD, "infra_ccif1_md", "axi_sel", 13),
+       GATE_INFRA1(CLK_INFRA_AUXADC_MD, "infra_auxadc_md", "clk26m", 14),
+       GATE_INFRA1(CLK_INFRA_PCIE_TL_26M, "infra_pcie_tl_26m", "axi_sel", 15),
+       GATE_INFRA1(CLK_INFRA_MSDC1_SRC, "infra_msdc1_src", "msdc30_1_sel", 16),
+       GATE_INFRA1(CLK_INFRA_MSDC2_SRC, "infra_msdc2_src", "msdc30_2_sel", 17),
+       GATE_INFRA1(CLK_INFRA_PCIE_TL_96M, "infra_pcie_tl_96m", "tl_sel", 18),
+       GATE_INFRA1(CLK_INFRA_PCIE_PL_P_250M, "infra_pcie_pl_p_250m", "axi_sel", 19),
+       GATE_INFRA1_FLAGS(CLK_INFRA_DEVICE_APC, "infra_device_apc", "axi_sel", 20, CLK_IS_CRITICAL),
+       GATE_INFRA1(CLK_INFRA_CCIF_AP, "infra_ccif_ap", "axi_sel", 23),
+       GATE_INFRA1(CLK_INFRA_DEBUGSYS, "infra_debugsys", "axi_sel", 24),
+       GATE_INFRA1(CLK_INFRA_AUDIO, "infra_audio", "axi_sel", 25),
+       GATE_INFRA1(CLK_INFRA_CCIF_MD, "infra_ccif_md", "axi_sel", 26),
+       GATE_INFRA1(CLK_INFRA_DXCC_SEC_CORE, "infra_dxcc_sec_core", "dxcc_sel", 27),
+       GATE_INFRA1(CLK_INFRA_DXCC_AO, "infra_dxcc_ao", "dxcc_sel", 28),
+       GATE_INFRA1(CLK_INFRA_DBG_TRACE, "infra_dbg_trace", "axi_sel", 29),
+       GATE_INFRA1(CLK_INFRA_DEVMPU_B, "infra_devmpu_b", "axi_sel", 30),
+       GATE_INFRA1(CLK_INFRA_DRAMC_F26M, "infra_dramc_f26m", "clk26m", 31),
+       /* INFRA2 */
+       GATE_INFRA2(CLK_INFRA_IRTX, "infra_irtx", "clk26m", 0),
+       GATE_INFRA2(CLK_INFRA_SSUSB, "infra_ssusb", "usb_top_sel", 1),
+       GATE_INFRA2(CLK_INFRA_DISP_PWM, "infra_disp_pwm", "axi_sel", 2),
+       GATE_INFRA2(CLK_INFRA_CLDMA_B, "infra_cldma_b", "axi_sel", 3),
+       GATE_INFRA2(CLK_INFRA_AUDIO_26M_B, "infra_audio_26m_b", "clk26m", 4),
+       GATE_INFRA2(CLK_INFRA_MODEM_TEMP_SHARE, "infra_modem_temp_share", "clk26m", 5),
+       GATE_INFRA2(CLK_INFRA_SPI1, "infra_spi1", "spi_sel", 6),
+       GATE_INFRA2(CLK_INFRA_I2C4, "infra_i2c4", "i2c_sel", 7),
+       GATE_INFRA2(CLK_INFRA_SPI2, "infra_spi2", "spi_sel", 9),
+       GATE_INFRA2(CLK_INFRA_SPI3, "infra_spi3", "spi_sel", 10),
+       GATE_INFRA2(CLK_INFRA_UNIPRO_SYS, "infra_unipro_sys", "ufs_sel", 11),
+       GATE_INFRA2(CLK_INFRA_UNIPRO_TICK, "infra_unipro_tick", "clk26m", 12),
+       GATE_INFRA2(CLK_INFRA_UFS_MP_SAP_B, "infra_ufs_mp_sap_b", "clk26m", 13),
+       GATE_INFRA2(CLK_INFRA_MD32_B, "infra_md32_b", "axi_sel", 14),
+       GATE_INFRA2(CLK_INFRA_UNIPRO_MBIST, "infra_unipro_mbist", "axi_sel", 16),
+       GATE_INFRA2(CLK_INFRA_I2C5, "infra_i2c5", "i2c_sel", 18),
+       GATE_INFRA2(CLK_INFRA_I2C5_ARBITER, "infra_i2c5_arbiter", "i2c_sel", 19),
+       GATE_INFRA2(CLK_INFRA_I2C5_IMM, "infra_i2c5_imm", "i2c_sel", 20),
+       GATE_INFRA2(CLK_INFRA_I2C1_ARBITER, "infra_i2c1_arbiter", "i2c_sel", 21),
+       GATE_INFRA2(CLK_INFRA_I2C1_IMM, "infra_i2c1_imm", "i2c_sel", 22),
+       GATE_INFRA2(CLK_INFRA_I2C2_ARBITER, "infra_i2c2_arbiter", "i2c_sel", 23),
+       GATE_INFRA2(CLK_INFRA_I2C2_IMM, "infra_i2c2_imm", "i2c_sel", 24),
+       GATE_INFRA2(CLK_INFRA_SPI4, "infra_spi4", "spi_sel", 25),
+       GATE_INFRA2(CLK_INFRA_SPI5, "infra_spi5", "spi_sel", 26),
+       GATE_INFRA2(CLK_INFRA_CQ_DMA, "infra_cq_dma", "axi_sel", 27),
+       GATE_INFRA2(CLK_INFRA_UFS, "infra_ufs", "ufs_sel", 28),
+       GATE_INFRA2(CLK_INFRA_AES_UFSFDE, "infra_aes_ufsfde", "aes_ufsfde_sel", 29),
+       GATE_INFRA2(CLK_INFRA_UFS_TICK, "infra_ufs_tick", "ufs_sel", 30),
+       GATE_INFRA2(CLK_INFRA_SSUSB_XHCI, "infra_ssusb_xhci", "ssusb_xhci_sel", 31),
+       /* INFRA3 */
+       GATE_INFRA3(CLK_INFRA_MSDC0_SELF, "infra_msdc0_self", "msdc50_0_sel", 0),
+       GATE_INFRA3(CLK_INFRA_MSDC1_SELF, "infra_msdc1_self", "msdc50_0_sel", 1),
+       GATE_INFRA3(CLK_INFRA_MSDC2_SELF, "infra_msdc2_self", "msdc50_0_sel", 2),
+       GATE_INFRA3(CLK_INFRA_UFS_AXI, "infra_ufs_axi", "axi_sel", 5),
+       GATE_INFRA3(CLK_INFRA_I2C6, "infra_i2c6", "i2c_sel", 6),
+       GATE_INFRA3(CLK_INFRA_AP_MSDC0, "infra_ap_msdc0", "msdc50_0_sel", 7),
+       GATE_INFRA3(CLK_INFRA_MD_MSDC0, "infra_md_msdc0", "msdc50_0_sel", 8),
+       GATE_INFRA3(CLK_INFRA_CCIF5_AP, "infra_ccif5_ap", "axi_sel", 9),
+       GATE_INFRA3(CLK_INFRA_CCIF5_MD, "infra_ccif5_md", "axi_sel", 10),
+       GATE_INFRA3(CLK_INFRA_PCIE_TOP_H_133M, "infra_pcie_top_h_133m", "axi_sel", 11),
+       GATE_INFRA3(CLK_INFRA_FLASHIF_TOP_H_133M, "infra_flashif_top_h_133m", "axi_sel", 14),
+       GATE_INFRA3(CLK_INFRA_PCIE_PERI_26M, "infra_pcie_peri_26m", "axi_sel", 15),
+       GATE_INFRA3(CLK_INFRA_CCIF2_AP, "infra_ccif2_ap", "axi_sel", 16),
+       GATE_INFRA3(CLK_INFRA_CCIF2_MD, "infra_ccif2_md", "axi_sel", 17),
+       GATE_INFRA3(CLK_INFRA_CCIF3_AP, "infra_ccif3_ap", "axi_sel", 18),
+       GATE_INFRA3(CLK_INFRA_CCIF3_MD, "infra_ccif3_md", "axi_sel", 19),
+       GATE_INFRA3(CLK_INFRA_SEJ_F13M, "infra_sej_f13m", "clk26m", 20),
+       GATE_INFRA3(CLK_INFRA_AES, "infra_aes", "axi_sel", 21),
+       GATE_INFRA3(CLK_INFRA_I2C7, "infra_i2c7", "i2c_sel", 22),
+       GATE_INFRA3(CLK_INFRA_I2C8, "infra_i2c8", "i2c_sel", 23),
+       GATE_INFRA3(CLK_INFRA_FBIST2FPC, "infra_fbist2fpc", "msdc50_0_sel", 24),
+       GATE_INFRA3_FLAGS(CLK_INFRA_DEVICE_APC_SYNC, "infra_device_apc_sync", "axi_sel", 25,
+                         CLK_IS_CRITICAL),
+       GATE_INFRA3(CLK_INFRA_DPMAIF_MAIN, "infra_dpmaif_main", "dpmaif_main_sel", 26),
+       GATE_INFRA3(CLK_INFRA_PCIE_TL_32K, "infra_pcie_tl_32k", "axi_sel", 27),
+       GATE_INFRA3(CLK_INFRA_CCIF4_AP, "infra_ccif4_ap", "axi_sel", 28),
+       GATE_INFRA3(CLK_INFRA_CCIF4_MD, "infra_ccif4_md", "axi_sel", 29),
+       GATE_INFRA3(CLK_INFRA_SPI6, "infra_spi6", "spi_sel", 30),
+       GATE_INFRA3(CLK_INFRA_SPI7, "infra_spi7", "spi_sel", 31),
+       /* INFRA4 */
+       GATE_INFRA4(CLK_INFRA_AP_DMA, "infra_ap_dma", "infra_ap_dma_pseudo", 31),
+       /* INFRA5 */
+       GATE_INFRA5_FLAGS(CLK_INFRA_133M, "infra_133m", "axi_sel", 0, CLK_IS_CRITICAL),
+       GATE_INFRA5_FLAGS(CLK_INFRA_66M, "infra_66m", "axi_sel", 1, CLK_IS_CRITICAL),
+       GATE_INFRA5(CLK_INFRA_66M_PERI_BUS, "infra_66m_peri_bus", "axi_sel", 2),
+       GATE_INFRA5(CLK_INFRA_FREE_DCM_133M, "infra_free_dcm_133m", "axi_sel", 3),
+       GATE_INFRA5(CLK_INFRA_FREE_DCM_66M, "infra_free_dcm_66m", "axi_sel", 4),
+       GATE_INFRA5(CLK_INFRA_PERI_BUS_DCM_133M, "infra_peri_bus_dcm_133m", "axi_sel", 5),
+       GATE_INFRA5(CLK_INFRA_PERI_BUS_DCM_66M, "infra_peri_bus_dcm_66m", "axi_sel", 6),
+       GATE_INFRA5(CLK_INFRA_FLASHIF_PERI_26M, "infra_flashif_peri_26m", "axi_sel", 30),
+       GATE_INFRA5(CLK_INFRA_FLASHIF_SFLASH, "infra_flashif_fsflash", "axi_sel", 31),
+};
+
+static const struct mtk_gate_regs peri_cg_regs = {
+       .set_ofs = 0x20c,
+       .clr_ofs = 0x20c,
+       .sta_ofs = 0x20c,
+};
+
+#define GATE_PERI(_id, _name, _parent, _shift) \
+       GATE_MTK(_id, _name, _parent, &peri_cg_regs, _shift, &mtk_clk_gate_ops_no_setclr_inv)
+
+static const struct mtk_gate peri_clks[] = {
+       GATE_PERI(CLK_PERI_PERIAXI, "peri_periaxi", "axi_sel", 31),
+};
+
+static const struct mtk_gate_regs top_cg_regs = {
+       .set_ofs = 0x150,
+       .clr_ofs = 0x150,
+       .sta_ofs = 0x150,
+};
+
+#define GATE_TOP(_id, _name, _parent, _shift)  \
+       GATE_MTK(_id, _name, _parent, &top_cg_regs, _shift, &mtk_clk_gate_ops_no_setclr_inv)
+
+static const struct mtk_gate top_clks[] = {
+       GATE_TOP(CLK_TOP_SSUSB_TOP_REF, "ssusb_top_ref", "clk26m", 24),
+       GATE_TOP(CLK_TOP_SSUSB_PHY_REF, "ssusb_phy_ref", "clk26m", 25),
+};
+
+#define MT8192_PLL_FMAX                (3800UL * MHZ)
+#define MT8192_PLL_FMIN                (1500UL * MHZ)
+#define MT8192_INTEGER_BITS    8
+
+#define PLL(_id, _name, _reg, _pwr_reg, _en_mask, _flags,              \
+                       _rst_bar_mask, _pcwbits, _pd_reg, _pd_shift,    \
+                       _tuner_reg, _tuner_en_reg, _tuner_en_bit,       \
+                       _pcw_reg, _pcw_shift, _pcw_chg_reg,             \
+                       _en_reg, _pll_en_bit) {                         \
+               .id = _id,                                              \
+               .name = _name,                                          \
+               .reg = _reg,                                            \
+               .pwr_reg = _pwr_reg,                                    \
+               .en_mask = _en_mask,                                    \
+               .flags = _flags,                                        \
+               .rst_bar_mask = _rst_bar_mask,                          \
+               .fmax = MT8192_PLL_FMAX,                                \
+               .fmin = MT8192_PLL_FMIN,                                \
+               .pcwbits = _pcwbits,                                    \
+               .pcwibits = MT8192_INTEGER_BITS,                        \
+               .pd_reg = _pd_reg,                                      \
+               .pd_shift = _pd_shift,                                  \
+               .tuner_reg = _tuner_reg,                                \
+               .tuner_en_reg = _tuner_en_reg,                          \
+               .tuner_en_bit = _tuner_en_bit,                          \
+               .pcw_reg = _pcw_reg,                                    \
+               .pcw_shift = _pcw_shift,                                \
+               .pcw_chg_reg = _pcw_chg_reg,                            \
+               .en_reg = _en_reg,                                      \
+               .pll_en_bit = _pll_en_bit,                              \
+       }
+
+#define PLL_B(_id, _name, _reg, _pwr_reg, _en_mask, _flags,            \
+                       _rst_bar_mask, _pcwbits, _pd_reg, _pd_shift,    \
+                       _tuner_reg, _tuner_en_reg, _tuner_en_bit,       \
+                       _pcw_reg, _pcw_shift)                           \
+               PLL(_id, _name, _reg, _pwr_reg, _en_mask, _flags,       \
+                       _rst_bar_mask, _pcwbits, _pd_reg, _pd_shift,    \
+                       _tuner_reg, _tuner_en_reg, _tuner_en_bit,       \
+                       _pcw_reg, _pcw_shift, 0, 0, 0)
+
+static const struct mtk_pll_data plls[] = {
+       PLL_B(CLK_APMIXED_MAINPLL, "mainpll", 0x0340, 0x034c, 0xff000000,
+             HAVE_RST_BAR, BIT(23), 22, 0x0344, 24, 0, 0, 0, 0x0344, 0),
+       PLL_B(CLK_APMIXED_UNIVPLL, "univpll", 0x0308, 0x0314, 0xff000000,
+             HAVE_RST_BAR, BIT(23), 22, 0x030c, 24, 0, 0, 0, 0x030c, 0),
+       PLL(CLK_APMIXED_USBPLL, "usbpll", 0x03c4, 0x03cc, 0x00000000,
+           0, 0, 22, 0x03c4, 24, 0, 0, 0, 0x03c4, 0, 0x03c4, 0x03cc, 2),
+       PLL_B(CLK_APMIXED_MSDCPLL, "msdcpll", 0x0350, 0x035c, 0x00000000,
+             0, 0, 22, 0x0354, 24, 0, 0, 0, 0x0354, 0),
+       PLL_B(CLK_APMIXED_MMPLL, "mmpll", 0x0360, 0x036c, 0xff000000,
+             HAVE_RST_BAR, BIT(23), 22, 0x0364, 24, 0, 0, 0, 0x0364, 0),
+       PLL_B(CLK_APMIXED_ADSPPLL, "adsppll", 0x0370, 0x037c, 0xff000000,
+             HAVE_RST_BAR, BIT(23), 22, 0x0374, 24, 0, 0, 0, 0x0374, 0),
+       PLL_B(CLK_APMIXED_MFGPLL, "mfgpll", 0x0268, 0x0274, 0x00000000,
+             0, 0, 22, 0x026c, 24, 0, 0, 0, 0x026c, 0),
+       PLL_B(CLK_APMIXED_TVDPLL, "tvdpll", 0x0380, 0x038c, 0x00000000,
+             0, 0, 22, 0x0384, 24, 0, 0, 0, 0x0384, 0),
+       PLL_B(CLK_APMIXED_APLL1, "apll1", 0x0318, 0x0328, 0x00000000,
+             0, 0, 32, 0x031c, 24, 0x0040, 0x000c, 0, 0x0320, 0),
+       PLL_B(CLK_APMIXED_APLL2, "apll2", 0x032c, 0x033c, 0x00000000,
+             0, 0, 32, 0x0330, 24, 0, 0, 0, 0x0334, 0),
+};
+
+static struct clk_onecell_data *top_clk_data;
+
+static void clk_mt8192_top_init_early(struct device_node *node)
+{
+       int i;
+
+       top_clk_data = mtk_alloc_clk_data(CLK_TOP_NR_CLK);
+       if (!top_clk_data)
+               return;
+
+       for (i = 0; i < CLK_TOP_NR_CLK; i++)
+               top_clk_data->clks[i] = ERR_PTR(-EPROBE_DEFER);
+
+       mtk_clk_register_factors(top_early_divs, ARRAY_SIZE(top_early_divs), top_clk_data);
+
+       of_clk_add_provider(node, of_clk_src_onecell_get, top_clk_data);
+}
+
+CLK_OF_DECLARE_DRIVER(mt8192_topckgen, "mediatek,mt8192-topckgen",
+                     clk_mt8192_top_init_early);
+
+static int clk_mt8192_top_probe(struct platform_device *pdev)
+{
+       struct device_node *node = pdev->dev.of_node;
+       int r;
+       void __iomem *base;
+
+       base = devm_platform_ioremap_resource(pdev, 0);
+       if (IS_ERR(base))
+               return PTR_ERR(base);
+
+       mtk_clk_register_fixed_clks(top_fixed_clks, ARRAY_SIZE(top_fixed_clks), top_clk_data);
+       mtk_clk_register_factors(top_early_divs, ARRAY_SIZE(top_early_divs), top_clk_data);
+       mtk_clk_register_factors(top_divs, ARRAY_SIZE(top_divs), top_clk_data);
+       mtk_clk_register_muxes(top_mtk_muxes, ARRAY_SIZE(top_mtk_muxes), node, &mt8192_clk_lock,
+                              top_clk_data);
+       mtk_clk_register_composites(top_muxes, ARRAY_SIZE(top_muxes), base, &mt8192_clk_lock,
+                                   top_clk_data);
+       mtk_clk_register_composites(top_adj_divs, ARRAY_SIZE(top_adj_divs), base, &mt8192_clk_lock,
+                                   top_clk_data);
+       r = mtk_clk_register_gates(node, top_clks, ARRAY_SIZE(top_clks), top_clk_data);
+       if (r)
+               return r;
+
+       return of_clk_add_provider(node, of_clk_src_onecell_get, top_clk_data);
+}
+
+static int clk_mt8192_infra_probe(struct platform_device *pdev)
+{
+       struct clk_onecell_data *clk_data;
+       struct device_node *node = pdev->dev.of_node;
+       int r;
+
+       clk_data = mtk_alloc_clk_data(CLK_INFRA_NR_CLK);
+       if (!clk_data)
+               return -ENOMEM;
+
+       r = mtk_clk_register_gates(node, infra_clks, ARRAY_SIZE(infra_clks), clk_data);
+       if (r)
+               return r;
+
+       return of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+}
+
+static int clk_mt8192_peri_probe(struct platform_device *pdev)
+{
+       struct clk_onecell_data *clk_data;
+       struct device_node *node = pdev->dev.of_node;
+       int r;
+
+       clk_data = mtk_alloc_clk_data(CLK_PERI_NR_CLK);
+       if (!clk_data)
+               return -ENOMEM;
+
+       r = mtk_clk_register_gates(node, peri_clks, ARRAY_SIZE(peri_clks), clk_data);
+       if (r)
+               return r;
+
+       return of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+}
+
+static int clk_mt8192_apmixed_probe(struct platform_device *pdev)
+{
+       struct clk_onecell_data *clk_data;
+       struct device_node *node = pdev->dev.of_node;
+       int r;
+
+       clk_data = mtk_alloc_clk_data(CLK_APMIXED_NR_CLK);
+       if (!clk_data)
+               return -ENOMEM;
+
+       mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls), clk_data);
+       r = mtk_clk_register_gates(node, apmixed_clks, ARRAY_SIZE(apmixed_clks), clk_data);
+       if (r)
+               return r;
+
+       return of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+}
+
+static const struct of_device_id of_match_clk_mt8192[] = {
+       {
+               .compatible = "mediatek,mt8192-apmixedsys",
+               .data = clk_mt8192_apmixed_probe,
+       }, {
+               .compatible = "mediatek,mt8192-topckgen",
+               .data = clk_mt8192_top_probe,
+       }, {
+               .compatible = "mediatek,mt8192-infracfg",
+               .data = clk_mt8192_infra_probe,
+       }, {
+               .compatible = "mediatek,mt8192-pericfg",
+               .data = clk_mt8192_peri_probe,
+       }, {
+               /* sentinel */
+       }
+};
+
+static int clk_mt8192_probe(struct platform_device *pdev)
+{
+       int (*clk_probe)(struct platform_device *pdev);
+       int r;
+
+       clk_probe = of_device_get_match_data(&pdev->dev);
+       if (!clk_probe)
+               return -EINVAL;
+
+       r = clk_probe(pdev);
+       if (r)
+               dev_err(&pdev->dev, "could not register clock provider: %s: %d\n", pdev->name, r);
+
+       return r;
+}
+
+static struct platform_driver clk_mt8192_drv = {
+       .probe = clk_mt8192_probe,
+       .driver = {
+               .name = "clk-mt8192",
+               .of_match_table = of_match_clk_mt8192,
+       },
+};
+
+static int __init clk_mt8192_init(void)
+{
+       return platform_driver_register(&clk_mt8192_drv);
+}
+
+arch_initcall(clk_mt8192_init);
index cec1c8a..4b6096c 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/clkdev.h>
 #include <linux/mfd/syscon.h>
 #include <linux/device.h>
+#include <linux/of_device.h>
 
 #include "clk-mtk.h"
 #include "clk-gate.h"
@@ -106,7 +107,7 @@ int mtk_clk_register_gates_with_dev(struct device_node *node,
        if (!clk_data)
                return -ENOMEM;
 
-       regmap = syscon_node_to_regmap(node);
+       regmap = device_node_to_regmap(node);
        if (IS_ERR(regmap)) {
                pr_err("Cannot find regmap for %pOF: %ld\n", node,
                                PTR_ERR(regmap));
@@ -286,3 +287,25 @@ void mtk_clk_register_dividers(const struct mtk_clk_divider *mcds,
                        clk_data->clks[mcd->id] = clk;
        }
 }
+
+int mtk_clk_simple_probe(struct platform_device *pdev)
+{
+       const struct mtk_clk_desc *mcd;
+       struct clk_onecell_data *clk_data;
+       struct device_node *node = pdev->dev.of_node;
+       int r;
+
+       mcd = of_device_get_match_data(&pdev->dev);
+       if (!mcd)
+               return -EINVAL;
+
+       clk_data = mtk_alloc_clk_data(mcd->num_clks);
+       if (!clk_data)
+               return -ENOMEM;
+
+       r = mtk_clk_register_gates(node, mcd->clks, mcd->num_clks, clk_data);
+       if (r)
+               return r;
+
+       return of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+}
index c3d6756..7de41c3 100644 (file)
@@ -10,6 +10,7 @@
 #include <linux/regmap.h>
 #include <linux/bitops.h>
 #include <linux/clk-provider.h>
+#include <linux/platform_device.h>
 
 struct clk;
 struct clk_onecell_data;
@@ -213,13 +214,13 @@ struct mtk_pll_div_table {
 struct mtk_pll_data {
        int id;
        const char *name;
-       uint32_t reg;
-       uint32_t pwr_reg;
-       uint32_t en_mask;
-       uint32_t pd_reg;
-       uint32_t tuner_reg;
-       uint32_t tuner_en_reg;
-       uint8_t tuner_en_bit;
+       u32 reg;
+       u32 pwr_reg;
+       u32 en_mask;
+       u32 pd_reg;
+       u32 tuner_reg;
+       u32 tuner_en_reg;
+       u8 tuner_en_bit;
        int pd_shift;
        unsigned int flags;
        const struct clk_ops *ops;
@@ -228,11 +229,13 @@ struct mtk_pll_data {
        unsigned long fmax;
        int pcwbits;
        int pcwibits;
-       uint32_t pcw_reg;
+       u32 pcw_reg;
        int pcw_shift;
-       uint32_t pcw_chg_reg;
+       u32 pcw_chg_reg;
        const struct mtk_pll_div_table *div_table;
        const char *parent_name;
+       u32 en_reg;
+       u8 pll_en_bit; /* Assume 0, indicates BIT(0) by default */
 };
 
 void mtk_clk_register_plls(struct device_node *node,
@@ -248,4 +251,11 @@ void mtk_register_reset_controller(struct device_node *np,
 void mtk_register_reset_controller_set_clr(struct device_node *np,
        unsigned int num_regs, int regofs);
 
+struct mtk_clk_desc {
+       const struct mtk_gate *clks;
+       size_t num_clks;
+};
+
+int mtk_clk_simple_probe(struct platform_device *pdev);
+
 #endif /* __DRV_CLK_MTK_H */
index b0c6170..855b0a1 100644 (file)
@@ -116,7 +116,12 @@ static int mtk_clk_mux_set_parent_setclr_lock(struct clk_hw *hw, u8 index)
        return 0;
 }
 
-static const struct clk_ops mtk_mux_ops = {
+const struct clk_ops mtk_mux_clr_set_upd_ops = {
+       .get_parent = mtk_clk_mux_get_parent,
+       .set_parent = mtk_clk_mux_set_parent_setclr_lock,
+};
+
+const struct clk_ops mtk_mux_gate_clr_set_upd_ops  = {
        .enable = mtk_clk_mux_enable_setclr,
        .disable = mtk_clk_mux_disable_setclr,
        .is_enabled = mtk_clk_mux_is_enabled,
@@ -140,7 +145,7 @@ static struct clk *mtk_clk_register_mux(const struct mtk_mux *mux,
        init.flags = mux->flags | CLK_SET_RATE_PARENT;
        init.parent_names = mux->parent_names;
        init.num_parents = mux->num_parents;
-       init.ops = &mtk_mux_ops;
+       init.ops = mux->ops;
 
        clk_mux->regmap = regmap;
        clk_mux->data = mux;
@@ -165,7 +170,7 @@ int mtk_clk_register_muxes(const struct mtk_mux *muxes,
        struct clk *clk;
        int i;
 
-       regmap = syscon_node_to_regmap(node);
+       regmap = device_node_to_regmap(node);
        if (IS_ERR(regmap)) {
                pr_err("Cannot find regmap for %pOF: %ld\n", node,
                       PTR_ERR(regmap));
index f194616..27841d6 100644 (file)
@@ -33,12 +33,13 @@ struct mtk_mux {
        u8 gate_shift;
        s8 upd_shift;
 
+       const struct clk_ops *ops;
        signed char num_parents;
 };
 
 #define GATE_CLR_SET_UPD_FLAGS(_id, _name, _parents, _mux_ofs,         \
                        _mux_set_ofs, _mux_clr_ofs, _shift, _width,     \
-                       _gate, _upd_ofs, _upd, _flags) {                \
+                       _gate, _upd_ofs, _upd, _flags, _ops) {          \
                .id = _id,                                              \
                .name = _name,                                          \
                .mux_ofs = _mux_ofs,                                    \
@@ -52,14 +53,19 @@ struct mtk_mux {
                .parent_names = _parents,                               \
                .num_parents = ARRAY_SIZE(_parents),                    \
                .flags = _flags,                                        \
+               .ops = &_ops,                                           \
        }
 
+extern const struct clk_ops mtk_mux_clr_set_upd_ops;
+extern const struct clk_ops mtk_mux_gate_clr_set_upd_ops;
+
 #define MUX_GATE_CLR_SET_UPD_FLAGS(_id, _name, _parents, _mux_ofs,     \
                        _mux_set_ofs, _mux_clr_ofs, _shift, _width,     \
                        _gate, _upd_ofs, _upd, _flags)                  \
                GATE_CLR_SET_UPD_FLAGS(_id, _name, _parents, _mux_ofs,  \
                        _mux_set_ofs, _mux_clr_ofs, _shift, _width,     \
-                       _gate, _upd_ofs, _upd, _flags)                  \
+                       _gate, _upd_ofs, _upd, _flags,                  \
+                       mtk_mux_gate_clr_set_upd_ops)
 
 #define MUX_GATE_CLR_SET_UPD(_id, _name, _parents, _mux_ofs,           \
                        _mux_set_ofs, _mux_clr_ofs, _shift, _width,     \
@@ -69,6 +75,14 @@ struct mtk_mux {
                        _width, _gate, _upd_ofs, _upd,                  \
                        CLK_SET_RATE_PARENT)
 
+#define MUX_CLR_SET_UPD(_id, _name, _parents, _mux_ofs,                        \
+                       _mux_set_ofs, _mux_clr_ofs, _shift, _width,     \
+                       _upd_ofs, _upd)                                 \
+               GATE_CLR_SET_UPD_FLAGS(_id, _name, _parents, _mux_ofs,  \
+                       _mux_set_ofs, _mux_clr_ofs, _shift, _width,     \
+                       0, _upd_ofs, _upd, CLK_SET_RATE_PARENT,         \
+                       mtk_mux_clr_set_upd_ops)
+
 int mtk_clk_register_muxes(const struct mtk_mux *muxes,
                           int num, struct device_node *node,
                           spinlock_t *lock,
index f440f2c..7fb001a 100644 (file)
@@ -44,6 +44,7 @@ struct mtk_clk_pll {
        void __iomem    *tuner_en_addr;
        void __iomem    *pcw_addr;
        void __iomem    *pcw_chg_addr;
+       void __iomem    *en_addr;
        const struct mtk_pll_data *data;
 };
 
@@ -56,7 +57,7 @@ static int mtk_pll_is_prepared(struct clk_hw *hw)
 {
        struct mtk_clk_pll *pll = to_mtk_clk_pll(hw);
 
-       return (readl(pll->base_addr + REG_CON0) & CON0_BASE_EN) != 0;
+       return (readl(pll->en_addr) & BIT(pll->data->pll_en_bit)) != 0;
 }
 
 static unsigned long __mtk_pll_recalc_rate(struct mtk_clk_pll *pll, u32 fin,
@@ -238,6 +239,7 @@ static int mtk_pll_prepare(struct clk_hw *hw)
 {
        struct mtk_clk_pll *pll = to_mtk_clk_pll(hw);
        u32 r;
+       u32 div_en_mask;
 
        r = readl(pll->pwr_addr) | CON0_PWR_ON;
        writel(r, pll->pwr_addr);
@@ -247,9 +249,14 @@ static int mtk_pll_prepare(struct clk_hw *hw)
        writel(r, pll->pwr_addr);
        udelay(1);
 
-       r = readl(pll->base_addr + REG_CON0);
-       r |= pll->data->en_mask;
-       writel(r, pll->base_addr + REG_CON0);
+       r = readl(pll->en_addr) | BIT(pll->data->pll_en_bit);
+       writel(r, pll->en_addr);
+
+       div_en_mask = pll->data->en_mask & ~CON0_BASE_EN;
+       if (div_en_mask) {
+               r = readl(pll->base_addr + REG_CON0) | div_en_mask;
+               writel(r, pll->base_addr + REG_CON0);
+       }
 
        __mtk_pll_tuner_enable(pll);
 
@@ -268,6 +275,7 @@ static void mtk_pll_unprepare(struct clk_hw *hw)
 {
        struct mtk_clk_pll *pll = to_mtk_clk_pll(hw);
        u32 r;
+       u32 div_en_mask;
 
        if (pll->data->flags & HAVE_RST_BAR) {
                r = readl(pll->base_addr + REG_CON0);
@@ -277,9 +285,14 @@ static void mtk_pll_unprepare(struct clk_hw *hw)
 
        __mtk_pll_tuner_disable(pll);
 
-       r = readl(pll->base_addr + REG_CON0);
-       r &= ~CON0_BASE_EN;
-       writel(r, pll->base_addr + REG_CON0);
+       div_en_mask = pll->data->en_mask & ~CON0_BASE_EN;
+       if (div_en_mask) {
+               r = readl(pll->base_addr + REG_CON0) & ~div_en_mask;
+               writel(r, pll->base_addr + REG_CON0);
+       }
+
+       r = readl(pll->en_addr) & ~BIT(pll->data->pll_en_bit);
+       writel(r, pll->en_addr);
 
        r = readl(pll->pwr_addr) | CON0_ISO_EN;
        writel(r, pll->pwr_addr);
@@ -321,6 +334,10 @@ static struct clk *mtk_clk_register_pll(const struct mtk_pll_data *data,
                pll->tuner_addr = base + data->tuner_reg;
        if (data->tuner_en_reg)
                pll->tuner_en_addr = base + data->tuner_en_reg;
+       if (data->en_reg)
+               pll->en_addr = base + data->en_reg;
+       else
+               pll->en_addr = pll->base_addr + REG_CON0;
        pll->hw.init = &init;
        pll->data = data;
 
index cb939c0..e562dc3 100644 (file)
@@ -98,7 +98,7 @@ static void mtk_register_reset_controller_common(struct device_node *np,
        int ret;
        struct regmap *regmap;
 
-       regmap = syscon_node_to_regmap(np);
+       regmap = device_node_to_regmap(np);
        if (IS_ERR(regmap)) {
                pr_err("Cannot find regmap for %pOF: %ld\n", np,
                                PTR_ERR(regmap));
index 62e00e1..0a55967 100644 (file)
@@ -240,6 +240,14 @@ config MSM_MMCC_8960
          Say Y if you want to support multimedia devices such as display,
          graphics, video encode/decode, camera, etc.
 
+config MSM_GCC_8953
+       tristate "MSM8953 Global Clock Controller"
+       select QCOM_GDSC
+       help
+         Support for the global clock controller on msm8953 devices.
+         Say Y if you want to use devices such as UART, SPI i2c, USB,
+         SD/eMMC, display, graphics, camera etc.
+
 config MSM_GCC_8974
        tristate "MSM8974 Global Clock Controller"
        select QCOM_GDSC
@@ -257,6 +265,15 @@ config MSM_MMCC_8974
          Say Y if you want to support multimedia devices such as display,
          graphics, video encode/decode, camera, etc.
 
+config MSM_MMCC_8994
+       tristate "MSM8994 Multimedia Clock Controller"
+       select MSM_GCC_8994
+       select QCOM_GDSC
+       help
+         Support for the multimedia clock controller on msm8994 devices.
+         Say Y if you want to support multimedia devices such as display,
+         graphics, video encode/decode, camera, etc.
+
 config MSM_GCC_8994
        tristate "MSM8994 Global Clock Controller"
        help
@@ -332,6 +349,15 @@ config SC_DISPCC_7180
          Say Y if you want to support display devices and functionality such as
          splash screen.
 
+config SC_DISPCC_7280
+       tristate "SC7280 Display Clock Controller"
+       select SC_GCC_7280
+       help
+         Support for the display clock controller on Qualcomm Technologies, Inc.
+         SC7280 devices.
+         Say Y if you want to support display devices and functionality such as
+         splash screen.
+
 config SC_GCC_7180
        tristate "SC7180 Global Clock Controller"
        select QCOM_GDSC
@@ -376,6 +402,14 @@ config SC_GPUCC_7180
          Say Y if you want to support graphics controller devices and
          functionality such as 3D graphics.
 
+config SC_GPUCC_7280
+       tristate "SC7280 Graphics Clock Controller"
+       select SC_GCC_7280
+       help
+         Support for the graphics clock controller on SC7280 devices.
+         Say Y if you want to support graphics controller devices and
+         functionality such as 3D graphics.
+
 config SC_MSS_7180
        tristate "SC7180 Modem Clock Controller"
        select SC_GCC_7180
@@ -393,6 +427,14 @@ config SC_VIDEOCC_7180
          Say Y if you want to support video devices and functionality such as
          video encode and decode.
 
+config SC_VIDEOCC_7280
+       tristate "SC7280 Video Clock Controller"
+       select SC_GCC_7280
+       help
+         Support for the video clock controller on SC7280 devices.
+         Say Y if you want to support video devices and functionality such as
+         video encode and decode.
+
 config SDM_CAMCC_845
        tristate "SDM845 Camera Clock Controller"
        select SDM_GCC_845
@@ -506,6 +548,13 @@ config SM_DISPCC_8250
          Say Y if you want to support display devices and functionality such as
          splash screen.
 
+config SM_GCC_6115
+       tristate "SM6115 and SM4250 Global Clock Controller"
+       help
+         Support for the global clock controller on SM6115 and SM4250 devices.
+         Say Y if you want to use peripheral devices such as UART, SPI,
+         i2C, USB, UFS, SDDC, PCIe, etc.
+
 config SM_GCC_6125
        tristate "SM6125 Global Clock Controller"
        help
@@ -513,6 +562,13 @@ config SM_GCC_6125
          Say Y if you want to use peripheral devices such as UART,
          SPI, I2C, USB, SD/UFS, PCIe etc.
 
+config SM_GCC_6350
+       tristate "SM6350 Global Clock Controller"
+       help
+         Support for the global clock controller on SM6350 devices.
+         Say Y if you want to use peripheral devices such as UART,
+         SPI, I2C, USB, SD/UFS, PCIe etc.
+
 config SM_GCC_8150
        tristate "SM8150 Global Clock Controller"
        help
@@ -554,7 +610,7 @@ config SM_GPUCC_8250
 
 config SM_VIDEOCC_8150
        tristate "SM8150 Video Clock Controller"
-       select SDM_GCC_8150
+       select SM_GCC_8150
        select QCOM_GDSC
        help
          Support for the video clock controller on SM8150 devices.
@@ -563,7 +619,7 @@ config SM_VIDEOCC_8150
 
 config SM_VIDEOCC_8250
        tristate "SM8250 Video Clock Controller"
-       select SDM_GCC_8250
+       select SM_GCC_8250
        select QCOM_GDSC
        help
          Support for the video clock controller on SM8250 devices.
index c2a1caf..9825ef8 100644 (file)
@@ -33,6 +33,7 @@ obj-$(CONFIG_MDM_LCC_9615) += lcc-mdm9615.o
 obj-$(CONFIG_MSM_GCC_8660) += gcc-msm8660.o
 obj-$(CONFIG_MSM_GCC_8916) += gcc-msm8916.o
 obj-$(CONFIG_MSM_GCC_8939) += gcc-msm8939.o
+obj-$(CONFIG_MSM_GCC_8953) += gcc-msm8953.o
 obj-$(CONFIG_MSM_GCC_8960) += gcc-msm8960.o
 obj-$(CONFIG_MSM_GCC_8974) += gcc-msm8974.o
 obj-$(CONFIG_MSM_GCC_8994) += gcc-msm8994.o
@@ -42,6 +43,7 @@ obj-$(CONFIG_MSM_GCC_8998) += gcc-msm8998.o
 obj-$(CONFIG_MSM_GPUCC_8998) += gpucc-msm8998.o
 obj-$(CONFIG_MSM_MMCC_8960) += mmcc-msm8960.o
 obj-$(CONFIG_MSM_MMCC_8974) += mmcc-msm8974.o
+obj-$(CONFIG_MSM_MMCC_8994) += mmcc-msm8994.o
 obj-$(CONFIG_MSM_MMCC_8996) += mmcc-msm8996.o
 obj-$(CONFIG_MSM_MMCC_8998) += mmcc-msm8998.o
 obj-$(CONFIG_QCOM_A53PLL) += a53-pll.o
@@ -57,13 +59,16 @@ obj-$(CONFIG_QCS_Q6SSTOP_404) += q6sstop-qcs404.o
 obj-$(CONFIG_QCS_TURING_404) += turingcc-qcs404.o
 obj-$(CONFIG_SC_CAMCC_7180) += camcc-sc7180.o
 obj-$(CONFIG_SC_DISPCC_7180) += dispcc-sc7180.o
+obj-$(CONFIG_SC_DISPCC_7280) += dispcc-sc7280.o
 obj-$(CONFIG_SC_GCC_7180) += gcc-sc7180.o
 obj-$(CONFIG_SC_GCC_7280) += gcc-sc7280.o
 obj-$(CONFIG_SC_GCC_8180X) += gcc-sc8180x.o
 obj-$(CONFIG_SC_GPUCC_7180) += gpucc-sc7180.o
+obj-$(CONFIG_SC_GPUCC_7280) += gpucc-sc7280.o
 obj-$(CONFIG_SC_LPASS_CORECC_7180) += lpasscorecc-sc7180.o
 obj-$(CONFIG_SC_MSS_7180) += mss-sc7180.o
 obj-$(CONFIG_SC_VIDEOCC_7180) += videocc-sc7180.o
+obj-$(CONFIG_SC_VIDEOCC_7280) += videocc-sc7280.o
 obj-$(CONFIG_SDM_CAMCC_845) += camcc-sdm845.o
 obj-$(CONFIG_SDM_DISPCC_845) += dispcc-sdm845.o
 obj-$(CONFIG_SDM_GCC_660) += gcc-sdm660.o
@@ -76,7 +81,9 @@ obj-$(CONFIG_SDM_VIDEOCC_845) += videocc-sdm845.o
 obj-$(CONFIG_SDX_GCC_55) += gcc-sdx55.o
 obj-$(CONFIG_SM_CAMCC_8250) += camcc-sm8250.o
 obj-$(CONFIG_SM_DISPCC_8250) += dispcc-sm8250.o
+obj-$(CONFIG_SM_GCC_6115) += gcc-sm6115.o
 obj-$(CONFIG_SM_GCC_6125) += gcc-sm6125.o
+obj-$(CONFIG_SM_GCC_6350) += gcc-sm6350.o
 obj-$(CONFIG_SM_GCC_8150) += gcc-sm8150.o
 obj-$(CONFIG_SM_GCC_8250) += gcc-sm8250.o
 obj-$(CONFIG_SM_GCC_8350) += gcc-sm8350.o
index af6ac17..9e6decb 100644 (file)
@@ -6,9 +6,11 @@
  * Author: Georgi Djakov <georgi.djakov@linaro.org>
  */
 
+#include <linux/clk.h>
 #include <linux/clk-provider.h>
 #include <linux/kernel.h>
 #include <linux/platform_device.h>
+#include <linux/pm_opp.h>
 #include <linux/regmap.h>
 #include <linux/module.h>
 
@@ -34,9 +36,59 @@ static const struct regmap_config a53pll_regmap_config = {
        .fast_io                = true,
 };
 
+static struct pll_freq_tbl *qcom_a53pll_get_freq_tbl(struct device *dev)
+{
+       struct pll_freq_tbl *freq_tbl;
+       unsigned long xo_freq;
+       unsigned long freq;
+       struct clk *xo_clk;
+       int count;
+       int ret;
+       int i;
+
+       xo_clk = devm_clk_get(dev, "xo");
+       if (IS_ERR(xo_clk))
+               return NULL;
+
+       xo_freq = clk_get_rate(xo_clk);
+
+       ret = devm_pm_opp_of_add_table(dev);
+       if (ret)
+               return NULL;
+
+       count = dev_pm_opp_get_opp_count(dev);
+       if (count <= 0)
+               return NULL;
+
+       freq_tbl = devm_kcalloc(dev, count + 1, sizeof(*freq_tbl), GFP_KERNEL);
+       if (!freq_tbl)
+               return NULL;
+
+       for (i = 0, freq = 0; i < count; i++, freq++) {
+               struct dev_pm_opp *opp;
+
+               opp = dev_pm_opp_find_freq_ceil(dev, &freq);
+               if (IS_ERR(opp))
+                       return NULL;
+
+               /* Skip the freq that is not divisible */
+               if (freq % xo_freq)
+                       continue;
+
+               freq_tbl[i].freq = freq;
+               freq_tbl[i].l = freq / xo_freq;
+               freq_tbl[i].n = 1;
+
+               dev_pm_opp_put(opp);
+       }
+
+       return freq_tbl;
+}
+
 static int qcom_a53pll_probe(struct platform_device *pdev)
 {
        struct device *dev = &pdev->dev;
+       struct device_node *np = dev->of_node;
        struct regmap *regmap;
        struct resource *res;
        struct clk_pll *pll;
@@ -64,13 +116,22 @@ static int qcom_a53pll_probe(struct platform_device *pdev)
        pll->mode_reg = 0x00;
        pll->status_reg = 0x1c;
        pll->status_bit = 16;
-       pll->freq_tbl = a53pll_freq;
 
-       init.name = "a53pll";
+       pll->freq_tbl = qcom_a53pll_get_freq_tbl(dev);
+       if (!pll->freq_tbl) {
+               /* Fall on a53pll_freq if no freq_tbl is found from OPP */
+               pll->freq_tbl = a53pll_freq;
+       }
+
+       /* Use an unique name by appending @unit-address */
+       init.name = devm_kasprintf(dev, GFP_KERNEL, "a53pll%s",
+                                  strchrnul(np->full_name, '@'));
+       if (!init.name)
+               return -ENOMEM;
+
        init.parent_names = (const char *[]){ "xo" };
        init.num_parents = 1;
        init.ops = &clk_pll_sr2_ops;
-       init.flags = CLK_IS_CRITICAL;
        pll->clkr.hw.init = &init;
 
        ret = devm_clk_register_regmap(dev, &pll->clkr);
@@ -91,6 +152,7 @@ static int qcom_a53pll_probe(struct platform_device *pdev)
 
 static const struct of_device_id qcom_a53pll_match_table[] = {
        { .compatible = "qcom,msm8916-a53pll" },
+       { .compatible = "qcom,msm8939-a53pll" },
        { }
 };
 MODULE_DEVICE_TABLE(of, qcom_a53pll_match_table);
index cf69a97..89e0730 100644 (file)
@@ -46,6 +46,7 @@ static int qcom_apcs_msm8916_clk_probe(struct platform_device *pdev)
 {
        struct device *dev = &pdev->dev;
        struct device *parent = dev->parent;
+       struct device_node *np = parent->of_node;
        struct clk_regmap_mux_div *a53cc;
        struct regmap *regmap;
        struct clk_init_data init = { };
@@ -61,11 +62,16 @@ static int qcom_apcs_msm8916_clk_probe(struct platform_device *pdev)
        if (!a53cc)
                return -ENOMEM;
 
-       init.name = "a53mux";
+       /* Use an unique name by appending parent's @unit-address */
+       init.name = devm_kasprintf(dev, GFP_KERNEL, "a53mux%s",
+                                  strchrnul(np->full_name, '@'));
+       if (!init.name)
+               return -ENOMEM;
+
        init.parent_data = pdata;
        init.num_parents = ARRAY_SIZE(pdata);
        init.ops = &clk_regmap_mux_div_ops;
-       init.flags = CLK_SET_RATE_PARENT;
+       init.flags = CLK_IS_CRITICAL | CLK_SET_RATE_PARENT;
 
        a53cc->clkr.hw.init = &init;
        a53cc->clkr.regmap = regmap;
index 9bcf2f8..ce73ee9 100644 (file)
@@ -1652,32 +1652,35 @@ static int cam_cc_sc7180_probe(struct platform_device *pdev)
        struct regmap *regmap;
        int ret;
 
-       pm_runtime_enable(&pdev->dev);
-       ret = pm_clk_create(&pdev->dev);
+       ret = devm_pm_runtime_enable(&pdev->dev);
+       if (ret < 0)
+               return ret;
+
+       ret = devm_pm_clk_create(&pdev->dev);
        if (ret < 0)
                return ret;
 
        ret = pm_clk_add(&pdev->dev, "xo");
        if (ret < 0) {
                dev_err(&pdev->dev, "Failed to acquire XO clock\n");
-               goto disable_pm_runtime;
+               return ret;
        }
 
        ret = pm_clk_add(&pdev->dev, "iface");
        if (ret < 0) {
                dev_err(&pdev->dev, "Failed to acquire iface clock\n");
-               goto disable_pm_runtime;
+               return ret;
        }
 
        ret = pm_runtime_get(&pdev->dev);
        if (ret)
-               goto destroy_pm_clk;
+               return ret;
 
        regmap = qcom_cc_map(pdev, &cam_cc_sc7180_desc);
        if (IS_ERR(regmap)) {
                ret = PTR_ERR(regmap);
                pm_runtime_put(&pdev->dev);
-               goto destroy_pm_clk;
+               return ret;
        }
 
        clk_fabia_pll_configure(&cam_cc_pll0, regmap, &cam_cc_pll0_config);
@@ -1689,18 +1692,10 @@ static int cam_cc_sc7180_probe(struct platform_device *pdev)
        pm_runtime_put(&pdev->dev);
        if (ret < 0) {
                dev_err(&pdev->dev, "Failed to register CAM CC clocks\n");
-               goto destroy_pm_clk;
+               return ret;
        }
 
        return 0;
-
-destroy_pm_clk:
-       pm_clk_destroy(&pdev->dev);
-
-disable_pm_runtime:
-       pm_runtime_disable(&pdev->dev);
-
-       return ret;
 }
 
 static const struct dev_pm_ops cam_cc_pm_ops = {
index 552d1cb..441d7a2 100644 (file)
@@ -536,6 +536,26 @@ static const struct clk_rpmh_desc clk_rpmh_sc7280 = {
        .num_clks = ARRAY_SIZE(sc7280_rpmh_clocks),
 };
 
+DEFINE_CLK_RPMH_VRM(sm6350, ln_bb_clk2, ln_bb_clk2_ao, "lnbclkg2", 4);
+DEFINE_CLK_RPMH_VRM(sm6350, ln_bb_clk3, ln_bb_clk3_ao, "lnbclkg3", 4);
+DEFINE_CLK_RPMH_ARC(sm6350, qlink, qlink_ao, "qphy.lvl", 0x1, 4);
+
+static struct clk_hw *sm6350_rpmh_clocks[] = {
+       [RPMH_CXO_CLK]          = &sc7280_bi_tcxo.hw,
+       [RPMH_CXO_CLK_A]        = &sc7280_bi_tcxo_ao.hw,
+       [RPMH_LN_BB_CLK2]       = &sm6350_ln_bb_clk2.hw,
+       [RPMH_LN_BB_CLK2_A]     = &sm6350_ln_bb_clk2_ao.hw,
+       [RPMH_LN_BB_CLK3]       = &sm6350_ln_bb_clk3.hw,
+       [RPMH_LN_BB_CLK3_A]     = &sm6350_ln_bb_clk3_ao.hw,
+       [RPMH_QLINK_CLK]        = &sm6350_qlink.hw,
+       [RPMH_QLINK_CLK_A]      = &sm6350_qlink_ao.hw,
+};
+
+static const struct clk_rpmh_desc clk_rpmh_sm6350 = {
+       .clks = sm6350_rpmh_clocks,
+       .num_clks = ARRAY_SIZE(sm6350_rpmh_clocks),
+};
+
 static struct clk_hw *of_clk_rpmh_hw_get(struct of_phandle_args *clkspec,
                                         void *data)
 {
@@ -623,6 +643,7 @@ static const struct of_device_id clk_rpmh_match_table[] = {
        { .compatible = "qcom,sc8180x-rpmh-clk", .data = &clk_rpmh_sc8180x},
        { .compatible = "qcom,sdm845-rpmh-clk", .data = &clk_rpmh_sdm845},
        { .compatible = "qcom,sdx55-rpmh-clk",  .data = &clk_rpmh_sdx55},
+       { .compatible = "qcom,sm6350-rpmh-clk", .data = &clk_rpmh_sm6350},
        { .compatible = "qcom,sm8150-rpmh-clk", .data = &clk_rpmh_sm8150},
        { .compatible = "qcom,sm8250-rpmh-clk", .data = &clk_rpmh_sm8250},
        { .compatible = "qcom,sm8350-rpmh-clk", .data = &clk_rpmh_sm8350},
index 800b2fe..bbc7fbc 100644 (file)
@@ -913,10 +913,166 @@ static const struct rpm_smd_clk_desc rpm_clk_sdm660 = {
        .num_clks = ARRAY_SIZE(sdm660_clks),
 };
 
+static struct clk_smd_rpm *mdm9607_clks[] = {
+       [RPM_SMD_XO_CLK_SRC]            = &sdm660_bi_tcxo,
+       [RPM_SMD_XO_A_CLK_SRC]          = &sdm660_bi_tcxo_a,
+       [RPM_SMD_PCNOC_CLK]             = &msm8916_pcnoc_clk,
+       [RPM_SMD_PCNOC_A_CLK]           = &msm8916_pcnoc_a_clk,
+       [RPM_SMD_BIMC_CLK]              = &msm8916_bimc_clk,
+       [RPM_SMD_BIMC_A_CLK]            = &msm8916_bimc_a_clk,
+       [RPM_SMD_QPIC_CLK]              = &qcs404_qpic_clk,
+       [RPM_SMD_QPIC_CLK_A]            = &qcs404_qpic_a_clk,
+       [RPM_SMD_QDSS_CLK]              = &msm8916_qdss_clk,
+       [RPM_SMD_QDSS_A_CLK]            = &msm8916_qdss_a_clk,
+       [RPM_SMD_BB_CLK1]               = &msm8916_bb_clk1,
+       [RPM_SMD_BB_CLK1_A]             = &msm8916_bb_clk1_a,
+       [RPM_SMD_BB_CLK1_PIN]           = &msm8916_bb_clk1_pin,
+       [RPM_SMD_BB_CLK1_A_PIN]         = &msm8916_bb_clk1_a_pin,
+};
+
+static const struct rpm_smd_clk_desc rpm_clk_mdm9607 = {
+       .clks = mdm9607_clks,
+       .num_clks = ARRAY_SIZE(mdm9607_clks),
+};
+
+static struct clk_smd_rpm *msm8953_clks[] = {
+       [RPM_SMD_XO_CLK_SRC]            = &sdm660_bi_tcxo,
+       [RPM_SMD_XO_A_CLK_SRC]          = &sdm660_bi_tcxo_a,
+       [RPM_SMD_PCNOC_CLK]             = &msm8916_pcnoc_clk,
+       [RPM_SMD_PCNOC_A_CLK]           = &msm8916_pcnoc_a_clk,
+       [RPM_SMD_SNOC_CLK]              = &msm8916_snoc_clk,
+       [RPM_SMD_SNOC_A_CLK]            = &msm8916_snoc_a_clk,
+       [RPM_SMD_BIMC_CLK]              = &msm8916_bimc_clk,
+       [RPM_SMD_BIMC_A_CLK]            = &msm8916_bimc_a_clk,
+       [RPM_SMD_IPA_CLK]               = &msm8976_ipa_clk,
+       [RPM_SMD_IPA_A_CLK]             = &msm8976_ipa_a_clk,
+       [RPM_SMD_SYSMMNOC_CLK]          = &msm8936_sysmmnoc_clk,
+       [RPM_SMD_SYSMMNOC_A_CLK]        = &msm8936_sysmmnoc_a_clk,
+       [RPM_SMD_QDSS_CLK]              = &msm8916_qdss_clk,
+       [RPM_SMD_QDSS_A_CLK]            = &msm8916_qdss_a_clk,
+       [RPM_SMD_BB_CLK1]               = &msm8916_bb_clk1,
+       [RPM_SMD_BB_CLK1_A]             = &msm8916_bb_clk1_a,
+       [RPM_SMD_BB_CLK2]               = &msm8916_bb_clk2,
+       [RPM_SMD_BB_CLK2_A]             = &msm8916_bb_clk2_a,
+       [RPM_SMD_RF_CLK2]               = &msm8916_rf_clk2,
+       [RPM_SMD_RF_CLK2_A]             = &msm8916_rf_clk2_a,
+       [RPM_SMD_RF_CLK3]               = &msm8992_ln_bb_clk,
+       [RPM_SMD_RF_CLK3_A]             = &msm8992_ln_bb_a_clk,
+       [RPM_SMD_DIV_CLK2]              = &msm8974_div_clk2,
+       [RPM_SMD_DIV_A_CLK2]            = &msm8974_div_a_clk2,
+       [RPM_SMD_BB_CLK1_PIN]           = &msm8916_bb_clk1_pin,
+       [RPM_SMD_BB_CLK1_A_PIN]         = &msm8916_bb_clk1_a_pin,
+       [RPM_SMD_BB_CLK2_PIN]           = &msm8916_bb_clk2_pin,
+       [RPM_SMD_BB_CLK2_A_PIN]         = &msm8916_bb_clk2_a_pin,
+};
+
+static const struct rpm_smd_clk_desc rpm_clk_msm8953 = {
+       .clks = msm8953_clks,
+       .num_clks = ARRAY_SIZE(msm8953_clks),
+};
+
+/* SM6125 */
+DEFINE_CLK_SMD_RPM(sm6125, cnoc_clk, cnoc_a_clk, QCOM_SMD_RPM_BUS_CLK, 1);
+DEFINE_CLK_SMD_RPM(sm6125, snoc_clk, snoc_a_clk, QCOM_SMD_RPM_BUS_CLK, 2);
+DEFINE_CLK_SMD_RPM_BRANCH(sm6125, qdss_clk, qdss_a_clk,
+                                       QCOM_SMD_RPM_MISC_CLK, 1, 19200000);
+DEFINE_CLK_SMD_RPM(sm6125, qup_clk, qup_a_clk, QCOM_SMD_RPM_QUP_CLK, 0);
+DEFINE_CLK_SMD_RPM(sm6125, mmnrt_clk, mmnrt_a_clk, QCOM_SMD_RPM_MMAXI_CLK, 0);
+DEFINE_CLK_SMD_RPM(sm6125, mmrt_clk, mmrt_a_clk, QCOM_SMD_RPM_MMAXI_CLK, 1);
+DEFINE_CLK_SMD_RPM(sm6125, snoc_periph_clk, snoc_periph_a_clk,
+                                               QCOM_SMD_RPM_BUS_CLK, 0);
+DEFINE_CLK_SMD_RPM(sm6125, snoc_lpass_clk, snoc_lpass_a_clk,
+                                               QCOM_SMD_RPM_BUS_CLK, 5);
+
+static struct clk_smd_rpm *sm6125_clks[] = {
+       [RPM_SMD_XO_CLK_SRC] = &sdm660_bi_tcxo,
+       [RPM_SMD_XO_A_CLK_SRC] = &sdm660_bi_tcxo_a,
+       [RPM_SMD_SNOC_CLK] = &sm6125_snoc_clk,
+       [RPM_SMD_SNOC_A_CLK] = &sm6125_snoc_a_clk,
+       [RPM_SMD_BIMC_CLK] = &msm8916_bimc_clk,
+       [RPM_SMD_BIMC_A_CLK] = &msm8916_bimc_a_clk,
+       [RPM_SMD_QDSS_CLK] = &sm6125_qdss_clk,
+       [RPM_SMD_QDSS_A_CLK] = &sm6125_qdss_a_clk,
+       [RPM_SMD_RF_CLK1] = &msm8916_rf_clk1,
+       [RPM_SMD_RF_CLK1_A] = &msm8916_rf_clk1_a,
+       [RPM_SMD_RF_CLK2] = &msm8916_rf_clk2,
+       [RPM_SMD_RF_CLK2_A] = &msm8916_rf_clk2_a,
+       [RPM_SMD_CNOC_CLK] = &sm6125_cnoc_clk,
+       [RPM_SMD_CNOC_A_CLK] = &sm6125_cnoc_a_clk,
+       [RPM_SMD_IPA_CLK] = &msm8976_ipa_clk,
+       [RPM_SMD_IPA_A_CLK] = &msm8976_ipa_a_clk,
+       [RPM_SMD_CE1_CLK] = &msm8992_ce1_clk,
+       [RPM_SMD_CE1_A_CLK] = &msm8992_ce1_a_clk,
+       [RPM_SMD_LN_BB_CLK1] = &msm8916_bb_clk1,
+       [RPM_SMD_LN_BB_CLK1_A] = &msm8916_bb_clk1_a,
+       [RPM_SMD_LN_BB_CLK2] = &msm8916_bb_clk2,
+       [RPM_SMD_LN_BB_CLK2_A] = &msm8916_bb_clk2_a,
+       [RPM_SMD_LN_BB_CLK3] = &sdm660_ln_bb_clk3,
+       [RPM_SMD_LN_BB_CLK3_A] = &sdm660_ln_bb_clk3_a,
+       [RPM_SMD_QUP_CLK] = &sm6125_qup_clk,
+       [RPM_SMD_QUP_A_CLK] = &sm6125_qup_a_clk,
+       [RPM_SMD_MMRT_CLK] = &sm6125_mmrt_clk,
+       [RPM_SMD_MMRT_A_CLK] = &sm6125_mmrt_a_clk,
+       [RPM_SMD_MMNRT_CLK] = &sm6125_mmnrt_clk,
+       [RPM_SMD_MMNRT_A_CLK] = &sm6125_mmnrt_a_clk,
+       [RPM_SMD_SNOC_PERIPH_CLK] = &sm6125_snoc_periph_clk,
+       [RPM_SMD_SNOC_PERIPH_A_CLK] = &sm6125_snoc_periph_a_clk,
+       [RPM_SMD_SNOC_LPASS_CLK] = &sm6125_snoc_lpass_clk,
+       [RPM_SMD_SNOC_LPASS_A_CLK] = &sm6125_snoc_lpass_a_clk,
+};
+
+static const struct rpm_smd_clk_desc rpm_clk_sm6125 = {
+       .clks = sm6125_clks,
+       .num_clks = ARRAY_SIZE(sm6125_clks),
+};
+
+/* SM6115 */
+static struct clk_smd_rpm *sm6115_clks[] = {
+       [RPM_SMD_XO_CLK_SRC] = &sdm660_bi_tcxo,
+       [RPM_SMD_XO_A_CLK_SRC] = &sdm660_bi_tcxo_a,
+       [RPM_SMD_SNOC_CLK] = &sm6125_snoc_clk,
+       [RPM_SMD_SNOC_A_CLK] = &sm6125_snoc_a_clk,
+       [RPM_SMD_BIMC_CLK] = &msm8916_bimc_clk,
+       [RPM_SMD_BIMC_A_CLK] = &msm8916_bimc_a_clk,
+       [RPM_SMD_QDSS_CLK] = &sm6125_qdss_clk,
+       [RPM_SMD_QDSS_A_CLK] = &sm6125_qdss_a_clk,
+       [RPM_SMD_RF_CLK1] = &msm8916_rf_clk1,
+       [RPM_SMD_RF_CLK1_A] = &msm8916_rf_clk1_a,
+       [RPM_SMD_RF_CLK2] = &msm8916_rf_clk2,
+       [RPM_SMD_RF_CLK2_A] = &msm8916_rf_clk2_a,
+       [RPM_SMD_CNOC_CLK] = &sm6125_cnoc_clk,
+       [RPM_SMD_CNOC_A_CLK] = &sm6125_cnoc_a_clk,
+       [RPM_SMD_IPA_CLK] = &msm8976_ipa_clk,
+       [RPM_SMD_IPA_A_CLK] = &msm8976_ipa_a_clk,
+       [RPM_SMD_CE1_CLK] = &msm8992_ce1_clk,
+       [RPM_SMD_CE1_A_CLK] = &msm8992_ce1_a_clk,
+       [RPM_SMD_QUP_CLK] = &sm6125_qup_clk,
+       [RPM_SMD_QUP_A_CLK] = &sm6125_qup_a_clk,
+       [RPM_SMD_MMRT_CLK] = &sm6125_mmrt_clk,
+       [RPM_SMD_MMRT_A_CLK] = &sm6125_mmrt_a_clk,
+       [RPM_SMD_MMNRT_CLK] = &sm6125_mmnrt_clk,
+       [RPM_SMD_MMNRT_A_CLK] = &sm6125_mmnrt_a_clk,
+       [RPM_SMD_SNOC_PERIPH_CLK] = &sm6125_snoc_periph_clk,
+       [RPM_SMD_SNOC_PERIPH_A_CLK] = &sm6125_snoc_periph_a_clk,
+       [RPM_SMD_SNOC_LPASS_CLK] = &sm6125_snoc_lpass_clk,
+       [RPM_SMD_SNOC_LPASS_A_CLK] = &sm6125_snoc_lpass_a_clk,
+       [RPM_SMD_RF_CLK1_PIN] = &msm8916_rf_clk1_pin,
+       [RPM_SMD_RF_CLK1_A_PIN] = &msm8916_rf_clk1_a_pin,
+       [RPM_SMD_RF_CLK2_PIN] = &msm8916_rf_clk2_pin,
+       [RPM_SMD_RF_CLK2_A_PIN] = &msm8916_rf_clk2_a_pin,
+};
+
+static const struct rpm_smd_clk_desc rpm_clk_sm6115 = {
+       .clks = sm6115_clks,
+       .num_clks = ARRAY_SIZE(sm6115_clks),
+};
+
 static const struct of_device_id rpm_smd_clk_match_table[] = {
+       { .compatible = "qcom,rpmcc-mdm9607", .data = &rpm_clk_mdm9607 },
        { .compatible = "qcom,rpmcc-msm8226", .data = &rpm_clk_msm8974 },
        { .compatible = "qcom,rpmcc-msm8916", .data = &rpm_clk_msm8916 },
        { .compatible = "qcom,rpmcc-msm8936", .data = &rpm_clk_msm8936 },
+       { .compatible = "qcom,rpmcc-msm8953", .data = &rpm_clk_msm8953 },
        { .compatible = "qcom,rpmcc-msm8974", .data = &rpm_clk_msm8974 },
        { .compatible = "qcom,rpmcc-msm8976", .data = &rpm_clk_msm8976 },
        { .compatible = "qcom,rpmcc-msm8992", .data = &rpm_clk_msm8992 },
@@ -925,6 +1081,8 @@ static const struct of_device_id rpm_smd_clk_match_table[] = {
        { .compatible = "qcom,rpmcc-msm8998", .data = &rpm_clk_msm8998 },
        { .compatible = "qcom,rpmcc-qcs404",  .data = &rpm_clk_qcs404  },
        { .compatible = "qcom,rpmcc-sdm660",  .data = &rpm_clk_sdm660  },
+       { .compatible = "qcom,rpmcc-sm6115",  .data = &rpm_clk_sm6115  },
+       { .compatible = "qcom,rpmcc-sm6125",  .data = &rpm_clk_sm6125  },
        { }
 };
 MODULE_DEVICE_TABLE(of, rpm_smd_clk_match_table);
diff --git a/drivers/clk/qcom/dispcc-sc7280.c b/drivers/clk/qcom/dispcc-sc7280.c
new file mode 100644 (file)
index 0000000..4ef4ae2
--- /dev/null
@@ -0,0 +1,908 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2021, The Linux Foundation. All rights reserved.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+#include <dt-bindings/clock/qcom,dispcc-sc7280.h>
+
+#include "clk-alpha-pll.h"
+#include "clk-branch.h"
+#include "clk-rcg.h"
+#include "clk-regmap-divider.h"
+#include "common.h"
+#include "gdsc.h"
+
+enum {
+       P_BI_TCXO,
+       P_DISP_CC_PLL0_OUT_EVEN,
+       P_DISP_CC_PLL0_OUT_MAIN,
+       P_DP_PHY_PLL_LINK_CLK,
+       P_DP_PHY_PLL_VCO_DIV_CLK,
+       P_DSI0_PHY_PLL_OUT_BYTECLK,
+       P_DSI0_PHY_PLL_OUT_DSICLK,
+       P_EDP_PHY_PLL_LINK_CLK,
+       P_EDP_PHY_PLL_VCO_DIV_CLK,
+       P_GCC_DISP_GPLL0_CLK,
+};
+
+static const struct pll_vco lucid_vco[] = {
+       { 249600000, 2000000000, 0 },
+};
+
+/* 1520MHz Configuration*/
+static const struct alpha_pll_config disp_cc_pll0_config = {
+       .l = 0x4F,
+       .alpha = 0x2AAA,
+       .config_ctl_val = 0x20485699,
+       .config_ctl_hi_val = 0x00002261,
+       .config_ctl_hi1_val = 0x329A299C,
+       .user_ctl_val = 0x00000001,
+       .user_ctl_hi_val = 0x00000805,
+       .user_ctl_hi1_val = 0x00000000,
+};
+
+static struct clk_alpha_pll disp_cc_pll0 = {
+       .offset = 0x0,
+       .vco_table = lucid_vco,
+       .num_vco = ARRAY_SIZE(lucid_vco),
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID],
+       .clkr = {
+               .hw.init = &(struct clk_init_data){
+                       .name = "disp_cc_pll0",
+                       .parent_data = &(const struct clk_parent_data){
+                               .fw_name = "bi_tcxo",
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_alpha_pll_lucid_ops,
+               },
+       },
+};
+
+static const struct parent_map disp_cc_parent_map_0[] = {
+       { P_BI_TCXO, 0 },
+};
+
+static const struct clk_parent_data disp_cc_parent_data_0[] = {
+       { .fw_name = "bi_tcxo" },
+};
+
+static const struct parent_map disp_cc_parent_map_1[] = {
+       { P_BI_TCXO, 0 },
+       { P_DP_PHY_PLL_LINK_CLK, 1 },
+       { P_DP_PHY_PLL_VCO_DIV_CLK, 2 },
+};
+
+static const struct clk_parent_data disp_cc_parent_data_1[] = {
+       { .fw_name = "bi_tcxo" },
+       { .fw_name = "dp_phy_pll_link_clk" },
+       { .fw_name = "dp_phy_pll_vco_div_clk" },
+};
+
+static const struct parent_map disp_cc_parent_map_2[] = {
+       { P_BI_TCXO, 0 },
+       { P_DSI0_PHY_PLL_OUT_BYTECLK, 1 },
+};
+
+static const struct clk_parent_data disp_cc_parent_data_2[] = {
+       { .fw_name = "bi_tcxo" },
+       { .fw_name = "dsi0_phy_pll_out_byteclk" },
+};
+
+static const struct parent_map disp_cc_parent_map_3[] = {
+       { P_BI_TCXO, 0 },
+       { P_EDP_PHY_PLL_LINK_CLK, 1 },
+       { P_EDP_PHY_PLL_VCO_DIV_CLK, 2 },
+};
+
+static const struct clk_parent_data disp_cc_parent_data_3[] = {
+       { .fw_name = "bi_tcxo" },
+       { .fw_name = "edp_phy_pll_link_clk" },
+       { .fw_name = "edp_phy_pll_vco_div_clk" },
+};
+
+static const struct parent_map disp_cc_parent_map_4[] = {
+       { P_BI_TCXO, 0 },
+       { P_DISP_CC_PLL0_OUT_MAIN, 1 },
+       { P_GCC_DISP_GPLL0_CLK, 4 },
+       { P_DISP_CC_PLL0_OUT_EVEN, 5 },
+};
+
+static const struct clk_parent_data disp_cc_parent_data_4[] = {
+       { .fw_name = "bi_tcxo" },
+       { .hw = &disp_cc_pll0.clkr.hw },
+       { .fw_name = "gcc_disp_gpll0_clk" },
+       { .hw = &disp_cc_pll0.clkr.hw },
+};
+
+static const struct parent_map disp_cc_parent_map_5[] = {
+       { P_BI_TCXO, 0 },
+       { P_GCC_DISP_GPLL0_CLK, 4 },
+};
+
+static const struct clk_parent_data disp_cc_parent_data_5[] = {
+       { .fw_name = "bi_tcxo" },
+       { .fw_name = "gcc_disp_gpll0_clk" },
+};
+
+static const struct parent_map disp_cc_parent_map_6[] = {
+       { P_BI_TCXO, 0 },
+       { P_DSI0_PHY_PLL_OUT_DSICLK, 1 },
+};
+
+static const struct clk_parent_data disp_cc_parent_data_6[] = {
+       { .fw_name = "bi_tcxo" },
+       { .fw_name = "dsi0_phy_pll_out_dsiclk" },
+};
+
+static const struct freq_tbl ftbl_disp_cc_mdss_ahb_clk_src[] = {
+       F(19200000, P_BI_TCXO, 1, 0, 0),
+       F(37500000, P_GCC_DISP_GPLL0_CLK, 16, 0, 0),
+       F(75000000, P_GCC_DISP_GPLL0_CLK, 8, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 disp_cc_mdss_ahb_clk_src = {
+       .cmd_rcgr = 0x1170,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = disp_cc_parent_map_5,
+       .freq_tbl = ftbl_disp_cc_mdss_ahb_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "disp_cc_mdss_ahb_clk_src",
+               .parent_data = disp_cc_parent_data_5,
+               .num_parents = ARRAY_SIZE(disp_cc_parent_data_5),
+               .ops = &clk_rcg2_shared_ops,
+       },
+};
+
+static struct clk_rcg2 disp_cc_mdss_byte0_clk_src = {
+       .cmd_rcgr = 0x10d8,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = disp_cc_parent_map_2,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "disp_cc_mdss_byte0_clk_src",
+               .parent_data = disp_cc_parent_data_2,
+               .num_parents = ARRAY_SIZE(disp_cc_parent_data_2),
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_byte2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_disp_cc_mdss_dp_aux_clk_src[] = {
+       F(19200000, P_BI_TCXO, 1, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 disp_cc_mdss_dp_aux_clk_src = {
+       .cmd_rcgr = 0x1158,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = disp_cc_parent_map_0,
+       .freq_tbl = ftbl_disp_cc_mdss_dp_aux_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "disp_cc_mdss_dp_aux_clk_src",
+               .parent_data = disp_cc_parent_data_0,
+               .num_parents = ARRAY_SIZE(disp_cc_parent_data_0),
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 disp_cc_mdss_dp_crypto_clk_src = {
+       .cmd_rcgr = 0x1128,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = disp_cc_parent_map_1,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "disp_cc_mdss_dp_crypto_clk_src",
+               .parent_data = disp_cc_parent_data_1,
+               .num_parents = ARRAY_SIZE(disp_cc_parent_data_1),
+               .ops = &clk_byte2_ops,
+       },
+};
+
+static struct clk_rcg2 disp_cc_mdss_dp_link_clk_src = {
+       .cmd_rcgr = 0x110c,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = disp_cc_parent_map_1,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "disp_cc_mdss_dp_link_clk_src",
+               .parent_data = disp_cc_parent_data_1,
+               .num_parents = ARRAY_SIZE(disp_cc_parent_data_1),
+               .ops = &clk_byte2_ops,
+       },
+};
+
+static struct clk_rcg2 disp_cc_mdss_dp_pixel_clk_src = {
+       .cmd_rcgr = 0x1140,
+       .mnd_width = 16,
+       .hid_width = 5,
+       .parent_map = disp_cc_parent_map_1,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "disp_cc_mdss_dp_pixel_clk_src",
+               .parent_data = disp_cc_parent_data_1,
+               .num_parents = ARRAY_SIZE(disp_cc_parent_data_1),
+               .ops = &clk_dp_ops,
+       },
+};
+
+static struct clk_rcg2 disp_cc_mdss_edp_aux_clk_src = {
+       .cmd_rcgr = 0x11d0,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = disp_cc_parent_map_0,
+       .freq_tbl = ftbl_disp_cc_mdss_dp_aux_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "disp_cc_mdss_edp_aux_clk_src",
+               .parent_data = disp_cc_parent_data_0,
+               .num_parents = ARRAY_SIZE(disp_cc_parent_data_0),
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 disp_cc_mdss_edp_link_clk_src = {
+       .cmd_rcgr = 0x11a0,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = disp_cc_parent_map_3,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "disp_cc_mdss_edp_link_clk_src",
+               .parent_data = disp_cc_parent_data_3,
+               .num_parents = ARRAY_SIZE(disp_cc_parent_data_3),
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_byte2_ops,
+       },
+};
+
+static struct clk_rcg2 disp_cc_mdss_edp_pixel_clk_src = {
+       .cmd_rcgr = 0x1188,
+       .mnd_width = 16,
+       .hid_width = 5,
+       .parent_map = disp_cc_parent_map_3,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "disp_cc_mdss_edp_pixel_clk_src",
+               .parent_data = disp_cc_parent_data_3,
+               .num_parents = ARRAY_SIZE(disp_cc_parent_data_3),
+               .ops = &clk_dp_ops,
+       },
+};
+
+static struct clk_rcg2 disp_cc_mdss_esc0_clk_src = {
+       .cmd_rcgr = 0x10f4,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = disp_cc_parent_map_2,
+       .freq_tbl = ftbl_disp_cc_mdss_dp_aux_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "disp_cc_mdss_esc0_clk_src",
+               .parent_data = disp_cc_parent_data_2,
+               .num_parents = ARRAY_SIZE(disp_cc_parent_data_2),
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_disp_cc_mdss_mdp_clk_src[] = {
+       F(200000000, P_GCC_DISP_GPLL0_CLK, 3, 0, 0),
+       F(300000000, P_GCC_DISP_GPLL0_CLK, 2, 0, 0),
+       F(380000000, P_DISP_CC_PLL0_OUT_MAIN, 4, 0, 0),
+       F(506666667, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0),
+       F(608000000, P_DISP_CC_PLL0_OUT_MAIN, 2.5, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 disp_cc_mdss_mdp_clk_src = {
+       .cmd_rcgr = 0x1090,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = disp_cc_parent_map_4,
+       .freq_tbl = ftbl_disp_cc_mdss_mdp_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "disp_cc_mdss_mdp_clk_src",
+               .parent_data = disp_cc_parent_data_4,
+               .num_parents = ARRAY_SIZE(disp_cc_parent_data_4),
+               .ops = &clk_rcg2_shared_ops,
+       },
+};
+
+static struct clk_rcg2 disp_cc_mdss_pclk0_clk_src = {
+       .cmd_rcgr = 0x1078,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = disp_cc_parent_map_6,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "disp_cc_mdss_pclk0_clk_src",
+               .parent_data = disp_cc_parent_data_6,
+               .num_parents = ARRAY_SIZE(disp_cc_parent_data_6),
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_pixel_ops,
+       },
+};
+
+static struct clk_rcg2 disp_cc_mdss_rot_clk_src = {
+       .cmd_rcgr = 0x10a8,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = disp_cc_parent_map_4,
+       .freq_tbl = ftbl_disp_cc_mdss_mdp_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "disp_cc_mdss_rot_clk_src",
+               .parent_data = disp_cc_parent_data_4,
+               .num_parents = ARRAY_SIZE(disp_cc_parent_data_4),
+               .ops = &clk_rcg2_shared_ops,
+       },
+};
+
+static struct clk_rcg2 disp_cc_mdss_vsync_clk_src = {
+       .cmd_rcgr = 0x10c0,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = disp_cc_parent_map_0,
+       .freq_tbl = ftbl_disp_cc_mdss_dp_aux_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "disp_cc_mdss_vsync_clk_src",
+               .parent_data = disp_cc_parent_data_0,
+               .num_parents = ARRAY_SIZE(disp_cc_parent_data_0),
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_regmap_div disp_cc_mdss_byte0_div_clk_src = {
+       .reg = 0x10f0,
+       .shift = 0,
+       .width = 4,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "disp_cc_mdss_byte0_div_clk_src",
+               .parent_hws = (const struct clk_hw*[]){
+                       &disp_cc_mdss_byte0_clk_src.clkr.hw,
+               },
+               .num_parents = 1,
+               .ops = &clk_regmap_div_ops,
+       },
+};
+
+static struct clk_regmap_div disp_cc_mdss_dp_link_div_clk_src = {
+       .reg = 0x1124,
+       .shift = 0,
+       .width = 4,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "disp_cc_mdss_dp_link_div_clk_src",
+               .parent_hws = (const struct clk_hw*[]){
+                       &disp_cc_mdss_dp_link_clk_src.clkr.hw,
+               },
+               .num_parents = 1,
+               .ops = &clk_regmap_div_ro_ops,
+       },
+};
+
+static struct clk_regmap_div disp_cc_mdss_edp_link_div_clk_src = {
+       .reg = 0x11b8,
+       .shift = 0,
+       .width = 4,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "disp_cc_mdss_edp_link_div_clk_src",
+               .parent_hws = (const struct clk_hw*[]){
+                       &disp_cc_mdss_edp_link_clk_src.clkr.hw,
+               },
+               .num_parents = 1,
+               .ops = &clk_regmap_div_ro_ops,
+       },
+};
+
+static struct clk_branch disp_cc_mdss_ahb_clk = {
+       .halt_reg = 0x1050,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x1050,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "disp_cc_mdss_ahb_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &disp_cc_mdss_ahb_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch disp_cc_mdss_byte0_clk = {
+       .halt_reg = 0x1030,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x1030,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "disp_cc_mdss_byte0_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &disp_cc_mdss_byte0_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch disp_cc_mdss_byte0_intf_clk = {
+       .halt_reg = 0x1034,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x1034,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "disp_cc_mdss_byte0_intf_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &disp_cc_mdss_byte0_div_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch disp_cc_mdss_dp_aux_clk = {
+       .halt_reg = 0x104c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x104c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "disp_cc_mdss_dp_aux_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &disp_cc_mdss_dp_aux_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch disp_cc_mdss_dp_crypto_clk = {
+       .halt_reg = 0x1044,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x1044,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "disp_cc_mdss_dp_crypto_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &disp_cc_mdss_dp_crypto_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch disp_cc_mdss_dp_link_clk = {
+       .halt_reg = 0x103c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x103c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "disp_cc_mdss_dp_link_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &disp_cc_mdss_dp_link_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch disp_cc_mdss_dp_link_intf_clk = {
+       .halt_reg = 0x1040,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x1040,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "disp_cc_mdss_dp_link_intf_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &disp_cc_mdss_dp_link_div_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch disp_cc_mdss_dp_pixel_clk = {
+       .halt_reg = 0x1048,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x1048,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "disp_cc_mdss_dp_pixel_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &disp_cc_mdss_dp_pixel_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch disp_cc_mdss_edp_aux_clk = {
+       .halt_reg = 0x1060,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x1060,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "disp_cc_mdss_edp_aux_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &disp_cc_mdss_edp_aux_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch disp_cc_mdss_edp_link_clk = {
+       .halt_reg = 0x1058,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x1058,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "disp_cc_mdss_edp_link_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &disp_cc_mdss_edp_link_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch disp_cc_mdss_edp_link_intf_clk = {
+       .halt_reg = 0x105c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x105c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "disp_cc_mdss_edp_link_intf_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &disp_cc_mdss_edp_link_div_clk_src.clkr.hw
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch disp_cc_mdss_edp_pixel_clk = {
+       .halt_reg = 0x1054,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x1054,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "disp_cc_mdss_edp_pixel_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &disp_cc_mdss_edp_pixel_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch disp_cc_mdss_esc0_clk = {
+       .halt_reg = 0x1038,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x1038,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "disp_cc_mdss_esc0_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &disp_cc_mdss_esc0_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch disp_cc_mdss_mdp_clk = {
+       .halt_reg = 0x1014,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x1014,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "disp_cc_mdss_mdp_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &disp_cc_mdss_mdp_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch disp_cc_mdss_mdp_lut_clk = {
+       .halt_reg = 0x1024,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x1024,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "disp_cc_mdss_mdp_lut_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &disp_cc_mdss_mdp_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch disp_cc_mdss_non_gdsc_ahb_clk = {
+       .halt_reg = 0x2004,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x2004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "disp_cc_mdss_non_gdsc_ahb_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &disp_cc_mdss_ahb_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch disp_cc_mdss_pclk0_clk = {
+       .halt_reg = 0x1010,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x1010,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "disp_cc_mdss_pclk0_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &disp_cc_mdss_pclk0_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch disp_cc_mdss_rot_clk = {
+       .halt_reg = 0x101c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x101c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "disp_cc_mdss_rot_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &disp_cc_mdss_rot_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch disp_cc_mdss_rscc_ahb_clk = {
+       .halt_reg = 0x200c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x200c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "disp_cc_mdss_rscc_ahb_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &disp_cc_mdss_ahb_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch disp_cc_mdss_rscc_vsync_clk = {
+       .halt_reg = 0x2008,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x2008,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "disp_cc_mdss_rscc_vsync_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &disp_cc_mdss_vsync_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch disp_cc_mdss_vsync_clk = {
+       .halt_reg = 0x102c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x102c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "disp_cc_mdss_vsync_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &disp_cc_mdss_vsync_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch disp_cc_sleep_clk = {
+       .halt_reg = 0x5004,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x5004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "disp_cc_sleep_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct gdsc disp_cc_mdss_core_gdsc = {
+       .gdscr = 0x1004,
+       .pd = {
+               .name = "disp_cc_mdss_core_gdsc",
+       },
+       .pwrsts = PWRSTS_OFF_ON,
+       .flags = HW_CTRL | RETAIN_FF_ENABLE,
+};
+
+static struct clk_regmap *disp_cc_sc7280_clocks[] = {
+       [DISP_CC_MDSS_AHB_CLK] = &disp_cc_mdss_ahb_clk.clkr,
+       [DISP_CC_MDSS_AHB_CLK_SRC] = &disp_cc_mdss_ahb_clk_src.clkr,
+       [DISP_CC_MDSS_BYTE0_CLK] = &disp_cc_mdss_byte0_clk.clkr,
+       [DISP_CC_MDSS_BYTE0_CLK_SRC] = &disp_cc_mdss_byte0_clk_src.clkr,
+       [DISP_CC_MDSS_BYTE0_DIV_CLK_SRC] = &disp_cc_mdss_byte0_div_clk_src.clkr,
+       [DISP_CC_MDSS_BYTE0_INTF_CLK] = &disp_cc_mdss_byte0_intf_clk.clkr,
+       [DISP_CC_MDSS_DP_AUX_CLK] = &disp_cc_mdss_dp_aux_clk.clkr,
+       [DISP_CC_MDSS_DP_AUX_CLK_SRC] = &disp_cc_mdss_dp_aux_clk_src.clkr,
+       [DISP_CC_MDSS_DP_CRYPTO_CLK] = &disp_cc_mdss_dp_crypto_clk.clkr,
+       [DISP_CC_MDSS_DP_CRYPTO_CLK_SRC] = &disp_cc_mdss_dp_crypto_clk_src.clkr,
+       [DISP_CC_MDSS_DP_LINK_CLK] = &disp_cc_mdss_dp_link_clk.clkr,
+       [DISP_CC_MDSS_DP_LINK_CLK_SRC] = &disp_cc_mdss_dp_link_clk_src.clkr,
+       [DISP_CC_MDSS_DP_LINK_DIV_CLK_SRC] =
+               &disp_cc_mdss_dp_link_div_clk_src.clkr,
+       [DISP_CC_MDSS_DP_LINK_INTF_CLK] = &disp_cc_mdss_dp_link_intf_clk.clkr,
+       [DISP_CC_MDSS_DP_PIXEL_CLK] = &disp_cc_mdss_dp_pixel_clk.clkr,
+       [DISP_CC_MDSS_DP_PIXEL_CLK_SRC] = &disp_cc_mdss_dp_pixel_clk_src.clkr,
+       [DISP_CC_MDSS_EDP_AUX_CLK] = &disp_cc_mdss_edp_aux_clk.clkr,
+       [DISP_CC_MDSS_EDP_AUX_CLK_SRC] = &disp_cc_mdss_edp_aux_clk_src.clkr,
+       [DISP_CC_MDSS_EDP_LINK_CLK] = &disp_cc_mdss_edp_link_clk.clkr,
+       [DISP_CC_MDSS_EDP_LINK_CLK_SRC] = &disp_cc_mdss_edp_link_clk_src.clkr,
+       [DISP_CC_MDSS_EDP_LINK_DIV_CLK_SRC] =
+               &disp_cc_mdss_edp_link_div_clk_src.clkr,
+       [DISP_CC_MDSS_EDP_LINK_INTF_CLK] = &disp_cc_mdss_edp_link_intf_clk.clkr,
+       [DISP_CC_MDSS_EDP_PIXEL_CLK] = &disp_cc_mdss_edp_pixel_clk.clkr,
+       [DISP_CC_MDSS_EDP_PIXEL_CLK_SRC] = &disp_cc_mdss_edp_pixel_clk_src.clkr,
+       [DISP_CC_MDSS_ESC0_CLK] = &disp_cc_mdss_esc0_clk.clkr,
+       [DISP_CC_MDSS_ESC0_CLK_SRC] = &disp_cc_mdss_esc0_clk_src.clkr,
+       [DISP_CC_MDSS_MDP_CLK] = &disp_cc_mdss_mdp_clk.clkr,
+       [DISP_CC_MDSS_MDP_CLK_SRC] = &disp_cc_mdss_mdp_clk_src.clkr,
+       [DISP_CC_MDSS_MDP_LUT_CLK] = &disp_cc_mdss_mdp_lut_clk.clkr,
+       [DISP_CC_MDSS_NON_GDSC_AHB_CLK] = &disp_cc_mdss_non_gdsc_ahb_clk.clkr,
+       [DISP_CC_MDSS_PCLK0_CLK] = &disp_cc_mdss_pclk0_clk.clkr,
+       [DISP_CC_MDSS_PCLK0_CLK_SRC] = &disp_cc_mdss_pclk0_clk_src.clkr,
+       [DISP_CC_MDSS_ROT_CLK] = &disp_cc_mdss_rot_clk.clkr,
+       [DISP_CC_MDSS_ROT_CLK_SRC] = &disp_cc_mdss_rot_clk_src.clkr,
+       [DISP_CC_MDSS_RSCC_AHB_CLK] = &disp_cc_mdss_rscc_ahb_clk.clkr,
+       [DISP_CC_MDSS_RSCC_VSYNC_CLK] = &disp_cc_mdss_rscc_vsync_clk.clkr,
+       [DISP_CC_MDSS_VSYNC_CLK] = &disp_cc_mdss_vsync_clk.clkr,
+       [DISP_CC_MDSS_VSYNC_CLK_SRC] = &disp_cc_mdss_vsync_clk_src.clkr,
+       [DISP_CC_PLL0] = &disp_cc_pll0.clkr,
+       [DISP_CC_SLEEP_CLK] = &disp_cc_sleep_clk.clkr,
+};
+
+static struct gdsc *disp_cc_sc7280_gdscs[] = {
+       [DISP_CC_MDSS_CORE_GDSC] = &disp_cc_mdss_core_gdsc,
+};
+
+static const struct regmap_config disp_cc_sc7280_regmap_config = {
+       .reg_bits = 32,
+       .reg_stride = 4,
+       .val_bits = 32,
+       .max_register = 0x10000,
+       .fast_io = true,
+};
+
+static const struct qcom_cc_desc disp_cc_sc7280_desc = {
+       .config = &disp_cc_sc7280_regmap_config,
+       .clks = disp_cc_sc7280_clocks,
+       .num_clks = ARRAY_SIZE(disp_cc_sc7280_clocks),
+       .gdscs = disp_cc_sc7280_gdscs,
+       .num_gdscs = ARRAY_SIZE(disp_cc_sc7280_gdscs),
+};
+
+static const struct of_device_id disp_cc_sc7280_match_table[] = {
+       { .compatible = "qcom,sc7280-dispcc" },
+       { }
+};
+MODULE_DEVICE_TABLE(of, disp_cc_sc7280_match_table);
+
+static int disp_cc_sc7280_probe(struct platform_device *pdev)
+{
+       struct regmap *regmap;
+
+       regmap = qcom_cc_map(pdev, &disp_cc_sc7280_desc);
+       if (IS_ERR(regmap))
+               return PTR_ERR(regmap);
+
+       clk_lucid_pll_configure(&disp_cc_pll0, regmap, &disp_cc_pll0_config);
+
+       /*
+        * Keep the clocks always-ON
+        * DISP_CC_XO_CLK
+        */
+       regmap_update_bits(regmap, 0x5008, BIT(0), BIT(0));
+
+       return qcom_cc_really_probe(pdev, &disp_cc_sc7280_desc, regmap);
+}
+
+static struct platform_driver disp_cc_sc7280_driver = {
+       .probe = disp_cc_sc7280_probe,
+       .driver = {
+               .name = "disp_cc-sc7280",
+               .of_match_table = disp_cc_sc7280_match_table,
+       },
+};
+
+static int __init disp_cc_sc7280_init(void)
+{
+       return platform_driver_register(&disp_cc_sc7280_driver);
+}
+subsys_initcall(disp_cc_sc7280_init);
+
+static void __exit disp_cc_sc7280_exit(void)
+{
+       platform_driver_unregister(&disp_cc_sc7280_driver);
+}
+module_exit(disp_cc_sc7280_exit);
+
+MODULE_DESCRIPTION("QTI DISP_CC sc7280 Driver");
+MODULE_LICENSE("GPL v2");
index 601c7c0..bf9ffe1 100644 (file)
@@ -26,6 +26,10 @@ enum {
        P_DISP_CC_PLL1_OUT_MAIN,
        P_DP_PHY_PLL_LINK_CLK,
        P_DP_PHY_PLL_VCO_DIV_CLK,
+       P_DPTX1_PHY_PLL_LINK_CLK,
+       P_DPTX1_PHY_PLL_VCO_DIV_CLK,
+       P_DPTX2_PHY_PLL_LINK_CLK,
+       P_DPTX2_PHY_PLL_VCO_DIV_CLK,
        P_EDP_PHY_PLL_LINK_CLK,
        P_EDP_PHY_PLL_VCO_DIV_CLK,
        P_DSI0_PHY_PLL_OUT_BYTECLK,
@@ -98,12 +102,20 @@ static const struct parent_map disp_cc_parent_map_0[] = {
        { P_BI_TCXO, 0 },
        { P_DP_PHY_PLL_LINK_CLK, 1 },
        { P_DP_PHY_PLL_VCO_DIV_CLK, 2 },
+       { P_DPTX1_PHY_PLL_LINK_CLK, 3 },
+       { P_DPTX1_PHY_PLL_VCO_DIV_CLK, 4 },
+       { P_DPTX2_PHY_PLL_LINK_CLK, 5 },
+       { P_DPTX2_PHY_PLL_VCO_DIV_CLK, 6 },
 };
 
 static const struct clk_parent_data disp_cc_parent_data_0[] = {
        { .fw_name = "bi_tcxo" },
        { .fw_name = "dp_phy_pll_link_clk" },
        { .fw_name = "dp_phy_pll_vco_div_clk" },
+       { .fw_name = "dptx1_phy_pll_link_clk" },
+       { .fw_name = "dptx1_phy_pll_vco_div_clk" },
+       { .fw_name = "dptx2_phy_pll_link_clk" },
+       { .fw_name = "dptx2_phy_pll_vco_div_clk" },
 };
 
 static const struct parent_map disp_cc_parent_map_1[] = {
@@ -269,20 +281,11 @@ static struct clk_rcg2 disp_cc_mdss_dp_aux_clk_src = {
        },
 };
 
-static const struct freq_tbl ftbl_disp_cc_mdss_dp_link1_clk_src[] = {
-       F(162000000, P_DP_PHY_PLL_LINK_CLK, 1, 0, 0),
-       F(270000000, P_DP_PHY_PLL_LINK_CLK, 1, 0, 0),
-       F(540000000, P_DP_PHY_PLL_LINK_CLK, 1, 0, 0),
-       F(810000000, P_DP_PHY_PLL_LINK_CLK, 1, 0, 0),
-       { }
-};
-
 static struct clk_rcg2 disp_cc_mdss_dp_link1_clk_src = {
        .cmd_rcgr = 0x220c,
        .mnd_width = 0,
        .hid_width = 5,
        .parent_map = disp_cc_parent_map_0,
-       .freq_tbl = ftbl_disp_cc_mdss_dp_link1_clk_src,
        .clkr.hw.init = &(struct clk_init_data){
                .name = "disp_cc_mdss_dp_link1_clk_src",
                .parent_data = disp_cc_parent_data_0,
@@ -296,7 +299,6 @@ static struct clk_rcg2 disp_cc_mdss_dp_link_clk_src = {
        .mnd_width = 0,
        .hid_width = 5,
        .parent_map = disp_cc_parent_map_0,
-       .freq_tbl = ftbl_disp_cc_mdss_dp_link1_clk_src,
        .clkr.hw.init = &(struct clk_init_data){
                .name = "disp_cc_mdss_dp_link_clk_src",
                .parent_data = disp_cc_parent_data_0,
diff --git a/drivers/clk/qcom/gcc-msm8953.c b/drivers/clk/qcom/gcc-msm8953.c
new file mode 100644 (file)
index 0000000..49513f1
--- /dev/null
@@ -0,0 +1,4250 @@
+// SPDX-License-Identifier: GPL-2.0-only
+// Copyright (c) 2021, The Linux Foundation. All rights reserved.
+
+#include <linux/kernel.h>
+#include <linux/bitops.h>
+#include <linux/err.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/clk-provider.h>
+#include <linux/regmap.h>
+#include <linux/reset-controller.h>
+
+#include <dt-bindings/clock/qcom,gcc-msm8953.h>
+
+#include "clk-alpha-pll.h"
+#include "clk-branch.h"
+#include "clk-rcg.h"
+#include "common.h"
+#include "gdsc.h"
+#include "reset.h"
+
+enum {
+       P_XO,
+       P_SLEEP_CLK,
+       P_GPLL0,
+       P_GPLL0_DIV2,
+       P_GPLL2,
+       P_GPLL3,
+       P_GPLL4,
+       P_GPLL6,
+       P_GPLL6_DIV2,
+       P_DSI0PLL,
+       P_DSI0PLL_BYTE,
+       P_DSI1PLL,
+       P_DSI1PLL_BYTE,
+};
+
+static struct clk_alpha_pll gpll0_early = {
+       .offset = 0x21000,
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
+       .clkr = {
+               .enable_reg = 0x45000,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gpll0_early",
+                       .parent_data = &(const struct clk_parent_data) {
+                               .fw_name = "xo",
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_alpha_pll_fixed_ops,
+               },
+       },
+};
+
+static struct clk_fixed_factor gpll0_early_div = {
+       .mult = 1,
+       .div = 2,
+       .hw.init = &(struct clk_init_data){
+               .name = "gpll0_early_div",
+               .parent_hws = (const struct clk_hw*[]){
+                       &gpll0_early.clkr.hw,
+               },
+               .num_parents = 1,
+               .ops = &clk_fixed_factor_ops,
+       },
+};
+
+static struct clk_alpha_pll_postdiv gpll0 = {
+       .offset = 0x21000,
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gpll0",
+               .parent_hws = (const struct clk_hw*[]){
+                       &gpll0_early.clkr.hw,
+               },
+               .num_parents = 1,
+               .ops = &clk_alpha_pll_postdiv_ro_ops,
+       },
+};
+
+static struct clk_alpha_pll gpll2_early = {
+       .offset = 0x4a000,
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
+       .clkr = {
+               .enable_reg = 0x45000,
+               .enable_mask = BIT(2),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gpll2_early",
+                       .parent_data = &(const struct clk_parent_data) {
+                               .fw_name = "xo",
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_alpha_pll_fixed_ops,
+               },
+       },
+};
+
+static struct clk_alpha_pll_postdiv gpll2 = {
+       .offset = 0x4a000,
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gpll2",
+               .parent_hws = (const struct clk_hw*[]){
+                       &gpll2_early.clkr.hw,
+               },
+               .num_parents = 1,
+               .ops = &clk_alpha_pll_postdiv_ro_ops,
+       },
+};
+
+static const struct pll_vco gpll3_p_vco[] = {
+       { 1000000000, 2000000000, 0 },
+};
+
+static const struct alpha_pll_config gpll3_early_config = {
+       .l = 63,
+       .config_ctl_val = 0x4001055b,
+       .early_output_mask = 0,
+       .post_div_mask = GENMASK(11, 8),
+       .post_div_val = BIT(8),
+};
+
+static struct clk_alpha_pll gpll3_early = {
+       .offset = 0x22000,
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
+       .vco_table = gpll3_p_vco,
+       .num_vco = ARRAY_SIZE(gpll3_p_vco),
+       .flags = SUPPORTS_DYNAMIC_UPDATE,
+       .clkr = {
+               .hw.init = &(struct clk_init_data){
+                       .name = "gpll3_early",
+                       .parent_data = &(const struct clk_parent_data) {
+                               .fw_name = "xo",
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_alpha_pll_ops,
+               },
+       },
+};
+
+static struct clk_alpha_pll_postdiv gpll3 = {
+       .offset = 0x22000,
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gpll3",
+               .parent_hws = (const struct clk_hw*[]){
+                       &gpll3_early.clkr.hw,
+               },
+               .num_parents = 1,
+               .ops = &clk_alpha_pll_postdiv_ops,
+               .flags = CLK_SET_RATE_PARENT,
+       },
+};
+
+static struct clk_alpha_pll gpll4_early = {
+       .offset = 0x24000,
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
+       .clkr = {
+               .enable_reg = 0x45000,
+               .enable_mask = BIT(5),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gpll4_early",
+                       .parent_data = &(const struct clk_parent_data) {
+                               .fw_name = "xo",
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_alpha_pll_fixed_ops,
+               },
+       },
+};
+
+static struct clk_alpha_pll_postdiv gpll4 = {
+       .offset = 0x24000,
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gpll4",
+               .parent_hws = (const struct clk_hw*[]){
+                       &gpll4_early.clkr.hw,
+               },
+               .num_parents = 1,
+               .ops = &clk_alpha_pll_postdiv_ro_ops,
+       },
+};
+
+static struct clk_alpha_pll gpll6_early = {
+       .offset = 0x37000,
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
+       .clkr = {
+               .enable_reg = 0x45000,
+               .enable_mask = BIT(7),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gpll6_early",
+                       .parent_data = &(const struct clk_parent_data) {
+                               .fw_name = "xo",
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_alpha_pll_fixed_ops,
+               },
+       },
+};
+
+static struct clk_fixed_factor gpll6_early_div = {
+       .mult = 1,
+       .div = 2,
+       .hw.init = &(struct clk_init_data){
+               .name = "gpll6_early_div",
+               .parent_hws = (const struct clk_hw*[]){
+                       &gpll6_early.clkr.hw,
+               },
+               .num_parents = 1,
+               .ops = &clk_fixed_factor_ops,
+       },
+};
+
+static struct clk_alpha_pll_postdiv gpll6 = {
+       .offset = 0x37000,
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gpll6",
+               .parent_hws = (const struct clk_hw*[]){
+                       &gpll6_early.clkr.hw,
+               },
+               .num_parents = 1,
+               .ops = &clk_alpha_pll_postdiv_ro_ops,
+       },
+};
+
+static const struct parent_map gcc_xo_gpll0_gpll0div2_2_map[] = {
+       { P_XO, 0 },
+       { P_GPLL0, 1 },
+       { P_GPLL0_DIV2, 2 },
+};
+
+static const struct parent_map gcc_xo_gpll0_gpll0div2_4_map[] = {
+       { P_XO, 0 },
+       { P_GPLL0, 1 },
+       { P_GPLL0_DIV2, 4 },
+};
+
+static const struct clk_parent_data gcc_xo_gpll0_gpll0div2_data[] = {
+       { .fw_name = "xo" },
+       { .hw = &gpll0.clkr.hw },
+       { .hw = &gpll0_early_div.hw },
+};
+
+static const struct parent_map gcc_apc_droop_detector_map[] = {
+       { P_XO, 0 },
+       { P_GPLL0, 1 },
+       { P_GPLL4, 2 },
+};
+
+static const struct clk_parent_data gcc_apc_droop_detector_data[] = {
+       { .fw_name = "xo" },
+       { .hw = &gpll0.clkr.hw },
+       { .hw = &gpll4.clkr.hw },
+};
+
+static const struct freq_tbl ftbl_apc_droop_detector_clk_src[] = {
+       F(19200000, P_XO, 1, 0, 0),
+       F(400000000, P_GPLL0, 2, 0, 0),
+       F(576000000, P_GPLL4, 2, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 apc0_droop_detector_clk_src = {
+       .cmd_rcgr = 0x78008,
+       .hid_width = 5,
+       .freq_tbl = ftbl_apc_droop_detector_clk_src,
+       .parent_map = gcc_apc_droop_detector_map,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "apc0_droop_detector_clk_src",
+               .parent_data = gcc_apc_droop_detector_data,
+               .num_parents = ARRAY_SIZE(gcc_apc_droop_detector_data),
+               .ops = &clk_rcg2_ops,
+       }
+};
+static struct clk_rcg2 apc1_droop_detector_clk_src = {
+       .cmd_rcgr = 0x79008,
+       .hid_width = 5,
+       .freq_tbl = ftbl_apc_droop_detector_clk_src,
+       .parent_map = gcc_apc_droop_detector_map,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "apc1_droop_detector_clk_src",
+               .parent_data = gcc_apc_droop_detector_data,
+               .num_parents = ARRAY_SIZE(gcc_apc_droop_detector_data),
+               .ops = &clk_rcg2_ops,
+       }
+};
+
+static const struct freq_tbl ftbl_apss_ahb_clk_src[] = {
+       F(19200000, P_XO, 1, 0, 0),
+       F(25000000, P_GPLL0_DIV2, 16, 0, 0),
+       F(50000000, P_GPLL0, 16, 0, 0),
+       F(100000000, P_GPLL0, 8, 0, 0),
+       F(133330000, P_GPLL0, 6, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 apss_ahb_clk_src = {
+       .cmd_rcgr = 0x46000,
+       .hid_width = 5,
+       .freq_tbl = ftbl_apss_ahb_clk_src,
+       .parent_map = gcc_xo_gpll0_gpll0div2_4_map,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "apss_ahb_clk_src",
+               .parent_data = gcc_xo_gpll0_gpll0div2_data,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll0div2_data),
+               .ops = &clk_rcg2_ops,
+       }
+};
+
+static const struct freq_tbl ftbl_blsp_i2c_apps_clk_src[] = {
+       F(19200000, P_XO, 1, 0, 0),
+       F(25000000, P_GPLL0_DIV2, 16, 0, 0),
+       F(50000000, P_GPLL0, 16, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 blsp1_qup1_i2c_apps_clk_src = {
+       .cmd_rcgr = 0x0200c,
+       .hid_width = 5,
+       .freq_tbl = ftbl_blsp_i2c_apps_clk_src,
+       .parent_map = gcc_xo_gpll0_gpll0div2_2_map,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "blsp1_qup1_i2c_apps_clk_src",
+               .parent_data = gcc_xo_gpll0_gpll0div2_data,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll0div2_data),
+               .ops = &clk_rcg2_ops,
+       }
+};
+
+static struct clk_rcg2 blsp1_qup2_i2c_apps_clk_src = {
+       .cmd_rcgr = 0x03000,
+       .hid_width = 5,
+       .freq_tbl = ftbl_blsp_i2c_apps_clk_src,
+       .parent_map = gcc_xo_gpll0_gpll0div2_2_map,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "blsp1_qup2_i2c_apps_clk_src",
+               .parent_data = gcc_xo_gpll0_gpll0div2_data,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll0div2_data),
+               .ops = &clk_rcg2_ops,
+       }
+};
+
+static struct clk_rcg2 blsp1_qup3_i2c_apps_clk_src = {
+       .cmd_rcgr = 0x04000,
+       .hid_width = 5,
+       .freq_tbl = ftbl_blsp_i2c_apps_clk_src,
+       .parent_map = gcc_xo_gpll0_gpll0div2_2_map,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "blsp1_qup3_i2c_apps_clk_src",
+               .parent_data = gcc_xo_gpll0_gpll0div2_data,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll0div2_data),
+               .ops = &clk_rcg2_ops,
+       }
+};
+
+static struct clk_rcg2 blsp1_qup4_i2c_apps_clk_src = {
+       .cmd_rcgr = 0x05000,
+       .hid_width = 5,
+       .freq_tbl = ftbl_blsp_i2c_apps_clk_src,
+       .parent_map = gcc_xo_gpll0_gpll0div2_2_map,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "blsp1_qup4_i2c_apps_clk_src",
+               .parent_data = gcc_xo_gpll0_gpll0div2_data,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll0div2_data),
+               .ops = &clk_rcg2_ops,
+       }
+};
+
+static struct clk_rcg2 blsp2_qup1_i2c_apps_clk_src = {
+       .cmd_rcgr = 0x0c00c,
+       .hid_width = 5,
+       .freq_tbl = ftbl_blsp_i2c_apps_clk_src,
+       .parent_map = gcc_xo_gpll0_gpll0div2_2_map,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "blsp2_qup1_i2c_apps_clk_src",
+               .parent_data = gcc_xo_gpll0_gpll0div2_data,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll0div2_data),
+               .ops = &clk_rcg2_ops,
+       }
+};
+
+static struct clk_rcg2 blsp2_qup2_i2c_apps_clk_src = {
+       .cmd_rcgr = 0x0d000,
+       .hid_width = 5,
+       .freq_tbl = ftbl_blsp_i2c_apps_clk_src,
+       .parent_map = gcc_xo_gpll0_gpll0div2_2_map,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "blsp2_qup2_i2c_apps_clk_src",
+               .parent_data = gcc_xo_gpll0_gpll0div2_data,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll0div2_data),
+               .ops = &clk_rcg2_ops,
+       }
+};
+
+static struct clk_rcg2 blsp2_qup3_i2c_apps_clk_src = {
+       .cmd_rcgr = 0x0f000,
+       .hid_width = 5,
+       .freq_tbl = ftbl_blsp_i2c_apps_clk_src,
+       .parent_map = gcc_xo_gpll0_gpll0div2_2_map,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "blsp2_qup3_i2c_apps_clk_src",
+               .parent_data = gcc_xo_gpll0_gpll0div2_data,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll0div2_data),
+               .ops = &clk_rcg2_ops,
+       }
+};
+
+static struct clk_rcg2 blsp2_qup4_i2c_apps_clk_src = {
+       .cmd_rcgr = 0x18000,
+       .hid_width = 5,
+       .freq_tbl = ftbl_blsp_i2c_apps_clk_src,
+       .parent_map = gcc_xo_gpll0_gpll0div2_2_map,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "blsp2_qup4_i2c_apps_clk_src",
+               .parent_data = gcc_xo_gpll0_gpll0div2_data,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll0div2_data),
+               .ops = &clk_rcg2_ops,
+       }
+};
+
+static const struct freq_tbl ftbl_blsp_spi_apps_clk_src[] = {
+       F(960000, P_XO, 10, 1, 2),
+       F(4800000, P_XO, 4, 0, 0),
+       F(9600000, P_XO, 2, 0, 0),
+       F(12500000, P_GPLL0_DIV2, 16, 1, 2),
+       F(16000000, P_GPLL0, 10, 1, 5),
+       F(19200000, P_XO, 1, 0, 0),
+       F(25000000, P_GPLL0, 16, 1, 2),
+       F(50000000, P_GPLL0, 16, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 blsp1_qup1_spi_apps_clk_src = {
+       .cmd_rcgr = 0x02024,
+       .hid_width = 5,
+       .mnd_width = 8,
+       .freq_tbl = ftbl_blsp_spi_apps_clk_src,
+       .parent_map = gcc_xo_gpll0_gpll0div2_2_map,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "blsp1_qup1_spi_apps_clk_src",
+               .parent_data = gcc_xo_gpll0_gpll0div2_data,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll0div2_data),
+               .ops = &clk_rcg2_ops,
+       }
+};
+
+static struct clk_rcg2 blsp1_qup2_spi_apps_clk_src = {
+       .cmd_rcgr = 0x03014,
+       .hid_width = 5,
+       .mnd_width = 8,
+       .freq_tbl = ftbl_blsp_spi_apps_clk_src,
+       .parent_map = gcc_xo_gpll0_gpll0div2_2_map,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "blsp1_qup2_spi_apps_clk_src",
+               .parent_data = gcc_xo_gpll0_gpll0div2_data,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll0div2_data),
+               .ops = &clk_rcg2_ops,
+       }
+};
+
+static struct clk_rcg2 blsp1_qup3_spi_apps_clk_src = {
+       .cmd_rcgr = 0x04024,
+       .hid_width = 5,
+       .mnd_width = 8,
+       .freq_tbl = ftbl_blsp_spi_apps_clk_src,
+       .parent_map = gcc_xo_gpll0_gpll0div2_2_map,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "blsp1_qup3_spi_apps_clk_src",
+               .parent_data = gcc_xo_gpll0_gpll0div2_data,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll0div2_data),
+               .ops = &clk_rcg2_ops,
+       }
+};
+
+static struct clk_rcg2 blsp1_qup4_spi_apps_clk_src = {
+       .cmd_rcgr = 0x05024,
+       .hid_width = 5,
+       .mnd_width = 8,
+       .freq_tbl = ftbl_blsp_spi_apps_clk_src,
+       .parent_map = gcc_xo_gpll0_gpll0div2_2_map,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "blsp1_qup4_spi_apps_clk_src",
+               .parent_data = gcc_xo_gpll0_gpll0div2_data,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll0div2_data),
+               .ops = &clk_rcg2_ops,
+       }
+};
+
+static struct clk_rcg2 blsp2_qup1_spi_apps_clk_src = {
+       .cmd_rcgr = 0x0c024,
+       .hid_width = 5,
+       .mnd_width = 8,
+       .freq_tbl = ftbl_blsp_spi_apps_clk_src,
+       .parent_map = gcc_xo_gpll0_gpll0div2_2_map,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "blsp2_qup1_spi_apps_clk_src",
+               .parent_data = gcc_xo_gpll0_gpll0div2_data,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll0div2_data),
+               .ops = &clk_rcg2_ops,
+       }
+};
+
+static struct clk_rcg2 blsp2_qup2_spi_apps_clk_src = {
+       .cmd_rcgr = 0x0d014,
+       .hid_width = 5,
+       .mnd_width = 8,
+       .freq_tbl = ftbl_blsp_spi_apps_clk_src,
+       .parent_map = gcc_xo_gpll0_gpll0div2_2_map,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "blsp2_qup2_spi_apps_clk_src",
+               .parent_data = gcc_xo_gpll0_gpll0div2_data,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll0div2_data),
+               .ops = &clk_rcg2_ops,
+       }
+};
+
+static struct clk_rcg2 blsp2_qup3_spi_apps_clk_src = {
+       .cmd_rcgr = 0x0f024,
+       .hid_width = 5,
+       .mnd_width = 8,
+       .freq_tbl = ftbl_blsp_spi_apps_clk_src,
+       .parent_map = gcc_xo_gpll0_gpll0div2_2_map,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "blsp2_qup3_spi_apps_clk_src",
+               .parent_data = gcc_xo_gpll0_gpll0div2_data,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll0div2_data),
+               .ops = &clk_rcg2_ops,
+       }
+};
+
+static struct clk_rcg2 blsp2_qup4_spi_apps_clk_src = {
+       .cmd_rcgr = 0x18024,
+       .hid_width = 5,
+       .mnd_width = 8,
+       .freq_tbl = ftbl_blsp_spi_apps_clk_src,
+       .parent_map = gcc_xo_gpll0_gpll0div2_2_map,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "blsp2_qup4_spi_apps_clk_src",
+               .parent_data = gcc_xo_gpll0_gpll0div2_data,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll0div2_data),
+               .ops = &clk_rcg2_ops,
+       }
+};
+
+static const struct freq_tbl ftbl_blsp_uart_apps_clk_src[] = {
+       F(3686400, P_GPLL0_DIV2, 1, 144, 15625),
+       F(7372800, P_GPLL0_DIV2, 1, 288, 15625),
+       F(14745600, P_GPLL0_DIV2, 1, 576, 15625),
+       F(16000000, P_GPLL0_DIV2, 5, 1, 5),
+       F(19200000, P_XO, 1, 0, 0),
+       F(24000000, P_GPLL0, 1, 3, 100),
+       F(25000000, P_GPLL0, 16, 1, 2),
+       F(32000000, P_GPLL0, 1, 1, 25),
+       F(40000000, P_GPLL0, 1, 1, 20),
+       F(46400000, P_GPLL0, 1, 29, 500),
+       F(48000000, P_GPLL0, 1, 3, 50),
+       F(51200000, P_GPLL0, 1, 8, 125),
+       F(56000000, P_GPLL0, 1, 7, 100),
+       F(58982400, P_GPLL0, 1, 1152, 15625),
+       F(60000000, P_GPLL0, 1, 3, 40),
+       F(64000000, P_GPLL0, 1, 2, 25),
+       { }
+};
+
+static struct clk_rcg2 blsp1_uart1_apps_clk_src = {
+       .cmd_rcgr = 0x02044,
+       .hid_width = 5,
+       .mnd_width = 16,
+       .freq_tbl = ftbl_blsp_uart_apps_clk_src,
+       .parent_map = gcc_xo_gpll0_gpll0div2_4_map,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "blsp1_uart1_apps_clk_src",
+               .parent_data = gcc_xo_gpll0_gpll0div2_data,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll0div2_data),
+               .ops = &clk_rcg2_ops,
+       }
+};
+
+static struct clk_rcg2 blsp1_uart2_apps_clk_src = {
+       .cmd_rcgr = 0x03034,
+       .hid_width = 5,
+       .mnd_width = 16,
+       .freq_tbl = ftbl_blsp_uart_apps_clk_src,
+       .parent_map = gcc_xo_gpll0_gpll0div2_4_map,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "blsp1_uart2_apps_clk_src",
+               .parent_data = gcc_xo_gpll0_gpll0div2_data,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll0div2_data),
+               .ops = &clk_rcg2_ops,
+       }
+};
+
+static struct clk_rcg2 blsp2_uart1_apps_clk_src = {
+       .cmd_rcgr = 0x0c044,
+       .hid_width = 5,
+       .mnd_width = 16,
+       .freq_tbl = ftbl_blsp_uart_apps_clk_src,
+       .parent_map = gcc_xo_gpll0_gpll0div2_4_map,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "blsp2_uart1_apps_clk_src",
+               .parent_data = gcc_xo_gpll0_gpll0div2_data,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll0div2_data),
+               .ops = &clk_rcg2_ops,
+       }
+};
+
+static struct clk_rcg2 blsp2_uart2_apps_clk_src = {
+       .cmd_rcgr = 0x0d034,
+       .hid_width = 5,
+       .mnd_width = 16,
+       .freq_tbl = ftbl_blsp_uart_apps_clk_src,
+       .parent_map = gcc_xo_gpll0_gpll0div2_4_map,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "blsp2_uart2_apps_clk_src",
+               .parent_data = gcc_xo_gpll0_gpll0div2_data,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll0div2_data),
+               .ops = &clk_rcg2_ops,
+       }
+};
+
+static const struct parent_map gcc_byte0_map[] = {
+       { P_XO, 0 },
+       { P_DSI0PLL_BYTE, 1 },
+       { P_DSI1PLL_BYTE, 3 },
+};
+
+static const struct parent_map gcc_byte1_map[] = {
+       { P_XO, 0 },
+       { P_DSI0PLL_BYTE, 3 },
+       { P_DSI1PLL_BYTE, 1 },
+};
+
+static const struct clk_parent_data gcc_byte_data[] = {
+       { .fw_name = "xo" },
+       { .fw_name = "dsi0pllbyte", .name = "dsi0pllbyte" },
+       { .fw_name = "dsi1pllbyte", .name = "dsi1pllbyte" },
+};
+
+static struct clk_rcg2 byte0_clk_src = {
+       .cmd_rcgr = 0x4d044,
+       .hid_width = 5,
+       .parent_map = gcc_byte0_map,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "byte0_clk_src",
+               .parent_data = gcc_byte_data,
+               .num_parents = ARRAY_SIZE(gcc_byte_data),
+               .ops = &clk_byte2_ops,
+               .flags = CLK_SET_RATE_PARENT,
+       }
+};
+
+static struct clk_rcg2 byte1_clk_src = {
+       .cmd_rcgr = 0x4d0b0,
+       .hid_width = 5,
+       .parent_map = gcc_byte1_map,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "byte1_clk_src",
+               .parent_data = gcc_byte_data,
+               .num_parents = ARRAY_SIZE(gcc_byte_data),
+               .ops = &clk_byte2_ops,
+               .flags = CLK_SET_RATE_PARENT,
+       }
+};
+
+static const struct parent_map gcc_gp_map[] = {
+       { P_XO, 0 },
+       { P_GPLL0, 1 },
+       { P_GPLL6, 2 },
+       { P_GPLL0_DIV2, 4 },
+       { P_SLEEP_CLK, 6 },
+};
+
+static const struct clk_parent_data gcc_gp_data[] = {
+       { .fw_name = "xo" },
+       { .hw = &gpll0.clkr.hw },
+       { .hw = &gpll6.clkr.hw },
+       { .hw = &gpll0_early_div.hw },
+       { .fw_name = "sleep", .name = "sleep" },
+};
+
+static const struct freq_tbl ftbl_camss_gp_clk_src[] = {
+       F(50000000, P_GPLL0_DIV2, 8, 0, 0),
+       F(100000000, P_GPLL0, 8, 0, 0),
+       F(200000000, P_GPLL0, 4, 0, 0),
+       F(266670000, P_GPLL0, 3, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 camss_gp0_clk_src = {
+       .cmd_rcgr = 0x54000,
+       .hid_width = 5,
+       .mnd_width = 8,
+       .freq_tbl = ftbl_camss_gp_clk_src,
+       .parent_map = gcc_gp_map,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "camss_gp0_clk_src",
+               .parent_data = gcc_gp_data,
+               .num_parents = ARRAY_SIZE(gcc_gp_data),
+               .ops = &clk_rcg2_ops,
+       }
+};
+
+static struct clk_rcg2 camss_gp1_clk_src = {
+       .cmd_rcgr = 0x55000,
+       .hid_width = 5,
+       .mnd_width = 8,
+       .freq_tbl = ftbl_camss_gp_clk_src,
+       .parent_map = gcc_gp_map,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "camss_gp1_clk_src",
+               .parent_data = gcc_gp_data,
+               .num_parents = ARRAY_SIZE(gcc_gp_data),
+               .ops = &clk_rcg2_ops,
+       }
+};
+
+static const struct freq_tbl ftbl_camss_top_ahb_clk_src[] = {
+       F(40000000, P_GPLL0_DIV2, 10, 0, 0),
+       F(80000000, P_GPLL0, 10, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 camss_top_ahb_clk_src = {
+       .cmd_rcgr = 0x5a000,
+       .hid_width = 5,
+       .freq_tbl = ftbl_camss_top_ahb_clk_src,
+       .parent_map = gcc_xo_gpll0_gpll0div2_2_map,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "camss_top_ahb_clk_src",
+               .parent_data = gcc_xo_gpll0_gpll0div2_data,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll0div2_data),
+               .ops = &clk_rcg2_ops,
+       }
+};
+
+static const struct parent_map gcc_cci_map[] = {
+       { P_XO, 0 },
+       { P_GPLL0, 2 },
+       { P_GPLL0_DIV2, 3 },
+       { P_SLEEP_CLK, 6 },
+};
+
+static const struct clk_parent_data gcc_cci_data[] = {
+       { .fw_name = "xo" },
+       { .hw = &gpll0.clkr.hw },
+       { .hw = &gpll0_early_div.hw },
+       { .fw_name = "sleep", .name = "sleep" },
+};
+
+static const struct freq_tbl ftbl_cci_clk_src[] = {
+       F(19200000, P_XO, 1, 0, 0),
+       F(37500000, P_GPLL0_DIV2, 1, 3, 32),
+       { }
+};
+
+static struct clk_rcg2 cci_clk_src = {
+       .cmd_rcgr = 0x51000,
+       .hid_width = 5,
+       .mnd_width = 8,
+       .freq_tbl = ftbl_cci_clk_src,
+       .parent_map = gcc_cci_map,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "cci_clk_src",
+               .parent_data = gcc_cci_data,
+               .num_parents = ARRAY_SIZE(gcc_cci_data),
+               .ops = &clk_rcg2_ops,
+       }
+};
+
+static const struct parent_map gcc_cpp_map[] = {
+       { P_XO, 0 },
+       { P_GPLL0, 1 },
+       { P_GPLL6, 3 },
+       { P_GPLL2, 4 },
+       { P_GPLL0_DIV2, 5 },
+};
+
+static const struct clk_parent_data gcc_cpp_data[] = {
+       { .fw_name = "xo" },
+       { .hw = &gpll0.clkr.hw },
+       { .hw = &gpll6.clkr.hw },
+       { .hw = &gpll2.clkr.hw },
+       { .hw = &gpll0_early_div.hw },
+};
+
+static const struct freq_tbl ftbl_cpp_clk_src[] = {
+       F(100000000, P_GPLL0_DIV2, 4, 0, 0),
+       F(200000000, P_GPLL0, 4, 0, 0),
+       F(266670000, P_GPLL0, 3, 0, 0),
+       F(320000000, P_GPLL0, 2.5, 0, 0),
+       F(400000000, P_GPLL0, 2, 0, 0),
+       F(465000000, P_GPLL2, 2, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 cpp_clk_src = {
+       .cmd_rcgr = 0x58018,
+       .hid_width = 5,
+       .freq_tbl = ftbl_cpp_clk_src,
+       .parent_map = gcc_cpp_map,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "cpp_clk_src",
+               .parent_data = gcc_cpp_data,
+               .num_parents = ARRAY_SIZE(gcc_cpp_data),
+               .ops = &clk_rcg2_ops,
+       }
+};
+
+static const struct freq_tbl ftbl_crypto_clk_src[] = {
+       F(40000000, P_GPLL0_DIV2, 10, 0, 0),
+       F(80000000, P_GPLL0, 10, 0, 0),
+       F(100000000, P_GPLL0, 8, 0, 0),
+       F(160000000, P_GPLL0, 5, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 crypto_clk_src = {
+       .cmd_rcgr = 0x16004,
+       .hid_width = 5,
+       .freq_tbl = ftbl_crypto_clk_src,
+       .parent_map = gcc_xo_gpll0_gpll0div2_4_map,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "crypto_clk_src",
+               .parent_data = gcc_xo_gpll0_gpll0div2_data,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll0div2_data),
+               .ops = &clk_rcg2_ops,
+       }
+};
+
+static const struct parent_map gcc_csi0_map[] = {
+       { P_XO, 0 },
+       { P_GPLL0, 1 },
+       { P_GPLL2, 4 },
+       { P_GPLL0_DIV2, 5 },
+};
+
+static const struct parent_map gcc_csi12_map[] = {
+       { P_XO, 0 },
+       { P_GPLL0, 1 },
+       { P_GPLL2, 5 },
+       { P_GPLL0_DIV2, 4 },
+};
+
+static const struct clk_parent_data gcc_csi_data[] = {
+       { .fw_name = "xo" },
+       { .hw = &gpll0.clkr.hw },
+       { .hw = &gpll2.clkr.hw },
+       { .hw = &gpll0_early_div.hw },
+};
+
+static const struct freq_tbl ftbl_csi_clk_src[] = {
+       F(100000000, P_GPLL0_DIV2, 4, 0, 0),
+       F(200000000, P_GPLL0, 4, 0, 0),
+       F(310000000, P_GPLL2, 3, 0, 0),
+       F(400000000, P_GPLL0, 2, 0, 0),
+       F(465000000, P_GPLL2, 2, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 csi0_clk_src = {
+       .cmd_rcgr = 0x4e020,
+       .hid_width = 5,
+       .freq_tbl = ftbl_csi_clk_src,
+       .parent_map = gcc_csi0_map,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "csi0_clk_src",
+               .parent_data = gcc_csi_data,
+               .num_parents = ARRAY_SIZE(gcc_csi_data),
+               .ops = &clk_rcg2_ops,
+       }
+};
+
+static struct clk_rcg2 csi1_clk_src = {
+       .cmd_rcgr = 0x4f020,
+       .hid_width = 5,
+       .freq_tbl = ftbl_csi_clk_src,
+       .parent_map = gcc_csi12_map,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "csi1_clk_src",
+               .parent_data = gcc_csi_data,
+               .num_parents = ARRAY_SIZE(gcc_csi_data),
+               .ops = &clk_rcg2_ops,
+       }
+};
+
+static struct clk_rcg2 csi2_clk_src = {
+       .cmd_rcgr = 0x3c020,
+       .hid_width = 5,
+       .freq_tbl = ftbl_csi_clk_src,
+       .parent_map = gcc_csi12_map,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "csi2_clk_src",
+               .parent_data = gcc_csi_data,
+               .num_parents = ARRAY_SIZE(gcc_csi_data),
+               .ops = &clk_rcg2_ops,
+       }
+};
+
+static const struct parent_map gcc_csip_map[] = {
+       { P_XO, 0 },
+       { P_GPLL0, 1 },
+       { P_GPLL4, 3 },
+       { P_GPLL2, 4 },
+       { P_GPLL0_DIV2, 5 },
+};
+
+static const struct clk_parent_data gcc_csip_data[] = {
+       { .fw_name = "xo" },
+       { .hw = &gpll0.clkr.hw },
+       { .hw = &gpll4.clkr.hw },
+       { .hw = &gpll2.clkr.hw },
+       { .hw = &gpll0_early_div.hw },
+};
+
+static const struct freq_tbl ftbl_csi_p_clk_src[] = {
+       F(66670000, P_GPLL0_DIV2, 6, 0, 0),
+       F(133330000, P_GPLL0, 6, 0, 0),
+       F(200000000, P_GPLL0, 4, 0, 0),
+       F(266670000, P_GPLL0, 3, 0, 0),
+       F(310000000, P_GPLL2, 3, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 csi0p_clk_src = {
+       .cmd_rcgr = 0x58084,
+       .hid_width = 5,
+       .freq_tbl = ftbl_csi_p_clk_src,
+       .parent_map = gcc_csip_map,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "csi0p_clk_src",
+               .parent_data = gcc_csip_data,
+               .num_parents = ARRAY_SIZE(gcc_csip_data),
+               .ops = &clk_rcg2_ops,
+       }
+};
+
+static struct clk_rcg2 csi1p_clk_src = {
+       .cmd_rcgr = 0x58094,
+       .hid_width = 5,
+       .freq_tbl = ftbl_csi_p_clk_src,
+       .parent_map = gcc_csip_map,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "csi1p_clk_src",
+               .parent_data = gcc_csip_data,
+               .num_parents = ARRAY_SIZE(gcc_csip_data),
+               .ops = &clk_rcg2_ops,
+       }
+};
+
+static struct clk_rcg2 csi2p_clk_src = {
+       .cmd_rcgr = 0x580a4,
+       .hid_width = 5,
+       .freq_tbl = ftbl_csi_p_clk_src,
+       .parent_map = gcc_csip_map,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "csi2p_clk_src",
+               .parent_data = gcc_csip_data,
+               .num_parents = ARRAY_SIZE(gcc_csip_data),
+               .ops = &clk_rcg2_ops,
+       }
+};
+
+static const struct freq_tbl ftbl_csi_phytimer_clk_src[] = {
+       F(100000000, P_GPLL0_DIV2, 4, 0, 0),
+       F(200000000, P_GPLL0, 4, 0, 0),
+       F(266670000, P_GPLL0, 3, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 csi0phytimer_clk_src = {
+       .cmd_rcgr = 0x4e000,
+       .hid_width = 5,
+       .freq_tbl = ftbl_csi_phytimer_clk_src,
+       .parent_map = gcc_xo_gpll0_gpll0div2_2_map,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "csi0phytimer_clk_src",
+               .parent_data = gcc_xo_gpll0_gpll0div2_data,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll0div2_data),
+               .ops = &clk_rcg2_ops,
+       }
+};
+
+static struct clk_rcg2 csi1phytimer_clk_src = {
+       .cmd_rcgr = 0x4f000,
+       .hid_width = 5,
+       .freq_tbl = ftbl_csi_phytimer_clk_src,
+       .parent_map = gcc_xo_gpll0_gpll0div2_2_map,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "csi1phytimer_clk_src",
+               .parent_data = gcc_xo_gpll0_gpll0div2_data,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll0div2_data),
+               .ops = &clk_rcg2_ops,
+       }
+};
+
+static struct clk_rcg2 csi2phytimer_clk_src = {
+       .cmd_rcgr = 0x4f05c,
+       .hid_width = 5,
+       .freq_tbl = ftbl_csi_phytimer_clk_src,
+       .parent_map = gcc_xo_gpll0_gpll0div2_2_map,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "csi2phytimer_clk_src",
+               .parent_data = gcc_xo_gpll0_gpll0div2_data,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll0div2_data),
+               .ops = &clk_rcg2_ops,
+       }
+};
+
+static const struct parent_map gcc_esc_map[] = {
+       { P_XO, 0 },
+       { P_GPLL0, 3 },
+};
+
+static const struct clk_parent_data gcc_esc_vsync_data[] = {
+       { .fw_name = "xo" },
+       { .hw = &gpll0.clkr.hw },
+};
+
+static const struct freq_tbl ftbl_esc0_1_clk_src[] = {
+       F(19200000, P_XO, 1, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 esc0_clk_src = {
+       .cmd_rcgr = 0x4d05c,
+       .hid_width = 5,
+       .freq_tbl = ftbl_esc0_1_clk_src,
+       .parent_map = gcc_esc_map,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "esc0_clk_src",
+               .parent_data = gcc_esc_vsync_data,
+               .num_parents = ARRAY_SIZE(gcc_esc_vsync_data),
+               .ops = &clk_rcg2_ops,
+       }
+};
+
+static struct clk_rcg2 esc1_clk_src = {
+       .cmd_rcgr = 0x4d0a8,
+       .hid_width = 5,
+       .freq_tbl = ftbl_esc0_1_clk_src,
+       .parent_map = gcc_esc_map,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "esc1_clk_src",
+               .parent_data = gcc_esc_vsync_data,
+               .num_parents = ARRAY_SIZE(gcc_esc_vsync_data),
+               .ops = &clk_rcg2_ops,
+       }
+};
+
+static const struct parent_map gcc_gfx3d_map[] = {
+       { P_XO, 0 },
+       { P_GPLL0, 1 },
+       { P_GPLL3, 2 },
+       { P_GPLL6, 3 },
+       { P_GPLL4, 4 },
+       { P_GPLL0_DIV2, 5 },
+       { P_GPLL6_DIV2, 6 },
+};
+
+static const struct clk_parent_data gcc_gfx3d_data[] = {
+       { .fw_name = "xo" },
+       { .hw = &gpll0.clkr.hw },
+       { .hw = &gpll3.clkr.hw },
+       { .hw = &gpll6.clkr.hw },
+       { .hw = &gpll4.clkr.hw },
+       { .hw = &gpll0_early_div.hw },
+       { .hw = &gpll6_early_div.hw },
+};
+
+static const struct freq_tbl ftbl_gfx3d_clk_src[] = {
+       F(19200000, P_XO, 1, 0, 0),
+       F(50000000, P_GPLL0_DIV2, 8, 0, 0),
+       F(80000000, P_GPLL0_DIV2, 5, 0, 0),
+       F(100000000, P_GPLL0_DIV2, 4, 0, 0),
+       F(133330000, P_GPLL0_DIV2, 3, 0, 0),
+       F(160000000, P_GPLL0_DIV2, 2.5, 0, 0),
+       F(200000000, P_GPLL0_DIV2, 2, 0, 0),
+       F(266670000, P_GPLL0, 3.0, 0, 0),
+       F(320000000, P_GPLL0, 2.5, 0, 0),
+       F(400000000, P_GPLL0, 2, 0, 0),
+       F(460800000, P_GPLL4, 2.5, 0, 0),
+       F(510000000, P_GPLL3, 2, 0, 0),
+       F(560000000, P_GPLL3, 2, 0, 0),
+       F(600000000, P_GPLL3, 2, 0, 0),
+       F(650000000, P_GPLL3, 2, 0, 0),
+       F(685000000, P_GPLL3, 2, 0, 0),
+       F(725000000, P_GPLL3, 2, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 gfx3d_clk_src = {
+       .cmd_rcgr = 0x59000,
+       .hid_width = 5,
+       .freq_tbl = ftbl_gfx3d_clk_src,
+       .parent_map = gcc_gfx3d_map,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "gfx3d_clk_src",
+               .parent_data = gcc_gfx3d_data,
+               .num_parents = ARRAY_SIZE(gcc_gfx3d_data),
+               .ops = &clk_rcg2_floor_ops,
+               .flags = CLK_SET_RATE_PARENT,
+       }
+};
+
+static const struct freq_tbl ftbl_gp_clk_src[] = {
+       F(19200000, P_XO, 1, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 gp1_clk_src = {
+       .cmd_rcgr = 0x08004,
+       .hid_width = 5,
+       .mnd_width = 8,
+       .freq_tbl = ftbl_gp_clk_src,
+       .parent_map = gcc_gp_map,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "gp1_clk_src",
+               .parent_data = gcc_gp_data,
+               .num_parents = ARRAY_SIZE(gcc_gp_data),
+               .ops = &clk_rcg2_ops,
+       }
+};
+
+static struct clk_rcg2 gp2_clk_src = {
+       .cmd_rcgr = 0x09004,
+       .hid_width = 5,
+       .mnd_width = 8,
+       .freq_tbl = ftbl_gp_clk_src,
+       .parent_map = gcc_gp_map,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "gp2_clk_src",
+               .parent_data = gcc_gp_data,
+               .num_parents = ARRAY_SIZE(gcc_gp_data),
+               .ops = &clk_rcg2_ops,
+       }
+};
+
+static struct clk_rcg2 gp3_clk_src = {
+       .cmd_rcgr = 0x0a004,
+       .hid_width = 5,
+       .mnd_width = 8,
+       .freq_tbl = ftbl_gp_clk_src,
+       .parent_map = gcc_gp_map,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "gp3_clk_src",
+               .parent_data = gcc_gp_data,
+               .num_parents = ARRAY_SIZE(gcc_gp_data),
+               .ops = &clk_rcg2_ops,
+       }
+};
+
+static const struct parent_map gcc_jpeg0_map[] = {
+       { P_XO, 0 },
+       { P_GPLL0, 1 },
+       { P_GPLL6, 2 },
+       { P_GPLL0_DIV2, 4 },
+       { P_GPLL2, 5 },
+};
+
+static const struct clk_parent_data gcc_jpeg0_data[] = {
+       { .fw_name = "xo" },
+       { .hw = &gpll0.clkr.hw },
+       { .hw = &gpll6.clkr.hw },
+       { .hw = &gpll0_early_div.hw },
+       { .hw = &gpll2.clkr.hw },
+};
+
+static const struct freq_tbl ftbl_jpeg0_clk_src[] = {
+       F(66670000, P_GPLL0_DIV2, 6, 0, 0),
+       F(133330000, P_GPLL0, 6, 0, 0),
+       F(200000000, P_GPLL0, 4, 0, 0),
+       F(266670000, P_GPLL0, 3, 0, 0),
+       F(310000000, P_GPLL2, 3, 0, 0),
+       F(320000000, P_GPLL0, 2.5, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 jpeg0_clk_src = {
+       .cmd_rcgr = 0x57000,
+       .hid_width = 5,
+       .freq_tbl = ftbl_jpeg0_clk_src,
+       .parent_map = gcc_jpeg0_map,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "jpeg0_clk_src",
+               .parent_data = gcc_jpeg0_data,
+               .num_parents = ARRAY_SIZE(gcc_jpeg0_data),
+               .ops = &clk_rcg2_ops,
+       }
+};
+
+static const struct parent_map gcc_mclk_map[] = {
+       { P_XO, 0 },
+       { P_GPLL0, 1 },
+       { P_GPLL6, 2 },
+       { P_GPLL0_DIV2, 4 },
+       { P_GPLL6_DIV2, 5 },
+       { P_SLEEP_CLK, 6 },
+};
+
+static const struct clk_parent_data gcc_mclk_data[] = {
+       { .fw_name = "xo" },
+       { .hw = &gpll0.clkr.hw },
+       { .hw = &gpll6.clkr.hw },
+       { .hw = &gpll0_early_div.hw },
+       { .hw = &gpll6_early_div.hw },
+       { .fw_name = "sleep", .name = "sleep" },
+};
+
+static const struct freq_tbl ftbl_mclk_clk_src[] = {
+       F(19200000, P_GPLL6, 5, 4, 45),
+       F(24000000, P_GPLL6_DIV2, 1, 2, 45),
+       F(26000000, P_GPLL0, 1, 4, 123),
+       F(33330000, P_GPLL0_DIV2, 12, 0, 0),
+       F(36610000, P_GPLL6, 1, 2, 59),
+       F(66667000, P_GPLL0, 12, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 mclk0_clk_src = {
+       .cmd_rcgr = 0x52000,
+       .hid_width = 5,
+       .mnd_width = 8,
+       .freq_tbl = ftbl_mclk_clk_src,
+       .parent_map = gcc_mclk_map,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "mclk0_clk_src",
+               .parent_data = gcc_mclk_data,
+               .num_parents = ARRAY_SIZE(gcc_mclk_data),
+               .ops = &clk_rcg2_ops,
+       }
+};
+
+static struct clk_rcg2 mclk1_clk_src = {
+       .cmd_rcgr = 0x53000,
+       .hid_width = 5,
+       .mnd_width = 8,
+       .freq_tbl = ftbl_mclk_clk_src,
+       .parent_map = gcc_mclk_map,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "mclk1_clk_src",
+               .parent_data = gcc_mclk_data,
+               .num_parents = ARRAY_SIZE(gcc_mclk_data),
+               .ops = &clk_rcg2_ops,
+       }
+};
+
+static struct clk_rcg2 mclk2_clk_src = {
+       .cmd_rcgr = 0x5c000,
+       .hid_width = 5,
+       .mnd_width = 8,
+       .freq_tbl = ftbl_mclk_clk_src,
+       .parent_map = gcc_mclk_map,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "mclk2_clk_src",
+               .parent_data = gcc_mclk_data,
+               .num_parents = ARRAY_SIZE(gcc_mclk_data),
+               .ops = &clk_rcg2_ops,
+       }
+};
+
+static struct clk_rcg2 mclk3_clk_src = {
+       .cmd_rcgr = 0x5e000,
+       .hid_width = 5,
+       .mnd_width = 8,
+       .freq_tbl = ftbl_mclk_clk_src,
+       .parent_map = gcc_mclk_map,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "mclk3_clk_src",
+               .parent_data = gcc_mclk_data,
+               .num_parents = ARRAY_SIZE(gcc_mclk_data),
+               .ops = &clk_rcg2_ops,
+       }
+};
+
+static const struct parent_map gcc_mdp_map[] = {
+       { P_XO, 0 },
+       { P_GPLL0, 1 },
+       { P_GPLL6, 3 },
+       { P_GPLL0_DIV2, 4 },
+};
+
+static const struct clk_parent_data gcc_mdp_data[] = {
+       { .fw_name = "xo" },
+       { .hw = &gpll0.clkr.hw },
+       { .hw = &gpll6.clkr.hw },
+       { .hw = &gpll0_early_div.hw },
+};
+
+static const struct freq_tbl ftbl_mdp_clk_src[] = {
+       F(50000000, P_GPLL0_DIV2, 8, 0, 0),
+       F(80000000, P_GPLL0_DIV2, 5, 0, 0),
+       F(160000000, P_GPLL0_DIV2, 2.5, 0, 0),
+       F(200000000, P_GPLL0, 4, 0, 0),
+       F(266670000, P_GPLL0, 3, 0, 0),
+       F(320000000, P_GPLL0, 2.5, 0, 0),
+       F(400000000, P_GPLL0, 2, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 mdp_clk_src = {
+       .cmd_rcgr = 0x4d014,
+       .hid_width = 5,
+       .freq_tbl = ftbl_mdp_clk_src,
+       .parent_map = gcc_mdp_map,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "mdp_clk_src",
+               .parent_data = gcc_mdp_data,
+               .num_parents = ARRAY_SIZE(gcc_mdp_data),
+               .ops = &clk_rcg2_ops,
+       }
+};
+
+static const struct parent_map gcc_pclk0_map[] = {
+       { P_XO, 0 },
+       { P_DSI0PLL, 1 },
+       { P_DSI1PLL, 3 },
+};
+
+static const struct parent_map gcc_pclk1_map[] = {
+       { P_XO, 0 },
+       { P_DSI0PLL, 3 },
+       { P_DSI1PLL, 1 },
+};
+
+static const struct clk_parent_data gcc_pclk_data[] = {
+       { .fw_name = "xo" },
+       { .fw_name = "dsi0pll", .name = "dsi0pll" },
+       { .fw_name = "dsi1pll", .name = "dsi1pll" },
+};
+
+static struct clk_rcg2 pclk0_clk_src = {
+       .cmd_rcgr = 0x4d000,
+       .hid_width = 5,
+       .mnd_width = 8,
+       .parent_map = gcc_pclk0_map,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "pclk0_clk_src",
+               .parent_data = gcc_pclk_data,
+               .num_parents = ARRAY_SIZE(gcc_pclk_data),
+               .ops = &clk_pixel_ops,
+               .flags = CLK_SET_RATE_PARENT,
+       }
+};
+
+static struct clk_rcg2 pclk1_clk_src = {
+       .cmd_rcgr = 0x4d0b8,
+       .hid_width = 5,
+       .mnd_width = 8,
+       .parent_map = gcc_pclk1_map,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "pclk1_clk_src",
+               .parent_data = gcc_pclk_data,
+               .num_parents = ARRAY_SIZE(gcc_pclk_data),
+               .ops = &clk_pixel_ops,
+               .flags = CLK_SET_RATE_PARENT,
+       }
+};
+
+static const struct freq_tbl ftbl_pdm2_clk_src[] = {
+       F(32000000, P_GPLL0_DIV2, 12.5, 0, 0),
+       F(64000000, P_GPLL0, 12.5, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 pdm2_clk_src = {
+       .cmd_rcgr = 0x44010,
+       .hid_width = 5,
+       .freq_tbl = ftbl_pdm2_clk_src,
+       .parent_map = gcc_xo_gpll0_gpll0div2_2_map,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "pdm2_clk_src",
+               .parent_data = gcc_xo_gpll0_gpll0div2_data,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll0div2_data),
+               .ops = &clk_rcg2_ops,
+       }
+};
+
+static const struct freq_tbl ftbl_rbcpr_gfx_clk_src[] = {
+       F(19200000, P_XO, 1, 0, 0),
+       F(50000000, P_GPLL0, 16, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 rbcpr_gfx_clk_src = {
+       .cmd_rcgr = 0x3a00c,
+       .hid_width = 5,
+       .freq_tbl = ftbl_rbcpr_gfx_clk_src,
+       .parent_map = gcc_xo_gpll0_gpll0div2_4_map,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "rbcpr_gfx_clk_src",
+               .parent_data = gcc_xo_gpll0_gpll0div2_data,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll0div2_data),
+               .ops = &clk_rcg2_ops,
+       }
+};
+
+static const struct parent_map gcc_sdcc1_ice_core_map[] = {
+       { P_XO, 0 },
+       { P_GPLL0, 1 },
+       { P_GPLL6, 2 },
+       { P_GPLL0_DIV2, 4 },
+};
+
+static const struct clk_parent_data gcc_sdcc1_ice_core_data[] = {
+       { .fw_name = "xo" },
+       { .hw = &gpll0.clkr.hw },
+       { .hw = &gpll6.clkr.hw },
+       { .hw = &gpll0_early_div.hw },
+};
+
+static const struct freq_tbl ftbl_sdcc1_ice_core_clk_src[] = {
+       F(80000000, P_GPLL0_DIV2, 5, 0, 0),
+       F(160000000, P_GPLL0, 5, 0, 0),
+       F(270000000, P_GPLL6, 4, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 sdcc1_ice_core_clk_src = {
+       .cmd_rcgr = 0x5d000,
+       .hid_width = 5,
+       .freq_tbl = ftbl_sdcc1_ice_core_clk_src,
+       .parent_map = gcc_sdcc1_ice_core_map,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "sdcc1_ice_core_clk_src",
+               .parent_data = gcc_sdcc1_ice_core_data,
+               .num_parents = ARRAY_SIZE(gcc_sdcc1_ice_core_data),
+               .ops = &clk_rcg2_ops,
+       }
+};
+
+static const struct parent_map gcc_sdcc_apps_map[] = {
+       { P_XO, 0 },
+       { P_GPLL0, 1 },
+       { P_GPLL4, 2 },
+       { P_GPLL0_DIV2, 4 },
+};
+
+static const struct clk_parent_data gcc_sdcc_apss_data[] = {
+       { .fw_name = "xo" },
+       { .hw = &gpll0.clkr.hw },
+       { .hw = &gpll4.clkr.hw },
+       { .hw = &gpll0_early_div.hw },
+};
+
+static const struct freq_tbl ftbl_sdcc1_apps_clk_src[] = {
+       F(144000, P_XO, 16, 3, 25),
+       F(400000, P_XO, 12, 1, 4),
+       F(20000000, P_GPLL0_DIV2, 5, 1, 4),
+       F(25000000, P_GPLL0_DIV2, 16, 0, 0),
+       F(50000000, P_GPLL0, 16, 0, 0),
+       F(100000000, P_GPLL0, 8, 0, 0),
+       F(177770000, P_GPLL0, 4.5, 0, 0),
+       F(192000000, P_GPLL4, 6, 0, 0),
+       F(384000000, P_GPLL4, 3, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 sdcc1_apps_clk_src = {
+       .cmd_rcgr = 0x42004,
+       .hid_width = 5,
+       .mnd_width = 8,
+       .freq_tbl = ftbl_sdcc1_apps_clk_src,
+       .parent_map = gcc_sdcc_apps_map,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "sdcc1_apps_clk_src",
+               .parent_data = gcc_sdcc_apss_data,
+               .num_parents = ARRAY_SIZE(gcc_sdcc_apss_data),
+               .ops = &clk_rcg2_floor_ops,
+       }
+};
+
+static const struct freq_tbl ftbl_sdcc2_apps_clk_src[] = {
+       F(144000, P_XO, 16, 3, 25),
+       F(400000, P_XO, 12, 1, 4),
+       F(20000000, P_GPLL0_DIV2, 5, 1, 4),
+       F(25000000, P_GPLL0_DIV2, 16, 0, 0),
+       F(50000000, P_GPLL0, 16, 0, 0),
+       F(100000000, P_GPLL0, 8, 0, 0),
+       F(177770000, P_GPLL0, 4.5, 0, 0),
+       F(192000000, P_GPLL4, 6, 0, 0),
+       F(200000000, P_GPLL0, 4, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 sdcc2_apps_clk_src = {
+       .cmd_rcgr = 0x43004,
+       .hid_width = 5,
+       .mnd_width = 8,
+       .freq_tbl = ftbl_sdcc2_apps_clk_src,
+       .parent_map = gcc_sdcc_apps_map,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "sdcc2_apps_clk_src",
+               .parent_data = gcc_sdcc_apss_data,
+               .num_parents = ARRAY_SIZE(gcc_sdcc_apss_data),
+               .ops = &clk_rcg2_floor_ops,
+       }
+};
+
+static const struct freq_tbl ftbl_usb30_master_clk_src[] = {
+       F(80000000, P_GPLL0_DIV2, 5, 0, 0),
+       F(100000000, P_GPLL0, 8, 0, 0),
+       F(133330000, P_GPLL0, 6, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 usb30_master_clk_src = {
+       .cmd_rcgr = 0x3f00c,
+       .hid_width = 5,
+       .freq_tbl = ftbl_usb30_master_clk_src,
+       .parent_map = gcc_xo_gpll0_gpll0div2_2_map,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "usb30_master_clk_src",
+               .parent_data = gcc_xo_gpll0_gpll0div2_data,
+               .num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll0div2_data),
+               .ops = &clk_rcg2_ops,
+       }
+};
+
+static const struct parent_map gcc_usb30_mock_utmi_map[] = {
+       { P_XO, 0 },
+       { P_GPLL6, 1 },
+       { P_GPLL6_DIV2, 2 },
+       { P_GPLL0, 3 },
+       { P_GPLL0_DIV2, 4 },
+};
+
+static const struct clk_parent_data gcc_usb30_mock_utmi_data[] = {
+       { .fw_name = "xo" },
+       { .hw = &gpll6.clkr.hw },
+       { .hw = &gpll6_early_div.hw },
+       { .hw = &gpll0.clkr.hw },
+       { .hw = &gpll0_early_div.hw },
+};
+
+static const struct freq_tbl ftbl_usb30_mock_utmi_clk_src[] = {
+       F(19200000, P_XO, 1, 0, 0),
+       F(60000000, P_GPLL6_DIV2, 9, 1, 1),
+       { }
+};
+
+static struct clk_rcg2 usb30_mock_utmi_clk_src = {
+       .cmd_rcgr = 0x3f020,
+       .hid_width = 5,
+       .mnd_width = 8,
+       .freq_tbl = ftbl_usb30_mock_utmi_clk_src,
+       .parent_map = gcc_usb30_mock_utmi_map,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "usb30_mock_utmi_clk_src",
+               .parent_data = gcc_usb30_mock_utmi_data,
+               .num_parents = ARRAY_SIZE(gcc_usb30_mock_utmi_data),
+               .ops = &clk_rcg2_ops,
+       }
+};
+
+static const struct parent_map gcc_usb3_aux_map[] = {
+       { P_XO, 0 },
+       { P_SLEEP_CLK, 6 },
+};
+
+static const struct clk_parent_data gcc_usb3_aux_data[] = {
+       { .fw_name = "xo" },
+       { .fw_name = "sleep", .name = "sleep" },
+};
+
+static const struct freq_tbl ftbl_usb3_aux_clk_src[] = {
+       F(19200000, P_XO, 1, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 usb3_aux_clk_src = {
+       .cmd_rcgr = 0x3f05c,
+       .hid_width = 5,
+       .mnd_width = 8,
+       .freq_tbl = ftbl_usb3_aux_clk_src,
+       .parent_map = gcc_usb3_aux_map,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "usb3_aux_clk_src",
+               .parent_data = gcc_usb3_aux_data,
+               .num_parents = ARRAY_SIZE(gcc_usb3_aux_data),
+               .ops = &clk_rcg2_ops,
+       }
+};
+
+static const struct parent_map gcc_vcodec0_map[] = {
+       { P_XO, 0 },
+       { P_GPLL0, 1 },
+       { P_GPLL6, 2 },
+       { P_GPLL2, 3 },
+       { P_GPLL0_DIV2, 4 },
+};
+
+static const struct clk_parent_data gcc_vcodec0_data[] = {
+       { .fw_name = "xo" },
+       { .hw = &gpll0.clkr.hw },
+       { .hw = &gpll6.clkr.hw },
+       { .hw = &gpll2.clkr.hw },
+       { .hw = &gpll0_early_div.hw },
+};
+
+static const struct freq_tbl ftbl_vcodec0_clk_src[] = {
+       F(114290000, P_GPLL0_DIV2, 3.5, 0, 0),
+       F(228570000, P_GPLL0, 3.5, 0, 0),
+       F(310000000, P_GPLL2, 3, 0, 0),
+       F(360000000, P_GPLL6, 3, 0, 0),
+       F(400000000, P_GPLL0, 2, 0, 0),
+       F(465000000, P_GPLL2, 2, 0, 0),
+       F(540000000, P_GPLL6, 2, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 vcodec0_clk_src = {
+       .cmd_rcgr = 0x4c000,
+       .hid_width = 5,
+       .freq_tbl = ftbl_vcodec0_clk_src,
+       .parent_map = gcc_vcodec0_map,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "vcodec0_clk_src",
+               .parent_data = gcc_vcodec0_data,
+               .num_parents = ARRAY_SIZE(gcc_vcodec0_data),
+               .ops = &clk_rcg2_ops,
+       }
+};
+
+static const struct parent_map gcc_vfe_map[] = {
+       { P_XO, 0 },
+       { P_GPLL0, 1 },
+       { P_GPLL6, 2 },
+       { P_GPLL4, 3 },
+       { P_GPLL2, 4 },
+       { P_GPLL0_DIV2, 5 },
+};
+
+static const struct clk_parent_data gcc_vfe_data[] = {
+       { .fw_name = "xo" },
+       { .hw = &gpll0.clkr.hw },
+       { .hw = &gpll6.clkr.hw },
+       { .hw = &gpll4.clkr.hw },
+       { .hw = &gpll2.clkr.hw },
+       { .hw = &gpll0_early_div.hw },
+};
+
+static const struct freq_tbl ftbl_vfe_clk_src[] = {
+       F(50000000, P_GPLL0_DIV2, 8, 0, 0),
+       F(100000000, P_GPLL0_DIV2, 4, 0, 0),
+       F(133330000, P_GPLL0, 6, 0, 0),
+       F(160000000, P_GPLL0, 5, 0, 0),
+       F(200000000, P_GPLL0, 4, 0, 0),
+       F(266670000, P_GPLL0, 3, 0, 0),
+       F(310000000, P_GPLL2, 3, 0, 0),
+       F(400000000, P_GPLL0, 2, 0, 0),
+       F(465000000, P_GPLL2, 2, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 vfe0_clk_src = {
+       .cmd_rcgr = 0x58000,
+       .hid_width = 5,
+       .freq_tbl = ftbl_vfe_clk_src,
+       .parent_map = gcc_vfe_map,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "vfe0_clk_src",
+               .parent_data = gcc_vfe_data,
+               .num_parents = ARRAY_SIZE(gcc_vfe_data),
+               .ops = &clk_rcg2_ops,
+       }
+};
+
+static struct clk_rcg2 vfe1_clk_src = {
+       .cmd_rcgr = 0x58054,
+       .hid_width = 5,
+       .freq_tbl = ftbl_vfe_clk_src,
+       .parent_map = gcc_vfe_map,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "vfe1_clk_src",
+               .parent_data = gcc_vfe_data,
+               .num_parents = ARRAY_SIZE(gcc_vfe_data),
+               .ops = &clk_rcg2_ops,
+       }
+};
+
+static const struct parent_map gcc_vsync_map[] = {
+       { P_XO, 0 },
+       { P_GPLL0, 2 },
+};
+
+static const struct freq_tbl ftbl_vsync_clk_src[] = {
+       F(19200000, P_XO, 1, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 vsync_clk_src = {
+       .cmd_rcgr = 0x4d02c,
+       .hid_width = 5,
+       .freq_tbl = ftbl_vsync_clk_src,
+       .parent_map = gcc_vsync_map,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "vsync_clk_src",
+               .parent_data = gcc_esc_vsync_data,
+               .num_parents = ARRAY_SIZE(gcc_esc_vsync_data),
+               .ops = &clk_rcg2_ops,
+       }
+};
+
+static struct clk_branch gcc_apc0_droop_detector_gpll0_clk = {
+       .halt_reg = 0x78004,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x78004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_apc0_droop_detector_gpll0_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &apc0_droop_detector_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_apc1_droop_detector_gpll0_clk = {
+       .halt_reg = 0x79004,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x79004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_apc1_droop_detector_gpll0_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &apc1_droop_detector_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_apss_ahb_clk = {
+       .halt_reg = 0x4601c,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x45004,
+               .enable_mask = BIT(14),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_apss_ahb_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &apss_ahb_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_apss_axi_clk = {
+       .halt_reg = 0x46020,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x45004,
+               .enable_mask = BIT(13),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_apss_axi_clk",
+                       .ops = &clk_branch2_ops,
+               }
+       }
+};
+
+static struct clk_branch gcc_apss_tcu_async_clk = {
+       .halt_reg = 0x12018,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x4500c,
+               .enable_mask = BIT(1),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_apss_tcu_async_clk",
+                       .ops = &clk_branch2_ops,
+               }
+       }
+};
+
+static struct clk_branch gcc_bimc_gfx_clk = {
+       .halt_reg = 0x59034,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x59034,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_bimc_gfx_clk",
+                       .ops = &clk_branch2_ops,
+               }
+       }
+};
+
+static struct clk_branch gcc_bimc_gpu_clk = {
+       .halt_reg = 0x59030,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x59030,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_bimc_gpu_clk",
+                       .ops = &clk_branch2_ops,
+               }
+       }
+};
+
+static struct clk_branch gcc_blsp1_ahb_clk = {
+       .halt_reg = 0x01008,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x45004,
+               .enable_mask = BIT(10),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_blsp1_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               }
+       }
+};
+
+static struct clk_branch gcc_blsp2_ahb_clk = {
+       .halt_reg = 0x0b008,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x45004,
+               .enable_mask = BIT(20),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_blsp2_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               }
+       }
+};
+
+static struct clk_branch gcc_blsp1_qup1_i2c_apps_clk = {
+       .halt_reg = 0x02008,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x02008,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_blsp1_qup1_i2c_apps_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &blsp1_qup1_i2c_apps_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_blsp1_qup2_i2c_apps_clk = {
+       .halt_reg = 0x03010,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x03010,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_blsp1_qup2_i2c_apps_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &blsp1_qup2_i2c_apps_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_blsp1_qup3_i2c_apps_clk = {
+       .halt_reg = 0x04020,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x04020,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_blsp1_qup3_i2c_apps_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &blsp1_qup3_i2c_apps_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_blsp1_qup4_i2c_apps_clk = {
+       .halt_reg = 0x05020,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x05020,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_blsp1_qup4_i2c_apps_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &blsp1_qup4_i2c_apps_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_blsp2_qup1_i2c_apps_clk = {
+       .halt_reg = 0x0c008,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x0c008,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_blsp2_qup1_i2c_apps_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &blsp2_qup1_i2c_apps_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_blsp2_qup2_i2c_apps_clk = {
+       .halt_reg = 0x0d010,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x0d010,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_blsp2_qup2_i2c_apps_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &blsp2_qup2_i2c_apps_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_blsp2_qup3_i2c_apps_clk = {
+       .halt_reg = 0x0f020,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x0f020,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_blsp2_qup3_i2c_apps_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &blsp2_qup3_i2c_apps_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_blsp2_qup4_i2c_apps_clk = {
+       .halt_reg = 0x18020,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x18020,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_blsp2_qup4_i2c_apps_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &blsp2_qup4_i2c_apps_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_blsp1_qup1_spi_apps_clk = {
+       .halt_reg = 0x02004,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x02004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_blsp1_qup1_spi_apps_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &blsp1_qup1_spi_apps_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_blsp1_qup2_spi_apps_clk = {
+       .halt_reg = 0x0300c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x0300c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_blsp1_qup2_spi_apps_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &blsp1_qup2_spi_apps_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_blsp1_qup3_spi_apps_clk = {
+       .halt_reg = 0x0401c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x0401c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_blsp1_qup3_spi_apps_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &blsp1_qup3_spi_apps_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_blsp1_qup4_spi_apps_clk = {
+       .halt_reg = 0x0501c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x0501c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_blsp1_qup4_spi_apps_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &blsp1_qup4_spi_apps_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_blsp2_qup1_spi_apps_clk = {
+       .halt_reg = 0x0c004,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x0c004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_blsp2_qup1_spi_apps_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &blsp2_qup1_spi_apps_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_blsp2_qup2_spi_apps_clk = {
+       .halt_reg = 0x0d00c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x0d00c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_blsp2_qup2_spi_apps_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &blsp2_qup2_spi_apps_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_blsp2_qup3_spi_apps_clk = {
+       .halt_reg = 0x0f01c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x0f01c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_blsp2_qup3_spi_apps_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &blsp2_qup3_spi_apps_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_blsp2_qup4_spi_apps_clk = {
+       .halt_reg = 0x1801c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x1801c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_blsp2_qup4_spi_apps_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &blsp2_qup4_spi_apps_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_blsp1_uart1_apps_clk = {
+       .halt_reg = 0x0203c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x0203c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_blsp1_uart1_apps_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &blsp1_uart1_apps_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_blsp1_uart2_apps_clk = {
+       .halt_reg = 0x0302c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x0302c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_blsp1_uart2_apps_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &blsp1_uart2_apps_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_blsp2_uart1_apps_clk = {
+       .halt_reg = 0x0c03c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x0c03c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_blsp2_uart1_apps_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &blsp2_uart1_apps_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_blsp2_uart2_apps_clk = {
+       .halt_reg = 0x0d02c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x0d02c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_blsp2_uart2_apps_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &blsp2_uart2_apps_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_boot_rom_ahb_clk = {
+       .halt_reg = 0x1300c,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x45004,
+               .enable_mask = BIT(7),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_boot_rom_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               }
+       }
+};
+
+static struct clk_branch gcc_camss_ahb_clk = {
+       .halt_reg = 0x56004,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x56004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_camss_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               }
+       }
+};
+
+static struct clk_branch gcc_camss_cci_ahb_clk = {
+       .halt_reg = 0x5101c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x5101c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_camss_cci_ahb_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &camss_top_ahb_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_camss_cci_clk = {
+       .halt_reg = 0x51018,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x51018,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_camss_cci_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &cci_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_camss_cpp_ahb_clk = {
+       .halt_reg = 0x58040,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x58040,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_camss_cpp_ahb_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &camss_top_ahb_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_camss_cpp_axi_clk = {
+       .halt_reg = 0x58064,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x58064,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_camss_cpp_axi_clk",
+                       .ops = &clk_branch2_ops,
+               }
+       }
+};
+
+static struct clk_branch gcc_camss_cpp_clk = {
+       .halt_reg = 0x5803c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x5803c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_camss_cpp_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &cpp_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_camss_csi0_ahb_clk = {
+       .halt_reg = 0x4e040,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x4e040,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_camss_csi0_ahb_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &camss_top_ahb_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_camss_csi1_ahb_clk = {
+       .halt_reg = 0x4f040,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x4f040,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_camss_csi1_ahb_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &camss_top_ahb_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_camss_csi2_ahb_clk = {
+       .halt_reg = 0x3c040,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x3c040,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_camss_csi2_ahb_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &camss_top_ahb_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_camss_csi0_clk = {
+       .halt_reg = 0x4e03c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x4e03c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_camss_csi0_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &csi0_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_camss_csi1_clk = {
+       .halt_reg = 0x4f03c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x4f03c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_camss_csi1_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &csi1_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_camss_csi2_clk = {
+       .halt_reg = 0x3c03c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x3c03c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_camss_csi2_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &csi2_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_camss_csi0_csiphy_3p_clk = {
+       .halt_reg = 0x58090,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x58090,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_camss_csi0_csiphy_3p_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &csi0p_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_camss_csi1_csiphy_3p_clk = {
+       .halt_reg = 0x580a0,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x580a0,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_camss_csi1_csiphy_3p_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &csi1p_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_camss_csi2_csiphy_3p_clk = {
+       .halt_reg = 0x580b0,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x580b0,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_camss_csi2_csiphy_3p_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &csi2p_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_camss_csi0phy_clk = {
+       .halt_reg = 0x4e048,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x4e048,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_camss_csi0phy_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &csi0_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_camss_csi1phy_clk = {
+       .halt_reg = 0x4f048,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x4f048,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_camss_csi1phy_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &csi1_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_camss_csi2phy_clk = {
+       .halt_reg = 0x3c048,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x3c048,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_camss_csi2phy_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &csi2_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_camss_csi0phytimer_clk = {
+       .halt_reg = 0x4e01c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x4e01c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_camss_csi0phytimer_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &csi0phytimer_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_camss_csi1phytimer_clk = {
+       .halt_reg = 0x4f01c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x4f01c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_camss_csi1phytimer_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &csi1phytimer_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_camss_csi2phytimer_clk = {
+       .halt_reg = 0x4f068,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x4f068,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_camss_csi2phytimer_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &csi2phytimer_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_camss_csi0pix_clk = {
+       .halt_reg = 0x4e058,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x4e058,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_camss_csi0pix_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &csi0_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_camss_csi1pix_clk = {
+       .halt_reg = 0x4f058,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x4f058,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_camss_csi1pix_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &csi1_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_camss_csi2pix_clk = {
+       .halt_reg = 0x3c058,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x3c058,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_camss_csi2pix_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &csi2_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_camss_csi0rdi_clk = {
+       .halt_reg = 0x4e050,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x4e050,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_camss_csi0rdi_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &csi0_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_camss_csi1rdi_clk = {
+       .halt_reg = 0x4f050,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x4f050,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_camss_csi1rdi_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &csi1_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_camss_csi2rdi_clk = {
+       .halt_reg = 0x3c050,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x3c050,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_camss_csi2rdi_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &csi2_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_camss_csi_vfe0_clk = {
+       .halt_reg = 0x58050,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x58050,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_camss_csi_vfe0_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &vfe0_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_camss_csi_vfe1_clk = {
+       .halt_reg = 0x58074,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x58074,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_camss_csi_vfe1_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &vfe1_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_camss_gp0_clk = {
+       .halt_reg = 0x54018,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x54018,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_camss_gp0_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &camss_gp0_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_camss_gp1_clk = {
+       .halt_reg = 0x55018,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x55018,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_camss_gp1_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &camss_gp1_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_camss_ispif_ahb_clk = {
+       .halt_reg = 0x50004,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x50004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_camss_ispif_ahb_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &camss_top_ahb_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_camss_jpeg0_clk = {
+       .halt_reg = 0x57020,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x57020,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_camss_jpeg0_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &jpeg0_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_camss_jpeg_ahb_clk = {
+       .halt_reg = 0x57024,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x57024,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_camss_jpeg_ahb_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &camss_top_ahb_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_camss_jpeg_axi_clk = {
+       .halt_reg = 0x57028,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x57028,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_camss_jpeg_axi_clk",
+                       .ops = &clk_branch2_ops,
+               }
+       }
+};
+
+static struct clk_branch gcc_camss_mclk0_clk = {
+       .halt_reg = 0x52018,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x52018,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_camss_mclk0_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &mclk0_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_camss_mclk1_clk = {
+       .halt_reg = 0x53018,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x53018,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_camss_mclk1_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &mclk1_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_camss_mclk2_clk = {
+       .halt_reg = 0x5c018,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x5c018,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_camss_mclk2_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &mclk2_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_camss_mclk3_clk = {
+       .halt_reg = 0x5e018,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x5e018,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_camss_mclk3_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &mclk3_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_camss_micro_ahb_clk = {
+       .halt_reg = 0x5600c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x5600c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_camss_micro_ahb_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &camss_top_ahb_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_camss_top_ahb_clk = {
+       .halt_reg = 0x5a014,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x5a014,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_camss_top_ahb_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &camss_top_ahb_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_camss_vfe0_ahb_clk = {
+       .halt_reg = 0x58044,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x58044,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_camss_vfe0_ahb_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &camss_top_ahb_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_camss_vfe0_axi_clk = {
+       .halt_reg = 0x58048,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x58048,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_camss_vfe0_axi_clk",
+                       .ops = &clk_branch2_ops,
+               }
+       }
+};
+
+static struct clk_branch gcc_camss_vfe0_clk = {
+       .halt_reg = 0x58038,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x58038,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_camss_vfe0_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &vfe0_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_camss_vfe1_ahb_clk = {
+       .halt_reg = 0x58060,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x58060,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_camss_vfe1_ahb_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &camss_top_ahb_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_camss_vfe1_axi_clk = {
+       .halt_reg = 0x58068,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x58068,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_camss_vfe1_axi_clk",
+                       .ops = &clk_branch2_ops,
+               }
+       }
+};
+
+static struct clk_branch gcc_camss_vfe1_clk = {
+       .halt_reg = 0x5805c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x5805c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_camss_vfe1_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &vfe1_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_cpp_tbu_clk = {
+       .halt_reg = 0x12040,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x4500c,
+               .enable_mask = BIT(14),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_cpp_tbu_clk",
+                       .ops = &clk_branch2_ops,
+               }
+       }
+};
+
+static struct clk_branch gcc_crypto_ahb_clk = {
+       .halt_reg = 0x16024,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x45004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_crypto_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               }
+       }
+};
+
+static struct clk_branch gcc_crypto_axi_clk = {
+       .halt_reg = 0x16020,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x45004,
+               .enable_mask = BIT(1),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_crypto_axi_clk",
+                       .ops = &clk_branch2_ops,
+               }
+       }
+};
+
+static struct clk_branch gcc_crypto_clk = {
+       .halt_reg = 0x1601c,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x45004,
+               .enable_mask = BIT(2),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_crypto_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &crypto_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_dcc_clk = {
+       .halt_reg = 0x77004,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x77004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_dcc_clk",
+                       .ops = &clk_branch2_ops,
+               }
+       }
+};
+
+static struct clk_branch gcc_gp1_clk = {
+       .halt_reg = 0x08000,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x08000,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_gp1_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &gp1_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_gp2_clk = {
+       .halt_reg = 0x09000,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x09000,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_gp2_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &gp2_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_gp3_clk = {
+       .halt_reg = 0x0a000,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x0a000,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_gp3_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &gp3_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_jpeg_tbu_clk = {
+       .halt_reg = 0x12034,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x4500c,
+               .enable_mask = BIT(10),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_jpeg_tbu_clk",
+                       .ops = &clk_branch2_ops,
+               }
+       }
+};
+
+static struct clk_branch gcc_mdp_tbu_clk = {
+       .halt_reg = 0x1201c,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x4500c,
+               .enable_mask = BIT(4),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_mdp_tbu_clk",
+                       .ops = &clk_branch2_ops,
+               }
+       }
+};
+
+static struct clk_branch gcc_mdss_ahb_clk = {
+       .halt_reg = 0x4d07c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x4d07c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_mdss_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               }
+       }
+};
+
+static struct clk_branch gcc_mdss_axi_clk = {
+       .halt_reg = 0x4d080,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x4d080,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_mdss_axi_clk",
+                       .ops = &clk_branch2_ops,
+               }
+       }
+};
+
+static struct clk_branch gcc_mdss_byte0_clk = {
+       .halt_reg = 0x4d094,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x4d094,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_mdss_byte0_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &byte0_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_mdss_byte1_clk = {
+       .halt_reg = 0x4d0a0,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x4d0a0,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_mdss_byte1_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &byte1_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_mdss_esc0_clk = {
+       .halt_reg = 0x4d098,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x4d098,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_mdss_esc0_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &esc0_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_mdss_esc1_clk = {
+       .halt_reg = 0x4d09c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x4d09c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_mdss_esc1_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &esc1_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_mdss_mdp_clk = {
+       .halt_reg = 0x4d088,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x4d088,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_mdss_mdp_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &mdp_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_mdss_pclk0_clk = {
+       .halt_reg = 0x4d084,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x4d084,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_mdss_pclk0_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &pclk0_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_mdss_pclk1_clk = {
+       .halt_reg = 0x4d0a4,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x4d0a4,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_mdss_pclk1_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &pclk1_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_mdss_vsync_clk = {
+       .halt_reg = 0x4d090,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x4d090,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_mdss_vsync_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &vsync_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_mss_cfg_ahb_clk = {
+       .halt_reg = 0x49000,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x49000,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_mss_cfg_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               }
+       }
+};
+
+static struct clk_branch gcc_mss_q6_bimc_axi_clk = {
+       .halt_reg = 0x49004,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x49004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_mss_q6_bimc_axi_clk",
+                       .ops = &clk_branch2_ops,
+               }
+       }
+};
+
+static struct clk_branch gcc_oxili_ahb_clk = {
+       .halt_reg = 0x59028,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x59028,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_oxili_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               }
+       }
+};
+
+static struct clk_branch gcc_oxili_aon_clk = {
+       .halt_reg = 0x59044,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x59044,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_oxili_aon_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &gfx3d_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+               }
+       }
+};
+
+static struct clk_branch gcc_oxili_gfx3d_clk = {
+       .halt_reg = 0x59020,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x59020,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_oxili_gfx3d_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &gfx3d_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_oxili_timer_clk = {
+       .halt_reg = 0x59040,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x59040,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_oxili_timer_clk",
+                       .ops = &clk_branch2_ops,
+               }
+       }
+};
+
+static struct clk_branch gcc_pcnoc_usb3_axi_clk = {
+       .halt_reg = 0x3f038,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x3f038,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_pcnoc_usb3_axi_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &usb30_master_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_pdm2_clk = {
+       .halt_reg = 0x4400c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x4400c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_pdm2_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &pdm2_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_pdm_ahb_clk = {
+       .halt_reg = 0x44004,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x44004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_pdm_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               }
+       }
+};
+
+static struct clk_branch gcc_prng_ahb_clk = {
+       .halt_reg = 0x13004,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x45004,
+               .enable_mask = BIT(8),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_prng_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               }
+       }
+};
+
+static struct clk_branch gcc_qdss_dap_clk = {
+       .halt_reg = 0x29084,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x45004,
+               .enable_mask = BIT(11),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_qdss_dap_clk",
+                       .ops = &clk_branch2_ops,
+               }
+       }
+};
+
+static struct clk_branch gcc_qusb_ref_clk = {
+       .halt_reg = 0,
+       .halt_check = BRANCH_HALT_SKIP,
+       .clkr = {
+               .enable_reg = 0x41030,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_qusb_ref_clk",
+                       .ops = &clk_branch2_ops,
+               }
+       }
+};
+
+static struct clk_branch gcc_rbcpr_gfx_clk = {
+       .halt_reg = 0x3a004,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x3a004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_rbcpr_gfx_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &rbcpr_gfx_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_sdcc1_ice_core_clk = {
+       .halt_reg = 0x5d014,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x5d014,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_sdcc1_ice_core_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &sdcc1_ice_core_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_sdcc1_ahb_clk = {
+       .halt_reg = 0x4201c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x4201c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_sdcc1_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               }
+       }
+};
+
+static struct clk_branch gcc_sdcc2_ahb_clk = {
+       .halt_reg = 0x4301c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x4301c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_sdcc2_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               }
+       }
+};
+
+static struct clk_branch gcc_sdcc1_apps_clk = {
+       .halt_reg = 0x42018,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x42018,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_sdcc1_apps_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &sdcc1_apps_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_sdcc2_apps_clk = {
+       .halt_reg = 0x43018,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x43018,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_sdcc2_apps_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &sdcc2_apps_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_smmu_cfg_clk = {
+       .halt_reg = 0x12038,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x4500c,
+               .enable_mask = BIT(12),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_smmu_cfg_clk",
+                       .ops = &clk_branch2_ops,
+               }
+       }
+};
+
+static struct clk_branch gcc_usb30_master_clk = {
+       .halt_reg = 0x3f000,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x3f000,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_usb30_master_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &usb30_master_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_usb30_mock_utmi_clk = {
+       .halt_reg = 0x3f008,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x3f008,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_usb30_mock_utmi_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &usb30_mock_utmi_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_usb30_sleep_clk = {
+       .halt_reg = 0x3f004,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x3f004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_usb30_sleep_clk",
+                       .ops = &clk_branch2_ops,
+               }
+       }
+};
+
+static struct clk_branch gcc_usb3_aux_clk = {
+       .halt_reg = 0x3f044,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x3f044,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_usb3_aux_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &usb3_aux_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_usb3_pipe_clk = {
+       .halt_reg = 0,
+       .halt_check = BRANCH_HALT_DELAY,
+       .clkr = {
+               .enable_reg = 0x3f040,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_usb3_pipe_clk",
+                       .ops = &clk_branch2_ops,
+               }
+       }
+};
+
+static struct clk_branch gcc_usb_phy_cfg_ahb_clk = {
+       .halt_reg = 0x3f080,
+       .halt_check = BRANCH_VOTED,
+       .clkr = {
+               .enable_reg = 0x3f080,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_usb_phy_cfg_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               }
+       }
+};
+
+static struct clk_branch gcc_usb_ss_ref_clk = {
+       .halt_reg = 0,
+       .halt_check = BRANCH_HALT_SKIP,
+       .clkr = {
+               .enable_reg = 0x3f07c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_usb_ss_ref_clk",
+                       .ops = &clk_branch2_ops,
+               }
+       }
+};
+
+static struct clk_branch gcc_venus0_ahb_clk = {
+       .halt_reg = 0x4c020,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x4c020,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_venus0_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               }
+       }
+};
+
+static struct clk_branch gcc_venus0_axi_clk = {
+       .halt_reg = 0x4c024,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x4c024,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_venus0_axi_clk",
+                       .ops = &clk_branch2_ops,
+               }
+       }
+};
+
+static struct clk_branch gcc_venus0_core0_vcodec0_clk = {
+       .halt_reg = 0x4c02c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x4c02c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_venus0_core0_vcodec0_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &vcodec0_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_venus0_vcodec0_clk = {
+       .halt_reg = 0x4c01c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x4c01c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_venus0_vcodec0_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &vcodec0_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               }
+       }
+};
+
+static struct clk_branch gcc_venus_tbu_clk = {
+       .halt_reg = 0x12014,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x4500c,
+               .enable_mask = BIT(5),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_venus_tbu_clk",
+                       .ops = &clk_branch2_ops,
+               }
+       }
+};
+
+static struct clk_branch gcc_vfe1_tbu_clk = {
+       .halt_reg = 0x12090,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x4500c,
+               .enable_mask = BIT(17),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_vfe1_tbu_clk",
+                       .ops = &clk_branch2_ops,
+               }
+       }
+};
+
+static struct clk_branch gcc_vfe_tbu_clk = {
+       .halt_reg = 0x1203c,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x4500c,
+               .enable_mask = BIT(9),
+               .hw.init = &(struct clk_init_data) {
+                       .name = "gcc_vfe_tbu_clk",
+                       .ops = &clk_branch2_ops,
+               }
+       }
+};
+
+static struct gdsc usb30_gdsc = {
+       .gdscr = 0x3f078,
+       .pd = {
+               .name = "usb30_gdsc",
+       },
+       .pwrsts = PWRSTS_OFF_ON,
+       /*
+        * FIXME: dwc3 usb gadget cannot resume after GDSC power off
+        * dwc3 7000000.dwc3: failed to enable ep0out
+        */
+       .flags = ALWAYS_ON,
+};
+
+static struct gdsc venus_gdsc = {
+       .gdscr = 0x4c018,
+       .cxcs = (unsigned int []){ 0x4c024, 0x4c01c },
+       .cxc_count = 2,
+       .pd = {
+               .name = "venus_gdsc",
+       },
+       .pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct gdsc venus_core0_gdsc = {
+       .gdscr = 0x4c028,
+       .cxcs = (unsigned int []){ 0x4c02c },
+       .cxc_count = 1,
+       .pd = {
+               .name = "venus_core0",
+       },
+       .flags = HW_CTRL,
+       .pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct gdsc mdss_gdsc = {
+       .gdscr = 0x4d078,
+       .cxcs = (unsigned int []){ 0x4d080, 0x4d088 },
+       .cxc_count = 2,
+       .pd = {
+               .name = "mdss_gdsc",
+       },
+       .pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct gdsc jpeg_gdsc = {
+       .gdscr = 0x5701c,
+       .cxcs = (unsigned int []){ 0x57020, 0x57028 },
+       .cxc_count = 2,
+       .pd = {
+               .name = "jpeg_gdsc",
+       },
+       .pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct gdsc vfe0_gdsc = {
+       .gdscr = 0x58034,
+       .cxcs = (unsigned int []){ 0x58038, 0x58048, 0x5600c, 0x58050 },
+       .cxc_count = 4,
+       .pd = {
+               .name = "vfe0_gdsc",
+       },
+       .pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct gdsc vfe1_gdsc = {
+       .gdscr = 0x5806c,
+       .cxcs = (unsigned int []){ 0x5805c, 0x58068, 0x5600c, 0x58074 },
+       .cxc_count = 4,
+       .pd = {
+               .name = "vfe1_gdsc",
+       },
+       .pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct gdsc oxili_gx_gdsc = {
+       .gdscr = 0x5901c,
+       .clamp_io_ctrl = 0x5b00c,
+       .cxcs = (unsigned int []){ 0x59000, 0x59024 },
+       .cxc_count = 2,
+       .pd = {
+               .name = "oxili_gx_gdsc",
+       },
+       .pwrsts = PWRSTS_OFF_ON,
+       .flags = CLAMP_IO,
+};
+
+static struct gdsc oxili_cx_gdsc = {
+       .gdscr = 0x5904c,
+       .cxcs = (unsigned int []){ 0x59020 },
+       .cxc_count = 1,
+       .pd = {
+               .name = "oxili_cx_gdsc",
+       },
+       .pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct gdsc cpp_gdsc = {
+       .gdscr = 0x58078,
+       .cxcs = (unsigned int []){ 0x5803c, 0x58064 },
+       .cxc_count = 2,
+       .pd = {
+               .name = "cpp_gdsc",
+       },
+       .flags = ALWAYS_ON,
+       .pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct clk_hw *gcc_msm8953_hws[] = {
+       &gpll0_early_div.hw,
+       &gpll6_early_div.hw,
+};
+
+static struct clk_regmap *gcc_msm8953_clocks[] = {
+       [GPLL0] = &gpll0.clkr,
+       [GPLL0_EARLY] = &gpll0_early.clkr,
+       [GPLL2] = &gpll2.clkr,
+       [GPLL2_EARLY] = &gpll2_early.clkr,
+       [GPLL3] = &gpll3.clkr,
+       [GPLL3_EARLY] = &gpll3_early.clkr,
+       [GPLL4] = &gpll4.clkr,
+       [GPLL4_EARLY] = &gpll4_early.clkr,
+       [GPLL6] = &gpll6.clkr,
+       [GPLL6_EARLY] = &gpll6_early.clkr,
+       [GCC_APSS_AHB_CLK] = &gcc_apss_ahb_clk.clkr,
+       [GCC_APSS_AXI_CLK] = &gcc_apss_axi_clk.clkr,
+       [GCC_BLSP1_AHB_CLK] = &gcc_blsp1_ahb_clk.clkr,
+       [GCC_BLSP2_AHB_CLK] = &gcc_blsp2_ahb_clk.clkr,
+       [GCC_BOOT_ROM_AHB_CLK] = &gcc_boot_rom_ahb_clk.clkr,
+       [GCC_CRYPTO_AHB_CLK] = &gcc_crypto_ahb_clk.clkr,
+       [GCC_CRYPTO_AXI_CLK] = &gcc_crypto_axi_clk.clkr,
+       [GCC_CRYPTO_CLK] = &gcc_crypto_clk.clkr,
+       [GCC_PRNG_AHB_CLK] = &gcc_prng_ahb_clk.clkr,
+       [GCC_QDSS_DAP_CLK] = &gcc_qdss_dap_clk.clkr,
+       [GCC_APSS_TCU_ASYNC_CLK] = &gcc_apss_tcu_async_clk.clkr,
+       [GCC_CPP_TBU_CLK] = &gcc_cpp_tbu_clk.clkr,
+       [GCC_JPEG_TBU_CLK] = &gcc_jpeg_tbu_clk.clkr,
+       [GCC_MDP_TBU_CLK] = &gcc_mdp_tbu_clk.clkr,
+       [GCC_SMMU_CFG_CLK] = &gcc_smmu_cfg_clk.clkr,
+       [GCC_VENUS_TBU_CLK] = &gcc_venus_tbu_clk.clkr,
+       [GCC_VFE1_TBU_CLK] = &gcc_vfe1_tbu_clk.clkr,
+       [GCC_VFE_TBU_CLK] = &gcc_vfe_tbu_clk.clkr,
+       [CAMSS_TOP_AHB_CLK_SRC] = &camss_top_ahb_clk_src.clkr,
+       [CSI0_CLK_SRC] = &csi0_clk_src.clkr,
+       [APSS_AHB_CLK_SRC] = &apss_ahb_clk_src.clkr,
+       [CSI1_CLK_SRC] = &csi1_clk_src.clkr,
+       [CSI2_CLK_SRC] = &csi2_clk_src.clkr,
+       [VFE0_CLK_SRC] = &vfe0_clk_src.clkr,
+       [VCODEC0_CLK_SRC] = &vcodec0_clk_src.clkr,
+       [CPP_CLK_SRC] = &cpp_clk_src.clkr,
+       [JPEG0_CLK_SRC] = &jpeg0_clk_src.clkr,
+       [USB30_MASTER_CLK_SRC] = &usb30_master_clk_src.clkr,
+       [VFE1_CLK_SRC] = &vfe1_clk_src.clkr,
+       [APC0_DROOP_DETECTOR_CLK_SRC] = &apc0_droop_detector_clk_src.clkr,
+       [APC1_DROOP_DETECTOR_CLK_SRC] = &apc1_droop_detector_clk_src.clkr,
+       [BLSP1_QUP1_I2C_APPS_CLK_SRC] = &blsp1_qup1_i2c_apps_clk_src.clkr,
+       [BLSP1_QUP1_SPI_APPS_CLK_SRC] = &blsp1_qup1_spi_apps_clk_src.clkr,
+       [BLSP1_QUP2_I2C_APPS_CLK_SRC] = &blsp1_qup2_i2c_apps_clk_src.clkr,
+       [BLSP1_QUP2_SPI_APPS_CLK_SRC] = &blsp1_qup2_spi_apps_clk_src.clkr,
+       [BLSP1_QUP3_I2C_APPS_CLK_SRC] = &blsp1_qup3_i2c_apps_clk_src.clkr,
+       [BLSP1_QUP3_SPI_APPS_CLK_SRC] = &blsp1_qup3_spi_apps_clk_src.clkr,
+       [BLSP1_QUP4_I2C_APPS_CLK_SRC] = &blsp1_qup4_i2c_apps_clk_src.clkr,
+       [BLSP1_QUP4_SPI_APPS_CLK_SRC] = &blsp1_qup4_spi_apps_clk_src.clkr,
+       [BLSP1_UART1_APPS_CLK_SRC] = &blsp1_uart1_apps_clk_src.clkr,
+       [BLSP1_UART2_APPS_CLK_SRC] = &blsp1_uart2_apps_clk_src.clkr,
+       [BLSP2_QUP1_I2C_APPS_CLK_SRC] = &blsp2_qup1_i2c_apps_clk_src.clkr,
+       [BLSP2_QUP1_SPI_APPS_CLK_SRC] = &blsp2_qup1_spi_apps_clk_src.clkr,
+       [BLSP2_QUP2_I2C_APPS_CLK_SRC] = &blsp2_qup2_i2c_apps_clk_src.clkr,
+       [BLSP2_QUP2_SPI_APPS_CLK_SRC] = &blsp2_qup2_spi_apps_clk_src.clkr,
+       [BLSP2_QUP3_I2C_APPS_CLK_SRC] = &blsp2_qup3_i2c_apps_clk_src.clkr,
+       [BLSP2_QUP3_SPI_APPS_CLK_SRC] = &blsp2_qup3_spi_apps_clk_src.clkr,
+       [BLSP2_QUP4_I2C_APPS_CLK_SRC] = &blsp2_qup4_i2c_apps_clk_src.clkr,
+       [BLSP2_QUP4_SPI_APPS_CLK_SRC] = &blsp2_qup4_spi_apps_clk_src.clkr,
+       [BLSP2_UART1_APPS_CLK_SRC] = &blsp2_uart1_apps_clk_src.clkr,
+       [BLSP2_UART2_APPS_CLK_SRC] = &blsp2_uart2_apps_clk_src.clkr,
+       [CCI_CLK_SRC] = &cci_clk_src.clkr,
+       [CSI0P_CLK_SRC] = &csi0p_clk_src.clkr,
+       [CSI1P_CLK_SRC] = &csi1p_clk_src.clkr,
+       [CSI2P_CLK_SRC] = &csi2p_clk_src.clkr,
+       [CAMSS_GP0_CLK_SRC] = &camss_gp0_clk_src.clkr,
+       [CAMSS_GP1_CLK_SRC] = &camss_gp1_clk_src.clkr,
+       [MCLK0_CLK_SRC] = &mclk0_clk_src.clkr,
+       [MCLK1_CLK_SRC] = &mclk1_clk_src.clkr,
+       [MCLK2_CLK_SRC] = &mclk2_clk_src.clkr,
+       [MCLK3_CLK_SRC] = &mclk3_clk_src.clkr,
+       [CSI0PHYTIMER_CLK_SRC] = &csi0phytimer_clk_src.clkr,
+       [CSI1PHYTIMER_CLK_SRC] = &csi1phytimer_clk_src.clkr,
+       [CSI2PHYTIMER_CLK_SRC] = &csi2phytimer_clk_src.clkr,
+       [CRYPTO_CLK_SRC] = &crypto_clk_src.clkr,
+       [GP1_CLK_SRC] = &gp1_clk_src.clkr,
+       [GP2_CLK_SRC] = &gp2_clk_src.clkr,
+       [GP3_CLK_SRC] = &gp3_clk_src.clkr,
+       [PDM2_CLK_SRC] = &pdm2_clk_src.clkr,
+       [RBCPR_GFX_CLK_SRC] = &rbcpr_gfx_clk_src.clkr,
+       [SDCC1_APPS_CLK_SRC] = &sdcc1_apps_clk_src.clkr,
+       [SDCC1_ICE_CORE_CLK_SRC] = &sdcc1_ice_core_clk_src.clkr,
+       [SDCC2_APPS_CLK_SRC] = &sdcc2_apps_clk_src.clkr,
+       [USB30_MOCK_UTMI_CLK_SRC] = &usb30_mock_utmi_clk_src.clkr,
+       [USB3_AUX_CLK_SRC] = &usb3_aux_clk_src.clkr,
+       [GCC_APC0_DROOP_DETECTOR_GPLL0_CLK] = &gcc_apc0_droop_detector_gpll0_clk.clkr,
+       [GCC_APC1_DROOP_DETECTOR_GPLL0_CLK] = &gcc_apc1_droop_detector_gpll0_clk.clkr,
+       [GCC_BLSP1_QUP1_I2C_APPS_CLK] = &gcc_blsp1_qup1_i2c_apps_clk.clkr,
+       [GCC_BLSP1_QUP1_SPI_APPS_CLK] = &gcc_blsp1_qup1_spi_apps_clk.clkr,
+       [GCC_BLSP1_QUP2_I2C_APPS_CLK] = &gcc_blsp1_qup2_i2c_apps_clk.clkr,
+       [GCC_BLSP1_QUP2_SPI_APPS_CLK] = &gcc_blsp1_qup2_spi_apps_clk.clkr,
+       [GCC_BLSP1_QUP3_I2C_APPS_CLK] = &gcc_blsp1_qup3_i2c_apps_clk.clkr,
+       [GCC_BLSP1_QUP3_SPI_APPS_CLK] = &gcc_blsp1_qup3_spi_apps_clk.clkr,
+       [GCC_BLSP1_QUP4_I2C_APPS_CLK] = &gcc_blsp1_qup4_i2c_apps_clk.clkr,
+       [GCC_BLSP1_QUP4_SPI_APPS_CLK] = &gcc_blsp1_qup4_spi_apps_clk.clkr,
+       [GCC_BLSP1_UART1_APPS_CLK] = &gcc_blsp1_uart1_apps_clk.clkr,
+       [GCC_BLSP1_UART2_APPS_CLK] = &gcc_blsp1_uart2_apps_clk.clkr,
+       [GCC_BLSP2_QUP1_I2C_APPS_CLK] = &gcc_blsp2_qup1_i2c_apps_clk.clkr,
+       [GCC_BLSP2_QUP1_SPI_APPS_CLK] = &gcc_blsp2_qup1_spi_apps_clk.clkr,
+       [GCC_BLSP2_QUP2_I2C_APPS_CLK] = &gcc_blsp2_qup2_i2c_apps_clk.clkr,
+       [GCC_BLSP2_QUP2_SPI_APPS_CLK] = &gcc_blsp2_qup2_spi_apps_clk.clkr,
+       [GCC_BLSP2_QUP3_I2C_APPS_CLK] = &gcc_blsp2_qup3_i2c_apps_clk.clkr,
+       [GCC_BLSP2_QUP3_SPI_APPS_CLK] = &gcc_blsp2_qup3_spi_apps_clk.clkr,
+       [GCC_BLSP2_QUP4_I2C_APPS_CLK] = &gcc_blsp2_qup4_i2c_apps_clk.clkr,
+       [GCC_BLSP2_QUP4_SPI_APPS_CLK] = &gcc_blsp2_qup4_spi_apps_clk.clkr,
+       [GCC_BLSP2_UART1_APPS_CLK] = &gcc_blsp2_uart1_apps_clk.clkr,
+       [GCC_BLSP2_UART2_APPS_CLK] = &gcc_blsp2_uart2_apps_clk.clkr,
+       [GCC_CAMSS_CCI_AHB_CLK] = &gcc_camss_cci_ahb_clk.clkr,
+       [GCC_CAMSS_CCI_CLK] = &gcc_camss_cci_clk.clkr,
+       [GCC_CAMSS_CPP_AHB_CLK] = &gcc_camss_cpp_ahb_clk.clkr,
+       [GCC_CAMSS_CPP_AXI_CLK] = &gcc_camss_cpp_axi_clk.clkr,
+       [GCC_CAMSS_CPP_CLK] = &gcc_camss_cpp_clk.clkr,
+       [GCC_CAMSS_CSI0_AHB_CLK] = &gcc_camss_csi0_ahb_clk.clkr,
+       [GCC_CAMSS_CSI0_CLK] = &gcc_camss_csi0_clk.clkr,
+       [GCC_CAMSS_CSI0_CSIPHY_3P_CLK] = &gcc_camss_csi0_csiphy_3p_clk.clkr,
+       [GCC_CAMSS_CSI0PHY_CLK] = &gcc_camss_csi0phy_clk.clkr,
+       [GCC_CAMSS_CSI0PIX_CLK] = &gcc_camss_csi0pix_clk.clkr,
+       [GCC_CAMSS_CSI0RDI_CLK] = &gcc_camss_csi0rdi_clk.clkr,
+       [GCC_CAMSS_CSI1_AHB_CLK] = &gcc_camss_csi1_ahb_clk.clkr,
+       [GCC_CAMSS_CSI1_CLK] = &gcc_camss_csi1_clk.clkr,
+       [GCC_CAMSS_CSI1_CSIPHY_3P_CLK] = &gcc_camss_csi1_csiphy_3p_clk.clkr,
+       [GCC_CAMSS_CSI1PHY_CLK] = &gcc_camss_csi1phy_clk.clkr,
+       [GCC_CAMSS_CSI1PIX_CLK] = &gcc_camss_csi1pix_clk.clkr,
+       [GCC_CAMSS_CSI1RDI_CLK] = &gcc_camss_csi1rdi_clk.clkr,
+       [GCC_CAMSS_CSI2_AHB_CLK] = &gcc_camss_csi2_ahb_clk.clkr,
+       [GCC_CAMSS_CSI2_CLK] = &gcc_camss_csi2_clk.clkr,
+       [GCC_CAMSS_CSI2_CSIPHY_3P_CLK] = &gcc_camss_csi2_csiphy_3p_clk.clkr,
+       [GCC_CAMSS_CSI2PHY_CLK] = &gcc_camss_csi2phy_clk.clkr,
+       [GCC_CAMSS_CSI2PIX_CLK] = &gcc_camss_csi2pix_clk.clkr,
+       [GCC_CAMSS_CSI2RDI_CLK] = &gcc_camss_csi2rdi_clk.clkr,
+       [GCC_CAMSS_CSI_VFE0_CLK] = &gcc_camss_csi_vfe0_clk.clkr,
+       [GCC_CAMSS_CSI_VFE1_CLK] = &gcc_camss_csi_vfe1_clk.clkr,
+       [GCC_CAMSS_GP0_CLK] = &gcc_camss_gp0_clk.clkr,
+       [GCC_CAMSS_GP1_CLK] = &gcc_camss_gp1_clk.clkr,
+       [GCC_CAMSS_ISPIF_AHB_CLK] = &gcc_camss_ispif_ahb_clk.clkr,
+       [GCC_CAMSS_JPEG0_CLK] = &gcc_camss_jpeg0_clk.clkr,
+       [GCC_CAMSS_JPEG_AHB_CLK] = &gcc_camss_jpeg_ahb_clk.clkr,
+       [GCC_CAMSS_JPEG_AXI_CLK] = &gcc_camss_jpeg_axi_clk.clkr,
+       [GCC_CAMSS_MCLK0_CLK] = &gcc_camss_mclk0_clk.clkr,
+       [GCC_CAMSS_MCLK1_CLK] = &gcc_camss_mclk1_clk.clkr,
+       [GCC_CAMSS_MCLK2_CLK] = &gcc_camss_mclk2_clk.clkr,
+       [GCC_CAMSS_MCLK3_CLK] = &gcc_camss_mclk3_clk.clkr,
+       [GCC_CAMSS_MICRO_AHB_CLK] = &gcc_camss_micro_ahb_clk.clkr,
+       [GCC_CAMSS_CSI0PHYTIMER_CLK] = &gcc_camss_csi0phytimer_clk.clkr,
+       [GCC_CAMSS_CSI1PHYTIMER_CLK] = &gcc_camss_csi1phytimer_clk.clkr,
+       [GCC_CAMSS_CSI2PHYTIMER_CLK] = &gcc_camss_csi2phytimer_clk.clkr,
+       [GCC_CAMSS_AHB_CLK] = &gcc_camss_ahb_clk.clkr,
+       [GCC_CAMSS_TOP_AHB_CLK] = &gcc_camss_top_ahb_clk.clkr,
+       [GCC_CAMSS_VFE0_CLK] = &gcc_camss_vfe0_clk.clkr,
+       [GCC_CAMSS_VFE0_AHB_CLK] = &gcc_camss_vfe0_ahb_clk.clkr,
+       [GCC_CAMSS_VFE0_AXI_CLK] = &gcc_camss_vfe0_axi_clk.clkr,
+       [GCC_CAMSS_VFE1_AHB_CLK] = &gcc_camss_vfe1_ahb_clk.clkr,
+       [GCC_CAMSS_VFE1_AXI_CLK] = &gcc_camss_vfe1_axi_clk.clkr,
+       [GCC_CAMSS_VFE1_CLK] = &gcc_camss_vfe1_clk.clkr,
+       [GCC_DCC_CLK] = &gcc_dcc_clk.clkr,
+       [GCC_GP1_CLK] = &gcc_gp1_clk.clkr,
+       [GCC_GP2_CLK] = &gcc_gp2_clk.clkr,
+       [GCC_GP3_CLK] = &gcc_gp3_clk.clkr,
+       [GCC_MSS_CFG_AHB_CLK] = &gcc_mss_cfg_ahb_clk.clkr,
+       [GCC_MSS_Q6_BIMC_AXI_CLK] = &gcc_mss_q6_bimc_axi_clk.clkr,
+       [GCC_PCNOC_USB3_AXI_CLK] = &gcc_pcnoc_usb3_axi_clk.clkr,
+       [GCC_PDM2_CLK] = &gcc_pdm2_clk.clkr,
+       [GCC_PDM_AHB_CLK] = &gcc_pdm_ahb_clk.clkr,
+       [GCC_RBCPR_GFX_CLK] = &gcc_rbcpr_gfx_clk.clkr,
+       [GCC_SDCC1_AHB_CLK] = &gcc_sdcc1_ahb_clk.clkr,
+       [GCC_SDCC1_APPS_CLK] = &gcc_sdcc1_apps_clk.clkr,
+       [GCC_SDCC1_ICE_CORE_CLK] = &gcc_sdcc1_ice_core_clk.clkr,
+       [GCC_SDCC2_AHB_CLK] = &gcc_sdcc2_ahb_clk.clkr,
+       [GCC_SDCC2_APPS_CLK] = &gcc_sdcc2_apps_clk.clkr,
+       [GCC_USB30_MASTER_CLK] = &gcc_usb30_master_clk.clkr,
+       [GCC_USB30_MOCK_UTMI_CLK] = &gcc_usb30_mock_utmi_clk.clkr,
+       [GCC_USB30_SLEEP_CLK] = &gcc_usb30_sleep_clk.clkr,
+       [GCC_USB3_AUX_CLK] = &gcc_usb3_aux_clk.clkr,
+       [GCC_USB_PHY_CFG_AHB_CLK] = &gcc_usb_phy_cfg_ahb_clk.clkr,
+       [GCC_VENUS0_AHB_CLK] = &gcc_venus0_ahb_clk.clkr,
+       [GCC_VENUS0_AXI_CLK] = &gcc_venus0_axi_clk.clkr,
+       [GCC_VENUS0_CORE0_VCODEC0_CLK] = &gcc_venus0_core0_vcodec0_clk.clkr,
+       [GCC_VENUS0_VCODEC0_CLK] = &gcc_venus0_vcodec0_clk.clkr,
+       [GCC_QUSB_REF_CLK] = &gcc_qusb_ref_clk.clkr,
+       [GCC_USB_SS_REF_CLK] = &gcc_usb_ss_ref_clk.clkr,
+       [GCC_USB3_PIPE_CLK] = &gcc_usb3_pipe_clk.clkr,
+       [MDP_CLK_SRC] = &mdp_clk_src.clkr,
+       [PCLK0_CLK_SRC] = &pclk0_clk_src.clkr,
+       [BYTE0_CLK_SRC] = &byte0_clk_src.clkr,
+       [ESC0_CLK_SRC] = &esc0_clk_src.clkr,
+       [PCLK1_CLK_SRC] = &pclk1_clk_src.clkr,
+       [BYTE1_CLK_SRC] = &byte1_clk_src.clkr,
+       [ESC1_CLK_SRC] = &esc1_clk_src.clkr,
+       [VSYNC_CLK_SRC] = &vsync_clk_src.clkr,
+       [GCC_MDSS_AHB_CLK] = &gcc_mdss_ahb_clk.clkr,
+       [GCC_MDSS_AXI_CLK] = &gcc_mdss_axi_clk.clkr,
+       [GCC_MDSS_PCLK0_CLK] = &gcc_mdss_pclk0_clk.clkr,
+       [GCC_MDSS_BYTE0_CLK] = &gcc_mdss_byte0_clk.clkr,
+       [GCC_MDSS_ESC0_CLK] = &gcc_mdss_esc0_clk.clkr,
+       [GCC_MDSS_PCLK1_CLK] = &gcc_mdss_pclk1_clk.clkr,
+       [GCC_MDSS_BYTE1_CLK] = &gcc_mdss_byte1_clk.clkr,
+       [GCC_MDSS_ESC1_CLK] = &gcc_mdss_esc1_clk.clkr,
+       [GCC_MDSS_MDP_CLK] = &gcc_mdss_mdp_clk.clkr,
+       [GCC_MDSS_VSYNC_CLK] = &gcc_mdss_vsync_clk.clkr,
+       [GCC_OXILI_TIMER_CLK] = &gcc_oxili_timer_clk.clkr,
+       [GCC_OXILI_GFX3D_CLK] = &gcc_oxili_gfx3d_clk.clkr,
+       [GCC_OXILI_AON_CLK] = &gcc_oxili_aon_clk.clkr,
+       [GCC_OXILI_AHB_CLK] = &gcc_oxili_ahb_clk.clkr,
+       [GCC_BIMC_GFX_CLK] = &gcc_bimc_gfx_clk.clkr,
+       [GCC_BIMC_GPU_CLK] = &gcc_bimc_gpu_clk.clkr,
+       [GFX3D_CLK_SRC] = &gfx3d_clk_src.clkr,
+};
+
+static const struct qcom_reset_map gcc_msm8953_resets[] = {
+       [GCC_CAMSS_MICRO_BCR]   = { 0x56008 },
+       [GCC_MSS_BCR]           = { 0x71000 },
+       [GCC_QUSB2_PHY_BCR]     = { 0x4103c },
+       [GCC_USB3PHY_PHY_BCR]   = { 0x3f03c },
+       [GCC_USB3_PHY_BCR]      = { 0x3f034 },
+       [GCC_USB_30_BCR]        = { 0x3f070 },
+};
+
+static const struct regmap_config gcc_msm8953_regmap_config = {
+       .reg_bits       = 32,
+       .reg_stride     = 4,
+       .val_bits       = 32,
+       .max_register   = 0x80000,
+       .fast_io        = true,
+};
+
+static struct gdsc *gcc_msm8953_gdscs[] = {
+       [CPP_GDSC] = &cpp_gdsc,
+       [JPEG_GDSC] = &jpeg_gdsc,
+       [MDSS_GDSC] = &mdss_gdsc,
+       [OXILI_CX_GDSC] = &oxili_cx_gdsc,
+       [OXILI_GX_GDSC] = &oxili_gx_gdsc,
+       [USB30_GDSC] = &usb30_gdsc,
+       [VENUS_CORE0_GDSC] = &venus_core0_gdsc,
+       [VENUS_GDSC] = &venus_gdsc,
+       [VFE0_GDSC] = &vfe0_gdsc,
+       [VFE1_GDSC] = &vfe1_gdsc,
+};
+
+static const struct qcom_cc_desc gcc_msm8953_desc = {
+       .config = &gcc_msm8953_regmap_config,
+       .clks = gcc_msm8953_clocks,
+       .num_clks = ARRAY_SIZE(gcc_msm8953_clocks),
+       .resets = gcc_msm8953_resets,
+       .num_resets = ARRAY_SIZE(gcc_msm8953_resets),
+       .gdscs = gcc_msm8953_gdscs,
+       .num_gdscs = ARRAY_SIZE(gcc_msm8953_gdscs),
+       .clk_hws = gcc_msm8953_hws,
+       .num_clk_hws = ARRAY_SIZE(gcc_msm8953_hws),
+};
+
+static int gcc_msm8953_probe(struct platform_device *pdev)
+{
+       struct regmap *regmap;
+
+       regmap  = qcom_cc_map(pdev, &gcc_msm8953_desc);
+       if (IS_ERR(regmap))
+               return PTR_ERR(regmap);
+
+       clk_alpha_pll_configure(&gpll3_early, regmap, &gpll3_early_config);
+
+       return qcom_cc_really_probe(pdev, &gcc_msm8953_desc, regmap);
+}
+
+static const struct of_device_id gcc_msm8953_match_table[] = {
+       { .compatible = "qcom,gcc-msm8953" },
+       {},
+};
+
+static struct platform_driver gcc_msm8953_driver = {
+       .probe = gcc_msm8953_probe,
+       .driver = {
+               .name = "gcc-msm8953",
+               .of_match_table = gcc_msm8953_match_table,
+               .owner = THIS_MODULE,
+       },
+};
+
+static int __init gcc_msm8953_init(void)
+{
+       return platform_driver_register(&gcc_msm8953_driver);
+}
+core_initcall(gcc_msm8953_init);
+
+static void __exit gcc_msm8953_exit(void)
+{
+       platform_driver_unregister(&gcc_msm8953_driver);
+}
+module_exit(gcc_msm8953_exit);
+
+MODULE_DESCRIPTION("Qualcomm GCC MSM8953 Driver");
+MODULE_LICENSE("GPL v2");
index 6394257..4d36f96 100644 (file)
@@ -37,114 +37,14 @@ enum {
        P_GPLL1_EARLY_DIV,
 };
 
-static const struct parent_map gcc_parent_map_xo_gpll0_gpll0_early_div[] = {
-       { P_XO, 0 },
-       { P_GPLL0, 1 },
-       { P_GPLL0_EARLY_DIV, 6 },
-};
-
-static const char * const gcc_parent_names_xo_gpll0_gpll0_early_div[] = {
-       "xo",
-       "gpll0",
-       "gpll0_early_div",
-};
-
-static const struct parent_map gcc_parent_map_xo_gpll0[] = {
-       { P_XO, 0 },
-       { P_GPLL0, 1 },
-};
-
-static const char * const gcc_parent_names_xo_gpll0[] = {
-       "xo",
-       "gpll0",
-};
-
-static const struct parent_map gcc_parent_map_xo_gpll0_sleep_clk_gpll0_early_div[] = {
-       { P_XO, 0 },
-       { P_GPLL0, 1 },
-       { P_SLEEP_CLK, 5 },
-       { P_GPLL0_EARLY_DIV, 6 },
-};
-
-static const char * const gcc_parent_names_xo_gpll0_sleep_clk_gpll0_early_div[] = {
-       "xo",
-       "gpll0",
-       "sleep_clk",
-       "gpll0_early_div",
-};
-
-static const struct parent_map gcc_parent_map_xo_sleep_clk[] = {
-       { P_XO, 0 },
-       { P_SLEEP_CLK, 5 },
-};
-
-static const char * const gcc_parent_names_xo_sleep_clk[] = {
-       "xo",
-       "sleep_clk",
-};
-
-static const struct parent_map gcc_parent_map_xo_gpll4[] = {
-       { P_XO, 0 },
-       { P_GPLL4, 5 },
-};
-
-static const char * const gcc_parent_names_xo_gpll4[] = {
-       "xo",
-       "gpll4",
-};
-
-static const struct parent_map gcc_parent_map_xo_gpll0_gpll0_early_div_gpll1_gpll4_gpll1_early_div[] = {
-       { P_XO, 0 },
-       { P_GPLL0, 1 },
-       { P_GPLL0_EARLY_DIV, 3 },
-       { P_GPLL1, 4 },
-       { P_GPLL4, 5 },
-       { P_GPLL1_EARLY_DIV, 6 },
-};
-
-static const char * const gcc_parent_names_xo_gpll0_gpll0_early_div_gpll1_gpll4_gpll1_early_div[] = {
-       "xo",
-       "gpll0",
-       "gpll0_early_div",
-       "gpll1",
-       "gpll4",
-       "gpll1_early_div",
-};
-
-static const struct parent_map gcc_parent_map_xo_gpll0_gpll4_gpll0_early_div[] = {
-       { P_XO, 0 },
-       { P_GPLL0, 1 },
-       { P_GPLL4, 5 },
-       { P_GPLL0_EARLY_DIV, 6 },
-};
-
-static const char * const gcc_parent_names_xo_gpll0_gpll4_gpll0_early_div[] = {
-       "xo",
-       "gpll0",
-       "gpll4",
-       "gpll0_early_div",
-};
-
-static const struct parent_map gcc_parent_map_xo_gpll0_gpll0_early_div_gpll4[] = {
-       { P_XO, 0 },
-       { P_GPLL0, 1 },
-       { P_GPLL0_EARLY_DIV, 2 },
-       { P_GPLL4, 5 },
-};
-
-static const char * const gcc_parent_names_xo_gpll0_gpll0_early_div_gpll4[] = {
-       "xo",
-       "gpll0",
-       "gpll0_early_div",
-       "gpll4",
-};
-
 static struct clk_fixed_factor xo = {
        .mult = 1,
        .div = 1,
        .hw.init = &(struct clk_init_data){
                .name = "xo",
-               .parent_names = (const char *[]){ "xo_board" },
+               .parent_data = &(const struct clk_parent_data) {
+                       .fw_name = "xo"
+               },
                .num_parents = 1,
                .ops = &clk_fixed_factor_ops,
        },
@@ -158,7 +58,9 @@ static struct clk_alpha_pll gpll0_early = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gpll0_early",
-                       .parent_names = (const char *[]){ "xo" },
+                       .parent_data = &(const struct clk_parent_data){
+                               .fw_name = "xo",
+                       },
                        .num_parents = 1,
                        .ops = &clk_alpha_pll_ops,
                },
@@ -170,7 +72,9 @@ static struct clk_fixed_factor gpll0_early_div = {
        .div = 2,
        .hw.init = &(struct clk_init_data){
                .name = "gpll0_early_div",
-               .parent_names = (const char *[]){ "gpll0_early" },
+               .parent_hws = (const struct clk_hw*[]){
+                       &gpll0_early.clkr.hw,
+               },
                .num_parents = 1,
                .ops = &clk_fixed_factor_ops,
        },
@@ -181,7 +85,9 @@ static struct clk_alpha_pll_postdiv gpll0 = {
        .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
        .clkr.hw.init = &(struct clk_init_data){
                .name = "gpll0",
-               .parent_names = (const char *[]){ "gpll0_early" },
+               .parent_hws = (const struct clk_hw*[]){
+                       &gpll0_early.clkr.hw,
+               },
                .num_parents = 1,
                .ops = &clk_alpha_pll_postdiv_ops,
        },
@@ -195,7 +101,9 @@ static struct clk_alpha_pll gpll1_early = {
                .enable_mask = BIT(1),
                .hw.init = &(struct clk_init_data){
                        .name = "gpll1_early",
-                       .parent_names = (const char *[]){ "xo" },
+                       .parent_data = &(const struct clk_parent_data){
+                               .fw_name = "xo",
+                       },
                        .num_parents = 1,
                        .ops = &clk_alpha_pll_ops,
                },
@@ -207,7 +115,9 @@ static struct clk_fixed_factor gpll1_early_div = {
        .div = 2,
        .hw.init = &(struct clk_init_data){
                .name = "gpll1_early_div",
-               .parent_names = (const char *[]){ "gpll1_early" },
+               .parent_hws = (const struct clk_hw*[]){
+                       &gpll1_early.clkr.hw,
+               },
                .num_parents = 1,
                .ops = &clk_fixed_factor_ops,
        },
@@ -218,7 +128,9 @@ static struct clk_alpha_pll_postdiv gpll1 = {
        .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
        .clkr.hw.init = &(struct clk_init_data){
                .name = "gpll1",
-               .parent_names = (const char *[]){ "gpll1_early" },
+               .parent_hws = (const struct clk_hw*[]){
+                       &gpll1_early.clkr.hw,
+               },
                .num_parents = 1,
                .ops = &clk_alpha_pll_postdiv_ops,
        },
@@ -232,7 +144,9 @@ static struct clk_alpha_pll gpll4_early = {
                .enable_mask = BIT(4),
                .hw.init = &(struct clk_init_data){
                        .name = "gpll4_early",
-                       .parent_names = (const char *[]){ "xo" },
+                       .parent_data = &(const struct clk_parent_data){
+                               .fw_name = "xo",
+                       },
                        .num_parents = 1,
                        .ops = &clk_alpha_pll_ops,
                },
@@ -245,12 +159,116 @@ static struct clk_alpha_pll_postdiv gpll4 = {
        .clkr.hw.init = &(struct clk_init_data)
        {
                .name = "gpll4",
-               .parent_names = (const char *[]) { "gpll4_early" },
+               .parent_hws = (const struct clk_hw*[]){
+                       &gpll4_early.clkr.hw,
+               },
                .num_parents = 1,
                .ops = &clk_alpha_pll_postdiv_ops,
        },
 };
 
+static const struct parent_map gcc_parent_map_xo_gpll0_gpll0_early_div[] = {
+       { P_XO, 0 },
+       { P_GPLL0, 1 },
+       { P_GPLL0_EARLY_DIV, 6 },
+};
+
+static const struct clk_parent_data gcc_parent_data_xo_gpll0_gpll0_early_div[] = {
+       { .fw_name = "xo" },
+       { .hw = &gpll0.clkr.hw },
+       { .hw = &gpll0_early_div.hw },
+};
+
+static const struct parent_map gcc_parent_map_xo_gpll0[] = {
+       { P_XO, 0 },
+       { P_GPLL0, 1 },
+};
+
+static const struct clk_parent_data gcc_parent_data_xo_gpll0[] = {
+       { .fw_name = "xo" },
+       { .hw = &gpll0.clkr.hw },
+};
+
+static const struct parent_map gcc_parent_map_xo_gpll0_sleep_clk_gpll0_early_div[] = {
+       { P_XO, 0 },
+       { P_GPLL0, 1 },
+       { P_SLEEP_CLK, 5 },
+       { P_GPLL0_EARLY_DIV, 6 },
+};
+
+static const struct clk_parent_data gcc_parent_data_xo_gpll0_sleep_clk_gpll0_early_div[] = {
+       { .fw_name = "xo" },
+       { .hw = &gpll0.clkr.hw },
+       { .fw_name = "sleep_clk" },
+       { .hw = &gpll0_early_div.hw },
+};
+
+static const struct parent_map gcc_parent_map_xo_sleep_clk[] = {
+       { P_XO, 0 },
+       { P_SLEEP_CLK, 5 },
+};
+
+static const struct clk_parent_data gcc_parent_data_xo_sleep_clk[] = {
+       { .fw_name = "xo" },
+       { .fw_name = "sleep_clk" },
+};
+
+static const struct parent_map gcc_parent_map_xo_gpll4[] = {
+       { P_XO, 0 },
+       { P_GPLL4, 5 },
+};
+
+static const struct clk_parent_data gcc_parent_data_xo_gpll4[] = {
+       { .fw_name = "xo" },
+       { .hw = &gpll4.clkr.hw },
+};
+
+static const struct parent_map gcc_parent_map_xo_gpll0_gpll0_early_div_gpll1_gpll4_gpll1_early_div[] = {
+       { P_XO, 0 },
+       { P_GPLL0, 1 },
+       { P_GPLL0_EARLY_DIV, 3 },
+       { P_GPLL1, 4 },
+       { P_GPLL4, 5 },
+       { P_GPLL1_EARLY_DIV, 6 },
+};
+
+static const struct clk_parent_data gcc_parent_data_xo_gpll0_gpll0_early_div_gpll1_gpll4_gpll1_early_div[] = {
+       { .fw_name = "xo" },
+       { .hw = &gpll0.clkr.hw },
+       { .hw = &gpll0_early_div.hw },
+       { .hw = &gpll1.clkr.hw },
+       { .hw = &gpll4.clkr.hw },
+       { .hw = &gpll1_early_div.hw },
+};
+
+static const struct parent_map gcc_parent_map_xo_gpll0_gpll4_gpll0_early_div[] = {
+       { P_XO, 0 },
+       { P_GPLL0, 1 },
+       { P_GPLL4, 5 },
+       { P_GPLL0_EARLY_DIV, 6 },
+};
+
+static const struct clk_parent_data gcc_parent_data_xo_gpll0_gpll4_gpll0_early_div[] = {
+       { .fw_name = "xo" },
+       { .hw = &gpll0.clkr.hw },
+       { .hw = &gpll4.clkr.hw },
+       { .hw = &gpll0_early_div.hw },
+};
+
+static const struct parent_map gcc_parent_map_xo_gpll0_gpll0_early_div_gpll4[] = {
+       { P_XO, 0 },
+       { P_GPLL0, 1 },
+       { P_GPLL0_EARLY_DIV, 2 },
+       { P_GPLL4, 5 },
+};
+
+static const struct clk_parent_data gcc_parent_data_xo_gpll0_gpll0_early_div_gpll4[] = {
+       { .fw_name = "xo" },
+       { .hw = &gpll0.clkr.hw },
+       { .hw = &gpll0_early_div.hw },
+       { .hw = &gpll4.clkr.hw },
+};
+
 static const struct freq_tbl ftbl_blsp1_qup1_i2c_apps_clk_src[] = {
        F(19200000, P_XO, 1, 0, 0),
        F(50000000, P_GPLL0, 12, 0, 0),
@@ -265,7 +283,7 @@ static struct clk_rcg2 blsp1_qup1_i2c_apps_clk_src = {
        .freq_tbl = ftbl_blsp1_qup1_i2c_apps_clk_src,
        .clkr.hw.init = &(struct clk_init_data){
                .name = "blsp1_qup1_i2c_apps_clk_src",
-               .parent_names = gcc_parent_names_xo_gpll0_gpll0_early_div,
+               .parent_data = gcc_parent_data_xo_gpll0_gpll0_early_div,
                .num_parents = 3,
                .ops = &clk_rcg2_ops,
        },
@@ -290,7 +308,7 @@ static struct clk_rcg2 blsp1_qup1_spi_apps_clk_src = {
        .freq_tbl = ftbl_blsp1_qup1_spi_apps_clk_src,
        .clkr.hw.init = &(struct clk_init_data){
                .name = "blsp1_qup1_spi_apps_clk_src",
-               .parent_names = gcc_parent_names_xo_gpll0_gpll0_early_div,
+               .parent_data = gcc_parent_data_xo_gpll0_gpll0_early_div,
                .num_parents = 3,
                .ops = &clk_rcg2_ops,
        },
@@ -304,7 +322,7 @@ static struct clk_rcg2 blsp1_qup2_i2c_apps_clk_src = {
        .freq_tbl = ftbl_blsp1_qup1_i2c_apps_clk_src,
        .clkr.hw.init = &(struct clk_init_data){
                .name = "blsp1_qup2_i2c_apps_clk_src",
-               .parent_names = gcc_parent_names_xo_gpll0_gpll0_early_div,
+               .parent_data = gcc_parent_data_xo_gpll0_gpll0_early_div,
                .num_parents = 3,
                .ops = &clk_rcg2_ops,
        },
@@ -318,7 +336,7 @@ static struct clk_rcg2 blsp1_qup2_spi_apps_clk_src = {
        .freq_tbl = ftbl_blsp1_qup1_spi_apps_clk_src,
        .clkr.hw.init = &(struct clk_init_data){
                .name = "blsp1_qup2_spi_apps_clk_src",
-               .parent_names = gcc_parent_names_xo_gpll0_gpll0_early_div,
+               .parent_data = gcc_parent_data_xo_gpll0_gpll0_early_div,
                .num_parents = 3,
                .ops = &clk_rcg2_ops,
        },
@@ -332,7 +350,7 @@ static struct clk_rcg2 blsp1_qup3_i2c_apps_clk_src = {
        .freq_tbl = ftbl_blsp1_qup1_i2c_apps_clk_src,
        .clkr.hw.init = &(struct clk_init_data){
                .name = "blsp1_qup3_i2c_apps_clk_src",
-               .parent_names = gcc_parent_names_xo_gpll0_gpll0_early_div,
+               .parent_data = gcc_parent_data_xo_gpll0_gpll0_early_div,
                .num_parents = 3,
                .ops = &clk_rcg2_ops,
        },
@@ -346,7 +364,7 @@ static struct clk_rcg2 blsp1_qup3_spi_apps_clk_src = {
        .freq_tbl = ftbl_blsp1_qup1_spi_apps_clk_src,
        .clkr.hw.init = &(struct clk_init_data){
                .name = "blsp1_qup3_spi_apps_clk_src",
-               .parent_names = gcc_parent_names_xo_gpll0_gpll0_early_div,
+               .parent_data = gcc_parent_data_xo_gpll0_gpll0_early_div,
                .num_parents = 3,
                .ops = &clk_rcg2_ops,
        },
@@ -360,7 +378,7 @@ static struct clk_rcg2 blsp1_qup4_i2c_apps_clk_src = {
        .freq_tbl = ftbl_blsp1_qup1_i2c_apps_clk_src,
        .clkr.hw.init = &(struct clk_init_data){
                .name = "blsp1_qup4_i2c_apps_clk_src",
-               .parent_names = gcc_parent_names_xo_gpll0_gpll0_early_div,
+               .parent_data = gcc_parent_data_xo_gpll0_gpll0_early_div,
                .num_parents = 3,
                .ops = &clk_rcg2_ops,
        },
@@ -374,7 +392,7 @@ static struct clk_rcg2 blsp1_qup4_spi_apps_clk_src = {
        .freq_tbl = ftbl_blsp1_qup1_spi_apps_clk_src,
        .clkr.hw.init = &(struct clk_init_data){
                .name = "blsp1_qup4_spi_apps_clk_src",
-               .parent_names = gcc_parent_names_xo_gpll0_gpll0_early_div,
+               .parent_data = gcc_parent_data_xo_gpll0_gpll0_early_div,
                .num_parents = 3,
                .ops = &clk_rcg2_ops,
        },
@@ -407,7 +425,7 @@ static struct clk_rcg2 blsp1_uart1_apps_clk_src = {
        .freq_tbl = ftbl_blsp1_uart1_apps_clk_src,
        .clkr.hw.init = &(struct clk_init_data){
                .name = "blsp1_uart1_apps_clk_src",
-               .parent_names = gcc_parent_names_xo_gpll0_gpll0_early_div,
+               .parent_data = gcc_parent_data_xo_gpll0_gpll0_early_div,
                .num_parents = 3,
                .ops = &clk_rcg2_ops,
        },
@@ -421,7 +439,7 @@ static struct clk_rcg2 blsp1_uart2_apps_clk_src = {
        .freq_tbl = ftbl_blsp1_uart1_apps_clk_src,
        .clkr.hw.init = &(struct clk_init_data){
                .name = "blsp1_uart2_apps_clk_src",
-               .parent_names = gcc_parent_names_xo_gpll0_gpll0_early_div,
+               .parent_data = gcc_parent_data_xo_gpll0_gpll0_early_div,
                .num_parents = 3,
                .ops = &clk_rcg2_ops,
        },
@@ -435,7 +453,7 @@ static struct clk_rcg2 blsp2_qup1_i2c_apps_clk_src = {
        .freq_tbl = ftbl_blsp1_qup1_i2c_apps_clk_src,
        .clkr.hw.init = &(struct clk_init_data){
                .name = "blsp2_qup1_i2c_apps_clk_src",
-               .parent_names = gcc_parent_names_xo_gpll0_gpll0_early_div,
+               .parent_data = gcc_parent_data_xo_gpll0_gpll0_early_div,
                .num_parents = 3,
                .ops = &clk_rcg2_ops,
        },
@@ -449,7 +467,7 @@ static struct clk_rcg2 blsp2_qup1_spi_apps_clk_src = {
        .freq_tbl = ftbl_blsp1_qup1_spi_apps_clk_src,
        .clkr.hw.init = &(struct clk_init_data){
                .name = "blsp2_qup1_spi_apps_clk_src",
-               .parent_names = gcc_parent_names_xo_gpll0_gpll0_early_div,
+               .parent_data = gcc_parent_data_xo_gpll0_gpll0_early_div,
                .num_parents = 3,
                .ops = &clk_rcg2_ops,
        },
@@ -463,7 +481,7 @@ static struct clk_rcg2 blsp2_qup2_i2c_apps_clk_src = {
        .freq_tbl = ftbl_blsp1_qup1_i2c_apps_clk_src,
        .clkr.hw.init = &(struct clk_init_data){
                .name = "blsp2_qup2_i2c_apps_clk_src",
-               .parent_names = gcc_parent_names_xo_gpll0_gpll0_early_div,
+               .parent_data = gcc_parent_data_xo_gpll0_gpll0_early_div,
                .num_parents = 3,
                .ops = &clk_rcg2_ops,
        },
@@ -477,7 +495,7 @@ static struct clk_rcg2 blsp2_qup2_spi_apps_clk_src = {
        .freq_tbl = ftbl_blsp1_qup1_spi_apps_clk_src,
        .clkr.hw.init = &(struct clk_init_data){
                .name = "blsp2_qup2_spi_apps_clk_src",
-               .parent_names = gcc_parent_names_xo_gpll0_gpll0_early_div,
+               .parent_data = gcc_parent_data_xo_gpll0_gpll0_early_div,
                .num_parents = 3,
                .ops = &clk_rcg2_ops,
        },
@@ -491,7 +509,7 @@ static struct clk_rcg2 blsp2_qup3_i2c_apps_clk_src = {
        .freq_tbl = ftbl_blsp1_qup1_i2c_apps_clk_src,
        .clkr.hw.init = &(struct clk_init_data){
                .name = "blsp2_qup3_i2c_apps_clk_src",
-               .parent_names = gcc_parent_names_xo_gpll0_gpll0_early_div,
+               .parent_data = gcc_parent_data_xo_gpll0_gpll0_early_div,
                .num_parents = 3,
                .ops = &clk_rcg2_ops,
        },
@@ -505,7 +523,7 @@ static struct clk_rcg2 blsp2_qup3_spi_apps_clk_src = {
        .freq_tbl = ftbl_blsp1_qup1_spi_apps_clk_src,
        .clkr.hw.init = &(struct clk_init_data){
                .name = "blsp2_qup3_spi_apps_clk_src",
-               .parent_names = gcc_parent_names_xo_gpll0_gpll0_early_div,
+               .parent_data = gcc_parent_data_xo_gpll0_gpll0_early_div,
                .num_parents = 3,
                .ops = &clk_rcg2_ops,
        },
@@ -519,7 +537,7 @@ static struct clk_rcg2 blsp2_qup4_i2c_apps_clk_src = {
        .freq_tbl = ftbl_blsp1_qup1_i2c_apps_clk_src,
        .clkr.hw.init = &(struct clk_init_data){
                .name = "blsp2_qup4_i2c_apps_clk_src",
-               .parent_names = gcc_parent_names_xo_gpll0_gpll0_early_div,
+               .parent_data = gcc_parent_data_xo_gpll0_gpll0_early_div,
                .num_parents = 3,
                .ops = &clk_rcg2_ops,
        },
@@ -533,7 +551,7 @@ static struct clk_rcg2 blsp2_qup4_spi_apps_clk_src = {
        .freq_tbl = ftbl_blsp1_qup1_spi_apps_clk_src,
        .clkr.hw.init = &(struct clk_init_data){
                .name = "blsp2_qup4_spi_apps_clk_src",
-               .parent_names = gcc_parent_names_xo_gpll0_gpll0_early_div,
+               .parent_data = gcc_parent_data_xo_gpll0_gpll0_early_div,
                .num_parents = 3,
                .ops = &clk_rcg2_ops,
        },
@@ -547,7 +565,7 @@ static struct clk_rcg2 blsp2_uart1_apps_clk_src = {
        .freq_tbl = ftbl_blsp1_uart1_apps_clk_src,
        .clkr.hw.init = &(struct clk_init_data){
                .name = "blsp2_uart1_apps_clk_src",
-               .parent_names = gcc_parent_names_xo_gpll0_gpll0_early_div,
+               .parent_data = gcc_parent_data_xo_gpll0_gpll0_early_div,
                .num_parents = 3,
                .ops = &clk_rcg2_ops,
        },
@@ -561,7 +579,7 @@ static struct clk_rcg2 blsp2_uart2_apps_clk_src = {
        .freq_tbl = ftbl_blsp1_uart1_apps_clk_src,
        .clkr.hw.init = &(struct clk_init_data){
                .name = "blsp2_uart2_apps_clk_src",
-               .parent_names = gcc_parent_names_xo_gpll0_gpll0_early_div,
+               .parent_data = gcc_parent_data_xo_gpll0_gpll0_early_div,
                .num_parents = 3,
                .ops = &clk_rcg2_ops,
        },
@@ -582,7 +600,7 @@ static struct clk_rcg2 gp1_clk_src = {
        .freq_tbl = ftbl_gp1_clk_src,
        .clkr.hw.init = &(struct clk_init_data){
                .name = "gp1_clk_src",
-               .parent_names = gcc_parent_names_xo_gpll0_sleep_clk_gpll0_early_div,
+               .parent_data = gcc_parent_data_xo_gpll0_sleep_clk_gpll0_early_div,
                .num_parents = 4,
                .ops = &clk_rcg2_ops,
        },
@@ -596,7 +614,7 @@ static struct clk_rcg2 gp2_clk_src = {
        .freq_tbl = ftbl_gp1_clk_src,
        .clkr.hw.init = &(struct clk_init_data){
                .name = "gp2_clk_src",
-               .parent_names = gcc_parent_names_xo_gpll0_sleep_clk_gpll0_early_div,
+               .parent_data = gcc_parent_data_xo_gpll0_sleep_clk_gpll0_early_div,
                .num_parents = 4,
                .ops = &clk_rcg2_ops,
        },
@@ -610,7 +628,7 @@ static struct clk_rcg2 gp3_clk_src = {
        .freq_tbl = ftbl_gp1_clk_src,
        .clkr.hw.init = &(struct clk_init_data){
                .name = "gp3_clk_src",
-               .parent_names = gcc_parent_names_xo_gpll0_sleep_clk_gpll0_early_div,
+               .parent_data = gcc_parent_data_xo_gpll0_sleep_clk_gpll0_early_div,
                .num_parents = 4,
                .ops = &clk_rcg2_ops,
        },
@@ -630,7 +648,7 @@ static struct clk_rcg2 hmss_gpll0_clk_src = {
        .freq_tbl = ftbl_hmss_gpll0_clk_src,
        .clkr.hw.init = &(struct clk_init_data){
                .name = "hmss_gpll0_clk_src",
-               .parent_names = gcc_parent_names_xo_gpll0_gpll0_early_div,
+               .parent_data = gcc_parent_data_xo_gpll0_gpll0_early_div,
                .num_parents = 3,
                .ops = &clk_rcg2_ops,
        },
@@ -651,7 +669,7 @@ static struct clk_rcg2 hmss_gpll4_clk_src = {
        .freq_tbl = ftbl_hmss_gpll4_clk_src,
        .clkr.hw.init = &(struct clk_init_data){
                .name = "hmss_gpll4_clk_src",
-               .parent_names = gcc_parent_names_xo_gpll4,
+               .parent_data = gcc_parent_data_xo_gpll4,
                .num_parents = 2,
                .ops = &clk_rcg2_ops,
        },
@@ -670,7 +688,7 @@ static struct clk_rcg2 hmss_rbcpr_clk_src = {
        .freq_tbl = ftbl_hmss_rbcpr_clk_src,
        .clkr.hw.init = &(struct clk_init_data){
                .name = "hmss_rbcpr_clk_src",
-               .parent_names = gcc_parent_names_xo_gpll0,
+               .parent_data = gcc_parent_data_xo_gpll0,
                .num_parents = 2,
                .ops = &clk_rcg2_ops,
        },
@@ -689,7 +707,7 @@ static struct clk_rcg2 pdm2_clk_src = {
        .freq_tbl = ftbl_pdm2_clk_src,
        .clkr.hw.init = &(struct clk_init_data){
                .name = "pdm2_clk_src",
-               .parent_names = gcc_parent_names_xo_gpll0_gpll0_early_div,
+               .parent_data = gcc_parent_data_xo_gpll0_gpll0_early_div,
                .num_parents = 3,
                .ops = &clk_rcg2_ops,
        },
@@ -711,7 +729,7 @@ static struct clk_rcg2 qspi_ser_clk_src = {
        .freq_tbl = ftbl_qspi_ser_clk_src,
        .clkr.hw.init = &(struct clk_init_data){
                .name = "qspi_ser_clk_src",
-               .parent_names = gcc_parent_names_xo_gpll0_gpll0_early_div_gpll1_gpll4_gpll1_early_div,
+               .parent_data = gcc_parent_data_xo_gpll0_gpll0_early_div_gpll1_gpll4_gpll1_early_div,
                .num_parents = 6,
                .ops = &clk_rcg2_ops,
        },
@@ -737,7 +755,7 @@ static struct clk_rcg2 sdcc1_apps_clk_src = {
        .freq_tbl = ftbl_sdcc1_apps_clk_src,
        .clkr.hw.init = &(struct clk_init_data){
                .name = "sdcc1_apps_clk_src",
-               .parent_names = gcc_parent_names_xo_gpll0_gpll4_gpll0_early_div,
+               .parent_data = gcc_parent_data_xo_gpll0_gpll4_gpll0_early_div,
                .num_parents = 4,
                .ops = &clk_rcg2_ops,
        },
@@ -759,7 +777,7 @@ static struct clk_rcg2 sdcc1_ice_core_clk_src = {
        .freq_tbl = ftbl_sdcc1_ice_core_clk_src,
        .clkr.hw.init = &(struct clk_init_data){
                .name = "sdcc1_ice_core_clk_src",
-               .parent_names = gcc_parent_names_xo_gpll0_gpll0_early_div,
+               .parent_data = gcc_parent_data_xo_gpll0_gpll0_early_div,
                .num_parents = 3,
                .ops = &clk_rcg2_ops,
        },
@@ -785,7 +803,7 @@ static struct clk_rcg2 sdcc2_apps_clk_src = {
        .freq_tbl = ftbl_sdcc2_apps_clk_src,
        .clkr.hw.init = &(struct clk_init_data){
                .name = "sdcc2_apps_clk_src",
-               .parent_names = gcc_parent_names_xo_gpll0_gpll0_early_div_gpll4,
+               .parent_data = gcc_parent_data_xo_gpll0_gpll0_early_div_gpll4,
                .num_parents = 4,
                .ops = &clk_rcg2_floor_ops,
        },
@@ -808,7 +826,7 @@ static struct clk_rcg2 ufs_axi_clk_src = {
        .freq_tbl = ftbl_ufs_axi_clk_src,
        .clkr.hw.init = &(struct clk_init_data){
                .name = "ufs_axi_clk_src",
-               .parent_names = gcc_parent_names_xo_gpll0_gpll0_early_div,
+               .parent_data = gcc_parent_data_xo_gpll0_gpll0_early_div,
                .num_parents = 3,
                .ops = &clk_rcg2_ops,
        },
@@ -829,7 +847,7 @@ static struct clk_rcg2 ufs_ice_core_clk_src = {
        .freq_tbl = ftbl_ufs_ice_core_clk_src,
        .clkr.hw.init = &(struct clk_init_data){
                .name = "ufs_ice_core_clk_src",
-               .parent_names = gcc_parent_names_xo_gpll0_gpll0_early_div,
+               .parent_data = gcc_parent_data_xo_gpll0_gpll0_early_div,
                .num_parents = 3,
                .ops = &clk_rcg2_ops,
        },
@@ -843,7 +861,7 @@ static struct clk_rcg2 ufs_phy_aux_clk_src = {
        .freq_tbl = ftbl_hmss_rbcpr_clk_src,
        .clkr.hw.init = &(struct clk_init_data){
                .name = "ufs_phy_aux_clk_src",
-               .parent_names = gcc_parent_names_xo_sleep_clk,
+               .parent_data = gcc_parent_data_xo_sleep_clk,
                .num_parents = 2,
                .ops = &clk_rcg2_ops,
        },
@@ -864,7 +882,7 @@ static struct clk_rcg2 ufs_unipro_core_clk_src = {
        .freq_tbl = ftbl_ufs_unipro_core_clk_src,
        .clkr.hw.init = &(struct clk_init_data){
                .name = "ufs_unipro_core_clk_src",
-               .parent_names = gcc_parent_names_xo_gpll0_gpll0_early_div,
+               .parent_data = gcc_parent_data_xo_gpll0_gpll0_early_div,
                .num_parents = 3,
                .ops = &clk_rcg2_ops,
        },
@@ -885,7 +903,7 @@ static struct clk_rcg2 usb20_master_clk_src = {
        .freq_tbl = ftbl_usb20_master_clk_src,
        .clkr.hw.init = &(struct clk_init_data){
                .name = "usb20_master_clk_src",
-               .parent_names = gcc_parent_names_xo_gpll0_gpll0_early_div,
+               .parent_data = gcc_parent_data_xo_gpll0_gpll0_early_div,
                .num_parents = 3,
                .ops = &clk_rcg2_ops,
        },
@@ -905,7 +923,7 @@ static struct clk_rcg2 usb20_mock_utmi_clk_src = {
        .freq_tbl = ftbl_usb20_mock_utmi_clk_src,
        .clkr.hw.init = &(struct clk_init_data){
                .name = "usb20_mock_utmi_clk_src",
-               .parent_names = gcc_parent_names_xo_gpll0_gpll0_early_div,
+               .parent_data = gcc_parent_data_xo_gpll0_gpll0_early_div,
                .num_parents = 3,
                .ops = &clk_rcg2_ops,
        },
@@ -930,7 +948,7 @@ static struct clk_rcg2 usb30_master_clk_src = {
        .freq_tbl = ftbl_usb30_master_clk_src,
        .clkr.hw.init = &(struct clk_init_data){
                .name = "usb30_master_clk_src",
-               .parent_names = gcc_parent_names_xo_gpll0_gpll0_early_div,
+               .parent_data = gcc_parent_data_xo_gpll0_gpll0_early_div,
                .num_parents = 3,
                .ops = &clk_rcg2_ops,
        },
@@ -951,7 +969,7 @@ static struct clk_rcg2 usb30_mock_utmi_clk_src = {
        .freq_tbl = ftbl_usb30_mock_utmi_clk_src,
        .clkr.hw.init = &(struct clk_init_data){
                .name = "usb30_mock_utmi_clk_src",
-               .parent_names = gcc_parent_names_xo_gpll0_gpll0_early_div,
+               .parent_data = gcc_parent_data_xo_gpll0_gpll0_early_div,
                .num_parents = 3,
                .ops = &clk_rcg2_ops,
        },
@@ -971,7 +989,7 @@ static struct clk_rcg2 usb3_phy_aux_clk_src = {
        .freq_tbl = ftbl_usb3_phy_aux_clk_src,
        .clkr.hw.init = &(struct clk_init_data){
                .name = "usb3_phy_aux_clk_src",
-               .parent_names = gcc_parent_names_xo_sleep_clk,
+               .parent_data = gcc_parent_data_xo_sleep_clk,
                .num_parents = 2,
                .ops = &clk_rcg2_ops,
        },
@@ -985,8 +1003,8 @@ static struct clk_branch gcc_aggre2_ufs_axi_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_aggre2_ufs_axi_clk",
-                       .parent_names = (const char *[]){
-                               "ufs_axi_clk_src",
+                       .parent_hws = (const struct clk_hw*[]) {
+                               &ufs_axi_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .ops = &clk_branch2_ops,
@@ -1002,8 +1020,8 @@ static struct clk_branch gcc_aggre2_usb3_axi_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_aggre2_usb3_axi_clk",
-                       .parent_names = (const char *[]){
-                               "usb30_master_clk_src",
+                       .parent_hws = (const struct clk_hw*[]) {
+                               &usb30_master_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .ops = &clk_branch2_ops,
@@ -1071,8 +1089,8 @@ static struct clk_branch gcc_blsp1_qup1_i2c_apps_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_blsp1_qup1_i2c_apps_clk",
-                       .parent_names = (const char *[]){
-                               "blsp1_qup1_i2c_apps_clk_src",
+                       .parent_hws = (const struct clk_hw*[]) {
+                               &blsp1_qup1_i2c_apps_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -1089,8 +1107,8 @@ static struct clk_branch gcc_blsp1_qup1_spi_apps_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_blsp1_qup1_spi_apps_clk",
-                       .parent_names = (const char *[]){
-                               "blsp1_qup1_spi_apps_clk_src",
+                       .parent_hws = (const struct clk_hw*[]) {
+                               &blsp1_qup1_spi_apps_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -1107,8 +1125,8 @@ static struct clk_branch gcc_blsp1_qup2_i2c_apps_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_blsp1_qup2_i2c_apps_clk",
-                       .parent_names = (const char *[]){
-                               "blsp1_qup2_i2c_apps_clk_src",
+                       .parent_hws = (const struct clk_hw*[]) {
+                               &blsp1_qup2_i2c_apps_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -1125,8 +1143,8 @@ static struct clk_branch gcc_blsp1_qup2_spi_apps_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_blsp1_qup2_spi_apps_clk",
-                       .parent_names = (const char *[]){
-                               "blsp1_qup2_spi_apps_clk_src",
+                       .parent_hws = (const struct clk_hw*[]) {
+                               &blsp1_qup2_spi_apps_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -1143,8 +1161,8 @@ static struct clk_branch gcc_blsp1_qup3_i2c_apps_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_blsp1_qup3_i2c_apps_clk",
-                       .parent_names = (const char *[]){
-                               "blsp1_qup3_i2c_apps_clk_src",
+                       .parent_hws = (const struct clk_hw*[]) {
+                               &blsp1_qup3_i2c_apps_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -1161,8 +1179,8 @@ static struct clk_branch gcc_blsp1_qup3_spi_apps_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_blsp1_qup3_spi_apps_clk",
-                       .parent_names = (const char *[]){
-                               "blsp1_qup3_spi_apps_clk_src",
+                       .parent_hws = (const struct clk_hw*[]) {
+                               &blsp1_qup3_spi_apps_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -1179,8 +1197,8 @@ static struct clk_branch gcc_blsp1_qup4_i2c_apps_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_blsp1_qup4_i2c_apps_clk",
-                       .parent_names = (const char *[]){
-                               "blsp1_qup4_i2c_apps_clk_src",
+                       .parent_hws = (const struct clk_hw*[]) {
+                               &blsp1_qup4_i2c_apps_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -1197,8 +1215,8 @@ static struct clk_branch gcc_blsp1_qup4_spi_apps_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_blsp1_qup4_spi_apps_clk",
-                       .parent_names = (const char *[]){
-                               "blsp1_qup4_spi_apps_clk_src",
+                       .parent_hws = (const struct clk_hw*[]) {
+                               &blsp1_qup4_spi_apps_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -1215,8 +1233,8 @@ static struct clk_branch gcc_blsp1_uart1_apps_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_blsp1_uart1_apps_clk",
-                       .parent_names = (const char *[]){
-                               "blsp1_uart1_apps_clk_src",
+                       .parent_hws = (const struct clk_hw*[]) {
+                               &blsp1_uart1_apps_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -1233,8 +1251,8 @@ static struct clk_branch gcc_blsp1_uart2_apps_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_blsp1_uart2_apps_clk",
-                       .parent_names = (const char *[]){
-                               "blsp1_uart2_apps_clk_src",
+                       .parent_hws = (const struct clk_hw*[]) {
+                               &blsp1_uart2_apps_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -1264,8 +1282,8 @@ static struct clk_branch gcc_blsp2_qup1_i2c_apps_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_blsp2_qup1_i2c_apps_clk",
-                       .parent_names = (const char *[]){
-                               "blsp2_qup1_i2c_apps_clk_src",
+                       .parent_hws = (const struct clk_hw*[]) {
+                               &blsp2_qup1_i2c_apps_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -1282,8 +1300,8 @@ static struct clk_branch gcc_blsp2_qup1_spi_apps_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_blsp2_qup1_spi_apps_clk",
-                       .parent_names = (const char *[]){
-                               "blsp2_qup1_spi_apps_clk_src",
+                       .parent_hws = (const struct clk_hw*[]) {
+                               &blsp2_qup1_spi_apps_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -1300,8 +1318,8 @@ static struct clk_branch gcc_blsp2_qup2_i2c_apps_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_blsp2_qup2_i2c_apps_clk",
-                       .parent_names = (const char *[]){
-                               "blsp2_qup2_i2c_apps_clk_src",
+                       .parent_hws = (const struct clk_hw*[]) {
+                               &blsp2_qup2_i2c_apps_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -1318,8 +1336,8 @@ static struct clk_branch gcc_blsp2_qup2_spi_apps_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_blsp2_qup2_spi_apps_clk",
-                       .parent_names = (const char *[]){
-                               "blsp2_qup2_spi_apps_clk_src",
+                       .parent_hws = (const struct clk_hw*[]) {
+                               &blsp2_qup2_spi_apps_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -1336,8 +1354,8 @@ static struct clk_branch gcc_blsp2_qup3_i2c_apps_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_blsp2_qup3_i2c_apps_clk",
-                       .parent_names = (const char *[]){
-                               "blsp2_qup3_i2c_apps_clk_src",
+                       .parent_hws = (const struct clk_hw*[]) {
+                               &blsp2_qup3_i2c_apps_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -1354,8 +1372,8 @@ static struct clk_branch gcc_blsp2_qup3_spi_apps_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_blsp2_qup3_spi_apps_clk",
-                       .parent_names = (const char *[]){
-                               "blsp2_qup3_spi_apps_clk_src",
+                       .parent_hws = (const struct clk_hw*[]) {
+                               &blsp2_qup3_spi_apps_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -1372,8 +1390,8 @@ static struct clk_branch gcc_blsp2_qup4_i2c_apps_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_blsp2_qup4_i2c_apps_clk",
-                       .parent_names = (const char *[]){
-                               "blsp2_qup4_i2c_apps_clk_src",
+                       .parent_hws = (const struct clk_hw*[]) {
+                               &blsp2_qup4_i2c_apps_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -1390,8 +1408,8 @@ static struct clk_branch gcc_blsp2_qup4_spi_apps_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_blsp2_qup4_spi_apps_clk",
-                       .parent_names = (const char *[]){
-                               "blsp2_qup4_spi_apps_clk_src",
+                       .parent_hws = (const struct clk_hw*[]) {
+                               &blsp2_qup4_spi_apps_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -1408,8 +1426,8 @@ static struct clk_branch gcc_blsp2_uart1_apps_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_blsp2_uart1_apps_clk",
-                       .parent_names = (const char *[]){
-                               "blsp2_uart1_apps_clk_src",
+                       .parent_hws = (const struct clk_hw*[]) {
+                               &blsp2_uart1_apps_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -1426,8 +1444,8 @@ static struct clk_branch gcc_blsp2_uart2_apps_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_blsp2_uart2_apps_clk",
-                       .parent_names = (const char *[]){
-                               "blsp2_uart2_apps_clk_src",
+                       .parent_hws = (const struct clk_hw*[]) {
+                               &blsp2_uart2_apps_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -1457,8 +1475,8 @@ static struct clk_branch gcc_cfg_noc_usb2_axi_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_cfg_noc_usb2_axi_clk",
-                       .parent_names = (const char *[]){
-                               "usb20_master_clk_src",
+                       .parent_hws = (const struct clk_hw*[]) {
+                               &usb20_master_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .ops = &clk_branch2_ops,
@@ -1474,8 +1492,8 @@ static struct clk_branch gcc_cfg_noc_usb3_axi_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_cfg_noc_usb3_axi_clk",
-                       .parent_names = (const char *[]){
-                               "usb30_master_clk_src",
+                       .parent_hws = (const struct clk_hw*[]) {
+                               &usb30_master_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .ops = &clk_branch2_ops,
@@ -1503,8 +1521,8 @@ static struct clk_branch gcc_gp1_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_gp1_clk",
-                       .parent_names = (const char *[]){
-                               "gp1_clk_src",
+                       .parent_hws = (const struct clk_hw*[]) {
+                               &gp1_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -1521,8 +1539,8 @@ static struct clk_branch gcc_gp2_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_gp2_clk",
-                       .parent_names = (const char *[]){
-                               "gp2_clk_src",
+                       .parent_hws = (const struct clk_hw*[]) {
+                               &gp2_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -1539,8 +1557,8 @@ static struct clk_branch gcc_gp3_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_gp3_clk",
-                       .parent_names = (const char *[]){
-                               "gp3_clk_src",
+                       .parent_hws = (const struct clk_hw*[]) {
+                               &gp3_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -1584,8 +1602,8 @@ static struct clk_branch gcc_gpu_gpll0_clk = {
                .enable_mask = BIT(4),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_gpu_gpll0_clk",
-                       .parent_names = (const char *[]){
-                               "gpll0",
+                       .parent_hws = (const struct clk_hw*[]) {
+                               &gpll0.clkr.hw,
                        },
                        .num_parents = 1,
                        .ops = &clk_branch2_ops,
@@ -1601,8 +1619,8 @@ static struct clk_branch gcc_gpu_gpll0_div_clk = {
                .enable_mask = BIT(3),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_gpu_gpll0_div_clk",
-                       .parent_names = (const char *[]){
-                               "gpll0_early_div",
+                       .parent_hws = (const struct clk_hw*[]) {
+                               &gpll0_early_div.hw,
                        },
                        .num_parents = 1,
                        .ops = &clk_branch2_ops,
@@ -1632,8 +1650,8 @@ static struct clk_branch gcc_hmss_rbcpr_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_hmss_rbcpr_clk",
-                       .parent_names = (const char *[]){
-                               "hmss_rbcpr_clk_src",
+                       .parent_hws = (const struct clk_hw*[]) {
+                               &hmss_rbcpr_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -1650,8 +1668,8 @@ static struct clk_branch gcc_mmss_gpll0_clk = {
                .enable_mask = BIT(1),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_mmss_gpll0_clk",
-                       .parent_names = (const char *[]){
-                               "gpll0",
+                       .parent_hws = (const struct clk_hw*[]) {
+                               &gpll0.clkr.hw,
                        },
                        .num_parents = 1,
                        .ops = &clk_branch2_ops,
@@ -1667,8 +1685,8 @@ static struct clk_branch gcc_mmss_gpll0_div_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_mmss_gpll0_div_clk",
-                       .parent_names = (const char *[]){
-                               "gpll0_early_div",
+                       .parent_hws = (const struct clk_hw*[]) {
+                               &gpll0_early_div.hw,
                        },
                        .num_parents = 1,
                        .ops = &clk_branch2_ops,
@@ -1767,8 +1785,8 @@ static struct clk_branch gcc_pdm2_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_pdm2_clk",
-                       .parent_names = (const char *[]){
-                               "pdm2_clk_src",
+                       .parent_hws = (const struct clk_hw*[]) {
+                               &pdm2_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -1824,8 +1842,8 @@ static struct clk_branch gcc_qspi_ser_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_qspi_ser_clk",
-                       .parent_names = (const char *[]){
-                               "qspi_ser_clk_src",
+                       .parent_hws = (const struct clk_hw*[]) {
+                               &qspi_ser_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -1881,8 +1899,8 @@ static struct clk_branch gcc_sdcc1_apps_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_sdcc1_apps_clk",
-                       .parent_names = (const char *[]){
-                               "sdcc1_apps_clk_src",
+                       .parent_hws = (const struct clk_hw*[]) {
+                               &sdcc1_apps_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -1899,8 +1917,8 @@ static struct clk_branch gcc_sdcc1_ice_core_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_sdcc1_ice_core_clk",
-                       .parent_names = (const char *[]){
-                               "sdcc1_ice_core_clk_src",
+                       .parent_hws = (const struct clk_hw*[]) {
+                               &sdcc1_ice_core_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -1930,8 +1948,8 @@ static struct clk_branch gcc_sdcc2_apps_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_sdcc2_apps_clk",
-                       .parent_names = (const char *[]){
-                               "sdcc2_apps_clk_src",
+                       .parent_hws = (const struct clk_hw*[]) {
+                               &sdcc2_apps_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -1961,8 +1979,8 @@ static struct clk_branch gcc_ufs_axi_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_ufs_axi_clk",
-                       .parent_names = (const char *[]){
-                               "ufs_axi_clk_src",
+                       .parent_hws = (const struct clk_hw*[]) {
+                               &ufs_axi_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -1992,8 +2010,8 @@ static struct clk_branch gcc_ufs_ice_core_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_ufs_ice_core_clk",
-                       .parent_names = (const char *[]){
-                               "ufs_ice_core_clk_src",
+                       .parent_hws = (const struct clk_hw*[]) {
+                               &ufs_ice_core_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2010,8 +2028,8 @@ static struct clk_branch gcc_ufs_phy_aux_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_ufs_phy_aux_clk",
-                       .parent_names = (const char *[]){
-                               "ufs_phy_aux_clk_src",
+                       .parent_hws = (const struct clk_hw*[]) {
+                               &ufs_phy_aux_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2067,8 +2085,8 @@ static struct clk_branch gcc_ufs_unipro_core_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_ufs_unipro_core_clk",
-                       .parent_names = (const char *[]){
-                               "ufs_unipro_core_clk_src",
+                       .parent_hws = (const struct clk_hw*[]) {
+                               &ufs_unipro_core_clk_src.clkr.hw,
                        },
                        .flags = CLK_SET_RATE_PARENT,
                        .num_parents = 1,
@@ -2085,8 +2103,8 @@ static struct clk_branch gcc_usb20_master_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_usb20_master_clk",
-                       .parent_names = (const char *[]){
-                               "usb20_master_clk_src"
+                       .parent_hws = (const struct clk_hw*[]) {
+                               &usb20_master_clk_src.clkr.hw,
                        },
                        .flags = CLK_SET_RATE_PARENT,
                        .num_parents = 1,
@@ -2103,8 +2121,8 @@ static struct clk_branch gcc_usb20_mock_utmi_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_usb20_mock_utmi_clk",
-                       .parent_names = (const char *[]){
-                               "usb20_mock_utmi_clk_src",
+                       .parent_hws = (const struct clk_hw*[]) {
+                               &usb20_mock_utmi_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2134,8 +2152,8 @@ static struct clk_branch gcc_usb30_master_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_usb30_master_clk",
-                       .parent_names = (const char *[]){
-                               "usb30_master_clk_src",
+                       .parent_hws = (const struct clk_hw*[]) {
+                               &usb30_master_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2152,8 +2170,8 @@ static struct clk_branch gcc_usb30_mock_utmi_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_usb30_mock_utmi_clk",
-                       .parent_names = (const char *[]){
-                               "usb30_mock_utmi_clk_src",
+                       .parent_hws = (const struct clk_hw*[]) {
+                               &usb30_mock_utmi_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
@@ -2196,8 +2214,8 @@ static struct clk_branch gcc_usb3_phy_aux_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_usb3_phy_aux_clk",
-                       .parent_names = (const char *[]){
-                               "usb3_phy_aux_clk_src",
+                       .parent_hws = (const struct clk_hw*[]) {
+                               &usb3_phy_aux_clk_src.clkr.hw,
                        },
                        .num_parents = 1,
                        .flags = CLK_SET_RATE_PARENT,
diff --git a/drivers/clk/qcom/gcc-sm6115.c b/drivers/clk/qcom/gcc-sm6115.c
new file mode 100644 (file)
index 0000000..bc09736
--- /dev/null
@@ -0,0 +1,3544 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
+ */
+
+#include <linux/err.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/clk-provider.h>
+#include <linux/regmap.h>
+#include <linux/reset-controller.h>
+
+#include <dt-bindings/clock/qcom,gcc-sm6115.h>
+
+#include "clk-alpha-pll.h"
+#include "clk-branch.h"
+#include "clk-pll.h"
+#include "clk-rcg.h"
+#include "clk-regmap.h"
+#include "clk-regmap-divider.h"
+#include "common.h"
+#include "gdsc.h"
+#include "reset.h"
+
+enum {
+       P_BI_TCXO,
+       P_GPLL0_OUT_AUX2,
+       P_GPLL0_OUT_EARLY,
+       P_GPLL10_OUT_MAIN,
+       P_GPLL11_OUT_MAIN,
+       P_GPLL3_OUT_EARLY,
+       P_GPLL4_OUT_MAIN,
+       P_GPLL6_OUT_EARLY,
+       P_GPLL6_OUT_MAIN,
+       P_GPLL7_OUT_MAIN,
+       P_GPLL8_OUT_EARLY,
+       P_GPLL8_OUT_MAIN,
+       P_GPLL9_OUT_EARLY,
+       P_GPLL9_OUT_MAIN,
+       P_SLEEP_CLK,
+};
+
+static struct pll_vco default_vco[] = {
+       { 500000000, 1000000000, 2 },
+};
+
+static struct pll_vco gpll9_vco[] = {
+       { 500000000, 1250000000, 0 },
+};
+
+static struct pll_vco gpll10_vco[] = {
+       { 750000000, 1500000000, 1 },
+};
+
+static struct clk_alpha_pll gpll0 = {
+       .offset = 0x0,
+       .vco_table = default_vco,
+       .num_vco = ARRAY_SIZE(default_vco),
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
+       .clkr = {
+               .enable_reg = 0x79000,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gpll0",
+                       .parent_data = &(const struct clk_parent_data){
+                               .fw_name = "bi_tcxo",
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_alpha_pll_ops,
+               },
+       },
+};
+
+static const struct clk_div_table post_div_table_gpll0_out_aux2[] = {
+       { 0x1, 2 },
+       { }
+};
+
+static struct clk_alpha_pll_postdiv gpll0_out_aux2 = {
+       .offset = 0x0,
+       .post_div_shift = 8,
+       .post_div_table = post_div_table_gpll0_out_aux2,
+       .num_post_div = ARRAY_SIZE(post_div_table_gpll0_out_aux2),
+       .width = 4,
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gpll0_out_aux2",
+               .parent_hws = (const struct clk_hw *[]){ &gpll0.clkr.hw },
+               .num_parents = 1,
+               .ops = &clk_alpha_pll_postdiv_ro_ops,
+       },
+};
+
+/* listed as BRAMMO, but it doesn't really match */
+static const u8 clk_gpll9_regs[PLL_OFF_MAX_REGS] = {
+       [PLL_OFF_L_VAL] = 0x04,
+       [PLL_OFF_ALPHA_VAL] = 0x08,
+       [PLL_OFF_ALPHA_VAL_U] = 0x0c,
+       [PLL_OFF_TEST_CTL] = 0x10,
+       [PLL_OFF_TEST_CTL_U] = 0x14,
+       [PLL_OFF_USER_CTL] = 0x18,
+       [PLL_OFF_CONFIG_CTL] = 0x1C,
+       [PLL_OFF_STATUS] = 0x20,
+};
+
+static const struct clk_div_table post_div_table_gpll0_out_main[] = {
+       { 0x0, 1 },
+       { }
+};
+
+static struct clk_alpha_pll_postdiv gpll0_out_main = {
+       .offset = 0x0,
+       .post_div_shift = 8,
+       .post_div_table = post_div_table_gpll0_out_main,
+       .num_post_div = ARRAY_SIZE(post_div_table_gpll0_out_main),
+       .width = 4,
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gpll0_out_main",
+               .parent_hws = (const struct clk_hw *[]){ &gpll0.clkr.hw },
+               .num_parents = 1,
+               .ops = &clk_alpha_pll_postdiv_ro_ops,
+       },
+};
+
+/* 1152MHz configuration */
+static const struct alpha_pll_config gpll10_config = {
+       .l = 0x3c,
+       .vco_val = 0x1 << 20,
+       .vco_mask = GENMASK(21, 20),
+       .main_output_mask = BIT(0),
+       .config_ctl_val = 0x4001055b,
+};
+
+static struct clk_alpha_pll gpll10 = {
+       .offset = 0xa000,
+       .vco_table = gpll10_vco,
+       .num_vco = ARRAY_SIZE(gpll10_vco),
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
+       .clkr = {
+               .enable_reg = 0x79000,
+               .enable_mask = BIT(10),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gpll10",
+                       .parent_data = &(const struct clk_parent_data){
+                               .fw_name = "bi_tcxo",
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_alpha_pll_ops,
+               },
+       },
+};
+
+static const struct clk_div_table post_div_table_gpll10_out_main[] = {
+       { 0x0, 1 },
+       { }
+};
+
+static struct clk_alpha_pll_postdiv gpll10_out_main = {
+       .offset = 0xa000,
+       .post_div_shift = 8,
+       .post_div_table = post_div_table_gpll10_out_main,
+       .num_post_div = ARRAY_SIZE(post_div_table_gpll10_out_main),
+       .width = 4,
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gpll10_out_main",
+               .parent_hws = (const struct clk_hw *[]){ &gpll10.clkr.hw },
+               .num_parents = 1,
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_alpha_pll_postdiv_ops,
+       },
+};
+
+/* 600MHz configuration */
+static const struct alpha_pll_config gpll11_config = {
+       .l = 0x1F,
+       .alpha = 0x0,
+       .alpha_hi = 0x40,
+       .alpha_en_mask = BIT(24),
+       .vco_val = 0x2 << 20,
+       .vco_mask = GENMASK(21, 20),
+       .config_ctl_val = 0x4001055b,
+};
+
+static struct clk_alpha_pll gpll11 = {
+       .offset = 0xb000,
+       .vco_table = default_vco,
+       .num_vco = ARRAY_SIZE(default_vco),
+       .flags = SUPPORTS_DYNAMIC_UPDATE,
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
+       .clkr = {
+               .enable_reg = 0x79000,
+               .enable_mask = BIT(11),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gpll11",
+                       .parent_data = &(const struct clk_parent_data){
+                               .fw_name = "bi_tcxo",
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_alpha_pll_ops,
+               },
+       },
+};
+
+static const struct clk_div_table post_div_table_gpll11_out_main[] = {
+       { 0x0, 1 },
+       { }
+};
+
+static struct clk_alpha_pll_postdiv gpll11_out_main = {
+       .offset = 0xb000,
+       .post_div_shift = 8,
+       .post_div_table = post_div_table_gpll11_out_main,
+       .num_post_div = ARRAY_SIZE(post_div_table_gpll11_out_main),
+       .width = 4,
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gpll11_out_main",
+               .parent_hws = (const struct clk_hw *[]){ &gpll11.clkr.hw },
+               .num_parents = 1,
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_alpha_pll_postdiv_ops,
+       },
+};
+
+static struct clk_alpha_pll gpll3 = {
+       .offset = 0x3000,
+       .vco_table = default_vco,
+       .num_vco = ARRAY_SIZE(default_vco),
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
+       .clkr = {
+               .enable_reg = 0x79000,
+               .enable_mask = BIT(3),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gpll3",
+                       .parent_data = &(const struct clk_parent_data){
+                               .fw_name = "bi_tcxo",
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_alpha_pll_ops,
+               },
+       },
+};
+
+static struct clk_alpha_pll gpll4 = {
+       .offset = 0x4000,
+       .vco_table = default_vco,
+       .num_vco = ARRAY_SIZE(default_vco),
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
+       .clkr = {
+               .enable_reg = 0x79000,
+               .enable_mask = BIT(4),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gpll4",
+                       .parent_data = &(const struct clk_parent_data){
+                               .fw_name = "bi_tcxo",
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_alpha_pll_ops,
+               },
+       },
+};
+
+static const struct clk_div_table post_div_table_gpll4_out_main[] = {
+       { 0x0, 1 },
+       { }
+};
+
+static struct clk_alpha_pll_postdiv gpll4_out_main = {
+       .offset = 0x4000,
+       .post_div_shift = 8,
+       .post_div_table = post_div_table_gpll4_out_main,
+       .num_post_div = ARRAY_SIZE(post_div_table_gpll4_out_main),
+       .width = 4,
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gpll4_out_main",
+               .parent_hws = (const struct clk_hw *[]){ &gpll4.clkr.hw },
+               .num_parents = 1,
+               .ops = &clk_alpha_pll_postdiv_ro_ops,
+       },
+};
+
+static struct clk_alpha_pll gpll6 = {
+       .offset = 0x6000,
+       .vco_table = default_vco,
+       .num_vco = ARRAY_SIZE(default_vco),
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
+       .clkr = {
+               .enable_reg = 0x79000,
+               .enable_mask = BIT(6),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gpll6",
+                       .parent_data = &(const struct clk_parent_data){
+                               .fw_name = "bi_tcxo",
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_alpha_pll_ops,
+               },
+       },
+};
+
+static const struct clk_div_table post_div_table_gpll6_out_main[] = {
+       { 0x1, 2 },
+       { }
+};
+
+static struct clk_alpha_pll_postdiv gpll6_out_main = {
+       .offset = 0x6000,
+       .post_div_shift = 8,
+       .post_div_table = post_div_table_gpll6_out_main,
+       .num_post_div = ARRAY_SIZE(post_div_table_gpll6_out_main),
+       .width = 4,
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gpll6_out_main",
+               .parent_hws = (const struct clk_hw *[]){ &gpll6.clkr.hw },
+               .num_parents = 1,
+               .ops = &clk_alpha_pll_postdiv_ro_ops,
+       },
+};
+
+static struct clk_alpha_pll gpll7 = {
+       .offset = 0x7000,
+       .vco_table = default_vco,
+       .num_vco = ARRAY_SIZE(default_vco),
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
+       .clkr = {
+               .enable_reg = 0x79000,
+               .enable_mask = BIT(7),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gpll7",
+                       .parent_data = &(const struct clk_parent_data){
+                               .fw_name = "bi_tcxo",
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_alpha_pll_ops,
+               },
+       },
+};
+
+static const struct clk_div_table post_div_table_gpll7_out_main[] = {
+       { 0x0, 1 },
+       { }
+};
+
+static struct clk_alpha_pll_postdiv gpll7_out_main = {
+       .offset = 0x7000,
+       .post_div_shift = 8,
+       .post_div_table = post_div_table_gpll7_out_main,
+       .num_post_div = ARRAY_SIZE(post_div_table_gpll7_out_main),
+       .width = 4,
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gpll7_out_main",
+               .parent_hws = (const struct clk_hw *[]){ &gpll7.clkr.hw },
+               .num_parents = 1,
+               .ops = &clk_alpha_pll_postdiv_ro_ops,
+       },
+};
+
+/* 800MHz configuration */
+static const struct alpha_pll_config gpll8_config = {
+       .l = 0x29,
+       .alpha = 0xAAAAAAAA,
+       .alpha_hi = 0xAA,
+       .alpha_en_mask = BIT(24),
+       .vco_val = 0x2 << 20,
+       .vco_mask = GENMASK(21, 20),
+       .main_output_mask = BIT(0),
+       .early_output_mask = BIT(3),
+       .post_div_val = 0x1 << 8,
+       .post_div_mask = GENMASK(11, 8),
+       .config_ctl_val = 0x4001055b,
+};
+
+static struct clk_alpha_pll gpll8 = {
+       .offset = 0x8000,
+       .vco_table = default_vco,
+       .num_vco = ARRAY_SIZE(default_vco),
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
+       .flags = SUPPORTS_DYNAMIC_UPDATE,
+       .clkr = {
+               .enable_reg = 0x79000,
+               .enable_mask = BIT(8),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gpll8",
+                       .parent_data = &(const struct clk_parent_data){
+                               .fw_name = "bi_tcxo",
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_alpha_pll_ops,
+               },
+       },
+};
+
+static const struct clk_div_table post_div_table_gpll8_out_main[] = {
+       { 0x1, 2 },
+       { }
+};
+
+static struct clk_alpha_pll_postdiv gpll8_out_main = {
+       .offset = 0x8000,
+       .post_div_shift = 8,
+       .post_div_table = post_div_table_gpll8_out_main,
+       .num_post_div = ARRAY_SIZE(post_div_table_gpll8_out_main),
+       .width = 4,
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gpll8_out_main",
+               .parent_hws = (const struct clk_hw *[]){ &gpll8.clkr.hw },
+               .num_parents = 1,
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_alpha_pll_postdiv_ro_ops,
+       },
+};
+
+/* 1152MHz configuration */
+static const struct alpha_pll_config gpll9_config = {
+       .l = 0x3C,
+       .alpha = 0x0,
+       .post_div_val = 0x1 << 8,
+       .post_div_mask = GENMASK(9, 8),
+       .main_output_mask = BIT(0),
+       .config_ctl_val = 0x00004289,
+};
+
+static struct clk_alpha_pll gpll9 = {
+       .offset = 0x9000,
+       .vco_table = gpll9_vco,
+       .num_vco = ARRAY_SIZE(gpll9_vco),
+       .regs = clk_gpll9_regs,
+       .clkr = {
+               .enable_reg = 0x79000,
+               .enable_mask = BIT(9),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gpll9",
+                       .parent_data = &(const struct clk_parent_data){
+                               .fw_name = "bi_tcxo",
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_alpha_pll_ops,
+               },
+       },
+};
+
+static const struct clk_div_table post_div_table_gpll9_out_main[] = {
+       { 0x1, 2 },
+       { }
+};
+
+static struct clk_alpha_pll_postdiv gpll9_out_main = {
+       .offset = 0x9000,
+       .post_div_shift = 8,
+       .post_div_table = post_div_table_gpll9_out_main,
+       .num_post_div = ARRAY_SIZE(post_div_table_gpll9_out_main),
+       .width = 2,
+       .regs = clk_gpll9_regs,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gpll9_out_main",
+               .parent_hws = (const struct clk_hw *[]){ &gpll9.clkr.hw },
+               .num_parents = 1,
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_alpha_pll_postdiv_ops,
+       },
+};
+
+static const struct parent_map gcc_parent_map_0[] = {
+       { P_BI_TCXO, 0 },
+       { P_GPLL0_OUT_EARLY, 1 },
+       { P_GPLL0_OUT_AUX2, 2 },
+};
+
+static const struct clk_parent_data gcc_parents_0[] = {
+       { .fw_name = "bi_tcxo" },
+       { .hw = &gpll0.clkr.hw },
+       { .hw = &gpll0_out_aux2.clkr.hw },
+};
+
+static const struct parent_map gcc_parent_map_1[] = {
+       { P_BI_TCXO, 0 },
+       { P_GPLL0_OUT_EARLY, 1 },
+       { P_GPLL0_OUT_AUX2, 2 },
+       { P_GPLL6_OUT_MAIN, 4 },
+};
+
+static const struct clk_parent_data gcc_parents_1[] = {
+       { .fw_name = "bi_tcxo" },
+       { .hw = &gpll0.clkr.hw },
+       { .hw = &gpll0_out_aux2.clkr.hw },
+       { .hw = &gpll6_out_main.clkr.hw },
+};
+
+static const struct parent_map gcc_parent_map_2[] = {
+       { P_BI_TCXO, 0 },
+       { P_GPLL0_OUT_EARLY, 1 },
+       { P_GPLL0_OUT_AUX2, 2 },
+       { P_SLEEP_CLK, 5 },
+};
+
+static const struct clk_parent_data gcc_parents_2[] = {
+       { .fw_name = "bi_tcxo" },
+       { .hw = &gpll0.clkr.hw },
+       { .hw = &gpll0_out_aux2.clkr.hw },
+       { .fw_name = "sleep_clk" },
+};
+
+static const struct parent_map gcc_parent_map_3[] = {
+       { P_BI_TCXO, 0 },
+       { P_GPLL0_OUT_EARLY, 1 },
+       { P_GPLL9_OUT_EARLY, 2 },
+       { P_GPLL10_OUT_MAIN, 3 },
+       { P_GPLL9_OUT_MAIN, 5 },
+};
+
+static const struct clk_parent_data gcc_parents_3[] = {
+       { .fw_name = "bi_tcxo" },
+       { .hw = &gpll0.clkr.hw },
+       { .hw = &gpll9.clkr.hw },
+       { .hw = &gpll10_out_main.clkr.hw },
+       { .hw = &gpll9_out_main.clkr.hw },
+};
+
+static const struct parent_map gcc_parent_map_4[] = {
+       { P_BI_TCXO, 0 },
+       { P_GPLL0_OUT_EARLY, 1 },
+       { P_GPLL0_OUT_AUX2, 2 },
+       { P_GPLL4_OUT_MAIN, 5 },
+};
+
+static const struct clk_parent_data gcc_parents_4[] = {
+       { .fw_name = "bi_tcxo" },
+       { .hw = &gpll0.clkr.hw },
+       { .hw = &gpll0_out_aux2.clkr.hw },
+       { .hw = &gpll4_out_main.clkr.hw },
+};
+
+static const struct parent_map gcc_parent_map_5[] = {
+       { P_BI_TCXO, 0 },
+       { P_GPLL0_OUT_EARLY, 1 },
+       { P_GPLL8_OUT_EARLY, 2 },
+       { P_GPLL10_OUT_MAIN, 3 },
+       { P_GPLL8_OUT_MAIN, 4 },
+       { P_GPLL9_OUT_MAIN, 5 },
+};
+
+static const struct clk_parent_data gcc_parents_5[] = {
+       { .fw_name = "bi_tcxo" },
+       { .hw = &gpll0.clkr.hw },
+       { .hw = &gpll8.clkr.hw },
+       { .hw = &gpll10_out_main.clkr.hw },
+       { .hw = &gpll8_out_main.clkr.hw },
+       { .hw = &gpll9_out_main.clkr.hw },
+};
+
+static const struct parent_map gcc_parent_map_6[] = {
+       { P_BI_TCXO, 0 },
+       { P_GPLL0_OUT_EARLY, 1 },
+       { P_GPLL8_OUT_EARLY, 2 },
+       { P_GPLL10_OUT_MAIN, 3 },
+       { P_GPLL6_OUT_MAIN, 4 },
+       { P_GPLL9_OUT_MAIN, 5 },
+       { P_GPLL3_OUT_EARLY, 6 },
+};
+
+static const struct clk_parent_data gcc_parents_6[] = {
+       { .fw_name = "bi_tcxo" },
+       { .hw = &gpll0.clkr.hw },
+       { .hw = &gpll8.clkr.hw },
+       { .hw = &gpll10_out_main.clkr.hw },
+       { .hw = &gpll6_out_main.clkr.hw },
+       { .hw = &gpll9_out_main.clkr.hw },
+       { .hw = &gpll3.clkr.hw },
+};
+
+static const struct parent_map gcc_parent_map_7[] = {
+       { P_BI_TCXO, 0 },
+       { P_GPLL0_OUT_EARLY, 1 },
+       { P_GPLL0_OUT_AUX2, 2 },
+       { P_GPLL10_OUT_MAIN, 3 },
+       { P_GPLL4_OUT_MAIN, 5 },
+       { P_GPLL3_OUT_EARLY, 6 },
+};
+
+static const struct clk_parent_data gcc_parents_7[] = {
+       { .fw_name = "bi_tcxo" },
+       { .hw = &gpll0.clkr.hw },
+       { .hw = &gpll0_out_aux2.clkr.hw },
+       { .hw = &gpll10_out_main.clkr.hw },
+       { .hw = &gpll4_out_main.clkr.hw },
+       { .hw = &gpll3.clkr.hw },
+};
+
+static const struct parent_map gcc_parent_map_8[] = {
+       { P_BI_TCXO, 0 },
+       { P_GPLL0_OUT_EARLY, 1 },
+       { P_GPLL8_OUT_EARLY, 2 },
+       { P_GPLL10_OUT_MAIN, 3 },
+       { P_GPLL8_OUT_MAIN, 4 },
+       { P_GPLL9_OUT_MAIN, 5 },
+       { P_GPLL3_OUT_EARLY, 6 },
+};
+
+static const struct clk_parent_data gcc_parents_8[] = {
+       { .fw_name = "bi_tcxo" },
+       { .hw = &gpll0.clkr.hw },
+       { .hw = &gpll8.clkr.hw },
+       { .hw = &gpll10_out_main.clkr.hw },
+       { .hw = &gpll8_out_main.clkr.hw },
+       { .hw = &gpll9_out_main.clkr.hw },
+       { .hw = &gpll3.clkr.hw },
+};
+
+static const struct parent_map gcc_parent_map_9[] = {
+       { P_BI_TCXO, 0 },
+       { P_GPLL0_OUT_EARLY, 1 },
+       { P_GPLL0_OUT_AUX2, 2 },
+       { P_GPLL10_OUT_MAIN, 3 },
+       { P_GPLL8_OUT_MAIN, 4 },
+       { P_GPLL9_OUT_MAIN, 5 },
+       { P_GPLL3_OUT_EARLY, 6 },
+};
+
+static const struct clk_parent_data gcc_parents_9[] = {
+       { .fw_name = "bi_tcxo" },
+       { .hw = &gpll0.clkr.hw },
+       { .hw = &gpll0_out_aux2.clkr.hw },
+       { .hw = &gpll10_out_main.clkr.hw },
+       { .hw = &gpll8_out_main.clkr.hw },
+       { .hw = &gpll9_out_main.clkr.hw },
+       { .hw = &gpll3.clkr.hw },
+};
+
+static const struct parent_map gcc_parent_map_10[] = {
+       { P_BI_TCXO, 0 },
+       { P_GPLL0_OUT_EARLY, 1 },
+       { P_GPLL8_OUT_EARLY, 2 },
+       { P_GPLL10_OUT_MAIN, 3 },
+       { P_GPLL6_OUT_EARLY, 4 },
+       { P_GPLL9_OUT_MAIN, 5 },
+};
+
+static const struct clk_parent_data gcc_parents_10[] = {
+       { .fw_name = "bi_tcxo" },
+       { .hw = &gpll0.clkr.hw },
+       { .hw = &gpll8.clkr.hw },
+       { .hw = &gpll10_out_main.clkr.hw },
+       { .hw = &gpll6.clkr.hw },
+       { .hw = &gpll9_out_main.clkr.hw },
+};
+
+static const struct parent_map gcc_parent_map_11[] = {
+       { P_BI_TCXO, 0 },
+       { P_GPLL0_OUT_EARLY, 1 },
+       { P_GPLL0_OUT_AUX2, 2 },
+       { P_GPLL7_OUT_MAIN, 3 },
+       { P_GPLL4_OUT_MAIN, 5 },
+};
+
+static const struct clk_parent_data gcc_parents_11[] = {
+       { .fw_name = "bi_tcxo" },
+       { .hw = &gpll0.clkr.hw },
+       { .hw = &gpll0_out_aux2.clkr.hw },
+       { .hw = &gpll7_out_main.clkr.hw },
+       { .hw = &gpll4_out_main.clkr.hw },
+};
+
+static const struct parent_map gcc_parent_map_12[] = {
+       { P_BI_TCXO, 0 },
+       { P_SLEEP_CLK, 5 },
+};
+
+static const struct clk_parent_data gcc_parents_12[] = {
+       { .fw_name = "bi_tcxo" },
+       { .fw_name = "sleep_clk" },
+};
+
+static const struct parent_map gcc_parent_map_13[] = {
+       { P_BI_TCXO, 0 },
+       { P_GPLL11_OUT_MAIN, 1 },
+};
+
+static const struct clk_parent_data gcc_parents_13[] = {
+       { .fw_name = "bi_tcxo" },
+       { .hw = &gpll11_out_main.clkr.hw },
+};
+
+static const struct freq_tbl ftbl_gcc_camss_axi_clk_src[] = {
+       F(19200000, P_BI_TCXO, 1, 0, 0),
+       F(150000000, P_GPLL0_OUT_AUX2, 2, 0, 0),
+       F(200000000, P_GPLL0_OUT_AUX2, 1.5, 0, 0),
+       F(300000000, P_GPLL0_OUT_AUX2, 1, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 gcc_camss_axi_clk_src = {
+       .cmd_rcgr = 0x5802c,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_7,
+       .freq_tbl = ftbl_gcc_camss_axi_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_camss_axi_clk_src",
+               .parent_data = gcc_parents_7,
+               .num_parents = ARRAY_SIZE(gcc_parents_7),
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_gcc_camss_cci_clk_src[] = {
+       F(19200000, P_BI_TCXO, 1, 0, 0),
+       F(37500000, P_GPLL0_OUT_AUX2, 8, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 gcc_camss_cci_clk_src = {
+       .cmd_rcgr = 0x56000,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_9,
+       .freq_tbl = ftbl_gcc_camss_cci_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_camss_cci_clk_src",
+               .parent_data = gcc_parents_9,
+               .num_parents = ARRAY_SIZE(gcc_parents_9),
+               .flags = CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_gcc_camss_csi0phytimer_clk_src[] = {
+       F(19200000, P_BI_TCXO, 1, 0, 0),
+       F(100000000, P_GPLL0_OUT_AUX2, 3, 0, 0),
+       F(200000000, P_GPLL0_OUT_AUX2, 1.5, 0, 0),
+       F(268800000, P_GPLL4_OUT_MAIN, 3, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 gcc_camss_csi0phytimer_clk_src = {
+       .cmd_rcgr = 0x59000,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_4,
+       .freq_tbl = ftbl_gcc_camss_csi0phytimer_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_camss_csi0phytimer_clk_src",
+               .parent_data = gcc_parents_4,
+               .num_parents = ARRAY_SIZE(gcc_parents_4),
+               .flags = CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 gcc_camss_csi1phytimer_clk_src = {
+       .cmd_rcgr = 0x5901c,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_4,
+       .freq_tbl = ftbl_gcc_camss_csi0phytimer_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_camss_csi1phytimer_clk_src",
+               .parent_data = gcc_parents_4,
+               .num_parents = ARRAY_SIZE(gcc_parents_4),
+               .flags = CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 gcc_camss_csi2phytimer_clk_src = {
+       .cmd_rcgr = 0x59038,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_4,
+       .freq_tbl = ftbl_gcc_camss_csi0phytimer_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_camss_csi2phytimer_clk_src",
+               .parent_data = gcc_parents_4,
+               .num_parents = ARRAY_SIZE(gcc_parents_4),
+               .flags = CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_gcc_camss_mclk0_clk_src[] = {
+       F(19200000, P_BI_TCXO, 1, 0, 0),
+       F(24000000, P_GPLL9_OUT_MAIN, 1, 1, 24),
+       F(64000000, P_GPLL9_OUT_MAIN, 1, 1, 9),
+       { }
+};
+
+static struct clk_rcg2 gcc_camss_mclk0_clk_src = {
+       .cmd_rcgr = 0x51000,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_3,
+       .freq_tbl = ftbl_gcc_camss_mclk0_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_camss_mclk0_clk_src",
+               .parent_data = gcc_parents_3,
+               .num_parents = ARRAY_SIZE(gcc_parents_3),
+               .flags = CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 gcc_camss_mclk1_clk_src = {
+       .cmd_rcgr = 0x5101c,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_3,
+       .freq_tbl = ftbl_gcc_camss_mclk0_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_camss_mclk1_clk_src",
+               .parent_data = gcc_parents_3,
+               .num_parents = ARRAY_SIZE(gcc_parents_3),
+               .flags = CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 gcc_camss_mclk2_clk_src = {
+       .cmd_rcgr = 0x51038,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_3,
+       .freq_tbl = ftbl_gcc_camss_mclk0_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_camss_mclk2_clk_src",
+               .parent_data = gcc_parents_3,
+               .num_parents = ARRAY_SIZE(gcc_parents_3),
+               .flags = CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 gcc_camss_mclk3_clk_src = {
+       .cmd_rcgr = 0x51054,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_3,
+       .freq_tbl = ftbl_gcc_camss_mclk0_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_camss_mclk3_clk_src",
+               .parent_data = gcc_parents_3,
+               .num_parents = ARRAY_SIZE(gcc_parents_3),
+               .flags = CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_gcc_camss_ope_ahb_clk_src[] = {
+       F(19200000, P_BI_TCXO, 1, 0, 0),
+       F(171428571, P_GPLL0_OUT_EARLY, 3.5, 0, 0),
+       F(240000000, P_GPLL0_OUT_EARLY, 2.5, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 gcc_camss_ope_ahb_clk_src = {
+       .cmd_rcgr = 0x55024,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_8,
+       .freq_tbl = ftbl_gcc_camss_ope_ahb_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_camss_ope_ahb_clk_src",
+               .parent_data = gcc_parents_8,
+               .num_parents = ARRAY_SIZE(gcc_parents_8),
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_gcc_camss_ope_clk_src[] = {
+       F(19200000, P_BI_TCXO, 1, 0, 0),
+       F(200000000, P_GPLL8_OUT_MAIN, 2, 0, 0),
+       F(266600000, P_GPLL8_OUT_MAIN, 1, 0, 0),
+       F(465000000, P_GPLL8_OUT_MAIN, 1, 0, 0),
+       F(576000000, P_GPLL9_OUT_MAIN, 1, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 gcc_camss_ope_clk_src = {
+       .cmd_rcgr = 0x55004,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_8,
+       .freq_tbl = ftbl_gcc_camss_ope_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_camss_ope_clk_src",
+               .parent_data = gcc_parents_8,
+               .num_parents = ARRAY_SIZE(gcc_parents_8),
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_gcc_camss_tfe_0_clk_src[] = {
+       F(19200000, P_BI_TCXO, 1, 0, 0),
+       F(128000000, P_GPLL10_OUT_MAIN, 9, 0, 0),
+       F(135529412, P_GPLL10_OUT_MAIN, 8.5, 0, 0),
+       F(144000000, P_GPLL10_OUT_MAIN, 8, 0, 0),
+       F(153600000, P_GPLL10_OUT_MAIN, 7.5, 0, 0),
+       F(164571429, P_GPLL10_OUT_MAIN, 7, 0, 0),
+       F(177230769, P_GPLL10_OUT_MAIN, 6.5, 0, 0),
+       F(192000000, P_GPLL10_OUT_MAIN, 6, 0, 0),
+       F(209454545, P_GPLL10_OUT_MAIN, 5.5, 0, 0),
+       F(230400000, P_GPLL10_OUT_MAIN, 5, 0, 0),
+       F(256000000, P_GPLL10_OUT_MAIN, 4.5, 0, 0),
+       F(288000000, P_GPLL10_OUT_MAIN, 4, 0, 0),
+       F(329142857, P_GPLL10_OUT_MAIN, 3.5, 0, 0),
+       F(384000000, P_GPLL10_OUT_MAIN, 3, 0, 0),
+       F(460800000, P_GPLL10_OUT_MAIN, 2.5, 0, 0),
+       F(576000000, P_GPLL10_OUT_MAIN, 2, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 gcc_camss_tfe_0_clk_src = {
+       .cmd_rcgr = 0x52004,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_5,
+       .freq_tbl = ftbl_gcc_camss_tfe_0_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_camss_tfe_0_clk_src",
+               .parent_data = gcc_parents_5,
+               .num_parents = ARRAY_SIZE(gcc_parents_5),
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_gcc_camss_tfe_0_csid_clk_src[] = {
+       F(19200000, P_BI_TCXO, 1, 0, 0),
+       F(120000000, P_GPLL0_OUT_EARLY, 5, 0, 0),
+       F(192000000, P_GPLL6_OUT_MAIN, 2, 0, 0),
+       F(240000000, P_GPLL0_OUT_EARLY, 2.5, 0, 0),
+       F(384000000, P_GPLL6_OUT_MAIN, 1, 0, 0),
+       F(426400000, P_GPLL3_OUT_EARLY, 2.5, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 gcc_camss_tfe_0_csid_clk_src = {
+       .cmd_rcgr = 0x52094,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_6,
+       .freq_tbl = ftbl_gcc_camss_tfe_0_csid_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_camss_tfe_0_csid_clk_src",
+               .parent_data = gcc_parents_6,
+               .num_parents = ARRAY_SIZE(gcc_parents_6),
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 gcc_camss_tfe_1_clk_src = {
+       .cmd_rcgr = 0x52024,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_5,
+       .freq_tbl = ftbl_gcc_camss_tfe_0_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_camss_tfe_1_clk_src",
+               .parent_data = gcc_parents_5,
+               .num_parents = ARRAY_SIZE(gcc_parents_5),
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 gcc_camss_tfe_1_csid_clk_src = {
+       .cmd_rcgr = 0x520b4,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_6,
+       .freq_tbl = ftbl_gcc_camss_tfe_0_csid_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_camss_tfe_1_csid_clk_src",
+               .parent_data = gcc_parents_6,
+               .num_parents = ARRAY_SIZE(gcc_parents_6),
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 gcc_camss_tfe_2_clk_src = {
+       .cmd_rcgr = 0x52044,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_5,
+       .freq_tbl = ftbl_gcc_camss_tfe_0_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_camss_tfe_2_clk_src",
+               .parent_data = gcc_parents_5,
+               .num_parents = ARRAY_SIZE(gcc_parents_5),
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 gcc_camss_tfe_2_csid_clk_src = {
+       .cmd_rcgr = 0x520d4,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_6,
+       .freq_tbl = ftbl_gcc_camss_tfe_0_csid_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_camss_tfe_2_csid_clk_src",
+               .parent_data = gcc_parents_6,
+               .num_parents = ARRAY_SIZE(gcc_parents_6),
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_gcc_camss_tfe_cphy_rx_clk_src[] = {
+       F(19200000, P_BI_TCXO, 1, 0, 0),
+       F(240000000, P_GPLL0_OUT_EARLY, 2.5, 0, 0),
+       F(341333333, P_GPLL6_OUT_EARLY, 1, 4, 9),
+       F(384000000, P_GPLL6_OUT_EARLY, 2, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 gcc_camss_tfe_cphy_rx_clk_src = {
+       .cmd_rcgr = 0x52064,
+       .mnd_width = 16,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_10,
+       .freq_tbl = ftbl_gcc_camss_tfe_cphy_rx_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_camss_tfe_cphy_rx_clk_src",
+               .parent_data = gcc_parents_10,
+               .num_parents = ARRAY_SIZE(gcc_parents_10),
+               .flags = CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_gcc_camss_top_ahb_clk_src[] = {
+       F(19200000, P_BI_TCXO, 1, 0, 0),
+       F(40000000, P_GPLL0_OUT_AUX2, 7.5, 0, 0),
+       F(80000000, P_GPLL0_OUT_EARLY, 7.5, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 gcc_camss_top_ahb_clk_src = {
+       .cmd_rcgr = 0x58010,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_7,
+       .freq_tbl = ftbl_gcc_camss_top_ahb_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_camss_top_ahb_clk_src",
+               .parent_data = gcc_parents_7,
+               .num_parents = ARRAY_SIZE(gcc_parents_7),
+               .flags = CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_gcc_gp1_clk_src[] = {
+       F(25000000, P_GPLL0_OUT_AUX2, 12, 0, 0),
+       F(50000000, P_GPLL0_OUT_AUX2, 6, 0, 0),
+       F(100000000, P_GPLL0_OUT_AUX2, 3, 0, 0),
+       F(200000000, P_GPLL0_OUT_AUX2, 1.5, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 gcc_gp1_clk_src = {
+       .cmd_rcgr = 0x4d004,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_2,
+       .freq_tbl = ftbl_gcc_gp1_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_gp1_clk_src",
+               .parent_data = gcc_parents_2,
+               .num_parents = ARRAY_SIZE(gcc_parents_2),
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 gcc_gp2_clk_src = {
+       .cmd_rcgr = 0x4e004,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_2,
+       .freq_tbl = ftbl_gcc_gp1_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_gp2_clk_src",
+               .parent_data = gcc_parents_2,
+               .num_parents = ARRAY_SIZE(gcc_parents_2),
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 gcc_gp3_clk_src = {
+       .cmd_rcgr = 0x4f004,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_2,
+       .freq_tbl = ftbl_gcc_gp1_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_gp3_clk_src",
+               .parent_data = gcc_parents_2,
+               .num_parents = ARRAY_SIZE(gcc_parents_2),
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_gcc_pdm2_clk_src[] = {
+       F(19200000, P_BI_TCXO, 1, 0, 0),
+       F(60000000, P_GPLL0_OUT_AUX2, 5, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 gcc_pdm2_clk_src = {
+       .cmd_rcgr = 0x20010,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_0,
+       .freq_tbl = ftbl_gcc_pdm2_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_pdm2_clk_src",
+               .parent_data = gcc_parents_0,
+               .num_parents = ARRAY_SIZE(gcc_parents_0),
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_gcc_qupv3_wrap0_s0_clk_src[] = {
+       F(7372800, P_GPLL0_OUT_AUX2, 1, 384, 15625),
+       F(14745600, P_GPLL0_OUT_AUX2, 1, 768, 15625),
+       F(19200000, P_BI_TCXO, 1, 0, 0),
+       F(29491200, P_GPLL0_OUT_AUX2, 1, 1536, 15625),
+       F(32000000, P_GPLL0_OUT_AUX2, 1, 8, 75),
+       F(48000000, P_GPLL0_OUT_AUX2, 1, 4, 25),
+       F(64000000, P_GPLL0_OUT_AUX2, 1, 16, 75),
+       F(75000000, P_GPLL0_OUT_AUX2, 4, 0, 0),
+       F(80000000, P_GPLL0_OUT_AUX2, 1, 4, 15),
+       F(96000000, P_GPLL0_OUT_AUX2, 1, 8, 25),
+       F(100000000, P_GPLL0_OUT_AUX2, 3, 0, 0),
+       F(102400000, P_GPLL0_OUT_AUX2, 1, 128, 375),
+       F(112000000, P_GPLL0_OUT_AUX2, 1, 28, 75),
+       F(117964800, P_GPLL0_OUT_AUX2, 1, 6144, 15625),
+       F(120000000, P_GPLL0_OUT_AUX2, 2.5, 0, 0),
+       F(128000000, P_GPLL6_OUT_MAIN, 3, 0, 0),
+       { }
+};
+
+static struct clk_init_data gcc_qupv3_wrap0_s0_clk_src_init = {
+       .name = "gcc_qupv3_wrap0_s0_clk_src",
+       .parent_data = gcc_parents_1,
+       .num_parents = ARRAY_SIZE(gcc_parents_1),
+       .ops = &clk_rcg2_ops,
+};
+
+static struct clk_rcg2 gcc_qupv3_wrap0_s0_clk_src = {
+       .cmd_rcgr = 0x1f148,
+       .mnd_width = 16,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_1,
+       .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
+       .clkr.hw.init = &gcc_qupv3_wrap0_s0_clk_src_init,
+};
+
+static struct clk_init_data gcc_qupv3_wrap0_s1_clk_src_init = {
+       .name = "gcc_qupv3_wrap0_s1_clk_src",
+       .parent_data = gcc_parents_1,
+       .num_parents = ARRAY_SIZE(gcc_parents_1),
+       .ops = &clk_rcg2_ops,
+};
+
+static struct clk_rcg2 gcc_qupv3_wrap0_s1_clk_src = {
+       .cmd_rcgr = 0x1f278,
+       .mnd_width = 16,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_1,
+       .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
+       .clkr.hw.init = &gcc_qupv3_wrap0_s1_clk_src_init,
+};
+
+static struct clk_init_data gcc_qupv3_wrap0_s2_clk_src_init = {
+       .name = "gcc_qupv3_wrap0_s2_clk_src",
+       .parent_data = gcc_parents_1,
+       .num_parents = ARRAY_SIZE(gcc_parents_1),
+       .ops = &clk_rcg2_ops,
+};
+
+static struct clk_rcg2 gcc_qupv3_wrap0_s2_clk_src = {
+       .cmd_rcgr = 0x1f3a8,
+       .mnd_width = 16,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_1,
+       .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
+       .clkr.hw.init = &gcc_qupv3_wrap0_s2_clk_src_init,
+};
+
+static struct clk_init_data gcc_qupv3_wrap0_s3_clk_src_init = {
+       .name = "gcc_qupv3_wrap0_s3_clk_src",
+       .parent_data = gcc_parents_1,
+       .num_parents = ARRAY_SIZE(gcc_parents_1),
+       .ops = &clk_rcg2_ops,
+};
+
+static struct clk_rcg2 gcc_qupv3_wrap0_s3_clk_src = {
+       .cmd_rcgr = 0x1f4d8,
+       .mnd_width = 16,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_1,
+       .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
+       .clkr.hw.init = &gcc_qupv3_wrap0_s3_clk_src_init,
+};
+
+static struct clk_init_data gcc_qupv3_wrap0_s4_clk_src_init = {
+       .name = "gcc_qupv3_wrap0_s4_clk_src",
+       .parent_data = gcc_parents_1,
+       .num_parents = ARRAY_SIZE(gcc_parents_1),
+       .ops = &clk_rcg2_ops,
+};
+
+static struct clk_rcg2 gcc_qupv3_wrap0_s4_clk_src = {
+       .cmd_rcgr = 0x1f608,
+       .mnd_width = 16,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_1,
+       .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
+       .clkr.hw.init = &gcc_qupv3_wrap0_s4_clk_src_init,
+};
+
+static struct clk_init_data gcc_qupv3_wrap0_s5_clk_src_init = {
+       .name = "gcc_qupv3_wrap0_s5_clk_src",
+       .parent_data = gcc_parents_1,
+       .num_parents = ARRAY_SIZE(gcc_parents_1),
+       .ops = &clk_rcg2_ops,
+};
+
+static struct clk_rcg2 gcc_qupv3_wrap0_s5_clk_src = {
+       .cmd_rcgr = 0x1f738,
+       .mnd_width = 16,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_1,
+       .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
+       .clkr.hw.init = &gcc_qupv3_wrap0_s5_clk_src_init,
+};
+
+static const struct freq_tbl ftbl_gcc_sdcc1_apps_clk_src[] = {
+       F(144000, P_BI_TCXO, 16, 3, 25),
+       F(400000, P_BI_TCXO, 12, 1, 4),
+       F(20000000, P_GPLL0_OUT_AUX2, 5, 1, 3),
+       F(25000000, P_GPLL0_OUT_AUX2, 6, 1, 2),
+       F(50000000, P_GPLL0_OUT_AUX2, 6, 0, 0),
+       F(100000000, P_GPLL0_OUT_AUX2, 3, 0, 0),
+       F(192000000, P_GPLL6_OUT_MAIN, 2, 0, 0),
+       F(384000000, P_GPLL6_OUT_MAIN, 1, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 gcc_sdcc1_apps_clk_src = {
+       .cmd_rcgr = 0x38028,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_1,
+       .freq_tbl = ftbl_gcc_sdcc1_apps_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_sdcc1_apps_clk_src",
+               .parent_data = gcc_parents_1,
+               .num_parents = ARRAY_SIZE(gcc_parents_1),
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_gcc_sdcc1_ice_core_clk_src[] = {
+       F(75000000, P_GPLL0_OUT_AUX2, 4, 0, 0),
+       F(100000000, P_GPLL0_OUT_AUX2, 3, 0, 0),
+       F(150000000, P_GPLL0_OUT_AUX2, 2, 0, 0),
+       F(200000000, P_GPLL0_OUT_EARLY, 3, 0, 0),
+       F(300000000, P_GPLL0_OUT_AUX2, 1, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 gcc_sdcc1_ice_core_clk_src = {
+       .cmd_rcgr = 0x38010,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_0,
+       .freq_tbl = ftbl_gcc_sdcc1_ice_core_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_sdcc1_ice_core_clk_src",
+               .parent_data = gcc_parents_0,
+               .num_parents = ARRAY_SIZE(gcc_parents_0),
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_gcc_sdcc2_apps_clk_src[] = {
+       F(400000, P_BI_TCXO, 12, 1, 4),
+       F(19200000, P_BI_TCXO, 1, 0, 0),
+       F(25000000, P_GPLL0_OUT_AUX2, 12, 0, 0),
+       F(50000000, P_GPLL0_OUT_AUX2, 6, 0, 0),
+       F(100000000, P_GPLL0_OUT_AUX2, 3, 0, 0),
+       F(200000000, P_GPLL0_OUT_EARLY, 3, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 gcc_sdcc2_apps_clk_src = {
+       .cmd_rcgr = 0x1e00c,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_11,
+       .freq_tbl = ftbl_gcc_sdcc2_apps_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_sdcc2_apps_clk_src",
+               .parent_data = gcc_parents_11,
+               .num_parents = ARRAY_SIZE(gcc_parents_11),
+               .ops = &clk_rcg2_ops,
+               .flags = CLK_OPS_PARENT_ENABLE,
+       },
+};
+
+static const struct freq_tbl ftbl_gcc_ufs_phy_axi_clk_src[] = {
+       F(25000000, P_GPLL0_OUT_AUX2, 12, 0, 0),
+       F(50000000, P_GPLL0_OUT_AUX2, 6, 0, 0),
+       F(100000000, P_GPLL0_OUT_AUX2, 3, 0, 0),
+       F(200000000, P_GPLL0_OUT_EARLY, 3, 0, 0),
+       F(240000000, P_GPLL0_OUT_EARLY, 2.5, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 gcc_ufs_phy_axi_clk_src = {
+       .cmd_rcgr = 0x45020,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_0,
+       .freq_tbl = ftbl_gcc_ufs_phy_axi_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_ufs_phy_axi_clk_src",
+               .parent_data = gcc_parents_0,
+               .num_parents = ARRAY_SIZE(gcc_parents_0),
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_gcc_ufs_phy_ice_core_clk_src[] = {
+       F(37500000, P_GPLL0_OUT_AUX2, 8, 0, 0),
+       F(75000000, P_GPLL0_OUT_AUX2, 4, 0, 0),
+       F(150000000, P_GPLL0_OUT_AUX2, 2, 0, 0),
+       F(300000000, P_GPLL0_OUT_AUX2, 1, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 gcc_ufs_phy_ice_core_clk_src = {
+       .cmd_rcgr = 0x45048,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_0,
+       .freq_tbl = ftbl_gcc_ufs_phy_ice_core_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_ufs_phy_ice_core_clk_src",
+               .parent_data = gcc_parents_0,
+               .num_parents = ARRAY_SIZE(gcc_parents_0),
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_gcc_ufs_phy_phy_aux_clk_src[] = {
+       F(9600000, P_BI_TCXO, 2, 0, 0),
+       F(19200000, P_BI_TCXO, 1, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 gcc_ufs_phy_phy_aux_clk_src = {
+       .cmd_rcgr = 0x4507c,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_0,
+       .freq_tbl = ftbl_gcc_ufs_phy_phy_aux_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_ufs_phy_phy_aux_clk_src",
+               .parent_data = gcc_parents_0,
+               .num_parents = ARRAY_SIZE(gcc_parents_0),
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_gcc_ufs_phy_unipro_core_clk_src[] = {
+       F(37500000, P_GPLL0_OUT_AUX2, 8, 0, 0),
+       F(75000000, P_GPLL0_OUT_AUX2, 4, 0, 0),
+       F(150000000, P_GPLL0_OUT_AUX2, 2, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 gcc_ufs_phy_unipro_core_clk_src = {
+       .cmd_rcgr = 0x45060,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_0,
+       .freq_tbl = ftbl_gcc_ufs_phy_unipro_core_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_ufs_phy_unipro_core_clk_src",
+               .parent_data = gcc_parents_0,
+               .num_parents = ARRAY_SIZE(gcc_parents_0),
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_gcc_usb30_prim_master_clk_src[] = {
+       F(66666667, P_GPLL0_OUT_AUX2, 4.5, 0, 0),
+       F(133333333, P_GPLL0_OUT_EARLY, 4.5, 0, 0),
+       F(200000000, P_GPLL0_OUT_EARLY, 3, 0, 0),
+       F(240000000, P_GPLL0_OUT_EARLY, 2.5, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 gcc_usb30_prim_master_clk_src = {
+       .cmd_rcgr = 0x1a01c,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_0,
+       .freq_tbl = ftbl_gcc_usb30_prim_master_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_usb30_prim_master_clk_src",
+               .parent_data = gcc_parents_0,
+               .num_parents = ARRAY_SIZE(gcc_parents_0),
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_gcc_usb30_prim_mock_utmi_clk_src[] = {
+       F(19200000, P_BI_TCXO, 1, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 gcc_usb30_prim_mock_utmi_clk_src = {
+       .cmd_rcgr = 0x1a034,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_0,
+       .freq_tbl = ftbl_gcc_usb30_prim_mock_utmi_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_usb30_prim_mock_utmi_clk_src",
+               .parent_data = gcc_parents_0,
+               .num_parents = ARRAY_SIZE(gcc_parents_0),
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_regmap_div gcc_usb30_prim_mock_utmi_postdiv_clk_src = {
+       .reg = 0x1a04c,
+       .shift = 0,
+       .width = 2,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "gcc_usb30_prim_mock_utmi_postdiv_clk_src",
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gcc_usb30_prim_mock_utmi_clk_src.clkr.hw },
+               .num_parents = 1,
+               .ops = &clk_regmap_div_ro_ops,
+       },
+};
+
+static struct clk_rcg2 gcc_usb3_prim_phy_aux_clk_src = {
+       .cmd_rcgr = 0x1a060,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_12,
+       .freq_tbl = ftbl_gcc_usb30_prim_mock_utmi_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_usb3_prim_phy_aux_clk_src",
+               .parent_data = gcc_parents_12,
+               .num_parents = ARRAY_SIZE(gcc_parents_12),
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_gcc_video_venus_clk_src[] = {
+       F(133333333, P_GPLL11_OUT_MAIN, 4.5, 0, 0),
+       F(240000000, P_GPLL11_OUT_MAIN, 2.5, 0, 0),
+       F(300000000, P_GPLL11_OUT_MAIN, 2, 0, 0),
+       F(384000000, P_GPLL11_OUT_MAIN, 2, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 gcc_video_venus_clk_src = {
+       .cmd_rcgr = 0x58060,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_13,
+       .freq_tbl = ftbl_gcc_video_venus_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_video_venus_clk_src",
+               .parent_data = gcc_parents_13,
+               .num_parents = ARRAY_SIZE(gcc_parents_13),
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_branch gcc_ahb2phy_csi_clk = {
+       .halt_reg = 0x1d004,
+       .halt_check = BRANCH_HALT,
+       .hwcg_reg = 0x1d004,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x1d004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_ahb2phy_csi_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_ahb2phy_usb_clk = {
+       .halt_reg = 0x1d008,
+       .halt_check = BRANCH_HALT,
+       .hwcg_reg = 0x1d008,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x1d008,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_ahb2phy_usb_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_bimc_gpu_axi_clk = {
+       .halt_reg = 0x71154,
+       .halt_check = BRANCH_HALT_DELAY,
+       .hwcg_reg = 0x71154,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x71154,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_bimc_gpu_axi_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_boot_rom_ahb_clk = {
+       .halt_reg = 0x23004,
+       .halt_check = BRANCH_HALT_VOTED,
+       .hwcg_reg = 0x23004,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x79004,
+               .enable_mask = BIT(10),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_boot_rom_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_cam_throttle_nrt_clk = {
+       .halt_reg = 0x17070,
+       .halt_check = BRANCH_HALT_VOTED,
+       .hwcg_reg = 0x17070,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x79004,
+               .enable_mask = BIT(27),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_cam_throttle_nrt_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_cam_throttle_rt_clk = {
+       .halt_reg = 0x1706c,
+       .halt_check = BRANCH_HALT_VOTED,
+       .hwcg_reg = 0x1706c,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x79004,
+               .enable_mask = BIT(26),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_cam_throttle_rt_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_camera_ahb_clk = {
+       .halt_reg = 0x17008,
+       .halt_check = BRANCH_HALT_DELAY,
+       .hwcg_reg = 0x17008,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x17008,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_camera_ahb_clk",
+                       .flags = CLK_IS_CRITICAL,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_camera_xo_clk = {
+       .halt_reg = 0x17028,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x17028,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_camera_xo_clk",
+                       .flags = CLK_IS_CRITICAL,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_camss_axi_clk = {
+       .halt_reg = 0x58044,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x58044,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_camss_axi_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                               &gcc_camss_axi_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_camss_camnoc_atb_clk = {
+       .halt_reg = 0x5804c,
+       .halt_check = BRANCH_HALT_DELAY,
+       .hwcg_reg = 0x5804c,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x5804c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_camss_camnoc_atb_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_camss_camnoc_nts_xo_clk = {
+       .halt_reg = 0x58050,
+       .halt_check = BRANCH_HALT_DELAY,
+       .hwcg_reg = 0x58050,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x58050,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_camss_camnoc_nts_xo_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_camss_cci_0_clk = {
+       .halt_reg = 0x56018,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x56018,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_camss_cci_0_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                               &gcc_camss_cci_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_camss_cphy_0_clk = {
+       .halt_reg = 0x52088,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x52088,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_camss_cphy_0_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                               &gcc_camss_tfe_cphy_rx_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_camss_cphy_1_clk = {
+       .halt_reg = 0x5208c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x5208c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_camss_cphy_1_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                               &gcc_camss_tfe_cphy_rx_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_camss_cphy_2_clk = {
+       .halt_reg = 0x52090,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x52090,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_camss_cphy_2_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                               &gcc_camss_tfe_cphy_rx_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_camss_csi0phytimer_clk = {
+       .halt_reg = 0x59018,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x59018,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_camss_csi0phytimer_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                               &gcc_camss_csi0phytimer_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_camss_csi1phytimer_clk = {
+       .halt_reg = 0x59034,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x59034,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_camss_csi1phytimer_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                               &gcc_camss_csi1phytimer_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_camss_csi2phytimer_clk = {
+       .halt_reg = 0x59050,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x59050,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_camss_csi2phytimer_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                               &gcc_camss_csi2phytimer_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_camss_mclk0_clk = {
+       .halt_reg = 0x51018,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x51018,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_camss_mclk0_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                               &gcc_camss_mclk0_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_camss_mclk1_clk = {
+       .halt_reg = 0x51034,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x51034,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_camss_mclk1_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                               &gcc_camss_mclk1_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_camss_mclk2_clk = {
+       .halt_reg = 0x51050,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x51050,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_camss_mclk2_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                               &gcc_camss_mclk2_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_camss_mclk3_clk = {
+       .halt_reg = 0x5106c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x5106c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_camss_mclk3_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                               &gcc_camss_mclk3_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_camss_nrt_axi_clk = {
+       .halt_reg = 0x58054,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x58054,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_camss_nrt_axi_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_camss_ope_ahb_clk = {
+       .halt_reg = 0x5503c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x5503c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_camss_ope_ahb_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                               &gcc_camss_ope_ahb_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_camss_ope_clk = {
+       .halt_reg = 0x5501c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x5501c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_camss_ope_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                               &gcc_camss_ope_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_camss_rt_axi_clk = {
+       .halt_reg = 0x5805c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x5805c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_camss_rt_axi_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_camss_tfe_0_clk = {
+       .halt_reg = 0x5201c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x5201c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_camss_tfe_0_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                               &gcc_camss_tfe_0_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_camss_tfe_0_cphy_rx_clk = {
+       .halt_reg = 0x5207c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x5207c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_camss_tfe_0_cphy_rx_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                               &gcc_camss_tfe_cphy_rx_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_camss_tfe_0_csid_clk = {
+       .halt_reg = 0x520ac,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x520ac,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_camss_tfe_0_csid_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                               &gcc_camss_tfe_0_csid_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_camss_tfe_1_clk = {
+       .halt_reg = 0x5203c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x5203c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_camss_tfe_1_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                               &gcc_camss_tfe_1_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_camss_tfe_1_cphy_rx_clk = {
+       .halt_reg = 0x52080,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x52080,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_camss_tfe_1_cphy_rx_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                               &gcc_camss_tfe_cphy_rx_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_camss_tfe_1_csid_clk = {
+       .halt_reg = 0x520cc,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x520cc,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_camss_tfe_1_csid_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                               &gcc_camss_tfe_1_csid_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_camss_tfe_2_clk = {
+       .halt_reg = 0x5205c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x5205c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_camss_tfe_2_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                               &gcc_camss_tfe_2_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_camss_tfe_2_cphy_rx_clk = {
+       .halt_reg = 0x52084,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x52084,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_camss_tfe_2_cphy_rx_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                               &gcc_camss_tfe_cphy_rx_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_camss_tfe_2_csid_clk = {
+       .halt_reg = 0x520ec,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x520ec,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_camss_tfe_2_csid_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                               &gcc_camss_tfe_2_csid_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_camss_top_ahb_clk = {
+       .halt_reg = 0x58028,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x58028,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_camss_top_ahb_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                               &gcc_camss_top_ahb_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_cfg_noc_usb3_prim_axi_clk = {
+       .halt_reg = 0x1a084,
+       .halt_check = BRANCH_HALT,
+       .hwcg_reg = 0x1a084,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x1a084,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_cfg_noc_usb3_prim_axi_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                               &gcc_usb30_prim_master_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_cpuss_gnoc_clk = {
+       .halt_reg = 0x2b004,
+       .halt_check = BRANCH_HALT_VOTED,
+       .hwcg_reg = 0x2b004,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x79004,
+               .enable_mask = BIT(22),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_cpuss_gnoc_clk",
+                       .flags = CLK_IS_CRITICAL,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_disp_ahb_clk = {
+       .halt_reg = 0x1700c,
+       .halt_check = BRANCH_HALT,
+       .hwcg_reg = 0x1700c,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x1700c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_disp_ahb_clk",
+                       .flags = CLK_IS_CRITICAL,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_regmap_div gcc_disp_gpll0_clk_src = {
+       .reg = 0x17058,
+       .shift = 0,
+       .width = 2,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "gcc_disp_gpll0_clk_src",
+               .parent_hws = (const struct clk_hw *[]){ &gpll0.clkr.hw },
+               .num_parents = 1,
+               .ops = &clk_regmap_div_ops,
+       },
+};
+
+static struct clk_branch gcc_disp_gpll0_div_clk_src = {
+       .halt_check = BRANCH_HALT_DELAY,
+       .clkr = {
+               .enable_reg = 0x79004,
+               .enable_mask = BIT(20),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_disp_gpll0_div_clk_src",
+                       .parent_hws = (const struct clk_hw *[]){
+                               &gcc_disp_gpll0_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_disp_hf_axi_clk = {
+       .halt_reg = 0x17020,
+       .halt_check = BRANCH_HALT,
+       .hwcg_reg = 0x17020,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x17020,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_disp_hf_axi_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_disp_throttle_core_clk = {
+       .halt_reg = 0x17064,
+       .halt_check = BRANCH_HALT_VOTED,
+       .hwcg_reg = 0x17064,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x7900c,
+               .enable_mask = BIT(5),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_disp_throttle_core_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_disp_xo_clk = {
+       .halt_reg = 0x1702c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x1702c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_disp_xo_clk",
+                       .flags = CLK_IS_CRITICAL,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_gp1_clk = {
+       .halt_reg = 0x4d000,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x4d000,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_gp1_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                               &gcc_gp1_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_gp2_clk = {
+       .halt_reg = 0x4e000,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x4e000,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_gp2_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                               &gcc_gp2_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_gp3_clk = {
+       .halt_reg = 0x4f000,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x4f000,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_gp3_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                               &gcc_gp3_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_gpu_cfg_ahb_clk = {
+       .halt_reg = 0x36004,
+       .halt_check = BRANCH_HALT,
+       .hwcg_reg = 0x36004,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x36004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_gpu_cfg_ahb_clk",
+                       .flags = CLK_IS_CRITICAL,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_gpu_gpll0_clk_src = {
+       .halt_check = BRANCH_HALT_DELAY,
+       .clkr = {
+               .enable_reg = 0x79004,
+               .enable_mask = BIT(15),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_gpu_gpll0_clk_src",
+                       .parent_hws = (const struct clk_hw *[]){
+                               &gpll0.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_gpu_gpll0_div_clk_src = {
+       .halt_check = BRANCH_HALT_DELAY,
+       .clkr = {
+               .enable_reg = 0x79004,
+               .enable_mask = BIT(16),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_gpu_gpll0_div_clk_src",
+                       .parent_hws = (const struct clk_hw *[]){
+                               &gpll0_out_aux2.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_gpu_iref_clk = {
+       .halt_reg = 0x36100,
+       .halt_check = BRANCH_HALT_DELAY,
+       .clkr = {
+               .enable_reg = 0x36100,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_gpu_iref_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_gpu_memnoc_gfx_clk = {
+       .halt_reg = 0x3600c,
+       .halt_check = BRANCH_VOTED,
+       .hwcg_reg = 0x3600c,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x3600c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_gpu_memnoc_gfx_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_gpu_snoc_dvm_gfx_clk = {
+       .halt_reg = 0x36018,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x36018,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_gpu_snoc_dvm_gfx_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_gpu_throttle_core_clk = {
+       .halt_reg = 0x36048,
+       .halt_check = BRANCH_HALT_VOTED,
+       .hwcg_reg = 0x36048,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x79004,
+               .enable_mask = BIT(31),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_gpu_throttle_core_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_pdm2_clk = {
+       .halt_reg = 0x2000c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x2000c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_pdm2_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                               &gcc_pdm2_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_pdm_ahb_clk = {
+       .halt_reg = 0x20004,
+       .halt_check = BRANCH_HALT,
+       .hwcg_reg = 0x20004,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x20004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_pdm_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_pdm_xo4_clk = {
+       .halt_reg = 0x20008,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x20008,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_pdm_xo4_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_prng_ahb_clk = {
+       .halt_reg = 0x21004,
+       .halt_check = BRANCH_HALT_VOTED,
+       .hwcg_reg = 0x21004,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x79004,
+               .enable_mask = BIT(13),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_prng_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_qmip_camera_nrt_ahb_clk = {
+       .halt_reg = 0x17014,
+       .halt_check = BRANCH_HALT_VOTED,
+       .hwcg_reg = 0x17014,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x7900c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qmip_camera_nrt_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_qmip_camera_rt_ahb_clk = {
+       .halt_reg = 0x17060,
+       .halt_check = BRANCH_HALT_VOTED,
+       .hwcg_reg = 0x17060,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x7900c,
+               .enable_mask = BIT(2),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qmip_camera_rt_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_qmip_disp_ahb_clk = {
+       .halt_reg = 0x17018,
+       .halt_check = BRANCH_HALT_VOTED,
+       .hwcg_reg = 0x17018,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x7900c,
+               .enable_mask = BIT(1),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qmip_disp_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_qmip_gpu_cfg_ahb_clk = {
+       .halt_reg = 0x36040,
+       .halt_check = BRANCH_HALT_VOTED,
+       .hwcg_reg = 0x36040,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x7900c,
+               .enable_mask = BIT(4),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qmip_gpu_cfg_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_qmip_video_vcodec_ahb_clk = {
+       .halt_reg = 0x17010,
+       .halt_check = BRANCH_HALT_VOTED,
+       .hwcg_reg = 0x17010,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x79004,
+               .enable_mask = BIT(25),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qmip_video_vcodec_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_qupv3_wrap0_core_2x_clk = {
+       .halt_reg = 0x1f014,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x7900c,
+               .enable_mask = BIT(9),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qupv3_wrap0_core_2x_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_qupv3_wrap0_core_clk = {
+       .halt_reg = 0x1f00c,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x7900c,
+               .enable_mask = BIT(8),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qupv3_wrap0_core_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_qupv3_wrap0_s0_clk = {
+       .halt_reg = 0x1f144,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x7900c,
+               .enable_mask = BIT(10),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qupv3_wrap0_s0_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                               &gcc_qupv3_wrap0_s0_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_qupv3_wrap0_s1_clk = {
+       .halt_reg = 0x1f274,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x7900c,
+               .enable_mask = BIT(11),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qupv3_wrap0_s1_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                               &gcc_qupv3_wrap0_s1_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_qupv3_wrap0_s2_clk = {
+       .halt_reg = 0x1f3a4,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x7900c,
+               .enable_mask = BIT(12),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qupv3_wrap0_s2_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                               &gcc_qupv3_wrap0_s2_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_qupv3_wrap0_s3_clk = {
+       .halt_reg = 0x1f4d4,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x7900c,
+               .enable_mask = BIT(13),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qupv3_wrap0_s3_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                               &gcc_qupv3_wrap0_s3_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_qupv3_wrap0_s4_clk = {
+       .halt_reg = 0x1f604,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x7900c,
+               .enable_mask = BIT(14),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qupv3_wrap0_s4_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                               &gcc_qupv3_wrap0_s4_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_qupv3_wrap0_s5_clk = {
+       .halt_reg = 0x1f734,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x7900c,
+               .enable_mask = BIT(15),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qupv3_wrap0_s5_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                               &gcc_qupv3_wrap0_s5_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_qupv3_wrap_0_m_ahb_clk = {
+       .halt_reg = 0x1f004,
+       .halt_check = BRANCH_HALT_VOTED,
+       .hwcg_reg = 0x1f004,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x7900c,
+               .enable_mask = BIT(6),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qupv3_wrap_0_m_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_qupv3_wrap_0_s_ahb_clk = {
+       .halt_reg = 0x1f008,
+       .halt_check = BRANCH_HALT_VOTED,
+       .hwcg_reg = 0x1f008,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x7900c,
+               .enable_mask = BIT(7),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qupv3_wrap_0_s_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_sdcc1_ahb_clk = {
+       .halt_reg = 0x38008,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x38008,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_sdcc1_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_sdcc1_apps_clk = {
+       .halt_reg = 0x38004,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x38004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_sdcc1_apps_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                               &gcc_sdcc1_apps_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT /* | CLK_ENABLE_HAND_OFF */,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_sdcc1_ice_core_clk = {
+       .halt_reg = 0x3800c,
+       .halt_check = BRANCH_HALT,
+       .hwcg_reg = 0x3800c,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x3800c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_sdcc1_ice_core_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                               &gcc_sdcc1_ice_core_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_sdcc2_ahb_clk = {
+       .halt_reg = 0x1e008,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x1e008,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_sdcc2_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_sdcc2_apps_clk = {
+       .halt_reg = 0x1e004,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x1e004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_sdcc2_apps_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                               &gcc_sdcc2_apps_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_sys_noc_cpuss_ahb_clk = {
+       .halt_reg = 0x2b06c,
+       .halt_check = BRANCH_HALT_VOTED,
+       .hwcg_reg = 0x2b06c,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x79004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_sys_noc_cpuss_ahb_clk",
+                       .flags = CLK_IS_CRITICAL,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_sys_noc_ufs_phy_axi_clk = {
+       .halt_reg = 0x45098,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x45098,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_sys_noc_ufs_phy_axi_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                               &gcc_ufs_phy_axi_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_sys_noc_usb3_prim_axi_clk = {
+       .halt_reg = 0x1a080,
+       .halt_check = BRANCH_HALT,
+       .hwcg_reg = 0x1a080,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x1a080,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_sys_noc_usb3_prim_axi_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                               &gcc_usb30_prim_master_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_ufs_clkref_clk = {
+       .halt_reg = 0x8c000,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x8c000,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_ufs_clkref_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_ufs_phy_ahb_clk = {
+       .halt_reg = 0x45014,
+       .halt_check = BRANCH_HALT,
+       .hwcg_reg = 0x45014,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x45014,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_ufs_phy_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_ufs_phy_axi_clk = {
+       .halt_reg = 0x45010,
+       .halt_check = BRANCH_HALT,
+       .hwcg_reg = 0x45010,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x45010,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_ufs_phy_axi_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                               &gcc_ufs_phy_axi_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_ufs_phy_ice_core_clk = {
+       .halt_reg = 0x45044,
+       .halt_check = BRANCH_HALT,
+       .hwcg_reg = 0x45044,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x45044,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_ufs_phy_ice_core_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                               &gcc_ufs_phy_ice_core_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_ufs_phy_phy_aux_clk = {
+       .halt_reg = 0x45078,
+       .halt_check = BRANCH_HALT,
+       .hwcg_reg = 0x45078,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x45078,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_ufs_phy_phy_aux_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                               &gcc_ufs_phy_phy_aux_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_ufs_phy_rx_symbol_0_clk = {
+       .halt_reg = 0x4501c,
+       .halt_check = BRANCH_HALT_SKIP,
+       .clkr = {
+               .enable_reg = 0x4501c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_ufs_phy_rx_symbol_0_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_ufs_phy_tx_symbol_0_clk = {
+       .halt_reg = 0x45018,
+       .halt_check = BRANCH_HALT_SKIP,
+       .clkr = {
+               .enable_reg = 0x45018,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_ufs_phy_tx_symbol_0_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_ufs_phy_unipro_core_clk = {
+       .halt_reg = 0x45040,
+       .halt_check = BRANCH_HALT,
+       .hwcg_reg = 0x45040,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x45040,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_ufs_phy_unipro_core_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                               &gcc_ufs_phy_unipro_core_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_usb30_prim_master_clk = {
+       .halt_reg = 0x1a010,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x1a010,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_usb30_prim_master_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                               &gcc_usb30_prim_master_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_usb30_prim_mock_utmi_clk = {
+       .halt_reg = 0x1a018,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x1a018,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_usb30_prim_mock_utmi_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                               &gcc_usb30_prim_mock_utmi_postdiv_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_usb30_prim_sleep_clk = {
+       .halt_reg = 0x1a014,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x1a014,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_usb30_prim_sleep_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_usb3_prim_clkref_clk = {
+       .halt_reg = 0x9f000,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x9f000,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_usb3_prim_clkref_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_usb3_prim_phy_com_aux_clk = {
+       .halt_reg = 0x1a054,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x1a054,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_usb3_prim_phy_com_aux_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                               &gcc_usb3_prim_phy_aux_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_usb3_prim_phy_pipe_clk = {
+       .halt_reg = 0x1a058,
+       .halt_check = BRANCH_HALT_SKIP,
+       .hwcg_reg = 0x1a058,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x1a058,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_usb3_prim_phy_pipe_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_vcodec0_axi_clk = {
+       .halt_reg = 0x6e008,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x6e008,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_vcodec0_axi_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_venus_ahb_clk = {
+       .halt_reg = 0x6e010,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x6e010,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_venus_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_venus_ctl_axi_clk = {
+       .halt_reg = 0x6e004,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x6e004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_venus_ctl_axi_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_video_ahb_clk = {
+       .halt_reg = 0x17004,
+       .halt_check = BRANCH_HALT,
+       .hwcg_reg = 0x17004,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x17004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_video_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_video_axi0_clk = {
+       .halt_reg = 0x1701c,
+       .halt_check = BRANCH_HALT,
+       .hwcg_reg = 0x1701c,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x1701c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_video_axi0_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_video_throttle_core_clk = {
+       .halt_reg = 0x17068,
+       .halt_check = BRANCH_HALT_VOTED,
+       .hwcg_reg = 0x17068,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x79004,
+               .enable_mask = BIT(28),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_video_throttle_core_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_video_vcodec0_sys_clk = {
+       .halt_reg = 0x580a4,
+       .halt_check = BRANCH_HALT_DELAY,
+       .hwcg_reg = 0x580a4,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x580a4,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_video_vcodec0_sys_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                               &gcc_video_venus_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_video_venus_ctl_clk = {
+       .halt_reg = 0x5808c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x5808c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_video_venus_ctl_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                               &gcc_video_venus_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_video_xo_clk = {
+       .halt_reg = 0x17024,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x17024,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_video_xo_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct gdsc gcc_camss_top_gdsc = {
+       .gdscr = 0x58004,
+       .pd = {
+               .name = "gcc_camss_top",
+       },
+       .pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct gdsc gcc_ufs_phy_gdsc = {
+       .gdscr = 0x45004,
+       .pd = {
+               .name = "gcc_ufs_phy",
+       },
+       .pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct gdsc gcc_usb30_prim_gdsc = {
+       .gdscr = 0x1a004,
+       .pd = {
+               .name = "gcc_usb30_prim",
+       },
+       .pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct gdsc gcc_vcodec0_gdsc = {
+       .gdscr = 0x58098,
+       .pd = {
+               .name = "gcc_vcodec0",
+       },
+       .pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct gdsc gcc_venus_gdsc = {
+       .gdscr = 0x5807c,
+       .pd = {
+               .name = "gcc_venus",
+       },
+       .pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct gdsc hlos1_vote_turing_mmu_tbu1_gdsc = {
+       .gdscr = 0x7d060,
+       .pd = {
+               .name = "hlos1_vote_turing_mmu_tbu1",
+       },
+       .pwrsts = PWRSTS_OFF_ON,
+       .flags = VOTABLE,
+};
+
+static struct gdsc hlos1_vote_turing_mmu_tbu0_gdsc = {
+       .gdscr = 0x7d060,
+       .pd = {
+               .name = "hlos1_vote_turing_mmu_tbu0",
+       },
+       .pwrsts = PWRSTS_OFF_ON,
+       .flags = VOTABLE,
+};
+
+static struct gdsc hlos1_vote_mm_snoc_mmu_tbu_rt_gdsc = {
+       .gdscr = 0x7d074,
+       .pd = {
+               .name = "hlos1_vote_mm_snoc_mmu_tbu_rt",
+       },
+       .pwrsts = PWRSTS_OFF_ON,
+       .flags = VOTABLE,
+};
+
+static struct gdsc hlos1_vote_mm_snoc_mmu_tbu_nrt_gdsc = {
+       .gdscr = 0x7d078,
+       .pd = {
+               .name = "hlos1_vote_mm_snoc_mmu_tbu_nrt",
+       },
+       .pwrsts = PWRSTS_OFF_ON,
+       .flags = VOTABLE,
+};
+
+static struct clk_regmap *gcc_sm6115_clocks[] = {
+       [GCC_AHB2PHY_CSI_CLK] = &gcc_ahb2phy_csi_clk.clkr,
+       [GCC_AHB2PHY_USB_CLK] = &gcc_ahb2phy_usb_clk.clkr,
+       [GCC_BIMC_GPU_AXI_CLK] = &gcc_bimc_gpu_axi_clk.clkr,
+       [GCC_BOOT_ROM_AHB_CLK] = &gcc_boot_rom_ahb_clk.clkr,
+       [GCC_CAM_THROTTLE_NRT_CLK] = &gcc_cam_throttle_nrt_clk.clkr,
+       [GCC_CAM_THROTTLE_RT_CLK] = &gcc_cam_throttle_rt_clk.clkr,
+       [GCC_CAMERA_AHB_CLK] = &gcc_camera_ahb_clk.clkr,
+       [GCC_CAMERA_XO_CLK] = &gcc_camera_xo_clk.clkr,
+       [GCC_CAMSS_AXI_CLK] = &gcc_camss_axi_clk.clkr,
+       [GCC_CAMSS_AXI_CLK_SRC] = &gcc_camss_axi_clk_src.clkr,
+       [GCC_CAMSS_CAMNOC_ATB_CLK] = &gcc_camss_camnoc_atb_clk.clkr,
+       [GCC_CAMSS_CAMNOC_NTS_XO_CLK] = &gcc_camss_camnoc_nts_xo_clk.clkr,
+       [GCC_CAMSS_CCI_0_CLK] = &gcc_camss_cci_0_clk.clkr,
+       [GCC_CAMSS_CCI_CLK_SRC] = &gcc_camss_cci_clk_src.clkr,
+       [GCC_CAMSS_CPHY_0_CLK] = &gcc_camss_cphy_0_clk.clkr,
+       [GCC_CAMSS_CPHY_1_CLK] = &gcc_camss_cphy_1_clk.clkr,
+       [GCC_CAMSS_CPHY_2_CLK] = &gcc_camss_cphy_2_clk.clkr,
+       [GCC_CAMSS_CSI0PHYTIMER_CLK] = &gcc_camss_csi0phytimer_clk.clkr,
+       [GCC_CAMSS_CSI0PHYTIMER_CLK_SRC] = &gcc_camss_csi0phytimer_clk_src.clkr,
+       [GCC_CAMSS_CSI1PHYTIMER_CLK] = &gcc_camss_csi1phytimer_clk.clkr,
+       [GCC_CAMSS_CSI1PHYTIMER_CLK_SRC] = &gcc_camss_csi1phytimer_clk_src.clkr,
+       [GCC_CAMSS_CSI2PHYTIMER_CLK] = &gcc_camss_csi2phytimer_clk.clkr,
+       [GCC_CAMSS_CSI2PHYTIMER_CLK_SRC] = &gcc_camss_csi2phytimer_clk_src.clkr,
+       [GCC_CAMSS_MCLK0_CLK] = &gcc_camss_mclk0_clk.clkr,
+       [GCC_CAMSS_MCLK0_CLK_SRC] = &gcc_camss_mclk0_clk_src.clkr,
+       [GCC_CAMSS_MCLK1_CLK] = &gcc_camss_mclk1_clk.clkr,
+       [GCC_CAMSS_MCLK1_CLK_SRC] = &gcc_camss_mclk1_clk_src.clkr,
+       [GCC_CAMSS_MCLK2_CLK] = &gcc_camss_mclk2_clk.clkr,
+       [GCC_CAMSS_MCLK2_CLK_SRC] = &gcc_camss_mclk2_clk_src.clkr,
+       [GCC_CAMSS_MCLK3_CLK] = &gcc_camss_mclk3_clk.clkr,
+       [GCC_CAMSS_MCLK3_CLK_SRC] = &gcc_camss_mclk3_clk_src.clkr,
+       [GCC_CAMSS_NRT_AXI_CLK] = &gcc_camss_nrt_axi_clk.clkr,
+       [GCC_CAMSS_OPE_AHB_CLK] = &gcc_camss_ope_ahb_clk.clkr,
+       [GCC_CAMSS_OPE_AHB_CLK_SRC] = &gcc_camss_ope_ahb_clk_src.clkr,
+       [GCC_CAMSS_OPE_CLK] = &gcc_camss_ope_clk.clkr,
+       [GCC_CAMSS_OPE_CLK_SRC] = &gcc_camss_ope_clk_src.clkr,
+       [GCC_CAMSS_RT_AXI_CLK] = &gcc_camss_rt_axi_clk.clkr,
+       [GCC_CAMSS_TFE_0_CLK] = &gcc_camss_tfe_0_clk.clkr,
+       [GCC_CAMSS_TFE_0_CLK_SRC] = &gcc_camss_tfe_0_clk_src.clkr,
+       [GCC_CAMSS_TFE_0_CPHY_RX_CLK] = &gcc_camss_tfe_0_cphy_rx_clk.clkr,
+       [GCC_CAMSS_TFE_0_CSID_CLK] = &gcc_camss_tfe_0_csid_clk.clkr,
+       [GCC_CAMSS_TFE_0_CSID_CLK_SRC] = &gcc_camss_tfe_0_csid_clk_src.clkr,
+       [GCC_CAMSS_TFE_1_CLK] = &gcc_camss_tfe_1_clk.clkr,
+       [GCC_CAMSS_TFE_1_CLK_SRC] = &gcc_camss_tfe_1_clk_src.clkr,
+       [GCC_CAMSS_TFE_1_CPHY_RX_CLK] = &gcc_camss_tfe_1_cphy_rx_clk.clkr,
+       [GCC_CAMSS_TFE_1_CSID_CLK] = &gcc_camss_tfe_1_csid_clk.clkr,
+       [GCC_CAMSS_TFE_1_CSID_CLK_SRC] = &gcc_camss_tfe_1_csid_clk_src.clkr,
+       [GCC_CAMSS_TFE_2_CLK] = &gcc_camss_tfe_2_clk.clkr,
+       [GCC_CAMSS_TFE_2_CLK_SRC] = &gcc_camss_tfe_2_clk_src.clkr,
+       [GCC_CAMSS_TFE_2_CPHY_RX_CLK] = &gcc_camss_tfe_2_cphy_rx_clk.clkr,
+       [GCC_CAMSS_TFE_2_CSID_CLK] = &gcc_camss_tfe_2_csid_clk.clkr,
+       [GCC_CAMSS_TFE_2_CSID_CLK_SRC] = &gcc_camss_tfe_2_csid_clk_src.clkr,
+       [GCC_CAMSS_TFE_CPHY_RX_CLK_SRC] = &gcc_camss_tfe_cphy_rx_clk_src.clkr,
+       [GCC_CAMSS_TOP_AHB_CLK] = &gcc_camss_top_ahb_clk.clkr,
+       [GCC_CAMSS_TOP_AHB_CLK_SRC] = &gcc_camss_top_ahb_clk_src.clkr,
+       [GCC_CFG_NOC_USB3_PRIM_AXI_CLK] = &gcc_cfg_noc_usb3_prim_axi_clk.clkr,
+       [GCC_CPUSS_GNOC_CLK] = &gcc_cpuss_gnoc_clk.clkr,
+       [GCC_DISP_AHB_CLK] = &gcc_disp_ahb_clk.clkr,
+       [GCC_DISP_GPLL0_CLK_SRC] = &gcc_disp_gpll0_clk_src.clkr,
+       [GCC_DISP_GPLL0_DIV_CLK_SRC] = &gcc_disp_gpll0_div_clk_src.clkr,
+       [GCC_DISP_HF_AXI_CLK] = &gcc_disp_hf_axi_clk.clkr,
+       [GCC_DISP_THROTTLE_CORE_CLK] = &gcc_disp_throttle_core_clk.clkr,
+       [GCC_DISP_XO_CLK] = &gcc_disp_xo_clk.clkr,
+       [GCC_GP1_CLK] = &gcc_gp1_clk.clkr,
+       [GCC_GP1_CLK_SRC] = &gcc_gp1_clk_src.clkr,
+       [GCC_GP2_CLK] = &gcc_gp2_clk.clkr,
+       [GCC_GP2_CLK_SRC] = &gcc_gp2_clk_src.clkr,
+       [GCC_GP3_CLK] = &gcc_gp3_clk.clkr,
+       [GCC_GP3_CLK_SRC] = &gcc_gp3_clk_src.clkr,
+       [GCC_GPU_CFG_AHB_CLK] = &gcc_gpu_cfg_ahb_clk.clkr,
+       [GCC_GPU_GPLL0_CLK_SRC] = &gcc_gpu_gpll0_clk_src.clkr,
+       [GCC_GPU_GPLL0_DIV_CLK_SRC] = &gcc_gpu_gpll0_div_clk_src.clkr,
+       [GCC_GPU_IREF_CLK] = &gcc_gpu_iref_clk.clkr,
+       [GCC_GPU_MEMNOC_GFX_CLK] = &gcc_gpu_memnoc_gfx_clk.clkr,
+       [GCC_GPU_SNOC_DVM_GFX_CLK] = &gcc_gpu_snoc_dvm_gfx_clk.clkr,
+       [GCC_GPU_THROTTLE_CORE_CLK] = &gcc_gpu_throttle_core_clk.clkr,
+       [GCC_PDM2_CLK] = &gcc_pdm2_clk.clkr,
+       [GCC_PDM2_CLK_SRC] = &gcc_pdm2_clk_src.clkr,
+       [GCC_PDM_AHB_CLK] = &gcc_pdm_ahb_clk.clkr,
+       [GCC_PDM_XO4_CLK] = &gcc_pdm_xo4_clk.clkr,
+       [GCC_PRNG_AHB_CLK] = &gcc_prng_ahb_clk.clkr,
+       [GCC_QMIP_CAMERA_NRT_AHB_CLK] = &gcc_qmip_camera_nrt_ahb_clk.clkr,
+       [GCC_QMIP_CAMERA_RT_AHB_CLK] = &gcc_qmip_camera_rt_ahb_clk.clkr,
+       [GCC_QMIP_DISP_AHB_CLK] = &gcc_qmip_disp_ahb_clk.clkr,
+       [GCC_QMIP_GPU_CFG_AHB_CLK] = &gcc_qmip_gpu_cfg_ahb_clk.clkr,
+       [GCC_QMIP_VIDEO_VCODEC_AHB_CLK] = &gcc_qmip_video_vcodec_ahb_clk.clkr,
+       [GCC_QUPV3_WRAP0_CORE_2X_CLK] = &gcc_qupv3_wrap0_core_2x_clk.clkr,
+       [GCC_QUPV3_WRAP0_CORE_CLK] = &gcc_qupv3_wrap0_core_clk.clkr,
+       [GCC_QUPV3_WRAP0_S0_CLK] = &gcc_qupv3_wrap0_s0_clk.clkr,
+       [GCC_QUPV3_WRAP0_S0_CLK_SRC] = &gcc_qupv3_wrap0_s0_clk_src.clkr,
+       [GCC_QUPV3_WRAP0_S1_CLK] = &gcc_qupv3_wrap0_s1_clk.clkr,
+       [GCC_QUPV3_WRAP0_S1_CLK_SRC] = &gcc_qupv3_wrap0_s1_clk_src.clkr,
+       [GCC_QUPV3_WRAP0_S2_CLK] = &gcc_qupv3_wrap0_s2_clk.clkr,
+       [GCC_QUPV3_WRAP0_S2_CLK_SRC] = &gcc_qupv3_wrap0_s2_clk_src.clkr,
+       [GCC_QUPV3_WRAP0_S3_CLK] = &gcc_qupv3_wrap0_s3_clk.clkr,
+       [GCC_QUPV3_WRAP0_S3_CLK_SRC] = &gcc_qupv3_wrap0_s3_clk_src.clkr,
+       [GCC_QUPV3_WRAP0_S4_CLK] = &gcc_qupv3_wrap0_s4_clk.clkr,
+       [GCC_QUPV3_WRAP0_S4_CLK_SRC] = &gcc_qupv3_wrap0_s4_clk_src.clkr,
+       [GCC_QUPV3_WRAP0_S5_CLK] = &gcc_qupv3_wrap0_s5_clk.clkr,
+       [GCC_QUPV3_WRAP0_S5_CLK_SRC] = &gcc_qupv3_wrap0_s5_clk_src.clkr,
+       [GCC_QUPV3_WRAP_0_M_AHB_CLK] = &gcc_qupv3_wrap_0_m_ahb_clk.clkr,
+       [GCC_QUPV3_WRAP_0_S_AHB_CLK] = &gcc_qupv3_wrap_0_s_ahb_clk.clkr,
+       [GCC_SDCC1_AHB_CLK] = &gcc_sdcc1_ahb_clk.clkr,
+       [GCC_SDCC1_APPS_CLK] = &gcc_sdcc1_apps_clk.clkr,
+       [GCC_SDCC1_APPS_CLK_SRC] = &gcc_sdcc1_apps_clk_src.clkr,
+       [GCC_SDCC1_ICE_CORE_CLK] = &gcc_sdcc1_ice_core_clk.clkr,
+       [GCC_SDCC1_ICE_CORE_CLK_SRC] = &gcc_sdcc1_ice_core_clk_src.clkr,
+       [GCC_SDCC2_AHB_CLK] = &gcc_sdcc2_ahb_clk.clkr,
+       [GCC_SDCC2_APPS_CLK] = &gcc_sdcc2_apps_clk.clkr,
+       [GCC_SDCC2_APPS_CLK_SRC] = &gcc_sdcc2_apps_clk_src.clkr,
+       [GCC_SYS_NOC_CPUSS_AHB_CLK] = &gcc_sys_noc_cpuss_ahb_clk.clkr,
+       [GCC_SYS_NOC_UFS_PHY_AXI_CLK] = &gcc_sys_noc_ufs_phy_axi_clk.clkr,
+       [GCC_SYS_NOC_USB3_PRIM_AXI_CLK] = &gcc_sys_noc_usb3_prim_axi_clk.clkr,
+       [GCC_UFS_CLKREF_CLK] = &gcc_ufs_clkref_clk.clkr,
+       [GCC_UFS_PHY_AHB_CLK] = &gcc_ufs_phy_ahb_clk.clkr,
+       [GCC_UFS_PHY_AXI_CLK] = &gcc_ufs_phy_axi_clk.clkr,
+       [GCC_UFS_PHY_AXI_CLK_SRC] = &gcc_ufs_phy_axi_clk_src.clkr,
+       [GCC_UFS_PHY_ICE_CORE_CLK] = &gcc_ufs_phy_ice_core_clk.clkr,
+       [GCC_UFS_PHY_ICE_CORE_CLK_SRC] = &gcc_ufs_phy_ice_core_clk_src.clkr,
+       [GCC_UFS_PHY_PHY_AUX_CLK] = &gcc_ufs_phy_phy_aux_clk.clkr,
+       [GCC_UFS_PHY_PHY_AUX_CLK_SRC] = &gcc_ufs_phy_phy_aux_clk_src.clkr,
+       [GCC_UFS_PHY_RX_SYMBOL_0_CLK] = &gcc_ufs_phy_rx_symbol_0_clk.clkr,
+       [GCC_UFS_PHY_TX_SYMBOL_0_CLK] = &gcc_ufs_phy_tx_symbol_0_clk.clkr,
+       [GCC_UFS_PHY_UNIPRO_CORE_CLK] = &gcc_ufs_phy_unipro_core_clk.clkr,
+       [GCC_UFS_PHY_UNIPRO_CORE_CLK_SRC] =
+               &gcc_ufs_phy_unipro_core_clk_src.clkr,
+       [GCC_USB30_PRIM_MASTER_CLK] = &gcc_usb30_prim_master_clk.clkr,
+       [GCC_USB30_PRIM_MASTER_CLK_SRC] = &gcc_usb30_prim_master_clk_src.clkr,
+       [GCC_USB30_PRIM_MOCK_UTMI_CLK] = &gcc_usb30_prim_mock_utmi_clk.clkr,
+       [GCC_USB30_PRIM_MOCK_UTMI_CLK_SRC] =
+               &gcc_usb30_prim_mock_utmi_clk_src.clkr,
+       [GCC_USB30_PRIM_MOCK_UTMI_POSTDIV_CLK_SRC] =
+               &gcc_usb30_prim_mock_utmi_postdiv_clk_src.clkr,
+       [GCC_USB30_PRIM_SLEEP_CLK] = &gcc_usb30_prim_sleep_clk.clkr,
+       [GCC_USB3_PRIM_CLKREF_CLK] = &gcc_usb3_prim_clkref_clk.clkr,
+       [GCC_USB3_PRIM_PHY_AUX_CLK_SRC] = &gcc_usb3_prim_phy_aux_clk_src.clkr,
+       [GCC_USB3_PRIM_PHY_COM_AUX_CLK] = &gcc_usb3_prim_phy_com_aux_clk.clkr,
+       [GCC_USB3_PRIM_PHY_PIPE_CLK] = &gcc_usb3_prim_phy_pipe_clk.clkr,
+       [GCC_VCODEC0_AXI_CLK] = &gcc_vcodec0_axi_clk.clkr,
+       [GCC_VENUS_AHB_CLK] = &gcc_venus_ahb_clk.clkr,
+       [GCC_VENUS_CTL_AXI_CLK] = &gcc_venus_ctl_axi_clk.clkr,
+       [GCC_VIDEO_AHB_CLK] = &gcc_video_ahb_clk.clkr,
+       [GCC_VIDEO_AXI0_CLK] = &gcc_video_axi0_clk.clkr,
+       [GCC_VIDEO_THROTTLE_CORE_CLK] = &gcc_video_throttle_core_clk.clkr,
+       [GCC_VIDEO_VCODEC0_SYS_CLK] = &gcc_video_vcodec0_sys_clk.clkr,
+       [GCC_VIDEO_VENUS_CLK_SRC] = &gcc_video_venus_clk_src.clkr,
+       [GCC_VIDEO_VENUS_CTL_CLK] = &gcc_video_venus_ctl_clk.clkr,
+       [GCC_VIDEO_XO_CLK] = &gcc_video_xo_clk.clkr,
+       [GPLL0] = &gpll0.clkr,
+       [GPLL0_OUT_AUX2] = &gpll0_out_aux2.clkr,
+       [GPLL0_OUT_MAIN] = &gpll0_out_main.clkr,
+       [GPLL10] = &gpll10.clkr,
+       [GPLL10_OUT_MAIN] = &gpll10_out_main.clkr,
+       [GPLL11] = &gpll11.clkr,
+       [GPLL11_OUT_MAIN] = &gpll11_out_main.clkr,
+       [GPLL3] = &gpll3.clkr,
+       [GPLL4] = &gpll4.clkr,
+       [GPLL4_OUT_MAIN] = &gpll4_out_main.clkr,
+       [GPLL6] = &gpll6.clkr,
+       [GPLL6_OUT_MAIN] = &gpll6_out_main.clkr,
+       [GPLL7] = &gpll7.clkr,
+       [GPLL7_OUT_MAIN] = &gpll7_out_main.clkr,
+       [GPLL8] = &gpll8.clkr,
+       [GPLL8_OUT_MAIN] = &gpll8_out_main.clkr,
+       [GPLL9] = &gpll9.clkr,
+       [GPLL9_OUT_MAIN] = &gpll9_out_main.clkr,
+};
+
+static const struct qcom_reset_map gcc_sm6115_resets[] = {
+       [GCC_QUSB2PHY_PRIM_BCR] = { 0x1c000 },
+       [GCC_QUSB2PHY_SEC_BCR] = { 0x1c004 },
+       [GCC_SDCC1_BCR] = { 0x38000 },
+       [GCC_SDCC2_BCR] = { 0x1e000 },
+       [GCC_UFS_PHY_BCR] = { 0x45000 },
+       [GCC_USB30_PRIM_BCR] = { 0x1a000 },
+       [GCC_USB_PHY_CFG_AHB2PHY_BCR] = { 0x1d000 },
+       [GCC_USB3PHY_PHY_PRIM_SP0_BCR] = { 0x1b008 },
+       [GCC_USB3_PHY_PRIM_SP0_BCR] = { 0x1b000 },
+       [GCC_VCODEC0_BCR] = { 0x58094 },
+       [GCC_VENUS_BCR] = { 0x58078 },
+       [GCC_VIDEO_INTERFACE_BCR] = { 0x6e000 },
+};
+
+static struct gdsc *gcc_sm6115_gdscs[] = {
+       [GCC_CAMSS_TOP_GDSC] = &gcc_camss_top_gdsc,
+       [GCC_UFS_PHY_GDSC] = &gcc_ufs_phy_gdsc,
+       [GCC_USB30_PRIM_GDSC] = &gcc_usb30_prim_gdsc,
+       [GCC_VCODEC0_GDSC] = &gcc_vcodec0_gdsc,
+       [GCC_VENUS_GDSC] = &gcc_venus_gdsc,
+       [HLOS1_VOTE_TURING_MMU_TBU1_GDSC] = &hlos1_vote_turing_mmu_tbu1_gdsc,
+       [HLOS1_VOTE_TURING_MMU_TBU0_GDSC] = &hlos1_vote_turing_mmu_tbu0_gdsc,
+       [HLOS1_VOTE_MM_SNOC_MMU_TBU_RT_GDSC] = &hlos1_vote_mm_snoc_mmu_tbu_rt_gdsc,
+       [HLOS1_VOTE_MM_SNOC_MMU_TBU_NRT_GDSC] = &hlos1_vote_mm_snoc_mmu_tbu_nrt_gdsc,
+};
+
+static const struct clk_rcg_dfs_data gcc_dfs_clocks[] = {
+       DEFINE_RCG_DFS(gcc_qupv3_wrap0_s0_clk_src),
+       DEFINE_RCG_DFS(gcc_qupv3_wrap0_s1_clk_src),
+       DEFINE_RCG_DFS(gcc_qupv3_wrap0_s2_clk_src),
+       DEFINE_RCG_DFS(gcc_qupv3_wrap0_s3_clk_src),
+       DEFINE_RCG_DFS(gcc_qupv3_wrap0_s4_clk_src),
+       DEFINE_RCG_DFS(gcc_qupv3_wrap0_s5_clk_src),
+};
+
+static const struct regmap_config gcc_sm6115_regmap_config = {
+       .reg_bits = 32,
+       .reg_stride = 4,
+       .val_bits = 32,
+       .max_register = 0xc7000,
+       .fast_io = true,
+};
+
+static const struct qcom_cc_desc gcc_sm6115_desc = {
+       .config = &gcc_sm6115_regmap_config,
+       .clks = gcc_sm6115_clocks,
+       .num_clks = ARRAY_SIZE(gcc_sm6115_clocks),
+       .resets = gcc_sm6115_resets,
+       .num_resets = ARRAY_SIZE(gcc_sm6115_resets),
+       .gdscs = gcc_sm6115_gdscs,
+       .num_gdscs = ARRAY_SIZE(gcc_sm6115_gdscs),
+};
+
+static const struct of_device_id gcc_sm6115_match_table[] = {
+       { .compatible = "qcom,gcc-sm6115" },
+       { }
+};
+MODULE_DEVICE_TABLE(of, gcc_sm6115_match_table);
+
+static int gcc_sm6115_probe(struct platform_device *pdev)
+{
+       struct regmap *regmap;
+       int ret;
+
+       regmap = qcom_cc_map(pdev, &gcc_sm6115_desc);
+       if (IS_ERR(regmap))
+               return PTR_ERR(regmap);
+
+       ret = qcom_cc_register_rcg_dfs(regmap, gcc_dfs_clocks,
+                       ARRAY_SIZE(gcc_dfs_clocks));
+       if (ret)
+               return ret;
+
+       clk_alpha_pll_configure(&gpll8, regmap, &gpll8_config);
+       clk_alpha_pll_configure(&gpll9, regmap, &gpll9_config);
+       clk_alpha_pll_configure(&gpll10, regmap, &gpll10_config);
+       clk_alpha_pll_configure(&gpll11, regmap, &gpll11_config);
+
+       return qcom_cc_really_probe(pdev, &gcc_sm6115_desc, regmap);
+}
+
+static struct platform_driver gcc_sm6115_driver = {
+       .probe = gcc_sm6115_probe,
+       .driver = {
+               .name = "gcc-sm6115",
+               .of_match_table = gcc_sm6115_match_table,
+       },
+};
+
+static int __init gcc_sm6115_init(void)
+{
+       return platform_driver_register(&gcc_sm6115_driver);
+}
+subsys_initcall(gcc_sm6115_init);
+
+static void __exit gcc_sm6115_exit(void)
+{
+       platform_driver_unregister(&gcc_sm6115_driver);
+}
+module_exit(gcc_sm6115_exit);
+
+MODULE_DESCRIPTION("QTI GCC SM6115 and SM4250 Driver");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:gcc-sm6115");
diff --git a/drivers/clk/qcom/gcc-sm6350.c b/drivers/clk/qcom/gcc-sm6350.c
new file mode 100644 (file)
index 0000000..053089f
--- /dev/null
@@ -0,0 +1,2588 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2021, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2021, Konrad Dybcio <konrad.dybcio@somainline.org>
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+#include <dt-bindings/clock/qcom,gcc-sm6350.h>
+
+#include "clk-alpha-pll.h"
+#include "clk-branch.h"
+#include "clk-rcg.h"
+#include "clk-regmap.h"
+#include "clk-regmap-divider.h"
+#include "clk-regmap-mux.h"
+#include "common.h"
+#include "gdsc.h"
+#include "reset.h"
+
+enum {
+       P_BI_TCXO,
+       P_GPLL0_OUT_EVEN,
+       P_GPLL0_OUT_MAIN,
+       P_GPLL0_OUT_ODD,
+       P_GPLL6_OUT_EVEN,
+       P_GPLL7_OUT_MAIN,
+       P_SLEEP_CLK,
+};
+
+static struct clk_alpha_pll gpll0 = {
+       .offset = 0x0,
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
+       .clkr = {
+               .enable_reg = 0x52010,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gpll0",
+                       .parent_data = &(const struct clk_parent_data){
+                               .fw_name = "bi_tcxo",
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_alpha_pll_fixed_fabia_ops,
+               },
+       },
+};
+
+static const struct clk_div_table post_div_table_gpll0_out_even[] = {
+       { 0x1, 2 },
+       { }
+};
+
+static struct clk_alpha_pll_postdiv gpll0_out_even = {
+       .offset = 0x0,
+       .post_div_shift = 8,
+       .post_div_table = post_div_table_gpll0_out_even,
+       .num_post_div = ARRAY_SIZE(post_div_table_gpll0_out_even),
+       .width = 4,
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gpll0_out_even",
+               .parent_hws = (const struct clk_hw*[]){
+                       &gpll0.clkr.hw,
+               },
+               .num_parents = 1,
+               .ops = &clk_alpha_pll_postdiv_fabia_ops,
+       },
+};
+
+static const struct clk_div_table post_div_table_gpll0_out_odd[] = {
+       { 0x3, 3 },
+       { }
+};
+
+static struct clk_alpha_pll_postdiv gpll0_out_odd = {
+       .offset = 0x0,
+       .post_div_shift = 12,
+       .post_div_table = post_div_table_gpll0_out_odd,
+       .num_post_div = ARRAY_SIZE(post_div_table_gpll0_out_odd),
+       .width = 4,
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gpll0_out_odd",
+               .parent_hws = (const struct clk_hw*[]){
+                       &gpll0.clkr.hw,
+               },
+               .num_parents = 1,
+               .ops = &clk_alpha_pll_postdiv_fabia_ops,
+       },
+};
+
+static struct clk_alpha_pll gpll6 = {
+       .offset = 0x6000,
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
+       .clkr = {
+               .enable_reg = 0x52010,
+               .enable_mask = BIT(6),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gpll6",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &gpll0.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_alpha_pll_fixed_fabia_ops,
+               },
+       },
+};
+
+static const struct clk_div_table post_div_table_gpll6_out_even[] = {
+       { 0x1, 2 },
+       { }
+};
+
+static struct clk_alpha_pll_postdiv gpll6_out_even = {
+       .offset = 0x6000,
+       .post_div_shift = 8,
+       .post_div_table = post_div_table_gpll6_out_even,
+       .num_post_div = ARRAY_SIZE(post_div_table_gpll6_out_even),
+       .width = 4,
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gpll6_out_even",
+               .parent_hws = (const struct clk_hw*[]){
+                       &gpll0.clkr.hw,
+               },
+               .num_parents = 1,
+               .ops = &clk_alpha_pll_postdiv_fabia_ops,
+       },
+};
+
+static struct clk_alpha_pll gpll7 = {
+       .offset = 0x7000,
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
+       .clkr = {
+               .enable_reg = 0x52010,
+               .enable_mask = BIT(7),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gpll7",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &gpll0.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_alpha_pll_fixed_fabia_ops,
+               },
+       },
+};
+
+static const struct parent_map gcc_parent_map_0[] = {
+       { P_BI_TCXO, 0 },
+       { P_GPLL0_OUT_MAIN, 1 },
+       { P_GPLL6_OUT_EVEN, 2 },
+       { P_GPLL0_OUT_EVEN, 6 },
+};
+
+static const struct clk_parent_data gcc_parent_data_0[] = {
+       { .fw_name = "bi_tcxo" },
+       { .hw = &gpll0.clkr.hw },
+       { .hw = &gpll6_out_even.clkr.hw },
+       { .hw = &gpll0_out_even.clkr.hw },
+};
+
+static const struct parent_map gcc_parent_map_1[] = {
+       { P_BI_TCXO, 0 },
+       { P_GPLL0_OUT_EVEN, 6 },
+};
+
+static const struct clk_parent_data gcc_parent_data_1[] = {
+       { .fw_name = "bi_tcxo" },
+       { .hw = &gpll0_out_even.clkr.hw },
+};
+
+static const struct parent_map gcc_parent_map_2[] = {
+       { P_BI_TCXO, 0 },
+       { P_GPLL0_OUT_ODD, 2 },
+};
+
+static const struct clk_parent_data gcc_parent_data_2[] = {
+       { .fw_name = "bi_tcxo" },
+       { .hw = &gpll0_out_odd.clkr.hw },
+};
+static const struct clk_parent_data gcc_parent_data_2_ao[] = {
+       { .fw_name = "bi_tcxo_ao" },
+       { .hw = &gpll0_out_odd.clkr.hw },
+};
+
+static const struct parent_map gcc_parent_map_4[] = {
+       { P_BI_TCXO, 0 },
+       { P_GPLL0_OUT_MAIN, 1 },
+       { P_GPLL0_OUT_ODD, 2 },
+};
+
+static const struct clk_parent_data gcc_parent_data_4[] = {
+       { .fw_name = "bi_tcxo" },
+       { .hw = &gpll0.clkr.hw },
+       { .hw = &gpll0_out_odd.clkr.hw },
+};
+
+static const struct parent_map gcc_parent_map_5[] = {
+       { P_BI_TCXO, 0 },
+       { P_GPLL0_OUT_ODD, 2 },
+       { P_SLEEP_CLK, 5 },
+       { P_GPLL0_OUT_EVEN, 6 },
+};
+
+static const struct clk_parent_data gcc_parent_data_5[] = {
+       { .fw_name = "bi_tcxo" },
+       { .hw = &gpll0_out_odd.clkr.hw },
+       { .fw_name = "sleep_clk" },
+       { .hw = &gpll0_out_even.clkr.hw },
+};
+
+static const struct parent_map gcc_parent_map_6[] = {
+       { P_BI_TCXO, 0 },
+       { P_SLEEP_CLK, 5 },
+};
+
+static const struct clk_parent_data gcc_parent_data_6[] = {
+       { .fw_name = "bi_tcxo" },
+       { .fw_name = "sleep_clk" }
+};
+
+static const struct parent_map gcc_parent_map_7[] = {
+       { P_BI_TCXO, 0 },
+       { P_GPLL6_OUT_EVEN, 2 },
+       { P_GPLL0_OUT_EVEN, 6 },
+};
+
+static const struct clk_parent_data gcc_parent_data_7[] = {
+       { .fw_name = "bi_tcxo" },
+       { .hw = &gpll6_out_even.clkr.hw },
+       { .hw = &gpll0_out_even.clkr.hw },
+};
+
+static const struct parent_map gcc_parent_map_8[] = {
+       { P_BI_TCXO, 0 },
+       { P_GPLL0_OUT_ODD, 2 },
+       { P_GPLL7_OUT_MAIN, 3 },
+};
+
+static const struct clk_parent_data gcc_parent_data_8[] = {
+       { .fw_name = "bi_tcxo" },
+       { .hw = &gpll0_out_odd.clkr.hw },
+       { .hw = &gpll7.clkr.hw },
+};
+
+static struct clk_regmap_div gcc_gpu_gpll0_main_div_clk_src = {
+       .reg = 0x4514C,
+       .shift = 0,
+       .width = 2,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "gcc_gpu_gpll0_main_div_clk_src",
+               .parent_hws = (const struct clk_hw*[]){
+                       &gpll0.clkr.hw,
+               },
+               .num_parents = 1,
+               .ops = &clk_regmap_div_ro_ops,
+       },
+};
+
+static struct clk_regmap_div gcc_npu_pll0_main_div_clk_src = {
+       .reg = 0x4ce00,
+       .shift = 0,
+       .width = 2,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "gcc_npu_pll0_main_div_clk_src",
+               .parent_hws = (const struct clk_hw*[]){
+                       &gpll0.clkr.hw,
+               },
+               .num_parents = 1,
+               .ops = &clk_regmap_div_ro_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_gcc_cpuss_ahb_clk_src[] = {
+       F(19200000, P_BI_TCXO, 1, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 gcc_cpuss_ahb_clk_src = {
+       .cmd_rcgr = 0x30014,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_2,
+       .freq_tbl = ftbl_gcc_cpuss_ahb_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_cpuss_ahb_clk_src",
+               .parent_data = gcc_parent_data_2_ao,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_2_ao),
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_gcc_gp1_clk_src[] = {
+       F(19200000, P_BI_TCXO, 1, 0, 0),
+       F(25000000, P_GPLL0_OUT_EVEN, 12, 0, 0),
+       F(50000000, P_GPLL0_OUT_ODD, 4, 0, 0),
+       F(100000000, P_GPLL0_OUT_ODD, 2, 0, 0),
+       F(200000000, P_GPLL0_OUT_ODD, 1, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 gcc_gp1_clk_src = {
+       .cmd_rcgr = 0x37004,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_5,
+       .freq_tbl = ftbl_gcc_gp1_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_gp1_clk_src",
+               .parent_data = gcc_parent_data_5,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_5),
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 gcc_gp2_clk_src = {
+       .cmd_rcgr = 0x38004,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_5,
+       .freq_tbl = ftbl_gcc_gp1_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_gp2_clk_src",
+               .parent_data = gcc_parent_data_5,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_5),
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 gcc_gp3_clk_src = {
+       .cmd_rcgr = 0x39004,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_5,
+       .freq_tbl = ftbl_gcc_gp1_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_gp3_clk_src",
+               .parent_data = gcc_parent_data_5,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_5),
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_gcc_pdm2_clk_src[] = {
+       F(19200000, P_BI_TCXO, 1, 0, 0),
+       F(60000000, P_GPLL0_OUT_EVEN, 5, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 gcc_pdm2_clk_src = {
+       .cmd_rcgr = 0x23010,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_1,
+       .freq_tbl = ftbl_gcc_pdm2_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_pdm2_clk_src",
+               .parent_data = gcc_parent_data_1,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_1),
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_gcc_qupv3_wrap0_s0_clk_src[] = {
+       F(7372800, P_GPLL0_OUT_EVEN, 1, 384, 15625),
+       F(14745600, P_GPLL0_OUT_EVEN, 1, 768, 15625),
+       F(19200000, P_BI_TCXO, 1, 0, 0),
+       F(29491200, P_GPLL0_OUT_EVEN, 1, 1536, 15625),
+       F(32000000, P_GPLL0_OUT_EVEN, 1, 8, 75),
+       F(48000000, P_GPLL0_OUT_EVEN, 1, 4, 25),
+       F(64000000, P_GPLL0_OUT_EVEN, 1, 16, 75),
+       F(75000000, P_GPLL0_OUT_EVEN, 4, 0, 0),
+       F(80000000, P_GPLL0_OUT_EVEN, 1, 4, 15),
+       F(96000000, P_GPLL0_OUT_EVEN, 1, 8, 25),
+       F(100000000, P_GPLL0_OUT_EVEN, 3, 0, 0),
+       F(102400000, P_GPLL0_OUT_EVEN, 1, 128, 375),
+       F(112000000, P_GPLL0_OUT_EVEN, 1, 28, 75),
+       F(117964800, P_GPLL0_OUT_EVEN, 1, 6144, 15625),
+       F(120000000, P_GPLL0_OUT_EVEN, 2.5, 0, 0),
+       F(128000000, P_GPLL6_OUT_EVEN, 3, 0, 0),
+       { }
+};
+
+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 = ARRAY_SIZE(gcc_parent_data_0),
+       .ops = &clk_rcg2_ops,
+};
+
+static struct clk_rcg2 gcc_qupv3_wrap0_s0_clk_src = {
+       .cmd_rcgr = 0x21148,
+       .mnd_width = 16,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_0,
+       .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
+       .clkr.hw.init = &gcc_qupv3_wrap0_s0_clk_src_init,
+};
+
+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 = ARRAY_SIZE(gcc_parent_data_0),
+       .ops = &clk_rcg2_ops,
+};
+
+static struct clk_rcg2 gcc_qupv3_wrap0_s1_clk_src = {
+       .cmd_rcgr = 0x21278,
+       .mnd_width = 16,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_0,
+       .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
+       .clkr.hw.init = &gcc_qupv3_wrap0_s1_clk_src_init,
+};
+
+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 = ARRAY_SIZE(gcc_parent_data_0),
+       .ops = &clk_rcg2_ops,
+};
+
+static struct clk_rcg2 gcc_qupv3_wrap0_s2_clk_src = {
+       .cmd_rcgr = 0x213a8,
+       .mnd_width = 16,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_0,
+       .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
+       .clkr.hw.init = &gcc_qupv3_wrap0_s2_clk_src_init,
+};
+
+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 = ARRAY_SIZE(gcc_parent_data_0),
+       .ops = &clk_rcg2_ops,
+};
+
+static struct clk_rcg2 gcc_qupv3_wrap0_s3_clk_src = {
+       .cmd_rcgr = 0x214d8,
+       .mnd_width = 16,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_0,
+       .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
+       .clkr.hw.init = &gcc_qupv3_wrap0_s3_clk_src_init,
+};
+
+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 = ARRAY_SIZE(gcc_parent_data_0),
+       .ops = &clk_rcg2_ops,
+};
+
+static struct clk_rcg2 gcc_qupv3_wrap0_s4_clk_src = {
+       .cmd_rcgr = 0x21608,
+       .mnd_width = 16,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_0,
+       .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
+       .clkr.hw.init = &gcc_qupv3_wrap0_s4_clk_src_init,
+};
+
+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 = ARRAY_SIZE(gcc_parent_data_0),
+       .ops = &clk_rcg2_ops,
+};
+
+static struct clk_rcg2 gcc_qupv3_wrap0_s5_clk_src = {
+       .cmd_rcgr = 0x21738,
+       .mnd_width = 16,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_0,
+       .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
+       .clkr.hw.init = &gcc_qupv3_wrap0_s5_clk_src_init,
+};
+
+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 = ARRAY_SIZE(gcc_parent_data_0),
+       .ops = &clk_rcg2_ops,
+};
+
+static struct clk_rcg2 gcc_qupv3_wrap1_s0_clk_src = {
+       .cmd_rcgr = 0x22018,
+       .mnd_width = 16,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_0,
+       .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
+       .clkr.hw.init = &gcc_qupv3_wrap1_s0_clk_src_init,
+};
+
+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 = ARRAY_SIZE(gcc_parent_data_0),
+       .ops = &clk_rcg2_ops,
+};
+
+static struct clk_rcg2 gcc_qupv3_wrap1_s1_clk_src = {
+       .cmd_rcgr = 0x22148,
+       .mnd_width = 16,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_0,
+       .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
+       .clkr.hw.init = &gcc_qupv3_wrap1_s1_clk_src_init,
+};
+
+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 = ARRAY_SIZE(gcc_parent_data_0),
+       .ops = &clk_rcg2_ops,
+};
+
+static struct clk_rcg2 gcc_qupv3_wrap1_s2_clk_src = {
+       .cmd_rcgr = 0x22278,
+       .mnd_width = 16,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_0,
+       .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
+       .clkr.hw.init = &gcc_qupv3_wrap1_s2_clk_src_init,
+};
+
+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 = ARRAY_SIZE(gcc_parent_data_0),
+       .ops = &clk_rcg2_ops,
+};
+
+static struct clk_rcg2 gcc_qupv3_wrap1_s3_clk_src = {
+       .cmd_rcgr = 0x223a8,
+       .mnd_width = 16,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_0,
+       .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
+       .clkr.hw.init = &gcc_qupv3_wrap1_s3_clk_src_init,
+};
+
+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 = ARRAY_SIZE(gcc_parent_data_0),
+       .ops = &clk_rcg2_ops,
+};
+
+static struct clk_rcg2 gcc_qupv3_wrap1_s4_clk_src = {
+       .cmd_rcgr = 0x224d8,
+       .mnd_width = 16,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_0,
+       .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
+       .clkr.hw.init = &gcc_qupv3_wrap1_s4_clk_src_init,
+};
+
+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 = ARRAY_SIZE(gcc_parent_data_0),
+       .ops = &clk_rcg2_ops,
+};
+
+static struct clk_rcg2 gcc_qupv3_wrap1_s5_clk_src = {
+       .cmd_rcgr = 0x22608,
+       .mnd_width = 16,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_0,
+       .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
+       .clkr.hw.init = &gcc_qupv3_wrap1_s5_clk_src_init,
+};
+
+static const struct freq_tbl ftbl_gcc_sdcc1_apps_clk_src[] = {
+       F(144000, P_BI_TCXO, 16, 3, 25),
+       F(400000, P_BI_TCXO, 12, 1, 4),
+       F(19200000, P_BI_TCXO, 1, 0, 0),
+       F(20000000, P_GPLL0_OUT_EVEN, 5, 1, 3),
+       F(25000000, P_GPLL0_OUT_EVEN, 12, 0, 0),
+       F(50000000, P_GPLL0_OUT_EVEN, 6, 0, 0),
+       F(100000000, P_GPLL0_OUT_EVEN, 3, 0, 0),
+       F(192000000, P_GPLL6_OUT_EVEN, 2, 0, 0),
+       F(384000000, P_GPLL6_OUT_EVEN, 1, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 gcc_sdcc1_apps_clk_src = {
+       .cmd_rcgr = 0x4b024,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_7,
+       .freq_tbl = ftbl_gcc_sdcc1_apps_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_sdcc1_apps_clk_src",
+               .parent_data = gcc_parent_data_7,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_7),
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_gcc_sdcc1_ice_core_clk_src[] = {
+       F(100000000, P_GPLL0_OUT_EVEN, 3, 0, 0),
+       F(150000000, P_GPLL0_OUT_EVEN, 2, 0, 0),
+       F(300000000, P_GPLL0_OUT_EVEN, 1, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 gcc_sdcc1_ice_core_clk_src = {
+       .cmd_rcgr = 0x4b00c,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_1,
+       .freq_tbl = ftbl_gcc_sdcc1_ice_core_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_sdcc1_ice_core_clk_src",
+               .parent_data = gcc_parent_data_1,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_1),
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_gcc_sdcc2_apps_clk_src[] = {
+       F(400000, P_BI_TCXO, 12, 1, 4),
+       F(9600000, P_BI_TCXO, 2, 0, 0),
+       F(19200000, P_BI_TCXO, 1, 0, 0),
+       F(25000000, P_GPLL0_OUT_ODD, 8, 0, 0),
+       F(50000000, P_GPLL0_OUT_ODD, 4, 0, 0),
+       F(100000000, P_GPLL0_OUT_ODD, 2, 0, 0),
+       F(202000000, P_GPLL7_OUT_MAIN, 4, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 gcc_sdcc2_apps_clk_src = {
+       .cmd_rcgr = 0x2000c,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_8,
+       .freq_tbl = ftbl_gcc_sdcc2_apps_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_sdcc2_apps_clk_src",
+               .parent_data = gcc_parent_data_8,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_8),
+               .ops = &clk_rcg2_floor_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_gcc_ufs_phy_axi_clk_src[] = {
+       F(25000000, P_GPLL0_OUT_ODD, 8, 0, 0),
+       F(50000000, P_GPLL0_OUT_ODD, 4, 0, 0),
+       F(100000000, P_GPLL0_OUT_ODD, 2, 0, 0),
+       F(200000000, P_GPLL0_OUT_ODD, 1, 0, 0),
+       F(240000000, P_GPLL0_OUT_MAIN, 2.5, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 gcc_ufs_phy_axi_clk_src = {
+       .cmd_rcgr = 0x3a01c,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_4,
+       .freq_tbl = ftbl_gcc_ufs_phy_axi_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_ufs_phy_axi_clk_src",
+               .parent_data = gcc_parent_data_4,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_4),
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_gcc_ufs_phy_ice_core_clk_src[] = {
+       F(37500000, P_GPLL0_OUT_EVEN, 8, 0, 0),
+       F(75000000, P_GPLL0_OUT_EVEN, 4, 0, 0),
+       F(150000000, P_GPLL0_OUT_EVEN, 2, 0, 0),
+       F(300000000, P_GPLL0_OUT_EVEN, 1, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 gcc_ufs_phy_ice_core_clk_src = {
+       .cmd_rcgr = 0x3a048,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_1,
+       .freq_tbl = ftbl_gcc_ufs_phy_ice_core_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_ufs_phy_ice_core_clk_src",
+               .parent_data = gcc_parent_data_1,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_1),
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_gcc_ufs_phy_phy_aux_clk_src[] = {
+       F(9600000, P_BI_TCXO, 2, 0, 0),
+       F(19200000, P_BI_TCXO, 1, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 gcc_ufs_phy_phy_aux_clk_src = {
+       .cmd_rcgr = 0x3a0b0,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .freq_tbl = ftbl_gcc_ufs_phy_phy_aux_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_ufs_phy_phy_aux_clk_src",
+               .parent_data = &(const struct clk_parent_data){
+                       .fw_name = "bi_tcxo",
+               },
+               .num_parents = 1,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_gcc_ufs_phy_unipro_core_clk_src[] = {
+       F(37500000, P_GPLL0_OUT_EVEN, 8, 0, 0),
+       F(75000000, P_GPLL0_OUT_EVEN, 4, 0, 0),
+       F(150000000, P_GPLL0_OUT_EVEN, 2, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 gcc_ufs_phy_unipro_core_clk_src = {
+       .cmd_rcgr = 0x3a060,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_1,
+       .freq_tbl = ftbl_gcc_ufs_phy_unipro_core_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_ufs_phy_unipro_core_clk_src",
+               .parent_data = gcc_parent_data_1,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_1),
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_gcc_usb30_prim_master_clk_src[] = {
+       F(66666667, P_GPLL0_OUT_ODD, 3, 0, 0),
+       F(133333333, P_GPLL0_OUT_MAIN, 4.5, 0, 0),
+       F(200000000, P_GPLL0_OUT_MAIN, 3, 0, 0),
+       F(240000000, P_GPLL0_OUT_MAIN, 2.5, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 gcc_usb30_prim_master_clk_src = {
+       .cmd_rcgr = 0x1a01c,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_4,
+       .freq_tbl = ftbl_gcc_usb30_prim_master_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_usb30_prim_master_clk_src",
+               .parent_data = gcc_parent_data_4,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_4),
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_gcc_usb30_prim_mock_utmi_clk_src[] = {
+       F(19200000, P_BI_TCXO, 1, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 gcc_usb30_prim_mock_utmi_clk_src = {
+       .cmd_rcgr = 0x1a034,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .freq_tbl = ftbl_gcc_usb30_prim_mock_utmi_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_usb30_prim_mock_utmi_clk_src",
+               .parent_data = &(const struct clk_parent_data){
+                       .fw_name = "bi_tcxo",
+               },
+               .num_parents = 1,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 gcc_usb3_prim_phy_aux_clk_src = {
+       .cmd_rcgr = 0x1a060,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = gcc_parent_map_6,
+       .freq_tbl = ftbl_gcc_usb30_prim_mock_utmi_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gcc_usb3_prim_phy_aux_clk_src",
+               .parent_data = gcc_parent_data_6,
+               .num_parents = ARRAY_SIZE(gcc_parent_data_6),
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_branch gcc_aggre_ufs_phy_axi_clk = {
+       .halt_reg = 0x3e014,
+       .halt_check = BRANCH_HALT_DELAY,
+       .hwcg_reg = 0x3e014,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x3e014,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_aggre_ufs_phy_axi_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &gcc_ufs_phy_axi_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_aggre_ufs_phy_axi_hw_ctl_clk = {
+       .halt_reg = 0x3e014,
+       .halt_check = BRANCH_HALT,
+       .hwcg_reg = 0x3e014,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x3e014,
+               .enable_mask = BIT(1),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_aggre_ufs_phy_axi_hw_ctl_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &gcc_ufs_phy_axi_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_ufs_phy_axi_hw_ctl_clk = {
+       .halt_reg = 0x3e014,
+       .halt_check = BRANCH_HALT,
+       .hwcg_reg = 0x3e014,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x3e014,
+               .enable_mask = BIT(1),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_ufs_phy_axi_hw_ctl_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &gcc_ufs_phy_axi_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_aggre_usb3_prim_axi_clk = {
+       .halt_reg = 0x3e010,
+       .halt_check = BRANCH_HALT,
+       .hwcg_reg = 0x3e010,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x3e010,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_aggre_usb3_prim_axi_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &gcc_usb30_prim_master_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_boot_rom_ahb_clk = {
+       .halt_reg = 0x26004,
+       .halt_check = BRANCH_HALT_VOTED,
+       .hwcg_reg = 0x26004,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x52000,
+               .enable_mask = BIT(28),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_boot_rom_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_camera_ahb_clk = {
+       .halt_reg = 0x17008,
+       .halt_check = BRANCH_HALT,
+       .hwcg_reg = 0x17008,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x17008,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_camera_ahb_clk",
+                       .flags = CLK_IS_CRITICAL,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_camera_axi_clk = {
+       .halt_reg = 0x17018,
+       .halt_check = BRANCH_HALT,
+       .hwcg_reg = 0x17018,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x17018,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_camera_axi_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_camera_throttle_nrt_axi_clk = {
+       .halt_reg = 0x17078,
+       .halt_check = BRANCH_VOTED,
+       .hwcg_reg = 0x17078,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x17078,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_camera_throttle_nrt_axi_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_camera_throttle_rt_axi_clk = {
+       .halt_reg = 0x17024,
+       .halt_check = BRANCH_VOTED,
+       .hwcg_reg = 0x17024,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x17024,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_camera_throttle_rt_axi_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_camera_xo_clk = {
+       .halt_reg = 0x17030,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x17030,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_camera_xo_clk",
+                       .flags = CLK_IS_CRITICAL,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_ce1_ahb_clk = {
+       .halt_reg = 0x2b00c,
+       .halt_check = BRANCH_HALT_VOTED,
+       .hwcg_reg = 0x2b00c,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x52008,
+               .enable_mask = BIT(3),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_ce1_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_ce1_axi_clk = {
+       .halt_reg = 0x2b008,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x52008,
+               .enable_mask = BIT(2),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_ce1_axi_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_ce1_clk = {
+       .halt_reg = 0x2b004,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x52008,
+               .enable_mask = BIT(1),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_ce1_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_cfg_noc_usb3_prim_axi_clk = {
+       .halt_reg = 0x1101c,
+       .halt_check = BRANCH_HALT,
+       .hwcg_reg = 0x1101c,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x1101c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_cfg_noc_usb3_prim_axi_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &gcc_usb30_prim_master_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_cpuss_ahb_clk = {
+       .halt_reg = 0x30000,
+       .halt_check = BRANCH_HALT_VOTED,
+       .hwcg_reg = 0x30000,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x52008,
+               .enable_mask = BIT(4),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_cpuss_ahb_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &gcc_cpuss_ahb_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_IS_CRITICAL | CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_cpuss_gnoc_clk = {
+       .halt_reg = 0x30004,
+       .halt_check = BRANCH_HALT_VOTED,
+       .hwcg_reg = 0x30004,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x52008,
+               .enable_mask = BIT(5),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_cpuss_gnoc_clk",
+                       .flags = CLK_IS_CRITICAL,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_cpuss_rbcpr_clk = {
+       .halt_reg = 0x30008,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x30008,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_cpuss_rbcpr_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_ddrss_gpu_axi_clk = {
+       .halt_reg = 0x2d038,
+       .halt_check = BRANCH_VOTED,
+       .hwcg_reg = 0x2d038,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x2d038,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_ddrss_gpu_axi_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_disp_ahb_clk = {
+       .halt_reg = 0x1700c,
+       .halt_check = BRANCH_HALT,
+       .hwcg_reg = 0x1700c,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x1700c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_disp_ahb_clk",
+                       .flags = CLK_IS_CRITICAL,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_disp_axi_clk = {
+       .halt_reg = 0x1701c,
+       .halt_check = BRANCH_HALT,
+       .hwcg_reg = 0x1701c,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x1701c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_disp_axi_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_disp_cc_sleep_clk = {
+       .halt_reg = 0x17074,
+       .halt_check = BRANCH_HALT_DELAY,
+       .hwcg_reg = 0x17074,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x17074,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_disp_cc_sleep_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_disp_cc_xo_clk = {
+       .halt_reg = 0x17070,
+       .halt_check = BRANCH_HALT,
+       .hwcg_reg = 0x17070,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x17070,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_disp_cc_xo_clk",
+                       .flags = CLK_IS_CRITICAL,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_disp_gpll0_clk = {
+       .halt_check = BRANCH_HALT_DELAY,
+       .clkr = {
+               .enable_reg = 0x52000,
+               .enable_mask = BIT(2),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_disp_gpll0_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &gpll0.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_disp_throttle_axi_clk = {
+       .halt_reg = 0x17028,
+       .halt_check = BRANCH_HALT,
+       .hwcg_reg = 0x17028,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x17028,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_disp_throttle_axi_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_disp_xo_clk = {
+       .halt_reg = 0x17034,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x17034,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_disp_xo_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_gp1_clk = {
+       .halt_reg = 0x37000,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x37000,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_gp1_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &gcc_gp1_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_gp2_clk = {
+       .halt_reg = 0x38000,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x38000,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_gp2_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &gcc_gp2_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_gp3_clk = {
+       .halt_reg = 0x39000,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x39000,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_gp3_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &gcc_gp3_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_gpu_cfg_ahb_clk = {
+       .halt_reg = 0x45004,
+       .halt_check = BRANCH_HALT,
+       .hwcg_reg = 0x45004,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x45004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_gpu_cfg_ahb_clk",
+                       .flags = CLK_IS_CRITICAL,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_gpu_gpll0_clk = {
+       .halt_check = BRANCH_HALT_DELAY,
+       .clkr = {
+               .enable_reg = 0x52008,
+               .enable_mask = BIT(7),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_gpu_gpll0_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &gpll0.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_gpu_gpll0_div_clk = {
+       .halt_check = BRANCH_HALT_DELAY,
+       .clkr = {
+               .enable_reg = 0x52008,
+               .enable_mask = BIT(8),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_gpu_gpll0_div_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &gcc_gpu_gpll0_main_div_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_gpu_memnoc_gfx_clk = {
+       .halt_reg = 0x4500c,
+       .halt_check = BRANCH_VOTED,
+       .hwcg_reg = 0x4500c,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x4500c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_gpu_memnoc_gfx_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_gpu_snoc_dvm_gfx_clk = {
+       .halt_reg = 0x45014,
+       .halt_check = BRANCH_HALT,
+       .hwcg_reg = 0x45014,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x45014,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_gpu_snoc_dvm_gfx_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_npu_axi_clk = {
+       .halt_reg = 0x4c008,
+       .halt_check = BRANCH_VOTED,
+       .hwcg_reg = 0x4c008,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x4c008,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_npu_axi_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_npu_bwmon_axi_clk = {
+       .halt_reg = 0x4d004,
+       .halt_check = BRANCH_HALT_DELAY,
+       .hwcg_reg = 0x4d004,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x4d004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_npu_bwmon_axi_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_npu_bwmon_dma_cfg_ahb_clk = {
+       .halt_reg = 0x4d008,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x4d008,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_npu_bwmon_dma_cfg_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_npu_bwmon_dsp_cfg_ahb_clk = {
+       .halt_reg = 0x4d00c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x4d00c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_npu_bwmon_dsp_cfg_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_npu_cfg_ahb_clk = {
+       .halt_reg = 0x4c004,
+       .halt_check = BRANCH_HALT,
+       .hwcg_reg = 0x4c004,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x4c004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_npu_cfg_ahb_clk",
+                       .flags = CLK_IS_CRITICAL,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_npu_dma_clk = {
+       .halt_reg = 0x4c140,
+       .halt_check = BRANCH_VOTED,
+       .hwcg_reg = 0x4c140,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x4c140,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_npu_dma_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_npu_gpll0_clk = {
+       .halt_check = BRANCH_HALT_DELAY,
+       .clkr = {
+               .enable_reg = 0x52008,
+               .enable_mask = BIT(9),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_npu_gpll0_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &gpll0.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_npu_gpll0_div_clk = {
+       .halt_check = BRANCH_HALT_DELAY,
+       .clkr = {
+               .enable_reg = 0x52008,
+               .enable_mask = BIT(10),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_npu_gpll0_div_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &gcc_npu_pll0_main_div_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_pdm2_clk = {
+       .halt_reg = 0x2300c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x2300c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_pdm2_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &gcc_pdm2_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_pdm_ahb_clk = {
+       .halt_reg = 0x23004,
+       .halt_check = BRANCH_HALT,
+       .hwcg_reg = 0x23004,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x23004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_pdm_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_pdm_xo4_clk = {
+       .halt_reg = 0x23008,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x23008,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_pdm_xo4_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_prng_ahb_clk = {
+       .halt_reg = 0x24004,
+       .halt_check = BRANCH_HALT_VOTED,
+       .hwcg_reg = 0x24004,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x52000,
+               .enable_mask = BIT(26),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_prng_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_qupv3_wrap0_core_2x_clk = {
+       .halt_reg = 0x21014,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x52000,
+               .enable_mask = BIT(9),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qupv3_wrap0_core_2x_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_qupv3_wrap0_core_clk = {
+       .halt_reg = 0x2100c,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x52000,
+               .enable_mask = BIT(8),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qupv3_wrap0_core_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_qupv3_wrap0_s0_clk = {
+       .halt_reg = 0x21144,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x52000,
+               .enable_mask = BIT(10),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qupv3_wrap0_s0_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &gcc_qupv3_wrap0_s0_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_qupv3_wrap0_s1_clk = {
+       .halt_reg = 0x21274,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x52000,
+               .enable_mask = BIT(11),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qupv3_wrap0_s1_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &gcc_qupv3_wrap0_s1_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_qupv3_wrap0_s2_clk = {
+       .halt_reg = 0x213a4,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x52000,
+               .enable_mask = BIT(12),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qupv3_wrap0_s2_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &gcc_qupv3_wrap0_s2_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_qupv3_wrap0_s3_clk = {
+       .halt_reg = 0x214d4,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x52000,
+               .enable_mask = BIT(13),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qupv3_wrap0_s3_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &gcc_qupv3_wrap0_s3_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_qupv3_wrap0_s4_clk = {
+       .halt_reg = 0x21604,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x52000,
+               .enable_mask = BIT(14),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qupv3_wrap0_s4_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &gcc_qupv3_wrap0_s4_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_qupv3_wrap0_s5_clk = {
+       .halt_reg = 0x21734,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x52000,
+               .enable_mask = BIT(15),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qupv3_wrap0_s5_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &gcc_qupv3_wrap0_s5_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_qupv3_wrap1_core_2x_clk = {
+       .halt_reg = 0x22004,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x52000,
+               .enable_mask = BIT(16),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qupv3_wrap1_core_2x_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_qupv3_wrap1_core_clk = {
+       .halt_reg = 0x22008,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x52000,
+               .enable_mask = BIT(17),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qupv3_wrap1_core_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_qupv3_wrap1_s0_clk = {
+       .halt_reg = 0x22014,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x52000,
+               .enable_mask = BIT(20),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qupv3_wrap1_s0_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &gcc_qupv3_wrap1_s0_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_qupv3_wrap1_s1_clk = {
+       .halt_reg = 0x22144,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x52000,
+               .enable_mask = BIT(21),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qupv3_wrap1_s1_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &gcc_qupv3_wrap1_s1_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_qupv3_wrap1_s2_clk = {
+       .halt_reg = 0x22274,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x52000,
+               .enable_mask = BIT(22),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qupv3_wrap1_s2_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &gcc_qupv3_wrap1_s2_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_qupv3_wrap1_s3_clk = {
+       .halt_reg = 0x223a4,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x52000,
+               .enable_mask = BIT(23),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qupv3_wrap1_s3_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &gcc_qupv3_wrap1_s3_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_qupv3_wrap1_s4_clk = {
+       .halt_reg = 0x224d4,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x52000,
+               .enable_mask = BIT(24),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qupv3_wrap1_s4_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &gcc_qupv3_wrap1_s4_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_qupv3_wrap1_s5_clk = {
+       .halt_reg = 0x22604,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x52000,
+               .enable_mask = BIT(25),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qupv3_wrap1_s5_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &gcc_qupv3_wrap1_s5_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_qupv3_wrap_0_m_ahb_clk = {
+       .halt_reg = 0x21004,
+       .halt_check = BRANCH_HALT_VOTED,
+       .hwcg_reg = 0x21004,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x52000,
+               .enable_mask = BIT(6),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qupv3_wrap_0_m_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_qupv3_wrap_0_s_ahb_clk = {
+       .halt_reg = 0x21008,
+       .halt_check = BRANCH_HALT_VOTED,
+       .hwcg_reg = 0x21008,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x52000,
+               .enable_mask = BIT(7),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qupv3_wrap_0_s_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_qupv3_wrap_1_m_ahb_clk = {
+       .halt_reg = 0x2200c,
+       .halt_check = BRANCH_HALT_VOTED,
+       .hwcg_reg = 0x2200c,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x52000,
+               .enable_mask = BIT(18),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qupv3_wrap_1_m_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_qupv3_wrap_1_s_ahb_clk = {
+       .halt_reg = 0x22010,
+       .halt_check = BRANCH_HALT_VOTED,
+       .hwcg_reg = 0x22010,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x52000,
+               .enable_mask = BIT(19),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qupv3_wrap_1_s_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_sdcc1_ahb_clk = {
+       .halt_reg = 0x4b004,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x4b004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_sdcc1_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_sdcc1_apps_clk = {
+       .halt_reg = 0x4b008,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x4b008,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_sdcc1_apps_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &gcc_sdcc1_apps_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_sdcc1_ice_core_clk = {
+       .halt_reg = 0x4b03c,
+       .halt_check = BRANCH_HALT,
+       .hwcg_reg = 0x4b03c,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x4b03c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_sdcc1_ice_core_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &gcc_sdcc1_ice_core_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_sdcc2_ahb_clk = {
+       .halt_reg = 0x20008,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x20008,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_sdcc2_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_sdcc2_apps_clk = {
+       .halt_reg = 0x20004,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x20004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_sdcc2_apps_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &gcc_sdcc2_apps_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_sys_noc_cpuss_ahb_clk = {
+       .halt_reg = 0x10140,
+       .halt_check = BRANCH_HALT_VOTED,
+       .hwcg_reg = 0x10140,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x52000,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_sys_noc_cpuss_ahb_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &gcc_cpuss_ahb_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_IS_CRITICAL | CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_ufs_mem_clkref_clk = {
+       .halt_reg = 0x8c000,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x8c000,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_ufs_mem_clkref_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_ufs_phy_ahb_clk = {
+       .halt_reg = 0x3a00c,
+       .halt_check = BRANCH_HALT,
+       .hwcg_reg = 0x3a00c,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x3a00c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_ufs_phy_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_ufs_phy_axi_clk = {
+       .halt_reg = 0x3a034,
+       .halt_check = BRANCH_HALT,
+       .hwcg_reg = 0x3a034,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x3a034,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_ufs_phy_axi_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &gcc_ufs_phy_axi_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_ufs_phy_ice_core_clk = {
+       .halt_reg = 0x3a0a4,
+       .halt_check = BRANCH_HALT,
+       .hwcg_reg = 0x3a0a4,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x3a0a4,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_ufs_phy_ice_core_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &gcc_ufs_phy_ice_core_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_ufs_phy_ice_core_hw_ctl_clk = {
+       .halt_reg = 0x3a0a4,
+       .halt_check = BRANCH_HALT,
+       .hwcg_reg = 0x3a0a4,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x3a0a4,
+               .enable_mask = BIT(1),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_ufs_phy_ice_core_hw_ctl_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &gcc_ufs_phy_ice_core_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_ufs_phy_phy_aux_clk = {
+       .halt_reg = 0x3a0ac,
+       .halt_check = BRANCH_HALT,
+       .hwcg_reg = 0x3a0ac,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x3a0ac,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_ufs_phy_phy_aux_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &gcc_ufs_phy_phy_aux_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_ufs_phy_phy_aux_hw_ctl_clk = {
+       .halt_reg = 0x3a0ac,
+       .halt_check = BRANCH_HALT,
+       .hwcg_reg = 0x3a0ac,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x3a0ac,
+               .enable_mask = BIT(1),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_ufs_phy_phy_aux_hw_ctl_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &gcc_ufs_phy_phy_aux_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_ufs_phy_rx_symbol_0_clk = {
+       .halt_reg = 0x3a014,
+       .halt_check = BRANCH_HALT_SKIP,
+       .clkr = {
+               .enable_reg = 0x3a014,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_ufs_phy_rx_symbol_0_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_ufs_phy_rx_symbol_1_clk = {
+       .halt_reg = 0x3a018,
+       .halt_check = BRANCH_HALT_SKIP,
+       .clkr = {
+               .enable_reg = 0x3a018,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_ufs_phy_rx_symbol_1_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_ufs_phy_tx_symbol_0_clk = {
+       .halt_reg = 0x3a010,
+       .halt_check = BRANCH_HALT_SKIP,
+       .clkr = {
+               .enable_reg = 0x3a010,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_ufs_phy_tx_symbol_0_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_ufs_phy_unipro_core_clk = {
+       .halt_reg = 0x3a09c,
+       .halt_check = BRANCH_HALT,
+       .hwcg_reg = 0x3a09c,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x3a09c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_ufs_phy_unipro_core_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &gcc_ufs_phy_unipro_core_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_ufs_phy_unipro_core_hw_ctl_clk = {
+       .halt_reg = 0x3a09c,
+       .halt_check = BRANCH_HALT,
+       .hwcg_reg = 0x3a09c,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x3a09c,
+               .enable_mask = BIT(1),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_ufs_phy_unipro_core_hw_ctl_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &gcc_ufs_phy_unipro_core_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_usb30_prim_master_clk = {
+       .halt_reg = 0x1a00c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x1a00c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_usb30_prim_master_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &gcc_usb30_prim_master_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_usb30_prim_mock_utmi_clk = {
+       .halt_reg = 0x1a018,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x1a018,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_usb30_prim_mock_utmi_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &gcc_usb30_prim_mock_utmi_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_usb30_prim_sleep_clk = {
+       .halt_reg = 0x1a014,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x1a014,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_usb30_prim_sleep_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_usb3_prim_clkref_clk = {
+       .halt_reg = 0x8c010,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x8c010,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_usb3_prim_clkref_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_usb3_prim_phy_aux_clk = {
+       .halt_reg = 0x1a050,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x1a050,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_usb3_prim_phy_aux_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &gcc_usb3_prim_phy_aux_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_usb3_prim_phy_com_aux_clk = {
+       .halt_reg = 0x1a054,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x1a054,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_usb3_prim_phy_com_aux_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &gcc_usb3_prim_phy_aux_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_usb3_prim_phy_pipe_clk = {
+       .halt_reg = 0x1a058,
+       .halt_check = BRANCH_HALT_SKIP,
+       .hwcg_reg = 0x1a058,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x1a058,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_usb3_prim_phy_pipe_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_video_ahb_clk = {
+       .halt_reg = 0x17004,
+       .halt_check = BRANCH_HALT,
+       .hwcg_reg = 0x17004,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x17004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_video_ahb_clk",
+                       .flags = CLK_IS_CRITICAL,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_video_axi_clk = {
+       .halt_reg = 0x17014,
+       .halt_check = BRANCH_HALT,
+       .hwcg_reg = 0x17014,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x17014,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_video_axi_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_video_throttle_axi_clk = {
+       .halt_reg = 0x17020,
+       .halt_check = BRANCH_HALT,
+       .hwcg_reg = 0x17020,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x17020,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_video_throttle_axi_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_video_xo_clk = {
+       .halt_reg = 0x1702c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x1702c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_video_xo_clk",
+                       .flags = CLK_IS_CRITICAL,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct gdsc usb30_prim_gdsc = {
+       .gdscr = 0x1a004,
+       .pd = {
+               .name = "usb30_prim_gdsc",
+       },
+       .pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct gdsc ufs_phy_gdsc = {
+       .gdscr = 0x3a004,
+       .pd = {
+               .name = "ufs_phy_gdsc",
+       },
+       .pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct gdsc hlos1_vote_mmnoc_mmu_tbu_hf0_gdsc = {
+       .gdscr = 0xb7040,
+       .pd = {
+               .name = "hlos1_vote_mmnoc_mmu_tbu_hf0_gdsc",
+       },
+       .pwrsts = PWRSTS_OFF_ON,
+       .flags = VOTABLE,
+};
+
+static struct gdsc hlos1_vote_mmnoc_mmu_tbu_hf1_gdsc = {
+       .gdscr = 0xb7044,
+       .pd = {
+               .name = "hlos1_vote_mmnoc_mmu_tbu_hf1_gdsc",
+       },
+       .pwrsts = PWRSTS_OFF_ON,
+       .flags = VOTABLE,
+};
+
+static struct clk_regmap *gcc_sm6350_clocks[] = {
+       [GCC_AGGRE_UFS_PHY_AXI_CLK] = &gcc_aggre_ufs_phy_axi_clk.clkr,
+       [GCC_AGGRE_USB3_PRIM_AXI_CLK] = &gcc_aggre_usb3_prim_axi_clk.clkr,
+       [GCC_BOOT_ROM_AHB_CLK] = &gcc_boot_rom_ahb_clk.clkr,
+       [GCC_CAMERA_AHB_CLK] = &gcc_camera_ahb_clk.clkr,
+       [GCC_CAMERA_AXI_CLK] = &gcc_camera_axi_clk.clkr,
+       [GCC_CAMERA_THROTTLE_NRT_AXI_CLK] =
+               &gcc_camera_throttle_nrt_axi_clk.clkr,
+       [GCC_CAMERA_THROTTLE_RT_AXI_CLK] = &gcc_camera_throttle_rt_axi_clk.clkr,
+       [GCC_CAMERA_XO_CLK] = &gcc_camera_xo_clk.clkr,
+       [GCC_CE1_AHB_CLK] = &gcc_ce1_ahb_clk.clkr,
+       [GCC_CE1_AXI_CLK] = &gcc_ce1_axi_clk.clkr,
+       [GCC_CE1_CLK] = &gcc_ce1_clk.clkr,
+       [GCC_CFG_NOC_USB3_PRIM_AXI_CLK] = &gcc_cfg_noc_usb3_prim_axi_clk.clkr,
+       [GCC_CPUSS_AHB_CLK] = &gcc_cpuss_ahb_clk.clkr,
+       [GCC_CPUSS_AHB_CLK_SRC] = &gcc_cpuss_ahb_clk_src.clkr,
+       [GCC_CPUSS_GNOC_CLK] = &gcc_cpuss_gnoc_clk.clkr,
+       [GCC_CPUSS_RBCPR_CLK] = &gcc_cpuss_rbcpr_clk.clkr,
+       [GCC_DDRSS_GPU_AXI_CLK] = &gcc_ddrss_gpu_axi_clk.clkr,
+       [GCC_DISP_AHB_CLK] = &gcc_disp_ahb_clk.clkr,
+       [GCC_DISP_AXI_CLK] = &gcc_disp_axi_clk.clkr,
+       [GCC_DISP_CC_SLEEP_CLK] = &gcc_disp_cc_sleep_clk.clkr,
+       [GCC_DISP_CC_XO_CLK] = &gcc_disp_cc_xo_clk.clkr,
+       [GCC_DISP_GPLL0_CLK] = &gcc_disp_gpll0_clk.clkr,
+       [GCC_DISP_THROTTLE_AXI_CLK] = &gcc_disp_throttle_axi_clk.clkr,
+       [GCC_DISP_XO_CLK] = &gcc_disp_xo_clk.clkr,
+       [GCC_GP1_CLK] = &gcc_gp1_clk.clkr,
+       [GCC_GP1_CLK_SRC] = &gcc_gp1_clk_src.clkr,
+       [GCC_GP2_CLK] = &gcc_gp2_clk.clkr,
+       [GCC_GP2_CLK_SRC] = &gcc_gp2_clk_src.clkr,
+       [GCC_GP3_CLK] = &gcc_gp3_clk.clkr,
+       [GCC_GP3_CLK_SRC] = &gcc_gp3_clk_src.clkr,
+       [GCC_GPU_CFG_AHB_CLK] = &gcc_gpu_cfg_ahb_clk.clkr,
+       [GCC_GPU_GPLL0_CLK] = &gcc_gpu_gpll0_clk.clkr,
+       [GCC_GPU_GPLL0_DIV_CLK] = &gcc_gpu_gpll0_div_clk.clkr,
+       [GCC_GPU_MEMNOC_GFX_CLK] = &gcc_gpu_memnoc_gfx_clk.clkr,
+       [GCC_GPU_SNOC_DVM_GFX_CLK] = &gcc_gpu_snoc_dvm_gfx_clk.clkr,
+       [GCC_NPU_AXI_CLK] = &gcc_npu_axi_clk.clkr,
+       [GCC_NPU_BWMON_AXI_CLK] = &gcc_npu_bwmon_axi_clk.clkr,
+       [GCC_NPU_BWMON_DMA_CFG_AHB_CLK] = &gcc_npu_bwmon_dma_cfg_ahb_clk.clkr,
+       [GCC_NPU_BWMON_DSP_CFG_AHB_CLK] = &gcc_npu_bwmon_dsp_cfg_ahb_clk.clkr,
+       [GCC_NPU_CFG_AHB_CLK] = &gcc_npu_cfg_ahb_clk.clkr,
+       [GCC_NPU_DMA_CLK] = &gcc_npu_dma_clk.clkr,
+       [GCC_NPU_GPLL0_CLK] = &gcc_npu_gpll0_clk.clkr,
+       [GCC_NPU_GPLL0_DIV_CLK] = &gcc_npu_gpll0_div_clk.clkr,
+       [GCC_PDM2_CLK] = &gcc_pdm2_clk.clkr,
+       [GCC_PDM2_CLK_SRC] = &gcc_pdm2_clk_src.clkr,
+       [GCC_PDM_AHB_CLK] = &gcc_pdm_ahb_clk.clkr,
+       [GCC_PDM_XO4_CLK] = &gcc_pdm_xo4_clk.clkr,
+       [GCC_PRNG_AHB_CLK] = &gcc_prng_ahb_clk.clkr,
+       [GCC_QUPV3_WRAP0_CORE_2X_CLK] = &gcc_qupv3_wrap0_core_2x_clk.clkr,
+       [GCC_QUPV3_WRAP0_CORE_CLK] = &gcc_qupv3_wrap0_core_clk.clkr,
+       [GCC_QUPV3_WRAP0_S0_CLK] = &gcc_qupv3_wrap0_s0_clk.clkr,
+       [GCC_QUPV3_WRAP0_S0_CLK_SRC] = &gcc_qupv3_wrap0_s0_clk_src.clkr,
+       [GCC_QUPV3_WRAP0_S1_CLK] = &gcc_qupv3_wrap0_s1_clk.clkr,
+       [GCC_QUPV3_WRAP0_S1_CLK_SRC] = &gcc_qupv3_wrap0_s1_clk_src.clkr,
+       [GCC_QUPV3_WRAP0_S2_CLK] = &gcc_qupv3_wrap0_s2_clk.clkr,
+       [GCC_QUPV3_WRAP0_S2_CLK_SRC] = &gcc_qupv3_wrap0_s2_clk_src.clkr,
+       [GCC_QUPV3_WRAP0_S3_CLK] = &gcc_qupv3_wrap0_s3_clk.clkr,
+       [GCC_QUPV3_WRAP0_S3_CLK_SRC] = &gcc_qupv3_wrap0_s3_clk_src.clkr,
+       [GCC_QUPV3_WRAP0_S4_CLK] = &gcc_qupv3_wrap0_s4_clk.clkr,
+       [GCC_QUPV3_WRAP0_S4_CLK_SRC] = &gcc_qupv3_wrap0_s4_clk_src.clkr,
+       [GCC_QUPV3_WRAP0_S5_CLK] = &gcc_qupv3_wrap0_s5_clk.clkr,
+       [GCC_QUPV3_WRAP0_S5_CLK_SRC] = &gcc_qupv3_wrap0_s5_clk_src.clkr,
+       [GCC_QUPV3_WRAP1_CORE_2X_CLK] = &gcc_qupv3_wrap1_core_2x_clk.clkr,
+       [GCC_QUPV3_WRAP1_CORE_CLK] = &gcc_qupv3_wrap1_core_clk.clkr,
+       [GCC_QUPV3_WRAP1_S0_CLK] = &gcc_qupv3_wrap1_s0_clk.clkr,
+       [GCC_QUPV3_WRAP1_S0_CLK_SRC] = &gcc_qupv3_wrap1_s0_clk_src.clkr,
+       [GCC_QUPV3_WRAP1_S1_CLK] = &gcc_qupv3_wrap1_s1_clk.clkr,
+       [GCC_QUPV3_WRAP1_S1_CLK_SRC] = &gcc_qupv3_wrap1_s1_clk_src.clkr,
+       [GCC_QUPV3_WRAP1_S2_CLK] = &gcc_qupv3_wrap1_s2_clk.clkr,
+       [GCC_QUPV3_WRAP1_S2_CLK_SRC] = &gcc_qupv3_wrap1_s2_clk_src.clkr,
+       [GCC_QUPV3_WRAP1_S3_CLK] = &gcc_qupv3_wrap1_s3_clk.clkr,
+       [GCC_QUPV3_WRAP1_S3_CLK_SRC] = &gcc_qupv3_wrap1_s3_clk_src.clkr,
+       [GCC_QUPV3_WRAP1_S4_CLK] = &gcc_qupv3_wrap1_s4_clk.clkr,
+       [GCC_QUPV3_WRAP1_S4_CLK_SRC] = &gcc_qupv3_wrap1_s4_clk_src.clkr,
+       [GCC_QUPV3_WRAP1_S5_CLK] = &gcc_qupv3_wrap1_s5_clk.clkr,
+       [GCC_QUPV3_WRAP1_S5_CLK_SRC] = &gcc_qupv3_wrap1_s5_clk_src.clkr,
+       [GCC_QUPV3_WRAP_0_M_AHB_CLK] = &gcc_qupv3_wrap_0_m_ahb_clk.clkr,
+       [GCC_QUPV3_WRAP_0_S_AHB_CLK] = &gcc_qupv3_wrap_0_s_ahb_clk.clkr,
+       [GCC_QUPV3_WRAP_1_M_AHB_CLK] = &gcc_qupv3_wrap_1_m_ahb_clk.clkr,
+       [GCC_QUPV3_WRAP_1_S_AHB_CLK] = &gcc_qupv3_wrap_1_s_ahb_clk.clkr,
+       [GCC_SDCC1_AHB_CLK] = &gcc_sdcc1_ahb_clk.clkr,
+       [GCC_SDCC1_APPS_CLK] = &gcc_sdcc1_apps_clk.clkr,
+       [GCC_SDCC1_APPS_CLK_SRC] = &gcc_sdcc1_apps_clk_src.clkr,
+       [GCC_SDCC1_ICE_CORE_CLK] = &gcc_sdcc1_ice_core_clk.clkr,
+       [GCC_SDCC1_ICE_CORE_CLK_SRC] = &gcc_sdcc1_ice_core_clk_src.clkr,
+       [GCC_SDCC2_AHB_CLK] = &gcc_sdcc2_ahb_clk.clkr,
+       [GCC_SDCC2_APPS_CLK] = &gcc_sdcc2_apps_clk.clkr,
+       [GCC_SDCC2_APPS_CLK_SRC] = &gcc_sdcc2_apps_clk_src.clkr,
+       [GCC_SYS_NOC_CPUSS_AHB_CLK] = &gcc_sys_noc_cpuss_ahb_clk.clkr,
+       [GCC_UFS_MEM_CLKREF_CLK] = &gcc_ufs_mem_clkref_clk.clkr,
+       [GCC_UFS_PHY_AHB_CLK] = &gcc_ufs_phy_ahb_clk.clkr,
+       [GCC_UFS_PHY_AXI_CLK] = &gcc_ufs_phy_axi_clk.clkr,
+       [GCC_UFS_PHY_AXI_CLK_SRC] = &gcc_ufs_phy_axi_clk_src.clkr,
+       [GCC_UFS_PHY_ICE_CORE_CLK] = &gcc_ufs_phy_ice_core_clk.clkr,
+       [GCC_UFS_PHY_ICE_CORE_CLK_SRC] = &gcc_ufs_phy_ice_core_clk_src.clkr,
+       [GCC_UFS_PHY_PHY_AUX_CLK] = &gcc_ufs_phy_phy_aux_clk.clkr,
+       [GCC_UFS_PHY_PHY_AUX_CLK_SRC] = &gcc_ufs_phy_phy_aux_clk_src.clkr,
+       [GCC_UFS_PHY_RX_SYMBOL_0_CLK] = &gcc_ufs_phy_rx_symbol_0_clk.clkr,
+       [GCC_UFS_PHY_RX_SYMBOL_1_CLK] = &gcc_ufs_phy_rx_symbol_1_clk.clkr,
+       [GCC_UFS_PHY_TX_SYMBOL_0_CLK] = &gcc_ufs_phy_tx_symbol_0_clk.clkr,
+       [GCC_UFS_PHY_UNIPRO_CORE_CLK] = &gcc_ufs_phy_unipro_core_clk.clkr,
+       [GCC_UFS_PHY_UNIPRO_CORE_CLK_SRC] =
+               &gcc_ufs_phy_unipro_core_clk_src.clkr,
+       [GCC_USB30_PRIM_MASTER_CLK] = &gcc_usb30_prim_master_clk.clkr,
+       [GCC_USB30_PRIM_MASTER_CLK_SRC] = &gcc_usb30_prim_master_clk_src.clkr,
+       [GCC_USB30_PRIM_MOCK_UTMI_CLK] = &gcc_usb30_prim_mock_utmi_clk.clkr,
+       [GCC_USB30_PRIM_MOCK_UTMI_CLK_SRC] =
+               &gcc_usb30_prim_mock_utmi_clk_src.clkr,
+       [GCC_USB30_PRIM_SLEEP_CLK] = &gcc_usb30_prim_sleep_clk.clkr,
+       [GCC_USB3_PRIM_CLKREF_CLK] = &gcc_usb3_prim_clkref_clk.clkr,
+       [GCC_USB3_PRIM_PHY_AUX_CLK] = &gcc_usb3_prim_phy_aux_clk.clkr,
+       [GCC_USB3_PRIM_PHY_AUX_CLK_SRC] = &gcc_usb3_prim_phy_aux_clk_src.clkr,
+       [GCC_USB3_PRIM_PHY_COM_AUX_CLK] = &gcc_usb3_prim_phy_com_aux_clk.clkr,
+       [GCC_USB3_PRIM_PHY_PIPE_CLK] = &gcc_usb3_prim_phy_pipe_clk.clkr,
+       [GCC_VIDEO_AHB_CLK] = &gcc_video_ahb_clk.clkr,
+       [GCC_VIDEO_AXI_CLK] = &gcc_video_axi_clk.clkr,
+       [GCC_VIDEO_THROTTLE_AXI_CLK] = &gcc_video_throttle_axi_clk.clkr,
+       [GCC_VIDEO_XO_CLK] = &gcc_video_xo_clk.clkr,
+       [GPLL0] = &gpll0.clkr,
+       [GPLL0_OUT_EVEN] = &gpll0_out_even.clkr,
+       [GPLL0_OUT_ODD] = &gpll0_out_odd.clkr,
+       [GPLL6] = &gpll6.clkr,
+       [GPLL6_OUT_EVEN] = &gpll6_out_even.clkr,
+       [GPLL7] = &gpll7.clkr,
+       [GCC_UFS_PHY_PHY_AUX_HW_CTL_CLK] = &gcc_ufs_phy_phy_aux_hw_ctl_clk.clkr,
+       [GCC_UFS_PHY_AXI_HW_CTL_CLK] = &gcc_ufs_phy_axi_hw_ctl_clk.clkr,
+       [GCC_AGGRE_UFS_PHY_AXI_HW_CTL_CLK] =
+                               &gcc_aggre_ufs_phy_axi_hw_ctl_clk.clkr,
+       [GCC_UFS_PHY_UNIPRO_CORE_HW_CTL_CLK] =
+                               &gcc_ufs_phy_unipro_core_hw_ctl_clk.clkr,
+       [GCC_UFS_PHY_ICE_CORE_HW_CTL_CLK] =
+                               &gcc_ufs_phy_ice_core_hw_ctl_clk.clkr,
+       [GCC_GPU_GPLL0_MAIN_DIV_CLK_SRC] = &gcc_gpu_gpll0_main_div_clk_src.clkr,
+       [GCC_NPU_PLL0_MAIN_DIV_CLK_SRC] = &gcc_npu_pll0_main_div_clk_src.clkr,
+};
+
+static struct gdsc *gcc_sm6350_gdscs[] = {
+       [USB30_PRIM_GDSC] = &usb30_prim_gdsc,
+       [UFS_PHY_GDSC] = &ufs_phy_gdsc,
+       [HLOS1_VOTE_MMNOC_MMU_TBU_HF0_GDSC] = &hlos1_vote_mmnoc_mmu_tbu_hf0_gdsc,
+       [HLOS1_VOTE_MMNOC_MMU_TBU_HF1_GDSC] = &hlos1_vote_mmnoc_mmu_tbu_hf1_gdsc,
+};
+
+static const struct qcom_reset_map gcc_sm6350_resets[] = {
+       [GCC_QUSB2PHY_PRIM_BCR] = { 0x1d000 },
+       [GCC_QUSB2PHY_SEC_BCR] = { 0x1e000 },
+       [GCC_SDCC1_BCR] = { 0x4b000 },
+       [GCC_SDCC2_BCR] = { 0x20000 },
+       [GCC_UFS_PHY_BCR] = { 0x3a000 },
+       [GCC_USB30_PRIM_BCR] = { 0x1a000 },
+       [GCC_USB3_PHY_PRIM_BCR] = { 0x1c000 },
+       [GCC_USB3_DP_PHY_PRIM_BCR] = { 0x1c008 },
+};
+
+static const struct clk_rcg_dfs_data gcc_dfs_clocks[] = {
+       DEFINE_RCG_DFS(gcc_qupv3_wrap0_s0_clk_src),
+       DEFINE_RCG_DFS(gcc_qupv3_wrap0_s1_clk_src),
+       DEFINE_RCG_DFS(gcc_qupv3_wrap0_s2_clk_src),
+       DEFINE_RCG_DFS(gcc_qupv3_wrap0_s3_clk_src),
+       DEFINE_RCG_DFS(gcc_qupv3_wrap0_s4_clk_src),
+       DEFINE_RCG_DFS(gcc_qupv3_wrap0_s5_clk_src),
+       DEFINE_RCG_DFS(gcc_qupv3_wrap1_s0_clk_src),
+       DEFINE_RCG_DFS(gcc_qupv3_wrap1_s1_clk_src),
+       DEFINE_RCG_DFS(gcc_qupv3_wrap1_s2_clk_src),
+       DEFINE_RCG_DFS(gcc_qupv3_wrap1_s3_clk_src),
+       DEFINE_RCG_DFS(gcc_qupv3_wrap1_s4_clk_src),
+       DEFINE_RCG_DFS(gcc_qupv3_wrap1_s5_clk_src),
+};
+
+static const struct regmap_config gcc_sm6350_regmap_config = {
+       .reg_bits = 32,
+       .reg_stride = 4,
+       .val_bits = 32,
+       .max_register = 0xbf030,
+       .fast_io = true,
+};
+
+static const struct qcom_cc_desc gcc_sm6350_desc = {
+       .config = &gcc_sm6350_regmap_config,
+       .clks = gcc_sm6350_clocks,
+       .num_clks = ARRAY_SIZE(gcc_sm6350_clocks),
+       .resets = gcc_sm6350_resets,
+       .num_resets = ARRAY_SIZE(gcc_sm6350_resets),
+       .gdscs = gcc_sm6350_gdscs,
+       .num_gdscs = ARRAY_SIZE(gcc_sm6350_gdscs),
+};
+
+static const struct of_device_id gcc_sm6350_match_table[] = {
+       { .compatible = "qcom,gcc-sm6350" },
+       { }
+};
+MODULE_DEVICE_TABLE(of, gcc_sm6350_match_table);
+
+static int gcc_sm6350_probe(struct platform_device *pdev)
+{
+       struct regmap *regmap;
+       int ret;
+
+       regmap = qcom_cc_map(pdev, &gcc_sm6350_desc);
+       if (IS_ERR(regmap))
+               return PTR_ERR(regmap);
+
+       /* Disable the GPLL0 active input to NPU and GPU via MISC registers */
+       regmap_update_bits(regmap, 0x4cf00, 0x3, 0x3);
+       regmap_update_bits(regmap, 0x45f00, 0x3, 0x3);
+
+       ret = qcom_cc_register_rcg_dfs(regmap, gcc_dfs_clocks,
+                       ARRAY_SIZE(gcc_dfs_clocks));
+       if (ret)
+               return ret;
+
+       return qcom_cc_really_probe(pdev, &gcc_sm6350_desc, regmap);;
+}
+
+static struct platform_driver gcc_sm6350_driver = {
+       .probe = gcc_sm6350_probe,
+       .driver = {
+               .name = "gcc-sm6350",
+               .of_match_table = gcc_sm6350_match_table,
+       },
+};
+
+static int __init gcc_sm6350_init(void)
+{
+       return platform_driver_register(&gcc_sm6350_driver);
+}
+core_initcall(gcc_sm6350_init);
+
+static void __exit gcc_sm6350_exit(void)
+{
+       platform_driver_unregister(&gcc_sm6350_driver);
+}
+module_exit(gcc_sm6350_exit);
+
+MODULE_DESCRIPTION("QTI GCC SM6350 Driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/clk/qcom/gpucc-sc7280.c b/drivers/clk/qcom/gpucc-sc7280.c
new file mode 100644 (file)
index 0000000..9a832f2
--- /dev/null
@@ -0,0 +1,491 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2021, The Linux Foundation. All rights reserved.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+#include <dt-bindings/clock/qcom,gpucc-sc7280.h>
+
+#include "clk-alpha-pll.h"
+#include "clk-branch.h"
+#include "clk-rcg.h"
+#include "clk-regmap-divider.h"
+#include "common.h"
+#include "reset.h"
+#include "gdsc.h"
+
+enum {
+       P_BI_TCXO,
+       P_GCC_GPU_GPLL0_CLK_SRC,
+       P_GCC_GPU_GPLL0_DIV_CLK_SRC,
+       P_GPU_CC_PLL0_OUT_MAIN,
+       P_GPU_CC_PLL1_OUT_MAIN,
+};
+
+static const struct pll_vco lucid_vco[] = {
+       { 249600000, 2000000000, 0 },
+};
+
+static struct clk_alpha_pll gpu_cc_pll0 = {
+       .offset = 0x0,
+       .vco_table = lucid_vco,
+       .num_vco = ARRAY_SIZE(lucid_vco),
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID],
+       .clkr = {
+               .hw.init = &(struct clk_init_data){
+                       .name = "gpu_cc_pll0",
+                       .parent_data = &(const struct clk_parent_data){
+                               .fw_name = "bi_tcxo",
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_alpha_pll_lucid_ops,
+               },
+       },
+};
+
+/* 500MHz Configuration */
+static const struct alpha_pll_config gpu_cc_pll1_config = {
+       .l = 0x1A,
+       .alpha = 0xAAA,
+       .config_ctl_val = 0x20485699,
+       .config_ctl_hi_val = 0x00002261,
+       .config_ctl_hi1_val = 0x329A299C,
+       .user_ctl_val = 0x00000001,
+       .user_ctl_hi_val = 0x00000805,
+       .user_ctl_hi1_val = 0x00000000,
+};
+
+static struct clk_alpha_pll gpu_cc_pll1 = {
+       .offset = 0x100,
+       .vco_table = lucid_vco,
+       .num_vco = ARRAY_SIZE(lucid_vco),
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID],
+       .clkr = {
+               .hw.init = &(struct clk_init_data){
+                       .name = "gpu_cc_pll1",
+                       .parent_data = &(const struct clk_parent_data){
+                               .fw_name = "bi_tcxo",
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_alpha_pll_lucid_ops,
+               },
+       },
+};
+
+static const struct parent_map gpu_cc_parent_map_0[] = {
+       { P_BI_TCXO, 0 },
+       { P_GPU_CC_PLL0_OUT_MAIN, 1 },
+       { P_GPU_CC_PLL1_OUT_MAIN, 3 },
+       { P_GCC_GPU_GPLL0_CLK_SRC, 5 },
+       { P_GCC_GPU_GPLL0_DIV_CLK_SRC, 6 },
+};
+
+static const struct clk_parent_data gpu_cc_parent_data_0[] = {
+       { .fw_name = "bi_tcxo" },
+       { .hw = &gpu_cc_pll0.clkr.hw },
+       { .hw = &gpu_cc_pll1.clkr.hw },
+       { .fw_name = "gcc_gpu_gpll0_clk_src" },
+       { .fw_name = "gcc_gpu_gpll0_div_clk_src" },
+};
+
+static const struct parent_map gpu_cc_parent_map_1[] = {
+       { P_BI_TCXO, 0 },
+       { P_GPU_CC_PLL1_OUT_MAIN, 3 },
+       { P_GCC_GPU_GPLL0_CLK_SRC, 5 },
+       { P_GCC_GPU_GPLL0_DIV_CLK_SRC, 6 },
+};
+
+static const struct clk_parent_data gpu_cc_parent_data_1[] = {
+       { .fw_name = "bi_tcxo", },
+       { .hw = &gpu_cc_pll1.clkr.hw },
+       { .fw_name = "gcc_gpu_gpll0_clk_src", },
+       { .fw_name = "gcc_gpu_gpll0_div_clk_src", },
+};
+
+static const struct freq_tbl ftbl_gpu_cc_gmu_clk_src[] = {
+       F(19200000, P_BI_TCXO, 1, 0, 0),
+       F(200000000, P_GCC_GPU_GPLL0_DIV_CLK_SRC, 1.5, 0, 0),
+       F(500000000, P_GPU_CC_PLL1_OUT_MAIN, 1, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 gpu_cc_gmu_clk_src = {
+       .cmd_rcgr = 0x1120,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = gpu_cc_parent_map_0,
+       .freq_tbl = ftbl_gpu_cc_gmu_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gpu_cc_gmu_clk_src",
+               .parent_data = gpu_cc_parent_data_0,
+               .num_parents = ARRAY_SIZE(gpu_cc_parent_data_0),
+               .ops = &clk_rcg2_shared_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_gpu_cc_hub_clk_src[] = {
+       F(150000000, P_GCC_GPU_GPLL0_DIV_CLK_SRC, 2, 0, 0),
+       F(240000000, P_GCC_GPU_GPLL0_CLK_SRC, 2.5, 0, 0),
+       F(300000000, P_GCC_GPU_GPLL0_CLK_SRC, 2, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 gpu_cc_hub_clk_src = {
+       .cmd_rcgr = 0x117c,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = gpu_cc_parent_map_1,
+       .freq_tbl = ftbl_gpu_cc_hub_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gpu_cc_hub_clk_src",
+               .parent_data = gpu_cc_parent_data_1,
+               .num_parents = ARRAY_SIZE(gpu_cc_parent_data_1),
+               .ops = &clk_rcg2_shared_ops,
+       },
+};
+
+static struct clk_regmap_div gpu_cc_hub_ahb_div_clk_src = {
+       .reg = 0x11c0,
+       .shift = 0,
+       .width = 4,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "gpu_cc_hub_ahb_div_clk_src",
+               .parent_hws = (const struct clk_hw*[]){
+                       &gpu_cc_hub_clk_src.clkr.hw,
+               },
+               .num_parents = 1,
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_regmap_div_ro_ops,
+       },
+};
+
+static struct clk_regmap_div gpu_cc_hub_cx_int_div_clk_src = {
+       .reg = 0x11bc,
+       .shift = 0,
+       .width = 4,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "gpu_cc_hub_cx_int_div_clk_src",
+               .parent_hws = (const struct clk_hw*[]){
+                       &gpu_cc_hub_clk_src.clkr.hw,
+               },
+               .num_parents = 1,
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_regmap_div_ro_ops,
+       },
+};
+
+static struct clk_branch gpu_cc_ahb_clk = {
+       .halt_reg = 0x1078,
+       .halt_check = BRANCH_HALT_DELAY,
+       .clkr = {
+               .enable_reg = 0x1078,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gpu_cc_ahb_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &gpu_cc_hub_ahb_div_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gpu_cc_crc_ahb_clk = {
+       .halt_reg = 0x107c,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x107c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gpu_cc_crc_ahb_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &gpu_cc_hub_ahb_div_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gpu_cc_cx_gmu_clk = {
+       .halt_reg = 0x1098,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x1098,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gpu_cc_cx_gmu_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &gpu_cc_gmu_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_aon_ops,
+               },
+       },
+};
+
+static struct clk_branch gpu_cc_cx_snoc_dvm_clk = {
+       .halt_reg = 0x108c,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x108c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gpu_cc_cx_snoc_dvm_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gpu_cc_cxo_aon_clk = {
+       .halt_reg = 0x1004,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x1004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gpu_cc_cxo_aon_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gpu_cc_cxo_clk = {
+       .halt_reg = 0x109c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x109c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gpu_cc_cxo_clk",
+                       .ops = &clk_branch2_aon_ops,
+               },
+       },
+};
+
+static struct clk_branch gpu_cc_gx_gmu_clk = {
+       .halt_reg = 0x1064,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x1064,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gpu_cc_gx_gmu_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &gpu_cc_gmu_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gpu_cc_hlos1_vote_gpu_smmu_clk = {
+       .halt_reg = 0x5000,
+       .halt_check = BRANCH_VOTED,
+       .clkr = {
+               .enable_reg = 0x5000,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gpu_cc_hlos1_vote_gpu_smmu_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gpu_cc_hub_aon_clk = {
+       .halt_reg = 0x1178,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x1178,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gpu_cc_hub_aon_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &gpu_cc_hub_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_aon_ops,
+               },
+       },
+};
+
+static struct clk_branch gpu_cc_hub_cx_int_clk = {
+       .halt_reg = 0x1204,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x1204,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gpu_cc_hub_cx_int_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &gpu_cc_hub_cx_int_div_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_aon_ops,
+               },
+       },
+};
+
+static struct clk_branch gpu_cc_mnd1x_0_gfx3d_clk = {
+       .halt_reg = 0x802c,
+       .halt_check = BRANCH_HALT_SKIP,
+       .clkr = {
+               .enable_reg = 0x802c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gpu_cc_mnd1x_0_gfx3d_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gpu_cc_mnd1x_1_gfx3d_clk = {
+       .halt_reg = 0x8030,
+       .halt_check = BRANCH_HALT_SKIP,
+       .clkr = {
+               .enable_reg = 0x8030,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gpu_cc_mnd1x_1_gfx3d_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gpu_cc_sleep_clk = {
+       .halt_reg = 0x1090,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x1090,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gpu_cc_sleep_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct gdsc cx_gdsc = {
+       .gdscr = 0x106c,
+       .gds_hw_ctrl = 0x1540,
+       .pd = {
+               .name = "cx_gdsc",
+       },
+       .pwrsts = PWRSTS_OFF_ON,
+       .flags = VOTABLE | RETAIN_FF_ENABLE,
+};
+
+static struct gdsc gx_gdsc = {
+       .gdscr = 0x100c,
+       .clamp_io_ctrl = 0x1508,
+       .pd = {
+               .name = "gx_gdsc",
+               .power_on = gdsc_gx_do_nothing_enable,
+       },
+       .pwrsts = PWRSTS_OFF_ON,
+       .flags = CLAMP_IO | RETAIN_FF_ENABLE,
+};
+
+static struct gdsc *gpu_cc_sc7180_gdscs[] = {
+       [GPU_CC_CX_GDSC] = &cx_gdsc,
+       [GPU_CC_GX_GDSC] = &gx_gdsc,
+};
+
+static struct clk_regmap *gpu_cc_sc7280_clocks[] = {
+       [GPU_CC_AHB_CLK] = &gpu_cc_ahb_clk.clkr,
+       [GPU_CC_CRC_AHB_CLK] = &gpu_cc_crc_ahb_clk.clkr,
+       [GPU_CC_CX_GMU_CLK] = &gpu_cc_cx_gmu_clk.clkr,
+       [GPU_CC_CX_SNOC_DVM_CLK] = &gpu_cc_cx_snoc_dvm_clk.clkr,
+       [GPU_CC_CXO_AON_CLK] = &gpu_cc_cxo_aon_clk.clkr,
+       [GPU_CC_CXO_CLK] = &gpu_cc_cxo_clk.clkr,
+       [GPU_CC_GMU_CLK_SRC] = &gpu_cc_gmu_clk_src.clkr,
+       [GPU_CC_GX_GMU_CLK] = &gpu_cc_gx_gmu_clk.clkr,
+       [GPU_CC_HLOS1_VOTE_GPU_SMMU_CLK] = &gpu_cc_hlos1_vote_gpu_smmu_clk.clkr,
+       [GPU_CC_HUB_AHB_DIV_CLK_SRC] = &gpu_cc_hub_ahb_div_clk_src.clkr,
+       [GPU_CC_HUB_AON_CLK] = &gpu_cc_hub_aon_clk.clkr,
+       [GPU_CC_HUB_CLK_SRC] = &gpu_cc_hub_clk_src.clkr,
+       [GPU_CC_HUB_CX_INT_CLK] = &gpu_cc_hub_cx_int_clk.clkr,
+       [GPU_CC_HUB_CX_INT_DIV_CLK_SRC] = &gpu_cc_hub_cx_int_div_clk_src.clkr,
+       [GPU_CC_MND1X_0_GFX3D_CLK] = &gpu_cc_mnd1x_0_gfx3d_clk.clkr,
+       [GPU_CC_MND1X_1_GFX3D_CLK] = &gpu_cc_mnd1x_1_gfx3d_clk.clkr,
+       [GPU_CC_PLL0] = &gpu_cc_pll0.clkr,
+       [GPU_CC_PLL1] = &gpu_cc_pll1.clkr,
+       [GPU_CC_SLEEP_CLK] = &gpu_cc_sleep_clk.clkr,
+};
+
+static const struct regmap_config gpu_cc_sc7280_regmap_config = {
+       .reg_bits = 32,
+       .reg_stride = 4,
+       .val_bits = 32,
+       .max_register = 0x8030,
+       .fast_io = true,
+};
+
+static const struct qcom_cc_desc gpu_cc_sc7280_desc = {
+       .config = &gpu_cc_sc7280_regmap_config,
+       .clks = gpu_cc_sc7280_clocks,
+       .num_clks = ARRAY_SIZE(gpu_cc_sc7280_clocks),
+       .gdscs = gpu_cc_sc7180_gdscs,
+       .num_gdscs = ARRAY_SIZE(gpu_cc_sc7180_gdscs),
+};
+
+static const struct of_device_id gpu_cc_sc7280_match_table[] = {
+       { .compatible = "qcom,sc7280-gpucc" },
+       { }
+};
+MODULE_DEVICE_TABLE(of, gpu_cc_sc7280_match_table);
+
+static int gpu_cc_sc7280_probe(struct platform_device *pdev)
+{
+       struct regmap *regmap;
+
+       regmap = qcom_cc_map(pdev, &gpu_cc_sc7280_desc);
+       if (IS_ERR(regmap))
+               return PTR_ERR(regmap);
+
+       clk_lucid_pll_configure(&gpu_cc_pll1, regmap, &gpu_cc_pll1_config);
+
+       /*
+        * Keep the clocks always-ON
+        * GPU_CC_CB_CLK, GPUCC_CX_GMU_CLK
+        */
+       regmap_update_bits(regmap, 0x1170, BIT(0), BIT(0));
+       regmap_update_bits(regmap, 0x1098, BIT(0), BIT(0));
+
+       return qcom_cc_really_probe(pdev, &gpu_cc_sc7280_desc, regmap);
+}
+
+static struct platform_driver gpu_cc_sc7280_driver = {
+       .probe = gpu_cc_sc7280_probe,
+       .driver = {
+               .name = "gpu_cc-sc7280",
+               .of_match_table = gpu_cc_sc7280_match_table,
+       },
+};
+
+static int __init gpu_cc_sc7280_init(void)
+{
+       return platform_driver_register(&gpu_cc_sc7280_driver);
+}
+subsys_initcall(gpu_cc_sc7280_init);
+
+static void __exit gpu_cc_sc7280_exit(void)
+{
+       platform_driver_unregister(&gpu_cc_sc7280_driver);
+}
+module_exit(gpu_cc_sc7280_exit);
+
+MODULE_DESCRIPTION("QTI GPU_CC SC7280 Driver");
+MODULE_LICENSE("GPL v2");
index 80fb6f7..8422fd0 100644 (file)
@@ -82,6 +82,14 @@ static const struct freq_tbl ftbl_gpu_cc_gmu_clk_src[] = {
        { }
 };
 
+static const struct freq_tbl ftbl_gpu_cc_gmu_clk_src_sc8180x[] = {
+       F(19200000, P_BI_TCXO, 1, 0, 0),
+       F(200000000, P_GPLL0_OUT_MAIN_DIV, 1.5, 0, 0),
+       F(400000000, P_GPLL0_OUT_MAIN, 1.5, 0, 0),
+       F(500000000, P_GPU_CC_PLL1_OUT_MAIN, 1, 0, 0),
+       { }
+};
+
 static struct clk_rcg2 gpu_cc_gmu_clk_src = {
        .cmd_rcgr = 0x1120,
        .mnd_width = 0,
@@ -277,6 +285,7 @@ static const struct qcom_cc_desc gpu_cc_sm8150_desc = {
 };
 
 static const struct of_device_id gpu_cc_sm8150_match_table[] = {
+       { .compatible = "qcom,sc8180x-gpucc" },
        { .compatible = "qcom,sm8150-gpucc" },
        { }
 };
@@ -290,6 +299,9 @@ static int gpu_cc_sm8150_probe(struct platform_device *pdev)
        if (IS_ERR(regmap))
                return PTR_ERR(regmap);
 
+       if (of_device_is_compatible(pdev->dev.of_node, "qcom,sc8180x-gpucc"))
+               gpu_cc_gmu_clk_src.freq_tbl = ftbl_gpu_cc_gmu_clk_src_sc8180x;
+
        clk_trion_pll_configure(&gpu_cc_pll1, regmap, &gpu_cc_pll1_config);
 
        return qcom_cc_really_probe(pdev, &gpu_cc_sm8150_desc, regmap);
index f5e31e6..96f476f 100644 (file)
@@ -251,15 +251,18 @@ static int lpass_gfm_clk_driver_probe(struct platform_device *pdev)
        if (IS_ERR(cc->base))
                return PTR_ERR(cc->base);
 
-       pm_runtime_enable(dev);
-       err = pm_clk_create(dev);
+       err = devm_pm_runtime_enable(dev);
        if (err)
-               goto pm_clk_err;
+               return err;
+
+       err = devm_pm_clk_create(dev);
+       if (err)
+               return err;
 
        err = of_pm_clk_add_clks(dev);
        if (err < 0) {
                dev_dbg(dev, "Failed to get lpass core voting clocks\n");
-               goto clk_reg_err;
+               return err;
        }
 
        for (i = 0; i < data->onecell_data->num; i++) {
@@ -273,22 +276,16 @@ static int lpass_gfm_clk_driver_probe(struct platform_device *pdev)
 
                err = devm_clk_hw_register(dev, &data->gfm_clks[i]->hw);
                if (err)
-                       goto clk_reg_err;
+                       return err;
 
        }
 
        err = devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get,
                                          data->onecell_data);
        if (err)
-               goto clk_reg_err;
+               return err;
 
        return 0;
-
-clk_reg_err:
-       pm_clk_destroy(dev);
-pm_clk_err:
-       pm_runtime_disable(dev);
-       return err;
 }
 
 static const struct of_device_id lpass_gfm_clk_match_table[] = {
index 2e0ecc3..ac09b7b 100644 (file)
@@ -356,32 +356,18 @@ static const struct qcom_cc_desc lpass_audio_hm_sc7180_desc = {
        .num_gdscs = ARRAY_SIZE(lpass_audio_hm_sc7180_gdscs),
 };
 
-static void lpass_pm_runtime_disable(void *data)
-{
-       pm_runtime_disable(data);
-}
-
-static void lpass_pm_clk_destroy(void *data)
-{
-       pm_clk_destroy(data);
-}
-
 static int lpass_create_pm_clks(struct platform_device *pdev)
 {
        int ret;
 
        pm_runtime_use_autosuspend(&pdev->dev);
        pm_runtime_set_autosuspend_delay(&pdev->dev, 500);
-       pm_runtime_enable(&pdev->dev);
 
-       ret = devm_add_action_or_reset(&pdev->dev, lpass_pm_runtime_disable, &pdev->dev);
+       ret = devm_pm_runtime_enable(&pdev->dev);
        if (ret)
                return ret;
 
-       ret = pm_clk_create(&pdev->dev);
-       if (ret)
-               return ret;
-       ret = devm_add_action_or_reset(&pdev->dev, lpass_pm_clk_destroy, &pdev->dev);
+       ret = devm_pm_clk_create(&pdev->dev);
        if (ret)
                return ret;
 
diff --git a/drivers/clk/qcom/mmcc-msm8994.c b/drivers/clk/qcom/mmcc-msm8994.c
new file mode 100644 (file)
index 0000000..89c5f5f
--- /dev/null
@@ -0,0 +1,2620 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2021, Konrad Dybcio <konrad.dybcio@somainline.org>
+ */
+
+#include <linux/kernel.h>
+#include <linux/bitops.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/clk-provider.h>
+#include <linux/regmap.h>
+#include <linux/reset-controller.h>
+#include <linux/clk.h>
+
+#include <dt-bindings/clock/qcom,mmcc-msm8994.h>
+
+#include "common.h"
+#include "clk-regmap.h"
+#include "clk-regmap-divider.h"
+#include "clk-alpha-pll.h"
+#include "clk-rcg.h"
+#include "clk-branch.h"
+#include "reset.h"
+#include "gdsc.h"
+
+
+enum {
+       P_XO,
+       P_GPLL0,
+       P_MMPLL0,
+       P_MMPLL1,
+       P_MMPLL3,
+       P_MMPLL4,
+       P_MMPLL5, /* Is this one even used by anything? Downstream doesn't tell. */
+       P_DSI0PLL,
+       P_DSI1PLL,
+       P_DSI0PLL_BYTE,
+       P_DSI1PLL_BYTE,
+       P_HDMIPLL,
+};
+static const struct parent_map mmcc_xo_gpll0_map[] = {
+       { P_XO, 0 },
+       { P_GPLL0, 5 }
+};
+
+static const struct clk_parent_data mmcc_xo_gpll0[] = {
+       { .fw_name = "xo" },
+       { .fw_name = "gpll0" },
+};
+
+static const struct parent_map mmss_xo_hdmi_map[] = {
+       { P_XO, 0 },
+       { P_HDMIPLL, 3 }
+};
+
+static const struct clk_parent_data mmss_xo_hdmi[] = {
+       { .fw_name = "xo" },
+       { .fw_name = "hdmipll" },
+};
+
+static const struct parent_map mmcc_xo_dsi0pll_dsi1pll_map[] = {
+       { P_XO, 0 },
+       { P_DSI0PLL, 1 },
+       { P_DSI1PLL, 2 }
+};
+
+static const struct clk_parent_data mmcc_xo_dsi0pll_dsi1pll[] = {
+       { .fw_name = "xo" },
+       { .fw_name = "dsi0pll" },
+       { .fw_name = "dsi1pll" },
+};
+
+static const struct parent_map mmcc_xo_dsibyte_map[] = {
+       { P_XO, 0 },
+       { P_DSI0PLL_BYTE, 1 },
+       { P_DSI1PLL_BYTE, 2 }
+};
+
+static const struct clk_parent_data mmcc_xo_dsibyte[] = {
+       { .fw_name = "xo" },
+       { .fw_name = "dsi0pllbyte" },
+       { .fw_name = "dsi1pllbyte" },
+};
+
+static struct pll_vco mmpll_p_vco[] = {
+       { 250000000, 500000000, 3 },
+       { 500000000, 1000000000, 2 },
+       { 1000000000, 1500000000, 1 },
+       { 1500000000, 2000000000, 0 },
+};
+
+static struct pll_vco mmpll_t_vco[] = {
+       { 500000000, 1500000000, 0 },
+};
+
+static const struct alpha_pll_config mmpll_p_config = {
+       .post_div_mask = 0xf00,
+};
+
+static struct clk_alpha_pll mmpll0_early = {
+       .offset = 0x0,
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
+       .vco_table = mmpll_p_vco,
+       .num_vco = ARRAY_SIZE(mmpll_p_vco),
+       .clkr = {
+               .enable_reg = 0x100,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "mmpll0_early",
+                       .parent_data = &(const struct clk_parent_data){
+                               .fw_name = "xo",
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_alpha_pll_ops,
+               },
+       },
+};
+
+static struct clk_alpha_pll_postdiv mmpll0 = {
+       .offset = 0x0,
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
+       .width = 4,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "mmpll0",
+               .parent_hws = (const struct clk_hw *[]){ &mmpll0_early.clkr.hw },
+               .num_parents = 1,
+               .ops = &clk_alpha_pll_postdiv_ops,
+               .flags = CLK_SET_RATE_PARENT,
+       },
+};
+
+static struct clk_alpha_pll mmpll1_early = {
+       .offset = 0x30,
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
+       .vco_table = mmpll_p_vco,
+       .num_vco = ARRAY_SIZE(mmpll_p_vco),
+       .clkr = {
+               .enable_reg = 0x100,
+               .enable_mask = BIT(1),
+               .hw.init = &(struct clk_init_data){
+                       .name = "mmpll1_early",
+                       .parent_data = &(const struct clk_parent_data){
+                               .fw_name = "xo",
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_alpha_pll_ops,
+               }
+       },
+};
+
+static struct clk_alpha_pll_postdiv mmpll1 = {
+       .offset = 0x30,
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
+       .width = 4,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "mmpll1",
+               .parent_hws = (const struct clk_hw *[]){ &mmpll1_early.clkr.hw },
+               .num_parents = 1,
+               .ops = &clk_alpha_pll_postdiv_ops,
+               .flags = CLK_SET_RATE_PARENT,
+       },
+};
+
+static struct clk_alpha_pll mmpll3_early = {
+       .offset = 0x60,
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
+       .vco_table = mmpll_p_vco,
+       .num_vco = ARRAY_SIZE(mmpll_p_vco),
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "mmpll3_early",
+               .parent_data = &(const struct clk_parent_data){
+                               .fw_name = "xo",
+               },
+               .num_parents = 1,
+               .ops = &clk_alpha_pll_ops,
+       },
+};
+
+static struct clk_alpha_pll_postdiv mmpll3 = {
+       .offset = 0x60,
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
+       .width = 4,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "mmpll3",
+               .parent_hws = (const struct clk_hw *[]){ &mmpll3_early.clkr.hw },
+               .num_parents = 1,
+               .ops = &clk_alpha_pll_postdiv_ops,
+               .flags = CLK_SET_RATE_PARENT,
+       },
+};
+
+static struct clk_alpha_pll mmpll4_early = {
+       .offset = 0x90,
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
+       .vco_table = mmpll_t_vco,
+       .num_vco = ARRAY_SIZE(mmpll_t_vco),
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "mmpll4_early",
+               .parent_data = &(const struct clk_parent_data){
+                               .fw_name = "xo",
+               },
+               .num_parents = 1,
+               .ops = &clk_alpha_pll_ops,
+       },
+};
+
+static struct clk_alpha_pll_postdiv mmpll4 = {
+       .offset = 0x90,
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
+       .width = 2,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "mmpll4",
+               .parent_hws = (const struct clk_hw *[]){ &mmpll4_early.clkr.hw },
+               .num_parents = 1,
+               .ops = &clk_alpha_pll_postdiv_ops,
+               .flags = CLK_SET_RATE_PARENT,
+       },
+};
+
+static const struct parent_map mmcc_xo_gpll0_mmpll1_map[] = {
+       { P_XO, 0 },
+       { P_GPLL0, 5 },
+       { P_MMPLL1, 2 }
+};
+
+static const struct clk_parent_data mmcc_xo_gpll0_mmpll1[] = {
+       { .fw_name = "xo" },
+       { .fw_name = "gpll0" },
+       { .hw = &mmpll1.clkr.hw },
+};
+
+static const struct parent_map mmcc_xo_gpll0_mmpll0_map[] = {
+       { P_XO, 0 },
+       { P_GPLL0, 5 },
+       { P_MMPLL0, 1 }
+};
+
+static const struct clk_parent_data mmcc_xo_gpll0_mmpll0[] = {
+       { .fw_name = "xo" },
+       { .fw_name = "gpll0" },
+       { .hw = &mmpll0.clkr.hw },
+};
+
+static const struct parent_map mmcc_xo_gpll0_mmpll0_mmpll3_map[] = {
+       { P_XO, 0 },
+       { P_GPLL0, 5 },
+       { P_MMPLL0, 1 },
+       { P_MMPLL3, 3 }
+};
+
+static const struct clk_parent_data mmcc_xo_gpll0_mmpll0_mmpll3[] = {
+       { .fw_name = "xo" },
+       { .fw_name = "gpll0" },
+       { .hw = &mmpll0.clkr.hw },
+       { .hw = &mmpll3.clkr.hw },
+};
+
+static const struct parent_map mmcc_xo_gpll0_mmpll0_mmpll4_map[] = {
+       { P_XO, 0 },
+       { P_GPLL0, 5 },
+       { P_MMPLL0, 1 },
+       { P_MMPLL4, 3 }
+};
+
+static const struct clk_parent_data mmcc_xo_gpll0_mmpll0_mmpll4[] = {
+       { .fw_name = "xo" },
+       { .fw_name = "gpll0" },
+       { .hw = &mmpll0.clkr.hw },
+       { .hw = &mmpll4.clkr.hw },
+};
+
+static struct clk_alpha_pll mmpll5_early = {
+       .offset = 0xc0,
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
+       .vco_table = mmpll_p_vco,
+       .num_vco = ARRAY_SIZE(mmpll_p_vco),
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "mmpll5_early",
+               .parent_data = &(const struct clk_parent_data){
+                               .fw_name = "xo",
+               },
+               .num_parents = 1,
+               .ops = &clk_alpha_pll_ops,
+       },
+};
+
+static struct clk_alpha_pll_postdiv mmpll5 = {
+       .offset = 0xc0,
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
+       .width = 4,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "mmpll5",
+               .parent_hws = (const struct clk_hw *[]){ &mmpll5_early.clkr.hw },
+               .num_parents = 1,
+               .ops = &clk_alpha_pll_postdiv_ops,
+               .flags = CLK_SET_RATE_PARENT,
+       },
+};
+
+static const struct freq_tbl ftbl_ahb_clk_src[] = {
+       /* Note: There might be more frequencies desired here. */
+       F(19200000, P_XO, 1, 0, 0),
+       F(40000000, P_GPLL0, 15, 0, 0),
+       F(80000000, P_MMPLL0, 10, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 ahb_clk_src = {
+       .cmd_rcgr = 0x5000,
+       .hid_width = 5,
+       .parent_map = mmcc_xo_gpll0_mmpll0_map,
+       .freq_tbl = ftbl_ahb_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "ahb_clk_src",
+               .parent_data = mmcc_xo_gpll0_mmpll0,
+               .num_parents = ARRAY_SIZE(mmcc_xo_gpll0_mmpll0),
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_axi_clk_src[] = {
+       F(75000000, P_GPLL0, 8, 0, 0),
+       F(150000000, P_GPLL0, 4, 0, 0),
+       F(333430000, P_MMPLL1, 3.5, 0, 0),
+       F(466800000, P_MMPLL1, 2.5, 0, 0),
+       { }
+};
+
+static const struct freq_tbl ftbl_axi_clk_src_8992[] = {
+       F(75000000, P_GPLL0, 8, 0, 0),
+       F(150000000, P_GPLL0, 4, 0, 0),
+       F(300000000, P_GPLL0, 2, 0, 0),
+       F(404000000, P_MMPLL1, 2, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 axi_clk_src = {
+       .cmd_rcgr = 0x5040,
+       .hid_width = 5,
+       .parent_map = mmcc_xo_gpll0_mmpll1_map,
+       .freq_tbl = ftbl_axi_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "axi_clk_src",
+               .parent_data = mmcc_xo_gpll0_mmpll1,
+               .num_parents = ARRAY_SIZE(mmcc_xo_gpll0_mmpll1),
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_csi0_1_2_3_clk_src[] = {
+       F(100000000, P_GPLL0, 6, 0, 0),
+       F(240000000, P_GPLL0, 2.5, 0, 0),
+       F(266670000, P_MMPLL0, 3, 0, 0),
+       { }
+};
+
+static const struct freq_tbl ftbl_csi0_1_2_3_clk_src_8992[] = {
+       F(100000000, P_GPLL0, 6, 0, 0),
+       F(266670000, P_MMPLL0, 3, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 csi0_clk_src = {
+       .cmd_rcgr = 0x3090,
+       .hid_width = 5,
+       .parent_map = mmcc_xo_gpll0_mmpll0_map,
+       .freq_tbl = ftbl_csi0_1_2_3_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "csi0_clk_src",
+               .parent_data = mmcc_xo_gpll0_mmpll0,
+               .num_parents = ARRAY_SIZE(mmcc_xo_gpll0_mmpll0),
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_vcodec0_clk_src[] = {
+       F(66670000, P_GPLL0, 9, 0, 0),
+       F(100000000, P_GPLL0, 6, 0, 0),
+       F(133330000, P_GPLL0, 4.5, 0, 0),
+       F(150000000, P_GPLL0, 4, 0, 0),
+       F(200000000, P_MMPLL0, 4, 0, 0),
+       F(240000000, P_GPLL0, 2.5, 0, 0),
+       F(266670000, P_MMPLL0, 3, 0, 0),
+       F(320000000, P_MMPLL0, 2.5, 0, 0),
+       F(510000000, P_MMPLL3, 2, 0, 0),
+       { }
+};
+
+static const struct freq_tbl ftbl_vcodec0_clk_src_8992[] = {
+       F(66670000, P_GPLL0, 9, 0, 0),
+       F(100000000, P_GPLL0, 6, 0, 0),
+       F(133330000, P_GPLL0, 4.5, 0, 0),
+       F(200000000, P_MMPLL0, 4, 0, 0),
+       F(320000000, P_MMPLL0, 2.5, 0, 0),
+       F(510000000, P_MMPLL3, 2, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 vcodec0_clk_src = {
+       .cmd_rcgr = 0x1000,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = mmcc_xo_gpll0_mmpll0_mmpll3_map,
+       .freq_tbl = ftbl_vcodec0_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "vcodec0_clk_src",
+               .parent_data = mmcc_xo_gpll0_mmpll0_mmpll3,
+               .num_parents = ARRAY_SIZE(mmcc_xo_gpll0_mmpll0_mmpll3),
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 csi1_clk_src = {
+       .cmd_rcgr = 0x3100,
+       .hid_width = 5,
+       .parent_map = mmcc_xo_gpll0_mmpll0_map,
+       .freq_tbl = ftbl_csi0_1_2_3_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "csi1_clk_src",
+               .parent_data = mmcc_xo_gpll0_mmpll0,
+               .num_parents = ARRAY_SIZE(mmcc_xo_gpll0_mmpll0),
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 csi2_clk_src = {
+       .cmd_rcgr = 0x3160,
+       .hid_width = 5,
+       .parent_map = mmcc_xo_gpll0_mmpll0_map,
+       .freq_tbl = ftbl_csi0_1_2_3_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "csi2_clk_src",
+               .parent_data = mmcc_xo_gpll0_mmpll0,
+               .num_parents = ARRAY_SIZE(mmcc_xo_gpll0_mmpll0),
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 csi3_clk_src = {
+       .cmd_rcgr = 0x31c0,
+       .hid_width = 5,
+       .parent_map = mmcc_xo_gpll0_mmpll0_map,
+       .freq_tbl = ftbl_csi0_1_2_3_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "csi3_clk_src",
+               .parent_data = mmcc_xo_gpll0_mmpll0,
+               .num_parents = ARRAY_SIZE(mmcc_xo_gpll0_mmpll0),
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_vfe0_clk_src[] = {
+       F(80000000, P_GPLL0, 7.5, 0, 0),
+       F(100000000, P_GPLL0, 6, 0, 0),
+       F(200000000, P_GPLL0, 3, 0, 0),
+       F(320000000, P_MMPLL0, 2.5, 0, 0),
+       F(400000000, P_MMPLL0, 2, 0, 0),
+       F(480000000, P_MMPLL4, 2, 0, 0),
+       F(533330000, P_MMPLL0, 1.5, 0, 0),
+       F(600000000, P_GPLL0, 1, 0, 0),
+       { }
+};
+
+static const struct freq_tbl ftbl_vfe0_1_clk_src_8992[] = {
+       F(80000000, P_GPLL0, 7.5, 0, 0),
+       F(100000000, P_GPLL0, 6, 0, 0),
+       F(200000000, P_GPLL0, 3, 0, 0),
+       F(320000000, P_MMPLL0, 2.5, 0, 0),
+       F(480000000, P_MMPLL4, 2, 0, 0),
+       F(600000000, P_GPLL0, 1, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 vfe0_clk_src = {
+       .cmd_rcgr = 0x3600,
+       .hid_width = 5,
+       .parent_map = mmcc_xo_gpll0_mmpll0_mmpll4_map,
+       .freq_tbl = ftbl_vfe0_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "vfe0_clk_src",
+               .parent_data = mmcc_xo_gpll0_mmpll0_mmpll4,
+               .num_parents = ARRAY_SIZE(mmcc_xo_gpll0_mmpll0_mmpll4),
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_vfe1_clk_src[] = {
+       F(80000000, P_GPLL0, 7.5, 0, 0),
+       F(100000000, P_GPLL0, 6, 0, 0),
+       F(200000000, P_GPLL0, 3, 0, 0),
+       F(320000000, P_MMPLL0, 2.5, 0, 0),
+       F(400000000, P_MMPLL0, 2, 0, 0),
+       F(533330000, P_MMPLL0, 1.5, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 vfe1_clk_src = {
+       .cmd_rcgr = 0x3620,
+       .hid_width = 5,
+       .parent_map = mmcc_xo_gpll0_mmpll0_mmpll4_map,
+       .freq_tbl = ftbl_vfe1_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "vfe1_clk_src",
+               .parent_data = mmcc_xo_gpll0_mmpll0_mmpll4,
+               .num_parents = ARRAY_SIZE(mmcc_xo_gpll0_mmpll0_mmpll4),
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_cpp_clk_src[] = {
+       F(100000000, P_GPLL0, 6, 0, 0),
+       F(200000000, P_GPLL0, 3, 0, 0),
+       F(320000000, P_MMPLL0, 2.5, 0, 0),
+       F(480000000, P_MMPLL4, 2, 0, 0),
+       F(600000000, P_GPLL0, 1, 0, 0),
+       F(640000000, P_MMPLL4, 1.5, 0, 0),
+       { }
+};
+
+static const struct freq_tbl ftbl_cpp_clk_src_8992[] = {
+       F(100000000, P_GPLL0, 6, 0, 0),
+       F(200000000, P_GPLL0, 3, 0, 0),
+       F(320000000, P_MMPLL0, 2.5, 0, 0),
+       F(480000000, P_MMPLL4, 2, 0, 0),
+       F(640000000, P_MMPLL4, 1.5, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 cpp_clk_src = {
+       .cmd_rcgr = 0x3640,
+       .hid_width = 5,
+       .parent_map = mmcc_xo_gpll0_mmpll0_mmpll4_map,
+       .freq_tbl = ftbl_cpp_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "cpp_clk_src",
+               .parent_data = mmcc_xo_gpll0_mmpll0_mmpll4,
+               .num_parents = ARRAY_SIZE(mmcc_xo_gpll0_mmpll0_mmpll4),
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_jpeg0_1_clk_src[] = {
+       F(75000000, P_GPLL0, 8, 0, 0),
+       F(150000000, P_GPLL0, 4, 0, 0),
+       F(228570000, P_MMPLL0, 3.5, 0, 0),
+       F(266670000, P_MMPLL0, 3, 0, 0),
+       F(320000000, P_MMPLL0, 2.5, 0, 0),
+       F(480000000, P_MMPLL4, 2, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 jpeg1_clk_src = {
+       .cmd_rcgr = 0x3520,
+       .hid_width = 5,
+       .parent_map = mmcc_xo_gpll0_mmpll0_mmpll4_map,
+       .freq_tbl = ftbl_jpeg0_1_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "jpeg1_clk_src",
+               .parent_data = mmcc_xo_gpll0_mmpll0_mmpll4,
+               .num_parents = ARRAY_SIZE(mmcc_xo_gpll0_mmpll0_mmpll4),
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_jpeg2_clk_src[] = {
+       F(75000000, P_GPLL0, 8, 0, 0),
+       F(133330000, P_GPLL0, 4.5, 0, 0),
+       F(150000000, P_GPLL0, 4, 0, 0),
+       F(228570000, P_MMPLL0, 3.5, 0, 0),
+       F(266670000, P_MMPLL0, 3, 0, 0),
+       F(320000000, P_MMPLL0, 2.5, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 jpeg2_clk_src = {
+       .cmd_rcgr = 0x3540,
+       .hid_width = 5,
+       .parent_map = mmcc_xo_gpll0_mmpll0_map,
+       .freq_tbl = ftbl_jpeg2_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "jpeg2_clk_src",
+               .parent_data = mmcc_xo_gpll0_mmpll0,
+               .num_parents = ARRAY_SIZE(mmcc_xo_gpll0_mmpll0),
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_csi2phytimer_clk_src[] = {
+       F(50000000, P_GPLL0, 12, 0, 0),
+       F(100000000, P_GPLL0, 6, 0, 0),
+       F(200000000, P_MMPLL0, 4, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 csi2phytimer_clk_src = {
+       .cmd_rcgr = 0x3060,
+       .hid_width = 5,
+       .parent_map = mmcc_xo_gpll0_mmpll0_map,
+       .freq_tbl = ftbl_csi2phytimer_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "csi2phytimer_clk_src",
+               .parent_data = mmcc_xo_gpll0_mmpll0,
+               .num_parents = ARRAY_SIZE(mmcc_xo_gpll0_mmpll0),
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_fd_core_clk_src[] = {
+       F(60000000, P_GPLL0, 10, 0, 0),
+       F(200000000, P_GPLL0, 3, 0, 0),
+       F(320000000, P_MMPLL0, 2.5, 0, 0),
+       F(400000000, P_MMPLL0, 2, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 fd_core_clk_src = {
+       .cmd_rcgr = 0x3b00,
+       .hid_width = 5,
+       .parent_map = mmcc_xo_gpll0_mmpll0_map,
+       .freq_tbl = ftbl_fd_core_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "fd_core_clk_src",
+               .parent_data = mmcc_xo_gpll0_mmpll0,
+               .num_parents = ARRAY_SIZE(mmcc_xo_gpll0_mmpll0),
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_mdp_clk_src[] = {
+       F(85710000, P_GPLL0, 7, 0, 0),
+       F(100000000, P_GPLL0, 6, 0, 0),
+       F(120000000, P_GPLL0, 5, 0, 0),
+       F(150000000, P_GPLL0, 4, 0, 0),
+       F(171430000, P_GPLL0, 3.5, 0, 0),
+       F(200000000, P_GPLL0, 3, 0, 0),
+       F(240000000, P_GPLL0, 2.5, 0, 0),
+       F(266670000, P_MMPLL0, 3, 0, 0),
+       F(300000000, P_GPLL0, 2, 0, 0),
+       F(320000000, P_MMPLL0, 2.5, 0, 0),
+       F(400000000, P_MMPLL0, 2, 0, 0),
+       { }
+};
+
+static const struct freq_tbl ftbl_mdp_clk_src_8992[] = {
+       F(85710000, P_GPLL0, 7, 0, 0),
+       F(171430000, P_GPLL0, 3.5, 0, 0),
+       F(200000000, P_GPLL0, 3, 0, 0),
+       F(240000000, P_GPLL0, 2.5, 0, 0),
+       F(266670000, P_MMPLL0, 3, 0, 0),
+       F(320000000, P_MMPLL0, 2.5, 0, 0),
+       F(400000000, P_MMPLL0, 2, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 mdp_clk_src = {
+       .cmd_rcgr = 0x2040,
+       .hid_width = 5,
+       .parent_map = mmcc_xo_gpll0_mmpll0_map,
+       .freq_tbl = ftbl_mdp_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "mdp_clk_src",
+               .parent_data = mmcc_xo_gpll0_mmpll0,
+               .num_parents = ARRAY_SIZE(mmcc_xo_gpll0_mmpll0),
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 pclk0_clk_src = {
+       .cmd_rcgr = 0x2000,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = mmcc_xo_dsi0pll_dsi1pll_map,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "pclk0_clk_src",
+               .parent_data = mmcc_xo_dsi0pll_dsi1pll,
+               .num_parents = ARRAY_SIZE(mmcc_xo_dsi0pll_dsi1pll),
+               .ops = &clk_pixel_ops,
+               .flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE,
+       },
+};
+
+static struct clk_rcg2 pclk1_clk_src = {
+       .cmd_rcgr = 0x2020,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = mmcc_xo_dsi0pll_dsi1pll_map,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "pclk1_clk_src",
+               .parent_data = mmcc_xo_dsi0pll_dsi1pll,
+               .num_parents = ARRAY_SIZE(mmcc_xo_dsi0pll_dsi1pll),
+               .ops = &clk_pixel_ops,
+               .flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE,
+       },
+};
+
+static const struct freq_tbl ftbl_ocmemnoc_clk_src[] = {
+       F(19200000, P_XO, 1, 0, 0),
+       F(75000000, P_GPLL0, 8, 0, 0),
+       F(100000000, P_GPLL0, 6, 0, 0),
+       F(150000000, P_GPLL0, 4, 0, 0),
+       F(228570000, P_MMPLL0, 3.5, 0, 0),
+       F(266670000, P_MMPLL0, 3, 0, 0),
+       F(320000000, P_MMPLL0, 2.5, 0, 0),
+       F(400000000, P_MMPLL0, 2, 0, 0),
+       { }
+};
+
+static const struct freq_tbl ftbl_ocmemnoc_clk_src_8992[] = {
+       F(19200000, P_XO, 1, 0, 0),
+       F(75000000, P_GPLL0, 8, 0, 0),
+       F(100000000, P_GPLL0, 6, 0, 0),
+       F(150000000, P_GPLL0, 4, 0, 0),
+       F(320000000, P_MMPLL0, 2.5, 0, 0),
+       F(400000000, P_MMPLL0, 2, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 ocmemnoc_clk_src = {
+       .cmd_rcgr = 0x5090,
+       .hid_width = 5,
+       .parent_map = mmcc_xo_gpll0_mmpll0_map,
+       .freq_tbl = ftbl_ocmemnoc_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "ocmemnoc_clk_src",
+               .parent_data = mmcc_xo_gpll0_mmpll0,
+               .num_parents = ARRAY_SIZE(mmcc_xo_gpll0_mmpll0),
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_cci_clk_src[] = {
+       F(19200000, P_XO, 1, 0, 0),
+       F(37500000, P_GPLL0, 16, 0, 0),
+       F(50000000, P_GPLL0, 12, 0, 0),
+       F(100000000, P_GPLL0, 6, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 cci_clk_src = {
+       .cmd_rcgr = 0x3300,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = mmcc_xo_gpll0_map,
+       .freq_tbl = ftbl_cci_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "cci_clk_src",
+               .parent_data = mmcc_xo_gpll0,
+               .num_parents = ARRAY_SIZE(mmcc_xo_gpll0),
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_mmss_gp0_1_clk_src[] = {
+       F(10000, P_XO, 16, 10, 120),
+       F(24000, P_GPLL0, 16, 1, 50),
+       F(6000000, P_GPLL0, 10, 1, 10),
+       F(12000000, P_GPLL0, 10, 1, 5),
+       F(13000000, P_GPLL0, 4, 13, 150),
+       F(24000000, P_GPLL0, 5, 1, 5),
+       { }
+};
+
+static struct clk_rcg2 mmss_gp0_clk_src = {
+       .cmd_rcgr = 0x3420,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = mmcc_xo_gpll0_map,
+       .freq_tbl = ftbl_mmss_gp0_1_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "mmss_gp0_clk_src",
+               .parent_data = mmcc_xo_gpll0,
+               .num_parents = ARRAY_SIZE(mmcc_xo_gpll0),
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 mmss_gp1_clk_src = {
+       .cmd_rcgr = 0x3450,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = mmcc_xo_gpll0_map,
+       .freq_tbl = ftbl_mmss_gp0_1_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "mmss_gp1_clk_src",
+               .parent_data = mmcc_xo_gpll0,
+               .num_parents = ARRAY_SIZE(mmcc_xo_gpll0),
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 jpeg0_clk_src = {
+       .cmd_rcgr = 0x3500,
+       .hid_width = 5,
+       .parent_map = mmcc_xo_gpll0_mmpll0_mmpll4_map,
+       .freq_tbl = ftbl_jpeg0_1_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "jpeg0_clk_src",
+               .parent_data = mmcc_xo_gpll0_mmpll0_mmpll4,
+               .num_parents = ARRAY_SIZE(mmcc_xo_gpll0_mmpll0_mmpll4),
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 jpeg_dma_clk_src = {
+       .cmd_rcgr = 0x3560,
+       .hid_width = 5,
+       .parent_map = mmcc_xo_gpll0_mmpll0_mmpll4_map,
+       .freq_tbl = ftbl_jpeg0_1_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "jpeg_dma_clk_src",
+               .parent_data = mmcc_xo_gpll0_mmpll0_mmpll4,
+               .num_parents = ARRAY_SIZE(mmcc_xo_gpll0_mmpll0_mmpll4),
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_mclk0_1_2_3_clk_src[] = {
+       F(4800000, P_XO, 4, 0, 0),
+       F(6000000, P_GPLL0, 10, 1, 10),
+       F(8000000, P_GPLL0, 15, 1, 5),
+       F(9600000, P_XO, 2, 0, 0),
+       F(16000000, P_MMPLL0, 10, 1, 5),
+       F(19200000, P_XO, 1, 0, 0),
+       F(24000000, P_GPLL0, 5, 1, 5),
+       F(32000000, P_MMPLL0, 5, 1, 5),
+       F(48000000, P_GPLL0, 12.5, 0, 0),
+       F(64000000, P_MMPLL0, 12.5, 0, 0),
+       { }
+};
+
+static const struct freq_tbl ftbl_mclk0_clk_src_8992[] = {
+       F(4800000, P_XO, 4, 0, 0),
+       F(6000000, P_MMPLL4, 10, 1, 16),
+       F(8000000, P_MMPLL4, 10, 1, 12),
+       F(9600000, P_XO, 2, 0, 0),
+       F(12000000, P_MMPLL4, 10, 1, 8),
+       F(16000000, P_MMPLL4, 10, 1, 6),
+       F(19200000, P_XO, 1, 0, 0),
+       F(24000000, P_MMPLL4, 10, 1, 4),
+       F(32000000, P_MMPLL4, 10, 1, 3),
+       F(48000000, P_MMPLL4, 10, 1, 2),
+       F(64000000, P_MMPLL4, 15, 0, 0),
+       { }
+};
+
+static const struct freq_tbl ftbl_mclk1_2_3_clk_src_8992[] = {
+       F(4800000, P_XO, 4, 0, 0),
+       F(6000000, P_MMPLL4, 10, 1, 16),
+       F(8000000, P_MMPLL4, 10, 1, 12),
+       F(9600000, P_XO, 2, 0, 0),
+       F(16000000, P_MMPLL4, 10, 1, 6),
+       F(19200000, P_XO, 1, 0, 0),
+       F(24000000, P_MMPLL4, 10, 1, 4),
+       F(32000000, P_MMPLL4, 10, 1, 3),
+       F(48000000, P_MMPLL4, 10, 1, 2),
+       F(64000000, P_MMPLL4, 15, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 mclk0_clk_src = {
+       .cmd_rcgr = 0x3360,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = mmcc_xo_gpll0_mmpll0_map,
+       .freq_tbl = ftbl_mclk0_1_2_3_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "mclk0_clk_src",
+               .parent_data = mmcc_xo_gpll0_mmpll0,
+               .num_parents = ARRAY_SIZE(mmcc_xo_gpll0_mmpll0),
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 mclk1_clk_src = {
+       .cmd_rcgr = 0x3390,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = mmcc_xo_gpll0_mmpll0_map,
+       .freq_tbl = ftbl_mclk0_1_2_3_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "mclk1_clk_src",
+               .parent_data = mmcc_xo_gpll0_mmpll0,
+               .num_parents = ARRAY_SIZE(mmcc_xo_gpll0_mmpll0),
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 mclk2_clk_src = {
+       .cmd_rcgr = 0x33c0,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = mmcc_xo_gpll0_mmpll0_map,
+       .freq_tbl = ftbl_mclk0_1_2_3_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "mclk2_clk_src",
+               .parent_data = mmcc_xo_gpll0_mmpll0,
+               .num_parents = ARRAY_SIZE(mmcc_xo_gpll0_mmpll0),
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 mclk3_clk_src = {
+       .cmd_rcgr = 0x33f0,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = mmcc_xo_gpll0_mmpll0_map,
+       .freq_tbl = ftbl_mclk0_1_2_3_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "mclk3_clk_src",
+               .parent_data = mmcc_xo_gpll0_mmpll0,
+               .num_parents = ARRAY_SIZE(mmcc_xo_gpll0_mmpll0),
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_csi0_1phytimer_clk_src[] = {
+       F(50000000, P_GPLL0, 12, 0, 0),
+       F(100000000, P_GPLL0, 6, 0, 0),
+       F(200000000, P_MMPLL0, 4, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 csi0phytimer_clk_src = {
+       .cmd_rcgr = 0x3000,
+       .hid_width = 5,
+       .parent_map = mmcc_xo_gpll0_mmpll0_map,
+       .freq_tbl = ftbl_csi0_1phytimer_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "csi0phytimer_clk_src",
+               .parent_data = mmcc_xo_gpll0_mmpll0,
+               .num_parents = ARRAY_SIZE(mmcc_xo_gpll0_mmpll0),
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 csi1phytimer_clk_src = {
+       .cmd_rcgr = 0x3030,
+       .hid_width = 5,
+       .parent_map = mmcc_xo_gpll0_mmpll0_map,
+       .freq_tbl = ftbl_csi0_1phytimer_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "csi1phytimer_clk_src",
+               .parent_data = mmcc_xo_gpll0_mmpll0,
+               .num_parents = ARRAY_SIZE(mmcc_xo_gpll0_mmpll0),
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 byte0_clk_src = {
+       .cmd_rcgr = 0x2120,
+       .hid_width = 5,
+       .parent_map = mmcc_xo_dsibyte_map,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "byte0_clk_src",
+               .parent_data = mmcc_xo_dsibyte,
+               .num_parents = ARRAY_SIZE(mmcc_xo_dsibyte),
+               .ops = &clk_byte2_ops,
+               .flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE,
+       },
+};
+
+static struct clk_rcg2 byte1_clk_src = {
+       .cmd_rcgr = 0x2140,
+       .hid_width = 5,
+       .parent_map = mmcc_xo_dsibyte_map,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "byte1_clk_src",
+               .parent_data = mmcc_xo_dsibyte,
+               .num_parents = ARRAY_SIZE(mmcc_xo_dsibyte),
+               .ops = &clk_byte2_ops,
+               .flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE,
+       },
+};
+
+static struct freq_tbl ftbl_mdss_esc0_1_clk[] = {
+       F(19200000, P_XO, 1, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 esc0_clk_src = {
+       .cmd_rcgr = 0x2160,
+       .hid_width = 5,
+       .parent_map = mmcc_xo_dsibyte_map,
+       .freq_tbl = ftbl_mdss_esc0_1_clk,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "esc0_clk_src",
+               .parent_data = mmcc_xo_dsibyte,
+               .num_parents = ARRAY_SIZE(mmcc_xo_dsibyte),
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 esc1_clk_src = {
+       .cmd_rcgr = 0x2180,
+       .hid_width = 5,
+       .parent_map = mmcc_xo_dsibyte_map,
+       .freq_tbl = ftbl_mdss_esc0_1_clk,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "esc1_clk_src",
+               .parent_data = mmcc_xo_dsibyte,
+               .num_parents = ARRAY_SIZE(mmcc_xo_dsibyte),
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct freq_tbl extpclk_freq_tbl[] = {
+       { .src = P_HDMIPLL },
+       { }
+};
+
+static struct clk_rcg2 extpclk_clk_src = {
+       .cmd_rcgr = 0x2060,
+       .hid_width = 5,
+       .parent_map = mmss_xo_hdmi_map,
+       .freq_tbl = extpclk_freq_tbl,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "extpclk_clk_src",
+               .parent_data = mmss_xo_hdmi,
+               .num_parents = ARRAY_SIZE(mmss_xo_hdmi),
+               .ops = &clk_rcg2_ops,
+               .flags = CLK_SET_RATE_PARENT,
+       },
+};
+
+static struct freq_tbl ftbl_hdmi_clk_src[] = {
+       F(19200000, P_XO, 1, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 hdmi_clk_src = {
+       .cmd_rcgr = 0x2100,
+       .hid_width = 5,
+       .parent_map = mmcc_xo_gpll0_map,
+       .freq_tbl = ftbl_hdmi_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "hdmi_clk_src",
+               .parent_data = mmcc_xo_gpll0,
+               .num_parents = ARRAY_SIZE(mmcc_xo_gpll0),
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct freq_tbl ftbl_mdss_vsync_clk[] = {
+       F(19200000, P_XO, 1, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 vsync_clk_src = {
+       .cmd_rcgr = 0x2080,
+       .hid_width = 5,
+       .parent_map = mmcc_xo_gpll0_map,
+       .freq_tbl = ftbl_mdss_vsync_clk,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "vsync_clk_src",
+               .parent_data = mmcc_xo_gpll0,
+               .num_parents = ARRAY_SIZE(mmcc_xo_gpll0),
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_rbbmtimer_clk_src[] = {
+       F(19200000, P_XO, 1, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 rbbmtimer_clk_src = {
+       .cmd_rcgr = 0x4090,
+       .hid_width = 5,
+       .parent_map = mmcc_xo_gpll0_map,
+       .freq_tbl = ftbl_rbbmtimer_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "rbbmtimer_clk_src",
+               .parent_data = mmcc_xo_gpll0,
+               .num_parents = ARRAY_SIZE(mmcc_xo_gpll0),
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_branch camss_ahb_clk = {
+       .halt_reg = 0x348c,
+       .clkr = {
+               .enable_reg = 0x348c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "camss_ahb_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &ahb_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch camss_cci_cci_ahb_clk = {
+       .halt_reg = 0x3348,
+       .clkr = {
+               .enable_reg = 0x3348,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "camss_cci_cci_ahb_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &ahb_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch camss_cci_cci_clk = {
+       .halt_reg = 0x3344,
+       .clkr = {
+               .enable_reg = 0x3344,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "camss_cci_cci_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &cci_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch camss_vfe_cpp_ahb_clk = {
+       .halt_reg = 0x36b4,
+       .clkr = {
+               .enable_reg = 0x36b4,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "camss_vfe_cpp_ahb_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &ahb_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch camss_vfe_cpp_axi_clk = {
+       .halt_reg = 0x36c4,
+       .clkr = {
+               .enable_reg = 0x36c4,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "camss_vfe_cpp_axi_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &axi_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch camss_vfe_cpp_clk = {
+       .halt_reg = 0x36b0,
+       .clkr = {
+               .enable_reg = 0x36b0,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "camss_vfe_cpp_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &cpp_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch camss_csi0_ahb_clk = {
+       .halt_reg = 0x30bc,
+       .clkr = {
+               .enable_reg = 0x30bc,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "camss_csi0_ahb_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &ahb_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch camss_csi0_clk = {
+       .halt_reg = 0x30b4,
+       .clkr = {
+               .enable_reg = 0x30b4,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "camss_csi0_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &csi0_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch camss_csi0phy_clk = {
+       .halt_reg = 0x30c4,
+       .clkr = {
+               .enable_reg = 0x30c4,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "camss_csi0phy_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &csi0_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch camss_csi0pix_clk = {
+       .halt_reg = 0x30e4,
+       .clkr = {
+               .enable_reg = 0x30e4,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "camss_csi0pix_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &csi0_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch camss_csi0rdi_clk = {
+       .halt_reg = 0x30d4,
+       .clkr = {
+               .enable_reg = 0x30d4,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "camss_csi0rdi_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &csi0_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch camss_csi1_ahb_clk = {
+       .halt_reg = 0x3128,
+       .clkr = {
+               .enable_reg = 0x3128,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "camss_csi1_ahb_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &ahb_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch camss_csi1_clk = {
+       .halt_reg = 0x3124,
+       .clkr = {
+               .enable_reg = 0x3124,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "camss_csi1_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &csi1_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch camss_csi1phy_clk = {
+       .halt_reg = 0x3134,
+       .clkr = {
+               .enable_reg = 0x3134,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "camss_csi1phy_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &csi1_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch camss_csi1pix_clk = {
+       .halt_reg = 0x3154,
+       .clkr = {
+               .enable_reg = 0x3154,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "camss_csi1pix_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &csi1_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch camss_csi1rdi_clk = {
+       .halt_reg = 0x3144,
+       .clkr = {
+               .enable_reg = 0x3144,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "camss_csi1rdi_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &csi1_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch camss_csi2_ahb_clk = {
+       .halt_reg = 0x3188,
+       .clkr = {
+               .enable_reg = 0x3188,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "camss_csi2_ahb_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &ahb_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch camss_csi2_clk = {
+       .halt_reg = 0x3184,
+       .clkr = {
+               .enable_reg = 0x3184,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "camss_csi2_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &csi1_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch camss_csi2phy_clk = {
+       .halt_reg = 0x3194,
+       .clkr = {
+               .enable_reg = 0x3194,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "camss_csi2phy_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &csi1_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch camss_csi2pix_clk = {
+       .halt_reg = 0x31b4,
+       .clkr = {
+               .enable_reg = 0x31b4,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "camss_csi2pix_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &csi1_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch camss_csi2rdi_clk = {
+       .halt_reg = 0x31a4,
+       .clkr = {
+               .enable_reg = 0x31a4,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "camss_csi2rdi_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &csi1_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch camss_csi3_ahb_clk = {
+       .halt_reg = 0x31e8,
+       .clkr = {
+               .enable_reg = 0x31e8,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "camss_csi3_ahb_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &ahb_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch camss_csi3_clk = {
+       .halt_reg = 0x31e4,
+       .clkr = {
+               .enable_reg = 0x31e4,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "camss_csi3_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &csi1_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch camss_csi3phy_clk = {
+       .halt_reg = 0x31f4,
+       .clkr = {
+               .enable_reg = 0x31f4,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "camss_csi3phy_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &csi1_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch camss_csi3pix_clk = {
+       .halt_reg = 0x3214,
+       .clkr = {
+               .enable_reg = 0x3214,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "camss_csi3pix_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &csi1_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch camss_csi3rdi_clk = {
+       .halt_reg = 0x3204,
+       .clkr = {
+               .enable_reg = 0x3204,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "camss_csi3rdi_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &csi1_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch camss_csi_vfe0_clk = {
+       .halt_reg = 0x3704,
+       .clkr = {
+               .enable_reg = 0x3704,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "camss_csi_vfe0_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &vfe0_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch camss_csi_vfe1_clk = {
+       .halt_reg = 0x3714,
+       .clkr = {
+               .enable_reg = 0x3714,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "camss_csi_vfe1_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &vfe1_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch camss_gp0_clk = {
+       .halt_reg = 0x3444,
+       .clkr = {
+               .enable_reg = 0x3444,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "camss_gp0_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &mmss_gp0_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch camss_gp1_clk = {
+       .halt_reg = 0x3474,
+       .clkr = {
+               .enable_reg = 0x3474,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "camss_gp1_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &mmss_gp1_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch camss_ispif_ahb_clk = {
+       .halt_reg = 0x3224,
+       .clkr = {
+               .enable_reg = 0x3224,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "camss_ispif_ahb_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &ahb_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch camss_jpeg_dma_clk = {
+       .halt_reg = 0x35c0,
+       .clkr = {
+               .enable_reg = 0x35c0,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "camss_jpeg_dma_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &jpeg_dma_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch camss_jpeg_jpeg0_clk = {
+       .halt_reg = 0x35a8,
+       .clkr = {
+               .enable_reg = 0x35a8,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "camss_jpeg_jpeg0_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &jpeg0_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch camss_jpeg_jpeg1_clk = {
+       .halt_reg = 0x35ac,
+       .clkr = {
+               .enable_reg = 0x35ac,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "camss_jpeg_jpeg1_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &jpeg1_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch camss_jpeg_jpeg2_clk = {
+       .halt_reg = 0x35b0,
+       .clkr = {
+               .enable_reg = 0x35b0,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "camss_jpeg_jpeg2_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &jpeg2_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch camss_jpeg_jpeg_ahb_clk = {
+       .halt_reg = 0x35b4,
+       .clkr = {
+               .enable_reg = 0x35b4,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "camss_jpeg_jpeg_ahb_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &ahb_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch camss_jpeg_jpeg_axi_clk = {
+       .halt_reg = 0x35b8,
+       .clkr = {
+               .enable_reg = 0x35b8,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "camss_jpeg_jpeg_axi_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &axi_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch camss_mclk0_clk = {
+       .halt_reg = 0x3384,
+       .clkr = {
+               .enable_reg = 0x3384,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "camss_mclk0_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &mclk0_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch camss_mclk1_clk = {
+       .halt_reg = 0x33b4,
+       .clkr = {
+               .enable_reg = 0x33b4,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "camss_mclk1_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &mclk1_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch camss_mclk2_clk = {
+       .halt_reg = 0x33e4,
+       .clkr = {
+               .enable_reg = 0x33e4,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "camss_mclk2_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &mclk2_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch camss_mclk3_clk = {
+       .halt_reg = 0x3414,
+       .clkr = {
+               .enable_reg = 0x3414,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "camss_mclk3_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &mclk3_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch camss_micro_ahb_clk = {
+       .halt_reg = 0x3494,
+       .clkr = {
+               .enable_reg = 0x3494,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "camss_micro_ahb_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &ahb_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch camss_phy0_csi0phytimer_clk = {
+       .halt_reg = 0x3024,
+       .clkr = {
+               .enable_reg = 0x3024,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "camss_phy0_csi0phytimer_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &csi0phytimer_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch camss_phy1_csi1phytimer_clk = {
+       .halt_reg = 0x3054,
+       .clkr = {
+               .enable_reg = 0x3054,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "camss_phy1_csi1phytimer_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &csi1phytimer_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch camss_phy2_csi2phytimer_clk = {
+       .halt_reg = 0x3084,
+       .clkr = {
+               .enable_reg = 0x3084,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "camss_phy2_csi2phytimer_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &csi2phytimer_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch camss_top_ahb_clk = {
+       .halt_reg = 0x3484,
+       .clkr = {
+               .enable_reg = 0x3484,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "camss_top_ahb_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &ahb_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch camss_vfe_vfe0_clk = {
+       .halt_reg = 0x36a8,
+       .clkr = {
+               .enable_reg = 0x36a8,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "camss_vfe_vfe0_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &vfe0_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch camss_vfe_vfe1_clk = {
+       .halt_reg = 0x36ac,
+       .clkr = {
+               .enable_reg = 0x36ac,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "camss_vfe_vfe1_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &vfe1_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch camss_vfe_vfe_ahb_clk = {
+       .halt_reg = 0x36b8,
+       .clkr = {
+               .enable_reg = 0x36b8,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "camss_vfe_vfe_ahb_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &ahb_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch camss_vfe_vfe_axi_clk = {
+       .halt_reg = 0x36bc,
+       .clkr = {
+               .enable_reg = 0x36bc,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "camss_vfe_vfe_axi_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &axi_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch fd_ahb_clk = {
+       .halt_reg = 0x3b74,
+       .clkr = {
+               .enable_reg = 0x3b74,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "fd_ahb_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &ahb_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch fd_axi_clk = {
+       .halt_reg = 0x3b70,
+       .clkr = {
+               .enable_reg = 0x3b70,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "fd_axi_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &axi_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch fd_core_clk = {
+       .halt_reg = 0x3b68,
+       .clkr = {
+               .enable_reg = 0x3b68,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "fd_core_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &fd_core_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch fd_core_uar_clk = {
+       .halt_reg = 0x3b6c,
+       .clkr = {
+               .enable_reg = 0x3b6c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "fd_core_uar_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &fd_core_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch mdss_ahb_clk = {
+       .halt_reg = 0x2308,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x2308,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "mdss_ahb_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &ahb_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch mdss_axi_clk = {
+       .halt_reg = 0x2310,
+       .clkr = {
+               .enable_reg = 0x2310,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "mdss_axi_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &axi_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch mdss_byte0_clk = {
+       .halt_reg = 0x233c,
+       .clkr = {
+               .enable_reg = 0x233c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "mdss_byte0_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &byte0_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch mdss_byte1_clk = {
+       .halt_reg = 0x2340,
+       .clkr = {
+               .enable_reg = 0x2340,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "mdss_byte1_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &byte1_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch mdss_esc0_clk = {
+       .halt_reg = 0x2344,
+       .clkr = {
+               .enable_reg = 0x2344,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "mdss_esc0_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &esc0_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch mdss_esc1_clk = {
+       .halt_reg = 0x2348,
+       .clkr = {
+               .enable_reg = 0x2348,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "mdss_esc1_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &esc1_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch mdss_extpclk_clk = {
+       .halt_reg = 0x2324,
+       .clkr = {
+               .enable_reg = 0x2324,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "mdss_extpclk_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &extpclk_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch mdss_hdmi_ahb_clk = {
+       .halt_reg = 0x230c,
+       .clkr = {
+               .enable_reg = 0x230c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "mdss_hdmi_ahb_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &ahb_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch mdss_hdmi_clk = {
+       .halt_reg = 0x2338,
+       .clkr = {
+               .enable_reg = 0x2338,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "mdss_hdmi_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &hdmi_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch mdss_mdp_clk = {
+       .halt_reg = 0x231c,
+       .clkr = {
+               .enable_reg = 0x231c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "mdss_mdp_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &mdp_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch mdss_pclk0_clk = {
+       .halt_reg = 0x2314,
+       .clkr = {
+               .enable_reg = 0x2314,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "mdss_pclk0_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &pclk0_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch mdss_pclk1_clk = {
+       .halt_reg = 0x2318,
+       .clkr = {
+               .enable_reg = 0x2318,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "mdss_pclk1_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &pclk1_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch mdss_vsync_clk = {
+       .halt_reg = 0x2328,
+       .clkr = {
+               .enable_reg = 0x2328,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "mdss_vsync_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &vsync_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch mmss_misc_ahb_clk = {
+       .halt_reg = 0x502c,
+       .clkr = {
+               .enable_reg = 0x502c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "mmss_misc_ahb_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &ahb_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch mmss_mmssnoc_axi_clk = {
+       .halt_reg = 0x506c,
+       .clkr = {
+               .enable_reg = 0x506c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "mmss_mmssnoc_axi_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &axi_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       /* Gating this clock will wreck havoc among MMSS! */
+                       .flags = CLK_SET_RATE_PARENT | CLK_IS_CRITICAL,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch mmss_s0_axi_clk = {
+       .halt_reg = 0x5064,
+       .clkr = {
+               .enable_reg = 0x5064,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "mmss_s0_axi_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &axi_clk_src.clkr.hw, },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch ocmemcx_ocmemnoc_clk = {
+       .halt_reg = 0x4058,
+       .clkr = {
+               .enable_reg = 0x4058,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "ocmemcx_ocmemnoc_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &ocmemnoc_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch oxili_gfx3d_clk = {
+       .halt_reg = 0x4028,
+       .clkr = {
+               .enable_reg = 0x4028,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "oxili_gfx3d_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .fw_name = "oxili_gfx3d_clk_src",
+                               .name = "oxili_gfx3d_clk_src"
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch oxili_rbbmtimer_clk = {
+       .halt_reg = 0x40b0,
+       .clkr = {
+               .enable_reg = 0x40b0,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "oxili_rbbmtimer_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &rbbmtimer_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch oxilicx_ahb_clk = {
+       .halt_reg = 0x403c,
+       .clkr = {
+               .enable_reg = 0x403c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "oxilicx_ahb_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &ahb_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch venus0_ahb_clk = {
+       .halt_reg = 0x1030,
+       .clkr = {
+               .enable_reg = 0x1030,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "venus0_ahb_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &ahb_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch venus0_axi_clk = {
+       .halt_reg = 0x1034,
+       .clkr = {
+               .enable_reg = 0x1034,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "venus0_axi_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &axi_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch venus0_ocmemnoc_clk = {
+       .halt_reg = 0x1038,
+       .clkr = {
+               .enable_reg = 0x1038,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "venus0_ocmemnoc_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &ocmemnoc_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch venus0_vcodec0_clk = {
+       .halt_reg = 0x1028,
+       .clkr = {
+               .enable_reg = 0x1028,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "venus0_vcodec0_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &vcodec0_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch venus0_core0_vcodec_clk = {
+       .halt_reg = 0x1048,
+       .clkr = {
+               .enable_reg = 0x1048,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "venus0_core0_vcodec_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &vcodec0_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch venus0_core1_vcodec_clk = {
+       .halt_reg = 0x104c,
+       .clkr = {
+               .enable_reg = 0x104c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "venus0_core1_vcodec_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &vcodec0_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch venus0_core2_vcodec_clk = {
+       .halt_reg = 0x1054,
+       .clkr = {
+               .enable_reg = 0x1054,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "venus0_core2_vcodec_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &vcodec0_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct gdsc venus_gdsc = {
+       .gdscr = 0x1024,
+       .cxcs = (unsigned int []){ 0x1038, 0x1034, 0x1048 },
+       .cxc_count = 3,
+       .pd = {
+               .name = "venus_gdsc",
+       },
+       .pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct gdsc venus_core0_gdsc = {
+       .gdscr = 0x1040,
+       .cxcs = (unsigned int []){ 0x1048 },
+       .cxc_count = 1,
+       .pd = {
+               .name = "venus_core0_gdsc",
+       },
+       .pwrsts = PWRSTS_OFF_ON,
+       .flags = HW_CTRL,
+};
+
+static struct gdsc venus_core1_gdsc = {
+       .gdscr = 0x1044,
+       .cxcs = (unsigned int []){ 0x104c },
+       .cxc_count = 1,
+       .pd = {
+       .name = "venus_core1_gdsc",
+       },
+       .pwrsts = PWRSTS_OFF_ON,
+       .flags = HW_CTRL,
+};
+
+static struct gdsc venus_core2_gdsc = {
+       .gdscr = 0x1050,
+       .cxcs = (unsigned int []){ 0x1054 },
+       .cxc_count = 1,
+       .pd = {
+               .name = "venus_core2_gdsc",
+       },
+       .pwrsts = PWRSTS_OFF_ON,
+       .flags = HW_CTRL,
+};
+
+static struct gdsc mdss_gdsc = {
+       .gdscr = 0x2304,
+       .cxcs = (unsigned int []){ 0x2310, 0x231c },
+       .cxc_count = 2,
+       .pd = {
+               .name = "mdss_gdsc",
+       },
+       .pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct gdsc camss_top_gdsc = {
+       .gdscr = 0x34a0,
+       .cxcs = (unsigned int []){ 0x3704, 0x3714, 0x3494 },
+       .cxc_count = 3,
+       .pd = {
+               .name = "camss_top_gdsc",
+       },
+       .pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct gdsc jpeg_gdsc = {
+       .gdscr = 0x35a4,
+       .cxcs = (unsigned int []){ 0x35a8 },
+       .cxc_count = 1,
+       .pd = {
+               .name = "jpeg_gdsc",
+       },
+       .parent = &camss_top_gdsc.pd,
+       .pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct gdsc vfe_gdsc = {
+       .gdscr = 0x36a4,
+       .cxcs = (unsigned int []){ 0x36bc },
+       .cxc_count = 1,
+       .pd = {
+               .name = "vfe_gdsc",
+       },
+       .parent = &camss_top_gdsc.pd,
+       .pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct gdsc cpp_gdsc = {
+       .gdscr = 0x36d4,
+       .cxcs = (unsigned int []){ 0x36c4, 0x36b0 },
+       .cxc_count = 2,
+       .pd = {
+               .name = "cpp_gdsc",
+       },
+       .parent = &camss_top_gdsc.pd,
+       .pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct gdsc fd_gdsc = {
+       .gdscr = 0x3b64,
+       .cxcs = (unsigned int []){ 0x3b70, 0x3b68 },
+       .pd = {
+               .name = "fd_gdsc",
+       },
+       .pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct gdsc oxili_cx_gdsc = {
+       .gdscr = 0x4034,
+       .pd = {
+               .name = "oxili_cx_gdsc",
+       },
+       .pwrsts = PWRSTS_OFF_ON,
+       .flags = VOTABLE,
+};
+
+static struct gdsc oxili_gx_gdsc = {
+       .gdscr = 0x4024,
+       .cxcs = (unsigned int []){ 0x4028 },
+       .cxc_count = 1,
+       .pd = {
+               .name = "oxili_gx_gdsc",
+       },
+       .pwrsts = PWRSTS_OFF_ON,
+       .parent = &oxili_cx_gdsc.pd,
+       .flags = CLAMP_IO,
+       .supply = "VDD_GFX",
+};
+
+static struct clk_regmap *mmcc_msm8994_clocks[] = {
+       [MMPLL0_EARLY] = &mmpll0_early.clkr,
+       [MMPLL0_PLL] = &mmpll0.clkr,
+       [MMPLL1_EARLY] = &mmpll1_early.clkr,
+       [MMPLL1_PLL] = &mmpll1.clkr,
+       [MMPLL3_EARLY] = &mmpll3_early.clkr,
+       [MMPLL3_PLL] = &mmpll3.clkr,
+       [MMPLL4_EARLY] = &mmpll4_early.clkr,
+       [MMPLL4_PLL] = &mmpll4.clkr,
+       [MMPLL5_EARLY] = &mmpll5_early.clkr,
+       [MMPLL5_PLL] = &mmpll5.clkr,
+       [AHB_CLK_SRC] = &ahb_clk_src.clkr,
+       [AXI_CLK_SRC] = &axi_clk_src.clkr,
+       [CSI0_CLK_SRC] = &csi0_clk_src.clkr,
+       [CSI1_CLK_SRC] = &csi1_clk_src.clkr,
+       [CSI2_CLK_SRC] = &csi2_clk_src.clkr,
+       [CSI3_CLK_SRC] = &csi3_clk_src.clkr,
+       [VFE0_CLK_SRC] = &vfe0_clk_src.clkr,
+       [VFE1_CLK_SRC] = &vfe1_clk_src.clkr,
+       [CPP_CLK_SRC] = &cpp_clk_src.clkr,
+       [JPEG0_CLK_SRC] = &jpeg0_clk_src.clkr,
+       [JPEG1_CLK_SRC] = &jpeg1_clk_src.clkr,
+       [JPEG2_CLK_SRC] = &jpeg2_clk_src.clkr,
+       [CSI2PHYTIMER_CLK_SRC] = &csi2phytimer_clk_src.clkr,
+       [FD_CORE_CLK_SRC] = &fd_core_clk_src.clkr,
+       [MDP_CLK_SRC] = &mdp_clk_src.clkr,
+       [PCLK0_CLK_SRC] = &pclk0_clk_src.clkr,
+       [PCLK1_CLK_SRC] = &pclk1_clk_src.clkr,
+       [OCMEMNOC_CLK_SRC] = &ocmemnoc_clk_src.clkr,
+       [CCI_CLK_SRC] = &cci_clk_src.clkr,
+       [MMSS_GP0_CLK_SRC] = &mmss_gp0_clk_src.clkr,
+       [MMSS_GP1_CLK_SRC] = &mmss_gp1_clk_src.clkr,
+       [JPEG_DMA_CLK_SRC] = &jpeg_dma_clk_src.clkr,
+       [MCLK0_CLK_SRC] = &mclk0_clk_src.clkr,
+       [MCLK1_CLK_SRC] = &mclk1_clk_src.clkr,
+       [MCLK2_CLK_SRC] = &mclk2_clk_src.clkr,
+       [MCLK3_CLK_SRC] = &mclk3_clk_src.clkr,
+       [CSI0PHYTIMER_CLK_SRC] = &csi0phytimer_clk_src.clkr,
+       [CSI1PHYTIMER_CLK_SRC] = &csi1phytimer_clk_src.clkr,
+       [BYTE0_CLK_SRC] = &byte0_clk_src.clkr,
+       [BYTE1_CLK_SRC] = &byte1_clk_src.clkr,
+       [ESC0_CLK_SRC] = &esc0_clk_src.clkr,
+       [ESC1_CLK_SRC] = &esc1_clk_src.clkr,
+       [MDSS_ESC0_CLK] = &mdss_esc0_clk.clkr,
+       [MDSS_ESC1_CLK] = &mdss_esc1_clk.clkr,
+       [EXTPCLK_CLK_SRC] = &extpclk_clk_src.clkr,
+       [HDMI_CLK_SRC] = &hdmi_clk_src.clkr,
+       [VSYNC_CLK_SRC] = &vsync_clk_src.clkr,
+       [RBBMTIMER_CLK_SRC] = &rbbmtimer_clk_src.clkr,
+       [CAMSS_AHB_CLK] = &camss_ahb_clk.clkr,
+       [CAMSS_CCI_CCI_AHB_CLK] = &camss_cci_cci_ahb_clk.clkr,
+       [CAMSS_CCI_CCI_CLK] = &camss_cci_cci_clk.clkr,
+       [CAMSS_VFE_CPP_AHB_CLK] = &camss_vfe_cpp_ahb_clk.clkr,
+       [CAMSS_VFE_CPP_AXI_CLK] = &camss_vfe_cpp_axi_clk.clkr,
+       [CAMSS_VFE_CPP_CLK] = &camss_vfe_cpp_clk.clkr,
+       [CAMSS_CSI0_AHB_CLK] = &camss_csi0_ahb_clk.clkr,
+       [CAMSS_CSI0_CLK] = &camss_csi0_clk.clkr,
+       [CAMSS_CSI0PHY_CLK] = &camss_csi0phy_clk.clkr,
+       [CAMSS_CSI0PIX_CLK] = &camss_csi0pix_clk.clkr,
+       [CAMSS_CSI0RDI_CLK] = &camss_csi0rdi_clk.clkr,
+       [CAMSS_CSI1_AHB_CLK] = &camss_csi1_ahb_clk.clkr,
+       [CAMSS_CSI1_CLK] = &camss_csi1_clk.clkr,
+       [CAMSS_CSI1PHY_CLK] = &camss_csi1phy_clk.clkr,
+       [CAMSS_CSI1PIX_CLK] = &camss_csi1pix_clk.clkr,
+       [CAMSS_CSI1RDI_CLK] = &camss_csi1rdi_clk.clkr,
+       [CAMSS_CSI2_AHB_CLK] = &camss_csi2_ahb_clk.clkr,
+       [CAMSS_CSI2_CLK] = &camss_csi2_clk.clkr,
+       [CAMSS_CSI2PHY_CLK] = &camss_csi2phy_clk.clkr,
+       [CAMSS_CSI2PIX_CLK] = &camss_csi2pix_clk.clkr,
+       [CAMSS_CSI2RDI_CLK] = &camss_csi2rdi_clk.clkr,
+       [CAMSS_CSI3_AHB_CLK] = &camss_csi3_ahb_clk.clkr,
+       [CAMSS_CSI3_CLK] = &camss_csi3_clk.clkr,
+       [CAMSS_CSI3PHY_CLK] = &camss_csi3phy_clk.clkr,
+       [CAMSS_CSI3PIX_CLK] = &camss_csi3pix_clk.clkr,
+       [CAMSS_CSI3RDI_CLK] = &camss_csi3rdi_clk.clkr,
+       [CAMSS_CSI_VFE0_CLK] = &camss_csi_vfe0_clk.clkr,
+       [CAMSS_CSI_VFE1_CLK] = &camss_csi_vfe1_clk.clkr,
+       [CAMSS_GP0_CLK] = &camss_gp0_clk.clkr,
+       [CAMSS_GP1_CLK] = &camss_gp1_clk.clkr,
+       [CAMSS_ISPIF_AHB_CLK] = &camss_ispif_ahb_clk.clkr,
+       [CAMSS_JPEG_DMA_CLK] = &camss_jpeg_dma_clk.clkr,
+       [CAMSS_JPEG_JPEG0_CLK] = &camss_jpeg_jpeg0_clk.clkr,
+       [CAMSS_JPEG_JPEG1_CLK] = &camss_jpeg_jpeg1_clk.clkr,
+       [CAMSS_JPEG_JPEG2_CLK] = &camss_jpeg_jpeg2_clk.clkr,
+       [CAMSS_JPEG_JPEG_AHB_CLK] = &camss_jpeg_jpeg_ahb_clk.clkr,
+       [CAMSS_JPEG_JPEG_AXI_CLK] = &camss_jpeg_jpeg_axi_clk.clkr,
+       [CAMSS_MCLK0_CLK] = &camss_mclk0_clk.clkr,
+       [CAMSS_MCLK1_CLK] = &camss_mclk1_clk.clkr,
+       [CAMSS_MCLK2_CLK] = &camss_mclk2_clk.clkr,
+       [CAMSS_MCLK3_CLK] = &camss_mclk3_clk.clkr,
+       [CAMSS_MICRO_AHB_CLK] = &camss_micro_ahb_clk.clkr,
+       [CAMSS_PHY0_CSI0PHYTIMER_CLK] = &camss_phy0_csi0phytimer_clk.clkr,
+       [CAMSS_PHY1_CSI1PHYTIMER_CLK] = &camss_phy1_csi1phytimer_clk.clkr,
+       [CAMSS_PHY2_CSI2PHYTIMER_CLK] = &camss_phy2_csi2phytimer_clk.clkr,
+       [CAMSS_TOP_AHB_CLK] = &camss_top_ahb_clk.clkr,
+       [CAMSS_VFE_VFE0_CLK] = &camss_vfe_vfe0_clk.clkr,
+       [CAMSS_VFE_VFE1_CLK] = &camss_vfe_vfe1_clk.clkr,
+       [CAMSS_VFE_VFE_AHB_CLK] = &camss_vfe_vfe_ahb_clk.clkr,
+       [CAMSS_VFE_VFE_AXI_CLK] = &camss_vfe_vfe_axi_clk.clkr,
+       [FD_AHB_CLK] = &fd_ahb_clk.clkr,
+       [FD_AXI_CLK] = &fd_axi_clk.clkr,
+       [FD_CORE_CLK] = &fd_core_clk.clkr,
+       [FD_CORE_UAR_CLK] = &fd_core_uar_clk.clkr,
+       [MDSS_AHB_CLK] = &mdss_ahb_clk.clkr,
+       [MDSS_AXI_CLK] = &mdss_axi_clk.clkr,
+       [MDSS_BYTE0_CLK] = &mdss_byte0_clk.clkr,
+       [MDSS_BYTE1_CLK] = &mdss_byte1_clk.clkr,
+       [MDSS_EXTPCLK_CLK] = &mdss_extpclk_clk.clkr,
+       [MDSS_HDMI_AHB_CLK] = &mdss_hdmi_ahb_clk.clkr,
+       [MDSS_HDMI_CLK] = &mdss_hdmi_clk.clkr,
+       [MDSS_MDP_CLK] = &mdss_mdp_clk.clkr,
+       [MDSS_PCLK0_CLK] = &mdss_pclk0_clk.clkr,
+       [MDSS_PCLK1_CLK] = &mdss_pclk1_clk.clkr,
+       [MDSS_VSYNC_CLK] = &mdss_vsync_clk.clkr,
+       [MMSS_MISC_AHB_CLK] = &mmss_misc_ahb_clk.clkr,
+       [MMSS_MMSSNOC_AXI_CLK] = &mmss_mmssnoc_axi_clk.clkr,
+       [MMSS_S0_AXI_CLK] = &mmss_s0_axi_clk.clkr,
+       [OCMEMCX_OCMEMNOC_CLK] = &ocmemcx_ocmemnoc_clk.clkr,
+       [OXILI_GFX3D_CLK] = &oxili_gfx3d_clk.clkr,
+       [OXILI_RBBMTIMER_CLK] = &oxili_rbbmtimer_clk.clkr,
+       [OXILICX_AHB_CLK] = &oxilicx_ahb_clk.clkr,
+       [VENUS0_AHB_CLK] = &venus0_ahb_clk.clkr,
+       [VENUS0_AXI_CLK] = &venus0_axi_clk.clkr,
+       [VENUS0_OCMEMNOC_CLK] = &venus0_ocmemnoc_clk.clkr,
+       [VENUS0_VCODEC0_CLK] = &venus0_vcodec0_clk.clkr,
+       [VENUS0_CORE0_VCODEC_CLK] = &venus0_core0_vcodec_clk.clkr,
+       [VENUS0_CORE1_VCODEC_CLK] = &venus0_core1_vcodec_clk.clkr,
+       [VENUS0_CORE2_VCODEC_CLK] = &venus0_core2_vcodec_clk.clkr,
+};
+
+static struct gdsc *mmcc_msm8994_gdscs[] = {
+       [VENUS_GDSC] = &venus_gdsc,
+       [VENUS_CORE0_GDSC] = &venus_core0_gdsc,
+       [VENUS_CORE1_GDSC] = &venus_core1_gdsc,
+       [VENUS_CORE2_GDSC] = &venus_core2_gdsc,
+       [CAMSS_TOP_GDSC] = &camss_top_gdsc,
+       [MDSS_GDSC] = &mdss_gdsc,
+       [JPEG_GDSC] = &jpeg_gdsc,
+       [VFE_GDSC] = &vfe_gdsc,
+       [CPP_GDSC] = &cpp_gdsc,
+       [OXILI_GX_GDSC] = &oxili_gx_gdsc,
+       [OXILI_CX_GDSC] = &oxili_cx_gdsc,
+       [FD_GDSC] = &fd_gdsc,
+};
+
+static const struct qcom_reset_map mmcc_msm8994_resets[] = {
+       [CAMSS_MICRO_BCR] = { 0x3490 },
+};
+
+static const struct regmap_config mmcc_msm8994_regmap_config = {
+       .reg_bits       = 32,
+       .reg_stride     = 4,
+       .val_bits       = 32,
+       .max_register   = 0x5200,
+       .fast_io        = true,
+};
+
+static const struct qcom_cc_desc mmcc_msm8994_desc = {
+       .config = &mmcc_msm8994_regmap_config,
+       .clks = mmcc_msm8994_clocks,
+       .num_clks = ARRAY_SIZE(mmcc_msm8994_clocks),
+       .resets = mmcc_msm8994_resets,
+       .num_resets = ARRAY_SIZE(mmcc_msm8994_resets),
+       .gdscs = mmcc_msm8994_gdscs,
+       .num_gdscs = ARRAY_SIZE(mmcc_msm8994_gdscs),
+};
+
+static const struct of_device_id mmcc_msm8994_match_table[] = {
+       { .compatible = "qcom,mmcc-msm8992" },
+       { .compatible = "qcom,mmcc-msm8994" }, /* V2 and V2.1 */
+       { }
+};
+MODULE_DEVICE_TABLE(of, mmcc_msm8994_match_table);
+
+static int mmcc_msm8994_probe(struct platform_device *pdev)
+{
+       struct regmap *regmap;
+
+       if (of_device_is_compatible(pdev->dev.of_node, "qcom,mmcc-msm8992")) {
+               /* MSM8992 features less clocks and some have different freq tables */
+               mmcc_msm8994_desc.clks[CAMSS_JPEG_JPEG1_CLK] = NULL;
+               mmcc_msm8994_desc.clks[CAMSS_JPEG_JPEG2_CLK] = NULL;
+               mmcc_msm8994_desc.clks[FD_CORE_CLK_SRC] = NULL;
+               mmcc_msm8994_desc.clks[FD_CORE_CLK] = NULL;
+               mmcc_msm8994_desc.clks[FD_CORE_UAR_CLK] = NULL;
+               mmcc_msm8994_desc.clks[FD_AXI_CLK] = NULL;
+               mmcc_msm8994_desc.clks[FD_AHB_CLK] = NULL;
+               mmcc_msm8994_desc.clks[JPEG1_CLK_SRC] = NULL;
+               mmcc_msm8994_desc.clks[JPEG2_CLK_SRC] = NULL;
+               mmcc_msm8994_desc.clks[VENUS0_CORE2_VCODEC_CLK] = NULL;
+
+               mmcc_msm8994_desc.gdscs[FD_GDSC] = NULL;
+               mmcc_msm8994_desc.gdscs[VENUS_CORE2_GDSC] = NULL;
+
+               axi_clk_src.freq_tbl = ftbl_axi_clk_src_8992;
+               cpp_clk_src.freq_tbl = ftbl_cpp_clk_src_8992;
+               csi0_clk_src.freq_tbl = ftbl_csi0_1_2_3_clk_src_8992;
+               csi1_clk_src.freq_tbl = ftbl_csi0_1_2_3_clk_src_8992;
+               csi2_clk_src.freq_tbl = ftbl_csi0_1_2_3_clk_src_8992;
+               csi3_clk_src.freq_tbl = ftbl_csi0_1_2_3_clk_src_8992;
+               mclk0_clk_src.freq_tbl = ftbl_mclk0_clk_src_8992;
+               mclk1_clk_src.freq_tbl = ftbl_mclk1_2_3_clk_src_8992;
+               mclk2_clk_src.freq_tbl = ftbl_mclk1_2_3_clk_src_8992;
+               mclk3_clk_src.freq_tbl = ftbl_mclk1_2_3_clk_src_8992;
+               mdp_clk_src.freq_tbl = ftbl_mdp_clk_src_8992;
+               ocmemnoc_clk_src.freq_tbl = ftbl_ocmemnoc_clk_src_8992;
+               vcodec0_clk_src.freq_tbl = ftbl_vcodec0_clk_src_8992;
+               vfe0_clk_src.freq_tbl = ftbl_vfe0_1_clk_src_8992;
+               vfe1_clk_src.freq_tbl = ftbl_vfe0_1_clk_src_8992;
+       }
+
+       regmap = qcom_cc_map(pdev, &mmcc_msm8994_desc);
+       if (IS_ERR(regmap))
+               return PTR_ERR(regmap);
+
+       clk_alpha_pll_configure(&mmpll0_early, regmap, &mmpll_p_config);
+       clk_alpha_pll_configure(&mmpll1_early, regmap, &mmpll_p_config);
+       clk_alpha_pll_configure(&mmpll3_early, regmap, &mmpll_p_config);
+       clk_alpha_pll_configure(&mmpll5_early, regmap, &mmpll_p_config);
+
+       return qcom_cc_really_probe(pdev, &mmcc_msm8994_desc, regmap);
+}
+
+static struct platform_driver mmcc_msm8994_driver = {
+       .probe          = mmcc_msm8994_probe,
+       .driver         = {
+               .name   = "mmcc-msm8994",
+               .of_match_table = mmcc_msm8994_match_table,
+       },
+};
+module_platform_driver(mmcc_msm8994_driver);
+
+MODULE_DESCRIPTION("QCOM MMCC MSM8994 Driver");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:mmcc-msm8994");
index 673fa1a..5a14074 100644 (file)
@@ -73,36 +73,23 @@ static int mss_sc7180_probe(struct platform_device *pdev)
 {
        int ret;
 
-       pm_runtime_enable(&pdev->dev);
-       ret = pm_clk_create(&pdev->dev);
+       ret = devm_pm_runtime_enable(&pdev->dev);
        if (ret)
-               goto disable_pm_runtime;
+               return ret;
+
+       ret = devm_pm_clk_create(&pdev->dev);
+       if (ret)
+               return ret;
 
        ret = pm_clk_add(&pdev->dev, "cfg_ahb");
        if (ret < 0) {
                dev_err(&pdev->dev, "failed to acquire iface clock\n");
-               goto destroy_pm_clk;
+               return ret;
        }
 
        ret = qcom_cc_probe(pdev, &mss_sc7180_desc);
        if (ret < 0)
-               goto destroy_pm_clk;
-
-       return 0;
-
-destroy_pm_clk:
-       pm_clk_destroy(&pdev->dev);
-
-disable_pm_runtime:
-       pm_runtime_disable(&pdev->dev);
-
-       return ret;
-}
-
-static int mss_sc7180_remove(struct platform_device *pdev)
-{
-       pm_clk_destroy(&pdev->dev);
-       pm_runtime_disable(&pdev->dev);
+               return ret;
 
        return 0;
 }
@@ -119,7 +106,6 @@ MODULE_DEVICE_TABLE(of, mss_sc7180_match_table);
 
 static struct platform_driver mss_sc7180_driver = {
        .probe          = mss_sc7180_probe,
-       .remove         = mss_sc7180_remove,
        .driver         = {
                .name           = "sc7180-mss",
                .of_match_table = mss_sc7180_match_table,
index 723f932..507386b 100644 (file)
@@ -159,15 +159,18 @@ static int q6sstopcc_qcs404_probe(struct platform_device *pdev)
        const struct qcom_cc_desc *desc;
        int ret;
 
-       pm_runtime_enable(&pdev->dev);
-       ret = pm_clk_create(&pdev->dev);
+       ret = devm_pm_runtime_enable(&pdev->dev);
        if (ret)
-               goto disable_pm_runtime;
+               return ret;
+
+       ret = devm_pm_clk_create(&pdev->dev);
+       if (ret)
+               return ret;
 
        ret = pm_clk_add(&pdev->dev, NULL);
        if (ret < 0) {
                dev_err(&pdev->dev, "failed to acquire iface clock\n");
-               goto destroy_pm_clk;
+               return ret;
        }
 
        q6sstop_regmap_config.name = "q6sstop_tcsr";
@@ -175,30 +178,14 @@ static int q6sstopcc_qcs404_probe(struct platform_device *pdev)
 
        ret = qcom_cc_probe_by_index(pdev, 1, desc);
        if (ret)
-               goto destroy_pm_clk;
+               return ret;
 
        q6sstop_regmap_config.name = "q6sstop_cc";
        desc = &q6sstop_qcs404_desc;
 
        ret = qcom_cc_probe_by_index(pdev, 0, desc);
        if (ret)
-               goto destroy_pm_clk;
-
-       return 0;
-
-destroy_pm_clk:
-       pm_clk_destroy(&pdev->dev);
-
-disable_pm_runtime:
-       pm_runtime_disable(&pdev->dev);
-
-       return ret;
-}
-
-static int q6sstopcc_qcs404_remove(struct platform_device *pdev)
-{
-       pm_clk_destroy(&pdev->dev);
-       pm_runtime_disable(&pdev->dev);
+               return ret;
 
        return 0;
 }
@@ -209,7 +196,6 @@ static const struct dev_pm_ops q6sstopcc_pm_ops = {
 
 static struct platform_driver q6sstopcc_qcs404_driver = {
        .probe          = q6sstopcc_qcs404_probe,
-       .remove         = q6sstopcc_qcs404_remove,
        .driver         = {
                .name   = "qcs404-q6sstopcc",
                .of_match_table = q6sstopcc_qcs404_match_table,
index 4cfbbf5..4543bda 100644 (file)
@@ -110,36 +110,23 @@ static int turingcc_probe(struct platform_device *pdev)
 {
        int ret;
 
-       pm_runtime_enable(&pdev->dev);
-       ret = pm_clk_create(&pdev->dev);
+       ret = devm_pm_runtime_enable(&pdev->dev);
        if (ret)
-               goto disable_pm_runtime;
+               return ret;
+
+       ret = devm_pm_clk_create(&pdev->dev);
+       if (ret)
+               return ret;
 
        ret = pm_clk_add(&pdev->dev, NULL);
        if (ret < 0) {
                dev_err(&pdev->dev, "failed to acquire iface clock\n");
-               goto destroy_pm_clk;
+               return ret;
        }
 
        ret = qcom_cc_probe(pdev, &turingcc_desc);
        if (ret < 0)
-               goto destroy_pm_clk;
-
-       return 0;
-
-destroy_pm_clk:
-       pm_clk_destroy(&pdev->dev);
-
-disable_pm_runtime:
-       pm_runtime_disable(&pdev->dev);
-
-       return ret;
-}
-
-static int turingcc_remove(struct platform_device *pdev)
-{
-       pm_clk_destroy(&pdev->dev);
-       pm_runtime_disable(&pdev->dev);
+               return ret;
 
        return 0;
 }
@@ -156,7 +143,6 @@ MODULE_DEVICE_TABLE(of, turingcc_match_table);
 
 static struct platform_driver turingcc_driver = {
        .probe          = turingcc_probe,
-       .remove         = turingcc_remove,
        .driver         = {
                .name   = "qcs404-turingcc",
                .of_match_table = turingcc_match_table,
diff --git a/drivers/clk/qcom/videocc-sc7280.c b/drivers/clk/qcom/videocc-sc7280.c
new file mode 100644 (file)
index 0000000..615695d
--- /dev/null
@@ -0,0 +1,325 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2021, The Linux Foundation. All rights reserved.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+#include <dt-bindings/clock/qcom,videocc-sc7280.h>
+
+#include "clk-alpha-pll.h"
+#include "clk-branch.h"
+#include "clk-rcg.h"
+#include "common.h"
+#include "reset.h"
+#include "gdsc.h"
+
+enum {
+       P_BI_TCXO,
+       P_SLEEP_CLK,
+       P_VIDEO_PLL0_OUT_EVEN,
+};
+
+static const struct pll_vco lucid_vco[] = {
+       { 249600000, 2000000000, 0 },
+};
+
+/* 400MHz Configuration */
+static const struct alpha_pll_config video_pll0_config = {
+       .l = 0x14,
+       .alpha = 0xD555,
+       .config_ctl_val = 0x20485699,
+       .config_ctl_hi_val = 0x00002261,
+       .config_ctl_hi1_val = 0x329A299C,
+       .user_ctl_val = 0x00000001,
+       .user_ctl_hi_val = 0x00000805,
+       .user_ctl_hi1_val = 0x00000000,
+};
+
+static struct clk_alpha_pll video_pll0 = {
+       .offset = 0x0,
+       .vco_table = lucid_vco,
+       .num_vco = ARRAY_SIZE(lucid_vco),
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID],
+       .clkr = {
+               .hw.init = &(struct clk_init_data){
+                       .name = "video_pll0",
+                       .parent_data = &(const struct clk_parent_data){
+                               .fw_name = "bi_tcxo",
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_alpha_pll_lucid_ops,
+               },
+       },
+};
+
+static const struct parent_map video_cc_parent_map_0[] = {
+       { P_BI_TCXO, 0 },
+       { P_VIDEO_PLL0_OUT_EVEN, 3 },
+};
+
+static const struct clk_parent_data video_cc_parent_data_0[] = {
+       { .fw_name = "bi_tcxo" },
+       { .hw = &video_pll0.clkr.hw },
+};
+
+static const struct parent_map video_cc_parent_map_1[] = {
+       { P_SLEEP_CLK, 0 },
+};
+
+static const struct clk_parent_data video_cc_parent_data_1[] = {
+       { .fw_name = "sleep_clk" },
+};
+
+static const struct freq_tbl ftbl_video_cc_iris_clk_src[] = {
+       F(133333333, P_VIDEO_PLL0_OUT_EVEN, 3, 0, 0),
+       F(240000000, P_VIDEO_PLL0_OUT_EVEN, 2, 0, 0),
+       F(335000000, P_VIDEO_PLL0_OUT_EVEN, 2, 0, 0),
+       F(424000000, P_VIDEO_PLL0_OUT_EVEN, 2, 0, 0),
+       F(460000000, P_VIDEO_PLL0_OUT_EVEN, 2, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 video_cc_iris_clk_src = {
+       .cmd_rcgr = 0x1000,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = video_cc_parent_map_0,
+       .freq_tbl = ftbl_video_cc_iris_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "video_cc_iris_clk_src",
+               .parent_data = video_cc_parent_data_0,
+               .num_parents = ARRAY_SIZE(video_cc_parent_data_0),
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_shared_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_video_cc_sleep_clk_src[] = {
+       F(32000, P_SLEEP_CLK, 1, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 video_cc_sleep_clk_src = {
+       .cmd_rcgr = 0x701c,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = video_cc_parent_map_1,
+       .freq_tbl = ftbl_video_cc_sleep_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "video_cc_sleep_clk_src",
+               .parent_data = video_cc_parent_data_1,
+               .num_parents = ARRAY_SIZE(video_cc_parent_data_1),
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_branch video_cc_iris_ahb_clk = {
+       .halt_reg = 0x5004,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x5004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "video_cc_iris_ahb_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &video_cc_iris_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch video_cc_mvs0_axi_clk = {
+       .halt_reg = 0x800c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x800c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "video_cc_mvs0_axi_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch video_cc_mvs0_core_clk = {
+       .halt_reg = 0x3010,
+       .halt_check = BRANCH_HALT_VOTED,
+       .hwcg_reg = 0x3010,
+       .hwcg_bit = 1,
+       .clkr = {
+               .enable_reg = 0x3010,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "video_cc_mvs0_core_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &video_cc_iris_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch video_cc_mvsc_core_clk = {
+       .halt_reg = 0x2014,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x2014,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "video_cc_mvsc_core_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &video_cc_iris_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch video_cc_mvsc_ctl_axi_clk = {
+       .halt_reg = 0x8004,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x8004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "video_cc_mvsc_ctl_axi_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch video_cc_sleep_clk = {
+       .halt_reg = 0x7034,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x7034,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "video_cc_sleep_clk",
+                       .parent_hws = (const struct clk_hw*[]){
+                               &video_cc_sleep_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch video_cc_venus_ahb_clk = {
+       .halt_reg = 0x801c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x801c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "video_cc_venus_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct gdsc mvs0_gdsc = {
+       .gdscr = 0x3004,
+       .pd = {
+               .name = "mvs0_gdsc",
+       },
+       .pwrsts = PWRSTS_OFF_ON,
+       .flags = HW_CTRL | RETAIN_FF_ENABLE,
+};
+
+static struct gdsc mvsc_gdsc = {
+       .gdscr = 0x2004,
+       .pd = {
+               .name = "mvsc_gdsc",
+       },
+       .flags = RETAIN_FF_ENABLE,
+       .pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct clk_regmap *video_cc_sc7280_clocks[] = {
+       [VIDEO_CC_IRIS_AHB_CLK] = &video_cc_iris_ahb_clk.clkr,
+       [VIDEO_CC_IRIS_CLK_SRC] = &video_cc_iris_clk_src.clkr,
+       [VIDEO_CC_MVS0_AXI_CLK] = &video_cc_mvs0_axi_clk.clkr,
+       [VIDEO_CC_MVS0_CORE_CLK] = &video_cc_mvs0_core_clk.clkr,
+       [VIDEO_CC_MVSC_CORE_CLK] = &video_cc_mvsc_core_clk.clkr,
+       [VIDEO_CC_MVSC_CTL_AXI_CLK] = &video_cc_mvsc_ctl_axi_clk.clkr,
+       [VIDEO_CC_SLEEP_CLK] = &video_cc_sleep_clk.clkr,
+       [VIDEO_CC_SLEEP_CLK_SRC] = &video_cc_sleep_clk_src.clkr,
+       [VIDEO_CC_VENUS_AHB_CLK] = &video_cc_venus_ahb_clk.clkr,
+       [VIDEO_PLL0] = &video_pll0.clkr,
+};
+
+static struct gdsc *video_cc_sc7280_gdscs[] = {
+       [MVS0_GDSC] = &mvs0_gdsc,
+       [MVSC_GDSC] = &mvsc_gdsc,
+};
+
+static const struct regmap_config video_cc_sc7280_regmap_config = {
+       .reg_bits = 32,
+       .reg_stride = 4,
+       .val_bits = 32,
+       .max_register = 0xb000,
+       .fast_io = true,
+};
+
+static const struct qcom_cc_desc video_cc_sc7280_desc = {
+       .config = &video_cc_sc7280_regmap_config,
+       .clks = video_cc_sc7280_clocks,
+       .num_clks = ARRAY_SIZE(video_cc_sc7280_clocks),
+       .gdscs = video_cc_sc7280_gdscs,
+       .num_gdscs = ARRAY_SIZE(video_cc_sc7280_gdscs),
+};
+
+static const struct of_device_id video_cc_sc7280_match_table[] = {
+       { .compatible = "qcom,sc7280-videocc" },
+       { }
+};
+MODULE_DEVICE_TABLE(of, video_cc_sc7280_match_table);
+
+static int video_cc_sc7280_probe(struct platform_device *pdev)
+{
+       struct regmap *regmap;
+
+       regmap = qcom_cc_map(pdev, &video_cc_sc7280_desc);
+       if (IS_ERR(regmap))
+               return PTR_ERR(regmap);
+
+       clk_lucid_pll_configure(&video_pll0, regmap, &video_pll0_config);
+
+       return qcom_cc_really_probe(pdev, &video_cc_sc7280_desc, regmap);
+}
+
+static struct platform_driver video_cc_sc7280_driver = {
+       .probe = video_cc_sc7280_probe,
+       .driver = {
+               .name = "video_cc-sc7280",
+               .of_match_table = video_cc_sc7280_match_table,
+       },
+};
+
+static int __init video_cc_sc7280_init(void)
+{
+       return platform_driver_register(&video_cc_sc7280_driver);
+}
+subsys_initcall(video_cc_sc7280_init);
+
+static void __exit video_cc_sc7280_exit(void)
+{
+       platform_driver_unregister(&video_cc_sc7280_driver);
+}
+module_exit(video_cc_sc7280_exit);
+
+MODULE_DESCRIPTION("QTI VIDEO_CC sc7280 Driver");
+MODULE_LICENSE("GPL v2");
index 7b45065..6d02807 100644 (file)
@@ -153,9 +153,7 @@ config CLK_R8A779A0
        select CLK_RENESAS_CPG_MSSR
 
 config CLK_R9A06G032
-       bool "Renesas R9A06G032 clock driver"
-       help
-         This is a driver for R9A06G032 clocks
+       bool "RZ/N1D clock support" if COMPILE_TEST
 
 config CLK_R9A07G044
        bool "RZ/G2L clock support" if COMPILE_TEST
index 5c6c5c7..7d01870 100644 (file)
@@ -37,7 +37,7 @@ obj-$(CONFIG_CLK_RCAR_CPG_LIB)                += rcar-cpg-lib.o
 obj-$(CONFIG_CLK_RCAR_GEN2_CPG)                += rcar-gen2-cpg.o
 obj-$(CONFIG_CLK_RCAR_GEN3_CPG)                += rcar-gen3-cpg.o
 obj-$(CONFIG_CLK_RCAR_USB2_CLOCK_SEL)  += rcar-usb2-clock-sel.o
-obj-$(CONFIG_CLK_RZG2L)                        += renesas-rzg2l-cpg.o
+obj-$(CONFIG_CLK_RZG2L)                        += rzg2l-cpg.o
 
 # Generic
 obj-$(CONFIG_CLK_RENESAS_CPG_MSSR)     += renesas-cpg-mssr.o
index 4a43ebe..39b185d 100644 (file)
@@ -210,7 +210,7 @@ static const struct mssr_mod_clk r8a774a1_mod_clks[] __initconst = {
        DEF_MOD("rpc-if",                917,   R8A774A1_CLK_RPCD2),
        DEF_MOD("i2c6",                  918,   R8A774A1_CLK_S0D6),
        DEF_MOD("i2c5",                  919,   R8A774A1_CLK_S0D6),
-       DEF_MOD("i2c-dvfs",              926,   R8A774A1_CLK_CP),
+       DEF_MOD("iic-pmic",              926,   R8A774A1_CLK_CP),
        DEF_MOD("i2c4",                  927,   R8A774A1_CLK_S0D6),
        DEF_MOD("i2c3",                  928,   R8A774A1_CLK_S0D6),
        DEF_MOD("i2c2",                  929,   R8A774A1_CLK_S3D2),
index 6f04c40..af602d8 100644 (file)
@@ -206,7 +206,7 @@ static const struct mssr_mod_clk r8a774b1_mod_clks[] __initconst = {
        DEF_MOD("rpc-if",                917,   R8A774B1_CLK_RPCD2),
        DEF_MOD("i2c6",                  918,   R8A774B1_CLK_S0D6),
        DEF_MOD("i2c5",                  919,   R8A774B1_CLK_S0D6),
-       DEF_MOD("i2c-dvfs",              926,   R8A774B1_CLK_CP),
+       DEF_MOD("iic-pmic",              926,   R8A774B1_CLK_CP),
        DEF_MOD("i2c4",                  927,   R8A774B1_CLK_S0D6),
        DEF_MOD("i2c3",                  928,   R8A774B1_CLK_S0D6),
        DEF_MOD("i2c2",                  929,   R8A774B1_CLK_S3D2),
index ed3a2cf..5b938eb 100644 (file)
@@ -210,7 +210,7 @@ static const struct mssr_mod_clk r8a774c0_mod_clks[] __initconst = {
        DEF_MOD("rpc-if",                917,   R8A774C0_CLK_RPCD2),
        DEF_MOD("i2c6",                  918,   R8A774C0_CLK_S3D2),
        DEF_MOD("i2c5",                  919,   R8A774C0_CLK_S3D2),
-       DEF_MOD("i2c-dvfs",              926,   R8A774C0_CLK_CP),
+       DEF_MOD("iic-pmic",              926,   R8A774C0_CLK_CP),
        DEF_MOD("i2c4",                  927,   R8A774C0_CLK_S3D2),
        DEF_MOD("i2c3",                  928,   R8A774C0_CLK_S3D2),
        DEF_MOD("i2c2",                  929,   R8A774C0_CLK_S3D2),
index b96c486..40c7146 100644 (file)
@@ -219,7 +219,7 @@ static const struct mssr_mod_clk r8a774e1_mod_clks[] __initconst = {
        DEF_MOD("i2c6",                  918,   R8A774E1_CLK_S0D6),
        DEF_MOD("i2c5",                  919,   R8A774E1_CLK_S0D6),
        DEF_MOD("adg",                   922,   R8A774E1_CLK_S0D1),
-       DEF_MOD("i2c-dvfs",              926,   R8A774E1_CLK_CP),
+       DEF_MOD("iic-pmic",              926,   R8A774E1_CLK_CP),
        DEF_MOD("i2c4",                  927,   R8A774E1_CLK_S0D6),
        DEF_MOD("i2c3",                  928,   R8A774E1_CLK_S0D6),
        DEF_MOD("i2c2",                  929,   R8A774E1_CLK_S3D2),
index acaf5a9..f16d125 100644 (file)
@@ -135,7 +135,6 @@ static const struct cpg_core_clk r8a779a0_core_clks[] __initconst = {
        DEF_FIXED("zt",         R8A779A0_CLK_ZT,        CLK_PLL1_DIV2,  2, 1),
        DEF_FIXED("ztr",        R8A779A0_CLK_ZTR,       CLK_PLL1_DIV2,  2, 1),
        DEF_FIXED("zr",         R8A779A0_CLK_ZR,        CLK_PLL1_DIV2,  1, 1),
-       DEF_FIXED("dsi",        R8A779A0_CLK_DSI,       CLK_PLL5_DIV4,  1, 1),
        DEF_FIXED("cnndsp",     R8A779A0_CLK_CNNDSP,    CLK_PLL5_DIV4,  1, 1),
        DEF_FIXED("vip",        R8A779A0_CLK_VIP,       CLK_PLL5,       5, 1),
        DEF_FIXED("adgh",       R8A779A0_CLK_ADGH,      CLK_PLL5_DIV4,  1, 1),
@@ -151,6 +150,7 @@ static const struct cpg_core_clk r8a779a0_core_clks[] __initconst = {
        DEF_DIV6P1("mso",       R8A779A0_CLK_MSO,       CLK_PLL5_DIV4,  0x87c),
        DEF_DIV6P1("canfd",     R8A779A0_CLK_CANFD,     CLK_PLL5_DIV4,  0x878),
        DEF_DIV6P1("csi0",      R8A779A0_CLK_CSI0,      CLK_PLL5_DIV4,  0x880),
+       DEF_DIV6P1("dsi",       R8A779A0_CLK_DSI,       CLK_PLL5_DIV4,  0x884),
 
        DEF_OSC("osc",          R8A779A0_CLK_OSC,       CLK_EXTAL,      8),
        DEF_MDSEL("r",          R8A779A0_CLK_R, 29, CLK_EXTALR, 1, CLK_OCO, 1),
@@ -167,6 +167,9 @@ static const struct mssr_mod_clk r8a779a0_mod_clks[] __initconst = {
        DEF_MOD("csi41",        400,    R8A779A0_CLK_CSI0),
        DEF_MOD("csi42",        401,    R8A779A0_CLK_CSI0),
        DEF_MOD("csi43",        402,    R8A779A0_CLK_CSI0),
+       DEF_MOD("du",           411,    R8A779A0_CLK_S3D1),
+       DEF_MOD("dsi0",         415,    R8A779A0_CLK_DSI),
+       DEF_MOD("dsi1",         416,    R8A779A0_CLK_DSI),
        DEF_MOD("fcpvd0",       508,    R8A779A0_CLK_S3D1),
        DEF_MOD("fcpvd1",       509,    R8A779A0_CLK_S3D1),
        DEF_MOD("hscif0",       514,    R8A779A0_CLK_S1D2),
index 50b5269..4c94b94 100644 (file)
 
 #include <dt-bindings/clock/r9a07g044-cpg.h>
 
-#include "renesas-rzg2l-cpg.h"
+#include "rzg2l-cpg.h"
 
 enum clk_ids {
        /* Core Clock Outputs exported to DT */
-       LAST_DT_CORE_CLK = R9A07G044_OSCCLK,
+       LAST_DT_CORE_CLK = R9A07G044_CLK_P0_DIV2,
 
        /* External Input Clocks */
        CLK_EXTAL,
@@ -30,24 +30,27 @@ enum clk_ids {
        CLK_PLL2_DIV20,
        CLK_PLL3,
        CLK_PLL3_DIV2,
+       CLK_PLL3_DIV2_4,
+       CLK_PLL3_DIV2_4_2,
        CLK_PLL3_DIV4,
-       CLK_PLL3_DIV8,
        CLK_PLL4,
        CLK_PLL5,
        CLK_PLL5_DIV2,
        CLK_PLL6,
+       CLK_P1_DIV2,
 
        /* Module Clocks */
        MOD_CLK_BASE,
 };
 
 /* Divider tables */
-static const struct clk_div_table dtable_3b[] = {
+static const struct clk_div_table dtable_1_32[] = {
        {0, 1},
        {1, 2},
        {2, 4},
        {3, 8},
        {4, 32},
+       {0, 0},
 };
 
 static const struct cpg_core_clk r9a07g044_core_clks[] __initconst = {
@@ -66,47 +69,123 @@ static const struct cpg_core_clk r9a07g044_core_clks[] __initconst = {
        DEF_FIXED(".pll2_div20", CLK_PLL2_DIV20, CLK_PLL2, 1, 20),
 
        DEF_FIXED(".pll3_div2", CLK_PLL3_DIV2, CLK_PLL3, 1, 2),
+       DEF_FIXED(".pll3_div2_4", CLK_PLL3_DIV2_4, CLK_PLL3_DIV2, 1, 4),
+       DEF_FIXED(".pll3_div2_4_2", CLK_PLL3_DIV2_4_2, CLK_PLL3_DIV2_4, 1, 2),
        DEF_FIXED(".pll3_div4", CLK_PLL3_DIV4, CLK_PLL3, 1, 4),
-       DEF_FIXED(".pll3_div8", CLK_PLL3_DIV8, CLK_PLL3, 1, 8),
 
        /* Core output clk */
        DEF_FIXED("I", R9A07G044_CLK_I, CLK_PLL1, 1, 1),
        DEF_DIV("P0", R9A07G044_CLK_P0, CLK_PLL2_DIV16, DIVPL2A,
-               dtable_3b, CLK_DIVIDER_HIWORD_MASK),
+               dtable_1_32, CLK_DIVIDER_HIWORD_MASK),
+       DEF_FIXED("P0_DIV2", R9A07G044_CLK_P0_DIV2, R9A07G044_CLK_P0, 1, 2),
        DEF_FIXED("TSU", R9A07G044_CLK_TSU, CLK_PLL2_DIV20, 1, 1),
-       DEF_DIV("P1", R9A07G044_CLK_P1, CLK_PLL3_DIV8,
-               DIVPL3B, dtable_3b, CLK_DIVIDER_HIWORD_MASK),
+       DEF_DIV("P1", R9A07G044_CLK_P1, CLK_PLL3_DIV2_4,
+               DIVPL3B, dtable_1_32, CLK_DIVIDER_HIWORD_MASK),
+       DEF_FIXED("P1_DIV2", CLK_P1_DIV2, R9A07G044_CLK_P1, 1, 2),
+       DEF_DIV("P2", R9A07G044_CLK_P2, CLK_PLL3_DIV2_4_2,
+               DIVPL3A, dtable_1_32, CLK_DIVIDER_HIWORD_MASK),
 };
 
 static struct rzg2l_mod_clk r9a07g044_mod_clks[] = {
-       DEF_MOD("gic",          R9A07G044_CLK_GIC600,
-                               R9A07G044_CLK_P1,
-                               0x514, BIT(0), (BIT(0) | BIT(1))),
-       DEF_MOD("ia55",         R9A07G044_CLK_IA55,
-                               R9A07G044_CLK_P1,
-                               0x518, (BIT(0) | BIT(1)), BIT(0)),
-       DEF_MOD("scif0",        R9A07G044_CLK_SCIF0,
-                               R9A07G044_CLK_P0,
-                               0x584, BIT(0), BIT(0)),
-       DEF_MOD("scif1",        R9A07G044_CLK_SCIF1,
-                               R9A07G044_CLK_P0,
-                               0x584, BIT(1), BIT(1)),
-       DEF_MOD("scif2",        R9A07G044_CLK_SCIF2,
-                               R9A07G044_CLK_P0,
-                               0x584, BIT(2), BIT(2)),
-       DEF_MOD("scif3",        R9A07G044_CLK_SCIF3,
-                               R9A07G044_CLK_P0,
-                               0x584, BIT(3), BIT(3)),
-       DEF_MOD("scif4",        R9A07G044_CLK_SCIF4,
-                               R9A07G044_CLK_P0,
-                               0x584, BIT(4), BIT(4)),
-       DEF_MOD("sci0",         R9A07G044_CLK_SCI0,
-                               R9A07G044_CLK_P0,
-                               0x588, BIT(0), BIT(0)),
+       DEF_MOD("gic",          R9A07G044_GIC600_GICCLK, R9A07G044_CLK_P1,
+                               0x514, 0),
+       DEF_MOD("ia55_pclk",    R9A07G044_IA55_PCLK, R9A07G044_CLK_P2,
+                               0x518, 0),
+       DEF_MOD("ia55_clk",     R9A07G044_IA55_CLK, R9A07G044_CLK_P1,
+                               0x518, 1),
+       DEF_MOD("dmac_aclk",    R9A07G044_DMAC_ACLK, R9A07G044_CLK_P1,
+                               0x52c, 0),
+       DEF_MOD("dmac_pclk",    R9A07G044_DMAC_PCLK, CLK_P1_DIV2,
+                               0x52c, 1),
+       DEF_MOD("ssi0_pclk",    R9A07G044_SSI0_PCLK2, R9A07G044_CLK_P0,
+                               0x570, 0),
+       DEF_MOD("ssi0_sfr",     R9A07G044_SSI0_PCLK_SFR, R9A07G044_CLK_P0,
+                               0x570, 1),
+       DEF_MOD("ssi1_pclk",    R9A07G044_SSI1_PCLK2, R9A07G044_CLK_P0,
+                               0x570, 2),
+       DEF_MOD("ssi1_sfr",     R9A07G044_SSI1_PCLK_SFR, R9A07G044_CLK_P0,
+                               0x570, 3),
+       DEF_MOD("ssi2_pclk",    R9A07G044_SSI2_PCLK2, R9A07G044_CLK_P0,
+                               0x570, 4),
+       DEF_MOD("ssi2_sfr",     R9A07G044_SSI2_PCLK_SFR, R9A07G044_CLK_P0,
+                               0x570, 5),
+       DEF_MOD("ssi3_pclk",    R9A07G044_SSI3_PCLK2, R9A07G044_CLK_P0,
+                               0x570, 6),
+       DEF_MOD("ssi3_sfr",     R9A07G044_SSI3_PCLK_SFR, R9A07G044_CLK_P0,
+                               0x570, 7),
+       DEF_MOD("usb0_host",    R9A07G044_USB_U2H0_HCLK, R9A07G044_CLK_P1,
+                               0x578, 0),
+       DEF_MOD("usb1_host",    R9A07G044_USB_U2H1_HCLK, R9A07G044_CLK_P1,
+                               0x578, 1),
+       DEF_MOD("usb0_func",    R9A07G044_USB_U2P_EXR_CPUCLK, R9A07G044_CLK_P1,
+                               0x578, 2),
+       DEF_MOD("usb_pclk",     R9A07G044_USB_PCLK, R9A07G044_CLK_P1,
+                               0x578, 3),
+       DEF_MOD("i2c0",         R9A07G044_I2C0_PCLK, R9A07G044_CLK_P0,
+                               0x580, 0),
+       DEF_MOD("i2c1",         R9A07G044_I2C1_PCLK, R9A07G044_CLK_P0,
+                               0x580, 1),
+       DEF_MOD("i2c2",         R9A07G044_I2C2_PCLK, R9A07G044_CLK_P0,
+                               0x580, 2),
+       DEF_MOD("i2c3",         R9A07G044_I2C3_PCLK, R9A07G044_CLK_P0,
+                               0x580, 3),
+       DEF_MOD("scif0",        R9A07G044_SCIF0_CLK_PCK, R9A07G044_CLK_P0,
+                               0x584, 0),
+       DEF_MOD("scif1",        R9A07G044_SCIF1_CLK_PCK, R9A07G044_CLK_P0,
+                               0x584, 1),
+       DEF_MOD("scif2",        R9A07G044_SCIF2_CLK_PCK, R9A07G044_CLK_P0,
+                               0x584, 2),
+       DEF_MOD("scif3",        R9A07G044_SCIF3_CLK_PCK, R9A07G044_CLK_P0,
+                               0x584, 3),
+       DEF_MOD("scif4",        R9A07G044_SCIF4_CLK_PCK, R9A07G044_CLK_P0,
+                               0x584, 4),
+       DEF_MOD("sci0",         R9A07G044_SCI0_CLKP, R9A07G044_CLK_P0,
+                               0x588, 0),
+       DEF_MOD("canfd",        R9A07G044_CANFD_PCLK, R9A07G044_CLK_P0,
+                               0x594, 0),
+       DEF_MOD("gpio",         R9A07G044_GPIO_HCLK, R9A07G044_OSCCLK,
+                               0x598, 0),
+       DEF_MOD("adc_adclk",    R9A07G044_ADC_ADCLK, R9A07G044_CLK_TSU,
+                               0x5a8, 0),
+       DEF_MOD("adc_pclk",     R9A07G044_ADC_PCLK, R9A07G044_CLK_P0,
+                               0x5a8, 1),
+};
+
+static struct rzg2l_reset r9a07g044_resets[] = {
+       DEF_RST(R9A07G044_GIC600_GICRESET_N, 0x814, 0),
+       DEF_RST(R9A07G044_GIC600_DBG_GICRESET_N, 0x814, 1),
+       DEF_RST(R9A07G044_IA55_RESETN, 0x818, 0),
+       DEF_RST(R9A07G044_DMAC_ARESETN, 0x82c, 0),
+       DEF_RST(R9A07G044_DMAC_RST_ASYNC, 0x82c, 1),
+       DEF_RST(R9A07G044_SSI0_RST_M2_REG, 0x870, 0),
+       DEF_RST(R9A07G044_SSI1_RST_M2_REG, 0x870, 1),
+       DEF_RST(R9A07G044_SSI2_RST_M2_REG, 0x870, 2),
+       DEF_RST(R9A07G044_SSI3_RST_M2_REG, 0x870, 3),
+       DEF_RST(R9A07G044_USB_U2H0_HRESETN, 0x878, 0),
+       DEF_RST(R9A07G044_USB_U2H1_HRESETN, 0x878, 1),
+       DEF_RST(R9A07G044_USB_U2P_EXL_SYSRST, 0x878, 2),
+       DEF_RST(R9A07G044_USB_PRESETN, 0x878, 3),
+       DEF_RST(R9A07G044_I2C0_MRST, 0x880, 0),
+       DEF_RST(R9A07G044_I2C1_MRST, 0x880, 1),
+       DEF_RST(R9A07G044_I2C2_MRST, 0x880, 2),
+       DEF_RST(R9A07G044_I2C3_MRST, 0x880, 3),
+       DEF_RST(R9A07G044_SCIF0_RST_SYSTEM_N, 0x884, 0),
+       DEF_RST(R9A07G044_SCIF1_RST_SYSTEM_N, 0x884, 1),
+       DEF_RST(R9A07G044_SCIF2_RST_SYSTEM_N, 0x884, 2),
+       DEF_RST(R9A07G044_SCIF3_RST_SYSTEM_N, 0x884, 3),
+       DEF_RST(R9A07G044_SCIF4_RST_SYSTEM_N, 0x884, 4),
+       DEF_RST(R9A07G044_SCI0_RST, 0x888, 0),
+       DEF_RST(R9A07G044_CANFD_RSTP_N, 0x894, 0),
+       DEF_RST(R9A07G044_CANFD_RSTC_N, 0x894, 1),
+       DEF_RST(R9A07G044_GPIO_RSTN, 0x898, 0),
+       DEF_RST(R9A07G044_GPIO_PORT_RESETN, 0x898, 1),
+       DEF_RST(R9A07G044_GPIO_SPARE_RESETN, 0x898, 2),
+       DEF_RST(R9A07G044_ADC_PRESETN, 0x8a8, 0),
+       DEF_RST(R9A07G044_ADC_ADRST_N, 0x8a8, 1),
 };
 
 static const unsigned int r9a07g044_crit_mod_clks[] __initconst = {
-       MOD_CLK_BASE + R9A07G044_CLK_GIC600,
+       MOD_CLK_BASE + R9A07G044_GIC600_GICCLK,
 };
 
 const struct rzg2l_cpg_info r9a07g044_cpg_info = {
@@ -123,5 +202,9 @@ const struct rzg2l_cpg_info r9a07g044_cpg_info = {
        /* Module Clocks */
        .mod_clks = r9a07g044_mod_clks,
        .num_mod_clks = ARRAY_SIZE(r9a07g044_mod_clks),
-       .num_hw_mod_clks = R9A07G044_CLK_MIPI_DSI_PIN + 1,
+       .num_hw_mod_clks = R9A07G044_TSU_PCLK + 1,
+
+       /* Resets */
+       .resets = r9a07g044_resets,
+       .num_resets = ARRAY_SIZE(r9a07g044_resets),
 };
diff --git a/drivers/clk/renesas/renesas-rzg2l-cpg.c b/drivers/clk/renesas/renesas-rzg2l-cpg.c
deleted file mode 100644 (file)
index 5009b9e..0000000
+++ /dev/null
@@ -1,750 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * RZ/G2L Clock Pulse Generator
- *
- * Copyright (C) 2021 Renesas Electronics Corp.
- *
- * Based on renesas-cpg-mssr.c
- *
- * Copyright (C) 2015 Glider bvba
- * Copyright (C) 2013 Ideas On Board SPRL
- * Copyright (C) 2015 Renesas Electronics Corp.
- */
-
-#include <linux/clk.h>
-#include <linux/clk-provider.h>
-#include <linux/clk/renesas.h>
-#include <linux/delay.h>
-#include <linux/device.h>
-#include <linux/init.h>
-#include <linux/mod_devicetable.h>
-#include <linux/module.h>
-#include <linux/of_address.h>
-#include <linux/of_device.h>
-#include <linux/platform_device.h>
-#include <linux/pm_clock.h>
-#include <linux/pm_domain.h>
-#include <linux/reset-controller.h>
-#include <linux/slab.h>
-
-#include <dt-bindings/clock/renesas-cpg-mssr.h>
-
-#include "renesas-rzg2l-cpg.h"
-
-#ifdef DEBUG
-#define WARN_DEBUG(x)  WARN_ON(x)
-#else
-#define WARN_DEBUG(x)  do { } while (0)
-#endif
-
-#define DIV_RSMASK(v, s, m)    ((v >> s) & m)
-#define GET_SHIFT(val)         ((val >> 12) & 0xff)
-#define GET_WIDTH(val)         ((val >> 8) & 0xf)
-
-#define KDIV(val)              DIV_RSMASK(val, 16, 0xffff)
-#define MDIV(val)              DIV_RSMASK(val, 6, 0x3ff)
-#define PDIV(val)              DIV_RSMASK(val, 0, 0x3f)
-#define SDIV(val)              DIV_RSMASK(val, 0, 0x7)
-
-#define CLK_ON_R(reg)          (reg)
-#define CLK_MON_R(reg)         (0x680 - 0x500 + (reg))
-#define CLK_RST_R(reg)         (0x800 - 0x500 + (reg))
-#define CLK_MRST_R(reg)                (0x980 - 0x500 + (reg))
-
-#define GET_REG_OFFSET(val)            ((val >> 20) & 0xfff)
-#define GET_REG_SAMPLL_CLK1(val)       ((val >> 22) & 0xfff)
-#define GET_REG_SAMPLL_CLK2(val)       ((val >> 12) & 0xfff)
-
-/**
- * struct rzg2l_cpg_priv - Clock Pulse Generator Private Data
- *
- * @rcdev: Reset controller entity
- * @dev: CPG device
- * @base: CPG register block base address
- * @rmw_lock: protects register accesses
- * @clks: Array containing all Core and Module Clocks
- * @num_core_clks: Number of Core Clocks in clks[]
- * @num_mod_clks: Number of Module Clocks in clks[]
- * @last_dt_core_clk: ID of the last Core Clock exported to DT
- * @notifiers: Notifier chain to save/restore clock state for system resume
- * @info: Pointer to platform data
- */
-struct rzg2l_cpg_priv {
-       struct reset_controller_dev rcdev;
-       struct device *dev;
-       void __iomem *base;
-       spinlock_t rmw_lock;
-
-       struct clk **clks;
-       unsigned int num_core_clks;
-       unsigned int num_mod_clks;
-       unsigned int last_dt_core_clk;
-
-       struct raw_notifier_head notifiers;
-       const struct rzg2l_cpg_info *info;
-};
-
-static void rzg2l_cpg_del_clk_provider(void *data)
-{
-       of_clk_del_provider(data);
-}
-
-static struct clk * __init
-rzg2l_cpg_div_clk_register(const struct cpg_core_clk *core,
-                          struct clk **clks,
-                          void __iomem *base,
-                          struct rzg2l_cpg_priv *priv)
-{
-       struct device *dev = priv->dev;
-       const struct clk *parent;
-       const char *parent_name;
-       struct clk_hw *clk_hw;
-
-       parent = clks[core->parent & 0xffff];
-       if (IS_ERR(parent))
-               return ERR_CAST(parent);
-
-       parent_name = __clk_get_name(parent);
-
-       if (core->dtable)
-               clk_hw = clk_hw_register_divider_table(dev, core->name,
-                                                      parent_name, 0,
-                                                      base + GET_REG_OFFSET(core->conf),
-                                                      GET_SHIFT(core->conf),
-                                                      GET_WIDTH(core->conf),
-                                                      core->flag,
-                                                      core->dtable,
-                                                      &priv->rmw_lock);
-       else
-               clk_hw = clk_hw_register_divider(dev, core->name,
-                                                parent_name, 0,
-                                                base + GET_REG_OFFSET(core->conf),
-                                                GET_SHIFT(core->conf),
-                                                GET_WIDTH(core->conf),
-                                                core->flag, &priv->rmw_lock);
-
-       if (IS_ERR(clk_hw))
-               return NULL;
-
-       return clk_hw->clk;
-}
-
-struct pll_clk {
-       struct clk_hw hw;
-       unsigned int conf;
-       unsigned int type;
-       void __iomem *base;
-       struct rzg2l_cpg_priv *priv;
-};
-
-#define to_pll(_hw)    container_of(_hw, struct pll_clk, hw)
-
-static unsigned long rzg2l_cpg_pll_clk_recalc_rate(struct clk_hw *hw,
-                                                  unsigned long parent_rate)
-{
-       struct pll_clk *pll_clk = to_pll(hw);
-       struct rzg2l_cpg_priv *priv = pll_clk->priv;
-       unsigned int val1, val2;
-       unsigned int mult = 1;
-       unsigned int div = 1;
-
-       if (pll_clk->type != CLK_TYPE_SAM_PLL)
-               return parent_rate;
-
-       val1 = readl(priv->base + GET_REG_SAMPLL_CLK1(pll_clk->conf));
-       val2 = readl(priv->base + GET_REG_SAMPLL_CLK2(pll_clk->conf));
-       mult = MDIV(val1) + KDIV(val1) / 65536;
-       div = PDIV(val1) * (1 << SDIV(val2));
-
-       return DIV_ROUND_CLOSEST_ULL((u64)parent_rate * mult, div);
-}
-
-static const struct clk_ops rzg2l_cpg_pll_ops = {
-       .recalc_rate = rzg2l_cpg_pll_clk_recalc_rate,
-};
-
-static struct clk * __init
-rzg2l_cpg_pll_clk_register(const struct cpg_core_clk *core,
-                          struct clk **clks,
-                          void __iomem *base,
-                          struct rzg2l_cpg_priv *priv)
-{
-       struct device *dev = priv->dev;
-       const struct clk *parent;
-       struct clk_init_data init;
-       const char *parent_name;
-       struct pll_clk *pll_clk;
-       struct clk *clk;
-
-       parent = clks[core->parent & 0xffff];
-       if (IS_ERR(parent))
-               return ERR_CAST(parent);
-
-       pll_clk = devm_kzalloc(dev, sizeof(*pll_clk), GFP_KERNEL);
-       if (!pll_clk) {
-               clk = ERR_PTR(-ENOMEM);
-               return NULL;
-       }
-
-       parent_name = __clk_get_name(parent);
-       init.name = core->name;
-       init.ops = &rzg2l_cpg_pll_ops;
-       init.flags = 0;
-       init.parent_names = &parent_name;
-       init.num_parents = 1;
-
-       pll_clk->hw.init = &init;
-       pll_clk->conf = core->conf;
-       pll_clk->base = base;
-       pll_clk->priv = priv;
-       pll_clk->type = core->type;
-
-       clk = clk_register(NULL, &pll_clk->hw);
-       if (IS_ERR(clk))
-               kfree(pll_clk);
-
-       return clk;
-}
-
-static struct clk
-*rzg2l_cpg_clk_src_twocell_get(struct of_phandle_args *clkspec,
-                              void *data)
-{
-       unsigned int clkidx = clkspec->args[1];
-       struct rzg2l_cpg_priv *priv = data;
-       struct device *dev = priv->dev;
-       const char *type;
-       struct clk *clk;
-
-       switch (clkspec->args[0]) {
-       case CPG_CORE:
-               type = "core";
-               if (clkidx > priv->last_dt_core_clk) {
-                       dev_err(dev, "Invalid %s clock index %u\n", type, clkidx);
-                       return ERR_PTR(-EINVAL);
-               }
-               clk = priv->clks[clkidx];
-               break;
-
-       case CPG_MOD:
-               type = "module";
-               if (clkidx > priv->num_mod_clks) {
-                       dev_err(dev, "Invalid %s clock index %u\n", type,
-                               clkidx);
-                       return ERR_PTR(-EINVAL);
-               }
-               clk = priv->clks[priv->num_core_clks + clkidx];
-               break;
-
-       default:
-               dev_err(dev, "Invalid CPG clock type %u\n", clkspec->args[0]);
-               return ERR_PTR(-EINVAL);
-       }
-
-       if (IS_ERR(clk))
-               dev_err(dev, "Cannot get %s clock %u: %ld", type, clkidx,
-                       PTR_ERR(clk));
-       else
-               dev_dbg(dev, "clock (%u, %u) is %pC at %lu Hz\n",
-                       clkspec->args[0], clkspec->args[1], clk,
-                       clk_get_rate(clk));
-       return clk;
-}
-
-static void __init
-rzg2l_cpg_register_core_clk(const struct cpg_core_clk *core,
-                           const struct rzg2l_cpg_info *info,
-                           struct rzg2l_cpg_priv *priv)
-{
-       struct clk *clk = ERR_PTR(-EOPNOTSUPP), *parent;
-       struct device *dev = priv->dev;
-       unsigned int id = core->id, div = core->div;
-       const char *parent_name;
-
-       WARN_DEBUG(id >= priv->num_core_clks);
-       WARN_DEBUG(PTR_ERR(priv->clks[id]) != -ENOENT);
-
-       if (!core->name) {
-               /* Skip NULLified clock */
-               return;
-       }
-
-       switch (core->type) {
-       case CLK_TYPE_IN:
-               clk = of_clk_get_by_name(priv->dev->of_node, core->name);
-               break;
-       case CLK_TYPE_FF:
-               WARN_DEBUG(core->parent >= priv->num_core_clks);
-               parent = priv->clks[core->parent];
-               if (IS_ERR(parent)) {
-                       clk = parent;
-                       goto fail;
-               }
-
-               parent_name = __clk_get_name(parent);
-               clk = clk_register_fixed_factor(NULL, core->name,
-                                               parent_name, CLK_SET_RATE_PARENT,
-                                               core->mult, div);
-               break;
-       case CLK_TYPE_SAM_PLL:
-               clk = rzg2l_cpg_pll_clk_register(core, priv->clks,
-                                                priv->base, priv);
-               break;
-       case CLK_TYPE_DIV:
-               clk = rzg2l_cpg_div_clk_register(core, priv->clks,
-                                                priv->base, priv);
-               break;
-       default:
-               goto fail;
-       };
-
-       if (IS_ERR_OR_NULL(clk))
-               goto fail;
-
-       dev_dbg(dev, "Core clock %pC at %lu Hz\n", clk, clk_get_rate(clk));
-       priv->clks[id] = clk;
-       return;
-
-fail:
-       dev_err(dev, "Failed to register %s clock %s: %ld\n", "core",
-               core->name, PTR_ERR(clk));
-}
-
-/**
- * struct mstp_clock - MSTP gating clock
- *
- * @hw: handle between common and hardware-specific interfaces
- * @off: register offset
- * @onoff: ON/MON bits
- * @reset: reset bits
- * @priv: CPG/MSTP private data
- */
-struct mstp_clock {
-       struct clk_hw hw;
-       u16 off;
-       u8 onoff;
-       u8 reset;
-       struct rzg2l_cpg_priv *priv;
-};
-
-#define to_mod_clock(_hw) container_of(_hw, struct mstp_clock, hw)
-
-static int rzg2l_mod_clock_endisable(struct clk_hw *hw, bool enable)
-{
-       struct mstp_clock *clock = to_mod_clock(hw);
-       struct rzg2l_cpg_priv *priv = clock->priv;
-       unsigned int reg = clock->off;
-       struct device *dev = priv->dev;
-       unsigned long flags;
-       unsigned int i;
-       u32 value;
-
-       if (!clock->off) {
-               dev_dbg(dev, "%pC does not support ON/OFF\n",  hw->clk);
-               return 0;
-       }
-
-       dev_dbg(dev, "CLK_ON %u/%pC %s\n", CLK_ON_R(reg), hw->clk,
-               enable ? "ON" : "OFF");
-       spin_lock_irqsave(&priv->rmw_lock, flags);
-
-       if (enable)
-               value = (clock->onoff << 16) | clock->onoff;
-       else
-               value = clock->onoff << 16;
-       writel(value, priv->base + CLK_ON_R(reg));
-
-       spin_unlock_irqrestore(&priv->rmw_lock, flags);
-
-       if (!enable)
-               return 0;
-
-       for (i = 1000; i > 0; --i) {
-               if (((readl(priv->base + CLK_MON_R(reg))) & clock->onoff))
-                       break;
-               cpu_relax();
-       }
-
-       if (!i) {
-               dev_err(dev, "Failed to enable CLK_ON %p\n",
-                       priv->base + CLK_ON_R(reg));
-               return -ETIMEDOUT;
-       }
-
-       return 0;
-}
-
-static int rzg2l_mod_clock_enable(struct clk_hw *hw)
-{
-       return rzg2l_mod_clock_endisable(hw, true);
-}
-
-static void rzg2l_mod_clock_disable(struct clk_hw *hw)
-{
-       rzg2l_mod_clock_endisable(hw, false);
-}
-
-static int rzg2l_mod_clock_is_enabled(struct clk_hw *hw)
-{
-       struct mstp_clock *clock = to_mod_clock(hw);
-       struct rzg2l_cpg_priv *priv = clock->priv;
-       u32 value;
-
-       if (!clock->off) {
-               dev_dbg(priv->dev, "%pC does not support ON/OFF\n",  hw->clk);
-               return 1;
-       }
-
-       value = readl(priv->base + CLK_MON_R(clock->off));
-
-       return !(value & clock->onoff);
-}
-
-static const struct clk_ops rzg2l_mod_clock_ops = {
-       .enable = rzg2l_mod_clock_enable,
-       .disable = rzg2l_mod_clock_disable,
-       .is_enabled = rzg2l_mod_clock_is_enabled,
-};
-
-static void __init
-rzg2l_cpg_register_mod_clk(const struct rzg2l_mod_clk *mod,
-                          const struct rzg2l_cpg_info *info,
-                          struct rzg2l_cpg_priv *priv)
-{
-       struct mstp_clock *clock = NULL;
-       struct device *dev = priv->dev;
-       unsigned int id = mod->id;
-       struct clk_init_data init;
-       struct clk *parent, *clk;
-       const char *parent_name;
-       unsigned int i;
-
-       WARN_DEBUG(id < priv->num_core_clks);
-       WARN_DEBUG(id >= priv->num_core_clks + priv->num_mod_clks);
-       WARN_DEBUG(mod->parent >= priv->num_core_clks + priv->num_mod_clks);
-       WARN_DEBUG(PTR_ERR(priv->clks[id]) != -ENOENT);
-
-       if (!mod->name) {
-               /* Skip NULLified clock */
-               return;
-       }
-
-       parent = priv->clks[mod->parent];
-       if (IS_ERR(parent)) {
-               clk = parent;
-               goto fail;
-       }
-
-       clock = devm_kzalloc(dev, sizeof(*clock), GFP_KERNEL);
-       if (!clock) {
-               clk = ERR_PTR(-ENOMEM);
-               goto fail;
-       }
-
-       init.name = mod->name;
-       init.ops = &rzg2l_mod_clock_ops;
-       init.flags = CLK_SET_RATE_PARENT;
-       for (i = 0; i < info->num_crit_mod_clks; i++)
-               if (id == info->crit_mod_clks[i]) {
-                       dev_dbg(dev, "CPG %s setting CLK_IS_CRITICAL\n",
-                               mod->name);
-                       init.flags |= CLK_IS_CRITICAL;
-                       break;
-               }
-
-       parent_name = __clk_get_name(parent);
-       init.parent_names = &parent_name;
-       init.num_parents = 1;
-
-       clock->off = mod->off;
-       clock->onoff = mod->onoff;
-       clock->reset = mod->reset;
-       clock->priv = priv;
-       clock->hw.init = &init;
-
-       clk = clk_register(NULL, &clock->hw);
-       if (IS_ERR(clk))
-               goto fail;
-
-       dev_dbg(dev, "Module clock %pC at %lu Hz\n", clk, clk_get_rate(clk));
-       priv->clks[id] = clk;
-       return;
-
-fail:
-       dev_err(dev, "Failed to register %s clock %s: %ld\n", "module",
-               mod->name, PTR_ERR(clk));
-       kfree(clock);
-}
-
-#define rcdev_to_priv(x)       container_of(x, struct rzg2l_cpg_priv, rcdev)
-
-static int rzg2l_cpg_reset(struct reset_controller_dev *rcdev,
-                          unsigned long id)
-{
-       struct rzg2l_cpg_priv *priv = rcdev_to_priv(rcdev);
-       const struct rzg2l_cpg_info *info = priv->info;
-       unsigned int reg = info->mod_clks[id].off;
-       u32 dis = info->mod_clks[id].reset;
-       u32 we = dis << 16;
-
-       dev_dbg(rcdev->dev, "reset name:%s id:%ld offset:0x%x\n",
-               info->mod_clks[id].name, id, CLK_RST_R(reg));
-
-       /* Reset module */
-       writel(we, priv->base + CLK_RST_R(reg));
-
-       /* Wait for at least one cycle of the RCLK clock (@ ca. 32 kHz) */
-       udelay(35);
-
-       /* Release module from reset state */
-       writel(we | dis, priv->base + CLK_RST_R(reg));
-
-       return 0;
-}
-
-static int rzg2l_cpg_assert(struct reset_controller_dev *rcdev,
-                           unsigned long id)
-{
-       struct rzg2l_cpg_priv *priv = rcdev_to_priv(rcdev);
-       const struct rzg2l_cpg_info *info = priv->info;
-       unsigned int reg = info->mod_clks[id].off;
-       u32 value = info->mod_clks[id].reset << 16;
-
-       dev_dbg(rcdev->dev, "assert name:%s id:%ld offset:0x%x\n",
-               info->mod_clks[id].name, id, CLK_RST_R(reg));
-
-       writel(value, priv->base + CLK_RST_R(reg));
-       return 0;
-}
-
-static int rzg2l_cpg_deassert(struct reset_controller_dev *rcdev,
-                             unsigned long id)
-{
-       struct rzg2l_cpg_priv *priv = rcdev_to_priv(rcdev);
-       const struct rzg2l_cpg_info *info = priv->info;
-       unsigned int reg = info->mod_clks[id].off;
-       u32 dis = info->mod_clks[id].reset;
-       u32 value = (dis << 16) | dis;
-
-       dev_dbg(rcdev->dev, "deassert name:%s id:%ld offset:0x%x\n",
-               info->mod_clks[id].name, id, CLK_RST_R(reg));
-
-       writel(value, priv->base + CLK_RST_R(reg));
-       return 0;
-}
-
-static int rzg2l_cpg_status(struct reset_controller_dev *rcdev,
-                           unsigned long id)
-{
-       struct rzg2l_cpg_priv *priv = rcdev_to_priv(rcdev);
-       const struct rzg2l_cpg_info *info = priv->info;
-       unsigned int reg = info->mod_clks[id].off;
-       u32 bitmask = info->mod_clks[id].reset;
-
-       return !(readl(priv->base + CLK_MRST_R(reg)) & bitmask);
-}
-
-static const struct reset_control_ops rzg2l_cpg_reset_ops = {
-       .reset = rzg2l_cpg_reset,
-       .assert = rzg2l_cpg_assert,
-       .deassert = rzg2l_cpg_deassert,
-       .status = rzg2l_cpg_status,
-};
-
-static int rzg2l_cpg_reset_xlate(struct reset_controller_dev *rcdev,
-                                const struct of_phandle_args *reset_spec)
-{
-       unsigned int id = reset_spec->args[0];
-
-       if (id >= rcdev->nr_resets) {
-               dev_err(rcdev->dev, "Invalid reset index %u\n", id);
-               return -EINVAL;
-       }
-
-       return id;
-}
-
-static int rzg2l_cpg_reset_controller_register(struct rzg2l_cpg_priv *priv)
-{
-       priv->rcdev.ops = &rzg2l_cpg_reset_ops;
-       priv->rcdev.of_node = priv->dev->of_node;
-       priv->rcdev.dev = priv->dev;
-       priv->rcdev.of_reset_n_cells = 1;
-       priv->rcdev.of_xlate = rzg2l_cpg_reset_xlate;
-       priv->rcdev.nr_resets = priv->num_mod_clks;
-
-       return devm_reset_controller_register(priv->dev, &priv->rcdev);
-}
-
-static bool rzg2l_cpg_is_pm_clk(const struct of_phandle_args *clkspec)
-{
-       if (clkspec->args_count != 2)
-               return false;
-
-       switch (clkspec->args[0]) {
-       case CPG_MOD:
-               return true;
-
-       default:
-               return false;
-       }
-}
-
-static int rzg2l_cpg_attach_dev(struct generic_pm_domain *unused, struct device *dev)
-{
-       struct device_node *np = dev->of_node;
-       struct of_phandle_args clkspec;
-       struct clk *clk;
-       int error;
-       int i = 0;
-
-       while (!of_parse_phandle_with_args(np, "clocks", "#clock-cells", i,
-                                          &clkspec)) {
-               if (rzg2l_cpg_is_pm_clk(&clkspec))
-                       goto found;
-
-               of_node_put(clkspec.np);
-               i++;
-       }
-
-       return 0;
-
-found:
-       clk = of_clk_get_from_provider(&clkspec);
-       of_node_put(clkspec.np);
-
-       if (IS_ERR(clk))
-               return PTR_ERR(clk);
-
-       error = pm_clk_create(dev);
-       if (error)
-               goto fail_put;
-
-       error = pm_clk_add_clk(dev, clk);
-       if (error)
-               goto fail_destroy;
-
-       return 0;
-
-fail_destroy:
-       pm_clk_destroy(dev);
-fail_put:
-       clk_put(clk);
-       return error;
-}
-
-static void rzg2l_cpg_detach_dev(struct generic_pm_domain *unused, struct device *dev)
-{
-       if (!pm_clk_no_clocks(dev))
-               pm_clk_destroy(dev);
-}
-
-static int __init rzg2l_cpg_add_clk_domain(struct device *dev)
-{
-       struct device_node *np = dev->of_node;
-       struct generic_pm_domain *genpd;
-
-       genpd = devm_kzalloc(dev, sizeof(*genpd), GFP_KERNEL);
-       if (!genpd)
-               return -ENOMEM;
-
-       genpd->name = np->name;
-       genpd->flags = GENPD_FLAG_PM_CLK | GENPD_FLAG_ALWAYS_ON |
-                      GENPD_FLAG_ACTIVE_WAKEUP;
-       genpd->attach_dev = rzg2l_cpg_attach_dev;
-       genpd->detach_dev = rzg2l_cpg_detach_dev;
-       pm_genpd_init(genpd, &pm_domain_always_on_gov, false);
-
-       of_genpd_add_provider_simple(np, genpd);
-       return 0;
-}
-
-static int __init rzg2l_cpg_probe(struct platform_device *pdev)
-{
-       struct device *dev = &pdev->dev;
-       struct device_node *np = dev->of_node;
-       const struct rzg2l_cpg_info *info;
-       struct rzg2l_cpg_priv *priv;
-       unsigned int nclks, i;
-       struct clk **clks;
-       int error;
-
-       info = of_device_get_match_data(dev);
-
-       priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
-       if (!priv)
-               return -ENOMEM;
-
-       priv->dev = dev;
-       priv->info = info;
-       spin_lock_init(&priv->rmw_lock);
-
-       priv->base = devm_platform_ioremap_resource(pdev, 0);
-       if (IS_ERR(priv->base))
-               return PTR_ERR(priv->base);
-
-       nclks = info->num_total_core_clks + info->num_hw_mod_clks;
-       clks = devm_kmalloc_array(dev, nclks, sizeof(*clks), GFP_KERNEL);
-       if (!clks)
-               return -ENOMEM;
-
-       dev_set_drvdata(dev, priv);
-       priv->clks = clks;
-       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;
-
-       for (i = 0; i < nclks; i++)
-               clks[i] = ERR_PTR(-ENOENT);
-
-       for (i = 0; i < info->num_core_clks; i++)
-               rzg2l_cpg_register_core_clk(&info->core_clks[i], info, priv);
-
-       for (i = 0; i < info->num_mod_clks; i++)
-               rzg2l_cpg_register_mod_clk(&info->mod_clks[i], info, priv);
-
-       error = of_clk_add_provider(np, rzg2l_cpg_clk_src_twocell_get, priv);
-       if (error)
-               return error;
-
-       error = devm_add_action_or_reset(dev, rzg2l_cpg_del_clk_provider, np);
-       if (error)
-               return error;
-
-       error = rzg2l_cpg_add_clk_domain(dev);
-       if (error)
-               return error;
-
-       error = rzg2l_cpg_reset_controller_register(priv);
-       if (error)
-               return error;
-
-       return 0;
-}
-
-static const struct of_device_id rzg2l_cpg_match[] = {
-#ifdef CONFIG_CLK_R9A07G044
-       {
-               .compatible = "renesas,r9a07g044-cpg",
-               .data = &r9a07g044_cpg_info,
-       },
-#endif
-       { /* sentinel */ }
-};
-
-static struct platform_driver rzg2l_cpg_driver = {
-       .driver         = {
-               .name   = "rzg2l-cpg",
-               .of_match_table = rzg2l_cpg_match,
-       },
-};
-
-static int __init rzg2l_cpg_init(void)
-{
-       return platform_driver_probe(&rzg2l_cpg_driver, rzg2l_cpg_probe);
-}
-
-subsys_initcall(rzg2l_cpg_init);
-
-MODULE_DESCRIPTION("Renesas RZ/G2L CPG Driver");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/clk/renesas/renesas-rzg2l-cpg.h b/drivers/clk/renesas/renesas-rzg2l-cpg.h
deleted file mode 100644 (file)
index 3948bdd..0000000
+++ /dev/null
@@ -1,136 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * RZ/G2L Clock Pulse Generator
- *
- * Copyright (C) 2021 Renesas Electronics Corp.
- *
- */
-
-#ifndef __RENESAS_RZG2L_CPG_H__
-#define __RENESAS_RZG2L_CPG_H__
-
-#define CPG_PL2_DDIV           (0x204)
-#define CPG_PL3A_DDIV          (0x208)
-
-/* n = 0/1/2 for PLL1/4/6 */
-#define CPG_SAMPLL_CLK1(n)     (0x04 + (16 * n))
-#define CPG_SAMPLL_CLK2(n)     (0x08 + (16 * n))
-
-#define PLL146_CONF(n) (CPG_SAMPLL_CLK1(n) << 22 | CPG_SAMPLL_CLK2(n) << 12)
-
-#define DDIV_PACK(offset, bitpos, size) \
-               (((offset) << 20) | ((bitpos) << 12) | ((size) << 8))
-#define DIVPL2A                DDIV_PACK(CPG_PL2_DDIV, 0, 3)
-#define DIVPL3B                DDIV_PACK(CPG_PL3A_DDIV, 4, 3)
-
-/**
- * Definitions of CPG Core Clocks
- *
- * These include:
- *   - Clock outputs exported to DT
- *   - External input clocks
- *   - Internal CPG clocks
- */
-struct cpg_core_clk {
-       const char *name;
-       unsigned int id;
-       unsigned int parent;
-       unsigned int div;
-       unsigned int mult;
-       unsigned int type;
-       unsigned int conf;
-       const struct clk_div_table *dtable;
-       const char * const *parent_names;
-       int flag;
-       int num_parents;
-};
-
-enum clk_types {
-       /* Generic */
-       CLK_TYPE_IN,            /* External Clock Input */
-       CLK_TYPE_FF,            /* Fixed Factor Clock */
-       CLK_TYPE_SAM_PLL,
-
-       /* Clock with divider */
-       CLK_TYPE_DIV,
-};
-
-#define DEF_TYPE(_name, _id, _type...) \
-       { .name = _name, .id = _id, .type = _type }
-#define DEF_BASE(_name, _id, _type, _parent...) \
-       DEF_TYPE(_name, _id, _type, .parent = _parent)
-#define DEF_SAMPLL(_name, _id, _parent, _conf) \
-       DEF_TYPE(_name, _id, CLK_TYPE_SAM_PLL, .parent = _parent, .conf = _conf)
-#define DEF_INPUT(_name, _id) \
-       DEF_TYPE(_name, _id, CLK_TYPE_IN)
-#define DEF_FIXED(_name, _id, _parent, _mult, _div) \
-       DEF_BASE(_name, _id, CLK_TYPE_FF, _parent, .div = _div, .mult = _mult)
-#define DEF_DIV(_name, _id, _parent, _conf, _dtable, _flag) \
-       DEF_TYPE(_name, _id, CLK_TYPE_DIV, .conf = _conf, \
-                .parent = _parent, .dtable = _dtable, .flag = _flag)
-
-/**
- * struct rzg2l_mod_clk - Module Clocks definitions
- *
- * @name: handle between common and hardware-specific interfaces
- * @id: clock index in array containing all Core and Module Clocks
- * @parent: id of parent clock
- * @off: register offset
- * @onoff: ON/MON bits
- * @reset: reset bits
- */
-struct rzg2l_mod_clk {
-       const char *name;
-       unsigned int id;
-       unsigned int parent;
-       u16 off;
-       u8 onoff;
-       u8 reset;
-};
-
-#define DEF_MOD(_name, _id, _parent, _off, _onoff, _reset)     \
-       [_id] = { \
-               .name = _name, \
-               .id = MOD_CLK_BASE + _id, \
-               .parent = (_parent), \
-               .off = (_off), \
-               .onoff = (_onoff), \
-               .reset = (_reset) \
-       }
-
-/**
- * struct rzg2l_cpg_info - SoC-specific CPG Description
- *
- * @core_clks: Array of Core Clock definitions
- * @num_core_clks: Number of entries in core_clks[]
- * @last_dt_core_clk: ID of the last Core Clock exported to DT
- * @num_total_core_clks: Total number of Core Clocks (exported + internal)
- *
- * @mod_clks: Array of Module Clock definitions
- * @num_mod_clks: Number of entries in mod_clks[]
- * @num_hw_mod_clks: Number of Module Clocks supported by the hardware
- *
- * @crit_mod_clks: Array with Module Clock IDs of critical clocks that
- *                 should not be disabled without a knowledgeable driver
- * @num_crit_mod_clks: Number of entries in crit_mod_clks[]
- */
-struct rzg2l_cpg_info {
-       /* Core Clocks */
-       const struct cpg_core_clk *core_clks;
-       unsigned int num_core_clks;
-       unsigned int last_dt_core_clk;
-       unsigned int num_total_core_clks;
-
-       /* Module Clocks */
-       const struct rzg2l_mod_clk *mod_clks;
-       unsigned int num_mod_clks;
-       unsigned int num_hw_mod_clks;
-
-       /* Critical Module Clocks that should not be disabled */
-       const unsigned int *crit_mod_clks;
-       unsigned int num_crit_mod_clks;
-};
-
-extern const struct rzg2l_cpg_info r9a07g044_cpg_info;
-
-#endif
diff --git a/drivers/clk/renesas/rzg2l-cpg.c b/drivers/clk/renesas/rzg2l-cpg.c
new file mode 100644 (file)
index 0000000..3b3b2c3
--- /dev/null
@@ -0,0 +1,750 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * RZ/G2L Clock Pulse Generator
+ *
+ * Copyright (C) 2021 Renesas Electronics Corp.
+ *
+ * Based on renesas-cpg-mssr.c
+ *
+ * Copyright (C) 2015 Glider bvba
+ * Copyright (C) 2013 Ideas On Board SPRL
+ * Copyright (C) 2015 Renesas Electronics Corp.
+ */
+
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/clk/renesas.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/init.h>
+#include <linux/mod_devicetable.h>
+#include <linux/module.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/pm_clock.h>
+#include <linux/pm_domain.h>
+#include <linux/reset-controller.h>
+#include <linux/slab.h>
+
+#include <dt-bindings/clock/renesas-cpg-mssr.h>
+
+#include "rzg2l-cpg.h"
+
+#ifdef DEBUG
+#define WARN_DEBUG(x)  WARN_ON(x)
+#else
+#define WARN_DEBUG(x)  do { } while (0)
+#endif
+
+#define DIV_RSMASK(v, s, m)    ((v >> s) & m)
+#define GET_SHIFT(val)         ((val >> 12) & 0xff)
+#define GET_WIDTH(val)         ((val >> 8) & 0xf)
+
+#define KDIV(val)              DIV_RSMASK(val, 16, 0xffff)
+#define MDIV(val)              DIV_RSMASK(val, 6, 0x3ff)
+#define PDIV(val)              DIV_RSMASK(val, 0, 0x3f)
+#define SDIV(val)              DIV_RSMASK(val, 0, 0x7)
+
+#define CLK_ON_R(reg)          (reg)
+#define CLK_MON_R(reg)         (0x180 + (reg))
+#define CLK_RST_R(reg)         (reg)
+#define CLK_MRST_R(reg)                (0x180 + (reg))
+
+#define GET_REG_OFFSET(val)            ((val >> 20) & 0xfff)
+#define GET_REG_SAMPLL_CLK1(val)       ((val >> 22) & 0xfff)
+#define GET_REG_SAMPLL_CLK2(val)       ((val >> 12) & 0xfff)
+
+/**
+ * struct rzg2l_cpg_priv - Clock Pulse Generator Private Data
+ *
+ * @rcdev: Reset controller entity
+ * @dev: CPG device
+ * @base: CPG register block base address
+ * @rmw_lock: protects register accesses
+ * @clks: Array containing all Core and Module Clocks
+ * @num_core_clks: Number of Core Clocks in clks[]
+ * @num_mod_clks: Number of Module Clocks in clks[]
+ * @last_dt_core_clk: ID of the last Core Clock exported to DT
+ * @notifiers: Notifier chain to save/restore clock state for system resume
+ * @info: Pointer to platform data
+ */
+struct rzg2l_cpg_priv {
+       struct reset_controller_dev rcdev;
+       struct device *dev;
+       void __iomem *base;
+       spinlock_t rmw_lock;
+
+       struct clk **clks;
+       unsigned int num_core_clks;
+       unsigned int num_mod_clks;
+       unsigned int num_resets;
+       unsigned int last_dt_core_clk;
+
+       struct raw_notifier_head notifiers;
+       const struct rzg2l_cpg_info *info;
+};
+
+static void rzg2l_cpg_del_clk_provider(void *data)
+{
+       of_clk_del_provider(data);
+}
+
+static struct clk * __init
+rzg2l_cpg_div_clk_register(const struct cpg_core_clk *core,
+                          struct clk **clks,
+                          void __iomem *base,
+                          struct rzg2l_cpg_priv *priv)
+{
+       struct device *dev = priv->dev;
+       const struct clk *parent;
+       const char *parent_name;
+       struct clk_hw *clk_hw;
+
+       parent = clks[core->parent & 0xffff];
+       if (IS_ERR(parent))
+               return ERR_CAST(parent);
+
+       parent_name = __clk_get_name(parent);
+
+       if (core->dtable)
+               clk_hw = clk_hw_register_divider_table(dev, core->name,
+                                                      parent_name, 0,
+                                                      base + GET_REG_OFFSET(core->conf),
+                                                      GET_SHIFT(core->conf),
+                                                      GET_WIDTH(core->conf),
+                                                      core->flag,
+                                                      core->dtable,
+                                                      &priv->rmw_lock);
+       else
+               clk_hw = clk_hw_register_divider(dev, core->name,
+                                                parent_name, 0,
+                                                base + GET_REG_OFFSET(core->conf),
+                                                GET_SHIFT(core->conf),
+                                                GET_WIDTH(core->conf),
+                                                core->flag, &priv->rmw_lock);
+
+       if (IS_ERR(clk_hw))
+               return ERR_CAST(clk_hw);
+
+       return clk_hw->clk;
+}
+
+struct pll_clk {
+       struct clk_hw hw;
+       unsigned int conf;
+       unsigned int type;
+       void __iomem *base;
+       struct rzg2l_cpg_priv *priv;
+};
+
+#define to_pll(_hw)    container_of(_hw, struct pll_clk, hw)
+
+static unsigned long rzg2l_cpg_pll_clk_recalc_rate(struct clk_hw *hw,
+                                                  unsigned long parent_rate)
+{
+       struct pll_clk *pll_clk = to_pll(hw);
+       struct rzg2l_cpg_priv *priv = pll_clk->priv;
+       unsigned int val1, val2;
+       unsigned int mult = 1;
+       unsigned int div = 1;
+
+       if (pll_clk->type != CLK_TYPE_SAM_PLL)
+               return parent_rate;
+
+       val1 = readl(priv->base + GET_REG_SAMPLL_CLK1(pll_clk->conf));
+       val2 = readl(priv->base + GET_REG_SAMPLL_CLK2(pll_clk->conf));
+       mult = MDIV(val1) + KDIV(val1) / 65536;
+       div = PDIV(val1) * (1 << SDIV(val2));
+
+       return DIV_ROUND_CLOSEST_ULL((u64)parent_rate * mult, div);
+}
+
+static const struct clk_ops rzg2l_cpg_pll_ops = {
+       .recalc_rate = rzg2l_cpg_pll_clk_recalc_rate,
+};
+
+static struct clk * __init
+rzg2l_cpg_pll_clk_register(const struct cpg_core_clk *core,
+                          struct clk **clks,
+                          void __iomem *base,
+                          struct rzg2l_cpg_priv *priv)
+{
+       struct device *dev = priv->dev;
+       const struct clk *parent;
+       struct clk_init_data init;
+       const char *parent_name;
+       struct pll_clk *pll_clk;
+
+       parent = clks[core->parent & 0xffff];
+       if (IS_ERR(parent))
+               return ERR_CAST(parent);
+
+       pll_clk = devm_kzalloc(dev, sizeof(*pll_clk), GFP_KERNEL);
+       if (!pll_clk)
+               return ERR_PTR(-ENOMEM);
+
+       parent_name = __clk_get_name(parent);
+       init.name = core->name;
+       init.ops = &rzg2l_cpg_pll_ops;
+       init.flags = 0;
+       init.parent_names = &parent_name;
+       init.num_parents = 1;
+
+       pll_clk->hw.init = &init;
+       pll_clk->conf = core->conf;
+       pll_clk->base = base;
+       pll_clk->priv = priv;
+       pll_clk->type = core->type;
+
+       return clk_register(NULL, &pll_clk->hw);
+}
+
+static struct clk
+*rzg2l_cpg_clk_src_twocell_get(struct of_phandle_args *clkspec,
+                              void *data)
+{
+       unsigned int clkidx = clkspec->args[1];
+       struct rzg2l_cpg_priv *priv = data;
+       struct device *dev = priv->dev;
+       const char *type;
+       struct clk *clk;
+
+       switch (clkspec->args[0]) {
+       case CPG_CORE:
+               type = "core";
+               if (clkidx > priv->last_dt_core_clk) {
+                       dev_err(dev, "Invalid %s clock index %u\n", type, clkidx);
+                       return ERR_PTR(-EINVAL);
+               }
+               clk = priv->clks[clkidx];
+               break;
+
+       case CPG_MOD:
+               type = "module";
+               if (clkidx >= priv->num_mod_clks) {
+                       dev_err(dev, "Invalid %s clock index %u\n", type,
+                               clkidx);
+                       return ERR_PTR(-EINVAL);
+               }
+               clk = priv->clks[priv->num_core_clks + clkidx];
+               break;
+
+       default:
+               dev_err(dev, "Invalid CPG clock type %u\n", clkspec->args[0]);
+               return ERR_PTR(-EINVAL);
+       }
+
+       if (IS_ERR(clk))
+               dev_err(dev, "Cannot get %s clock %u: %ld", type, clkidx,
+                       PTR_ERR(clk));
+       else
+               dev_dbg(dev, "clock (%u, %u) is %pC at %lu Hz\n",
+                       clkspec->args[0], clkspec->args[1], clk,
+                       clk_get_rate(clk));
+       return clk;
+}
+
+static void __init
+rzg2l_cpg_register_core_clk(const struct cpg_core_clk *core,
+                           const struct rzg2l_cpg_info *info,
+                           struct rzg2l_cpg_priv *priv)
+{
+       struct clk *clk = ERR_PTR(-EOPNOTSUPP), *parent;
+       struct device *dev = priv->dev;
+       unsigned int id = core->id, div = core->div;
+       const char *parent_name;
+
+       WARN_DEBUG(id >= priv->num_core_clks);
+       WARN_DEBUG(PTR_ERR(priv->clks[id]) != -ENOENT);
+
+       if (!core->name) {
+               /* Skip NULLified clock */
+               return;
+       }
+
+       switch (core->type) {
+       case CLK_TYPE_IN:
+               clk = of_clk_get_by_name(priv->dev->of_node, core->name);
+               break;
+       case CLK_TYPE_FF:
+               WARN_DEBUG(core->parent >= priv->num_core_clks);
+               parent = priv->clks[core->parent];
+               if (IS_ERR(parent)) {
+                       clk = parent;
+                       goto fail;
+               }
+
+               parent_name = __clk_get_name(parent);
+               clk = clk_register_fixed_factor(NULL, core->name,
+                                               parent_name, CLK_SET_RATE_PARENT,
+                                               core->mult, div);
+               break;
+       case CLK_TYPE_SAM_PLL:
+               clk = rzg2l_cpg_pll_clk_register(core, priv->clks,
+                                                priv->base, priv);
+               break;
+       case CLK_TYPE_DIV:
+               clk = rzg2l_cpg_div_clk_register(core, priv->clks,
+                                                priv->base, priv);
+               break;
+       default:
+               goto fail;
+       }
+
+       if (IS_ERR_OR_NULL(clk))
+               goto fail;
+
+       dev_dbg(dev, "Core clock %pC at %lu Hz\n", clk, clk_get_rate(clk));
+       priv->clks[id] = clk;
+       return;
+
+fail:
+       dev_err(dev, "Failed to register %s clock %s: %ld\n", "core",
+               core->name, PTR_ERR(clk));
+}
+
+/**
+ * struct mstp_clock - MSTP gating clock
+ *
+ * @hw: handle between common and hardware-specific interfaces
+ * @off: register offset
+ * @bit: ON/MON bit
+ * @priv: CPG/MSTP private data
+ */
+struct mstp_clock {
+       struct clk_hw hw;
+       u16 off;
+       u8 bit;
+       struct rzg2l_cpg_priv *priv;
+};
+
+#define to_mod_clock(_hw) container_of(_hw, struct mstp_clock, hw)
+
+static int rzg2l_mod_clock_endisable(struct clk_hw *hw, bool enable)
+{
+       struct mstp_clock *clock = to_mod_clock(hw);
+       struct rzg2l_cpg_priv *priv = clock->priv;
+       unsigned int reg = clock->off;
+       struct device *dev = priv->dev;
+       unsigned long flags;
+       unsigned int i;
+       u32 bitmask = BIT(clock->bit);
+       u32 value;
+
+       if (!clock->off) {
+               dev_dbg(dev, "%pC does not support ON/OFF\n",  hw->clk);
+               return 0;
+       }
+
+       dev_dbg(dev, "CLK_ON %u/%pC %s\n", CLK_ON_R(reg), hw->clk,
+               enable ? "ON" : "OFF");
+       spin_lock_irqsave(&priv->rmw_lock, flags);
+
+       if (enable)
+               value = (bitmask << 16) | bitmask;
+       else
+               value = bitmask << 16;
+       writel(value, priv->base + CLK_ON_R(reg));
+
+       spin_unlock_irqrestore(&priv->rmw_lock, flags);
+
+       if (!enable)
+               return 0;
+
+       for (i = 1000; i > 0; --i) {
+               if (((readl(priv->base + CLK_MON_R(reg))) & bitmask))
+                       break;
+               cpu_relax();
+       }
+
+       if (!i) {
+               dev_err(dev, "Failed to enable CLK_ON %p\n",
+                       priv->base + CLK_ON_R(reg));
+               return -ETIMEDOUT;
+       }
+
+       return 0;
+}
+
+static int rzg2l_mod_clock_enable(struct clk_hw *hw)
+{
+       return rzg2l_mod_clock_endisable(hw, true);
+}
+
+static void rzg2l_mod_clock_disable(struct clk_hw *hw)
+{
+       rzg2l_mod_clock_endisable(hw, false);
+}
+
+static int rzg2l_mod_clock_is_enabled(struct clk_hw *hw)
+{
+       struct mstp_clock *clock = to_mod_clock(hw);
+       struct rzg2l_cpg_priv *priv = clock->priv;
+       u32 bitmask = BIT(clock->bit);
+       u32 value;
+
+       if (!clock->off) {
+               dev_dbg(priv->dev, "%pC does not support ON/OFF\n",  hw->clk);
+               return 1;
+       }
+
+       value = readl(priv->base + CLK_MON_R(clock->off));
+
+       return !(value & bitmask);
+}
+
+static const struct clk_ops rzg2l_mod_clock_ops = {
+       .enable = rzg2l_mod_clock_enable,
+       .disable = rzg2l_mod_clock_disable,
+       .is_enabled = rzg2l_mod_clock_is_enabled,
+};
+
+static void __init
+rzg2l_cpg_register_mod_clk(const struct rzg2l_mod_clk *mod,
+                          const struct rzg2l_cpg_info *info,
+                          struct rzg2l_cpg_priv *priv)
+{
+       struct mstp_clock *clock = NULL;
+       struct device *dev = priv->dev;
+       unsigned int id = mod->id;
+       struct clk_init_data init;
+       struct clk *parent, *clk;
+       const char *parent_name;
+       unsigned int i;
+
+       WARN_DEBUG(id < priv->num_core_clks);
+       WARN_DEBUG(id >= priv->num_core_clks + priv->num_mod_clks);
+       WARN_DEBUG(mod->parent >= priv->num_core_clks + priv->num_mod_clks);
+       WARN_DEBUG(PTR_ERR(priv->clks[id]) != -ENOENT);
+
+       if (!mod->name) {
+               /* Skip NULLified clock */
+               return;
+       }
+
+       parent = priv->clks[mod->parent];
+       if (IS_ERR(parent)) {
+               clk = parent;
+               goto fail;
+       }
+
+       clock = devm_kzalloc(dev, sizeof(*clock), GFP_KERNEL);
+       if (!clock) {
+               clk = ERR_PTR(-ENOMEM);
+               goto fail;
+       }
+
+       init.name = mod->name;
+       init.ops = &rzg2l_mod_clock_ops;
+       init.flags = CLK_SET_RATE_PARENT;
+       for (i = 0; i < info->num_crit_mod_clks; i++)
+               if (id == info->crit_mod_clks[i]) {
+                       dev_dbg(dev, "CPG %s setting CLK_IS_CRITICAL\n",
+                               mod->name);
+                       init.flags |= CLK_IS_CRITICAL;
+                       break;
+               }
+
+       parent_name = __clk_get_name(parent);
+       init.parent_names = &parent_name;
+       init.num_parents = 1;
+
+       clock->off = mod->off;
+       clock->bit = mod->bit;
+       clock->priv = priv;
+       clock->hw.init = &init;
+
+       clk = clk_register(NULL, &clock->hw);
+       if (IS_ERR(clk))
+               goto fail;
+
+       dev_dbg(dev, "Module clock %pC at %lu Hz\n", clk, clk_get_rate(clk));
+       priv->clks[id] = clk;
+       return;
+
+fail:
+       dev_err(dev, "Failed to register %s clock %s: %ld\n", "module",
+               mod->name, PTR_ERR(clk));
+}
+
+#define rcdev_to_priv(x)       container_of(x, struct rzg2l_cpg_priv, rcdev)
+
+static int rzg2l_cpg_reset(struct reset_controller_dev *rcdev,
+                          unsigned long id)
+{
+       struct rzg2l_cpg_priv *priv = rcdev_to_priv(rcdev);
+       const struct rzg2l_cpg_info *info = priv->info;
+       unsigned int reg = info->resets[id].off;
+       u32 dis = BIT(info->resets[id].bit);
+       u32 we = dis << 16;
+
+       dev_dbg(rcdev->dev, "reset id:%ld offset:0x%x\n", id, CLK_RST_R(reg));
+
+       /* Reset module */
+       writel(we, priv->base + CLK_RST_R(reg));
+
+       /* Wait for at least one cycle of the RCLK clock (@ ca. 32 kHz) */
+       udelay(35);
+
+       /* Release module from reset state */
+       writel(we | dis, priv->base + CLK_RST_R(reg));
+
+       return 0;
+}
+
+static int rzg2l_cpg_assert(struct reset_controller_dev *rcdev,
+                           unsigned long id)
+{
+       struct rzg2l_cpg_priv *priv = rcdev_to_priv(rcdev);
+       const struct rzg2l_cpg_info *info = priv->info;
+       unsigned int reg = info->resets[id].off;
+       u32 value = BIT(info->resets[id].bit) << 16;
+
+       dev_dbg(rcdev->dev, "assert id:%ld offset:0x%x\n", id, CLK_RST_R(reg));
+
+       writel(value, priv->base + CLK_RST_R(reg));
+       return 0;
+}
+
+static int rzg2l_cpg_deassert(struct reset_controller_dev *rcdev,
+                             unsigned long id)
+{
+       struct rzg2l_cpg_priv *priv = rcdev_to_priv(rcdev);
+       const struct rzg2l_cpg_info *info = priv->info;
+       unsigned int reg = info->resets[id].off;
+       u32 dis = BIT(info->resets[id].bit);
+       u32 value = (dis << 16) | dis;
+
+       dev_dbg(rcdev->dev, "deassert id:%ld offset:0x%x\n", id,
+               CLK_RST_R(reg));
+
+       writel(value, priv->base + CLK_RST_R(reg));
+       return 0;
+}
+
+static int rzg2l_cpg_status(struct reset_controller_dev *rcdev,
+                           unsigned long id)
+{
+       struct rzg2l_cpg_priv *priv = rcdev_to_priv(rcdev);
+       const struct rzg2l_cpg_info *info = priv->info;
+       unsigned int reg = info->resets[id].off;
+       u32 bitmask = BIT(info->resets[id].bit);
+
+       return !(readl(priv->base + CLK_MRST_R(reg)) & bitmask);
+}
+
+static const struct reset_control_ops rzg2l_cpg_reset_ops = {
+       .reset = rzg2l_cpg_reset,
+       .assert = rzg2l_cpg_assert,
+       .deassert = rzg2l_cpg_deassert,
+       .status = rzg2l_cpg_status,
+};
+
+static int rzg2l_cpg_reset_xlate(struct reset_controller_dev *rcdev,
+                                const struct of_phandle_args *reset_spec)
+{
+       struct rzg2l_cpg_priv *priv = rcdev_to_priv(rcdev);
+       const struct rzg2l_cpg_info *info = priv->info;
+       unsigned int id = reset_spec->args[0];
+
+       if (id >= rcdev->nr_resets || !info->resets[id].off) {
+               dev_err(rcdev->dev, "Invalid reset index %u\n", id);
+               return -EINVAL;
+       }
+
+       return id;
+}
+
+static int rzg2l_cpg_reset_controller_register(struct rzg2l_cpg_priv *priv)
+{
+       priv->rcdev.ops = &rzg2l_cpg_reset_ops;
+       priv->rcdev.of_node = priv->dev->of_node;
+       priv->rcdev.dev = priv->dev;
+       priv->rcdev.of_reset_n_cells = 1;
+       priv->rcdev.of_xlate = rzg2l_cpg_reset_xlate;
+       priv->rcdev.nr_resets = priv->num_resets;
+
+       return devm_reset_controller_register(priv->dev, &priv->rcdev);
+}
+
+static bool rzg2l_cpg_is_pm_clk(const struct of_phandle_args *clkspec)
+{
+       if (clkspec->args_count != 2)
+               return false;
+
+       switch (clkspec->args[0]) {
+       case CPG_MOD:
+               return true;
+
+       default:
+               return false;
+       }
+}
+
+static int rzg2l_cpg_attach_dev(struct generic_pm_domain *unused, struct device *dev)
+{
+       struct device_node *np = dev->of_node;
+       struct of_phandle_args clkspec;
+       bool once = true;
+       struct clk *clk;
+       int error;
+       int i = 0;
+
+       while (!of_parse_phandle_with_args(np, "clocks", "#clock-cells", i,
+                                          &clkspec)) {
+               if (rzg2l_cpg_is_pm_clk(&clkspec)) {
+                       if (once) {
+                               once = false;
+                               error = pm_clk_create(dev);
+                               if (error) {
+                                       of_node_put(clkspec.np);
+                                       goto err;
+                               }
+                       }
+                       clk = of_clk_get_from_provider(&clkspec);
+                       of_node_put(clkspec.np);
+                       if (IS_ERR(clk)) {
+                               error = PTR_ERR(clk);
+                               goto fail_destroy;
+                       }
+
+                       error = pm_clk_add_clk(dev, clk);
+                       if (error) {
+                               dev_err(dev, "pm_clk_add_clk failed %d\n",
+                                       error);
+                               goto fail_put;
+                       }
+               } else {
+                       of_node_put(clkspec.np);
+               }
+               i++;
+       }
+
+       return 0;
+
+fail_put:
+       clk_put(clk);
+
+fail_destroy:
+       pm_clk_destroy(dev);
+err:
+       return error;
+}
+
+static void rzg2l_cpg_detach_dev(struct generic_pm_domain *unused, struct device *dev)
+{
+       if (!pm_clk_no_clocks(dev))
+               pm_clk_destroy(dev);
+}
+
+static int __init rzg2l_cpg_add_clk_domain(struct device *dev)
+{
+       struct device_node *np = dev->of_node;
+       struct generic_pm_domain *genpd;
+
+       genpd = devm_kzalloc(dev, sizeof(*genpd), GFP_KERNEL);
+       if (!genpd)
+               return -ENOMEM;
+
+       genpd->name = np->name;
+       genpd->flags = GENPD_FLAG_PM_CLK | GENPD_FLAG_ALWAYS_ON |
+                      GENPD_FLAG_ACTIVE_WAKEUP;
+       genpd->attach_dev = rzg2l_cpg_attach_dev;
+       genpd->detach_dev = rzg2l_cpg_detach_dev;
+       pm_genpd_init(genpd, &pm_domain_always_on_gov, false);
+
+       of_genpd_add_provider_simple(np, genpd);
+       return 0;
+}
+
+static int __init rzg2l_cpg_probe(struct platform_device *pdev)
+{
+       struct device *dev = &pdev->dev;
+       struct device_node *np = dev->of_node;
+       const struct rzg2l_cpg_info *info;
+       struct rzg2l_cpg_priv *priv;
+       unsigned int nclks, i;
+       struct clk **clks;
+       int error;
+
+       info = of_device_get_match_data(dev);
+
+       priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+       if (!priv)
+               return -ENOMEM;
+
+       priv->dev = dev;
+       priv->info = info;
+       spin_lock_init(&priv->rmw_lock);
+
+       priv->base = devm_platform_ioremap_resource(pdev, 0);
+       if (IS_ERR(priv->base))
+               return PTR_ERR(priv->base);
+
+       nclks = info->num_total_core_clks + info->num_hw_mod_clks;
+       clks = devm_kmalloc_array(dev, nclks, sizeof(*clks), GFP_KERNEL);
+       if (!clks)
+               return -ENOMEM;
+
+       dev_set_drvdata(dev, priv);
+       priv->clks = clks;
+       priv->num_core_clks = info->num_total_core_clks;
+       priv->num_mod_clks = info->num_hw_mod_clks;
+       priv->num_resets = info->num_resets;
+       priv->last_dt_core_clk = info->last_dt_core_clk;
+
+       for (i = 0; i < nclks; i++)
+               clks[i] = ERR_PTR(-ENOENT);
+
+       for (i = 0; i < info->num_core_clks; i++)
+               rzg2l_cpg_register_core_clk(&info->core_clks[i], info, priv);
+
+       for (i = 0; i < info->num_mod_clks; i++)
+               rzg2l_cpg_register_mod_clk(&info->mod_clks[i], info, priv);
+
+       error = of_clk_add_provider(np, rzg2l_cpg_clk_src_twocell_get, priv);
+       if (error)
+               return error;
+
+       error = devm_add_action_or_reset(dev, rzg2l_cpg_del_clk_provider, np);
+       if (error)
+               return error;
+
+       error = rzg2l_cpg_add_clk_domain(dev);
+       if (error)
+               return error;
+
+       error = rzg2l_cpg_reset_controller_register(priv);
+       if (error)
+               return error;
+
+       return 0;
+}
+
+static const struct of_device_id rzg2l_cpg_match[] = {
+#ifdef CONFIG_CLK_R9A07G044
+       {
+               .compatible = "renesas,r9a07g044-cpg",
+               .data = &r9a07g044_cpg_info,
+       },
+#endif
+       { /* sentinel */ }
+};
+
+static struct platform_driver rzg2l_cpg_driver = {
+       .driver         = {
+               .name   = "rzg2l-cpg",
+               .of_match_table = rzg2l_cpg_match,
+       },
+};
+
+static int __init rzg2l_cpg_init(void)
+{
+       return platform_driver_probe(&rzg2l_cpg_driver, rzg2l_cpg_probe);
+}
+
+subsys_initcall(rzg2l_cpg_init);
+
+MODULE_DESCRIPTION("Renesas RZ/G2L CPG Driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/clk/renesas/rzg2l-cpg.h b/drivers/clk/renesas/rzg2l-cpg.h
new file mode 100644 (file)
index 0000000..6369528
--- /dev/null
@@ -0,0 +1,155 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * RZ/G2L Clock Pulse Generator
+ *
+ * Copyright (C) 2021 Renesas Electronics Corp.
+ *
+ */
+
+#ifndef __RENESAS_RZG2L_CPG_H__
+#define __RENESAS_RZG2L_CPG_H__
+
+#define CPG_PL2_DDIV           (0x204)
+#define CPG_PL3A_DDIV          (0x208)
+
+/* n = 0/1/2 for PLL1/4/6 */
+#define CPG_SAMPLL_CLK1(n)     (0x04 + (16 * n))
+#define CPG_SAMPLL_CLK2(n)     (0x08 + (16 * n))
+
+#define PLL146_CONF(n) (CPG_SAMPLL_CLK1(n) << 22 | CPG_SAMPLL_CLK2(n) << 12)
+
+#define DDIV_PACK(offset, bitpos, size) \
+               (((offset) << 20) | ((bitpos) << 12) | ((size) << 8))
+#define DIVPL2A                DDIV_PACK(CPG_PL2_DDIV, 0, 3)
+#define DIVPL3A                DDIV_PACK(CPG_PL3A_DDIV, 0, 3)
+#define DIVPL3B                DDIV_PACK(CPG_PL3A_DDIV, 4, 3)
+
+/**
+ * Definitions of CPG Core Clocks
+ *
+ * These include:
+ *   - Clock outputs exported to DT
+ *   - External input clocks
+ *   - Internal CPG clocks
+ */
+struct cpg_core_clk {
+       const char *name;
+       unsigned int id;
+       unsigned int parent;
+       unsigned int div;
+       unsigned int mult;
+       unsigned int type;
+       unsigned int conf;
+       const struct clk_div_table *dtable;
+       const char * const *parent_names;
+       int flag;
+       int num_parents;
+};
+
+enum clk_types {
+       /* Generic */
+       CLK_TYPE_IN,            /* External Clock Input */
+       CLK_TYPE_FF,            /* Fixed Factor Clock */
+       CLK_TYPE_SAM_PLL,
+
+       /* Clock with divider */
+       CLK_TYPE_DIV,
+};
+
+#define DEF_TYPE(_name, _id, _type...) \
+       { .name = _name, .id = _id, .type = _type }
+#define DEF_BASE(_name, _id, _type, _parent...) \
+       DEF_TYPE(_name, _id, _type, .parent = _parent)
+#define DEF_SAMPLL(_name, _id, _parent, _conf) \
+       DEF_TYPE(_name, _id, CLK_TYPE_SAM_PLL, .parent = _parent, .conf = _conf)
+#define DEF_INPUT(_name, _id) \
+       DEF_TYPE(_name, _id, CLK_TYPE_IN)
+#define DEF_FIXED(_name, _id, _parent, _mult, _div) \
+       DEF_BASE(_name, _id, CLK_TYPE_FF, _parent, .div = _div, .mult = _mult)
+#define DEF_DIV(_name, _id, _parent, _conf, _dtable, _flag) \
+       DEF_TYPE(_name, _id, CLK_TYPE_DIV, .conf = _conf, \
+                .parent = _parent, .dtable = _dtable, .flag = _flag)
+
+/**
+ * struct rzg2l_mod_clk - Module Clocks definitions
+ *
+ * @name: handle between common and hardware-specific interfaces
+ * @id: clock index in array containing all Core and Module Clocks
+ * @parent: id of parent clock
+ * @off: register offset
+ * @bit: ON/MON bit
+ */
+struct rzg2l_mod_clk {
+       const char *name;
+       unsigned int id;
+       unsigned int parent;
+       u16 off;
+       u8 bit;
+};
+
+#define DEF_MOD(_name, _id, _parent, _off, _bit)       \
+       { \
+               .name = _name, \
+               .id = MOD_CLK_BASE + (_id), \
+               .parent = (_parent), \
+               .off = (_off), \
+               .bit = (_bit), \
+       }
+
+/**
+ * struct rzg2l_reset - Reset definitions
+ *
+ * @off: register offset
+ * @bit: reset bit
+ */
+struct rzg2l_reset {
+       u16 off;
+       u8 bit;
+};
+
+#define DEF_RST(_id, _off, _bit)       \
+       [_id] = { \
+               .off = (_off), \
+               .bit = (_bit) \
+       }
+
+/**
+ * struct rzg2l_cpg_info - SoC-specific CPG Description
+ *
+ * @core_clks: Array of Core Clock definitions
+ * @num_core_clks: Number of entries in core_clks[]
+ * @last_dt_core_clk: ID of the last Core Clock exported to DT
+ * @num_total_core_clks: Total number of Core Clocks (exported + internal)
+ *
+ * @mod_clks: Array of Module Clock definitions
+ * @num_mod_clks: Number of entries in mod_clks[]
+ * @num_hw_mod_clks: Number of Module Clocks supported by the hardware
+ *
+ * @crit_mod_clks: Array with Module Clock IDs of critical clocks that
+ *                 should not be disabled without a knowledgeable driver
+ * @num_crit_mod_clks: Number of entries in crit_mod_clks[]
+ */
+struct rzg2l_cpg_info {
+       /* Core Clocks */
+       const struct cpg_core_clk *core_clks;
+       unsigned int num_core_clks;
+       unsigned int last_dt_core_clk;
+       unsigned int num_total_core_clks;
+
+       /* Module Clocks */
+       const struct rzg2l_mod_clk *mod_clks;
+       unsigned int num_mod_clks;
+       unsigned int num_hw_mod_clks;
+
+       /* Resets */
+       const struct rzg2l_reset *resets;
+       unsigned int num_resets;
+
+       /* Critical Module Clocks that should not be disabled */
+       const unsigned int *crit_mod_clks;
+       unsigned int num_crit_mod_clks;
+};
+
+extern const struct rzg2l_cpg_info r9a07g044_cpg_info;
+
+#endif
index 1cb21ea..242e94c 100644 (file)
@@ -107,10 +107,10 @@ static const struct clk_parent_data gpio_db_free_mux[] = {
 };
 
 static const struct clk_parent_data psi_ref_free_mux[] = {
-       { .fw_name = "main_pll_c3",
-         .name = "main_pll_c3", },
-       { .fw_name = "peri_pll_c3",
-         .name = "peri_pll_c3", },
+       { .fw_name = "main_pll_c2",
+         .name = "main_pll_c2", },
+       { .fw_name = "peri_pll_c2",
+         .name = "peri_pll_c2", },
        { .fw_name = "osc1",
          .name = "osc1", },
        { .fw_name = "cb-intosc-hs-div2-clk",
@@ -195,6 +195,13 @@ static const struct clk_parent_data sdmmc_mux[] = {
          .name = "boot_clk", },
 };
 
+static const struct clk_parent_data s2f_user0_mux[] = {
+       { .fw_name = "s2f_user0_free_clk",
+         .name = "s2f_user0_free_clk", },
+       { .fw_name = "boot_clk",
+         .name = "boot_clk", },
+};
+
 static const struct clk_parent_data s2f_user1_mux[] = {
        { .fw_name = "s2f_user1_free_clk",
          .name = "s2f_user1_free_clk", },
@@ -273,7 +280,7 @@ static const struct stratix10_perip_cnt_clock agilex_main_perip_cnt_clks[] = {
        { AGILEX_SDMMC_FREE_CLK, "sdmmc_free_clk", NULL, sdmmc_free_mux,
          ARRAY_SIZE(sdmmc_free_mux), 0, 0xE4, 0, 0, 0},
        { AGILEX_S2F_USER0_FREE_CLK, "s2f_user0_free_clk", NULL, s2f_usr0_free_mux,
-         ARRAY_SIZE(s2f_usr0_free_mux), 0, 0xE8, 0, 0, 0},
+         ARRAY_SIZE(s2f_usr0_free_mux), 0, 0xE8, 0, 0x30, 2},
        { AGILEX_S2F_USER1_FREE_CLK, "s2f_user1_free_clk", NULL, s2f_usr1_free_mux,
          ARRAY_SIZE(s2f_usr1_free_mux), 0, 0xEC, 0, 0x88, 5},
        { AGILEX_PSI_REF_FREE_CLK, "psi_ref_free_clk", NULL, psi_ref_free_mux,
@@ -319,6 +326,8 @@ static const struct stratix10_gate_clock agilex_gate_clks[] = {
          4, 0x98, 0, 16, 0x88, 3, 0},
        { AGILEX_SDMMC_CLK, "sdmmc_clk", NULL, sdmmc_mux, ARRAY_SIZE(sdmmc_mux), 0, 0x7C,
          5, 0, 0, 0, 0x88, 4, 4},
+       { AGILEX_S2F_USER0_CLK, "s2f_user0_clk", NULL, s2f_user0_mux, ARRAY_SIZE(s2f_user0_mux), 0, 0x24,
+         6, 0, 0, 0, 0x30, 2, 0},
        { AGILEX_S2F_USER1_CLK, "s2f_user1_clk", NULL, s2f_user1_mux, ARRAY_SIZE(s2f_user1_mux), 0, 0x7C,
          6, 0, 0, 0, 0x88, 5, 0},
        { AGILEX_PSI_REF_CLK, "psi_ref_clk", NULL, psi_mux, ARRAY_SIZE(psi_mux), 0, 0x7C,
index 18564ef..1244c4e 100644 (file)
@@ -1,6 +1,6 @@
 # SPDX-License-Identifier: GPL-2.0-only
 obj-$(CONFIG_PMC_ATOM)         += clk-pmc-atom.o
 obj-$(CONFIG_X86_AMD_PLATFORM_DEVICE)  += clk-fch.o
-clk-x86-lpss-objs              := clk-lpt.o
+clk-x86-lpss-y                 := clk-lpss-atom.o
 obj-$(CONFIG_X86_INTEL_LPSS)   += clk-x86-lpss.o
 obj-$(CONFIG_CLK_LGM_CGU)      += clk-cgu.o clk-cgu-pll.o clk-lgm.o
diff --git a/drivers/clk/x86/clk-lpss-atom.c b/drivers/clk/x86/clk-lpss-atom.c
new file mode 100644 (file)
index 0000000..aa9d0bb
--- /dev/null
@@ -0,0 +1,47 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Intel Low Power Subsystem clocks.
+ *
+ * Copyright (C) 2013, Intel Corporation
+ * Authors: Mika Westerberg <mika.westerberg@linux.intel.com>
+ *         Heikki Krogerus <heikki.krogerus@linux.intel.com>
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/err.h>
+#include <linux/module.h>
+#include <linux/platform_data/x86/clk-lpss.h>
+#include <linux/platform_device.h>
+
+static int lpss_atom_clk_probe(struct platform_device *pdev)
+{
+       struct lpss_clk_data *drvdata;
+       struct clk *clk;
+
+       drvdata = devm_kzalloc(&pdev->dev, sizeof(*drvdata), GFP_KERNEL);
+       if (!drvdata)
+               return -ENOMEM;
+
+       /* LPSS free running clock */
+       drvdata->name = "lpss_clk";
+       clk = clk_register_fixed_rate(&pdev->dev, drvdata->name, NULL,
+                                     0, 100000000);
+       if (IS_ERR(clk))
+               return PTR_ERR(clk);
+
+       drvdata->clk = clk;
+       platform_set_drvdata(pdev, drvdata);
+       return 0;
+}
+
+static struct platform_driver lpss_atom_clk_driver = {
+       .driver = {
+               .name = "clk-lpss-atom",
+       },
+       .probe = lpss_atom_clk_probe,
+};
+
+int __init lpss_atom_clk_init(void)
+{
+       return platform_driver_register(&lpss_atom_clk_driver);
+}
diff --git a/drivers/clk/x86/clk-lpt.c b/drivers/clk/x86/clk-lpt.c
deleted file mode 100644 (file)
index fbe9fd3..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Intel Low Power Subsystem clocks.
- *
- * Copyright (C) 2013, Intel Corporation
- * Authors: Mika Westerberg <mika.westerberg@linux.intel.com>
- *         Heikki Krogerus <heikki.krogerus@linux.intel.com>
- */
-
-#include <linux/clk-provider.h>
-#include <linux/err.h>
-#include <linux/module.h>
-#include <linux/platform_data/x86/clk-lpss.h>
-#include <linux/platform_device.h>
-
-static int lpt_clk_probe(struct platform_device *pdev)
-{
-       struct lpss_clk_data *drvdata;
-       struct clk *clk;
-
-       drvdata = devm_kzalloc(&pdev->dev, sizeof(*drvdata), GFP_KERNEL);
-       if (!drvdata)
-               return -ENOMEM;
-
-       /* LPSS free running clock */
-       drvdata->name = "lpss_clk";
-       clk = clk_register_fixed_rate(&pdev->dev, drvdata->name, NULL,
-                                     0, 100000000);
-       if (IS_ERR(clk))
-               return PTR_ERR(clk);
-
-       drvdata->clk = clk;
-       platform_set_drvdata(pdev, drvdata);
-       return 0;
-}
-
-static struct platform_driver lpt_clk_driver = {
-       .driver = {
-               .name = "clk-lpt",
-       },
-       .probe = lpt_clk_probe,
-};
-
-int __init lpt_clk_init(void)
-{
-       return platform_driver_register(&lpt_clk_driver);
-}
index 182a4db..c538a15 100644 (file)
@@ -942,8 +942,6 @@ static int __init longhaul_init(void)
                return cpufreq_register_driver(&longhaul_driver);
        case 10:
                pr_err("Use acpi-cpufreq driver for VIA C7\n");
-       default:
-               ;
        }
 
        return -ENODEV;
index 20d9bdd..394e6e1 100644 (file)
@@ -211,8 +211,8 @@ static struct sync_file *sync_file_merge(const char *name, struct sync_file *a,
                                         struct sync_file *b)
 {
        struct sync_file *sync_file;
-       struct dma_fence **fences, **nfences, **a_fences, **b_fences;
-       int i, i_a, i_b, num_fences, a_num_fences, b_num_fences;
+       struct dma_fence **fences = NULL, **nfences, **a_fences, **b_fences;
+       int i = 0, i_a, i_b, num_fences, a_num_fences, b_num_fences;
 
        sync_file = sync_file_alloc();
        if (!sync_file)
@@ -236,7 +236,7 @@ static struct sync_file *sync_file_merge(const char *name, struct sync_file *a,
         * If a sync_file can only be created with sync_file_merge
         * and sync_file_create, this is a reasonable assumption.
         */
-       for (i = i_a = i_b = 0; i_a < a_num_fences && i_b < b_num_fences; ) {
+       for (i_a = i_b = 0; i_a < a_num_fences && i_b < b_num_fences; ) {
                struct dma_fence *pt_a = a_fences[i_a];
                struct dma_fence *pt_b = b_fences[i_b];
 
@@ -277,15 +277,16 @@ static struct sync_file *sync_file_merge(const char *name, struct sync_file *a,
                fences = nfences;
        }
 
-       if (sync_file_set_fence(sync_file, fences, i) < 0) {
-               kfree(fences);
+       if (sync_file_set_fence(sync_file, fences, i) < 0)
                goto err;
-       }
 
        strlcpy(sync_file->user_name, name, sizeof(sync_file->user_name));
        return sync_file;
 
 err:
+       while (i)
+               dma_fence_put(fences[--i]);
+       kfree(fences);
        fput(sync_file->file);
        return NULL;
 
index 104ad42..baab1ca 100644 (file)
@@ -618,6 +618,7 @@ static int ipu_enable_channel(struct idmac *idmac, struct idmac_channel *ichan)
        case IDMAC_SDC_1:
        case IDMAC_IC_7:
                ipu_channel_set_priority(ipu, channel, true);
+               break;
        default:
                break;
        }
@@ -978,6 +979,7 @@ static int ipu_init_channel(struct idmac *idmac, struct idmac_channel *ichan)
        case IDMAC_SDC_0:
        case IDMAC_SDC_1:
                n_desc = 4;
+               break;
        default:
                break;
        }
index c1a6914..4a51fdb 100644 (file)
@@ -813,6 +813,7 @@ inline bool is_buswidth_valid(u8 buswidth, bool is_mpc8308)
        case 16:
                if (is_mpc8308)
                        return false;
+               break;
        case 1:
        case 2:
        case 4:
index 96ad218..a358586 100644 (file)
@@ -4948,6 +4948,7 @@ static int setup_resources(struct udma_dev *ud)
                                                       ud->tchan_cnt),
                         ud->rchan_cnt - bitmap_weight(ud->rchan_map,
                                                       ud->rchan_cnt));
+               break;
        default:
                break;
        }
index 91164c5..2fc4c3f 100644 (file)
@@ -271,7 +271,7 @@ config EDAC_PND2
 config EDAC_IGEN6
        tristate "Intel client SoC Integrated MC"
        depends on PCI && PCI_MMCONFIG && ARCH_HAVE_NMI_SAFE_CMPXCHG
-       depends on X64_64 && X86_MCE_INTEL
+       depends on X86_64 && X86_MCE_INTEL
        help
          Support for error detection and correction on the Intel
          client SoC Integrated Memory Controller using In-Band ECC IP.
index 83166e0..00fe595 100644 (file)
@@ -46,9 +46,6 @@ static int ffa_device_probe(struct device *dev)
        struct ffa_driver *ffa_drv = to_ffa_driver(dev->driver);
        struct ffa_device *ffa_dev = to_ffa_dev(dev);
 
-       if (!ffa_device_match(dev, dev->driver))
-               return -ENODEV;
-
        return ffa_drv->probe(ffa_dev);
 }
 
@@ -99,6 +96,9 @@ int ffa_driver_register(struct ffa_driver *driver, struct module *owner,
 {
        int ret;
 
+       if (!driver->probe)
+               return -EINVAL;
+
        driver->driver.bus = &ffa_bus_type;
        driver->driver.name = driver->name;
        driver->driver.owner = owner;
index b1edb4b..c9fb56a 100644 (file)
 #define PACK_TARGET_INFO(s, r)         \
        (FIELD_PREP(SENDER_ID_MASK, (s)) | FIELD_PREP(RECEIVER_ID_MASK, (r)))
 
-/**
+/*
  * FF-A specification mentions explicitly about '4K pages'. This should
  * not be confused with the kernel PAGE_SIZE, which is the translation
  * granule kernel is configured and may be one among 4K, 16K and 64K.
@@ -149,8 +149,10 @@ static const int ffa_linux_errmap[] = {
 
 static inline int ffa_to_linux_errno(int errno)
 {
-       if (errno < FFA_RET_SUCCESS && errno >= -ARRAY_SIZE(ffa_linux_errmap))
-               return ffa_linux_errmap[-errno];
+       int err_idx = -errno;
+
+       if (err_idx >= 0 && err_idx < ARRAY_SIZE(ffa_linux_errmap))
+               return ffa_linux_errmap[err_idx];
        return -EINVAL;
 }
 
index 784cf00..6c7e249 100644 (file)
@@ -104,11 +104,6 @@ static int scmi_dev_probe(struct device *dev)
 {
        struct scmi_driver *scmi_drv = to_scmi_driver(dev->driver);
        struct scmi_device *scmi_dev = to_scmi_dev(dev);
-       const struct scmi_device_id *id;
-
-       id = scmi_dev_match_id(scmi_dev, scmi_drv);
-       if (!id)
-               return -ENODEV;
 
        if (!scmi_dev->handle)
                return -EPROBE_DEFER;
@@ -139,6 +134,9 @@ int scmi_driver_register(struct scmi_driver *driver, struct module *owner,
 {
        int retval;
 
+       if (!driver->probe)
+               return -EINVAL;
+
        retval = scmi_protocol_device_request(driver->id_table);
        if (retval)
                return retval;
index 66e5e69..9b2e8d4 100644 (file)
@@ -47,7 +47,6 @@ enum scmi_error_codes {
        SCMI_ERR_GENERIC = -8,  /* Generic Error */
        SCMI_ERR_HARDWARE = -9, /* Hardware Error */
        SCMI_ERR_PROTOCOL = -10,/* Protocol Error */
-       SCMI_ERR_MAX
 };
 
 /* List of all SCMI devices active in system */
@@ -166,8 +165,10 @@ static const int scmi_linux_errmap[] = {
 
 static inline int scmi_to_linux_errno(int errno)
 {
-       if (errno < SCMI_SUCCESS && errno > SCMI_ERR_MAX)
-               return scmi_linux_errmap[-errno];
+       int err_idx = -errno;
+
+       if (err_idx >= SCMI_SUCCESS && err_idx < ARRAY_SIZE(scmi_linux_errmap))
+               return scmi_linux_errmap[err_idx];
        return -EIO;
 }
 
@@ -1025,8 +1026,9 @@ static int __scmi_xfer_info_init(struct scmi_info *sinfo,
        const struct scmi_desc *desc = sinfo->desc;
 
        /* Pre-allocated messages, no more than what hdr.seq can support */
-       if (WARN_ON(desc->max_msg >= MSG_TOKEN_MAX)) {
-               dev_err(dev, "Maximum message of %d exceeds supported %ld\n",
+       if (WARN_ON(!desc->max_msg || desc->max_msg > MSG_TOKEN_MAX)) {
+               dev_err(dev,
+                       "Invalid maximum messages %d, not in range [1 - %lu]\n",
                        desc->max_msg, MSG_TOKEN_MAX);
                return -EINVAL;
        }
@@ -1137,6 +1139,8 @@ scmi_txrx_setup(struct scmi_info *info, struct device *dev, int prot_id)
  * @proto_id and @name: if device was still not existent it is created as a
  * child of the specified SCMI instance @info and its transport properly
  * initialized as usual.
+ *
+ * Return: A properly initialized scmi device, NULL otherwise.
  */
 static inline struct scmi_device *
 scmi_get_protocol_device(struct device_node *np, struct scmi_info *info,
index d860beb..0efd20c 100644 (file)
@@ -1457,6 +1457,8 @@ static void scmi_devm_release_notifier(struct device *dev, void *res)
  *
  * Generic devres managed helper to register a notifier_block against a
  * protocol event.
+ *
+ * Return: 0 on Success
  */
 static int scmi_devm_notifier_register(struct scmi_device *sdev,
                                       u8 proto_id, u8 evt_id,
@@ -1523,6 +1525,8 @@ static int scmi_devm_notifier_match(struct device *dev, void *res, void *data)
  * Generic devres managed helper to explicitly un-register a notifier_block
  * against a protocol event, which was previously registered using the above
  * @scmi_devm_notifier_register.
+ *
+ * Return: 0 on Success
  */
 static int scmi_devm_notifier_unregister(struct scmi_device *sdev,
                                         u8 proto_id, u8 evt_id,
index 2c88aa2..3084715 100644 (file)
@@ -166,7 +166,8 @@ struct scmi_msg_sensor_reading_get {
 
 struct scmi_resp_sensor_reading_complete {
        __le32 id;
-       __le64 readings;
+       __le32 readings_low;
+       __le32 readings_high;
 };
 
 struct scmi_sensor_reading_resp {
@@ -717,7 +718,8 @@ static int scmi_sensor_reading_get(const struct scmi_protocol_handle *ph,
 
                        resp = t->rx.buf;
                        if (le32_to_cpu(resp->id) == sensor_id)
-                               *value = get_unaligned_le64(&resp->readings);
+                               *value =
+                                       get_unaligned_le64(&resp->readings_low);
                        else
                                ret = -EPROTO;
                }
index db16b3e..cf62f43 100644 (file)
@@ -269,7 +269,7 @@ int amdgpu_amdkfd_gpuvm_free_memory_of_gpu(
                struct kgd_dev *kgd, struct kgd_mem *mem, void *drm_priv,
                uint64_t *size);
 int amdgpu_amdkfd_gpuvm_map_memory_to_gpu(
-               struct kgd_dev *kgd, struct kgd_mem *mem, void *drm_priv, bool *table_freed);
+               struct kgd_dev *kgd, struct kgd_mem *mem, void *drm_priv);
 int amdgpu_amdkfd_gpuvm_unmap_memory_from_gpu(
                struct kgd_dev *kgd, struct kgd_mem *mem, void *drm_priv);
 int amdgpu_amdkfd_gpuvm_sync_memory(
index 3b8e1ee..4fb1575 100644 (file)
@@ -1057,8 +1057,7 @@ static void unmap_bo_from_gpuvm(struct kgd_mem *mem,
 
 static int update_gpuvm_pte(struct kgd_mem *mem,
                            struct kfd_mem_attachment *entry,
-                           struct amdgpu_sync *sync,
-                           bool *table_freed)
+                           struct amdgpu_sync *sync)
 {
        struct amdgpu_bo_va *bo_va = entry->bo_va;
        struct amdgpu_device *adev = entry->adev;
@@ -1069,7 +1068,7 @@ static int update_gpuvm_pte(struct kgd_mem *mem,
                return ret;
 
        /* Update the page tables  */
-       ret = amdgpu_vm_bo_update(adev, bo_va, false, table_freed);
+       ret = amdgpu_vm_bo_update(adev, bo_va, false);
        if (ret) {
                pr_err("amdgpu_vm_bo_update failed\n");
                return ret;
@@ -1081,8 +1080,7 @@ static int update_gpuvm_pte(struct kgd_mem *mem,
 static int map_bo_to_gpuvm(struct kgd_mem *mem,
                           struct kfd_mem_attachment *entry,
                           struct amdgpu_sync *sync,
-                          bool no_update_pte,
-                          bool *table_freed)
+                          bool no_update_pte)
 {
        int ret;
 
@@ -1099,7 +1097,7 @@ static int map_bo_to_gpuvm(struct kgd_mem *mem,
        if (no_update_pte)
                return 0;
 
-       ret = update_gpuvm_pte(mem, entry, sync, table_freed);
+       ret = update_gpuvm_pte(mem, entry, sync);
        if (ret) {
                pr_err("update_gpuvm_pte() failed\n");
                goto update_gpuvm_pte_failed;
@@ -1393,8 +1391,7 @@ int amdgpu_amdkfd_gpuvm_alloc_memory_of_gpu(
                domain = alloc_domain = AMDGPU_GEM_DOMAIN_VRAM;
                alloc_flags = AMDGPU_GEM_CREATE_VRAM_WIPE_ON_RELEASE;
                alloc_flags |= (flags & KFD_IOC_ALLOC_MEM_FLAGS_PUBLIC) ?
-                       AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED :
-                       AMDGPU_GEM_CREATE_NO_CPU_ACCESS;
+                       AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED : 0;
        } else if (flags & KFD_IOC_ALLOC_MEM_FLAGS_GTT) {
                domain = alloc_domain = AMDGPU_GEM_DOMAIN_GTT;
                alloc_flags = 0;
@@ -1597,8 +1594,7 @@ int amdgpu_amdkfd_gpuvm_free_memory_of_gpu(
 }
 
 int amdgpu_amdkfd_gpuvm_map_memory_to_gpu(
-               struct kgd_dev *kgd, struct kgd_mem *mem,
-               void *drm_priv, bool *table_freed)
+               struct kgd_dev *kgd, struct kgd_mem *mem, void *drm_priv)
 {
        struct amdgpu_device *adev = get_amdgpu_device(kgd);
        struct amdgpu_vm *avm = drm_priv_to_vm(drm_priv);
@@ -1686,7 +1682,7 @@ int amdgpu_amdkfd_gpuvm_map_memory_to_gpu(
                         entry->va, entry->va + bo_size, entry);
 
                ret = map_bo_to_gpuvm(mem, entry, ctx.sync,
-                                     is_invalid_userptr, table_freed);
+                                     is_invalid_userptr);
                if (ret) {
                        pr_err("Failed to map bo to gpuvm\n");
                        goto out_unreserve;
@@ -2136,7 +2132,7 @@ static int validate_invalid_user_pages(struct amdkfd_process_info *process_info)
                                continue;
 
                        kfd_mem_dmaunmap_attachment(mem, attachment);
-                       ret = update_gpuvm_pte(mem, attachment, &sync, NULL);
+                       ret = update_gpuvm_pte(mem, attachment, &sync);
                        if (ret) {
                                pr_err("%s: update PTE failed\n", __func__);
                                /* make sure this gets validated again */
@@ -2342,7 +2338,7 @@ int amdgpu_amdkfd_gpuvm_restore_process_bos(void *info, struct dma_fence **ef)
                                continue;
 
                        kfd_mem_dmaunmap_attachment(mem, attachment);
-                       ret = update_gpuvm_pte(mem, attachment, &sync_obj, NULL);
+                       ret = update_gpuvm_pte(mem, attachment, &sync_obj);
                        if (ret) {
                                pr_debug("Memory eviction: update PTE failed. Try again\n");
                                goto validate_map_fail;
index 76fe5b7..30fa1f6 100644 (file)
@@ -781,7 +781,7 @@ static int amdgpu_cs_vm_handling(struct amdgpu_cs_parser *p)
        if (r)
                return r;
 
-       r = amdgpu_vm_bo_update(adev, fpriv->prt_va, false, NULL);
+       r = amdgpu_vm_bo_update(adev, fpriv->prt_va, false);
        if (r)
                return r;
 
@@ -792,7 +792,7 @@ static int amdgpu_cs_vm_handling(struct amdgpu_cs_parser *p)
        if (amdgpu_mcbp || amdgpu_sriov_vf(adev)) {
                bo_va = fpriv->csa_va;
                BUG_ON(!bo_va);
-               r = amdgpu_vm_bo_update(adev, bo_va, false, NULL);
+               r = amdgpu_vm_bo_update(adev, bo_va, false);
                if (r)
                        return r;
 
@@ -811,7 +811,7 @@ static int amdgpu_cs_vm_handling(struct amdgpu_cs_parser *p)
                if (bo_va == NULL)
                        continue;
 
-               r = amdgpu_vm_bo_update(adev, bo_va, false, NULL);
+               r = amdgpu_vm_bo_update(adev, bo_va, false);
                if (r)
                        return r;
 
index 71beb0d..abb9288 100644 (file)
@@ -1168,6 +1168,7 @@ static const struct pci_device_id pciidlist[] = {
        {0x1002, 0x734F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_NAVI14},
 
        /* Renoir */
+       {0x1002, 0x15E7, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RENOIR|AMD_IS_APU},
        {0x1002, 0x1636, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RENOIR|AMD_IS_APU},
        {0x1002, 0x1638, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RENOIR|AMD_IS_APU},
        {0x1002, 0x164C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RENOIR|AMD_IS_APU},
index b3404c4..d0d9bc4 100644 (file)
@@ -612,7 +612,7 @@ static void amdgpu_gem_va_update_vm(struct amdgpu_device *adev,
 
        if (operation == AMDGPU_VA_OP_MAP ||
            operation == AMDGPU_VA_OP_REPLACE) {
-               r = amdgpu_vm_bo_update(adev, bo_va, false, NULL);
+               r = amdgpu_vm_bo_update(adev, bo_va, false);
                if (r)
                        goto error;
        }
index 32ce0e6..83af307 100644 (file)
@@ -278,6 +278,21 @@ static bool amdgpu_msi_ok(struct amdgpu_device *adev)
        return true;
 }
 
+static void amdgpu_restore_msix(struct amdgpu_device *adev)
+{
+       u16 ctrl;
+
+       pci_read_config_word(adev->pdev, adev->pdev->msix_cap + PCI_MSIX_FLAGS, &ctrl);
+       if (!(ctrl & PCI_MSIX_FLAGS_ENABLE))
+               return;
+
+       /* VF FLR */
+       ctrl &= ~PCI_MSIX_FLAGS_ENABLE;
+       pci_write_config_word(adev->pdev, adev->pdev->msix_cap + PCI_MSIX_FLAGS, ctrl);
+       ctrl |= PCI_MSIX_FLAGS_ENABLE;
+       pci_write_config_word(adev->pdev, adev->pdev->msix_cap + PCI_MSIX_FLAGS, ctrl);
+}
+
 /**
  * amdgpu_irq_init - initialize interrupt handling
  *
@@ -569,6 +584,9 @@ void amdgpu_irq_gpu_reset_resume_helper(struct amdgpu_device *adev)
 {
        int i, j, k;
 
+       if (amdgpu_sriov_vf(adev))
+               amdgpu_restore_msix(adev);
+
        for (i = 0; i < AMDGPU_IRQ_CLIENTID_MAX; ++i) {
                if (!adev->irq.client[i].sources)
                        continue;
index c13b02c..fc66aca 100644 (file)
@@ -809,7 +809,7 @@ static int amdgpu_ras_enable_all_features(struct amdgpu_device *adev,
 
 /* query/inject/cure begin */
 int amdgpu_ras_query_error_status(struct amdgpu_device *adev,
-       struct ras_query_if *info)
+                                 struct ras_query_if *info)
 {
        struct ras_manager *obj = amdgpu_ras_find_obj(adev, &info->head);
        struct ras_err_data err_data = {0, 0, 0, NULL};
@@ -1043,17 +1043,32 @@ int amdgpu_ras_error_inject(struct amdgpu_device *adev,
        return ret;
 }
 
-/* get the total error counts on all IPs */
-void amdgpu_ras_query_error_count(struct amdgpu_device *adev,
-                                 unsigned long *ce_count,
-                                 unsigned long *ue_count)
+/**
+ * amdgpu_ras_query_error_count -- Get error counts of all IPs
+ * adev: pointer to AMD GPU device
+ * ce_count: pointer to an integer to be set to the count of correctible errors.
+ * ue_count: pointer to an integer to be set to the count of uncorrectible
+ * errors.
+ *
+ * If set, @ce_count or @ue_count, count and return the corresponding
+ * error counts in those integer pointers. Return 0 if the device
+ * supports RAS. Return -EOPNOTSUPP if the device doesn't support RAS.
+ */
+int amdgpu_ras_query_error_count(struct amdgpu_device *adev,
+                                unsigned long *ce_count,
+                                unsigned long *ue_count)
 {
        struct amdgpu_ras *con = amdgpu_ras_get_context(adev);
        struct ras_manager *obj;
        unsigned long ce, ue;
 
        if (!adev->ras_enabled || !con)
-               return;
+               return -EOPNOTSUPP;
+
+       /* Don't count since no reporting.
+        */
+       if (!ce_count && !ue_count)
+               return 0;
 
        ce = 0;
        ue = 0;
@@ -1061,9 +1076,11 @@ void amdgpu_ras_query_error_count(struct amdgpu_device *adev,
                struct ras_query_if info = {
                        .head = obj->head,
                };
+               int res;
 
-               if (amdgpu_ras_query_error_status(adev, &info))
-                       return;
+               res = amdgpu_ras_query_error_status(adev, &info);
+               if (res)
+                       return res;
 
                ce += info.ce_count;
                ue += info.ue_count;
@@ -1074,6 +1091,8 @@ void amdgpu_ras_query_error_count(struct amdgpu_device *adev,
 
        if (ue_count)
                *ue_count = ue;
+
+       return 0;
 }
 /* query/inject/cure end */
 
@@ -2137,9 +2156,10 @@ static void amdgpu_ras_counte_dw(struct work_struct *work)
 
        /* Cache new values.
         */
-       amdgpu_ras_query_error_count(adev, &ce_count, &ue_count);
-       atomic_set(&con->ras_ce_count, ce_count);
-       atomic_set(&con->ras_ue_count, ue_count);
+       if (amdgpu_ras_query_error_count(adev, &ce_count, &ue_count) == 0) {
+               atomic_set(&con->ras_ce_count, ce_count);
+               atomic_set(&con->ras_ue_count, ue_count);
+       }
 
        pm_runtime_mark_last_busy(dev->dev);
 Out:
@@ -2312,9 +2332,10 @@ int amdgpu_ras_late_init(struct amdgpu_device *adev,
 
        /* Those are the cached values at init.
         */
-       amdgpu_ras_query_error_count(adev, &ce_count, &ue_count);
-       atomic_set(&con->ras_ce_count, ce_count);
-       atomic_set(&con->ras_ue_count, ue_count);
+       if (amdgpu_ras_query_error_count(adev, &ce_count, &ue_count) == 0) {
+               atomic_set(&con->ras_ce_count, ce_count);
+               atomic_set(&con->ras_ue_count, ue_count);
+       }
 
        return 0;
 cleanup:
index 256cea5..b504ed8 100644 (file)
@@ -490,9 +490,9 @@ int amdgpu_ras_request_reset_on_boot(struct amdgpu_device *adev,
 void amdgpu_ras_resume(struct amdgpu_device *adev);
 void amdgpu_ras_suspend(struct amdgpu_device *adev);
 
-void amdgpu_ras_query_error_count(struct amdgpu_device *adev,
-                                 unsigned long *ce_count,
-                                 unsigned long *ue_count);
+int amdgpu_ras_query_error_count(struct amdgpu_device *adev,
+                                unsigned long *ce_count,
+                                unsigned long *ue_count);
 
 /* error handling functions */
 int amdgpu_ras_add_bad_pages(struct amdgpu_device *adev,
index 79cfa2d..078c068 100644 (file)
@@ -1758,7 +1758,7 @@ int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev,
        r = vm->update_funcs->commit(&params, fence);
 
        if (table_freed)
-               *table_freed = *table_freed || params.table_freed;
+               *table_freed = params.table_freed;
 
 error_unlock:
        amdgpu_vm_eviction_unlock(vm);
@@ -1816,7 +1816,6 @@ void amdgpu_vm_get_memory(struct amdgpu_vm *vm, uint64_t *vram_mem,
  * @adev: amdgpu_device pointer
  * @bo_va: requested BO and VM object
  * @clear: if true clear the entries
- * @table_freed: return true if page table is freed
  *
  * Fill in the page table entries for @bo_va.
  *
@@ -1824,7 +1823,7 @@ void amdgpu_vm_get_memory(struct amdgpu_vm *vm, uint64_t *vram_mem,
  * 0 for success, -EINVAL for failure.
  */
 int amdgpu_vm_bo_update(struct amdgpu_device *adev, struct amdgpu_bo_va *bo_va,
-                       bool clear, bool *table_freed)
+                       bool clear)
 {
        struct amdgpu_bo *bo = bo_va->base.bo;
        struct amdgpu_vm *vm = bo_va->base.vm;
@@ -1903,7 +1902,7 @@ int amdgpu_vm_bo_update(struct amdgpu_device *adev, struct amdgpu_bo_va *bo_va,
                                                resv, mapping->start,
                                                mapping->last, update_flags,
                                                mapping->offset, mem,
-                                               pages_addr, last_update, table_freed);
+                                               pages_addr, last_update, NULL);
                if (r)
                        return r;
        }
@@ -2155,7 +2154,7 @@ int amdgpu_vm_handle_moved(struct amdgpu_device *adev,
 
        list_for_each_entry_safe(bo_va, tmp, &vm->moved, base.vm_status) {
                /* Per VM BOs never need to bo cleared in the page tables */
-               r = amdgpu_vm_bo_update(adev, bo_va, false, NULL);
+               r = amdgpu_vm_bo_update(adev, bo_va, false);
                if (r)
                        return r;
        }
@@ -2174,7 +2173,7 @@ int amdgpu_vm_handle_moved(struct amdgpu_device *adev,
                else
                        clear = true;
 
-               r = amdgpu_vm_bo_update(adev, bo_va, clear, NULL);
+               r = amdgpu_vm_bo_update(adev, bo_va, clear);
                if (r)
                        return r;
 
index ddb85a8..f8fa653 100644 (file)
@@ -406,7 +406,7 @@ int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev,
                                struct dma_fence **fence, bool *free_table);
 int amdgpu_vm_bo_update(struct amdgpu_device *adev,
                        struct amdgpu_bo_va *bo_va,
-                       bool clear, bool *table_freed);
+                       bool clear);
 bool amdgpu_vm_evictable(struct amdgpu_bo *bo);
 void amdgpu_vm_bo_invalidate(struct amdgpu_device *adev,
                             struct amdgpu_bo *bo, bool evicted);
index 3332442..7e0d8c0 100644 (file)
@@ -766,7 +766,7 @@ static const struct amdgpu_irq_src_funcs dce_virtual_crtc_irq_funcs = {
 
 static void dce_virtual_set_irq_funcs(struct amdgpu_device *adev)
 {
-       adev->crtc_irq.num_types = AMDGPU_CRTC_IRQ_VBLANK6 + 1;
+       adev->crtc_irq.num_types = adev->mode_info.num_crtc;
        adev->crtc_irq.funcs = &dce_virtual_crtc_irq_funcs;
 }
 
index 3ee4815..ff2307d 100644 (file)
@@ -252,7 +252,7 @@ static void xgpu_ai_mailbox_flr_work(struct work_struct *work)
         * otherwise the mailbox msg will be ruined/reseted by
         * the VF FLR.
         */
-       if (!down_read_trylock(&adev->reset_sem))
+       if (!down_write_trylock(&adev->reset_sem))
                return;
 
        amdgpu_virt_fini_data_exchange(adev);
@@ -268,7 +268,7 @@ static void xgpu_ai_mailbox_flr_work(struct work_struct *work)
 
 flr_done:
        atomic_set(&adev->in_gpu_reset, 0);
-       up_read(&adev->reset_sem);
+       up_write(&adev->reset_sem);
 
        /* Trigger recovery for world switch failure if no TDR */
        if (amdgpu_device_should_recover_gpu(adev)
index 48e588d..9f7aac4 100644 (file)
@@ -273,7 +273,7 @@ static void xgpu_nv_mailbox_flr_work(struct work_struct *work)
         * otherwise the mailbox msg will be ruined/reseted by
         * the VF FLR.
         */
-       if (!down_read_trylock(&adev->reset_sem))
+       if (!down_write_trylock(&adev->reset_sem))
                return;
 
        amdgpu_virt_fini_data_exchange(adev);
@@ -289,7 +289,7 @@ static void xgpu_nv_mailbox_flr_work(struct work_struct *work)
 
 flr_done:
        atomic_set(&adev->in_gpu_reset, 0);
-       up_read(&adev->reset_sem);
+       up_write(&adev->reset_sem);
 
        /* Trigger recovery for world switch failure if no TDR */
        if (amdgpu_device_should_recover_gpu(adev)
index 67541c3..e48acdd 100644 (file)
@@ -1393,7 +1393,6 @@ static int kfd_ioctl_map_memory_to_gpu(struct file *filep,
        long err = 0;
        int i;
        uint32_t *devices_arr = NULL;
-       bool table_freed = false;
 
        dev = kfd_device_by_id(GET_GPU_ID(args->handle));
        if (!dev)
@@ -1451,8 +1450,7 @@ static int kfd_ioctl_map_memory_to_gpu(struct file *filep,
                        goto get_mem_obj_from_handle_failed;
                }
                err = amdgpu_amdkfd_gpuvm_map_memory_to_gpu(
-                       peer->kgd, (struct kgd_mem *)mem,
-                       peer_pdd->drm_priv, &table_freed);
+                       peer->kgd, (struct kgd_mem *)mem, peer_pdd->drm_priv);
                if (err) {
                        pr_err("Failed to map to gpu %d/%d\n",
                               i, args->n_devices);
@@ -1470,17 +1468,16 @@ static int kfd_ioctl_map_memory_to_gpu(struct file *filep,
        }
 
        /* Flush TLBs after waiting for the page table updates to complete */
-       if (table_freed) {
-               for (i = 0; i < args->n_devices; i++) {
-                       peer = kfd_device_by_id(devices_arr[i]);
-                       if (WARN_ON_ONCE(!peer))
-                               continue;
-                       peer_pdd = kfd_get_process_device_data(peer, p);
-                       if (WARN_ON_ONCE(!peer_pdd))
-                               continue;
-                       kfd_flush_tlb(peer_pdd, TLB_FLUSH_LEGACY);
-               }
+       for (i = 0; i < args->n_devices; i++) {
+               peer = kfd_device_by_id(devices_arr[i]);
+               if (WARN_ON_ONCE(!peer))
+                       continue;
+               peer_pdd = kfd_get_process_device_data(peer, p);
+               if (WARN_ON_ONCE(!peer_pdd))
+                       continue;
+               kfd_flush_tlb(peer_pdd, TLB_FLUSH_LEGACY);
        }
+
        kfree(devices_arr);
 
        return err;
@@ -1568,27 +1565,10 @@ static int kfd_ioctl_unmap_memory_from_gpu(struct file *filep,
                }
                args->n_success = i+1;
        }
-       mutex_unlock(&p->mutex);
-
-       err = amdgpu_amdkfd_gpuvm_sync_memory(dev->kgd, (struct kgd_mem *) mem, true);
-       if (err) {
-               pr_debug("Sync memory failed, wait interrupted by user signal\n");
-               goto sync_memory_failed;
-       }
-
-       /* Flush TLBs after waiting for the page table updates to complete */
-       for (i = 0; i < args->n_devices; i++) {
-               peer = kfd_device_by_id(devices_arr[i]);
-               if (WARN_ON_ONCE(!peer))
-                       continue;
-               peer_pdd = kfd_get_process_device_data(peer, p);
-               if (WARN_ON_ONCE(!peer_pdd))
-                       continue;
-               kfd_flush_tlb(peer_pdd, TLB_FLUSH_HEAVYWEIGHT);
-       }
-
        kfree(devices_arr);
 
+       mutex_unlock(&p->mutex);
+
        return 0;
 
 bind_process_to_device_failed:
@@ -1596,7 +1576,6 @@ get_mem_obj_from_handle_failed:
 unmap_memory_from_gpu_failed:
        mutex_unlock(&p->mutex);
 copy_from_user_failed:
-sync_memory_failed:
        kfree(devices_arr);
        return err;
 }
index 21ec8a1..8a2c6fc 100644 (file)
@@ -714,8 +714,7 @@ static int kfd_process_alloc_gpuvm(struct kfd_process_device *pdd,
        if (err)
                goto err_alloc_mem;
 
-       err = amdgpu_amdkfd_gpuvm_map_memory_to_gpu(kdev->kgd, mem,
-                       pdd->drm_priv, NULL);
+       err = amdgpu_amdkfd_gpuvm_map_memory_to_gpu(kdev->kgd, mem, pdd->drm_priv);
        if (err)
                goto err_map_mem;
 
index 9a71d89..c7b364e 100644 (file)
@@ -2375,21 +2375,27 @@ static bool svm_range_skip_recover(struct svm_range *prange)
 
 static void
 svm_range_count_fault(struct amdgpu_device *adev, struct kfd_process *p,
-                     struct svm_range *prange, int32_t gpuidx)
+                     int32_t gpuidx)
 {
        struct kfd_process_device *pdd;
 
-       if (gpuidx == MAX_GPU_INSTANCE)
-               /* fault is on different page of same range
-                * or fault is skipped to recover later
-                */
-               pdd = svm_range_get_pdd_by_adev(prange, adev);
-       else
-               /* fault recovered
-                * or fault cannot recover because GPU no access on the range
-                */
-               pdd = kfd_process_device_from_gpuidx(p, gpuidx);
+       /* fault is on different page of same range
+        * or fault is skipped to recover later
+        * or fault is on invalid virtual address
+        */
+       if (gpuidx == MAX_GPU_INSTANCE) {
+               uint32_t gpuid;
+               int r;
 
+               r = kfd_process_gpuid_from_kgd(p, adev, &gpuid, &gpuidx);
+               if (r < 0)
+                       return;
+       }
+
+       /* fault is recovered
+        * or fault cannot recover because GPU no access on the range
+        */
+       pdd = kfd_process_device_from_gpuidx(p, gpuidx);
        if (pdd)
                WRITE_ONCE(pdd->faults, pdd->faults + 1);
 }
@@ -2525,7 +2531,7 @@ out_unlock_svms:
        mutex_unlock(&svms->lock);
        mmap_read_unlock(mm);
 
-       svm_range_count_fault(adev, p, prange, gpuidx);
+       svm_range_count_fault(adev, p, gpuidx);
 
        mmput(mm);
 out:
index 01e1062..d3a2a5f 100644 (file)
@@ -9191,7 +9191,7 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state)
 #if defined(CONFIG_BACKLIGHT_CLASS_DEVICE) ||          \
        defined(CONFIG_BACKLIGHT_CLASS_DEVICE_MODULE)
        /* restore the backlight level */
-       if (dm->backlight_dev)
+       if (dm->backlight_dev && (amdgpu_dm_backlight_get_level(dm) != dm->brightness[0]))
                amdgpu_dm_backlight_set_level(dm, dm->brightness[0]);
 #endif
        /*
index 66db5e9..dad4a4c 100644 (file)
@@ -31,8 +31,8 @@
 #include "dcn31_smu.h"
 
 #include "yellow_carp_offset.h"
-#include "mp/mp_13_0_1_offset.h"
-#include "mp/mp_13_0_1_sh_mask.h"
+#include "mp/mp_13_0_2_offset.h"
+#include "mp/mp_13_0_2_sh_mask.h"
 
 #define REG(reg_name) \
        (MP0_BASE.instance[0].segment[reg ## reg_name ## _BASE_IDX] + reg ## reg_name)
index b8832bd..6da226b 100644 (file)
@@ -1620,11 +1620,12 @@ enum dc_status dpcd_configure_lttpr_mode(struct dc_link *link, struct link_train
 {
        enum dc_status status = DC_OK;
 
-       if (lt_settings->lttpr_mode == LTTPR_MODE_NON_TRANSPARENT)
-               status = configure_lttpr_mode_non_transparent(link, lt_settings);
-       else
+       if (lt_settings->lttpr_mode == LTTPR_MODE_TRANSPARENT)
                status = configure_lttpr_mode_transparent(link);
 
+       else if (lt_settings->lttpr_mode == LTTPR_MODE_NON_TRANSPARENT)
+               status = configure_lttpr_mode_non_transparent(link, lt_settings);
+
        return status;
 }
 
@@ -1784,7 +1785,6 @@ bool perform_link_training_with_retries(
                link_enc = stream->link_enc;
        else
                link_enc = link->link_enc;
-       ASSERT(link_enc);
 
        /* We need to do this before the link training to ensure the idle pattern in SST
         * mode will be sent right after the link training
index fc1fc1a..836864a 100644 (file)
@@ -390,7 +390,7 @@ void dcn31_update_info_frame(struct pipe_ctx *pipe_ctx)
        is_hdmi_tmds = dc_is_hdmi_tmds_signal(pipe_ctx->stream->signal);
        is_dp = dc_is_dp_signal(pipe_ctx->stream->signal);
 
-       if (!is_hdmi_tmds)
+       if (!is_hdmi_tmds && !is_dp)
                return;
 
        if (is_hdmi_tmds)
diff --git a/drivers/gpu/drm/amd/include/asic_reg/mp/mp_13_0_1_offset.h b/drivers/gpu/drm/amd/include/asic_reg/mp/mp_13_0_1_offset.h
deleted file mode 100644 (file)
index dfacc6b..0000000
+++ /dev/null
@@ -1,355 +0,0 @@
-/*
- * Copyright 2020 Advanced Micro Devices, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- *
- */
-#ifndef _mp_13_0_1_OFFSET_HEADER
-#define _mp_13_0_1_OFFSET_HEADER
-
-
-
-// addressBlock: mp_SmuMp0_SmnDec
-// base address: 0x0
-#define regMP0_SMN_C2PMSG_32                                                                            0x0060
-#define regMP0_SMN_C2PMSG_32_BASE_IDX                                                                   0
-#define regMP0_SMN_C2PMSG_33                                                                            0x0061
-#define regMP0_SMN_C2PMSG_33_BASE_IDX                                                                   0
-#define regMP0_SMN_C2PMSG_34                                                                            0x0062
-#define regMP0_SMN_C2PMSG_34_BASE_IDX                                                                   0
-#define regMP0_SMN_C2PMSG_35                                                                            0x0063
-#define regMP0_SMN_C2PMSG_35_BASE_IDX                                                                   0
-#define regMP0_SMN_C2PMSG_36                                                                            0x0064
-#define regMP0_SMN_C2PMSG_36_BASE_IDX                                                                   0
-#define regMP0_SMN_C2PMSG_37                                                                            0x0065
-#define regMP0_SMN_C2PMSG_37_BASE_IDX                                                                   0
-#define regMP0_SMN_C2PMSG_38                                                                            0x0066
-#define regMP0_SMN_C2PMSG_38_BASE_IDX                                                                   0
-#define regMP0_SMN_C2PMSG_39                                                                            0x0067
-#define regMP0_SMN_C2PMSG_39_BASE_IDX                                                                   0
-#define regMP0_SMN_C2PMSG_40                                                                            0x0068
-#define regMP0_SMN_C2PMSG_40_BASE_IDX                                                                   0
-#define regMP0_SMN_C2PMSG_41                                                                            0x0069
-#define regMP0_SMN_C2PMSG_41_BASE_IDX                                                                   0
-#define regMP0_SMN_C2PMSG_42                                                                            0x006a
-#define regMP0_SMN_C2PMSG_42_BASE_IDX                                                                   0
-#define regMP0_SMN_C2PMSG_43                                                                            0x006b
-#define regMP0_SMN_C2PMSG_43_BASE_IDX                                                                   0
-#define regMP0_SMN_C2PMSG_44                                                                            0x006c
-#define regMP0_SMN_C2PMSG_44_BASE_IDX                                                                   0
-#define regMP0_SMN_C2PMSG_45                                                                            0x006d
-#define regMP0_SMN_C2PMSG_45_BASE_IDX                                                                   0
-#define regMP0_SMN_C2PMSG_46                                                                            0x006e
-#define regMP0_SMN_C2PMSG_46_BASE_IDX                                                                   0
-#define regMP0_SMN_C2PMSG_47                                                                            0x006f
-#define regMP0_SMN_C2PMSG_47_BASE_IDX                                                                   0
-#define regMP0_SMN_C2PMSG_48                                                                            0x0070
-#define regMP0_SMN_C2PMSG_48_BASE_IDX                                                                   0
-#define regMP0_SMN_C2PMSG_49                                                                            0x0071
-#define regMP0_SMN_C2PMSG_49_BASE_IDX                                                                   0
-#define regMP0_SMN_C2PMSG_50                                                                            0x0072
-#define regMP0_SMN_C2PMSG_50_BASE_IDX                                                                   0
-#define regMP0_SMN_C2PMSG_51                                                                            0x0073
-#define regMP0_SMN_C2PMSG_51_BASE_IDX                                                                   0
-#define regMP0_SMN_C2PMSG_52                                                                            0x0074
-#define regMP0_SMN_C2PMSG_52_BASE_IDX                                                                   0
-#define regMP0_SMN_C2PMSG_53                                                                            0x0075
-#define regMP0_SMN_C2PMSG_53_BASE_IDX                                                                   0
-#define regMP0_SMN_C2PMSG_54                                                                            0x0076
-#define regMP0_SMN_C2PMSG_54_BASE_IDX                                                                   0
-#define regMP0_SMN_C2PMSG_55                                                                            0x0077
-#define regMP0_SMN_C2PMSG_55_BASE_IDX                                                                   0
-#define regMP0_SMN_C2PMSG_56                                                                            0x0078
-#define regMP0_SMN_C2PMSG_56_BASE_IDX                                                                   0
-#define regMP0_SMN_C2PMSG_57                                                                            0x0079
-#define regMP0_SMN_C2PMSG_57_BASE_IDX                                                                   0
-#define regMP0_SMN_C2PMSG_58                                                                            0x007a
-#define regMP0_SMN_C2PMSG_58_BASE_IDX                                                                   0
-#define regMP0_SMN_C2PMSG_59                                                                            0x007b
-#define regMP0_SMN_C2PMSG_59_BASE_IDX                                                                   0
-#define regMP0_SMN_C2PMSG_60                                                                            0x007c
-#define regMP0_SMN_C2PMSG_60_BASE_IDX                                                                   0
-#define regMP0_SMN_C2PMSG_61                                                                            0x007d
-#define regMP0_SMN_C2PMSG_61_BASE_IDX                                                                   0
-#define regMP0_SMN_C2PMSG_62                                                                            0x007e
-#define regMP0_SMN_C2PMSG_62_BASE_IDX                                                                   0
-#define regMP0_SMN_C2PMSG_63                                                                            0x007f
-#define regMP0_SMN_C2PMSG_63_BASE_IDX                                                                   0
-#define regMP0_SMN_C2PMSG_64                                                                            0x0080
-#define regMP0_SMN_C2PMSG_64_BASE_IDX                                                                   0
-#define regMP0_SMN_C2PMSG_65                                                                            0x0081
-#define regMP0_SMN_C2PMSG_65_BASE_IDX                                                                   0
-#define regMP0_SMN_C2PMSG_66                                                                            0x0082
-#define regMP0_SMN_C2PMSG_66_BASE_IDX                                                                   0
-#define regMP0_SMN_C2PMSG_67                                                                            0x0083
-#define regMP0_SMN_C2PMSG_67_BASE_IDX                                                                   0
-#define regMP0_SMN_C2PMSG_68                                                                            0x0084
-#define regMP0_SMN_C2PMSG_68_BASE_IDX                                                                   0
-#define regMP0_SMN_C2PMSG_69                                                                            0x0085
-#define regMP0_SMN_C2PMSG_69_BASE_IDX                                                                   0
-#define regMP0_SMN_C2PMSG_70                                                                            0x0086
-#define regMP0_SMN_C2PMSG_70_BASE_IDX                                                                   0
-#define regMP0_SMN_C2PMSG_71                                                                            0x0087
-#define regMP0_SMN_C2PMSG_71_BASE_IDX                                                                   0
-#define regMP0_SMN_C2PMSG_72                                                                            0x0088
-#define regMP0_SMN_C2PMSG_72_BASE_IDX                                                                   0
-#define regMP0_SMN_C2PMSG_73                                                                            0x0089
-#define regMP0_SMN_C2PMSG_73_BASE_IDX                                                                   0
-#define regMP0_SMN_C2PMSG_74                                                                            0x008a
-#define regMP0_SMN_C2PMSG_74_BASE_IDX                                                                   0
-#define regMP0_SMN_C2PMSG_75                                                                            0x008b
-#define regMP0_SMN_C2PMSG_75_BASE_IDX                                                                   0
-#define regMP0_SMN_C2PMSG_76                                                                            0x008c
-#define regMP0_SMN_C2PMSG_76_BASE_IDX                                                                   0
-#define regMP0_SMN_C2PMSG_77                                                                            0x008d
-#define regMP0_SMN_C2PMSG_77_BASE_IDX                                                                   0
-#define regMP0_SMN_C2PMSG_78                                                                            0x008e
-#define regMP0_SMN_C2PMSG_78_BASE_IDX                                                                   0
-#define regMP0_SMN_C2PMSG_79                                                                            0x008f
-#define regMP0_SMN_C2PMSG_79_BASE_IDX                                                                   0
-#define regMP0_SMN_C2PMSG_80                                                                            0x0090
-#define regMP0_SMN_C2PMSG_80_BASE_IDX                                                                   0
-#define regMP0_SMN_C2PMSG_81                                                                            0x0091
-#define regMP0_SMN_C2PMSG_81_BASE_IDX                                                                   0
-#define regMP0_SMN_C2PMSG_82                                                                            0x0092
-#define regMP0_SMN_C2PMSG_82_BASE_IDX                                                                   0
-#define regMP0_SMN_C2PMSG_83                                                                            0x0093
-#define regMP0_SMN_C2PMSG_83_BASE_IDX                                                                   0
-#define regMP0_SMN_C2PMSG_84                                                                            0x0094
-#define regMP0_SMN_C2PMSG_84_BASE_IDX                                                                   0
-#define regMP0_SMN_C2PMSG_85                                                                            0x0095
-#define regMP0_SMN_C2PMSG_85_BASE_IDX                                                                   0
-#define regMP0_SMN_C2PMSG_86                                                                            0x0096
-#define regMP0_SMN_C2PMSG_86_BASE_IDX                                                                   0
-#define regMP0_SMN_C2PMSG_87                                                                            0x0097
-#define regMP0_SMN_C2PMSG_87_BASE_IDX                                                                   0
-#define regMP0_SMN_C2PMSG_88                                                                            0x0098
-#define regMP0_SMN_C2PMSG_88_BASE_IDX                                                                   0
-#define regMP0_SMN_C2PMSG_89                                                                            0x0099
-#define regMP0_SMN_C2PMSG_89_BASE_IDX                                                                   0
-#define regMP0_SMN_C2PMSG_90                                                                            0x009a
-#define regMP0_SMN_C2PMSG_90_BASE_IDX                                                                   0
-#define regMP0_SMN_C2PMSG_91                                                                            0x009b
-#define regMP0_SMN_C2PMSG_91_BASE_IDX                                                                   0
-#define regMP0_SMN_C2PMSG_92                                                                            0x009c
-#define regMP0_SMN_C2PMSG_92_BASE_IDX                                                                   0
-#define regMP0_SMN_C2PMSG_93                                                                            0x009d
-#define regMP0_SMN_C2PMSG_93_BASE_IDX                                                                   0
-#define regMP0_SMN_C2PMSG_94                                                                            0x009e
-#define regMP0_SMN_C2PMSG_94_BASE_IDX                                                                   0
-#define regMP0_SMN_C2PMSG_95                                                                            0x009f
-#define regMP0_SMN_C2PMSG_95_BASE_IDX                                                                   0
-#define regMP0_SMN_C2PMSG_96                                                                            0x00a0
-#define regMP0_SMN_C2PMSG_96_BASE_IDX                                                                   0
-#define regMP0_SMN_C2PMSG_97                                                                            0x00a1
-#define regMP0_SMN_C2PMSG_97_BASE_IDX                                                                   0
-#define regMP0_SMN_C2PMSG_98                                                                            0x00a2
-#define regMP0_SMN_C2PMSG_98_BASE_IDX                                                                   0
-#define regMP0_SMN_C2PMSG_99                                                                            0x00a3
-#define regMP0_SMN_C2PMSG_99_BASE_IDX                                                                   0
-#define regMP0_SMN_C2PMSG_100                                                                           0x00a4
-#define regMP0_SMN_C2PMSG_100_BASE_IDX                                                                  0
-#define regMP0_SMN_C2PMSG_101                                                                           0x00a5
-#define regMP0_SMN_C2PMSG_101_BASE_IDX                                                                  0
-#define regMP0_SMN_C2PMSG_102                                                                           0x00a6
-#define regMP0_SMN_C2PMSG_102_BASE_IDX                                                                  0
-#define regMP0_SMN_C2PMSG_103                                                                           0x00a7
-#define regMP0_SMN_C2PMSG_103_BASE_IDX                                                                  0
-#define regMP0_SMN_IH_CREDIT                                                                            0x00c1
-#define regMP0_SMN_IH_CREDIT_BASE_IDX                                                                   0
-#define regMP0_SMN_IH_SW_INT                                                                            0x00c2
-#define regMP0_SMN_IH_SW_INT_BASE_IDX                                                                   0
-#define regMP0_SMN_IH_SW_INT_CTRL                                                                       0x00c3
-#define regMP0_SMN_IH_SW_INT_CTRL_BASE_IDX                                                              0
-
-
-// addressBlock: mp_SmuMp1_SmnDec
-// base address: 0x0
-#define regMP1_SMN_C2PMSG_32                                                                            0x0260
-#define regMP1_SMN_C2PMSG_32_BASE_IDX                                                                   0
-#define regMP1_SMN_C2PMSG_33                                                                            0x0261
-#define regMP1_SMN_C2PMSG_33_BASE_IDX                                                                   0
-#define regMP1_SMN_C2PMSG_34                                                                            0x0262
-#define regMP1_SMN_C2PMSG_34_BASE_IDX                                                                   0
-#define regMP1_SMN_C2PMSG_35                                                                            0x0263
-#define regMP1_SMN_C2PMSG_35_BASE_IDX                                                                   0
-#define regMP1_SMN_C2PMSG_36                                                                            0x0264
-#define regMP1_SMN_C2PMSG_36_BASE_IDX                                                                   0
-#define regMP1_SMN_C2PMSG_37                                                                            0x0265
-#define regMP1_SMN_C2PMSG_37_BASE_IDX                                                                   0
-#define regMP1_SMN_C2PMSG_38                                                                            0x0266
-#define regMP1_SMN_C2PMSG_38_BASE_IDX                                                                   0
-#define regMP1_SMN_C2PMSG_39                                                                            0x0267
-#define regMP1_SMN_C2PMSG_39_BASE_IDX                                                                   0
-#define regMP1_SMN_C2PMSG_40                                                                            0x0268
-#define regMP1_SMN_C2PMSG_40_BASE_IDX                                                                   0
-#define regMP1_SMN_C2PMSG_41                                                                            0x0269
-#define regMP1_SMN_C2PMSG_41_BASE_IDX                                                                   0
-#define regMP1_SMN_C2PMSG_42                                                                            0x026a
-#define regMP1_SMN_C2PMSG_42_BASE_IDX                                                                   0
-#define regMP1_SMN_C2PMSG_43                                                                            0x026b
-#define regMP1_SMN_C2PMSG_43_BASE_IDX                                                                   0
-#define regMP1_SMN_C2PMSG_44                                                                            0x026c
-#define regMP1_SMN_C2PMSG_44_BASE_IDX                                                                   0
-#define regMP1_SMN_C2PMSG_45                                                                            0x026d
-#define regMP1_SMN_C2PMSG_45_BASE_IDX                                                                   0
-#define regMP1_SMN_C2PMSG_46                                                                            0x026e
-#define regMP1_SMN_C2PMSG_46_BASE_IDX                                                                   0
-#define regMP1_SMN_C2PMSG_47                                                                            0x026f
-#define regMP1_SMN_C2PMSG_47_BASE_IDX                                                                   0
-#define regMP1_SMN_C2PMSG_48                                                                            0x0270
-#define regMP1_SMN_C2PMSG_48_BASE_IDX                                                                   0
-#define regMP1_SMN_C2PMSG_49                                                                            0x0271
-#define regMP1_SMN_C2PMSG_49_BASE_IDX                                                                   0
-#define regMP1_SMN_C2PMSG_50                                                                            0x0272
-#define regMP1_SMN_C2PMSG_50_BASE_IDX                                                                   0
-#define regMP1_SMN_C2PMSG_51                                                                            0x0273
-#define regMP1_SMN_C2PMSG_51_BASE_IDX                                                                   0
-#define regMP1_SMN_C2PMSG_52                                                                            0x0274
-#define regMP1_SMN_C2PMSG_52_BASE_IDX                                                                   0
-#define regMP1_SMN_C2PMSG_53                                                                            0x0275
-#define regMP1_SMN_C2PMSG_53_BASE_IDX                                                                   0
-#define regMP1_SMN_C2PMSG_54                                                                            0x0276
-#define regMP1_SMN_C2PMSG_54_BASE_IDX                                                                   0
-#define regMP1_SMN_C2PMSG_55                                                                            0x0277
-#define regMP1_SMN_C2PMSG_55_BASE_IDX                                                                   0
-#define regMP1_SMN_C2PMSG_56                                                                            0x0278
-#define regMP1_SMN_C2PMSG_56_BASE_IDX                                                                   0
-#define regMP1_SMN_C2PMSG_57                                                                            0x0279
-#define regMP1_SMN_C2PMSG_57_BASE_IDX                                                                   0
-#define regMP1_SMN_C2PMSG_58                                                                            0x027a
-#define regMP1_SMN_C2PMSG_58_BASE_IDX                                                                   0
-#define regMP1_SMN_C2PMSG_59                                                                            0x027b
-#define regMP1_SMN_C2PMSG_59_BASE_IDX                                                                   0
-#define regMP1_SMN_C2PMSG_60                                                                            0x027c
-#define regMP1_SMN_C2PMSG_60_BASE_IDX                                                                   0
-#define regMP1_SMN_C2PMSG_61                                                                            0x027d
-#define regMP1_SMN_C2PMSG_61_BASE_IDX                                                                   0
-#define regMP1_SMN_C2PMSG_62                                                                            0x027e
-#define regMP1_SMN_C2PMSG_62_BASE_IDX                                                                   0
-#define regMP1_SMN_C2PMSG_63                                                                            0x027f
-#define regMP1_SMN_C2PMSG_63_BASE_IDX                                                                   0
-#define regMP1_SMN_C2PMSG_64                                                                            0x0280
-#define regMP1_SMN_C2PMSG_64_BASE_IDX                                                                   0
-#define regMP1_SMN_C2PMSG_65                                                                            0x0281
-#define regMP1_SMN_C2PMSG_65_BASE_IDX                                                                   0
-#define regMP1_SMN_C2PMSG_66                                                                            0x0282
-#define regMP1_SMN_C2PMSG_66_BASE_IDX                                                                   0
-#define regMP1_SMN_C2PMSG_67                                                                            0x0283
-#define regMP1_SMN_C2PMSG_67_BASE_IDX                                                                   0
-#define regMP1_SMN_C2PMSG_68                                                                            0x0284
-#define regMP1_SMN_C2PMSG_68_BASE_IDX                                                                   0
-#define regMP1_SMN_C2PMSG_69                                                                            0x0285
-#define regMP1_SMN_C2PMSG_69_BASE_IDX                                                                   0
-#define regMP1_SMN_C2PMSG_70                                                                            0x0286
-#define regMP1_SMN_C2PMSG_70_BASE_IDX                                                                   0
-#define regMP1_SMN_C2PMSG_71                                                                            0x0287
-#define regMP1_SMN_C2PMSG_71_BASE_IDX                                                                   0
-#define regMP1_SMN_C2PMSG_72                                                                            0x0288
-#define regMP1_SMN_C2PMSG_72_BASE_IDX                                                                   0
-#define regMP1_SMN_C2PMSG_73                                                                            0x0289
-#define regMP1_SMN_C2PMSG_73_BASE_IDX                                                                   0
-#define regMP1_SMN_C2PMSG_74                                                                            0x028a
-#define regMP1_SMN_C2PMSG_74_BASE_IDX                                                                   0
-#define regMP1_SMN_C2PMSG_75                                                                            0x028b
-#define regMP1_SMN_C2PMSG_75_BASE_IDX                                                                   0
-#define regMP1_SMN_C2PMSG_76                                                                            0x028c
-#define regMP1_SMN_C2PMSG_76_BASE_IDX                                                                   0
-#define regMP1_SMN_C2PMSG_77                                                                            0x028d
-#define regMP1_SMN_C2PMSG_77_BASE_IDX                                                                   0
-#define regMP1_SMN_C2PMSG_78                                                                            0x028e
-#define regMP1_SMN_C2PMSG_78_BASE_IDX                                                                   0
-#define regMP1_SMN_C2PMSG_79                                                                            0x028f
-#define regMP1_SMN_C2PMSG_79_BASE_IDX                                                                   0
-#define regMP1_SMN_C2PMSG_80                                                                            0x0290
-#define regMP1_SMN_C2PMSG_80_BASE_IDX                                                                   0
-#define regMP1_SMN_C2PMSG_81                                                                            0x0291
-#define regMP1_SMN_C2PMSG_81_BASE_IDX                                                                   0
-#define regMP1_SMN_C2PMSG_82                                                                            0x0292
-#define regMP1_SMN_C2PMSG_82_BASE_IDX                                                                   0
-#define regMP1_SMN_C2PMSG_83                                                                            0x0293
-#define regMP1_SMN_C2PMSG_83_BASE_IDX                                                                   0
-#define regMP1_SMN_C2PMSG_84                                                                            0x0294
-#define regMP1_SMN_C2PMSG_84_BASE_IDX                                                                   0
-#define regMP1_SMN_C2PMSG_85                                                                            0x0295
-#define regMP1_SMN_C2PMSG_85_BASE_IDX                                                                   0
-#define regMP1_SMN_C2PMSG_86                                                                            0x0296
-#define regMP1_SMN_C2PMSG_86_BASE_IDX                                                                   0
-#define regMP1_SMN_C2PMSG_87                                                                            0x0297
-#define regMP1_SMN_C2PMSG_87_BASE_IDX                                                                   0
-#define regMP1_SMN_C2PMSG_88                                                                            0x0298
-#define regMP1_SMN_C2PMSG_88_BASE_IDX                                                                   0
-#define regMP1_SMN_C2PMSG_89                                                                            0x0299
-#define regMP1_SMN_C2PMSG_89_BASE_IDX                                                                   0
-#define regMP1_SMN_C2PMSG_90                                                                            0x029a
-#define regMP1_SMN_C2PMSG_90_BASE_IDX                                                                   0
-#define regMP1_SMN_C2PMSG_91                                                                            0x029b
-#define regMP1_SMN_C2PMSG_91_BASE_IDX                                                                   0
-#define regMP1_SMN_C2PMSG_92                                                                            0x029c
-#define regMP1_SMN_C2PMSG_92_BASE_IDX                                                                   0
-#define regMP1_SMN_C2PMSG_93                                                                            0x029d
-#define regMP1_SMN_C2PMSG_93_BASE_IDX                                                                   0
-#define regMP1_SMN_C2PMSG_94                                                                            0x029e
-#define regMP1_SMN_C2PMSG_94_BASE_IDX                                                                   0
-#define regMP1_SMN_C2PMSG_95                                                                            0x029f
-#define regMP1_SMN_C2PMSG_95_BASE_IDX                                                                   0
-#define regMP1_SMN_C2PMSG_96                                                                            0x02a0
-#define regMP1_SMN_C2PMSG_96_BASE_IDX                                                                   0
-#define regMP1_SMN_C2PMSG_97                                                                            0x02a1
-#define regMP1_SMN_C2PMSG_97_BASE_IDX                                                                   0
-#define regMP1_SMN_C2PMSG_98                                                                            0x02a2
-#define regMP1_SMN_C2PMSG_98_BASE_IDX                                                                   0
-#define regMP1_SMN_C2PMSG_99                                                                            0x02a3
-#define regMP1_SMN_C2PMSG_99_BASE_IDX                                                                   0
-#define regMP1_SMN_C2PMSG_100                                                                           0x02a4
-#define regMP1_SMN_C2PMSG_100_BASE_IDX                                                                  0
-#define regMP1_SMN_C2PMSG_101                                                                           0x02a5
-#define regMP1_SMN_C2PMSG_101_BASE_IDX                                                                  0
-#define regMP1_SMN_C2PMSG_102                                                                           0x02a6
-#define regMP1_SMN_C2PMSG_102_BASE_IDX                                                                  0
-#define regMP1_SMN_C2PMSG_103                                                                           0x02a7
-#define regMP1_SMN_C2PMSG_103_BASE_IDX                                                                  0
-#define regMP1_SMN_IH_CREDIT                                                                            0x02c1
-#define regMP1_SMN_IH_CREDIT_BASE_IDX                                                                   0
-#define regMP1_SMN_IH_SW_INT                                                                            0x02c2
-#define regMP1_SMN_IH_SW_INT_BASE_IDX                                                                   0
-#define regMP1_SMN_IH_SW_INT_CTRL                                                                       0x02c3
-#define regMP1_SMN_IH_SW_INT_CTRL_BASE_IDX                                                              0
-#define regMP1_SMN_FPS_CNT                                                                              0x02c4
-#define regMP1_SMN_FPS_CNT_BASE_IDX                                                                     0
-#define regMP1_SMN_EXT_SCRATCH0                                                                         0x0340
-#define regMP1_SMN_EXT_SCRATCH0_BASE_IDX                                                                0
-#define regMP1_SMN_EXT_SCRATCH1                                                                         0x0341
-#define regMP1_SMN_EXT_SCRATCH1_BASE_IDX                                                                0
-#define regMP1_SMN_EXT_SCRATCH2                                                                         0x0342
-#define regMP1_SMN_EXT_SCRATCH2_BASE_IDX                                                                0
-#define regMP1_SMN_EXT_SCRATCH3                                                                         0x0343
-#define regMP1_SMN_EXT_SCRATCH3_BASE_IDX                                                                0
-#define regMP1_SMN_EXT_SCRATCH4                                                                         0x0344
-#define regMP1_SMN_EXT_SCRATCH4_BASE_IDX                                                                0
-#define regMP1_SMN_EXT_SCRATCH5                                                                         0x0345
-#define regMP1_SMN_EXT_SCRATCH5_BASE_IDX                                                                0
-#define regMP1_SMN_EXT_SCRATCH6                                                                         0x0346
-#define regMP1_SMN_EXT_SCRATCH6_BASE_IDX                                                                0
-#define regMP1_SMN_EXT_SCRATCH7                                                                         0x0347
-#define regMP1_SMN_EXT_SCRATCH7_BASE_IDX                                                                0
-
-
-#endif
diff --git a/drivers/gpu/drm/amd/include/asic_reg/mp/mp_13_0_1_sh_mask.h b/drivers/gpu/drm/amd/include/asic_reg/mp/mp_13_0_1_sh_mask.h
deleted file mode 100644 (file)
index 2d5e8b5..0000000
+++ /dev/null
@@ -1,531 +0,0 @@
-/*
- * Copyright 2020 Advanced Micro Devices, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- *
- */
-#ifndef _mp_13_0_1_SH_MASK_HEADER
-#define _mp_13_0_1_SH_MASK_HEADER
-
-
-// addressBlock: mp_SmuMp0_SmnDec
-//MP0_SMN_C2PMSG_32
-#define MP0_SMN_C2PMSG_32__CONTENT__SHIFT                                                                     0x0
-#define MP0_SMN_C2PMSG_32__CONTENT_MASK                                                                       0xFFFFFFFFL
-//MP0_SMN_C2PMSG_33
-#define MP0_SMN_C2PMSG_33__CONTENT__SHIFT                                                                     0x0
-#define MP0_SMN_C2PMSG_33__CONTENT_MASK                                                                       0xFFFFFFFFL
-//MP0_SMN_C2PMSG_34
-#define MP0_SMN_C2PMSG_34__CONTENT__SHIFT                                                                     0x0
-#define MP0_SMN_C2PMSG_34__CONTENT_MASK                                                                       0xFFFFFFFFL
-//MP0_SMN_C2PMSG_35
-#define MP0_SMN_C2PMSG_35__CONTENT__SHIFT                                                                     0x0
-#define MP0_SMN_C2PMSG_35__CONTENT_MASK                                                                       0xFFFFFFFFL
-//MP0_SMN_C2PMSG_36
-#define MP0_SMN_C2PMSG_36__CONTENT__SHIFT                                                                     0x0
-#define MP0_SMN_C2PMSG_36__CONTENT_MASK                                                                       0xFFFFFFFFL
-//MP0_SMN_C2PMSG_37
-#define MP0_SMN_C2PMSG_37__CONTENT__SHIFT                                                                     0x0
-#define MP0_SMN_C2PMSG_37__CONTENT_MASK                                                                       0xFFFFFFFFL
-//MP0_SMN_C2PMSG_38
-#define MP0_SMN_C2PMSG_38__CONTENT__SHIFT                                                                     0x0
-#define MP0_SMN_C2PMSG_38__CONTENT_MASK                                                                       0xFFFFFFFFL
-//MP0_SMN_C2PMSG_39
-#define MP0_SMN_C2PMSG_39__CONTENT__SHIFT                                                                     0x0
-#define MP0_SMN_C2PMSG_39__CONTENT_MASK                                                                       0xFFFFFFFFL
-//MP0_SMN_C2PMSG_40
-#define MP0_SMN_C2PMSG_40__CONTENT__SHIFT                                                                     0x0
-#define MP0_SMN_C2PMSG_40__CONTENT_MASK                                                                       0xFFFFFFFFL
-//MP0_SMN_C2PMSG_41
-#define MP0_SMN_C2PMSG_41__CONTENT__SHIFT                                                                     0x0
-#define MP0_SMN_C2PMSG_41__CONTENT_MASK                                                                       0xFFFFFFFFL
-//MP0_SMN_C2PMSG_42
-#define MP0_SMN_C2PMSG_42__CONTENT__SHIFT                                                                     0x0
-#define MP0_SMN_C2PMSG_42__CONTENT_MASK                                                                       0xFFFFFFFFL
-//MP0_SMN_C2PMSG_43
-#define MP0_SMN_C2PMSG_43__CONTENT__SHIFT                                                                     0x0
-#define MP0_SMN_C2PMSG_43__CONTENT_MASK                                                                       0xFFFFFFFFL
-//MP0_SMN_C2PMSG_44
-#define MP0_SMN_C2PMSG_44__CONTENT__SHIFT                                                                     0x0
-#define MP0_SMN_C2PMSG_44__CONTENT_MASK                                                                       0xFFFFFFFFL
-//MP0_SMN_C2PMSG_45
-#define MP0_SMN_C2PMSG_45__CONTENT__SHIFT                                                                     0x0
-#define MP0_SMN_C2PMSG_45__CONTENT_MASK                                                                       0xFFFFFFFFL
-//MP0_SMN_C2PMSG_46
-#define MP0_SMN_C2PMSG_46__CONTENT__SHIFT                                                                     0x0
-#define MP0_SMN_C2PMSG_46__CONTENT_MASK                                                                       0xFFFFFFFFL
-//MP0_SMN_C2PMSG_47
-#define MP0_SMN_C2PMSG_47__CONTENT__SHIFT                                                                     0x0
-#define MP0_SMN_C2PMSG_47__CONTENT_MASK                                                                       0xFFFFFFFFL
-//MP0_SMN_C2PMSG_48
-#define MP0_SMN_C2PMSG_48__CONTENT__SHIFT                                                                     0x0
-#define MP0_SMN_C2PMSG_48__CONTENT_MASK                                                                       0xFFFFFFFFL
-//MP0_SMN_C2PMSG_49
-#define MP0_SMN_C2PMSG_49__CONTENT__SHIFT                                                                     0x0
-#define MP0_SMN_C2PMSG_49__CONTENT_MASK                                                                       0xFFFFFFFFL
-//MP0_SMN_C2PMSG_50
-#define MP0_SMN_C2PMSG_50__CONTENT__SHIFT                                                                     0x0
-#define MP0_SMN_C2PMSG_50__CONTENT_MASK                                                                       0xFFFFFFFFL
-//MP0_SMN_C2PMSG_51
-#define MP0_SMN_C2PMSG_51__CONTENT__SHIFT                                                                     0x0
-#define MP0_SMN_C2PMSG_51__CONTENT_MASK                                                                       0xFFFFFFFFL
-//MP0_SMN_C2PMSG_52
-#define MP0_SMN_C2PMSG_52__CONTENT__SHIFT                                                                     0x0
-#define MP0_SMN_C2PMSG_52__CONTENT_MASK                                                                       0xFFFFFFFFL
-//MP0_SMN_C2PMSG_53
-#define MP0_SMN_C2PMSG_53__CONTENT__SHIFT                                                                     0x0
-#define MP0_SMN_C2PMSG_53__CONTENT_MASK                                                                       0xFFFFFFFFL
-//MP0_SMN_C2PMSG_54
-#define MP0_SMN_C2PMSG_54__CONTENT__SHIFT                                                                     0x0
-#define MP0_SMN_C2PMSG_54__CONTENT_MASK                                                                       0xFFFFFFFFL
-//MP0_SMN_C2PMSG_55
-#define MP0_SMN_C2PMSG_55__CONTENT__SHIFT                                                                     0x0
-#define MP0_SMN_C2PMSG_55__CONTENT_MASK                                                                       0xFFFFFFFFL
-//MP0_SMN_C2PMSG_56
-#define MP0_SMN_C2PMSG_56__CONTENT__SHIFT                                                                     0x0
-#define MP0_SMN_C2PMSG_56__CONTENT_MASK                                                                       0xFFFFFFFFL
-//MP0_SMN_C2PMSG_57
-#define MP0_SMN_C2PMSG_57__CONTENT__SHIFT                                                                     0x0
-#define MP0_SMN_C2PMSG_57__CONTENT_MASK                                                                       0xFFFFFFFFL
-//MP0_SMN_C2PMSG_58
-#define MP0_SMN_C2PMSG_58__CONTENT__SHIFT                                                                     0x0
-#define MP0_SMN_C2PMSG_58__CONTENT_MASK                                                                       0xFFFFFFFFL
-//MP0_SMN_C2PMSG_59
-#define MP0_SMN_C2PMSG_59__CONTENT__SHIFT                                                                     0x0
-#define MP0_SMN_C2PMSG_59__CONTENT_MASK                                                                       0xFFFFFFFFL
-//MP0_SMN_C2PMSG_60
-#define MP0_SMN_C2PMSG_60__CONTENT__SHIFT                                                                     0x0
-#define MP0_SMN_C2PMSG_60__CONTENT_MASK                                                                       0xFFFFFFFFL
-//MP0_SMN_C2PMSG_61
-#define MP0_SMN_C2PMSG_61__CONTENT__SHIFT                                                                     0x0
-#define MP0_SMN_C2PMSG_61__CONTENT_MASK                                                                       0xFFFFFFFFL
-//MP0_SMN_C2PMSG_62
-#define MP0_SMN_C2PMSG_62__CONTENT__SHIFT                                                                     0x0
-#define MP0_SMN_C2PMSG_62__CONTENT_MASK                                                                       0xFFFFFFFFL
-//MP0_SMN_C2PMSG_63
-#define MP0_SMN_C2PMSG_63__CONTENT__SHIFT                                                                     0x0
-#define MP0_SMN_C2PMSG_63__CONTENT_MASK                                                                       0xFFFFFFFFL
-//MP0_SMN_C2PMSG_64
-#define MP0_SMN_C2PMSG_64__CONTENT__SHIFT                                                                     0x0
-#define MP0_SMN_C2PMSG_64__CONTENT_MASK                                                                       0xFFFFFFFFL
-//MP0_SMN_C2PMSG_65
-#define MP0_SMN_C2PMSG_65__CONTENT__SHIFT                                                                     0x0
-#define MP0_SMN_C2PMSG_65__CONTENT_MASK                                                                       0xFFFFFFFFL
-//MP0_SMN_C2PMSG_66
-#define MP0_SMN_C2PMSG_66__CONTENT__SHIFT                                                                     0x0
-#define MP0_SMN_C2PMSG_66__CONTENT_MASK                                                                       0xFFFFFFFFL
-//MP0_SMN_C2PMSG_67
-#define MP0_SMN_C2PMSG_67__CONTENT__SHIFT                                                                     0x0
-#define MP0_SMN_C2PMSG_67__CONTENT_MASK                                                                       0xFFFFFFFFL
-//MP0_SMN_C2PMSG_68
-#define MP0_SMN_C2PMSG_68__CONTENT__SHIFT                                                                     0x0
-#define MP0_SMN_C2PMSG_68__CONTENT_MASK                                                                       0xFFFFFFFFL
-//MP0_SMN_C2PMSG_69
-#define MP0_SMN_C2PMSG_69__CONTENT__SHIFT                                                                     0x0
-#define MP0_SMN_C2PMSG_69__CONTENT_MASK                                                                       0xFFFFFFFFL
-//MP0_SMN_C2PMSG_70
-#define MP0_SMN_C2PMSG_70__CONTENT__SHIFT                                                                     0x0
-#define MP0_SMN_C2PMSG_70__CONTENT_MASK                                                                       0xFFFFFFFFL
-//MP0_SMN_C2PMSG_71
-#define MP0_SMN_C2PMSG_71__CONTENT__SHIFT                                                                     0x0
-#define MP0_SMN_C2PMSG_71__CONTENT_MASK                                                                       0xFFFFFFFFL
-//MP0_SMN_C2PMSG_72
-#define MP0_SMN_C2PMSG_72__CONTENT__SHIFT                                                                     0x0
-#define MP0_SMN_C2PMSG_72__CONTENT_MASK                                                                       0xFFFFFFFFL
-//MP0_SMN_C2PMSG_73
-#define MP0_SMN_C2PMSG_73__CONTENT__SHIFT                                                                     0x0
-#define MP0_SMN_C2PMSG_73__CONTENT_MASK                                                                       0xFFFFFFFFL
-//MP0_SMN_C2PMSG_74
-#define MP0_SMN_C2PMSG_74__CONTENT__SHIFT                                                                     0x0
-#define MP0_SMN_C2PMSG_74__CONTENT_MASK                                                                       0xFFFFFFFFL
-//MP0_SMN_C2PMSG_75
-#define MP0_SMN_C2PMSG_75__CONTENT__SHIFT                                                                     0x0
-#define MP0_SMN_C2PMSG_75__CONTENT_MASK                                                                       0xFFFFFFFFL
-//MP0_SMN_C2PMSG_76
-#define MP0_SMN_C2PMSG_76__CONTENT__SHIFT                                                                     0x0
-#define MP0_SMN_C2PMSG_76__CONTENT_MASK                                                                       0xFFFFFFFFL
-//MP0_SMN_C2PMSG_77
-#define MP0_SMN_C2PMSG_77__CONTENT__SHIFT                                                                     0x0
-#define MP0_SMN_C2PMSG_77__CONTENT_MASK                                                                       0xFFFFFFFFL
-//MP0_SMN_C2PMSG_78
-#define MP0_SMN_C2PMSG_78__CONTENT__SHIFT                                                                     0x0
-#define MP0_SMN_C2PMSG_78__CONTENT_MASK                                                                       0xFFFFFFFFL
-//MP0_SMN_C2PMSG_79
-#define MP0_SMN_C2PMSG_79__CONTENT__SHIFT                                                                     0x0
-#define MP0_SMN_C2PMSG_79__CONTENT_MASK                                                                       0xFFFFFFFFL
-//MP0_SMN_C2PMSG_80
-#define MP0_SMN_C2PMSG_80__CONTENT__SHIFT                                                                     0x0
-#define MP0_SMN_C2PMSG_80__CONTENT_MASK                                                                       0xFFFFFFFFL
-//MP0_SMN_C2PMSG_81
-#define MP0_SMN_C2PMSG_81__CONTENT__SHIFT                                                                     0x0
-#define MP0_SMN_C2PMSG_81__CONTENT_MASK                                                                       0xFFFFFFFFL
-//MP0_SMN_C2PMSG_82
-#define MP0_SMN_C2PMSG_82__CONTENT__SHIFT                                                                     0x0
-#define MP0_SMN_C2PMSG_82__CONTENT_MASK                                                                       0xFFFFFFFFL
-//MP0_SMN_C2PMSG_83
-#define MP0_SMN_C2PMSG_83__CONTENT__SHIFT                                                                     0x0
-#define MP0_SMN_C2PMSG_83__CONTENT_MASK                                                                       0xFFFFFFFFL
-//MP0_SMN_C2PMSG_84
-#define MP0_SMN_C2PMSG_84__CONTENT__SHIFT                                                                     0x0
-#define MP0_SMN_C2PMSG_84__CONTENT_MASK                                                                       0xFFFFFFFFL
-//MP0_SMN_C2PMSG_85
-#define MP0_SMN_C2PMSG_85__CONTENT__SHIFT                                                                     0x0
-#define MP0_SMN_C2PMSG_85__CONTENT_MASK                                                                       0xFFFFFFFFL
-//MP0_SMN_C2PMSG_86
-#define MP0_SMN_C2PMSG_86__CONTENT__SHIFT                                                                     0x0
-#define MP0_SMN_C2PMSG_86__CONTENT_MASK                                                                       0xFFFFFFFFL
-//MP0_SMN_C2PMSG_87
-#define MP0_SMN_C2PMSG_87__CONTENT__SHIFT                                                                     0x0
-#define MP0_SMN_C2PMSG_87__CONTENT_MASK                                                                       0xFFFFFFFFL
-//MP0_SMN_C2PMSG_88
-#define MP0_SMN_C2PMSG_88__CONTENT__SHIFT                                                                     0x0
-#define MP0_SMN_C2PMSG_88__CONTENT_MASK                                                                       0xFFFFFFFFL
-//MP0_SMN_C2PMSG_89
-#define MP0_SMN_C2PMSG_89__CONTENT__SHIFT                                                                     0x0
-#define MP0_SMN_C2PMSG_89__CONTENT_MASK                                                                       0xFFFFFFFFL
-//MP0_SMN_C2PMSG_90
-#define MP0_SMN_C2PMSG_90__CONTENT__SHIFT                                                                     0x0
-#define MP0_SMN_C2PMSG_90__CONTENT_MASK                                                                       0xFFFFFFFFL
-//MP0_SMN_C2PMSG_91
-#define MP0_SMN_C2PMSG_91__CONTENT__SHIFT                                                                     0x0
-#define MP0_SMN_C2PMSG_91__CONTENT_MASK                                                                       0xFFFFFFFFL
-//MP0_SMN_C2PMSG_92
-#define MP0_SMN_C2PMSG_92__CONTENT__SHIFT                                                                     0x0
-#define MP0_SMN_C2PMSG_92__CONTENT_MASK                                                                       0xFFFFFFFFL
-//MP0_SMN_C2PMSG_93
-#define MP0_SMN_C2PMSG_93__CONTENT__SHIFT                                                                     0x0
-#define MP0_SMN_C2PMSG_93__CONTENT_MASK                                                                       0xFFFFFFFFL
-//MP0_SMN_C2PMSG_94
-#define MP0_SMN_C2PMSG_94__CONTENT__SHIFT                                                                     0x0
-#define MP0_SMN_C2PMSG_94__CONTENT_MASK                                                                       0xFFFFFFFFL
-//MP0_SMN_C2PMSG_95
-#define MP0_SMN_C2PMSG_95__CONTENT__SHIFT                                                                     0x0
-#define MP0_SMN_C2PMSG_95__CONTENT_MASK                                                                       0xFFFFFFFFL
-//MP0_SMN_C2PMSG_96
-#define MP0_SMN_C2PMSG_96__CONTENT__SHIFT                                                                     0x0
-#define MP0_SMN_C2PMSG_96__CONTENT_MASK                                                                       0xFFFFFFFFL
-//MP0_SMN_C2PMSG_97
-#define MP0_SMN_C2PMSG_97__CONTENT__SHIFT                                                                     0x0
-#define MP0_SMN_C2PMSG_97__CONTENT_MASK                                                                       0xFFFFFFFFL
-//MP0_SMN_C2PMSG_98
-#define MP0_SMN_C2PMSG_98__CONTENT__SHIFT                                                                     0x0
-#define MP0_SMN_C2PMSG_98__CONTENT_MASK                                                                       0xFFFFFFFFL
-//MP0_SMN_C2PMSG_99
-#define MP0_SMN_C2PMSG_99__CONTENT__SHIFT                                                                     0x0
-#define MP0_SMN_C2PMSG_99__CONTENT_MASK                                                                       0xFFFFFFFFL
-//MP0_SMN_C2PMSG_100
-#define MP0_SMN_C2PMSG_100__CONTENT__SHIFT                                                                    0x0
-#define MP0_SMN_C2PMSG_100__CONTENT_MASK                                                                      0xFFFFFFFFL
-//MP0_SMN_C2PMSG_101
-#define MP0_SMN_C2PMSG_101__CONTENT__SHIFT                                                                    0x0
-#define MP0_SMN_C2PMSG_101__CONTENT_MASK                                                                      0xFFFFFFFFL
-//MP0_SMN_C2PMSG_102
-#define MP0_SMN_C2PMSG_102__CONTENT__SHIFT                                                                    0x0
-#define MP0_SMN_C2PMSG_102__CONTENT_MASK                                                                      0xFFFFFFFFL
-//MP0_SMN_C2PMSG_103
-#define MP0_SMN_C2PMSG_103__CONTENT__SHIFT                                                                    0x0
-#define MP0_SMN_C2PMSG_103__CONTENT_MASK                                                                      0xFFFFFFFFL
-//MP0_SMN_IH_CREDIT
-#define MP0_SMN_IH_CREDIT__CREDIT_VALUE__SHIFT                                                                0x0
-#define MP0_SMN_IH_CREDIT__CLIENT_ID__SHIFT                                                                   0x10
-#define MP0_SMN_IH_CREDIT__CREDIT_VALUE_MASK                                                                  0x00000003L
-#define MP0_SMN_IH_CREDIT__CLIENT_ID_MASK                                                                     0x00FF0000L
-//MP0_SMN_IH_SW_INT
-#define MP0_SMN_IH_SW_INT__ID__SHIFT                                                                          0x0
-#define MP0_SMN_IH_SW_INT__VALID__SHIFT                                                                       0x8
-#define MP0_SMN_IH_SW_INT__ID_MASK                                                                            0x000000FFL
-#define MP0_SMN_IH_SW_INT__VALID_MASK                                                                         0x00000100L
-//MP0_SMN_IH_SW_INT_CTRL
-#define MP0_SMN_IH_SW_INT_CTRL__INT_MASK__SHIFT                                                               0x0
-#define MP0_SMN_IH_SW_INT_CTRL__INT_ACK__SHIFT                                                                0x8
-#define MP0_SMN_IH_SW_INT_CTRL__INT_MASK_MASK                                                                 0x00000001L
-#define MP0_SMN_IH_SW_INT_CTRL__INT_ACK_MASK                                                                  0x00000100L
-
-
-// addressBlock: mp_SmuMp1Pub_CruDec
-//MP1_FIRMWARE_FLAGS
-#define MP1_FIRMWARE_FLAGS__INTERRUPTS_ENABLED__SHIFT                                                         0x0
-#define MP1_FIRMWARE_FLAGS__RESERVED__SHIFT                                                                   0x1
-#define MP1_FIRMWARE_FLAGS__INTERRUPTS_ENABLED_MASK                                                           0x00000001L
-#define MP1_FIRMWARE_FLAGS__RESERVED_MASK                                                                     0xFFFFFFFEL
-
-
-// addressBlock: mp_SmuMp1_SmnDec
-//MP1_SMN_C2PMSG_32
-#define MP1_SMN_C2PMSG_32__CONTENT__SHIFT                                                                     0x0
-#define MP1_SMN_C2PMSG_32__CONTENT_MASK                                                                       0xFFFFFFFFL
-//MP1_SMN_C2PMSG_33
-#define MP1_SMN_C2PMSG_33__CONTENT__SHIFT                                                                     0x0
-#define MP1_SMN_C2PMSG_33__CONTENT_MASK                                                                       0xFFFFFFFFL
-//MP1_SMN_C2PMSG_34
-#define MP1_SMN_C2PMSG_34__CONTENT__SHIFT                                                                     0x0
-#define MP1_SMN_C2PMSG_34__CONTENT_MASK                                                                       0xFFFFFFFFL
-//MP1_SMN_C2PMSG_35
-#define MP1_SMN_C2PMSG_35__CONTENT__SHIFT                                                                     0x0
-#define MP1_SMN_C2PMSG_35__CONTENT_MASK                                                                       0xFFFFFFFFL
-//MP1_SMN_C2PMSG_36
-#define MP1_SMN_C2PMSG_36__CONTENT__SHIFT                                                                     0x0
-#define MP1_SMN_C2PMSG_36__CONTENT_MASK                                                                       0xFFFFFFFFL
-//MP1_SMN_C2PMSG_37
-#define MP1_SMN_C2PMSG_37__CONTENT__SHIFT                                                                     0x0
-#define MP1_SMN_C2PMSG_37__CONTENT_MASK                                                                       0xFFFFFFFFL
-//MP1_SMN_C2PMSG_38
-#define MP1_SMN_C2PMSG_38__CONTENT__SHIFT                                                                     0x0
-#define MP1_SMN_C2PMSG_38__CONTENT_MASK                                                                       0xFFFFFFFFL
-//MP1_SMN_C2PMSG_39
-#define MP1_SMN_C2PMSG_39__CONTENT__SHIFT                                                                     0x0
-#define MP1_SMN_C2PMSG_39__CONTENT_MASK                                                                       0xFFFFFFFFL
-//MP1_SMN_C2PMSG_40
-#define MP1_SMN_C2PMSG_40__CONTENT__SHIFT                                                                     0x0
-#define MP1_SMN_C2PMSG_40__CONTENT_MASK                                                                       0xFFFFFFFFL
-//MP1_SMN_C2PMSG_41
-#define MP1_SMN_C2PMSG_41__CONTENT__SHIFT                                                                     0x0
-#define MP1_SMN_C2PMSG_41__CONTENT_MASK                                                                       0xFFFFFFFFL
-//MP1_SMN_C2PMSG_42
-#define MP1_SMN_C2PMSG_42__CONTENT__SHIFT                                                                     0x0
-#define MP1_SMN_C2PMSG_42__CONTENT_MASK                                                                       0xFFFFFFFFL
-//MP1_SMN_C2PMSG_43
-#define MP1_SMN_C2PMSG_43__CONTENT__SHIFT                                                                     0x0
-#define MP1_SMN_C2PMSG_43__CONTENT_MASK                                                                       0xFFFFFFFFL
-//MP1_SMN_C2PMSG_44
-#define MP1_SMN_C2PMSG_44__CONTENT__SHIFT                                                                     0x0
-#define MP1_SMN_C2PMSG_44__CONTENT_MASK                                                                       0xFFFFFFFFL
-//MP1_SMN_C2PMSG_45
-#define MP1_SMN_C2PMSG_45__CONTENT__SHIFT                                                                     0x0
-#define MP1_SMN_C2PMSG_45__CONTENT_MASK                                                                       0xFFFFFFFFL
-//MP1_SMN_C2PMSG_46
-#define MP1_SMN_C2PMSG_46__CONTENT__SHIFT                                                                     0x0
-#define MP1_SMN_C2PMSG_46__CONTENT_MASK                                                                       0xFFFFFFFFL
-//MP1_SMN_C2PMSG_47
-#define MP1_SMN_C2PMSG_47__CONTENT__SHIFT                                                                     0x0
-#define MP1_SMN_C2PMSG_47__CONTENT_MASK                                                                       0xFFFFFFFFL
-//MP1_SMN_C2PMSG_48
-#define MP1_SMN_C2PMSG_48__CONTENT__SHIFT                                                                     0x0
-#define MP1_SMN_C2PMSG_48__CONTENT_MASK                                                                       0xFFFFFFFFL
-//MP1_SMN_C2PMSG_49
-#define MP1_SMN_C2PMSG_49__CONTENT__SHIFT                                                                     0x0
-#define MP1_SMN_C2PMSG_49__CONTENT_MASK                                                                       0xFFFFFFFFL
-//MP1_SMN_C2PMSG_50
-#define MP1_SMN_C2PMSG_50__CONTENT__SHIFT                                                                     0x0
-#define MP1_SMN_C2PMSG_50__CONTENT_MASK                                                                       0xFFFFFFFFL
-//MP1_SMN_C2PMSG_51
-#define MP1_SMN_C2PMSG_51__CONTENT__SHIFT                                                                     0x0
-#define MP1_SMN_C2PMSG_51__CONTENT_MASK                                                                       0xFFFFFFFFL
-//MP1_SMN_C2PMSG_52
-#define MP1_SMN_C2PMSG_52__CONTENT__SHIFT                                                                     0x0
-#define MP1_SMN_C2PMSG_52__CONTENT_MASK                                                                       0xFFFFFFFFL
-//MP1_SMN_C2PMSG_53
-#define MP1_SMN_C2PMSG_53__CONTENT__SHIFT                                                                     0x0
-#define MP1_SMN_C2PMSG_53__CONTENT_MASK                                                                       0xFFFFFFFFL
-//MP1_SMN_C2PMSG_54
-#define MP1_SMN_C2PMSG_54__CONTENT__SHIFT                                                                     0x0
-#define MP1_SMN_C2PMSG_54__CONTENT_MASK                                                                       0xFFFFFFFFL
-//MP1_SMN_C2PMSG_55
-#define MP1_SMN_C2PMSG_55__CONTENT__SHIFT                                                                     0x0
-#define MP1_SMN_C2PMSG_55__CONTENT_MASK                                                                       0xFFFFFFFFL
-//MP1_SMN_C2PMSG_56
-#define MP1_SMN_C2PMSG_56__CONTENT__SHIFT                                                                     0x0
-#define MP1_SMN_C2PMSG_56__CONTENT_MASK                                                                       0xFFFFFFFFL
-//MP1_SMN_C2PMSG_57
-#define MP1_SMN_C2PMSG_57__CONTENT__SHIFT                                                                     0x0
-#define MP1_SMN_C2PMSG_57__CONTENT_MASK                                                                       0xFFFFFFFFL
-//MP1_SMN_C2PMSG_58
-#define MP1_SMN_C2PMSG_58__CONTENT__SHIFT                                                                     0x0
-#define MP1_SMN_C2PMSG_58__CONTENT_MASK                                                                       0xFFFFFFFFL
-//MP1_SMN_C2PMSG_59
-#define MP1_SMN_C2PMSG_59__CONTENT__SHIFT                                                                     0x0
-#define MP1_SMN_C2PMSG_59__CONTENT_MASK                                                                       0xFFFFFFFFL
-//MP1_SMN_C2PMSG_60
-#define MP1_SMN_C2PMSG_60__CONTENT__SHIFT                                                                     0x0
-#define MP1_SMN_C2PMSG_60__CONTENT_MASK                                                                       0xFFFFFFFFL
-//MP1_SMN_C2PMSG_61
-#define MP1_SMN_C2PMSG_61__CONTENT__SHIFT                                                                     0x0
-#define MP1_SMN_C2PMSG_61__CONTENT_MASK                                                                       0xFFFFFFFFL
-//MP1_SMN_C2PMSG_62
-#define MP1_SMN_C2PMSG_62__CONTENT__SHIFT                                                                     0x0
-#define MP1_SMN_C2PMSG_62__CONTENT_MASK                                                                       0xFFFFFFFFL
-//MP1_SMN_C2PMSG_63
-#define MP1_SMN_C2PMSG_63__CONTENT__SHIFT                                                                     0x0
-#define MP1_SMN_C2PMSG_63__CONTENT_MASK                                                                       0xFFFFFFFFL
-//MP1_SMN_C2PMSG_64
-#define MP1_SMN_C2PMSG_64__CONTENT__SHIFT                                                                     0x0
-#define MP1_SMN_C2PMSG_64__CONTENT_MASK                                                                       0xFFFFFFFFL
-//MP1_SMN_C2PMSG_65
-#define MP1_SMN_C2PMSG_65__CONTENT__SHIFT                                                                     0x0
-#define MP1_SMN_C2PMSG_65__CONTENT_MASK                                                                       0xFFFFFFFFL
-//MP1_SMN_C2PMSG_66
-#define MP1_SMN_C2PMSG_66__CONTENT__SHIFT                                                                     0x0
-#define MP1_SMN_C2PMSG_66__CONTENT_MASK                                                                       0xFFFFFFFFL
-//MP1_SMN_C2PMSG_67
-#define MP1_SMN_C2PMSG_67__CONTENT__SHIFT                                                                     0x0
-#define MP1_SMN_C2PMSG_67__CONTENT_MASK                                                                       0xFFFFFFFFL
-//MP1_SMN_C2PMSG_68
-#define MP1_SMN_C2PMSG_68__CONTENT__SHIFT                                                                     0x0
-#define MP1_SMN_C2PMSG_68__CONTENT_MASK                                                                       0xFFFFFFFFL
-//MP1_SMN_C2PMSG_69
-#define MP1_SMN_C2PMSG_69__CONTENT__SHIFT                                                                     0x0
-#define MP1_SMN_C2PMSG_69__CONTENT_MASK                                                                       0xFFFFFFFFL
-//MP1_SMN_C2PMSG_70
-#define MP1_SMN_C2PMSG_70__CONTENT__SHIFT                                                                     0x0
-#define MP1_SMN_C2PMSG_70__CONTENT_MASK                                                                       0xFFFFFFFFL
-//MP1_SMN_C2PMSG_71
-#define MP1_SMN_C2PMSG_71__CONTENT__SHIFT                                                                     0x0
-#define MP1_SMN_C2PMSG_71__CONTENT_MASK                                                                       0xFFFFFFFFL
-//MP1_SMN_C2PMSG_72
-#define MP1_SMN_C2PMSG_72__CONTENT__SHIFT                                                                     0x0
-#define MP1_SMN_C2PMSG_72__CONTENT_MASK                                                                       0xFFFFFFFFL
-//MP1_SMN_C2PMSG_73
-#define MP1_SMN_C2PMSG_73__CONTENT__SHIFT                                                                     0x0
-#define MP1_SMN_C2PMSG_73__CONTENT_MASK                                                                       0xFFFFFFFFL
-//MP1_SMN_C2PMSG_74
-#define MP1_SMN_C2PMSG_74__CONTENT__SHIFT                                                                     0x0
-#define MP1_SMN_C2PMSG_74__CONTENT_MASK                                                                       0xFFFFFFFFL
-//MP1_SMN_C2PMSG_75
-#define MP1_SMN_C2PMSG_75__CONTENT__SHIFT                                                                     0x0
-#define MP1_SMN_C2PMSG_75__CONTENT_MASK                                                                       0xFFFFFFFFL
-//MP1_SMN_C2PMSG_76
-#define MP1_SMN_C2PMSG_76__CONTENT__SHIFT                                                                     0x0
-#define MP1_SMN_C2PMSG_76__CONTENT_MASK                                                                       0xFFFFFFFFL
-//MP1_SMN_C2PMSG_77
-#define MP1_SMN_C2PMSG_77__CONTENT__SHIFT                                                                     0x0
-#define MP1_SMN_C2PMSG_77__CONTENT_MASK                                                                       0xFFFFFFFFL
-//MP1_SMN_C2PMSG_78
-#define MP1_SMN_C2PMSG_78__CONTENT__SHIFT                                                                     0x0
-#define MP1_SMN_C2PMSG_78__CONTENT_MASK                                                                       0xFFFFFFFFL
-//MP1_SMN_C2PMSG_79
-#define MP1_SMN_C2PMSG_79__CONTENT__SHIFT                                                                     0x0
-#define MP1_SMN_C2PMSG_79__CONTENT_MASK                                                                       0xFFFFFFFFL
-//MP1_SMN_C2PMSG_80
-#define MP1_SMN_C2PMSG_80__CONTENT__SHIFT                                                                     0x0
-#define MP1_SMN_C2PMSG_80__CONTENT_MASK                                                                       0xFFFFFFFFL
-//MP1_SMN_C2PMSG_81
-#define MP1_SMN_C2PMSG_81__CONTENT__SHIFT                                                                     0x0
-#define MP1_SMN_C2PMSG_81__CONTENT_MASK                                                                       0xFFFFFFFFL
-//MP1_SMN_C2PMSG_82
-#define MP1_SMN_C2PMSG_82__CONTENT__SHIFT                                                                     0x0
-#define MP1_SMN_C2PMSG_82__CONTENT_MASK                                                                       0xFFFFFFFFL
-//MP1_SMN_C2PMSG_83
-#define MP1_SMN_C2PMSG_83__CONTENT__SHIFT                                                                     0x0
-#define MP1_SMN_C2PMSG_83__CONTENT_MASK                                                                       0xFFFFFFFFL
-//MP1_SMN_C2PMSG_84
-#define MP1_SMN_C2PMSG_84__CONTENT__SHIFT                                                                     0x0
-#define MP1_SMN_C2PMSG_84__CONTENT_MASK                                                                       0xFFFFFFFFL
-//MP1_SMN_C2PMSG_85
-#define MP1_SMN_C2PMSG_85__CONTENT__SHIFT                                                                     0x0
-#define MP1_SMN_C2PMSG_85__CONTENT_MASK                                                                       0xFFFFFFFFL
-//MP1_SMN_C2PMSG_86
-#define MP1_SMN_C2PMSG_86__CONTENT__SHIFT                                                                     0x0
-#define MP1_SMN_C2PMSG_86__CONTENT_MASK                                                                       0xFFFFFFFFL
-//MP1_SMN_C2PMSG_87
-#define MP1_SMN_C2PMSG_87__CONTENT__SHIFT                                                                     0x0
-#define MP1_SMN_C2PMSG_87__CONTENT_MASK                                                                       0xFFFFFFFFL
-//MP1_SMN_C2PMSG_88
-#define MP1_SMN_C2PMSG_88__CONTENT__SHIFT                                                                     0x0
-#define MP1_SMN_C2PMSG_88__CONTENT_MASK                                                                       0xFFFFFFFFL
-//MP1_SMN_C2PMSG_89
-#define MP1_SMN_C2PMSG_89__CONTENT__SHIFT                                                                     0x0
-#define MP1_SMN_C2PMSG_89__CONTENT_MASK                                                                       0xFFFFFFFFL
-//MP1_SMN_C2PMSG_90
-#define MP1_SMN_C2PMSG_90__CONTENT__SHIFT                                                                     0x0
-#define MP1_SMN_C2PMSG_90__CONTENT_MASK                                                                       0xFFFFFFFFL
-//MP1_SMN_C2PMSG_91
-#define MP1_SMN_C2PMSG_91__CONTENT__SHIFT                                                                     0x0
-#define MP1_SMN_C2PMSG_91__CONTENT_MASK                                                                       0xFFFFFFFFL
-//MP1_SMN_C2PMSG_92
-#define MP1_SMN_C2PMSG_92__CONTENT__SHIFT                                                                     0x0
-#define MP1_SMN_C2PMSG_92__CONTENT_MASK                                                                       0xFFFFFFFFL
-//MP1_SMN_C2PMSG_93
-#define MP1_SMN_C2PMSG_93__CONTENT__SHIFT                                                                     0x0
-#define MP1_SMN_C2PMSG_93__CONTENT_MASK                                                                       0xFFFFFFFFL
-//MP1_SMN_C2PMSG_94
-#define MP1_SMN_C2PMSG_94__CONTENT__SHIFT                                                                     0x0
-#define MP1_SMN_C2PMSG_94__CONTENT_MASK                                                                       0xFFFFFFFFL
-//MP1_SMN_C2PMSG_95
-#define MP1_SMN_C2PMSG_95__CONTENT__SHIFT                                                                     0x0
-#define MP1_SMN_C2PMSG_95__CONTENT_MASK                                                                       0xFFFFFFFFL
-//MP1_SMN_C2PMSG_96
-#define MP1_SMN_C2PMSG_96__CONTENT__SHIFT                                                                     0x0
-#define MP1_SMN_C2PMSG_96__CONTENT_MASK                                                                       0xFFFFFFFFL
-//MP1_SMN_C2PMSG_97
-#define MP1_SMN_C2PMSG_97__CONTENT__SHIFT                                                                     0x0
-#define MP1_SMN_C2PMSG_97__CONTENT_MASK                                                                       0xFFFFFFFFL
-//MP1_SMN_C2PMSG_98
-#define MP1_SMN_C2PMSG_98__CONTENT__SHIFT                                                                     0x0
-#define MP1_SMN_C2PMSG_98__CONTENT_MASK                                                                       0xFFFFFFFFL
-//MP1_SMN_C2PMSG_99
-#define MP1_SMN_C2PMSG_99__CONTENT__SHIFT                                                                     0x0
-#define MP1_SMN_C2PMSG_99__CONTENT_MASK                                                                       0xFFFFFFFFL
-//MP1_SMN_C2PMSG_100
-#define MP1_SMN_C2PMSG_100__CONTENT__SHIFT                                                                    0x0
-#define MP1_SMN_C2PMSG_100__CONTENT_MASK                                                                      0xFFFFFFFFL
-//MP1_SMN_C2PMSG_101
-#define MP1_SMN_C2PMSG_101__CONTENT__SHIFT                                                                    0x0
-#define MP1_SMN_C2PMSG_101__CONTENT_MASK                                                                      0xFFFFFFFFL
-//MP1_SMN_C2PMSG_102
-#define MP1_SMN_C2PMSG_102__CONTENT__SHIFT                                                                    0x0
-#define MP1_SMN_C2PMSG_102__CONTENT_MASK                                                                      0xFFFFFFFFL
-//MP1_SMN_C2PMSG_103
-#define MP1_SMN_C2PMSG_103__CONTENT__SHIFT                                                                    0x0
-#define MP1_SMN_C2PMSG_103__CONTENT_MASK                                                                      0xFFFFFFFFL
-//MP1_SMN_IH_CREDIT
-#define MP1_SMN_IH_CREDIT__CREDIT_VALUE__SHIFT                                                                0x0
-#define MP1_SMN_IH_CREDIT__CLIENT_ID__SHIFT                                                                   0x10
-#define MP1_SMN_IH_CREDIT__CREDIT_VALUE_MASK                                                                  0x00000003L
-#define MP1_SMN_IH_CREDIT__CLIENT_ID_MASK                                                                     0x00FF0000L
-//MP1_SMN_IH_SW_INT
-#define MP1_SMN_IH_SW_INT__ID__SHIFT                                                                          0x0
-#define MP1_SMN_IH_SW_INT__VALID__SHIFT                                                                       0x8
-#define MP1_SMN_IH_SW_INT__ID_MASK                                                                            0x000000FFL
-#define MP1_SMN_IH_SW_INT__VALID_MASK                                                                         0x00000100L
-//MP1_SMN_IH_SW_INT_CTRL
-#define MP1_SMN_IH_SW_INT_CTRL__INT_MASK__SHIFT                                                               0x0
-#define MP1_SMN_IH_SW_INT_CTRL__INT_ACK__SHIFT                                                                0x8
-#define MP1_SMN_IH_SW_INT_CTRL__INT_MASK_MASK                                                                 0x00000001L
-#define MP1_SMN_IH_SW_INT_CTRL__INT_ACK_MASK                                                                  0x00000100L
-//MP1_SMN_FPS_CNT
-#define MP1_SMN_FPS_CNT__COUNT__SHIFT                                                                         0x0
-#define MP1_SMN_FPS_CNT__COUNT_MASK                                                                           0xFFFFFFFFL
-//MP1_SMN_EXT_SCRATCH0
-#define MP1_SMN_EXT_SCRATCH0__DATA__SHIFT                                                                     0x0
-#define MP1_SMN_EXT_SCRATCH0__DATA_MASK                                                                       0xFFFFFFFFL
-//MP1_SMN_EXT_SCRATCH1
-#define MP1_SMN_EXT_SCRATCH1__DATA__SHIFT                                                                     0x0
-#define MP1_SMN_EXT_SCRATCH1__DATA_MASK                                                                       0xFFFFFFFFL
-//MP1_SMN_EXT_SCRATCH2
-#define MP1_SMN_EXT_SCRATCH2__DATA__SHIFT                                                                     0x0
-#define MP1_SMN_EXT_SCRATCH2__DATA_MASK                                                                       0xFFFFFFFFL
-//MP1_SMN_EXT_SCRATCH3
-#define MP1_SMN_EXT_SCRATCH3__DATA__SHIFT                                                                     0x0
-#define MP1_SMN_EXT_SCRATCH3__DATA_MASK                                                                       0xFFFFFFFFL
-//MP1_SMN_EXT_SCRATCH4
-#define MP1_SMN_EXT_SCRATCH4__DATA__SHIFT                                                                     0x0
-#define MP1_SMN_EXT_SCRATCH4__DATA_MASK                                                                       0xFFFFFFFFL
-//MP1_SMN_EXT_SCRATCH5
-#define MP1_SMN_EXT_SCRATCH5__DATA__SHIFT                                                                     0x0
-#define MP1_SMN_EXT_SCRATCH5__DATA_MASK                                                                       0xFFFFFFFFL
-//MP1_SMN_EXT_SCRATCH6
-#define MP1_SMN_EXT_SCRATCH6__DATA__SHIFT                                                                     0x0
-#define MP1_SMN_EXT_SCRATCH6__DATA_MASK                                                                       0xFFFFFFFFL
-//MP1_SMN_EXT_SCRATCH7
-#define MP1_SMN_EXT_SCRATCH7__DATA__SHIFT                                                                     0x0
-#define MP1_SMN_EXT_SCRATCH7__DATA_MASK                                                                       0xFFFFFFFFL
-
-
-#endif
index 6119a36..3fea243 100644 (file)
@@ -26,6 +26,7 @@
 #include "amdgpu_smu.h"
 
 #define SMU13_DRIVER_IF_VERSION_INV 0xFFFFFFFF
+#define SMU13_DRIVER_IF_VERSION_YELLOW_CARP 0x03
 #define SMU13_DRIVER_IF_VERSION_ALDE 0x07
 
 /* MP Apertures */
diff --git a/drivers/gpu/drm/amd/pm/inc/smu_v13_0_1.h b/drivers/gpu/drm/amd/pm/inc/smu_v13_0_1.h
deleted file mode 100644 (file)
index b6c976a..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright 2020 Advanced Micro Devices, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- */
-#ifndef __SMU_V13_0_1_H__
-#define __SMU_V13_0_1_H__
-
-#include "amdgpu_smu.h"
-
-#define SMU13_0_1_DRIVER_IF_VERSION_INV 0xFFFFFFFF
-#define SMU13_0_1_DRIVER_IF_VERSION_YELLOW_CARP 0x3
-
-/* MP Apertures */
-#define MP0_Public                     0x03800000
-#define MP0_SRAM                       0x03900000
-#define MP1_Public                     0x03b00000
-#define MP1_SRAM                       0x03c00004
-
-/* address block */
-#define smnMP1_FIRMWARE_FLAGS          0x3010024
-
-
-#if defined(SWSMU_CODE_LAYER_L2) || defined(SWSMU_CODE_LAYER_L3)
-
-int smu_v13_0_1_check_fw_status(struct smu_context *smu);
-
-int smu_v13_0_1_check_fw_version(struct smu_context *smu);
-
-int smu_v13_0_1_fini_smc_tables(struct smu_context *smu);
-
-int smu_v13_0_1_get_vbios_bootup_values(struct smu_context *smu);
-
-int smu_v13_0_1_set_default_dpm_tables(struct smu_context *smu);
-
-int smu_v13_0_1_set_driver_table_location(struct smu_context *smu);
-
-int smu_v13_0_1_gfx_off_control(struct smu_context *smu, bool enable);
-#endif
-#endif
index 388c5cb..0a5d46a 100644 (file)
@@ -1528,6 +1528,7 @@ int smu_v11_0_baco_set_state(struct smu_context *smu, enum smu_baco_state state)
                case CHIP_SIENNA_CICHLID:
                case CHIP_NAVY_FLOUNDER:
                case CHIP_DIMGREY_CAVEFISH:
+               case CHIP_BEIGE_GOBY:
                        if (amdgpu_runtime_pm == 2)
                                ret = smu_cmn_send_smc_msg_with_param(smu,
                                                                      SMU_MSG_EnterBaco,
index 9b3a850..d4c4c49 100644 (file)
@@ -23,7 +23,7 @@
 # Makefile for the 'smu manager' sub-component of powerplay.
 # It provides the smu management services for the driver.
 
-SMU13_MGR = smu_v13_0.o aldebaran_ppt.o smu_v13_0_1.o yellow_carp_ppt.o
+SMU13_MGR = smu_v13_0.o aldebaran_ppt.o yellow_carp_ppt.o
 
 AMD_SWSMU_SMU13MGR = $(addprefix $(AMD_SWSMU_PATH)/smu13/,$(SMU13_MGR))
 
index a3dc719..a421ba8 100644 (file)
@@ -210,6 +210,9 @@ int smu_v13_0_check_fw_version(struct smu_context *smu)
        case CHIP_ALDEBARAN:
                smu->smc_driver_if_version = SMU13_DRIVER_IF_VERSION_ALDE;
                break;
+       case CHIP_YELLOW_CARP:
+               smu->smc_driver_if_version = SMU13_DRIVER_IF_VERSION_YELLOW_CARP;
+               break;
        default:
                dev_err(smu->adev->dev, "smu unsupported asic type:%d.\n", smu->adev->asic_type);
                smu->smc_driver_if_version = SMU13_DRIVER_IF_VERSION_INV;
@@ -694,6 +697,27 @@ failed:
        return ret;
 }
 
+int smu_v13_0_gfx_off_control(struct smu_context *smu, bool enable)
+{
+       int ret = 0;
+       struct amdgpu_device *adev = smu->adev;
+
+       switch (adev->asic_type) {
+       case CHIP_YELLOW_CARP:
+               if (!(adev->pm.pp_feature & PP_GFXOFF_MASK))
+                       return 0;
+               if (enable)
+                       ret = smu_cmn_send_smc_msg(smu, SMU_MSG_AllowGfxOff, NULL);
+               else
+                       ret = smu_cmn_send_smc_msg(smu, SMU_MSG_DisallowGfxOff, NULL);
+               break;
+       default:
+               break;
+       }
+
+       return ret;
+}
+
 int smu_v13_0_system_features_control(struct smu_context *smu,
                                      bool en)
 {
diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_1.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_1.c
deleted file mode 100644 (file)
index 61917b4..0000000
+++ /dev/null
@@ -1,311 +0,0 @@
-/*
- * Copyright 2020 Advanced Micro Devices, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- */
-
-//#include <linux/reboot.h>
-
-#define SWSMU_CODE_LAYER_L3
-
-#include "amdgpu.h"
-#include "amdgpu_smu.h"
-#include "smu_v13_0_1.h"
-#include "soc15_common.h"
-#include "smu_cmn.h"
-#include "atomfirmware.h"
-#include "amdgpu_atomfirmware.h"
-#include "amdgpu_atombios.h"
-#include "atom.h"
-
-#include "asic_reg/mp/mp_13_0_1_offset.h"
-#include "asic_reg/mp/mp_13_0_1_sh_mask.h"
-
-/*
- * DO NOT use these for err/warn/info/debug messages.
- * Use dev_err, dev_warn, dev_info and dev_dbg instead.
- * They are more MGPU friendly.
- */
-#undef pr_err
-#undef pr_warn
-#undef pr_info
-#undef pr_debug
-
-int smu_v13_0_1_check_fw_status(struct smu_context *smu)
-{
-       struct amdgpu_device *adev = smu->adev;
-       uint32_t mp1_fw_flags;
-
-       mp1_fw_flags = RREG32_PCIE(MP1_Public |
-                                  (smnMP1_FIRMWARE_FLAGS & 0xffffffff));
-
-       if ((mp1_fw_flags & MP1_FIRMWARE_FLAGS__INTERRUPTS_ENABLED_MASK) >>
-           MP1_FIRMWARE_FLAGS__INTERRUPTS_ENABLED__SHIFT)
-               return 0;
-
-       return -EIO;
-}
-
-int smu_v13_0_1_check_fw_version(struct smu_context *smu)
-{
-       uint32_t if_version = 0xff, smu_version = 0xff;
-       uint16_t smu_major;
-       uint8_t smu_minor, smu_debug;
-       int ret = 0;
-
-       ret = smu_cmn_get_smc_version(smu, &if_version, &smu_version);
-       if (ret)
-               return ret;
-
-       smu_major = (smu_version >> 16) & 0xffff;
-       smu_minor = (smu_version >> 8) & 0xff;
-       smu_debug = (smu_version >> 0) & 0xff;
-
-       switch (smu->adev->asic_type) {
-       case CHIP_YELLOW_CARP:
-               smu->smc_driver_if_version = SMU13_0_1_DRIVER_IF_VERSION_YELLOW_CARP;
-               break;
-
-       default:
-               dev_err(smu->adev->dev, "smu unsupported asic type:%d.\n", smu->adev->asic_type);
-               smu->smc_driver_if_version = SMU13_0_1_DRIVER_IF_VERSION_INV;
-               break;
-       }
-
-       dev_info(smu->adev->dev, "smu fw reported version = 0x%08x (%d.%d.%d)\n",
-                        smu_version, smu_major, smu_minor, smu_debug);
-
-       /*
-        * 1. if_version mismatch is not critical as our fw is designed
-        * to be backward compatible.
-        * 2. New fw usually brings some optimizations. But that's visible
-        * only on the paired driver.
-        * Considering above, we just leave user a warning message instead
-        * of halt driver loading.
-        */
-       if (if_version != smu->smc_driver_if_version) {
-               dev_info(smu->adev->dev, "smu driver if version = 0x%08x, smu fw if version = 0x%08x, "
-                        "smu fw version = 0x%08x (%d.%d.%d)\n",
-                        smu->smc_driver_if_version, if_version,
-                        smu_version, smu_major, smu_minor, smu_debug);
-               dev_warn(smu->adev->dev, "SMU driver if version not matched\n");
-       }
-
-       return ret;
-}
-
-int smu_v13_0_1_fini_smc_tables(struct smu_context *smu)
-{
-       struct smu_table_context *smu_table = &smu->smu_table;
-
-       kfree(smu_table->clocks_table);
-       smu_table->clocks_table = NULL;
-
-       kfree(smu_table->metrics_table);
-       smu_table->metrics_table = NULL;
-
-       kfree(smu_table->watermarks_table);
-       smu_table->watermarks_table = NULL;
-
-       return 0;
-}
-
-static int smu_v13_0_1_atom_get_smu_clockinfo(struct amdgpu_device *adev,
-                                               uint8_t clk_id,
-                                               uint8_t syspll_id,
-                                               uint32_t *clk_freq)
-{
-       struct atom_get_smu_clock_info_parameters_v3_1 input = {0};
-       struct atom_get_smu_clock_info_output_parameters_v3_1 *output;
-       int ret, index;
-
-       input.clk_id = clk_id;
-       input.syspll_id = syspll_id;
-       input.command = GET_SMU_CLOCK_INFO_V3_1_GET_CLOCK_FREQ;
-       index = get_index_into_master_table(atom_master_list_of_command_functions_v2_1,
-                                           getsmuclockinfo);
-
-       ret = amdgpu_atom_execute_table(adev->mode_info.atom_context, index,
-                                       (uint32_t *)&input);
-       if (ret)
-               return -EINVAL;
-
-       output = (struct atom_get_smu_clock_info_output_parameters_v3_1 *)&input;
-       *clk_freq = le32_to_cpu(output->atom_smu_outputclkfreq.smu_clock_freq_hz) / 10000;
-
-       return 0;
-}
-
-int smu_v13_0_1_get_vbios_bootup_values(struct smu_context *smu)
-{
-       int ret, index;
-       uint16_t size;
-       uint8_t frev, crev;
-       struct atom_common_table_header *header;
-       struct atom_firmware_info_v3_4 *v_3_4;
-       struct atom_firmware_info_v3_3 *v_3_3;
-       struct atom_firmware_info_v3_1 *v_3_1;
-
-       index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1,
-                                           firmwareinfo);
-
-       ret = amdgpu_atombios_get_data_table(smu->adev, index, &size, &frev, &crev,
-                                            (uint8_t **)&header);
-       if (ret)
-               return ret;
-
-       if (header->format_revision != 3) {
-               dev_err(smu->adev->dev, "unknown atom_firmware_info version! for smu13\n");
-               return -EINVAL;
-       }
-
-       switch (header->content_revision) {
-       case 0:
-       case 1:
-       case 2:
-               v_3_1 = (struct atom_firmware_info_v3_1 *)header;
-               smu->smu_table.boot_values.revision = v_3_1->firmware_revision;
-               smu->smu_table.boot_values.gfxclk = v_3_1->bootup_sclk_in10khz;
-               smu->smu_table.boot_values.uclk = v_3_1->bootup_mclk_in10khz;
-               smu->smu_table.boot_values.socclk = 0;
-               smu->smu_table.boot_values.dcefclk = 0;
-               smu->smu_table.boot_values.vddc = v_3_1->bootup_vddc_mv;
-               smu->smu_table.boot_values.vddci = v_3_1->bootup_vddci_mv;
-               smu->smu_table.boot_values.mvddc = v_3_1->bootup_mvddc_mv;
-               smu->smu_table.boot_values.vdd_gfx = v_3_1->bootup_vddgfx_mv;
-               smu->smu_table.boot_values.cooling_id = v_3_1->coolingsolution_id;
-               break;
-       case 3:
-               v_3_3 = (struct atom_firmware_info_v3_3 *)header;
-               smu->smu_table.boot_values.revision = v_3_3->firmware_revision;
-               smu->smu_table.boot_values.gfxclk = v_3_3->bootup_sclk_in10khz;
-               smu->smu_table.boot_values.uclk = v_3_3->bootup_mclk_in10khz;
-               smu->smu_table.boot_values.socclk = 0;
-               smu->smu_table.boot_values.dcefclk = 0;
-               smu->smu_table.boot_values.vddc = v_3_3->bootup_vddc_mv;
-               smu->smu_table.boot_values.vddci = v_3_3->bootup_vddci_mv;
-               smu->smu_table.boot_values.mvddc = v_3_3->bootup_mvddc_mv;
-               smu->smu_table.boot_values.vdd_gfx = v_3_3->bootup_vddgfx_mv;
-               smu->smu_table.boot_values.cooling_id = v_3_3->coolingsolution_id;
-               break;
-       case 4:
-       default:
-               v_3_4 = (struct atom_firmware_info_v3_4 *)header;
-               smu->smu_table.boot_values.revision = v_3_4->firmware_revision;
-               smu->smu_table.boot_values.gfxclk = v_3_4->bootup_sclk_in10khz;
-               smu->smu_table.boot_values.uclk = v_3_4->bootup_mclk_in10khz;
-               smu->smu_table.boot_values.socclk = 0;
-               smu->smu_table.boot_values.dcefclk = 0;
-               smu->smu_table.boot_values.vddc = v_3_4->bootup_vddc_mv;
-               smu->smu_table.boot_values.vddci = v_3_4->bootup_vddci_mv;
-               smu->smu_table.boot_values.mvddc = v_3_4->bootup_mvddc_mv;
-               smu->smu_table.boot_values.vdd_gfx = v_3_4->bootup_vddgfx_mv;
-               smu->smu_table.boot_values.cooling_id = v_3_4->coolingsolution_id;
-               break;
-       }
-
-       smu->smu_table.boot_values.format_revision = header->format_revision;
-       smu->smu_table.boot_values.content_revision = header->content_revision;
-
-       smu_v13_0_1_atom_get_smu_clockinfo(smu->adev,
-                                       (uint8_t)SMU11_SYSPLL0_SOCCLK_ID,
-                                       (uint8_t)0,
-                                       &smu->smu_table.boot_values.socclk);
-
-       smu_v13_0_1_atom_get_smu_clockinfo(smu->adev,
-                                       (uint8_t)SMU11_SYSPLL0_DCEFCLK_ID,
-                                       (uint8_t)0,
-                                       &smu->smu_table.boot_values.dcefclk);
-
-       smu_v13_0_1_atom_get_smu_clockinfo(smu->adev,
-                                       (uint8_t)SMU11_SYSPLL0_ECLK_ID,
-                                       (uint8_t)0,
-                                       &smu->smu_table.boot_values.eclk);
-
-       smu_v13_0_1_atom_get_smu_clockinfo(smu->adev,
-                                       (uint8_t)SMU11_SYSPLL0_VCLK_ID,
-                                       (uint8_t)0,
-                                       &smu->smu_table.boot_values.vclk);
-
-       smu_v13_0_1_atom_get_smu_clockinfo(smu->adev,
-                                       (uint8_t)SMU11_SYSPLL0_DCLK_ID,
-                                       (uint8_t)0,
-                                       &smu->smu_table.boot_values.dclk);
-
-       if ((smu->smu_table.boot_values.format_revision == 3) &&
-           (smu->smu_table.boot_values.content_revision >= 2))
-               smu_v13_0_1_atom_get_smu_clockinfo(smu->adev,
-                                               (uint8_t)SMU11_SYSPLL1_0_FCLK_ID,
-                                               (uint8_t)SMU11_SYSPLL1_2_ID,
-                                               &smu->smu_table.boot_values.fclk);
-
-       return 0;
-}
-
-int smu_v13_0_1_set_default_dpm_tables(struct smu_context *smu)
-{
-       struct smu_table_context *smu_table = &smu->smu_table;
-
-       return smu_cmn_update_table(smu, SMU_TABLE_DPMCLOCKS, 0, smu_table->clocks_table, false);
-}
-
-int smu_v13_0_1_set_driver_table_location(struct smu_context *smu)
-{
-       struct smu_table *driver_table = &smu->smu_table.driver_table;
-       int ret = 0;
-
-       if (!driver_table->mc_address)
-               return 0;
-
-       ret = smu_cmn_send_smc_msg_with_param(smu,
-                       SMU_MSG_SetDriverDramAddrHigh,
-                       upper_32_bits(driver_table->mc_address),
-                       NULL);
-
-       if (ret)
-               return ret;
-
-       ret = smu_cmn_send_smc_msg_with_param(smu,
-                       SMU_MSG_SetDriverDramAddrLow,
-                       lower_32_bits(driver_table->mc_address),
-                       NULL);
-
-       return ret;
-}
-
-int smu_v13_0_1_gfx_off_control(struct smu_context *smu, bool enable)
-{
-       int ret = 0;
-       struct amdgpu_device *adev = smu->adev;
-
-       switch (adev->asic_type) {
-       case CHIP_YELLOW_CARP:
-               if (!(adev->pm.pp_feature & PP_GFXOFF_MASK))
-                       return 0;
-               if (enable)
-                       ret = smu_cmn_send_smc_msg(smu, SMU_MSG_AllowGfxOff, NULL);
-               else
-                       ret = smu_cmn_send_smc_msg(smu, SMU_MSG_DisallowGfxOff, NULL);
-               break;
-       default:
-               break;
-       }
-
-       return ret;
-}
index 18a1ffd..0cfeb9f 100644 (file)
@@ -25,7 +25,7 @@
 
 #include "amdgpu.h"
 #include "amdgpu_smu.h"
-#include "smu_v13_0_1.h"
+#include "smu_v13_0.h"
 #include "smu13_driver_if_yellow_carp.h"
 #include "yellow_carp_ppt.h"
 #include "smu_v13_0_1_ppsmc.h"
@@ -186,6 +186,22 @@ err0_out:
        return -ENOMEM;
 }
 
+static int yellow_carp_fini_smc_tables(struct smu_context *smu)
+{
+       struct smu_table_context *smu_table = &smu->smu_table;
+
+       kfree(smu_table->clocks_table);
+       smu_table->clocks_table = NULL;
+
+       kfree(smu_table->metrics_table);
+       smu_table->metrics_table = NULL;
+
+       kfree(smu_table->watermarks_table);
+       smu_table->watermarks_table = NULL;
+
+       return 0;
+}
+
 static int yellow_carp_system_features_control(struct smu_context *smu, bool en)
 {
        struct smu_feature *feature = &smu->smu_feature;
@@ -282,13 +298,9 @@ static int yellow_carp_mode_reset(struct smu_context *smu, int type)
        if (index < 0)
                return index == -EACCES ? 0 : index;
 
-       mutex_lock(&smu->message_lock);
-
-       ret = smu_cmn_send_msg_without_waiting(smu, (uint16_t)index, type);
-
-       mutex_unlock(&smu->message_lock);
-
-       mdelay(10);
+       ret = smu_cmn_send_smc_msg_with_param(smu, (uint16_t)index, type, NULL);
+       if (ret)
+               dev_err(smu->adev->dev, "Failed to mode reset!\n");
 
        return ret;
 }
@@ -659,6 +671,13 @@ static ssize_t yellow_carp_get_gpu_metrics(struct smu_context *smu,
        return sizeof(struct gpu_metrics_v2_1);
 }
 
+static int yellow_carp_set_default_dpm_tables(struct smu_context *smu)
+{
+       struct smu_table_context *smu_table = &smu->smu_table;
+
+       return smu_cmn_update_table(smu, SMU_TABLE_DPMCLOCKS, 0, smu_table->clocks_table, false);
+}
+
 static int yellow_carp_od_edit_dpm_table(struct smu_context *smu, enum PP_OD_DPM_TABLE_COMMAND type,
                                        long input[], uint32_t size)
 {
@@ -1203,17 +1222,17 @@ static int yellow_carp_set_fine_grain_gfx_freq_parameters(struct smu_context *sm
 }
 
 static const struct pptable_funcs yellow_carp_ppt_funcs = {
-       .check_fw_status = smu_v13_0_1_check_fw_status,
-       .check_fw_version = smu_v13_0_1_check_fw_version,
+       .check_fw_status = smu_v13_0_check_fw_status,
+       .check_fw_version = smu_v13_0_check_fw_version,
        .init_smc_tables = yellow_carp_init_smc_tables,
-       .fini_smc_tables = smu_v13_0_1_fini_smc_tables,
-       .get_vbios_bootup_values = smu_v13_0_1_get_vbios_bootup_values,
+       .fini_smc_tables = yellow_carp_fini_smc_tables,
+       .get_vbios_bootup_values = smu_v13_0_get_vbios_bootup_values,
        .system_features_control = yellow_carp_system_features_control,
        .send_smc_msg_with_param = smu_cmn_send_smc_msg_with_param,
        .send_smc_msg = smu_cmn_send_smc_msg,
        .dpm_set_vcn_enable = yellow_carp_dpm_set_vcn_enable,
        .dpm_set_jpeg_enable = yellow_carp_dpm_set_jpeg_enable,
-       .set_default_dpm_table = smu_v13_0_1_set_default_dpm_tables,
+       .set_default_dpm_table = yellow_carp_set_default_dpm_tables,
        .read_sensor = yellow_carp_read_sensor,
        .is_dpm_running = yellow_carp_is_dpm_running,
        .set_watermarks_table = yellow_carp_set_watermarks_table,
@@ -1222,8 +1241,8 @@ static const struct pptable_funcs yellow_carp_ppt_funcs = {
        .get_gpu_metrics = yellow_carp_get_gpu_metrics,
        .get_enabled_mask = smu_cmn_get_enabled_32_bits_mask,
        .get_pp_feature_mask = smu_cmn_get_pp_feature_mask,
-       .set_driver_table_location = smu_v13_0_1_set_driver_table_location,
-       .gfx_off_control = smu_v13_0_1_gfx_off_control,
+       .set_driver_table_location = smu_v13_0_set_driver_table_location,
+       .gfx_off_control = smu_v13_0_gfx_off_control,
        .post_init = yellow_carp_post_smu_init,
        .mode2_reset = yellow_carp_mode2_reset,
        .get_dpm_ultimate_freq = yellow_carp_get_dpm_ultimate_freq,
index f4fb68e..e382b7f 100644 (file)
@@ -62,6 +62,7 @@ static void try_to_writeback(struct drm_i915_gem_object *obj,
        switch (obj->mm.madv) {
        case I915_MADV_DONTNEED:
                i915_gem_object_truncate(obj);
+               return;
        case __I915_MADV_PURGED:
                return;
        }
index 21c8b73..da4f5eb 100644 (file)
@@ -303,10 +303,7 @@ static void __gen8_ppgtt_alloc(struct i915_address_space * const vm,
                        __i915_gem_object_pin_pages(pt->base);
                        i915_gem_object_make_unshrinkable(pt->base);
 
-                       if (lvl ||
-                           gen8_pt_count(*start, end) < I915_PDES ||
-                           intel_vgpu_active(vm->i915))
-                               fill_px(pt, vm->scratch[lvl]->encode);
+                       fill_px(pt, vm->scratch[lvl]->encode);
 
                        spin_lock(&pd->lock);
                        if (likely(!pd->entry[idx])) {
index cac7f3f..f8948de 100644 (file)
@@ -348,7 +348,7 @@ static struct i915_fence_reg *fence_find(struct i915_ggtt *ggtt)
        if (intel_has_pending_fb_unpin(ggtt->vm.i915))
                return ERR_PTR(-EAGAIN);
 
-       return ERR_PTR(-EDEADLK);
+       return ERR_PTR(-ENOBUFS);
 }
 
 int __i915_vma_pin_fence(struct i915_vma *vma)
index 1411787..1e8a971 100644 (file)
@@ -1169,7 +1169,7 @@ static int msm_gem_new_impl(struct drm_device *dev,
        case MSM_BO_CACHED_COHERENT:
                if (priv->has_cached_coherent)
                        break;
-               /* fallthrough */
+               fallthrough;
        default:
                DRM_DEV_ERROR(dev->dev, "invalid cache flag: %x\n",
                                (flags & MSM_BO_CACHE_MASK));
index ef70140..873cbd3 100644 (file)
@@ -706,9 +706,7 @@ static int nt35510_power_on(struct nt35510 *nt)
        if (ret)
                return ret;
 
-       ret = nt35510_read_id(nt);
-       if (ret)
-               return ret;
+       nt35510_read_id(nt);
 
        /* Set up stuff in  manufacturer control, page 1 */
        ret = nt35510_send_long(nt, dsi, MCS_CMD_MAUCCTR,
index 19fd39d..37a1b6a 100644 (file)
@@ -127,7 +127,7 @@ static void qxl_bo_move_notify(struct ttm_buffer_object *bo,
        struct qxl_bo *qbo;
        struct qxl_device *qdev;
 
-       if (!qxl_ttm_bo_is_qxl_bo(bo))
+       if (!qxl_ttm_bo_is_qxl_bo(bo) || !bo->resource)
                return;
        qbo = to_qxl_bo(bo);
        qdev = to_qxl(qbo->tbo.base.dev);
index 0339538..f4b08a8 100644 (file)
@@ -181,6 +181,9 @@ int ttm_range_man_fini(struct ttm_device *bdev,
        struct drm_mm *mm = &rman->mm;
        int ret;
 
+       if (!man)
+               return 0;
+
        ttm_resource_manager_set_used(man, false);
 
        ret = ttm_resource_manager_evict_all(bdev, man);
index 6f5ea00..45aeeca 100644 (file)
@@ -36,6 +36,7 @@
 #include <drm/drm_ioctl.h>
 #include <drm/drm_sysfs.h>
 #include <drm/ttm/ttm_bo_driver.h>
+#include <drm/ttm/ttm_range_manager.h>
 #include <drm/ttm/ttm_placement.h>
 #include <generated/utsrelease.h>
 
index 5648664..f2d6254 100644 (file)
@@ -354,7 +354,6 @@ static void vmw_otable_batch_takedown(struct vmw_private *dev_priv,
        ttm_bo_unpin(bo);
        ttm_bo_unreserve(bo);
 
-       ttm_bo_unpin(batch->otable_bo);
        ttm_bo_put(batch->otable_bo);
        batch->otable_bo = NULL;
 }
index dd20b01..235f9bd 100644 (file)
@@ -379,6 +379,7 @@ static void arm_smmu_cmdq_skip_err(struct arm_smmu_device *smmu)
        switch (idx) {
        case CMDQ_ERR_CERROR_ABT_IDX:
                dev_err(smmu->dev, "retrying command fetch\n");
+               return;
        case CMDQ_ERR_CERROR_NONE_IDX:
                return;
        case CMDQ_ERR_CERROR_ATC_INV_IDX:
index 25ed444..021cf8f 100644 (file)
@@ -849,12 +849,10 @@ static int qcom_iommu_device_probe(struct platform_device *pdev)
        ret = iommu_device_register(&qcom_iommu->iommu, &qcom_iommu_ops, dev);
        if (ret) {
                dev_err(dev, "Failed to register iommu\n");
-               goto err_sysfs_remove;
+               return ret;
        }
 
-       ret = bus_set_iommu(&platform_bus_type, &qcom_iommu_ops);
-       if (ret)
-               goto err_unregister_device;
+       bus_set_iommu(&platform_bus_type, &qcom_iommu_ops);
 
        if (qcom_iommu->local_base) {
                pm_runtime_get_sync(dev);
@@ -863,13 +861,6 @@ static int qcom_iommu_device_probe(struct platform_device *pdev)
        }
 
        return 0;
-
-err_unregister_device:
-       iommu_device_unregister(&qcom_iommu->iommu);
-
-err_sysfs_remove:
-       iommu_device_sysfs_remove(&qcom_iommu->iommu);
-       return ret;
 }
 
 static int qcom_iommu_device_remove(struct platform_device *pdev)
index a6a07d9..dd22fc7 100644 (file)
@@ -2429,10 +2429,11 @@ __domain_mapping(struct dmar_domain *domain, unsigned long iov_pfn,
        return 0;
 }
 
-static void domain_context_clear_one(struct intel_iommu *iommu, u8 bus, u8 devfn)
+static void domain_context_clear_one(struct device_domain_info *info, u8 bus, u8 devfn)
 {
-       unsigned long flags;
+       struct intel_iommu *iommu = info->iommu;
        struct context_entry *context;
+       unsigned long flags;
        u16 did_old;
 
        if (!iommu)
@@ -2444,7 +2445,16 @@ static void domain_context_clear_one(struct intel_iommu *iommu, u8 bus, u8 devfn
                spin_unlock_irqrestore(&iommu->lock, flags);
                return;
        }
-       did_old = context_domain_id(context);
+
+       if (sm_supported(iommu)) {
+               if (hw_pass_through && domain_type_is_si(info->domain))
+                       did_old = FLPT_DEFAULT_DID;
+               else
+                       did_old = info->domain->iommu_did[iommu->seq_id];
+       } else {
+               did_old = context_domain_id(context);
+       }
+
        context_clear_entry(context);
        __iommu_flush_cache(iommu, context, sizeof(*context));
        spin_unlock_irqrestore(&iommu->lock, flags);
@@ -2462,6 +2472,8 @@ static void domain_context_clear_one(struct intel_iommu *iommu, u8 bus, u8 devfn
                                 0,
                                 0,
                                 DMA_TLB_DSI_FLUSH);
+
+       __iommu_flush_dev_iotlb(info, 0, MAX_AGAW_PFN_WIDTH);
 }
 
 static inline void unlink_domain_info(struct device_domain_info *info)
@@ -4425,9 +4437,9 @@ out_free_dmar:
 
 static int domain_context_clear_one_cb(struct pci_dev *pdev, u16 alias, void *opaque)
 {
-       struct intel_iommu *iommu = opaque;
+       struct device_domain_info *info = opaque;
 
-       domain_context_clear_one(iommu, PCI_BUS_NUM(alias), alias & 0xff);
+       domain_context_clear_one(info, PCI_BUS_NUM(alias), alias & 0xff);
        return 0;
 }
 
@@ -4437,12 +4449,13 @@ static int domain_context_clear_one_cb(struct pci_dev *pdev, u16 alias, void *op
  * devices, unbinding the driver from any one of them will possibly leave
  * the others unable to operate.
  */
-static void domain_context_clear(struct intel_iommu *iommu, struct device *dev)
+static void domain_context_clear(struct device_domain_info *info)
 {
-       if (!iommu || !dev || !dev_is_pci(dev))
+       if (!info->iommu || !info->dev || !dev_is_pci(info->dev))
                return;
 
-       pci_for_each_dma_alias(to_pci_dev(dev), &domain_context_clear_one_cb, iommu);
+       pci_for_each_dma_alias(to_pci_dev(info->dev),
+                              &domain_context_clear_one_cb, info);
 }
 
 static void __dmar_remove_one_dev_info(struct device_domain_info *info)
@@ -4459,14 +4472,13 @@ static void __dmar_remove_one_dev_info(struct device_domain_info *info)
        iommu = info->iommu;
        domain = info->domain;
 
-       if (info->dev) {
+       if (info->dev && !dev_is_real_dma_subdevice(info->dev)) {
                if (dev_is_pci(info->dev) && sm_supported(iommu))
                        intel_pasid_tear_down_entry(iommu, info->dev,
                                        PASID_RID2PASID, false);
 
                iommu_disable_dev_iotlb(info);
-               if (!dev_is_real_dma_subdevice(info->dev))
-                       domain_context_clear(iommu, info->dev);
+               domain_context_clear(info);
                intel_pasid_free_table(info->dev);
        }
 
index 94b9d8e..9febfb7 100644 (file)
@@ -544,12 +544,14 @@ static inline u32 rk_dma_addr_dte(dma_addr_t dt_dma)
 }
 
 #define DT_HI_MASK GENMASK_ULL(39, 32)
+#define DTE_BASE_HI_MASK GENMASK(11, 4)
 #define DT_SHIFT   28
 
 static inline phys_addr_t rk_dte_addr_phys_v2(u32 addr)
 {
-       return (phys_addr_t)(addr & RK_DTE_PT_ADDRESS_MASK) |
-              ((addr & DT_HI_MASK) << DT_SHIFT);
+       u64 addr64 = addr;
+       return (phys_addr_t)(addr64 & RK_DTE_PT_ADDRESS_MASK) |
+              ((addr64 & DTE_BASE_HI_MASK) << DT_SHIFT);
 }
 
 static inline u32 rk_dma_addr_dte_v2(dma_addr_t dt_dma)
index 0db17bc..cb1a64a 100644 (file)
@@ -789,6 +789,8 @@ static irqreturn_t jz_mmc_irq_worker(int irq, void *devid)
                                break;
                        }
                }
+               fallthrough;
+
        case JZ4740_MMC_STATE_DONE:
                break;
        }
index 99b7986..6a6a2a2 100644 (file)
@@ -108,8 +108,8 @@ map_word cfi_build_cmd(u_long cmd, struct map_info *map, struct cfi_private *cfi
 #if BITS_PER_LONG >= 64
        case 8:
                onecmd |= (onecmd << (chip_mode * 32));
-#endif
                fallthrough;
+#endif
        case 4:
                onecmd |= (onecmd << (chip_mode * 16));
                fallthrough;
@@ -164,8 +164,8 @@ unsigned long cfi_merge_status(map_word val, struct map_info *map,
 #if BITS_PER_LONG >= 64
        case 8:
                res |= (onestat >> (chip_mode * 32));
-#endif
                fallthrough;
+#endif
        case 4:
                res |= (onestat >> (chip_mode * 16));
                fallthrough;
index 0ff7567..d22d783 100644 (file)
@@ -401,24 +401,85 @@ static int bond_vlan_rx_kill_vid(struct net_device *bond_dev,
 static int bond_ipsec_add_sa(struct xfrm_state *xs)
 {
        struct net_device *bond_dev = xs->xso.dev;
+       struct bond_ipsec *ipsec;
        struct bonding *bond;
        struct slave *slave;
+       int err;
 
        if (!bond_dev)
                return -EINVAL;
 
+       rcu_read_lock();
        bond = netdev_priv(bond_dev);
        slave = rcu_dereference(bond->curr_active_slave);
-       xs->xso.real_dev = slave->dev;
-       bond->xs = xs;
+       if (!slave) {
+               rcu_read_unlock();
+               return -ENODEV;
+       }
 
-       if (!(slave->dev->xfrmdev_ops
-             && slave->dev->xfrmdev_ops->xdo_dev_state_add)) {
+       if (!slave->dev->xfrmdev_ops ||
+           !slave->dev->xfrmdev_ops->xdo_dev_state_add ||
+           netif_is_bond_master(slave->dev)) {
                slave_warn(bond_dev, slave->dev, "Slave does not support ipsec offload\n");
+               rcu_read_unlock();
                return -EINVAL;
        }
 
-       return slave->dev->xfrmdev_ops->xdo_dev_state_add(xs);
+       ipsec = kmalloc(sizeof(*ipsec), GFP_ATOMIC);
+       if (!ipsec) {
+               rcu_read_unlock();
+               return -ENOMEM;
+       }
+       xs->xso.real_dev = slave->dev;
+
+       err = slave->dev->xfrmdev_ops->xdo_dev_state_add(xs);
+       if (!err) {
+               ipsec->xs = xs;
+               INIT_LIST_HEAD(&ipsec->list);
+               spin_lock_bh(&bond->ipsec_lock);
+               list_add(&ipsec->list, &bond->ipsec_list);
+               spin_unlock_bh(&bond->ipsec_lock);
+       } else {
+               kfree(ipsec);
+       }
+       rcu_read_unlock();
+       return err;
+}
+
+static void bond_ipsec_add_sa_all(struct bonding *bond)
+{
+       struct net_device *bond_dev = bond->dev;
+       struct bond_ipsec *ipsec;
+       struct slave *slave;
+
+       rcu_read_lock();
+       slave = rcu_dereference(bond->curr_active_slave);
+       if (!slave)
+               goto out;
+
+       if (!slave->dev->xfrmdev_ops ||
+           !slave->dev->xfrmdev_ops->xdo_dev_state_add ||
+           netif_is_bond_master(slave->dev)) {
+               spin_lock_bh(&bond->ipsec_lock);
+               if (!list_empty(&bond->ipsec_list))
+                       slave_warn(bond_dev, slave->dev,
+                                  "%s: no slave xdo_dev_state_add\n",
+                                  __func__);
+               spin_unlock_bh(&bond->ipsec_lock);
+               goto out;
+       }
+
+       spin_lock_bh(&bond->ipsec_lock);
+       list_for_each_entry(ipsec, &bond->ipsec_list, list) {
+               ipsec->xs->xso.real_dev = slave->dev;
+               if (slave->dev->xfrmdev_ops->xdo_dev_state_add(ipsec->xs)) {
+                       slave_warn(bond_dev, slave->dev, "%s: failed to add SA\n", __func__);
+                       ipsec->xs->xso.real_dev = NULL;
+               }
+       }
+       spin_unlock_bh(&bond->ipsec_lock);
+out:
+       rcu_read_unlock();
 }
 
 /**
@@ -428,27 +489,77 @@ static int bond_ipsec_add_sa(struct xfrm_state *xs)
 static void bond_ipsec_del_sa(struct xfrm_state *xs)
 {
        struct net_device *bond_dev = xs->xso.dev;
+       struct bond_ipsec *ipsec;
        struct bonding *bond;
        struct slave *slave;
 
        if (!bond_dev)
                return;
 
+       rcu_read_lock();
        bond = netdev_priv(bond_dev);
        slave = rcu_dereference(bond->curr_active_slave);
 
        if (!slave)
-               return;
+               goto out;
 
-       xs->xso.real_dev = slave->dev;
+       if (!xs->xso.real_dev)
+               goto out;
+
+       WARN_ON(xs->xso.real_dev != slave->dev);
 
-       if (!(slave->dev->xfrmdev_ops
-             && slave->dev->xfrmdev_ops->xdo_dev_state_delete)) {
+       if (!slave->dev->xfrmdev_ops ||
+           !slave->dev->xfrmdev_ops->xdo_dev_state_delete ||
+           netif_is_bond_master(slave->dev)) {
                slave_warn(bond_dev, slave->dev, "%s: no slave xdo_dev_state_delete\n", __func__);
-               return;
+               goto out;
        }
 
        slave->dev->xfrmdev_ops->xdo_dev_state_delete(xs);
+out:
+       spin_lock_bh(&bond->ipsec_lock);
+       list_for_each_entry(ipsec, &bond->ipsec_list, list) {
+               if (ipsec->xs == xs) {
+                       list_del(&ipsec->list);
+                       kfree(ipsec);
+                       break;
+               }
+       }
+       spin_unlock_bh(&bond->ipsec_lock);
+       rcu_read_unlock();
+}
+
+static void bond_ipsec_del_sa_all(struct bonding *bond)
+{
+       struct net_device *bond_dev = bond->dev;
+       struct bond_ipsec *ipsec;
+       struct slave *slave;
+
+       rcu_read_lock();
+       slave = rcu_dereference(bond->curr_active_slave);
+       if (!slave) {
+               rcu_read_unlock();
+               return;
+       }
+
+       spin_lock_bh(&bond->ipsec_lock);
+       list_for_each_entry(ipsec, &bond->ipsec_list, list) {
+               if (!ipsec->xs->xso.real_dev)
+                       continue;
+
+               if (!slave->dev->xfrmdev_ops ||
+                   !slave->dev->xfrmdev_ops->xdo_dev_state_delete ||
+                   netif_is_bond_master(slave->dev)) {
+                       slave_warn(bond_dev, slave->dev,
+                                  "%s: no slave xdo_dev_state_delete\n",
+                                  __func__);
+               } else {
+                       slave->dev->xfrmdev_ops->xdo_dev_state_delete(ipsec->xs);
+               }
+               ipsec->xs->xso.real_dev = NULL;
+       }
+       spin_unlock_bh(&bond->ipsec_lock);
+       rcu_read_unlock();
 }
 
 /**
@@ -459,21 +570,37 @@ static void bond_ipsec_del_sa(struct xfrm_state *xs)
 static bool bond_ipsec_offload_ok(struct sk_buff *skb, struct xfrm_state *xs)
 {
        struct net_device *bond_dev = xs->xso.dev;
-       struct bonding *bond = netdev_priv(bond_dev);
-       struct slave *curr_active = rcu_dereference(bond->curr_active_slave);
-       struct net_device *slave_dev = curr_active->dev;
+       struct net_device *real_dev;
+       struct slave *curr_active;
+       struct bonding *bond;
+       int err;
 
-       if (BOND_MODE(bond) != BOND_MODE_ACTIVEBACKUP)
-               return true;
+       bond = netdev_priv(bond_dev);
+       rcu_read_lock();
+       curr_active = rcu_dereference(bond->curr_active_slave);
+       real_dev = curr_active->dev;
 
-       if (!(slave_dev->xfrmdev_ops
-             && slave_dev->xfrmdev_ops->xdo_dev_offload_ok)) {
-               slave_warn(bond_dev, slave_dev, "%s: no slave xdo_dev_offload_ok\n", __func__);
-               return false;
+       if (BOND_MODE(bond) != BOND_MODE_ACTIVEBACKUP) {
+               err = false;
+               goto out;
        }
 
-       xs->xso.real_dev = slave_dev;
-       return slave_dev->xfrmdev_ops->xdo_dev_offload_ok(skb, xs);
+       if (!xs->xso.real_dev) {
+               err = false;
+               goto out;
+       }
+
+       if (!real_dev->xfrmdev_ops ||
+           !real_dev->xfrmdev_ops->xdo_dev_offload_ok ||
+           netif_is_bond_master(real_dev)) {
+               err = false;
+               goto out;
+       }
+
+       err = real_dev->xfrmdev_ops->xdo_dev_offload_ok(skb, xs);
+out:
+       rcu_read_unlock();
+       return err;
 }
 
 static const struct xfrmdev_ops bond_xfrmdev_ops = {
@@ -990,8 +1117,7 @@ void bond_change_active_slave(struct bonding *bond, struct slave *new_active)
                return;
 
 #ifdef CONFIG_XFRM_OFFLOAD
-       if (old_active && bond->xs)
-               bond_ipsec_del_sa(bond->xs);
+       bond_ipsec_del_sa_all(bond);
 #endif /* CONFIG_XFRM_OFFLOAD */
 
        if (new_active) {
@@ -1066,10 +1192,7 @@ void bond_change_active_slave(struct bonding *bond, struct slave *new_active)
        }
 
 #ifdef CONFIG_XFRM_OFFLOAD
-       if (new_active && bond->xs) {
-               xfrm_dev_state_flush(dev_net(bond->dev), bond->dev, true);
-               bond_ipsec_add_sa(bond->xs);
-       }
+       bond_ipsec_add_sa_all(bond);
 #endif /* CONFIG_XFRM_OFFLOAD */
 
        /* resend IGMP joins since active slave has changed or
@@ -3327,6 +3450,7 @@ static int bond_master_netdev_event(unsigned long event,
                return bond_event_changename(event_bond);
        case NETDEV_UNREGISTER:
                bond_remove_proc_entry(event_bond);
+               xfrm_dev_state_flush(dev_net(bond_dev), bond_dev, true);
                break;
        case NETDEV_REGISTER:
                bond_create_proc_entry(event_bond);
@@ -4894,7 +5018,8 @@ void bond_setup(struct net_device *bond_dev)
 #ifdef CONFIG_XFRM_OFFLOAD
        /* set up xfrm device ops (only supported in active-backup right now) */
        bond_dev->xfrmdev_ops = &bond_xfrmdev_ops;
-       bond->xs = NULL;
+       INIT_LIST_HEAD(&bond->ipsec_list);
+       spin_lock_init(&bond->ipsec_lock);
 #endif /* CONFIG_XFRM_OFFLOAD */
 
        /* don't acquire bond device's netif_tx_lock when transmitting */
index a77124b..709660c 100644 (file)
@@ -20,15 +20,6 @@ config CAIF_TTY
          identified as N_CAIF. When this ldisc is opened from user space
          it will redirect the TTY's traffic into the CAIF stack.
 
-config CAIF_HSI
-       tristate "CAIF HSI transport driver"
-       depends on CAIF
-       default n
-       help
-         The CAIF low level driver for CAIF over HSI.
-         Be aware that if you enable this then you also need to
-         enable a low-level HSI driver.
-
 config CAIF_VIRTIO
        tristate "CAIF virtio transport driver"
        depends on CAIF && HAS_DMA
index b1918c8..97f664f 100644 (file)
@@ -4,8 +4,5 @@ ccflags-$(CONFIG_CAIF_DEBUG) := -DDEBUG
 # Serial interface
 obj-$(CONFIG_CAIF_TTY) += caif_serial.o
 
-# HSI interface
-obj-$(CONFIG_CAIF_HSI) += caif_hsi.o
-
 # Virtio interface
 obj-$(CONFIG_CAIF_VIRTIO) += caif_virtio.o
diff --git a/drivers/net/caif/caif_hsi.c b/drivers/net/caif/caif_hsi.c
deleted file mode 100644 (file)
index 3d63b15..0000000
+++ /dev/null
@@ -1,1454 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Copyright (C) ST-Ericsson AB 2010
- * Author:  Daniel Martensson
- *         Dmitry.Tarnyagin  / dmitry.tarnyagin@lockless.no
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME fmt
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/device.h>
-#include <linux/netdevice.h>
-#include <linux/string.h>
-#include <linux/list.h>
-#include <linux/interrupt.h>
-#include <linux/delay.h>
-#include <linux/sched.h>
-#include <linux/if_arp.h>
-#include <linux/timer.h>
-#include <net/rtnetlink.h>
-#include <linux/pkt_sched.h>
-#include <net/caif/caif_layer.h>
-#include <net/caif/caif_hsi.h>
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Daniel Martensson");
-MODULE_DESCRIPTION("CAIF HSI driver");
-
-/* Returns the number of padding bytes for alignment. */
-#define PAD_POW2(x, pow) ((((x)&((pow)-1)) == 0) ? 0 :\
-                               (((pow)-((x)&((pow)-1)))))
-
-static const struct cfhsi_config  hsi_default_config = {
-
-       /* Inactivity timeout on HSI, ms */
-       .inactivity_timeout = HZ,
-
-       /* Aggregation timeout (ms) of zero means no aggregation is done*/
-       .aggregation_timeout = 1,
-
-       /*
-        * HSI link layer flow-control thresholds.
-        * Threshold values for the HSI packet queue. Flow-control will be
-        * asserted when the number of packets exceeds q_high_mark. It will
-        * not be de-asserted before the number of packets drops below
-        * q_low_mark.
-        * Warning: A high threshold value might increase throughput but it
-        * will at the same time prevent channel prioritization and increase
-        * the risk of flooding the modem. The high threshold should be above
-        * the low.
-        */
-       .q_high_mark = 100,
-       .q_low_mark = 50,
-
-       /*
-        * HSI padding options.
-        * Warning: must be a base of 2 (& operation used) and can not be zero !
-        */
-       .head_align = 4,
-       .tail_align = 4,
-};
-
-#define ON 1
-#define OFF 0
-
-static LIST_HEAD(cfhsi_list);
-
-static void cfhsi_inactivity_tout(struct timer_list *t)
-{
-       struct cfhsi *cfhsi = from_timer(cfhsi, t, inactivity_timer);
-
-       netdev_dbg(cfhsi->ndev, "%s.\n",
-               __func__);
-
-       /* Schedule power down work queue. */
-       if (!test_bit(CFHSI_SHUTDOWN, &cfhsi->bits))
-               queue_work(cfhsi->wq, &cfhsi->wake_down_work);
-}
-
-static void cfhsi_update_aggregation_stats(struct cfhsi *cfhsi,
-                                          const struct sk_buff *skb,
-                                          int direction)
-{
-       struct caif_payload_info *info;
-       int hpad, tpad, len;
-
-       info = (struct caif_payload_info *)&skb->cb;
-       hpad = 1 + PAD_POW2((info->hdr_len + 1), cfhsi->cfg.head_align);
-       tpad = PAD_POW2((skb->len + hpad), cfhsi->cfg.tail_align);
-       len = skb->len + hpad + tpad;
-
-       if (direction > 0)
-               cfhsi->aggregation_len += len;
-       else if (direction < 0)
-               cfhsi->aggregation_len -= len;
-}
-
-static bool cfhsi_can_send_aggregate(struct cfhsi *cfhsi)
-{
-       int i;
-
-       if (cfhsi->cfg.aggregation_timeout == 0)
-               return true;
-
-       for (i = 0; i < CFHSI_PRIO_BEBK; ++i) {
-               if (cfhsi->qhead[i].qlen)
-                       return true;
-       }
-
-       /* TODO: Use aggregation_len instead */
-       if (cfhsi->qhead[CFHSI_PRIO_BEBK].qlen >= CFHSI_MAX_PKTS)
-               return true;
-
-       return false;
-}
-
-static struct sk_buff *cfhsi_dequeue(struct cfhsi *cfhsi)
-{
-       struct sk_buff *skb;
-       int i;
-
-       for (i = 0; i < CFHSI_PRIO_LAST; ++i) {
-               skb = skb_dequeue(&cfhsi->qhead[i]);
-               if (skb)
-                       break;
-       }
-
-       return skb;
-}
-
-static int cfhsi_tx_queue_len(struct cfhsi *cfhsi)
-{
-       int i, len = 0;
-       for (i = 0; i < CFHSI_PRIO_LAST; ++i)
-               len += skb_queue_len(&cfhsi->qhead[i]);
-       return len;
-}
-
-static void cfhsi_abort_tx(struct cfhsi *cfhsi)
-{
-       struct sk_buff *skb;
-
-       for (;;) {
-               spin_lock_bh(&cfhsi->lock);
-               skb = cfhsi_dequeue(cfhsi);
-               if (!skb)
-                       break;
-
-               cfhsi->ndev->stats.tx_errors++;
-               cfhsi->ndev->stats.tx_dropped++;
-               cfhsi_update_aggregation_stats(cfhsi, skb, -1);
-               spin_unlock_bh(&cfhsi->lock);
-               kfree_skb(skb);
-       }
-       cfhsi->tx_state = CFHSI_TX_STATE_IDLE;
-       if (!test_bit(CFHSI_SHUTDOWN, &cfhsi->bits))
-               mod_timer(&cfhsi->inactivity_timer,
-                       jiffies + cfhsi->cfg.inactivity_timeout);
-       spin_unlock_bh(&cfhsi->lock);
-}
-
-static int cfhsi_flush_fifo(struct cfhsi *cfhsi)
-{
-       char buffer[32]; /* Any reasonable value */
-       size_t fifo_occupancy;
-       int ret;
-
-       netdev_dbg(cfhsi->ndev, "%s.\n",
-               __func__);
-
-       do {
-               ret = cfhsi->ops->cfhsi_fifo_occupancy(cfhsi->ops,
-                               &fifo_occupancy);
-               if (ret) {
-                       netdev_warn(cfhsi->ndev,
-                               "%s: can't get FIFO occupancy: %d.\n",
-                               __func__, ret);
-                       break;
-               } else if (!fifo_occupancy)
-                       /* No more data, exitting normally */
-                       break;
-
-               fifo_occupancy = min(sizeof(buffer), fifo_occupancy);
-               set_bit(CFHSI_FLUSH_FIFO, &cfhsi->bits);
-               ret = cfhsi->ops->cfhsi_rx(buffer, fifo_occupancy,
-                               cfhsi->ops);
-               if (ret) {
-                       clear_bit(CFHSI_FLUSH_FIFO, &cfhsi->bits);
-                       netdev_warn(cfhsi->ndev,
-                               "%s: can't read data: %d.\n",
-                               __func__, ret);
-                       break;
-               }
-
-               ret = 5 * HZ;
-               ret = wait_event_interruptible_timeout(cfhsi->flush_fifo_wait,
-                        !test_bit(CFHSI_FLUSH_FIFO, &cfhsi->bits), ret);
-
-               if (ret < 0) {
-                       netdev_warn(cfhsi->ndev,
-                               "%s: can't wait for flush complete: %d.\n",
-                               __func__, ret);
-                       break;
-               } else if (!ret) {
-                       ret = -ETIMEDOUT;
-                       netdev_warn(cfhsi->ndev,
-                               "%s: timeout waiting for flush complete.\n",
-                               __func__);
-                       break;
-               }
-       } while (1);
-
-       return ret;
-}
-
-static int cfhsi_tx_frm(struct cfhsi_desc *desc, struct cfhsi *cfhsi)
-{
-       int nfrms = 0;
-       int pld_len = 0;
-       struct sk_buff *skb;
-       u8 *pfrm = desc->emb_frm + CFHSI_MAX_EMB_FRM_SZ;
-
-       skb = cfhsi_dequeue(cfhsi);
-       if (!skb)
-               return 0;
-
-       /* Clear offset. */
-       desc->offset = 0;
-
-       /* Check if we can embed a CAIF frame. */
-       if (skb->len < CFHSI_MAX_EMB_FRM_SZ) {
-               struct caif_payload_info *info;
-               int hpad;
-               int tpad;
-
-               /* Calculate needed head alignment and tail alignment. */
-               info = (struct caif_payload_info *)&skb->cb;
-
-               hpad = 1 + PAD_POW2((info->hdr_len + 1), cfhsi->cfg.head_align);
-               tpad = PAD_POW2((skb->len + hpad), cfhsi->cfg.tail_align);
-
-               /* Check if frame still fits with added alignment. */
-               if ((skb->len + hpad + tpad) <= CFHSI_MAX_EMB_FRM_SZ) {
-                       u8 *pemb = desc->emb_frm;
-                       desc->offset = CFHSI_DESC_SHORT_SZ;
-                       *pemb = (u8)(hpad - 1);
-                       pemb += hpad;
-
-                       /* Update network statistics. */
-                       spin_lock_bh(&cfhsi->lock);
-                       cfhsi->ndev->stats.tx_packets++;
-                       cfhsi->ndev->stats.tx_bytes += skb->len;
-                       cfhsi_update_aggregation_stats(cfhsi, skb, -1);
-                       spin_unlock_bh(&cfhsi->lock);
-
-                       /* Copy in embedded CAIF frame. */
-                       skb_copy_bits(skb, 0, pemb, skb->len);
-
-                       /* Consume the SKB */
-                       consume_skb(skb);
-                       skb = NULL;
-               }
-       }
-
-       /* Create payload CAIF frames. */
-       while (nfrms < CFHSI_MAX_PKTS) {
-               struct caif_payload_info *info;
-               int hpad;
-               int tpad;
-
-               if (!skb)
-                       skb = cfhsi_dequeue(cfhsi);
-
-               if (!skb)
-                       break;
-
-               /* Calculate needed head alignment and tail alignment. */
-               info = (struct caif_payload_info *)&skb->cb;
-
-               hpad = 1 + PAD_POW2((info->hdr_len + 1), cfhsi->cfg.head_align);
-               tpad = PAD_POW2((skb->len + hpad), cfhsi->cfg.tail_align);
-
-               /* Fill in CAIF frame length in descriptor. */
-               desc->cffrm_len[nfrms] = hpad + skb->len + tpad;
-
-               /* Fill head padding information. */
-               *pfrm = (u8)(hpad - 1);
-               pfrm += hpad;
-
-               /* Update network statistics. */
-               spin_lock_bh(&cfhsi->lock);
-               cfhsi->ndev->stats.tx_packets++;
-               cfhsi->ndev->stats.tx_bytes += skb->len;
-               cfhsi_update_aggregation_stats(cfhsi, skb, -1);
-               spin_unlock_bh(&cfhsi->lock);
-
-               /* Copy in CAIF frame. */
-               skb_copy_bits(skb, 0, pfrm, skb->len);
-
-               /* Update payload length. */
-               pld_len += desc->cffrm_len[nfrms];
-
-               /* Update frame pointer. */
-               pfrm += skb->len + tpad;
-
-               /* Consume the SKB */
-               consume_skb(skb);
-               skb = NULL;
-
-               /* Update number of frames. */
-               nfrms++;
-       }
-
-       /* Unused length fields should be zero-filled (according to SPEC). */
-       while (nfrms < CFHSI_MAX_PKTS) {
-               desc->cffrm_len[nfrms] = 0x0000;
-               nfrms++;
-       }
-
-       /* Check if we can piggy-back another descriptor. */
-       if (cfhsi_can_send_aggregate(cfhsi))
-               desc->header |= CFHSI_PIGGY_DESC;
-       else
-               desc->header &= ~CFHSI_PIGGY_DESC;
-
-       return CFHSI_DESC_SZ + pld_len;
-}
-
-static void cfhsi_start_tx(struct cfhsi *cfhsi)
-{
-       struct cfhsi_desc *desc = (struct cfhsi_desc *)cfhsi->tx_buf;
-       int len, res;
-
-       netdev_dbg(cfhsi->ndev, "%s.\n", __func__);
-
-       if (test_bit(CFHSI_SHUTDOWN, &cfhsi->bits))
-               return;
-
-       do {
-               /* Create HSI frame. */
-               len = cfhsi_tx_frm(desc, cfhsi);
-               if (!len) {
-                       spin_lock_bh(&cfhsi->lock);
-                       if (unlikely(cfhsi_tx_queue_len(cfhsi))) {
-                               spin_unlock_bh(&cfhsi->lock);
-                               res = -EAGAIN;
-                               continue;
-                       }
-                       cfhsi->tx_state = CFHSI_TX_STATE_IDLE;
-                       /* Start inactivity timer. */
-                       mod_timer(&cfhsi->inactivity_timer,
-                               jiffies + cfhsi->cfg.inactivity_timeout);
-                       spin_unlock_bh(&cfhsi->lock);
-                       break;
-               }
-
-               /* Set up new transfer. */
-               res = cfhsi->ops->cfhsi_tx(cfhsi->tx_buf, len, cfhsi->ops);
-               if (WARN_ON(res < 0))
-                       netdev_err(cfhsi->ndev, "%s: TX error %d.\n",
-                               __func__, res);
-       } while (res < 0);
-}
-
-static void cfhsi_tx_done(struct cfhsi *cfhsi)
-{
-       netdev_dbg(cfhsi->ndev, "%s.\n", __func__);
-
-       if (test_bit(CFHSI_SHUTDOWN, &cfhsi->bits))
-               return;
-
-       /*
-        * Send flow on if flow off has been previously signalled
-        * and number of packets is below low water mark.
-        */
-       spin_lock_bh(&cfhsi->lock);
-       if (cfhsi->flow_off_sent &&
-                       cfhsi_tx_queue_len(cfhsi) <= cfhsi->cfg.q_low_mark &&
-                       cfhsi->cfdev.flowctrl) {
-
-               cfhsi->flow_off_sent = 0;
-               cfhsi->cfdev.flowctrl(cfhsi->ndev, ON);
-       }
-
-       if (cfhsi_can_send_aggregate(cfhsi)) {
-               spin_unlock_bh(&cfhsi->lock);
-               cfhsi_start_tx(cfhsi);
-       } else {
-               mod_timer(&cfhsi->aggregation_timer,
-                       jiffies + cfhsi->cfg.aggregation_timeout);
-               spin_unlock_bh(&cfhsi->lock);
-       }
-
-       return;
-}
-
-static void cfhsi_tx_done_cb(struct cfhsi_cb_ops *cb_ops)
-{
-       struct cfhsi *cfhsi;
-
-       cfhsi = container_of(cb_ops, struct cfhsi, cb_ops);
-       netdev_dbg(cfhsi->ndev, "%s.\n",
-               __func__);
-
-       if (test_bit(CFHSI_SHUTDOWN, &cfhsi->bits))
-               return;
-       cfhsi_tx_done(cfhsi);
-}
-
-static int cfhsi_rx_desc(struct cfhsi_desc *desc, struct cfhsi *cfhsi)
-{
-       int xfer_sz = 0;
-       int nfrms = 0;
-       u16 *plen = NULL;
-       u8 *pfrm = NULL;
-
-       if ((desc->header & ~CFHSI_PIGGY_DESC) ||
-                       (desc->offset > CFHSI_MAX_EMB_FRM_SZ)) {
-               netdev_err(cfhsi->ndev, "%s: Invalid descriptor.\n",
-                       __func__);
-               return -EPROTO;
-       }
-
-       /* Check for embedded CAIF frame. */
-       if (desc->offset) {
-               struct sk_buff *skb;
-               int len = 0;
-               pfrm = ((u8 *)desc) + desc->offset;
-
-               /* Remove offset padding. */
-               pfrm += *pfrm + 1;
-
-               /* Read length of CAIF frame (little endian). */
-               len = *pfrm;
-               len |= ((*(pfrm+1)) << 8) & 0xFF00;
-               len += 2;       /* Add FCS fields. */
-
-               /* Sanity check length of CAIF frame. */
-               if (unlikely(len > CFHSI_MAX_CAIF_FRAME_SZ)) {
-                       netdev_err(cfhsi->ndev, "%s: Invalid length.\n",
-                               __func__);
-                       return -EPROTO;
-               }
-
-               /* Allocate SKB (OK even in IRQ context). */
-               skb = alloc_skb(len + 1, GFP_ATOMIC);
-               if (!skb) {
-                       netdev_err(cfhsi->ndev, "%s: Out of memory !\n",
-                               __func__);
-                       return -ENOMEM;
-               }
-               caif_assert(skb != NULL);
-
-               skb_put_data(skb, pfrm, len);
-
-               skb->protocol = htons(ETH_P_CAIF);
-               skb_reset_mac_header(skb);
-               skb->dev = cfhsi->ndev;
-
-               netif_rx_any_context(skb);
-
-               /* Update network statistics. */
-               cfhsi->ndev->stats.rx_packets++;
-               cfhsi->ndev->stats.rx_bytes += len;
-       }
-
-       /* Calculate transfer length. */
-       plen = desc->cffrm_len;
-       while (nfrms < CFHSI_MAX_PKTS && *plen) {
-               xfer_sz += *plen;
-               plen++;
-               nfrms++;
-       }
-
-       /* Check for piggy-backed descriptor. */
-       if (desc->header & CFHSI_PIGGY_DESC)
-               xfer_sz += CFHSI_DESC_SZ;
-
-       if ((xfer_sz % 4) || (xfer_sz > (CFHSI_BUF_SZ_RX - CFHSI_DESC_SZ))) {
-               netdev_err(cfhsi->ndev,
-                               "%s: Invalid payload len: %d, ignored.\n",
-                       __func__, xfer_sz);
-               return -EPROTO;
-       }
-       return xfer_sz;
-}
-
-static int cfhsi_rx_desc_len(struct cfhsi_desc *desc)
-{
-       int xfer_sz = 0;
-       int nfrms = 0;
-       u16 *plen;
-
-       if ((desc->header & ~CFHSI_PIGGY_DESC) ||
-                       (desc->offset > CFHSI_MAX_EMB_FRM_SZ)) {
-
-               pr_err("Invalid descriptor. %x %x\n", desc->header,
-                               desc->offset);
-               return -EPROTO;
-       }
-
-       /* Calculate transfer length. */
-       plen = desc->cffrm_len;
-       while (nfrms < CFHSI_MAX_PKTS && *plen) {
-               xfer_sz += *plen;
-               plen++;
-               nfrms++;
-       }
-
-       if (xfer_sz % 4) {
-               pr_err("Invalid payload len: %d, ignored.\n", xfer_sz);
-               return -EPROTO;
-       }
-       return xfer_sz;
-}
-
-static int cfhsi_rx_pld(struct cfhsi_desc *desc, struct cfhsi *cfhsi)
-{
-       int rx_sz = 0;
-       int nfrms = 0;
-       u16 *plen = NULL;
-       u8 *pfrm = NULL;
-
-       /* Sanity check header and offset. */
-       if (WARN_ON((desc->header & ~CFHSI_PIGGY_DESC) ||
-                       (desc->offset > CFHSI_MAX_EMB_FRM_SZ))) {
-               netdev_err(cfhsi->ndev, "%s: Invalid descriptor.\n",
-                       __func__);
-               return -EPROTO;
-       }
-
-       /* Set frame pointer to start of payload. */
-       pfrm = desc->emb_frm + CFHSI_MAX_EMB_FRM_SZ;
-       plen = desc->cffrm_len;
-
-       /* Skip already processed frames. */
-       while (nfrms < cfhsi->rx_state.nfrms) {
-               pfrm += *plen;
-               rx_sz += *plen;
-               plen++;
-               nfrms++;
-       }
-
-       /* Parse payload. */
-       while (nfrms < CFHSI_MAX_PKTS && *plen) {
-               struct sk_buff *skb;
-               u8 *pcffrm = NULL;
-               int len;
-
-               /* CAIF frame starts after head padding. */
-               pcffrm = pfrm + *pfrm + 1;
-
-               /* Read length of CAIF frame (little endian). */
-               len = *pcffrm;
-               len |= ((*(pcffrm + 1)) << 8) & 0xFF00;
-               len += 2;       /* Add FCS fields. */
-
-               /* Sanity check length of CAIF frames. */
-               if (unlikely(len > CFHSI_MAX_CAIF_FRAME_SZ)) {
-                       netdev_err(cfhsi->ndev, "%s: Invalid length.\n",
-                               __func__);
-                       return -EPROTO;
-               }
-
-               /* Allocate SKB (OK even in IRQ context). */
-               skb = alloc_skb(len + 1, GFP_ATOMIC);
-               if (!skb) {
-                       netdev_err(cfhsi->ndev, "%s: Out of memory !\n",
-                               __func__);
-                       cfhsi->rx_state.nfrms = nfrms;
-                       return -ENOMEM;
-               }
-               caif_assert(skb != NULL);
-
-               skb_put_data(skb, pcffrm, len);
-
-               skb->protocol = htons(ETH_P_CAIF);
-               skb_reset_mac_header(skb);
-               skb->dev = cfhsi->ndev;
-
-               netif_rx_any_context(skb);
-
-               /* Update network statistics. */
-               cfhsi->ndev->stats.rx_packets++;
-               cfhsi->ndev->stats.rx_bytes += len;
-
-               pfrm += *plen;
-               rx_sz += *plen;
-               plen++;
-               nfrms++;
-       }
-
-       return rx_sz;
-}
-
-static void cfhsi_rx_done(struct cfhsi *cfhsi)
-{
-       int res;
-       int desc_pld_len = 0, rx_len, rx_state;
-       struct cfhsi_desc *desc = NULL;
-       u8 *rx_ptr, *rx_buf;
-       struct cfhsi_desc *piggy_desc = NULL;
-
-       desc = (struct cfhsi_desc *)cfhsi->rx_buf;
-
-       netdev_dbg(cfhsi->ndev, "%s\n", __func__);
-
-       if (test_bit(CFHSI_SHUTDOWN, &cfhsi->bits))
-               return;
-
-       /* Update inactivity timer if pending. */
-       spin_lock_bh(&cfhsi->lock);
-       mod_timer_pending(&cfhsi->inactivity_timer,
-                       jiffies + cfhsi->cfg.inactivity_timeout);
-       spin_unlock_bh(&cfhsi->lock);
-
-       if (cfhsi->rx_state.state == CFHSI_RX_STATE_DESC) {
-               desc_pld_len = cfhsi_rx_desc_len(desc);
-
-               if (desc_pld_len < 0)
-                       goto out_of_sync;
-
-               rx_buf = cfhsi->rx_buf;
-               rx_len = desc_pld_len;
-               if (desc_pld_len > 0 && (desc->header & CFHSI_PIGGY_DESC))
-                       rx_len += CFHSI_DESC_SZ;
-               if (desc_pld_len == 0)
-                       rx_buf = cfhsi->rx_flip_buf;
-       } else {
-               rx_buf = cfhsi->rx_flip_buf;
-
-               rx_len = CFHSI_DESC_SZ;
-               if (cfhsi->rx_state.pld_len > 0 &&
-                               (desc->header & CFHSI_PIGGY_DESC)) {
-
-                       piggy_desc = (struct cfhsi_desc *)
-                               (desc->emb_frm + CFHSI_MAX_EMB_FRM_SZ +
-                                               cfhsi->rx_state.pld_len);
-
-                       cfhsi->rx_state.piggy_desc = true;
-
-                       /* Extract payload len from piggy-backed descriptor. */
-                       desc_pld_len = cfhsi_rx_desc_len(piggy_desc);
-                       if (desc_pld_len < 0)
-                               goto out_of_sync;
-
-                       if (desc_pld_len > 0) {
-                               rx_len = desc_pld_len;
-                               if (piggy_desc->header & CFHSI_PIGGY_DESC)
-                                       rx_len += CFHSI_DESC_SZ;
-                       }
-
-                       /*
-                        * Copy needed information from the piggy-backed
-                        * descriptor to the descriptor in the start.
-                        */
-                       memcpy(rx_buf, (u8 *)piggy_desc,
-                                       CFHSI_DESC_SHORT_SZ);
-               }
-       }
-
-       if (desc_pld_len) {
-               rx_state = CFHSI_RX_STATE_PAYLOAD;
-               rx_ptr = rx_buf + CFHSI_DESC_SZ;
-       } else {
-               rx_state = CFHSI_RX_STATE_DESC;
-               rx_ptr = rx_buf;
-               rx_len = CFHSI_DESC_SZ;
-       }
-
-       /* Initiate next read */
-       if (test_bit(CFHSI_AWAKE, &cfhsi->bits)) {
-               /* Set up new transfer. */
-               netdev_dbg(cfhsi->ndev, "%s: Start RX.\n",
-                               __func__);
-
-               res = cfhsi->ops->cfhsi_rx(rx_ptr, rx_len,
-                               cfhsi->ops);
-               if (WARN_ON(res < 0)) {
-                       netdev_err(cfhsi->ndev, "%s: RX error %d.\n",
-                               __func__, res);
-                       cfhsi->ndev->stats.rx_errors++;
-                       cfhsi->ndev->stats.rx_dropped++;
-               }
-       }
-
-       if (cfhsi->rx_state.state == CFHSI_RX_STATE_DESC) {
-               /* Extract payload from descriptor */
-               if (cfhsi_rx_desc(desc, cfhsi) < 0)
-                       goto out_of_sync;
-       } else {
-               /* Extract payload */
-               if (cfhsi_rx_pld(desc, cfhsi) < 0)
-                       goto out_of_sync;
-               if (piggy_desc) {
-                       /* Extract any payload in piggyback descriptor. */
-                       if (cfhsi_rx_desc(piggy_desc, cfhsi) < 0)
-                               goto out_of_sync;
-                       /* Mark no embedded frame after extracting it */
-                       piggy_desc->offset = 0;
-               }
-       }
-
-       /* Update state info */
-       memset(&cfhsi->rx_state, 0, sizeof(cfhsi->rx_state));
-       cfhsi->rx_state.state = rx_state;
-       cfhsi->rx_ptr = rx_ptr;
-       cfhsi->rx_len = rx_len;
-       cfhsi->rx_state.pld_len = desc_pld_len;
-       cfhsi->rx_state.piggy_desc = desc->header & CFHSI_PIGGY_DESC;
-
-       if (rx_buf != cfhsi->rx_buf)
-               swap(cfhsi->rx_buf, cfhsi->rx_flip_buf);
-       return;
-
-out_of_sync:
-       netdev_err(cfhsi->ndev, "%s: Out of sync.\n", __func__);
-       print_hex_dump_bytes("--> ", DUMP_PREFIX_NONE,
-                       cfhsi->rx_buf, CFHSI_DESC_SZ);
-       schedule_work(&cfhsi->out_of_sync_work);
-}
-
-static void cfhsi_rx_slowpath(struct timer_list *t)
-{
-       struct cfhsi *cfhsi = from_timer(cfhsi, t, rx_slowpath_timer);
-
-       netdev_dbg(cfhsi->ndev, "%s.\n",
-               __func__);
-
-       cfhsi_rx_done(cfhsi);
-}
-
-static void cfhsi_rx_done_cb(struct cfhsi_cb_ops *cb_ops)
-{
-       struct cfhsi *cfhsi;
-
-       cfhsi = container_of(cb_ops, struct cfhsi, cb_ops);
-       netdev_dbg(cfhsi->ndev, "%s.\n",
-               __func__);
-
-       if (test_bit(CFHSI_SHUTDOWN, &cfhsi->bits))
-               return;
-
-       if (test_and_clear_bit(CFHSI_FLUSH_FIFO, &cfhsi->bits))
-               wake_up_interruptible(&cfhsi->flush_fifo_wait);
-       else
-               cfhsi_rx_done(cfhsi);
-}
-
-static void cfhsi_wake_up(struct work_struct *work)
-{
-       struct cfhsi *cfhsi = NULL;
-       int res;
-       int len;
-       long ret;
-
-       cfhsi = container_of(work, struct cfhsi, wake_up_work);
-
-       if (test_bit(CFHSI_SHUTDOWN, &cfhsi->bits))
-               return;
-
-       if (unlikely(test_bit(CFHSI_AWAKE, &cfhsi->bits))) {
-               /* It happenes when wakeup is requested by
-                * both ends at the same time. */
-               clear_bit(CFHSI_WAKE_UP, &cfhsi->bits);
-               clear_bit(CFHSI_WAKE_UP_ACK, &cfhsi->bits);
-               return;
-       }
-
-       /* Activate wake line. */
-       cfhsi->ops->cfhsi_wake_up(cfhsi->ops);
-
-       netdev_dbg(cfhsi->ndev, "%s: Start waiting.\n",
-               __func__);
-
-       /* Wait for acknowledge. */
-       ret = CFHSI_WAKE_TOUT;
-       ret = wait_event_interruptible_timeout(cfhsi->wake_up_wait,
-                                       test_and_clear_bit(CFHSI_WAKE_UP_ACK,
-                                                       &cfhsi->bits), ret);
-       if (unlikely(ret < 0)) {
-               /* Interrupted by signal. */
-               netdev_err(cfhsi->ndev, "%s: Signalled: %ld.\n",
-                       __func__, ret);
-
-               clear_bit(CFHSI_WAKE_UP, &cfhsi->bits);
-               cfhsi->ops->cfhsi_wake_down(cfhsi->ops);
-               return;
-       } else if (!ret) {
-               bool ca_wake = false;
-               size_t fifo_occupancy = 0;
-
-               /* Wakeup timeout */
-               netdev_dbg(cfhsi->ndev, "%s: Timeout.\n",
-                       __func__);
-
-               /* Check FIFO to check if modem has sent something. */
-               WARN_ON(cfhsi->ops->cfhsi_fifo_occupancy(cfhsi->ops,
-                                       &fifo_occupancy));
-
-               netdev_dbg(cfhsi->ndev, "%s: Bytes in FIFO: %u.\n",
-                               __func__, (unsigned) fifo_occupancy);
-
-               /* Check if we misssed the interrupt. */
-               WARN_ON(cfhsi->ops->cfhsi_get_peer_wake(cfhsi->ops,
-                                                       &ca_wake));
-
-               if (ca_wake) {
-                       netdev_err(cfhsi->ndev, "%s: CA Wake missed !.\n",
-                               __func__);
-
-                       /* Clear the CFHSI_WAKE_UP_ACK bit to prevent race. */
-                       clear_bit(CFHSI_WAKE_UP_ACK, &cfhsi->bits);
-
-                       /* Continue execution. */
-                       goto wake_ack;
-               }
-
-               clear_bit(CFHSI_WAKE_UP, &cfhsi->bits);
-               cfhsi->ops->cfhsi_wake_down(cfhsi->ops);
-               return;
-       }
-wake_ack:
-       netdev_dbg(cfhsi->ndev, "%s: Woken.\n",
-               __func__);
-
-       /* Clear power up bit. */
-       set_bit(CFHSI_AWAKE, &cfhsi->bits);
-       clear_bit(CFHSI_WAKE_UP, &cfhsi->bits);
-
-       /* Resume read operation. */
-       netdev_dbg(cfhsi->ndev, "%s: Start RX.\n", __func__);
-       res = cfhsi->ops->cfhsi_rx(cfhsi->rx_ptr, cfhsi->rx_len, cfhsi->ops);
-
-       if (WARN_ON(res < 0))
-               netdev_err(cfhsi->ndev, "%s: RX err %d.\n", __func__, res);
-
-       /* Clear power up acknowledment. */
-       clear_bit(CFHSI_WAKE_UP_ACK, &cfhsi->bits);
-
-       spin_lock_bh(&cfhsi->lock);
-
-       /* Resume transmit if queues are not empty. */
-       if (!cfhsi_tx_queue_len(cfhsi)) {
-               netdev_dbg(cfhsi->ndev, "%s: Peer wake, start timer.\n",
-                       __func__);
-               /* Start inactivity timer. */
-               mod_timer(&cfhsi->inactivity_timer,
-                               jiffies + cfhsi->cfg.inactivity_timeout);
-               spin_unlock_bh(&cfhsi->lock);
-               return;
-       }
-
-       netdev_dbg(cfhsi->ndev, "%s: Host wake.\n",
-               __func__);
-
-       spin_unlock_bh(&cfhsi->lock);
-
-       /* Create HSI frame. */
-       len = cfhsi_tx_frm((struct cfhsi_desc *)cfhsi->tx_buf, cfhsi);
-
-       if (likely(len > 0)) {
-               /* Set up new transfer. */
-               res = cfhsi->ops->cfhsi_tx(cfhsi->tx_buf, len, cfhsi->ops);
-               if (WARN_ON(res < 0)) {
-                       netdev_err(cfhsi->ndev, "%s: TX error %d.\n",
-                               __func__, res);
-                       cfhsi_abort_tx(cfhsi);
-               }
-       } else {
-               netdev_err(cfhsi->ndev,
-                               "%s: Failed to create HSI frame: %d.\n",
-                               __func__, len);
-       }
-}
-
-static void cfhsi_wake_down(struct work_struct *work)
-{
-       long ret;
-       struct cfhsi *cfhsi = NULL;
-       size_t fifo_occupancy = 0;
-       int retry = CFHSI_WAKE_TOUT;
-
-       cfhsi = container_of(work, struct cfhsi, wake_down_work);
-       netdev_dbg(cfhsi->ndev, "%s.\n", __func__);
-
-       if (test_bit(CFHSI_SHUTDOWN, &cfhsi->bits))
-               return;
-
-       /* Deactivate wake line. */
-       cfhsi->ops->cfhsi_wake_down(cfhsi->ops);
-
-       /* Wait for acknowledge. */
-       ret = CFHSI_WAKE_TOUT;
-       ret = wait_event_interruptible_timeout(cfhsi->wake_down_wait,
-                                       test_and_clear_bit(CFHSI_WAKE_DOWN_ACK,
-                                                       &cfhsi->bits), ret);
-       if (ret < 0) {
-               /* Interrupted by signal. */
-               netdev_err(cfhsi->ndev, "%s: Signalled: %ld.\n",
-                       __func__, ret);
-               return;
-       } else if (!ret) {
-               bool ca_wake = true;
-
-               /* Timeout */
-               netdev_err(cfhsi->ndev, "%s: Timeout.\n", __func__);
-
-               /* Check if we misssed the interrupt. */
-               WARN_ON(cfhsi->ops->cfhsi_get_peer_wake(cfhsi->ops,
-                                                       &ca_wake));
-               if (!ca_wake)
-                       netdev_err(cfhsi->ndev, "%s: CA Wake missed !.\n",
-                               __func__);
-       }
-
-       /* Check FIFO occupancy. */
-       while (retry) {
-               WARN_ON(cfhsi->ops->cfhsi_fifo_occupancy(cfhsi->ops,
-                                                       &fifo_occupancy));
-
-               if (!fifo_occupancy)
-                       break;
-
-               set_current_state(TASK_INTERRUPTIBLE);
-               schedule_timeout(1);
-               retry--;
-       }
-
-       if (!retry)
-               netdev_err(cfhsi->ndev, "%s: FIFO Timeout.\n", __func__);
-
-       /* Clear AWAKE condition. */
-       clear_bit(CFHSI_AWAKE, &cfhsi->bits);
-
-       /* Cancel pending RX requests. */
-       cfhsi->ops->cfhsi_rx_cancel(cfhsi->ops);
-}
-
-static void cfhsi_out_of_sync(struct work_struct *work)
-{
-       struct cfhsi *cfhsi = NULL;
-
-       cfhsi = container_of(work, struct cfhsi, out_of_sync_work);
-
-       rtnl_lock();
-       dev_close(cfhsi->ndev);
-       rtnl_unlock();
-}
-
-static void cfhsi_wake_up_cb(struct cfhsi_cb_ops *cb_ops)
-{
-       struct cfhsi *cfhsi = NULL;
-
-       cfhsi = container_of(cb_ops, struct cfhsi, cb_ops);
-       netdev_dbg(cfhsi->ndev, "%s.\n",
-               __func__);
-
-       set_bit(CFHSI_WAKE_UP_ACK, &cfhsi->bits);
-       wake_up_interruptible(&cfhsi->wake_up_wait);
-
-       if (test_bit(CFHSI_SHUTDOWN, &cfhsi->bits))
-               return;
-
-       /* Schedule wake up work queue if the peer initiates. */
-       if (!test_and_set_bit(CFHSI_WAKE_UP, &cfhsi->bits))
-               queue_work(cfhsi->wq, &cfhsi->wake_up_work);
-}
-
-static void cfhsi_wake_down_cb(struct cfhsi_cb_ops *cb_ops)
-{
-       struct cfhsi *cfhsi = NULL;
-
-       cfhsi = container_of(cb_ops, struct cfhsi, cb_ops);
-       netdev_dbg(cfhsi->ndev, "%s.\n",
-               __func__);
-
-       /* Initiating low power is only permitted by the host (us). */
-       set_bit(CFHSI_WAKE_DOWN_ACK, &cfhsi->bits);
-       wake_up_interruptible(&cfhsi->wake_down_wait);
-}
-
-static void cfhsi_aggregation_tout(struct timer_list *t)
-{
-       struct cfhsi *cfhsi = from_timer(cfhsi, t, aggregation_timer);
-
-       netdev_dbg(cfhsi->ndev, "%s.\n",
-               __func__);
-
-       cfhsi_start_tx(cfhsi);
-}
-
-static netdev_tx_t cfhsi_xmit(struct sk_buff *skb, struct net_device *dev)
-{
-       struct cfhsi *cfhsi = NULL;
-       int start_xfer = 0;
-       int timer_active;
-       int prio;
-
-       if (!dev)
-               return -EINVAL;
-
-       cfhsi = netdev_priv(dev);
-
-       switch (skb->priority) {
-       case TC_PRIO_BESTEFFORT:
-       case TC_PRIO_FILLER:
-       case TC_PRIO_BULK:
-               prio = CFHSI_PRIO_BEBK;
-               break;
-       case TC_PRIO_INTERACTIVE_BULK:
-               prio = CFHSI_PRIO_VI;
-               break;
-       case TC_PRIO_INTERACTIVE:
-               prio = CFHSI_PRIO_VO;
-               break;
-       case TC_PRIO_CONTROL:
-       default:
-               prio = CFHSI_PRIO_CTL;
-               break;
-       }
-
-       spin_lock_bh(&cfhsi->lock);
-
-       /* Update aggregation statistics  */
-       cfhsi_update_aggregation_stats(cfhsi, skb, 1);
-
-       /* Queue the SKB */
-       skb_queue_tail(&cfhsi->qhead[prio], skb);
-
-       /* Sanity check; xmit should not be called after unregister_netdev */
-       if (WARN_ON(test_bit(CFHSI_SHUTDOWN, &cfhsi->bits))) {
-               spin_unlock_bh(&cfhsi->lock);
-               cfhsi_abort_tx(cfhsi);
-               return -EINVAL;
-       }
-
-       /* Send flow off if number of packets is above high water mark. */
-       if (!cfhsi->flow_off_sent &&
-               cfhsi_tx_queue_len(cfhsi) > cfhsi->cfg.q_high_mark &&
-               cfhsi->cfdev.flowctrl) {
-               cfhsi->flow_off_sent = 1;
-               cfhsi->cfdev.flowctrl(cfhsi->ndev, OFF);
-       }
-
-       if (cfhsi->tx_state == CFHSI_TX_STATE_IDLE) {
-               cfhsi->tx_state = CFHSI_TX_STATE_XFER;
-               start_xfer = 1;
-       }
-
-       if (!start_xfer) {
-               /* Send aggregate if it is possible */
-               bool aggregate_ready =
-                       cfhsi_can_send_aggregate(cfhsi) &&
-                       del_timer(&cfhsi->aggregation_timer) > 0;
-               spin_unlock_bh(&cfhsi->lock);
-               if (aggregate_ready)
-                       cfhsi_start_tx(cfhsi);
-               return NETDEV_TX_OK;
-       }
-
-       /* Delete inactivity timer if started. */
-       timer_active = del_timer_sync(&cfhsi->inactivity_timer);
-
-       spin_unlock_bh(&cfhsi->lock);
-
-       if (timer_active) {
-               struct cfhsi_desc *desc = (struct cfhsi_desc *)cfhsi->tx_buf;
-               int len;
-               int res;
-
-               /* Create HSI frame. */
-               len = cfhsi_tx_frm(desc, cfhsi);
-               WARN_ON(!len);
-
-               /* Set up new transfer. */
-               res = cfhsi->ops->cfhsi_tx(cfhsi->tx_buf, len, cfhsi->ops);
-               if (WARN_ON(res < 0)) {
-                       netdev_err(cfhsi->ndev, "%s: TX error %d.\n",
-                               __func__, res);
-                       cfhsi_abort_tx(cfhsi);
-               }
-       } else {
-               /* Schedule wake up work queue if the we initiate. */
-               if (!test_and_set_bit(CFHSI_WAKE_UP, &cfhsi->bits))
-                       queue_work(cfhsi->wq, &cfhsi->wake_up_work);
-       }
-
-       return NETDEV_TX_OK;
-}
-
-static const struct net_device_ops cfhsi_netdevops;
-
-static void cfhsi_setup(struct net_device *dev)
-{
-       int i;
-       struct cfhsi *cfhsi = netdev_priv(dev);
-       dev->features = 0;
-       dev->type = ARPHRD_CAIF;
-       dev->flags = IFF_POINTOPOINT | IFF_NOARP;
-       dev->mtu = CFHSI_MAX_CAIF_FRAME_SZ;
-       dev->priv_flags |= IFF_NO_QUEUE;
-       dev->needs_free_netdev = true;
-       dev->netdev_ops = &cfhsi_netdevops;
-       for (i = 0; i < CFHSI_PRIO_LAST; ++i)
-               skb_queue_head_init(&cfhsi->qhead[i]);
-       cfhsi->cfdev.link_select = CAIF_LINK_HIGH_BANDW;
-       cfhsi->cfdev.use_frag = false;
-       cfhsi->cfdev.use_stx = false;
-       cfhsi->cfdev.use_fcs = false;
-       cfhsi->ndev = dev;
-       cfhsi->cfg = hsi_default_config;
-}
-
-static int cfhsi_open(struct net_device *ndev)
-{
-       struct cfhsi *cfhsi = netdev_priv(ndev);
-       int res;
-
-       clear_bit(CFHSI_SHUTDOWN, &cfhsi->bits);
-
-       /* Initialize state vaiables. */
-       cfhsi->tx_state = CFHSI_TX_STATE_IDLE;
-       cfhsi->rx_state.state = CFHSI_RX_STATE_DESC;
-
-       /* Set flow info */
-       cfhsi->flow_off_sent = 0;
-
-       /*
-        * Allocate a TX buffer with the size of a HSI packet descriptors
-        * and the necessary room for CAIF payload frames.
-        */
-       cfhsi->tx_buf = kzalloc(CFHSI_BUF_SZ_TX, GFP_KERNEL);
-       if (!cfhsi->tx_buf) {
-               res = -ENODEV;
-               goto err_alloc_tx;
-       }
-
-       /*
-        * Allocate a RX buffer with the size of two HSI packet descriptors and
-        * the necessary room for CAIF payload frames.
-        */
-       cfhsi->rx_buf = kzalloc(CFHSI_BUF_SZ_RX, GFP_KERNEL);
-       if (!cfhsi->rx_buf) {
-               res = -ENODEV;
-               goto err_alloc_rx;
-       }
-
-       cfhsi->rx_flip_buf = kzalloc(CFHSI_BUF_SZ_RX, GFP_KERNEL);
-       if (!cfhsi->rx_flip_buf) {
-               res = -ENODEV;
-               goto err_alloc_rx_flip;
-       }
-
-       /* Initialize aggregation timeout */
-       cfhsi->cfg.aggregation_timeout = hsi_default_config.aggregation_timeout;
-
-       /* Initialize recieve vaiables. */
-       cfhsi->rx_ptr = cfhsi->rx_buf;
-       cfhsi->rx_len = CFHSI_DESC_SZ;
-
-       /* Initialize spin locks. */
-       spin_lock_init(&cfhsi->lock);
-
-       /* Set up the driver. */
-       cfhsi->cb_ops.tx_done_cb = cfhsi_tx_done_cb;
-       cfhsi->cb_ops.rx_done_cb = cfhsi_rx_done_cb;
-       cfhsi->cb_ops.wake_up_cb = cfhsi_wake_up_cb;
-       cfhsi->cb_ops.wake_down_cb = cfhsi_wake_down_cb;
-
-       /* Initialize the work queues. */
-       INIT_WORK(&cfhsi->wake_up_work, cfhsi_wake_up);
-       INIT_WORK(&cfhsi->wake_down_work, cfhsi_wake_down);
-       INIT_WORK(&cfhsi->out_of_sync_work, cfhsi_out_of_sync);
-
-       /* Clear all bit fields. */
-       clear_bit(CFHSI_WAKE_UP_ACK, &cfhsi->bits);
-       clear_bit(CFHSI_WAKE_DOWN_ACK, &cfhsi->bits);
-       clear_bit(CFHSI_WAKE_UP, &cfhsi->bits);
-       clear_bit(CFHSI_AWAKE, &cfhsi->bits);
-
-       /* Create work thread. */
-       cfhsi->wq = alloc_ordered_workqueue(cfhsi->ndev->name, WQ_MEM_RECLAIM);
-       if (!cfhsi->wq) {
-               netdev_err(cfhsi->ndev, "%s: Failed to create work queue.\n",
-                       __func__);
-               res = -ENODEV;
-               goto err_create_wq;
-       }
-
-       /* Initialize wait queues. */
-       init_waitqueue_head(&cfhsi->wake_up_wait);
-       init_waitqueue_head(&cfhsi->wake_down_wait);
-       init_waitqueue_head(&cfhsi->flush_fifo_wait);
-
-       /* Setup the inactivity timer. */
-       timer_setup(&cfhsi->inactivity_timer, cfhsi_inactivity_tout, 0);
-       /* Setup the slowpath RX timer. */
-       timer_setup(&cfhsi->rx_slowpath_timer, cfhsi_rx_slowpath, 0);
-       /* Setup the aggregation timer. */
-       timer_setup(&cfhsi->aggregation_timer, cfhsi_aggregation_tout, 0);
-
-       /* Activate HSI interface. */
-       res = cfhsi->ops->cfhsi_up(cfhsi->ops);
-       if (res) {
-               netdev_err(cfhsi->ndev,
-                       "%s: can't activate HSI interface: %d.\n",
-                       __func__, res);
-               goto err_activate;
-       }
-
-       /* Flush FIFO */
-       res = cfhsi_flush_fifo(cfhsi);
-       if (res) {
-               netdev_err(cfhsi->ndev, "%s: Can't flush FIFO: %d.\n",
-                       __func__, res);
-               goto err_net_reg;
-       }
-       return res;
-
- err_net_reg:
-       cfhsi->ops->cfhsi_down(cfhsi->ops);
- err_activate:
-       destroy_workqueue(cfhsi->wq);
- err_create_wq:
-       kfree(cfhsi->rx_flip_buf);
- err_alloc_rx_flip:
-       kfree(cfhsi->rx_buf);
- err_alloc_rx:
-       kfree(cfhsi->tx_buf);
- err_alloc_tx:
-       return res;
-}
-
-static int cfhsi_close(struct net_device *ndev)
-{
-       struct cfhsi *cfhsi = netdev_priv(ndev);
-       u8 *tx_buf, *rx_buf, *flip_buf;
-
-       /* going to shutdown driver */
-       set_bit(CFHSI_SHUTDOWN, &cfhsi->bits);
-
-       /* Delete timers if pending */
-       del_timer_sync(&cfhsi->inactivity_timer);
-       del_timer_sync(&cfhsi->rx_slowpath_timer);
-       del_timer_sync(&cfhsi->aggregation_timer);
-
-       /* Cancel pending RX request (if any) */
-       cfhsi->ops->cfhsi_rx_cancel(cfhsi->ops);
-
-       /* Destroy workqueue */
-       destroy_workqueue(cfhsi->wq);
-
-       /* Store bufferes: will be freed later. */
-       tx_buf = cfhsi->tx_buf;
-       rx_buf = cfhsi->rx_buf;
-       flip_buf = cfhsi->rx_flip_buf;
-       /* Flush transmit queues. */
-       cfhsi_abort_tx(cfhsi);
-
-       /* Deactivate interface */
-       cfhsi->ops->cfhsi_down(cfhsi->ops);
-
-       /* Free buffers. */
-       kfree(tx_buf);
-       kfree(rx_buf);
-       kfree(flip_buf);
-       return 0;
-}
-
-static void cfhsi_uninit(struct net_device *dev)
-{
-       struct cfhsi *cfhsi = netdev_priv(dev);
-       ASSERT_RTNL();
-       symbol_put(cfhsi_get_device);
-       list_del(&cfhsi->list);
-}
-
-static const struct net_device_ops cfhsi_netdevops = {
-       .ndo_uninit = cfhsi_uninit,
-       .ndo_open = cfhsi_open,
-       .ndo_stop = cfhsi_close,
-       .ndo_start_xmit = cfhsi_xmit
-};
-
-static void cfhsi_netlink_parms(struct nlattr *data[], struct cfhsi *cfhsi)
-{
-       int i;
-
-       if (!data) {
-               pr_debug("no params data found\n");
-               return;
-       }
-
-       i = __IFLA_CAIF_HSI_INACTIVITY_TOUT;
-       /*
-        * Inactivity timeout in millisecs. Lowest possible value is 1,
-        * and highest possible is NEXT_TIMER_MAX_DELTA.
-        */
-       if (data[i]) {
-               u32 inactivity_timeout = nla_get_u32(data[i]);
-               /* Pre-calculate inactivity timeout. */
-               cfhsi->cfg.inactivity_timeout = inactivity_timeout * HZ / 1000;
-               if (cfhsi->cfg.inactivity_timeout == 0)
-                       cfhsi->cfg.inactivity_timeout = 1;
-               else if (cfhsi->cfg.inactivity_timeout > NEXT_TIMER_MAX_DELTA)
-                       cfhsi->cfg.inactivity_timeout = NEXT_TIMER_MAX_DELTA;
-       }
-
-       i = __IFLA_CAIF_HSI_AGGREGATION_TOUT;
-       if (data[i])
-               cfhsi->cfg.aggregation_timeout = nla_get_u32(data[i]);
-
-       i = __IFLA_CAIF_HSI_HEAD_ALIGN;
-       if (data[i])
-               cfhsi->cfg.head_align = nla_get_u32(data[i]);
-
-       i = __IFLA_CAIF_HSI_TAIL_ALIGN;
-       if (data[i])
-               cfhsi->cfg.tail_align = nla_get_u32(data[i]);
-
-       i = __IFLA_CAIF_HSI_QHIGH_WATERMARK;
-       if (data[i])
-               cfhsi->cfg.q_high_mark = nla_get_u32(data[i]);
-
-       i = __IFLA_CAIF_HSI_QLOW_WATERMARK;
-       if (data[i])
-               cfhsi->cfg.q_low_mark = nla_get_u32(data[i]);
-}
-
-static int caif_hsi_changelink(struct net_device *dev, struct nlattr *tb[],
-                              struct nlattr *data[],
-                              struct netlink_ext_ack *extack)
-{
-       cfhsi_netlink_parms(data, netdev_priv(dev));
-       netdev_state_change(dev);
-       return 0;
-}
-
-static const struct nla_policy caif_hsi_policy[__IFLA_CAIF_HSI_MAX + 1] = {
-       [__IFLA_CAIF_HSI_INACTIVITY_TOUT] = { .type = NLA_U32, .len = 4 },
-       [__IFLA_CAIF_HSI_AGGREGATION_TOUT] = { .type = NLA_U32, .len = 4 },
-       [__IFLA_CAIF_HSI_HEAD_ALIGN] = { .type = NLA_U32, .len = 4 },
-       [__IFLA_CAIF_HSI_TAIL_ALIGN] = { .type = NLA_U32, .len = 4 },
-       [__IFLA_CAIF_HSI_QHIGH_WATERMARK] = { .type = NLA_U32, .len = 4 },
-       [__IFLA_CAIF_HSI_QLOW_WATERMARK] = { .type = NLA_U32, .len = 4 },
-};
-
-static size_t caif_hsi_get_size(const struct net_device *dev)
-{
-       int i;
-       size_t s = 0;
-       for (i = __IFLA_CAIF_HSI_UNSPEC + 1; i < __IFLA_CAIF_HSI_MAX; i++)
-               s += nla_total_size(caif_hsi_policy[i].len);
-       return s;
-}
-
-static int caif_hsi_fill_info(struct sk_buff *skb, const struct net_device *dev)
-{
-       struct cfhsi *cfhsi = netdev_priv(dev);
-
-       if (nla_put_u32(skb, __IFLA_CAIF_HSI_INACTIVITY_TOUT,
-                       cfhsi->cfg.inactivity_timeout) ||
-           nla_put_u32(skb, __IFLA_CAIF_HSI_AGGREGATION_TOUT,
-                       cfhsi->cfg.aggregation_timeout) ||
-           nla_put_u32(skb, __IFLA_CAIF_HSI_HEAD_ALIGN,
-                       cfhsi->cfg.head_align) ||
-           nla_put_u32(skb, __IFLA_CAIF_HSI_TAIL_ALIGN,
-                       cfhsi->cfg.tail_align) ||
-           nla_put_u32(skb, __IFLA_CAIF_HSI_QHIGH_WATERMARK,
-                       cfhsi->cfg.q_high_mark) ||
-           nla_put_u32(skb, __IFLA_CAIF_HSI_QLOW_WATERMARK,
-                       cfhsi->cfg.q_low_mark))
-               return -EMSGSIZE;
-
-       return 0;
-}
-
-static int caif_hsi_newlink(struct net *src_net, struct net_device *dev,
-                           struct nlattr *tb[], struct nlattr *data[],
-                           struct netlink_ext_ack *extack)
-{
-       struct cfhsi *cfhsi = NULL;
-       struct cfhsi_ops *(*get_ops)(void);
-
-       ASSERT_RTNL();
-
-       cfhsi = netdev_priv(dev);
-       cfhsi_netlink_parms(data, cfhsi);
-
-       get_ops = symbol_get(cfhsi_get_ops);
-       if (!get_ops) {
-               pr_err("%s: failed to get the cfhsi_ops\n", __func__);
-               return -ENODEV;
-       }
-
-       /* Assign the HSI device. */
-       cfhsi->ops = (*get_ops)();
-       if (!cfhsi->ops) {
-               pr_err("%s: failed to get the cfhsi_ops\n", __func__);
-               goto err;
-       }
-
-       /* Assign the driver to this HSI device. */
-       cfhsi->ops->cb_ops = &cfhsi->cb_ops;
-       if (register_netdevice(dev)) {
-               pr_warn("%s: caif_hsi device registration failed\n", __func__);
-               goto err;
-       }
-       /* Add CAIF HSI device to list. */
-       list_add_tail(&cfhsi->list, &cfhsi_list);
-
-       return 0;
-err:
-       symbol_put(cfhsi_get_ops);
-       return -ENODEV;
-}
-
-static struct rtnl_link_ops caif_hsi_link_ops __read_mostly = {
-       .kind           = "cfhsi",
-       .priv_size      = sizeof(struct cfhsi),
-       .setup          = cfhsi_setup,
-       .maxtype        = __IFLA_CAIF_HSI_MAX,
-       .policy = caif_hsi_policy,
-       .newlink        = caif_hsi_newlink,
-       .changelink     = caif_hsi_changelink,
-       .get_size       = caif_hsi_get_size,
-       .fill_info      = caif_hsi_fill_info,
-};
-
-static void __exit cfhsi_exit_module(void)
-{
-       struct list_head *list_node;
-       struct list_head *n;
-       struct cfhsi *cfhsi;
-
-       rtnl_link_unregister(&caif_hsi_link_ops);
-
-       rtnl_lock();
-       list_for_each_safe(list_node, n, &cfhsi_list) {
-               cfhsi = list_entry(list_node, struct cfhsi, list);
-               unregister_netdevice(cfhsi->ndev);
-       }
-       rtnl_unlock();
-}
-
-static int __init cfhsi_init_module(void)
-{
-       return rtnl_link_register(&caif_hsi_link_ops);
-}
-
-module_init(cfhsi_init_module);
-module_exit(cfhsi_exit_module);
index a7e5ac6..1542bfb 100644 (file)
@@ -419,8 +419,10 @@ int ksz_switch_register(struct ksz_device *dev,
                                if (of_property_read_u32(port, "reg",
                                                         &port_num))
                                        continue;
-                               if (!(dev->port_mask & BIT(port_num)))
+                               if (!(dev->port_mask & BIT(port_num))) {
+                                       of_node_put(port);
                                        return -EINVAL;
+                               }
                                of_get_phy_mode(port,
                                                &dev->ports[port_num].interface);
                        }
index 961fa6b..beb4157 100644 (file)
@@ -3583,6 +3583,7 @@ static const struct mv88e6xxx_ops mv88e6141_ops = {
        .port_set_speed_duplex = mv88e6341_port_set_speed_duplex,
        .port_max_speed_mode = mv88e6341_port_max_speed_mode,
        .port_tag_remap = mv88e6095_port_tag_remap,
+       .port_set_policy = mv88e6352_port_set_policy,
        .port_set_frame_mode = mv88e6351_port_set_frame_mode,
        .port_set_ucast_flood = mv88e6352_port_set_ucast_flood,
        .port_set_mcast_flood = mv88e6352_port_set_mcast_flood,
@@ -3596,7 +3597,7 @@ static const struct mv88e6xxx_ops mv88e6141_ops = {
        .port_set_cmode = mv88e6341_port_set_cmode,
        .port_setup_message_port = mv88e6xxx_setup_message_port,
        .stats_snapshot = mv88e6390_g1_stats_snapshot,
-       .stats_set_histogram = mv88e6095_g1_stats_set_histogram,
+       .stats_set_histogram = mv88e6390_g1_stats_set_histogram,
        .stats_get_sset_count = mv88e6320_stats_get_sset_count,
        .stats_get_strings = mv88e6320_stats_get_strings,
        .stats_get_stats = mv88e6390_stats_get_stats,
@@ -3606,6 +3607,9 @@ static const struct mv88e6xxx_ops mv88e6141_ops = {
        .mgmt_rsvd2cpu =  mv88e6390_g1_mgmt_rsvd2cpu,
        .pot_clear = mv88e6xxx_g2_pot_clear,
        .reset = mv88e6352_g1_reset,
+       .rmu_disable = mv88e6390_g1_rmu_disable,
+       .atu_get_hash = mv88e6165_g1_atu_get_hash,
+       .atu_set_hash = mv88e6165_g1_atu_set_hash,
        .vtu_getnext = mv88e6352_g1_vtu_getnext,
        .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
        .serdes_power = mv88e6390_serdes_power,
@@ -3619,6 +3623,11 @@ static const struct mv88e6xxx_ops mv88e6141_ops = {
        .serdes_irq_enable = mv88e6390_serdes_irq_enable,
        .serdes_irq_status = mv88e6390_serdes_irq_status,
        .gpio_ops = &mv88e6352_gpio_ops,
+       .serdes_get_sset_count = mv88e6390_serdes_get_sset_count,
+       .serdes_get_strings = mv88e6390_serdes_get_strings,
+       .serdes_get_stats = mv88e6390_serdes_get_stats,
+       .serdes_get_regs_len = mv88e6390_serdes_get_regs_len,
+       .serdes_get_regs = mv88e6390_serdes_get_regs,
        .phylink_validate = mv88e6341_phylink_validate,
 };
 
@@ -4383,6 +4392,7 @@ static const struct mv88e6xxx_ops mv88e6341_ops = {
        .port_set_speed_duplex = mv88e6341_port_set_speed_duplex,
        .port_max_speed_mode = mv88e6341_port_max_speed_mode,
        .port_tag_remap = mv88e6095_port_tag_remap,
+       .port_set_policy = mv88e6352_port_set_policy,
        .port_set_frame_mode = mv88e6351_port_set_frame_mode,
        .port_set_ucast_flood = mv88e6352_port_set_ucast_flood,
        .port_set_mcast_flood = mv88e6352_port_set_mcast_flood,
@@ -4396,7 +4406,7 @@ static const struct mv88e6xxx_ops mv88e6341_ops = {
        .port_set_cmode = mv88e6341_port_set_cmode,
        .port_setup_message_port = mv88e6xxx_setup_message_port,
        .stats_snapshot = mv88e6390_g1_stats_snapshot,
-       .stats_set_histogram = mv88e6095_g1_stats_set_histogram,
+       .stats_set_histogram = mv88e6390_g1_stats_set_histogram,
        .stats_get_sset_count = mv88e6320_stats_get_sset_count,
        .stats_get_strings = mv88e6320_stats_get_strings,
        .stats_get_stats = mv88e6390_stats_get_stats,
@@ -4406,6 +4416,9 @@ static const struct mv88e6xxx_ops mv88e6341_ops = {
        .mgmt_rsvd2cpu =  mv88e6390_g1_mgmt_rsvd2cpu,
        .pot_clear = mv88e6xxx_g2_pot_clear,
        .reset = mv88e6352_g1_reset,
+       .rmu_disable = mv88e6390_g1_rmu_disable,
+       .atu_get_hash = mv88e6165_g1_atu_get_hash,
+       .atu_set_hash = mv88e6165_g1_atu_set_hash,
        .vtu_getnext = mv88e6352_g1_vtu_getnext,
        .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
        .serdes_power = mv88e6390_serdes_power,
@@ -4421,6 +4434,11 @@ static const struct mv88e6xxx_ops mv88e6341_ops = {
        .gpio_ops = &mv88e6352_gpio_ops,
        .avb_ops = &mv88e6390_avb_ops,
        .ptp_ops = &mv88e6352_ptp_ops,
+       .serdes_get_sset_count = mv88e6390_serdes_get_sset_count,
+       .serdes_get_strings = mv88e6390_serdes_get_strings,
+       .serdes_get_stats = mv88e6390_serdes_get_stats,
+       .serdes_get_regs_len = mv88e6390_serdes_get_regs_len,
+       .serdes_get_regs = mv88e6390_serdes_get_regs,
        .phylink_validate = mv88e6341_phylink_validate,
 };
 
index e4fbef8..b1d46dd 100644 (file)
@@ -722,7 +722,7 @@ static struct mv88e6390_serdes_hw_stat mv88e6390_serdes_hw_stats[] = {
 
 int mv88e6390_serdes_get_sset_count(struct mv88e6xxx_chip *chip, int port)
 {
-       if (mv88e6390_serdes_get_lane(chip, port) < 0)
+       if (mv88e6xxx_serdes_get_lane(chip, port) < 0)
                return 0;
 
        return ARRAY_SIZE(mv88e6390_serdes_hw_stats);
@@ -734,7 +734,7 @@ int mv88e6390_serdes_get_strings(struct mv88e6xxx_chip *chip,
        struct mv88e6390_serdes_hw_stat *stat;
        int i;
 
-       if (mv88e6390_serdes_get_lane(chip, port) < 0)
+       if (mv88e6xxx_serdes_get_lane(chip, port) < 0)
                return 0;
 
        for (i = 0; i < ARRAY_SIZE(mv88e6390_serdes_hw_stats); i++) {
@@ -770,7 +770,7 @@ int mv88e6390_serdes_get_stats(struct mv88e6xxx_chip *chip, int port,
        int lane;
        int i;
 
-       lane = mv88e6390_serdes_get_lane(chip, port);
+       lane = mv88e6xxx_serdes_get_lane(chip, port);
        if (lane < 0)
                return 0;
 
index 4f05456..ced8c9c 100644 (file)
@@ -122,14 +122,12 @@ static int sja1105_init_mac_settings(struct sja1105_private *priv)
 
        for (i = 0; i < ds->num_ports; i++) {
                mac[i] = default_mac;
-               if (i == dsa_upstream_port(priv->ds, i)) {
-                       /* STP doesn't get called for CPU port, so we need to
-                        * set the I/O parameters statically.
-                        */
-                       mac[i].dyn_learn = true;
-                       mac[i].ingress = true;
-                       mac[i].egress = true;
-               }
+
+               /* Let sja1105_bridge_stp_state_set() keep address learning
+                * enabled for the CPU port.
+                */
+               if (dsa_is_cpu_port(ds, i))
+                       priv->learn_ena |= BIT(i);
        }
 
        return 0;
index 7dff203..f19370c 100644 (file)
@@ -594,6 +594,11 @@ int atl1c_phy_init(struct atl1c_hw *hw)
        int ret_val;
        u16 mii_bmcr_data = BMCR_RESET;
 
+       if (hw->nic_type == athr_mt) {
+               hw->phy_configured = true;
+               return 0;
+       }
+
        if ((atl1c_read_phy_reg(hw, MII_PHYSID1, &hw->phy_id1) != 0) ||
                (atl1c_read_phy_reg(hw, MII_PHYSID2, &hw->phy_id2) != 0)) {
                dev_err(&pdev->dev, "Error get phy ID\n");
index 41f7f07..db74241 100644 (file)
@@ -1640,7 +1640,8 @@ static void bcmgenet_power_up(struct bcmgenet_priv *priv,
 
        switch (mode) {
        case GENET_POWER_PASSIVE:
-               reg &= ~(EXT_PWR_DOWN_DLL | EXT_PWR_DOWN_BIAS);
+               reg &= ~(EXT_PWR_DOWN_DLL | EXT_PWR_DOWN_BIAS |
+                        EXT_ENERGY_DET_MASK);
                if (GENET_IS_V5(priv)) {
                        reg &= ~(EXT_PWR_DOWN_PHY_EN |
                                 EXT_PWR_DOWN_PHY_RD |
@@ -3237,15 +3238,21 @@ static void bcmgenet_get_hw_addr(struct bcmgenet_priv *priv,
 /* Returns a reusable dma control register value */
 static u32 bcmgenet_dma_disable(struct bcmgenet_priv *priv)
 {
+       unsigned int i;
        u32 reg;
        u32 dma_ctrl;
 
        /* disable DMA */
        dma_ctrl = 1 << (DESC_INDEX + DMA_RING_BUF_EN_SHIFT) | DMA_EN;
+       for (i = 0; i < priv->hw_params->tx_queues; i++)
+               dma_ctrl |= (1 << (i + DMA_RING_BUF_EN_SHIFT));
        reg = bcmgenet_tdma_readl(priv, DMA_CTRL);
        reg &= ~dma_ctrl;
        bcmgenet_tdma_writel(priv, reg, DMA_CTRL);
 
+       dma_ctrl = 1 << (DESC_INDEX + DMA_RING_BUF_EN_SHIFT) | DMA_EN;
+       for (i = 0; i < priv->hw_params->rx_queues; i++)
+               dma_ctrl |= (1 << (i + DMA_RING_BUF_EN_SHIFT));
        reg = bcmgenet_rdma_readl(priv, DMA_CTRL);
        reg &= ~dma_ctrl;
        bcmgenet_rdma_writel(priv, reg, DMA_CTRL);
@@ -3292,7 +3299,6 @@ static int bcmgenet_open(struct net_device *dev)
 {
        struct bcmgenet_priv *priv = netdev_priv(dev);
        unsigned long dma_ctrl;
-       u32 reg;
        int ret;
 
        netif_dbg(priv, ifup, dev, "bcmgenet_open\n");
@@ -3318,12 +3324,6 @@ static int bcmgenet_open(struct net_device *dev)
 
        bcmgenet_set_hw_addr(priv, dev->dev_addr);
 
-       if (priv->internal_phy) {
-               reg = bcmgenet_ext_readl(priv, EXT_EXT_PWR_MGMT);
-               reg |= EXT_ENERGY_DET_MASK;
-               bcmgenet_ext_writel(priv, reg, EXT_EXT_PWR_MGMT);
-       }
-
        /* Disable RX/TX DMA and flush TX queues */
        dma_ctrl = bcmgenet_dma_disable(priv);
 
@@ -4139,7 +4139,6 @@ static int bcmgenet_resume(struct device *d)
        struct bcmgenet_priv *priv = netdev_priv(dev);
        struct bcmgenet_rxnfc_rule *rule;
        unsigned long dma_ctrl;
-       u32 reg;
        int ret;
 
        if (!netif_running(dev))
@@ -4176,12 +4175,6 @@ static int bcmgenet_resume(struct device *d)
                if (rule->state != BCMGENET_RXNFC_STATE_UNUSED)
                        bcmgenet_hfb_create_rxnfc_filter(priv, rule);
 
-       if (priv->internal_phy) {
-               reg = bcmgenet_ext_readl(priv, EXT_EXT_PWR_MGMT);
-               reg |= EXT_ENERGY_DET_MASK;
-               bcmgenet_ext_writel(priv, reg, EXT_EXT_PWR_MGMT);
-       }
-
        /* Disable RX/TX DMA and flush TX queues */
        dma_ctrl = bcmgenet_dma_disable(priv);
 
index facde82..e31a5a3 100644 (file)
@@ -186,12 +186,6 @@ int bcmgenet_wol_power_down_cfg(struct bcmgenet_priv *priv,
        reg |= CMD_RX_EN;
        bcmgenet_umac_writel(priv, reg, UMAC_CMD);
 
-       if (priv->hw_params->flags & GENET_HAS_EXT) {
-               reg = bcmgenet_ext_readl(priv, EXT_EXT_PWR_MGMT);
-               reg &= ~EXT_ENERGY_DET_MASK;
-               bcmgenet_ext_writel(priv, reg, EXT_EXT_PWR_MGMT);
-       }
-
        reg = UMAC_IRQ_MPD_R;
        if (hfb_enable)
                reg |=  UMAC_IRQ_HFB_SM | UMAC_IRQ_HFB_MM;
index 9a2b166..dbf9a0e 100644 (file)
@@ -2643,6 +2643,9 @@ static void detach_ulds(struct adapter *adap)
 {
        unsigned int i;
 
+       if (!is_uld(adap))
+               return;
+
        mutex_lock(&uld_mutex);
        list_del(&adap->list_node);
 
@@ -7141,10 +7144,13 @@ static void remove_one(struct pci_dev *pdev)
                 */
                destroy_workqueue(adapter->workq);
 
-               if (is_uld(adapter)) {
-                       detach_ulds(adapter);
-                       t4_uld_clean_up(adapter);
-               }
+               detach_ulds(adapter);
+
+               for_each_port(adapter, i)
+                       if (adapter->port[i]->reg_state == NETREG_REGISTERED)
+                               unregister_netdev(adapter->port[i]);
+
+               t4_uld_clean_up(adapter);
 
                adap_free_hma_mem(adapter);
 
@@ -7152,10 +7158,6 @@ static void remove_one(struct pci_dev *pdev)
 
                cxgb4_free_mps_ref_entries(adapter);
 
-               for_each_port(adapter, i)
-                       if (adapter->port[i]->reg_state == NETREG_REGISTERED)
-                               unregister_netdev(adapter->port[i]);
-
                debugfs_remove_recursive(adapter->debugfs_root);
 
                if (!is_t4(adapter->params.chip))
index 743af9e..17faac7 100644 (file)
@@ -581,6 +581,9 @@ void t4_uld_clean_up(struct adapter *adap)
 {
        unsigned int i;
 
+       if (!is_uld(adap))
+               return;
+
        mutex_lock(&uld_mutex);
        for (i = 0; i < CXGB4_ULD_MAX; i++) {
                if (!adap->uld[i].handle)
index 867e87a..099a2bc 100644 (file)
@@ -1469,7 +1469,7 @@ static int gve_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 
        err = pci_enable_device(pdev);
        if (err)
-               return -ENXIO;
+               return err;
 
        err = pci_request_regions(pdev, "gvnic-cfg");
        if (err)
@@ -1477,19 +1477,12 @@ static int gve_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 
        pci_set_master(pdev);
 
-       err = pci_set_dma_mask(pdev, DMA_BIT_MASK(64));
+       err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64));
        if (err) {
                dev_err(&pdev->dev, "Failed to set dma mask: err=%d\n", err);
                goto abort_with_pci_region;
        }
 
-       err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64));
-       if (err) {
-               dev_err(&pdev->dev,
-                       "Failed to set consistent dma mask: err=%d\n", err);
-               goto abort_with_pci_region;
-       }
-
        reg_bar = pci_iomap(pdev, GVE_REGISTER_BAR, 0);
        if (!reg_bar) {
                dev_err(&pdev->dev, "Failed to map pci bar!\n");
@@ -1512,6 +1505,7 @@ static int gve_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        dev = alloc_etherdev_mqs(sizeof(*priv), max_tx_queues, max_rx_queues);
        if (!dev) {
                dev_err(&pdev->dev, "could not allocate netdev\n");
+               err = -ENOMEM;
                goto abort_with_db_bar;
        }
        SET_NETDEV_DEV(dev, &pdev->dev);
@@ -1565,7 +1559,7 @@ static int gve_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 
        err = register_netdev(dev);
        if (err)
-               goto abort_with_wq;
+               goto abort_with_gve_init;
 
        dev_info(&pdev->dev, "GVE version %s\n", gve_version_str);
        dev_info(&pdev->dev, "GVE queue format %d\n", (int)priv->queue_format);
@@ -1573,6 +1567,9 @@ static int gve_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        queue_work(priv->gve_wq, &priv->service_task);
        return 0;
 
+abort_with_gve_init:
+       gve_teardown_priv_resources(priv);
+
 abort_with_wq:
        destroy_workqueue(priv->gve_wq);
 
@@ -1590,7 +1587,7 @@ abort_with_pci_region:
 
 abort_with_enabled:
        pci_disable_device(pdev);
-       return -ENXIO;
+       return err;
 }
 
 static void gve_remove(struct pci_dev *pdev)
index 77bb822..8500621 100644 (file)
@@ -566,13 +566,6 @@ static int gve_rx_dqo(struct napi_struct *napi, struct gve_rx_ring *rx,
                return 0;
        }
 
-       /* Prefetch the payload header. */
-       prefetch((char *)buf_state->addr + buf_state->page_info.page_offset);
-#if L1_CACHE_BYTES < 128
-       prefetch((char *)buf_state->addr + buf_state->page_info.page_offset +
-                L1_CACHE_BYTES);
-#endif
-
        if (eop && buf_len <= priv->rx_copybreak) {
                rx->skb_head = gve_rx_copy(priv->dev, napi,
                                           &buf_state->page_info, buf_len, 0);
index 374a75d..ed77191 100644 (file)
@@ -2420,9 +2420,10 @@ out:
 
 static void __ibmvnic_reset(struct work_struct *work)
 {
-       struct ibmvnic_rwi *rwi;
        struct ibmvnic_adapter *adapter;
        bool saved_state = false;
+       struct ibmvnic_rwi *tmprwi;
+       struct ibmvnic_rwi *rwi;
        unsigned long flags;
        u32 reset_state;
        int rc = 0;
@@ -2489,7 +2490,7 @@ static void __ibmvnic_reset(struct work_struct *work)
                } else {
                        rc = do_reset(adapter, rwi, reset_state);
                }
-               kfree(rwi);
+               tmprwi = rwi;
                adapter->last_reset_time = jiffies;
 
                if (rc)
@@ -2497,8 +2498,23 @@ static void __ibmvnic_reset(struct work_struct *work)
 
                rwi = get_next_rwi(adapter);
 
+               /*
+                * If there is another reset queued, free the previous rwi
+                * and process the new reset even if previous reset failed
+                * (the previous reset could have failed because of a fail
+                * over for instance, so process the fail over).
+                *
+                * If there are no resets queued and the previous reset failed,
+                * the adapter would be in an undefined state. So retry the
+                * previous reset as a hard reset.
+                */
+               if (rwi)
+                       kfree(tmprwi);
+               else if (rc)
+                       rwi = tmprwi;
+
                if (rwi && (rwi->reset_reason == VNIC_RESET_FAILOVER ||
-                           rwi->reset_reason == VNIC_RESET_MOBILITY))
+                           rwi->reset_reason == VNIC_RESET_MOBILITY || rc))
                        adapter->force_reset_recovery = true;
        }
 
index d150dad..757a54c 100644 (file)
@@ -7664,6 +7664,7 @@ err_flashmap:
 err_ioremap:
        free_netdev(netdev);
 err_alloc_etherdev:
+       pci_disable_pcie_error_reporting(pdev);
        pci_release_mem_regions(pdev);
 err_pci_reg:
 err_dma:
index dbcae92..adfa276 100644 (file)
@@ -2227,6 +2227,7 @@ err_sw_init:
 err_ioremap:
        free_netdev(netdev);
 err_alloc_netdev:
+       pci_disable_pcie_error_reporting(pdev);
        pci_release_mem_regions(pdev);
 err_pci_reg:
 err_dma:
index e612c24..44bafed 100644 (file)
@@ -3798,6 +3798,7 @@ static int iavf_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 err_ioremap:
        free_netdev(netdev);
 err_alloc_etherdev:
+       pci_disable_pcie_error_reporting(pdev);
        pci_release_regions(pdev);
 err_pci_reg:
 err_dma:
index 7e6435d..171a7a6 100644 (file)
@@ -931,6 +931,7 @@ static void igb_configure_msix(struct igb_adapter *adapter)
  **/
 static int igb_request_msix(struct igb_adapter *adapter)
 {
+       unsigned int num_q_vectors = adapter->num_q_vectors;
        struct net_device *netdev = adapter->netdev;
        int i, err = 0, vector = 0, free_vector = 0;
 
@@ -939,7 +940,13 @@ static int igb_request_msix(struct igb_adapter *adapter)
        if (err)
                goto err_out;
 
-       for (i = 0; i < adapter->num_q_vectors; i++) {
+       if (num_q_vectors > MAX_Q_VECTORS) {
+               num_q_vectors = MAX_Q_VECTORS;
+               dev_warn(&adapter->pdev->dev,
+                        "The number of queue vectors (%d) is higher than max allowed (%d)\n",
+                        adapter->num_q_vectors, MAX_Q_VECTORS);
+       }
+       for (i = 0; i < num_q_vectors; i++) {
                struct igb_q_vector *q_vector = adapter->q_vector[i];
 
                vector++;
@@ -1678,14 +1685,15 @@ static bool is_any_txtime_enabled(struct igb_adapter *adapter)
  **/
 static void igb_config_tx_modes(struct igb_adapter *adapter, int queue)
 {
-       struct igb_ring *ring = adapter->tx_ring[queue];
        struct net_device *netdev = adapter->netdev;
        struct e1000_hw *hw = &adapter->hw;
+       struct igb_ring *ring;
        u32 tqavcc, tqavctrl;
        u16 value;
 
        WARN_ON(hw->mac.type != e1000_i210);
        WARN_ON(queue < 0 || queue > 1);
+       ring = adapter->tx_ring[queue];
 
        /* If any of the Qav features is enabled, configure queues as SR and
         * with HIGH PRIO. If none is, then configure them with LOW PRIO and
@@ -3615,6 +3623,7 @@ err_sw_init:
 err_ioremap:
        free_netdev(netdev);
 err_alloc_etherdev:
+       pci_disable_pcie_error_reporting(pdev);
        pci_release_mem_regions(pdev);
 err_pci_reg:
 err_dma:
@@ -4835,6 +4844,8 @@ static void igb_clean_tx_ring(struct igb_ring *tx_ring)
                                               DMA_TO_DEVICE);
                }
 
+               tx_buffer->next_to_watch = NULL;
+
                /* move us one more past the eop_desc for start of next pkt */
                tx_buffer++;
                i++;
index 9e0bbb2..5901ed9 100644 (file)
@@ -578,7 +578,7 @@ static inline s32 igc_read_phy_reg(struct igc_hw *hw, u32 offset, u16 *data)
        if (hw->phy.ops.read_reg)
                return hw->phy.ops.read_reg(hw, offset, data);
 
-       return 0;
+       return -EOPNOTSUPP;
 }
 
 void igc_reinit_locked(struct igc_adapter *);
index 9532309..e29aadb 100644 (file)
@@ -232,6 +232,8 @@ static void igc_clean_tx_ring(struct igc_ring *tx_ring)
                                igc_unmap_tx_buffer(tx_ring->dev, tx_buffer);
                }
 
+               tx_buffer->next_to_watch = NULL;
+
                /* move us one more past the eop_desc for start of next pkt */
                tx_buffer++;
                i++;
@@ -6054,6 +6056,7 @@ err_sw_init:
 err_ioremap:
        free_netdev(netdev);
 err_alloc_etherdev:
+       pci_disable_pcie_error_reporting(pdev);
        pci_release_mem_regions(pdev);
 err_pci_reg:
 err_dma:
index ffff69e..913253f 100644 (file)
@@ -11067,6 +11067,7 @@ err_ioremap:
        disable_dev = !test_and_set_bit(__IXGBE_DISABLED, &adapter->state);
        free_netdev(netdev);
 err_alloc_etherdev:
+       pci_disable_pcie_error_reporting(pdev);
        pci_release_mem_regions(pdev);
 err_pci_reg:
 err_dma:
index caaea2c..e3e4676 100644 (file)
@@ -211,7 +211,7 @@ struct xfrm_state *ixgbevf_ipsec_find_rx_state(struct ixgbevf_ipsec *ipsec,
 static int ixgbevf_ipsec_parse_proto_keys(struct xfrm_state *xs,
                                          u32 *mykey, u32 *mysalt)
 {
-       struct net_device *dev = xs->xso.dev;
+       struct net_device *dev = xs->xso.real_dev;
        unsigned char *key_data;
        char *alg_name = NULL;
        int key_len;
@@ -260,12 +260,15 @@ static int ixgbevf_ipsec_parse_proto_keys(struct xfrm_state *xs,
  **/
 static int ixgbevf_ipsec_add_sa(struct xfrm_state *xs)
 {
-       struct net_device *dev = xs->xso.dev;
-       struct ixgbevf_adapter *adapter = netdev_priv(dev);
-       struct ixgbevf_ipsec *ipsec = adapter->ipsec;
+       struct net_device *dev = xs->xso.real_dev;
+       struct ixgbevf_adapter *adapter;
+       struct ixgbevf_ipsec *ipsec;
        u16 sa_idx;
        int ret;
 
+       adapter = netdev_priv(dev);
+       ipsec = adapter->ipsec;
+
        if (xs->id.proto != IPPROTO_ESP && xs->id.proto != IPPROTO_AH) {
                netdev_err(dev, "Unsupported protocol 0x%04x for IPsec offload\n",
                           xs->id.proto);
@@ -383,11 +386,14 @@ static int ixgbevf_ipsec_add_sa(struct xfrm_state *xs)
  **/
 static void ixgbevf_ipsec_del_sa(struct xfrm_state *xs)
 {
-       struct net_device *dev = xs->xso.dev;
-       struct ixgbevf_adapter *adapter = netdev_priv(dev);
-       struct ixgbevf_ipsec *ipsec = adapter->ipsec;
+       struct net_device *dev = xs->xso.real_dev;
+       struct ixgbevf_adapter *adapter;
+       struct ixgbevf_ipsec *ipsec;
        u16 sa_idx;
 
+       adapter = netdev_priv(dev);
+       ipsec = adapter->ipsec;
+
        if (xs->xso.flags & XFRM_OFFLOAD_INBOUND) {
                sa_idx = xs->xso.offload_handle - IXGBE_IPSEC_BASE_RX_INDEX;
 
index 361bc4f..76a7777 100644 (file)
@@ -2299,19 +2299,19 @@ mvneta_swbm_add_rx_fragment(struct mvneta_port *pp,
                skb_frag_off_set(frag, pp->rx_offset_correction);
                skb_frag_size_set(frag, data_len);
                __skb_frag_set_page(frag, page);
-
-               /* last fragment */
-               if (len == *size) {
-                       struct skb_shared_info *sinfo;
-
-                       sinfo = xdp_get_shared_info_from_buff(xdp);
-                       sinfo->nr_frags = xdp_sinfo->nr_frags;
-                       memcpy(sinfo->frags, xdp_sinfo->frags,
-                              sinfo->nr_frags * sizeof(skb_frag_t));
-               }
        } else {
                page_pool_put_full_page(rxq->page_pool, page, true);
        }
+
+       /* last fragment */
+       if (len == *size) {
+               struct skb_shared_info *sinfo;
+
+               sinfo = xdp_get_shared_info_from_buff(xdp);
+               sinfo->nr_frags = xdp_sinfo->nr_frags;
+               memcpy(sinfo->frags, xdp_sinfo->frags,
+                      sinfo->nr_frags * sizeof(skb_frag_t));
+       }
        *size -= len;
 }
 
index fac6474..9169849 100644 (file)
@@ -86,6 +86,22 @@ bool is_lmac_valid(struct cgx *cgx, int lmac_id)
        return test_bit(lmac_id, &cgx->lmac_bmap);
 }
 
+/* Helper function to get sequential index
+ * given the enabled LMAC of a CGX
+ */
+static int get_sequence_id_of_lmac(struct cgx *cgx, int lmac_id)
+{
+       int tmp, id = 0;
+
+       for_each_set_bit(tmp, &cgx->lmac_bmap, MAX_LMAC_PER_CGX) {
+               if (tmp == lmac_id)
+                       break;
+               id++;
+       }
+
+       return id;
+}
+
 struct mac_ops *get_mac_ops(void *cgxd)
 {
        if (!cgxd)
@@ -211,37 +227,257 @@ static u64 mac2u64 (u8 *mac_addr)
        return mac;
 }
 
+static void cfg2mac(u64 cfg, u8 *mac_addr)
+{
+       int i, index = 0;
+
+       for (i = ETH_ALEN - 1; i >= 0; i--, index++)
+               mac_addr[i] = (cfg >> (8 * index)) & 0xFF;
+}
+
 int cgx_lmac_addr_set(u8 cgx_id, u8 lmac_id, u8 *mac_addr)
 {
        struct cgx *cgx_dev = cgx_get_pdata(cgx_id);
+       struct lmac *lmac = lmac_pdata(lmac_id, cgx_dev);
        struct mac_ops *mac_ops;
+       int index, id;
        u64 cfg;
 
+       /* access mac_ops to know csr_offset */
        mac_ops = cgx_dev->mac_ops;
+
        /* copy 6bytes from macaddr */
        /* memcpy(&cfg, mac_addr, 6); */
 
        cfg = mac2u64 (mac_addr);
 
-       cgx_write(cgx_dev, 0, (CGXX_CMRX_RX_DMAC_CAM0 + (lmac_id * 0x8)),
+       id = get_sequence_id_of_lmac(cgx_dev, lmac_id);
+
+       index = id * lmac->mac_to_index_bmap.max;
+
+       cgx_write(cgx_dev, 0, (CGXX_CMRX_RX_DMAC_CAM0 + (index * 0x8)),
                  cfg | CGX_DMAC_CAM_ADDR_ENABLE | ((u64)lmac_id << 49));
 
        cfg = cgx_read(cgx_dev, lmac_id, CGXX_CMRX_RX_DMAC_CTL0);
-       cfg |= CGX_DMAC_CTL0_CAM_ENABLE;
+       cfg |= (CGX_DMAC_CTL0_CAM_ENABLE | CGX_DMAC_BCAST_MODE |
+               CGX_DMAC_MCAST_MODE);
        cgx_write(cgx_dev, lmac_id, CGXX_CMRX_RX_DMAC_CTL0, cfg);
 
        return 0;
 }
 
+u64 cgx_read_dmac_ctrl(void *cgxd, int lmac_id)
+{
+       struct mac_ops *mac_ops;
+       struct cgx *cgx = cgxd;
+
+       if (!cgxd || !is_lmac_valid(cgxd, lmac_id))
+               return 0;
+
+       cgx = cgxd;
+       /* Get mac_ops to know csr offset */
+       mac_ops = cgx->mac_ops;
+
+       return cgx_read(cgxd, lmac_id, CGXX_CMRX_RX_DMAC_CTL0);
+}
+
+u64 cgx_read_dmac_entry(void *cgxd, int index)
+{
+       struct mac_ops *mac_ops;
+       struct cgx *cgx;
+
+       if (!cgxd)
+               return 0;
+
+       cgx = cgxd;
+       mac_ops = cgx->mac_ops;
+       return cgx_read(cgx, 0, (CGXX_CMRX_RX_DMAC_CAM0 + (index * 8)));
+}
+
+int cgx_lmac_addr_add(u8 cgx_id, u8 lmac_id, u8 *mac_addr)
+{
+       struct cgx *cgx_dev = cgx_get_pdata(cgx_id);
+       struct lmac *lmac = lmac_pdata(lmac_id, cgx_dev);
+       struct mac_ops *mac_ops;
+       int index, idx;
+       u64 cfg = 0;
+       int id;
+
+       if (!lmac)
+               return -ENODEV;
+
+       mac_ops = cgx_dev->mac_ops;
+       /* Get available index where entry is to be installed */
+       idx = rvu_alloc_rsrc(&lmac->mac_to_index_bmap);
+       if (idx < 0)
+               return idx;
+
+       id = get_sequence_id_of_lmac(cgx_dev, lmac_id);
+
+       index = id * lmac->mac_to_index_bmap.max + idx;
+
+       cfg = mac2u64 (mac_addr);
+       cfg |= CGX_DMAC_CAM_ADDR_ENABLE;
+       cfg |= ((u64)lmac_id << 49);
+       cgx_write(cgx_dev, 0, (CGXX_CMRX_RX_DMAC_CAM0 + (index * 0x8)), cfg);
+
+       cfg = cgx_read(cgx_dev, lmac_id, CGXX_CMRX_RX_DMAC_CTL0);
+       cfg |= (CGX_DMAC_BCAST_MODE | CGX_DMAC_CAM_ACCEPT);
+
+       if (is_multicast_ether_addr(mac_addr)) {
+               cfg &= ~GENMASK_ULL(2, 1);
+               cfg |= CGX_DMAC_MCAST_MODE_CAM;
+               lmac->mcast_filters_count++;
+       } else if (!lmac->mcast_filters_count) {
+               cfg |= CGX_DMAC_MCAST_MODE;
+       }
+
+       cgx_write(cgx_dev, lmac_id, CGXX_CMRX_RX_DMAC_CTL0, cfg);
+
+       return idx;
+}
+
+int cgx_lmac_addr_reset(u8 cgx_id, u8 lmac_id)
+{
+       struct cgx *cgx_dev = cgx_get_pdata(cgx_id);
+       struct lmac *lmac = lmac_pdata(lmac_id, cgx_dev);
+       struct mac_ops *mac_ops;
+       u8 index = 0, id;
+       u64 cfg;
+
+       if (!lmac)
+               return -ENODEV;
+
+       mac_ops = cgx_dev->mac_ops;
+       /* Restore index 0 to its default init value as done during
+        * cgx_lmac_init
+        */
+       set_bit(0, lmac->mac_to_index_bmap.bmap);
+
+       id = get_sequence_id_of_lmac(cgx_dev, lmac_id);
+
+       index = id * lmac->mac_to_index_bmap.max + index;
+       cgx_write(cgx_dev, 0, (CGXX_CMRX_RX_DMAC_CAM0 + (index * 0x8)), 0);
+
+       /* Reset CGXX_CMRX_RX_DMAC_CTL0 register to default state */
+       cfg = cgx_read(cgx_dev, lmac_id, CGXX_CMRX_RX_DMAC_CTL0);
+       cfg &= ~CGX_DMAC_CAM_ACCEPT;
+       cfg |= (CGX_DMAC_BCAST_MODE | CGX_DMAC_MCAST_MODE);
+       cgx_write(cgx_dev, lmac_id, CGXX_CMRX_RX_DMAC_CTL0, cfg);
+
+       return 0;
+}
+
+/* Allows caller to change macaddress associated with index
+ * in dmac filter table including index 0 reserved for
+ * interface mac address
+ */
+int cgx_lmac_addr_update(u8 cgx_id, u8 lmac_id, u8 *mac_addr, u8 index)
+{
+       struct cgx *cgx_dev = cgx_get_pdata(cgx_id);
+       struct mac_ops *mac_ops;
+       struct lmac *lmac;
+       u64 cfg;
+       int id;
+
+       lmac = lmac_pdata(lmac_id, cgx_dev);
+       if (!lmac)
+               return -ENODEV;
+
+       mac_ops = cgx_dev->mac_ops;
+       /* Validate the index */
+       if (index >= lmac->mac_to_index_bmap.max)
+               return -EINVAL;
+
+       /* ensure index is already set */
+       if (!test_bit(index, lmac->mac_to_index_bmap.bmap))
+               return -EINVAL;
+
+       id = get_sequence_id_of_lmac(cgx_dev, lmac_id);
+
+       index = id * lmac->mac_to_index_bmap.max + index;
+
+       cfg = cgx_read(cgx_dev, 0, (CGXX_CMRX_RX_DMAC_CAM0 + (index * 0x8)));
+       cfg &= ~CGX_RX_DMAC_ADR_MASK;
+       cfg |= mac2u64 (mac_addr);
+
+       cgx_write(cgx_dev, 0, (CGXX_CMRX_RX_DMAC_CAM0 + (index * 0x8)), cfg);
+       return 0;
+}
+
+int cgx_lmac_addr_del(u8 cgx_id, u8 lmac_id, u8 index)
+{
+       struct cgx *cgx_dev = cgx_get_pdata(cgx_id);
+       struct lmac *lmac = lmac_pdata(lmac_id, cgx_dev);
+       struct mac_ops *mac_ops;
+       u8 mac[ETH_ALEN];
+       u64 cfg;
+       int id;
+
+       if (!lmac)
+               return -ENODEV;
+
+       mac_ops = cgx_dev->mac_ops;
+       /* Validate the index */
+       if (index >= lmac->mac_to_index_bmap.max)
+               return -EINVAL;
+
+       /* Skip deletion for reserved index i.e. index 0 */
+       if (index == 0)
+               return 0;
+
+       rvu_free_rsrc(&lmac->mac_to_index_bmap, index);
+
+       id = get_sequence_id_of_lmac(cgx_dev, lmac_id);
+
+       index = id * lmac->mac_to_index_bmap.max + index;
+
+       /* Read MAC address to check whether it is ucast or mcast */
+       cfg = cgx_read(cgx_dev, 0, (CGXX_CMRX_RX_DMAC_CAM0 + (index * 0x8)));
+
+       cfg2mac(cfg, mac);
+       if (is_multicast_ether_addr(mac))
+               lmac->mcast_filters_count--;
+
+       if (!lmac->mcast_filters_count) {
+               cfg = cgx_read(cgx_dev, lmac_id, CGXX_CMRX_RX_DMAC_CTL0);
+               cfg &= ~GENMASK_ULL(2, 1);
+               cfg |= CGX_DMAC_MCAST_MODE;
+               cgx_write(cgx_dev, lmac_id, CGXX_CMRX_RX_DMAC_CTL0, cfg);
+       }
+
+       cgx_write(cgx_dev, 0, (CGXX_CMRX_RX_DMAC_CAM0 + (index * 0x8)), 0);
+
+       return 0;
+}
+
+int cgx_lmac_addr_max_entries_get(u8 cgx_id, u8 lmac_id)
+{
+       struct cgx *cgx_dev = cgx_get_pdata(cgx_id);
+       struct lmac *lmac = lmac_pdata(lmac_id, cgx_dev);
+
+       if (lmac)
+               return lmac->mac_to_index_bmap.max;
+
+       return 0;
+}
+
 u64 cgx_lmac_addr_get(u8 cgx_id, u8 lmac_id)
 {
        struct cgx *cgx_dev = cgx_get_pdata(cgx_id);
+       struct lmac *lmac = lmac_pdata(lmac_id, cgx_dev);
        struct mac_ops *mac_ops;
+       int index;
        u64 cfg;
+       int id;
 
        mac_ops = cgx_dev->mac_ops;
 
-       cfg = cgx_read(cgx_dev, 0, CGXX_CMRX_RX_DMAC_CAM0 + lmac_id * 0x8);
+       id = get_sequence_id_of_lmac(cgx_dev, lmac_id);
+
+       index = id * lmac->mac_to_index_bmap.max;
+
+       cfg = cgx_read(cgx_dev, 0, CGXX_CMRX_RX_DMAC_CAM0 + index * 0x8);
        return cfg & CGX_RX_DMAC_ADR_MASK;
 }
 
@@ -297,35 +533,51 @@ int cgx_lmac_internal_loopback(void *cgxd, int lmac_id, bool enable)
 void cgx_lmac_promisc_config(int cgx_id, int lmac_id, bool enable)
 {
        struct cgx *cgx = cgx_get_pdata(cgx_id);
+       struct lmac *lmac = lmac_pdata(lmac_id, cgx);
+       u16 max_dmac = lmac->mac_to_index_bmap.max;
        struct mac_ops *mac_ops;
+       int index, i;
        u64 cfg = 0;
+       int id;
 
        if (!cgx)
                return;
 
+       id = get_sequence_id_of_lmac(cgx, lmac_id);
+
        mac_ops = cgx->mac_ops;
        if (enable) {
                /* Enable promiscuous mode on LMAC */
                cfg = cgx_read(cgx, lmac_id, CGXX_CMRX_RX_DMAC_CTL0);
-               cfg &= ~(CGX_DMAC_CAM_ACCEPT | CGX_DMAC_MCAST_MODE);
-               cfg |= CGX_DMAC_BCAST_MODE;
+               cfg &= ~CGX_DMAC_CAM_ACCEPT;
+               cfg |= (CGX_DMAC_BCAST_MODE | CGX_DMAC_MCAST_MODE);
                cgx_write(cgx, lmac_id, CGXX_CMRX_RX_DMAC_CTL0, cfg);
 
-               cfg = cgx_read(cgx, 0,
-                              (CGXX_CMRX_RX_DMAC_CAM0 + lmac_id * 0x8));
-               cfg &= ~CGX_DMAC_CAM_ADDR_ENABLE;
-               cgx_write(cgx, 0,
-                         (CGXX_CMRX_RX_DMAC_CAM0 + lmac_id * 0x8), cfg);
+               for (i = 0; i < max_dmac; i++) {
+                       index = id * max_dmac + i;
+                       cfg = cgx_read(cgx, 0,
+                                      (CGXX_CMRX_RX_DMAC_CAM0 + index * 0x8));
+                       cfg &= ~CGX_DMAC_CAM_ADDR_ENABLE;
+                       cgx_write(cgx, 0,
+                                 (CGXX_CMRX_RX_DMAC_CAM0 + index * 0x8), cfg);
+               }
        } else {
                /* Disable promiscuous mode */
                cfg = cgx_read(cgx, lmac_id, CGXX_CMRX_RX_DMAC_CTL0);
                cfg |= CGX_DMAC_CAM_ACCEPT | CGX_DMAC_MCAST_MODE;
                cgx_write(cgx, lmac_id, CGXX_CMRX_RX_DMAC_CTL0, cfg);
-               cfg = cgx_read(cgx, 0,
-                              (CGXX_CMRX_RX_DMAC_CAM0 + lmac_id * 0x8));
-               cfg |= CGX_DMAC_CAM_ADDR_ENABLE;
-               cgx_write(cgx, 0,
-                         (CGXX_CMRX_RX_DMAC_CAM0 + lmac_id * 0x8), cfg);
+               for (i = 0; i < max_dmac; i++) {
+                       index = id * max_dmac + i;
+                       cfg = cgx_read(cgx, 0,
+                                      (CGXX_CMRX_RX_DMAC_CAM0 + index * 0x8));
+                       if ((cfg & CGX_RX_DMAC_ADR_MASK) != 0) {
+                               cfg |= CGX_DMAC_CAM_ADDR_ENABLE;
+                               cgx_write(cgx, 0,
+                                         (CGXX_CMRX_RX_DMAC_CAM0 +
+                                          index * 0x8),
+                                         cfg);
+                       }
+               }
        }
 }
 
@@ -1234,6 +1486,15 @@ static int cgx_lmac_init(struct cgx *cgx)
                }
 
                lmac->cgx = cgx;
+               lmac->mac_to_index_bmap.max =
+                               MAX_DMAC_ENTRIES_PER_CGX / cgx->lmac_count;
+               err = rvu_alloc_bitmap(&lmac->mac_to_index_bmap);
+               if (err)
+                       return err;
+
+               /* Reserve first entry for default MAC address */
+               set_bit(0, lmac->mac_to_index_bmap.bmap);
+
                init_waitqueue_head(&lmac->wq_cmd_cmplt);
                mutex_init(&lmac->cmd_lock);
                spin_lock_init(&lmac->event_cb_lock);
@@ -1274,6 +1535,7 @@ static int cgx_lmac_exit(struct cgx *cgx)
                        continue;
                cgx->mac_ops->mac_pause_frm_config(cgx, lmac->lmac_id, false);
                cgx_configure_interrupt(cgx, lmac, lmac->lmac_id, true);
+               kfree(lmac->mac_to_index_bmap.bmap);
                kfree(lmac->name);
                kfree(lmac);
        }
index 1252126..237ba2b 100644 (file)
@@ -23,6 +23,7 @@
 
 #define CGX_ID_MASK                    0x7
 #define MAX_LMAC_PER_CGX               4
+#define MAX_DMAC_ENTRIES_PER_CGX       32
 #define CGX_FIFO_LEN                   65536 /* 64K for both Rx & Tx */
 #define CGX_OFFSET(x)                  ((x) * MAX_LMAC_PER_CGX)
 
 #define CGXX_CMRX_RX_DMAC_CTL0         (0x1F8 + mac_ops->csr_offset)
 #define CGX_DMAC_CTL0_CAM_ENABLE       BIT_ULL(3)
 #define CGX_DMAC_CAM_ACCEPT            BIT_ULL(3)
+#define CGX_DMAC_MCAST_MODE_CAM                BIT_ULL(2)
 #define CGX_DMAC_MCAST_MODE            BIT_ULL(1)
 #define CGX_DMAC_BCAST_MODE            BIT_ULL(0)
 #define CGXX_CMRX_RX_DMAC_CAM0         (0x200 + mac_ops->csr_offset)
 #define CGX_DMAC_CAM_ADDR_ENABLE       BIT_ULL(48)
+#define CGX_DMAC_CAM_ENTRY_LMACID      GENMASK_ULL(50, 49)
 #define CGXX_CMRX_RX_DMAC_CAM1         0x400
 #define CGX_RX_DMAC_ADR_MASK           GENMASK_ULL(47, 0)
 #define CGXX_CMRX_TX_STAT0             0x700
@@ -139,7 +142,11 @@ int cgx_get_rx_stats(void *cgxd, int lmac_id, int idx, u64 *rx_stat);
 int cgx_lmac_rx_tx_enable(void *cgxd, int lmac_id, bool enable);
 int cgx_lmac_tx_enable(void *cgxd, int lmac_id, bool enable);
 int cgx_lmac_addr_set(u8 cgx_id, u8 lmac_id, u8 *mac_addr);
+int cgx_lmac_addr_reset(u8 cgx_id, u8 lmac_id);
 u64 cgx_lmac_addr_get(u8 cgx_id, u8 lmac_id);
+int cgx_lmac_addr_add(u8 cgx_id, u8 lmac_id, u8 *mac_addr);
+int cgx_lmac_addr_del(u8 cgx_id, u8 lmac_id, u8 index);
+int cgx_lmac_addr_max_entries_get(u8 cgx_id, u8 lmac_id);
 void cgx_lmac_promisc_config(int cgx_id, int lmac_id, bool enable);
 void cgx_lmac_enadis_rx_pause_fwding(void *cgxd, int lmac_id, bool enable);
 int cgx_lmac_internal_loopback(void *cgxd, int lmac_id, bool enable);
@@ -165,4 +172,7 @@ u8 cgx_get_lmacid(void *cgxd, u8 lmac_index);
 unsigned long cgx_get_lmac_bmap(void *cgxd);
 void cgx_lmac_write(int cgx_id, int lmac_id, u64 offset, u64 val);
 u64 cgx_lmac_read(int cgx_id, int lmac_id, u64 offset);
+int cgx_lmac_addr_update(u8 cgx_id, u8 lmac_id, u8 *mac_addr, u8 index);
+u64 cgx_read_dmac_ctrl(void *cgxd, int lmac_id);
+u64 cgx_read_dmac_entry(void *cgxd, int index);
 #endif /* CGX_H */
index 45706fd..a8b7b1c 100644 (file)
 #include "rvu.h"
 #include "cgx.h"
 /**
- * struct lmac
+ * struct lmac - per lmac locks and properties
  * @wq_cmd_cmplt:      waitq to keep the process blocked until cmd completion
  * @cmd_lock:          Lock to serialize the command interface
  * @resp:              command response
  * @link_info:         link related information
+ * @mac_to_index_bmap: Mac address to CGX table index mapping
  * @event_cb:          callback for linkchange events
  * @event_cb_lock:     lock for serializing callback with unregister
- * @cmd_pend:          flag set before new command is started
- *                     flag cleared after command response is received
  * @cgx:               parent cgx port
+ * @mcast_filters_count:  Number of multicast filters installed
  * @lmac_id:           lmac port id
+ * @cmd_pend:          flag set before new command is started
+ *                     flag cleared after command response is received
  * @name:              lmac port name
  */
 struct lmac {
@@ -29,12 +31,14 @@ struct lmac {
        struct mutex cmd_lock;
        u64 resp;
        struct cgx_link_user_info link_info;
+       struct rsrc_bmap mac_to_index_bmap;
        struct cgx_event_cb event_cb;
        /* lock for serializing callback with unregister */
        spinlock_t event_cb_lock;
-       bool cmd_pend;
        struct cgx *cgx;
+       u8 mcast_filters_count;
        u8 lmac_id;
+       bool cmd_pend;
        char *name;
 };
 
index 770d862..f5ec39d 100644 (file)
@@ -134,6 +134,8 @@ M(MSIX_OFFSET,              0x005, msix_offset, msg_req, msix_offset_rsp)   \
 M(VF_FLR,              0x006, vf_flr, msg_req, msg_rsp)                \
 M(PTP_OP,              0x007, ptp_op, ptp_req, ptp_rsp)                \
 M(GET_HW_CAP,          0x008, get_hw_cap, msg_req, get_hw_cap_rsp)     \
+M(LMTST_TBL_SETUP,     0x00a, lmtst_tbl_setup, lmtst_tbl_setup_req,    \
+                               msg_rsp)                                \
 M(SET_VF_PERM,         0x00b, set_vf_perm, set_vf_perm, msg_rsp)       \
 /* CGX mbox IDs (range 0x200 - 0x3FF) */                               \
 M(CGX_START_RXTX,      0x200, cgx_start_rxtx, msg_req, msg_rsp)        \
@@ -163,7 +165,15 @@ M(CGX_SET_LINK_MODE,       0x214, cgx_set_link_mode, cgx_set_link_mode_req,\
 M(CGX_FEATURES_GET,    0x215, cgx_features_get, msg_req,               \
                               cgx_features_info_msg)                   \
 M(RPM_STATS,           0x216, rpm_stats, msg_req, rpm_stats_rsp)       \
- /* NPA mbox IDs (range 0x400 - 0x5FF) */                              \
+M(CGX_MAC_ADDR_ADD,    0x217, cgx_mac_addr_add, cgx_mac_addr_add_req,    \
+                              cgx_mac_addr_add_rsp)            \
+M(CGX_MAC_ADDR_DEL,    0x218, cgx_mac_addr_del, cgx_mac_addr_del_req,    \
+                              msg_rsp)         \
+M(CGX_MAC_MAX_ENTRIES_GET, 0x219, cgx_mac_max_entries_get, msg_req,    \
+                                 cgx_max_dmac_entries_get_rsp)         \
+M(CGX_MAC_ADDR_RESET,  0x21A, cgx_mac_addr_reset, msg_req, msg_rsp)    \
+M(CGX_MAC_ADDR_UPDATE, 0x21B, cgx_mac_addr_update, cgx_mac_addr_update_req, \
+                              msg_rsp)                                 \
 /* NPA mbox IDs (range 0x400 - 0x5FF) */                               \
 M(NPA_LF_ALLOC,                0x400, npa_lf_alloc,                            \
                                npa_lf_alloc_req, npa_lf_alloc_rsp)     \
@@ -401,6 +411,38 @@ struct cgx_mac_addr_set_or_get {
        u8 mac_addr[ETH_ALEN];
 };
 
+/* Structure for requesting the operation to
+ * add DMAC filter entry into CGX interface
+ */
+struct cgx_mac_addr_add_req {
+       struct mbox_msghdr hdr;
+       u8 mac_addr[ETH_ALEN];
+};
+
+/* Structure for response against the operation to
+ * add DMAC filter entry into CGX interface
+ */
+struct cgx_mac_addr_add_rsp {
+       struct mbox_msghdr hdr;
+       u8 index;
+};
+
+/* Structure for requesting the operation to
+ * delete DMAC filter entry from CGX interface
+ */
+struct cgx_mac_addr_del_req {
+       struct mbox_msghdr hdr;
+       u8 index;
+};
+
+/* Structure for response against the operation to
+ * get maximum supported DMAC filter entries
+ */
+struct cgx_max_dmac_entries_get_rsp {
+       struct mbox_msghdr hdr;
+       u8 max_dmac_filters;
+};
+
 struct cgx_link_user_info {
        uint64_t link_up:1;
        uint64_t full_duplex:1;
@@ -499,6 +541,12 @@ struct cgx_set_link_mode_rsp {
        int status;
 };
 
+struct cgx_mac_addr_update_req {
+       struct mbox_msghdr hdr;
+       u8 mac_addr[ETH_ALEN];
+       u8 index;
+};
+
 #define RVU_LMAC_FEAT_FC               BIT_ULL(0) /* pause frames */
 #define RVU_LMAC_FEAT_PTP              BIT_ULL(1) /* precision time protocol */
 #define RVU_MAC_VERSION                        BIT_ULL(2)
@@ -1278,6 +1326,14 @@ struct set_vf_perm  {
        u64     flags;
 };
 
+struct lmtst_tbl_setup_req {
+       struct mbox_msghdr hdr;
+       u16 base_pcifunc;
+       u8  use_local_lmt_region;
+       u64 lmt_iova;
+       u64 rsvd[4];
+};
+
 /* CPT mailbox error codes
  * Range 901 - 1000.
  */
index 0b09294..10cddf1 100644 (file)
@@ -2333,6 +2333,7 @@ static void __rvu_flr_handler(struct rvu *rvu, u16 pcifunc)
        rvu_blklf_teardown(rvu, pcifunc, BLKADDR_SSOW);
        rvu_blklf_teardown(rvu, pcifunc, BLKADDR_SSO);
        rvu_blklf_teardown(rvu, pcifunc, BLKADDR_NPA);
+       rvu_reset_lmt_map_tbl(rvu, pcifunc);
        rvu_detach_rsrcs(rvu, NULL, pcifunc);
        mutex_unlock(&rvu->flr_lock);
 }
index 9e5d9ba..10e58a5 100644 (file)
@@ -243,6 +243,7 @@ struct rvu_pfvf {
        u8      nix_blkaddr; /* BLKADDR_NIX0/1 assigned to this PF */
        u8      nix_rx_intf; /* NIX0_RX/NIX1_RX interface to NPC */
        u8      nix_tx_intf; /* NIX0_TX/NIX1_TX interface to NPC */
+       u64     lmt_base_addr; /* Preseving the pcifunc's lmtst base addr*/
        unsigned long flags;
 };
 
@@ -656,6 +657,8 @@ void rvu_cgx_enadis_rx_bp(struct rvu *rvu, int pf, bool enable);
 int rvu_cgx_start_stop_io(struct rvu *rvu, u16 pcifunc, bool start);
 int rvu_cgx_nix_cuml_stats(struct rvu *rvu, void *cgxd, int lmac_id, int index,
                           int rxtxflag, u64 *stat);
+void rvu_cgx_disable_dmac_entries(struct rvu *rvu, u16 pcifunc);
+
 /* NPA APIs */
 int rvu_npa_init(struct rvu *rvu);
 void rvu_npa_freemem(struct rvu *rvu);
@@ -741,6 +744,7 @@ void npc_read_mcam_entry(struct rvu *rvu, struct npc_mcam *mcam,
 bool is_mac_feature_supported(struct rvu *rvu, int pf, int feature);
 u32  rvu_cgx_get_fifolen(struct rvu *rvu);
 void *rvu_first_cgx_pdata(struct rvu *rvu);
+int cgxlmac_to_pf(struct rvu *rvu, int cgx_id, int lmac_id);
 
 int npc_get_nixlf_mcam_index(struct npc_mcam *mcam, u16 pcifunc, int nixlf,
                             int type);
@@ -754,6 +758,9 @@ int rvu_cpt_lf_teardown(struct rvu *rvu, u16 pcifunc, int lf, int slot);
 int rvu_set_channels_base(struct rvu *rvu);
 void rvu_program_channels(struct rvu *rvu);
 
+/* CN10K RVU - LMT*/
+void rvu_reset_lmt_map_tbl(struct rvu *rvu, u16 pcifunc);
+
 #ifdef CONFIG_DEBUG_FS
 void rvu_dbg_init(struct rvu *rvu);
 void rvu_dbg_exit(struct rvu *rvu);
index 6e2bf4f..6cc8fbb 100644 (file)
@@ -63,7 +63,7 @@ static u16 cgxlmac_to_pfmap(struct rvu *rvu, u8 cgx_id, u8 lmac_id)
        return rvu->cgxlmac2pf_map[CGX_OFFSET(cgx_id) + lmac_id];
 }
 
-static int cgxlmac_to_pf(struct rvu *rvu, int cgx_id, int lmac_id)
+int cgxlmac_to_pf(struct rvu *rvu, int cgx_id, int lmac_id)
 {
        unsigned long pfmap;
 
@@ -454,6 +454,31 @@ int rvu_cgx_config_rxtx(struct rvu *rvu, u16 pcifunc, bool start)
        return 0;
 }
 
+void rvu_cgx_disable_dmac_entries(struct rvu *rvu, u16 pcifunc)
+{
+       int pf = rvu_get_pf(pcifunc);
+       int i = 0, lmac_count = 0;
+       u8 max_dmac_filters;
+       u8 cgx_id, lmac_id;
+       void *cgx_dev;
+
+       if (!is_cgx_config_permitted(rvu, pcifunc))
+               return;
+
+       rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_id, &lmac_id);
+       cgx_dev = cgx_get_pdata(cgx_id);
+       lmac_count = cgx_get_lmac_cnt(cgx_dev);
+       max_dmac_filters = MAX_DMAC_ENTRIES_PER_CGX / lmac_count;
+
+       for (i = 0; i < max_dmac_filters; i++)
+               cgx_lmac_addr_del(cgx_id, lmac_id, i);
+
+       /* As cgx_lmac_addr_del does not clear entry for index 0
+        * so it needs to be done explicitly
+        */
+       cgx_lmac_addr_reset(cgx_id, lmac_id);
+}
+
 int rvu_mbox_handler_cgx_start_rxtx(struct rvu *rvu, struct msg_req *req,
                                    struct msg_rsp *rsp)
 {
@@ -557,6 +582,63 @@ int rvu_mbox_handler_cgx_mac_addr_set(struct rvu *rvu,
        return 0;
 }
 
+int rvu_mbox_handler_cgx_mac_addr_add(struct rvu *rvu,
+                                     struct cgx_mac_addr_add_req *req,
+                                     struct cgx_mac_addr_add_rsp *rsp)
+{
+       int pf = rvu_get_pf(req->hdr.pcifunc);
+       u8 cgx_id, lmac_id;
+       int rc = 0;
+
+       if (!is_cgx_config_permitted(rvu, req->hdr.pcifunc))
+               return -EPERM;
+
+       rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_id, &lmac_id);
+       rc = cgx_lmac_addr_add(cgx_id, lmac_id, req->mac_addr);
+       if (rc >= 0) {
+               rsp->index = rc;
+               return 0;
+       }
+
+       return rc;
+}
+
+int rvu_mbox_handler_cgx_mac_addr_del(struct rvu *rvu,
+                                     struct cgx_mac_addr_del_req *req,
+                                     struct msg_rsp *rsp)
+{
+       int pf = rvu_get_pf(req->hdr.pcifunc);
+       u8 cgx_id, lmac_id;
+
+       if (!is_cgx_config_permitted(rvu, req->hdr.pcifunc))
+               return -EPERM;
+
+       rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_id, &lmac_id);
+       return cgx_lmac_addr_del(cgx_id, lmac_id, req->index);
+}
+
+int rvu_mbox_handler_cgx_mac_max_entries_get(struct rvu *rvu,
+                                            struct msg_req *req,
+                                            struct cgx_max_dmac_entries_get_rsp
+                                            *rsp)
+{
+       int pf = rvu_get_pf(req->hdr.pcifunc);
+       u8 cgx_id, lmac_id;
+
+       /* If msg is received from PFs(which are not mapped to CGX LMACs)
+        * or VF then no entries are allocated for DMAC filters at CGX level.
+        * So returning zero.
+        */
+       if (!is_cgx_config_permitted(rvu, req->hdr.pcifunc)) {
+               rsp->max_dmac_filters = 0;
+               return 0;
+       }
+
+       rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_id, &lmac_id);
+       rsp->max_dmac_filters = cgx_lmac_addr_max_entries_get(cgx_id, lmac_id);
+       return 0;
+}
+
 int rvu_mbox_handler_cgx_mac_addr_get(struct rvu *rvu,
                                      struct cgx_mac_addr_set_or_get *req,
                                      struct cgx_mac_addr_set_or_get *rsp)
@@ -953,3 +1035,30 @@ int rvu_mbox_handler_cgx_set_link_mode(struct rvu *rvu,
        rsp->status = cgx_set_link_mode(cgxd, req->args, cgx_idx, lmac);
        return 0;
 }
+
+int rvu_mbox_handler_cgx_mac_addr_reset(struct rvu *rvu, struct msg_req *req,
+                                       struct msg_rsp *rsp)
+{
+       int pf = rvu_get_pf(req->hdr.pcifunc);
+       u8 cgx_id, lmac_id;
+
+       if (!is_cgx_config_permitted(rvu, req->hdr.pcifunc))
+               return -EPERM;
+
+       rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_id, &lmac_id);
+       return cgx_lmac_addr_reset(cgx_id, lmac_id);
+}
+
+int rvu_mbox_handler_cgx_mac_addr_update(struct rvu *rvu,
+                                        struct cgx_mac_addr_update_req *req,
+                                        struct msg_rsp *rsp)
+{
+       int pf = rvu_get_pf(req->hdr.pcifunc);
+       u8 cgx_id, lmac_id;
+
+       if (!is_cgx_config_permitted(rvu, req->hdr.pcifunc))
+               return -EPERM;
+
+       rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_id, &lmac_id);
+       return cgx_lmac_addr_update(cgx_id, lmac_id, req->mac_addr, req->index);
+}
index 7d9e71c..8d48b64 100644 (file)
 #include "cgx.h"
 #include "rvu_reg.h"
 
+/* RVU LMTST */
+#define LMT_TBL_OP_READ                0
+#define LMT_TBL_OP_WRITE       1
+#define LMT_MAP_TABLE_SIZE     (128 * 1024)
+#define LMT_MAPTBL_ENTRY_SIZE  16
+
+/* Function to perform operations (read/write) on lmtst map table */
+static int lmtst_map_table_ops(struct rvu *rvu, u32 index, u64 *val,
+                              int lmt_tbl_op)
+{
+       void __iomem *lmt_map_base;
+       u64 tbl_base;
+
+       tbl_base = rvu_read64(rvu, BLKADDR_APR, APR_AF_LMT_MAP_BASE);
+
+       lmt_map_base = ioremap_wc(tbl_base, LMT_MAP_TABLE_SIZE);
+       if (!lmt_map_base) {
+               dev_err(rvu->dev, "Failed to setup lmt map table mapping!!\n");
+               return -ENOMEM;
+       }
+
+       if (lmt_tbl_op == LMT_TBL_OP_READ) {
+               *val = readq(lmt_map_base + index);
+       } else {
+               writeq((*val), (lmt_map_base + index));
+               /* Flushing the AP interceptor cache to make APR_LMT_MAP_ENTRY_S
+                * changes effective. Write 1 for flush and read is being used as a
+                * barrier and sets up a data dependency. Write to 0 after a write
+                * to 1 to complete the flush.
+                */
+               rvu_write64(rvu, BLKADDR_APR, APR_AF_LMT_CTL, BIT_ULL(0));
+               rvu_read64(rvu, BLKADDR_APR, APR_AF_LMT_CTL);
+               rvu_write64(rvu, BLKADDR_APR, APR_AF_LMT_CTL, 0x00);
+       }
+
+       iounmap(lmt_map_base);
+       return 0;
+}
+
+static u32 rvu_get_lmtst_tbl_index(struct rvu *rvu, u16 pcifunc)
+{
+       return ((rvu_get_pf(pcifunc) * rvu->hw->total_vfs) +
+               (pcifunc & RVU_PFVF_FUNC_MASK)) * LMT_MAPTBL_ENTRY_SIZE;
+}
+
+static int rvu_get_lmtaddr(struct rvu *rvu, u16 pcifunc,
+                          u64 iova, u64 *lmt_addr)
+{
+       u64 pa, val, pf;
+       int err;
+
+       if (!iova) {
+               dev_err(rvu->dev, "%s Requested Null address for transulation\n", __func__);
+               return -EINVAL;
+       }
+
+       rvu_write64(rvu, BLKADDR_RVUM, RVU_AF_SMMU_ADDR_REQ, iova);
+       pf = rvu_get_pf(pcifunc) & 0x1F;
+       val = BIT_ULL(63) | BIT_ULL(14) | BIT_ULL(13) | pf << 8 |
+             ((pcifunc & RVU_PFVF_FUNC_MASK) & 0xFF);
+       rvu_write64(rvu, BLKADDR_RVUM, RVU_AF_SMMU_TXN_REQ, val);
+
+       err = rvu_poll_reg(rvu, BLKADDR_RVUM, RVU_AF_SMMU_ADDR_RSP_STS, BIT_ULL(0), false);
+       if (err) {
+               dev_err(rvu->dev, "%s LMTLINE iova transulation failed\n", __func__);
+               return err;
+       }
+       val = rvu_read64(rvu, BLKADDR_RVUM, RVU_AF_SMMU_ADDR_RSP_STS);
+       if (val & ~0x1ULL) {
+               dev_err(rvu->dev, "%s LMTLINE iova transulation failed err:%llx\n", __func__, val);
+               return -EIO;
+       }
+       /* PA[51:12] = RVU_AF_SMMU_TLN_FLIT1[60:21]
+        * PA[11:0] = IOVA[11:0]
+        */
+       pa = rvu_read64(rvu, BLKADDR_RVUM, RVU_AF_SMMU_TLN_FLIT1) >> 21;
+       pa &= GENMASK_ULL(39, 0);
+       *lmt_addr = (pa << 12) | (iova  & 0xFFF);
+
+       return 0;
+}
+
+static int rvu_update_lmtaddr(struct rvu *rvu, u16 pcifunc, u64 lmt_addr)
+{
+       struct rvu_pfvf *pfvf = rvu_get_pfvf(rvu, pcifunc);
+       u32 tbl_idx;
+       int err = 0;
+       u64 val;
+
+       /* Read the current lmt addr of pcifunc */
+       tbl_idx = rvu_get_lmtst_tbl_index(rvu, pcifunc);
+       err = lmtst_map_table_ops(rvu, tbl_idx, &val, LMT_TBL_OP_READ);
+       if (err) {
+               dev_err(rvu->dev,
+                       "Failed to read LMT map table: index 0x%x err %d\n",
+                       tbl_idx, err);
+               return err;
+       }
+
+       /* Storing the seondary's lmt base address as this needs to be
+        * reverted in FLR. Also making sure this default value doesn't
+        * get overwritten on multiple calls to this mailbox.
+        */
+       if (!pfvf->lmt_base_addr)
+               pfvf->lmt_base_addr = val;
+
+       /* Update the LMT table with new addr */
+       err = lmtst_map_table_ops(rvu, tbl_idx, &lmt_addr, LMT_TBL_OP_WRITE);
+       if (err) {
+               dev_err(rvu->dev,
+                       "Failed to update LMT map table: index 0x%x err %d\n",
+                       tbl_idx, err);
+               return err;
+       }
+       return 0;
+}
+
+int rvu_mbox_handler_lmtst_tbl_setup(struct rvu *rvu,
+                                    struct lmtst_tbl_setup_req *req,
+                                    struct msg_rsp *rsp)
+{
+       u64 lmt_addr, val;
+       u32 pri_tbl_idx;
+       int err = 0;
+
+       /* Check if PF_FUNC wants to use it's own local memory as LMTLINE
+        * region, if so, convert that IOVA to physical address and
+        * populate LMT table with that address
+        */
+       if (req->use_local_lmt_region) {
+               err = rvu_get_lmtaddr(rvu, req->hdr.pcifunc,
+                                     req->lmt_iova, &lmt_addr);
+               if (err < 0)
+                       return err;
+
+               /* Update the lmt addr for this PFFUNC in the LMT table */
+               err = rvu_update_lmtaddr(rvu, req->hdr.pcifunc, lmt_addr);
+               if (err)
+                       return err;
+       }
+
+       /* Reconfiguring lmtst map table in lmt region shared mode i.e. make
+        * multiple PF_FUNCs to share an LMTLINE region, so primary/base
+        * pcifunc (which is passed as an argument to mailbox) is the one
+        * whose lmt base address will be shared among other secondary
+        * pcifunc (will be the one who is calling this mailbox).
+        */
+       if (req->base_pcifunc) {
+               /* Calculating the LMT table index equivalent to primary
+                * pcifunc.
+                */
+               pri_tbl_idx = rvu_get_lmtst_tbl_index(rvu, req->base_pcifunc);
+
+               /* Read the base lmt addr of the primary pcifunc */
+               err = lmtst_map_table_ops(rvu, pri_tbl_idx, &val,
+                                         LMT_TBL_OP_READ);
+               if (err) {
+                       dev_err(rvu->dev,
+                               "Failed to read LMT map table: index 0x%x err %d\n",
+                               pri_tbl_idx, err);
+                       return err;
+               }
+
+               /* Update the base lmt addr of secondary with primary's base
+                * lmt addr.
+                */
+               err = rvu_update_lmtaddr(rvu, req->hdr.pcifunc, val);
+               if (err)
+                       return err;
+       }
+
+       return 0;
+}
+
+/* Resetting the lmtst map table to original base addresses */
+void rvu_reset_lmt_map_tbl(struct rvu *rvu, u16 pcifunc)
+{
+       struct rvu_pfvf *pfvf = rvu_get_pfvf(rvu, pcifunc);
+       u32 tbl_idx;
+       int err;
+
+       if (is_rvu_otx2(rvu))
+               return;
+
+       if (pfvf->lmt_base_addr) {
+               /* This corresponds to lmt map table index */
+               tbl_idx = rvu_get_lmtst_tbl_index(rvu, pcifunc);
+               /* Reverting back original lmt base addr for respective
+                * pcifunc.
+                */
+               err = lmtst_map_table_ops(rvu, tbl_idx, &pfvf->lmt_base_addr,
+                                         LMT_TBL_OP_WRITE);
+               if (err)
+                       dev_err(rvu->dev,
+                               "Failed to update LMT map table: index 0x%x err %d\n",
+                               tbl_idx, err);
+               pfvf->lmt_base_addr = 0;
+       }
+}
+
 int rvu_set_channels_base(struct rvu *rvu)
 {
        struct rvu_hwinfo *hw = rvu->hw;
index 3cc3c6f..370d4ca 100644 (file)
@@ -1971,10 +1971,9 @@ static int cgx_print_stats(struct seq_file *s, int lmac_id)
        return err;
 }
 
-static int rvu_dbg_cgx_stat_display(struct seq_file *filp, void *unused)
+static int rvu_dbg_derive_lmacid(struct seq_file *filp, int *lmac_id)
 {
        struct dentry *current_dir;
-       int err, lmac_id;
        char *buf;
 
        current_dir = filp->file->f_path.dentry->d_parent;
@@ -1982,17 +1981,87 @@ static int rvu_dbg_cgx_stat_display(struct seq_file *filp, void *unused)
        if (!buf)
                return -EINVAL;
 
-       err = kstrtoint(buf + 1, 10, &lmac_id);
-       if (!err) {
-               err = cgx_print_stats(filp, lmac_id);
-               if (err)
-                       return err;
-       }
+       return kstrtoint(buf + 1, 10, lmac_id);
+}
+
+static int rvu_dbg_cgx_stat_display(struct seq_file *filp, void *unused)
+{
+       int lmac_id, err;
+
+       err = rvu_dbg_derive_lmacid(filp, &lmac_id);
+       if (!err)
+               return cgx_print_stats(filp, lmac_id);
+
        return err;
 }
 
 RVU_DEBUG_SEQ_FOPS(cgx_stat, cgx_stat_display, NULL);
 
+static int cgx_print_dmac_flt(struct seq_file *s, int lmac_id)
+{
+       struct pci_dev *pdev = NULL;
+       void *cgxd = s->private;
+       char *bcast, *mcast;
+       u16 index, domain;
+       u8 dmac[ETH_ALEN];
+       struct rvu *rvu;
+       u64 cfg, mac;
+       int pf;
+
+       rvu = pci_get_drvdata(pci_get_device(PCI_VENDOR_ID_CAVIUM,
+                                            PCI_DEVID_OCTEONTX2_RVU_AF, NULL));
+       if (!rvu)
+               return -ENODEV;
+
+       pf = cgxlmac_to_pf(rvu, cgx_get_cgxid(cgxd), lmac_id);
+       domain = 2;
+
+       pdev = pci_get_domain_bus_and_slot(domain, pf + 1, 0);
+       if (!pdev)
+               return 0;
+
+       cfg = cgx_read_dmac_ctrl(cgxd, lmac_id);
+       bcast = cfg & CGX_DMAC_BCAST_MODE ? "ACCEPT" : "REJECT";
+       mcast = cfg & CGX_DMAC_MCAST_MODE ? "ACCEPT" : "REJECT";
+
+       seq_puts(s,
+                "PCI dev       RVUPF   BROADCAST  MULTICAST  FILTER-MODE\n");
+       seq_printf(s, "%s  PF%d  %9s  %9s",
+                  dev_name(&pdev->dev), pf, bcast, mcast);
+       if (cfg & CGX_DMAC_CAM_ACCEPT)
+               seq_printf(s, "%12s\n\n", "UNICAST");
+       else
+               seq_printf(s, "%16s\n\n", "PROMISCUOUS");
+
+       seq_puts(s, "\nDMAC-INDEX  ADDRESS\n");
+
+       for (index = 0 ; index < 32 ; index++) {
+               cfg = cgx_read_dmac_entry(cgxd, index);
+               /* Display enabled dmac entries associated with current lmac */
+               if (lmac_id == FIELD_GET(CGX_DMAC_CAM_ENTRY_LMACID, cfg) &&
+                   FIELD_GET(CGX_DMAC_CAM_ADDR_ENABLE, cfg)) {
+                       mac = FIELD_GET(CGX_RX_DMAC_ADR_MASK, cfg);
+                       u64_to_ether_addr(mac, dmac);
+                       seq_printf(s, "%7d     %pM\n", index, dmac);
+               }
+       }
+
+       return 0;
+}
+
+static int rvu_dbg_cgx_dmac_flt_display(struct seq_file *filp, void *unused)
+{
+       int err, lmac_id;
+
+       err = rvu_dbg_derive_lmacid(filp, &lmac_id);
+       if (!err)
+               return cgx_print_dmac_flt(filp, lmac_id);
+
+       return err;
+}
+
+RVU_DEBUG_SEQ_FOPS(cgx_dmac_flt, cgx_dmac_flt_display, NULL);
+
 static void rvu_dbg_cgx_init(struct rvu *rvu)
 {
        struct mac_ops *mac_ops;
@@ -2029,6 +2098,9 @@ static void rvu_dbg_cgx_init(struct rvu *rvu)
 
                        debugfs_create_file("stats", 0600, rvu->rvu_dbg.lmac,
                                            cgx, &rvu_dbg_cgx_stat_fops);
+                       debugfs_create_file("mac_filter", 0600,
+                                           rvu->rvu_dbg.lmac, cgx,
+                                           &rvu_dbg_cgx_dmac_flt_fops);
                }
        }
 }
index d6f8210..aeae377 100644 (file)
@@ -346,6 +346,9 @@ static void nix_interface_deinit(struct rvu *rvu, u16 pcifunc, u8 nixlf)
 
        /* Free and disable any MCAM entries used by this NIX LF */
        rvu_npc_disable_mcam_entries(rvu, pcifunc, nixlf);
+
+       /* Disable DMAC filters used */
+       rvu_cgx_disable_dmac_entries(rvu, pcifunc);
 }
 
 int rvu_mbox_handler_nix_bp_disable(struct rvu *rvu,
index 76837d5..8b01ef6 100644 (file)
 #define RVU_AF_PFX_VF_BAR4_ADDR             (0x5400 | (a) << 4)
 #define RVU_AF_PFX_VF_BAR4_CFG              (0x5600 | (a) << 4)
 #define RVU_AF_PFX_LMTLINE_ADDR             (0x5800 | (a) << 4)
+#define RVU_AF_SMMU_ADDR_REQ               (0x6000)
+#define RVU_AF_SMMU_TXN_REQ                (0x6008)
+#define RVU_AF_SMMU_ADDR_RSP_STS           (0x6010)
+#define RVU_AF_SMMU_ADDR_TLN               (0x6018)
+#define RVU_AF_SMMU_TLN_FLIT1              (0x6030)
 
 /* Admin function's privileged PF/VF registers */
 #define RVU_PRIV_CONST                      (0x8000000)
 #define LBK_LINK_CFG_ID_MASK           GENMASK_ULL(11, 6)
 #define LBK_LINK_CFG_BASE_MASK         GENMASK_ULL(5, 0)
 
+/* APR */
+#define        APR_AF_LMT_CFG                  (0x000ull)
+#define        APR_AF_LMT_MAP_BASE             (0x008ull)
+#define        APR_AF_LMT_CTL                  (0x010ull)
+
 #endif /* RVU_REG_H */
index 14aa8e3..5bbe672 100644 (file)
@@ -35,7 +35,8 @@ enum rvu_block_addr_e {
        BLKADDR_NDC_NPA0        = 0xeULL,
        BLKADDR_NDC_NIX1_RX     = 0x10ULL,
        BLKADDR_NDC_NIX1_TX     = 0x11ULL,
-       BLK_COUNT               = 0x12ULL,
+       BLKADDR_APR             = 0x16ULL,
+       BLK_COUNT               = 0x17ULL,
 };
 
 /* RVU Block Type Enumeration */
index 457c947..3254b02 100644 (file)
@@ -7,7 +7,7 @@ obj-$(CONFIG_OCTEONTX2_PF) += rvu_nicpf.o
 obj-$(CONFIG_OCTEONTX2_VF) += rvu_nicvf.o
 
 rvu_nicpf-y := otx2_pf.o otx2_common.o otx2_txrx.o otx2_ethtool.o \
-                    otx2_ptp.o otx2_flows.o otx2_tc.o cn10k.o
+               otx2_ptp.o otx2_flows.o otx2_tc.o cn10k.o otx2_dmac_flt.o
 rvu_nicvf-y := otx2_vf.o
 
 ccflags-y += -I$(srctree)/drivers/net/ethernet/marvell/octeontx2/af
index 1b08896..184de94 100644 (file)
@@ -22,69 +22,52 @@ static struct dev_hw_ops cn10k_hw_ops = {
        .refill_pool_ptrs = cn10k_refill_pool_ptrs,
 };
 
-int cn10k_pf_lmtst_init(struct otx2_nic *pf)
+int cn10k_lmtst_init(struct otx2_nic *pfvf)
 {
-       int size, num_lines;
-       u64 base;
 
-       if (!test_bit(CN10K_LMTST, &pf->hw.cap_flag)) {
-               pf->hw_ops = &otx2_hw_ops;
+       struct lmtst_tbl_setup_req *req;
+       int qcount, err;
+
+       if (!test_bit(CN10K_LMTST, &pfvf->hw.cap_flag)) {
+               pfvf->hw_ops = &otx2_hw_ops;
                return 0;
        }
 
-       pf->hw_ops = &cn10k_hw_ops;
-       base = pci_resource_start(pf->pdev, PCI_MBOX_BAR_NUM) +
-                      (MBOX_SIZE * (pf->total_vfs + 1));
-
-       size = pci_resource_len(pf->pdev, PCI_MBOX_BAR_NUM) -
-              (MBOX_SIZE * (pf->total_vfs + 1));
-
-       pf->hw.lmt_base = ioremap(base, size);
+       pfvf->hw_ops = &cn10k_hw_ops;
+       qcount = pfvf->hw.max_queues;
+       /* LMTST lines allocation
+        * qcount = num_online_cpus();
+        * NPA = TX + RX + XDP.
+        * NIX = TX * 32 (For Burst SQE flush).
+        */
+       pfvf->tot_lmt_lines = (qcount * 3) + (qcount * 32);
+       pfvf->npa_lmt_lines = qcount * 3;
+       pfvf->nix_lmt_size =  LMT_BURST_SIZE * LMT_LINE_SIZE;
 
-       if (!pf->hw.lmt_base) {
-               dev_err(pf->dev, "Unable to map PF LMTST region\n");
+       mutex_lock(&pfvf->mbox.lock);
+       req = otx2_mbox_alloc_msg_lmtst_tbl_setup(&pfvf->mbox);
+       if (!req) {
+               mutex_unlock(&pfvf->mbox.lock);
                return -ENOMEM;
        }
 
-       /* FIXME: Get the num of LMTST lines from LMT table */
-       pf->tot_lmt_lines = size / LMT_LINE_SIZE;
-       num_lines = (pf->tot_lmt_lines - NIX_LMTID_BASE) /
-                           pf->hw.tx_queues;
-       /* Number of LMT lines per SQ queues */
-       pf->nix_lmt_lines = num_lines > 32 ? 32 : num_lines;
-
-       pf->nix_lmt_size = pf->nix_lmt_lines * LMT_LINE_SIZE;
-       return 0;
-}
+       req->use_local_lmt_region = true;
 
-int cn10k_vf_lmtst_init(struct otx2_nic *vf)
-{
-       int size, num_lines;
-
-       if (!test_bit(CN10K_LMTST, &vf->hw.cap_flag)) {
-               vf->hw_ops = &otx2_hw_ops;
-               return 0;
+       err = qmem_alloc(pfvf->dev, &pfvf->dync_lmt, pfvf->tot_lmt_lines,
+                        LMT_LINE_SIZE);
+       if (err) {
+               mutex_unlock(&pfvf->mbox.lock);
+               return err;
        }
+       pfvf->hw.lmt_base = (u64 *)pfvf->dync_lmt->base;
+       req->lmt_iova = (u64)pfvf->dync_lmt->iova;
 
-       vf->hw_ops = &cn10k_hw_ops;
-       size = pci_resource_len(vf->pdev, PCI_MBOX_BAR_NUM);
-       vf->hw.lmt_base = ioremap_wc(pci_resource_start(vf->pdev,
-                                                       PCI_MBOX_BAR_NUM),
-                                    size);
-       if (!vf->hw.lmt_base) {
-               dev_err(vf->dev, "Unable to map VF LMTST region\n");
-               return -ENOMEM;
-       }
+       err = otx2_sync_mbox_msg(&pfvf->mbox);
+       mutex_unlock(&pfvf->mbox.lock);
 
-       vf->tot_lmt_lines = size / LMT_LINE_SIZE;
-       /* LMTST lines per SQ */
-       num_lines = (vf->tot_lmt_lines - NIX_LMTID_BASE) /
-                           vf->hw.tx_queues;
-       vf->nix_lmt_lines = num_lines > 32 ? 32 : num_lines;
-       vf->nix_lmt_size = vf->nix_lmt_lines * LMT_LINE_SIZE;
        return 0;
 }
-EXPORT_SYMBOL(cn10k_vf_lmtst_init);
+EXPORT_SYMBOL(cn10k_lmtst_init);
 
 int cn10k_sq_aq_init(void *dev, u16 qidx, u16 sqb_aura)
 {
@@ -93,9 +76,11 @@ int cn10k_sq_aq_init(void *dev, u16 qidx, u16 sqb_aura)
        struct otx2_snd_queue *sq;
 
        sq = &pfvf->qset.sq[qidx];
-       sq->lmt_addr = (__force u64 *)((u64)pfvf->hw.nix_lmt_base +
+       sq->lmt_addr = (u64 *)((u64)pfvf->hw.nix_lmt_base +
                               (qidx * pfvf->nix_lmt_size));
 
+       sq->lmt_id = pfvf->npa_lmt_lines + (qidx * LMT_BURST_SIZE);
+
        /* Get memory to put this msg */
        aq = otx2_mbox_alloc_msg_nix_cn10k_aq_enq(&pfvf->mbox);
        if (!aq)
@@ -158,15 +143,13 @@ void cn10k_refill_pool_ptrs(void *dev, struct otx2_cq_queue *cq)
 
 void cn10k_sqe_flush(void *dev, struct otx2_snd_queue *sq, int size, int qidx)
 {
-       struct otx2_nic *pfvf = dev;
-       int lmt_id = NIX_LMTID_BASE + (qidx * pfvf->nix_lmt_lines);
        u64 val = 0, tar_addr = 0;
 
        /* FIXME: val[0:10] LMT_ID.
         * [12:15] no of LMTST - 1 in the burst.
         * [19:63] data size of each LMTST in the burst except first.
         */
-       val = (lmt_id & 0x7FF);
+       val = (sq->lmt_id & 0x7FF);
        /* Target address for LMTST flush tells HW how many 128bit
         * words are present.
         * tar_addr[6:4] size of first LMTST - 1 in units of 128b.
index 71292a4..1a1ae33 100644 (file)
@@ -12,8 +12,7 @@
 void cn10k_refill_pool_ptrs(void *dev, struct otx2_cq_queue *cq);
 void cn10k_sqe_flush(void *dev, struct otx2_snd_queue *sq, int size, int qidx);
 int cn10k_sq_aq_init(void *dev, u16 qidx, u16 sqb_aura);
-int cn10k_pf_lmtst_init(struct otx2_nic *pf);
-int cn10k_vf_lmtst_init(struct otx2_nic *vf);
+int cn10k_lmtst_init(struct otx2_nic *pfvf);
 int cn10k_free_all_ipolicers(struct otx2_nic *pfvf);
 int cn10k_alloc_matchall_ipolicer(struct otx2_nic *pfvf);
 int cn10k_free_matchall_ipolicer(struct otx2_nic *pfvf);
index cf7875d..7cccd80 100644 (file)
@@ -210,6 +210,9 @@ int otx2_set_mac_address(struct net_device *netdev, void *p)
                /* update dmac field in vlan offload rule */
                if (pfvf->flags & OTX2_FLAG_RX_VLAN_SUPPORT)
                        otx2_install_rxvlan_offload_flow(pfvf);
+               /* update dmac address in ntuple and DMAC filter list */
+               if (pfvf->flags & OTX2_FLAG_DMACFLTR_SUPPORT)
+                       otx2_dmacflt_update_pfmac_flow(pfvf);
        } else {
                return -EPERM;
        }
index 234b330..8fd58cd 100644 (file)
@@ -218,8 +218,8 @@ struct otx2_hw {
        unsigned long           cap_flag;
 
 #define LMT_LINE_SIZE          128
-#define NIX_LMTID_BASE         72 /* RX + TX + XDP */
-       void __iomem            *lmt_base;
+#define LMT_BURST_SIZE         32 /* 32 LMTST lines for burst SQE flush */
+       u64                     *lmt_base;
        u64                     *npa_lmt_base;
        u64                     *nix_lmt_base;
 };
@@ -288,6 +288,9 @@ struct otx2_flow_config {
        u16                     tc_flower_offset;
        u16                     ntuple_max_flows;
        u16                     tc_max_flows;
+       u8                      dmacflt_max_flows;
+       u8                      *bmap_to_dmacindex;
+       unsigned long           dmacflt_bmap;
        struct list_head        flow_list;
 };
 
@@ -329,6 +332,7 @@ struct otx2_nic {
 #define OTX2_FLAG_TC_FLOWER_SUPPORT            BIT_ULL(11)
 #define OTX2_FLAG_TC_MATCHALL_EGRESS_ENABLED   BIT_ULL(12)
 #define OTX2_FLAG_TC_MATCHALL_INGRESS_ENABLED  BIT_ULL(13)
+#define OTX2_FLAG_DMACFLTR_SUPPORT             BIT_ULL(14)
        u64                     flags;
 
        struct otx2_qset        qset;
@@ -363,8 +367,9 @@ struct otx2_nic {
        /* Block address of NIX either BLKADDR_NIX0 or BLKADDR_NIX1 */
        int                     nix_blkaddr;
        /* LMTST Lines info */
+       struct qmem             *dync_lmt;
        u16                     tot_lmt_lines;
-       u16                     nix_lmt_lines;
+       u16                     npa_lmt_lines;
        u32                     nix_lmt_size;
 
        struct otx2_ptp         *ptp;
@@ -833,4 +838,11 @@ int otx2_init_tc(struct otx2_nic *nic);
 void otx2_shutdown_tc(struct otx2_nic *nic);
 int otx2_setup_tc(struct net_device *netdev, enum tc_setup_type type,
                  void *type_data);
+/* CGX/RPM DMAC filters support */
+int otx2_dmacflt_get_max_cnt(struct otx2_nic *pf);
+int otx2_dmacflt_add(struct otx2_nic *pf, const u8 *mac, u8 bit_pos);
+int otx2_dmacflt_remove(struct otx2_nic *pf, const u8 *mac, u8 bit_pos);
+int otx2_dmacflt_update(struct otx2_nic *pf, u8 *mac, u8 bit_pos);
+void otx2_dmacflt_reinstall_flows(struct otx2_nic *pf);
+void otx2_dmacflt_update_pfmac_flow(struct otx2_nic *pfvf);
 #endif /* OTX2_COMMON_H */
diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_dmac_flt.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_dmac_flt.c
new file mode 100644 (file)
index 0000000..383a6b5
--- /dev/null
@@ -0,0 +1,173 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Marvell OcteonTx2 RVU Physcial Function ethernet driver
+ *
+ * Copyright (C) 2021 Marvell.
+ */
+
+#include "otx2_common.h"
+
+static int otx2_dmacflt_do_add(struct otx2_nic *pf, const u8 *mac,
+                              u8 *dmac_index)
+{
+       struct cgx_mac_addr_add_req *req;
+       struct cgx_mac_addr_add_rsp *rsp;
+       int err;
+
+       mutex_lock(&pf->mbox.lock);
+
+       req = otx2_mbox_alloc_msg_cgx_mac_addr_add(&pf->mbox);
+       if (!req) {
+               mutex_unlock(&pf->mbox.lock);
+               return -ENOMEM;
+       }
+
+       ether_addr_copy(req->mac_addr, mac);
+       err = otx2_sync_mbox_msg(&pf->mbox);
+
+       if (!err) {
+               rsp = (struct cgx_mac_addr_add_rsp *)
+                        otx2_mbox_get_rsp(&pf->mbox.mbox, 0, &req->hdr);
+               *dmac_index = rsp->index;
+       }
+
+       mutex_unlock(&pf->mbox.lock);
+       return err;
+}
+
+static int otx2_dmacflt_add_pfmac(struct otx2_nic *pf)
+{
+       struct cgx_mac_addr_set_or_get *req;
+       int err;
+
+       mutex_lock(&pf->mbox.lock);
+
+       req = otx2_mbox_alloc_msg_cgx_mac_addr_set(&pf->mbox);
+       if (!req) {
+               mutex_unlock(&pf->mbox.lock);
+               return -ENOMEM;
+       }
+
+       ether_addr_copy(req->mac_addr, pf->netdev->dev_addr);
+       err = otx2_sync_mbox_msg(&pf->mbox);
+
+       mutex_unlock(&pf->mbox.lock);
+       return err;
+}
+
+int otx2_dmacflt_add(struct otx2_nic *pf, const u8 *mac, u8 bit_pos)
+{
+       u8 *dmacindex;
+
+       /* Store dmacindex returned by CGX/RPM driver which will
+        * be used for macaddr update/remove
+        */
+       dmacindex = &pf->flow_cfg->bmap_to_dmacindex[bit_pos];
+
+       if (ether_addr_equal(mac, pf->netdev->dev_addr))
+               return otx2_dmacflt_add_pfmac(pf);
+       else
+               return otx2_dmacflt_do_add(pf, mac, dmacindex);
+}
+
+static int otx2_dmacflt_do_remove(struct otx2_nic *pfvf, const u8 *mac,
+                                 u8 dmac_index)
+{
+       struct cgx_mac_addr_del_req *req;
+       int err;
+
+       mutex_lock(&pfvf->mbox.lock);
+       req = otx2_mbox_alloc_msg_cgx_mac_addr_del(&pfvf->mbox);
+       if (!req) {
+               mutex_unlock(&pfvf->mbox.lock);
+               return -ENOMEM;
+       }
+
+       req->index = dmac_index;
+
+       err = otx2_sync_mbox_msg(&pfvf->mbox);
+       mutex_unlock(&pfvf->mbox.lock);
+
+       return err;
+}
+
+static int otx2_dmacflt_remove_pfmac(struct otx2_nic *pf)
+{
+       struct msg_req *req;
+       int err;
+
+       mutex_lock(&pf->mbox.lock);
+       req = otx2_mbox_alloc_msg_cgx_mac_addr_reset(&pf->mbox);
+       if (!req) {
+               mutex_unlock(&pf->mbox.lock);
+               return -ENOMEM;
+       }
+
+       err = otx2_sync_mbox_msg(&pf->mbox);
+
+       mutex_unlock(&pf->mbox.lock);
+       return err;
+}
+
+int otx2_dmacflt_remove(struct otx2_nic *pf, const u8 *mac,
+                       u8 bit_pos)
+{
+       u8 dmacindex = pf->flow_cfg->bmap_to_dmacindex[bit_pos];
+
+       if (ether_addr_equal(mac, pf->netdev->dev_addr))
+               return otx2_dmacflt_remove_pfmac(pf);
+       else
+               return otx2_dmacflt_do_remove(pf, mac, dmacindex);
+}
+
+/* CGX/RPM blocks support max unicast entries of 32.
+ * on typical configuration MAC block associated
+ * with 4 lmacs, each lmac will have 8 dmac entries
+ */
+int otx2_dmacflt_get_max_cnt(struct otx2_nic *pf)
+{
+       struct cgx_max_dmac_entries_get_rsp *rsp;
+       struct msg_req *msg;
+       int err;
+
+       mutex_lock(&pf->mbox.lock);
+       msg = otx2_mbox_alloc_msg_cgx_mac_max_entries_get(&pf->mbox);
+
+       if (!msg) {
+               mutex_unlock(&pf->mbox.lock);
+               return -ENOMEM;
+       }
+
+       err = otx2_sync_mbox_msg(&pf->mbox);
+       if (err)
+               goto out;
+
+       rsp = (struct cgx_max_dmac_entries_get_rsp *)
+                    otx2_mbox_get_rsp(&pf->mbox.mbox, 0, &msg->hdr);
+       pf->flow_cfg->dmacflt_max_flows = rsp->max_dmac_filters;
+
+out:
+       mutex_unlock(&pf->mbox.lock);
+       return err;
+}
+
+int otx2_dmacflt_update(struct otx2_nic *pf, u8 *mac, u8 bit_pos)
+{
+       struct cgx_mac_addr_update_req *req;
+       int rc;
+
+       mutex_lock(&pf->mbox.lock);
+
+       req = otx2_mbox_alloc_msg_cgx_mac_addr_update(&pf->mbox);
+
+       if (!req) {
+               mutex_unlock(&pf->mbox.lock);
+               return -ENOMEM;
+       }
+
+       ether_addr_copy(req->mac_addr, mac);
+       req->index = pf->flow_cfg->bmap_to_dmacindex[bit_pos];
+       rc = otx2_sync_mbox_msg(&pf->mbox);
+
+       mutex_unlock(&pf->mbox.lock);
+       return rc;
+}
index 8c97106..4d9de52 100644 (file)
@@ -18,6 +18,12 @@ struct otx2_flow {
        bool is_vf;
        u8 rss_ctx_id;
        int vf;
+       bool dmac_filter;
+};
+
+enum dmac_req {
+       DMAC_ADDR_UPDATE,
+       DMAC_ADDR_DEL
 };
 
 static void otx2_clear_ntuple_flow_info(struct otx2_nic *pfvf, struct otx2_flow_config *flow_cfg)
@@ -219,6 +225,22 @@ int otx2_mcam_flow_init(struct otx2_nic *pf)
        if (!pf->mac_table)
                return -ENOMEM;
 
+       otx2_dmacflt_get_max_cnt(pf);
+
+       /* DMAC filters are not allocated */
+       if (!pf->flow_cfg->dmacflt_max_flows)
+               return 0;
+
+       pf->flow_cfg->bmap_to_dmacindex =
+                       devm_kzalloc(pf->dev, sizeof(u8) *
+                                    pf->flow_cfg->dmacflt_max_flows,
+                                    GFP_KERNEL);
+
+       if (!pf->flow_cfg->bmap_to_dmacindex)
+               return -ENOMEM;
+
+       pf->flags |= OTX2_FLAG_DMACFLTR_SUPPORT;
+
        return 0;
 }
 
@@ -280,6 +302,12 @@ int otx2_add_macfilter(struct net_device *netdev, const u8 *mac)
 {
        struct otx2_nic *pf = netdev_priv(netdev);
 
+       if (bitmap_weight(&pf->flow_cfg->dmacflt_bmap,
+                         pf->flow_cfg->dmacflt_max_flows))
+               netdev_warn(netdev,
+                           "Add %pM to CGX/RPM DMAC filters list as well\n",
+                           mac);
+
        return otx2_do_add_macfilter(pf, mac);
 }
 
@@ -351,12 +379,22 @@ static void otx2_add_flow_to_list(struct otx2_nic *pfvf, struct otx2_flow *flow)
        list_add(&flow->list, head);
 }
 
+static int otx2_get_maxflows(struct otx2_flow_config *flow_cfg)
+{
+       if (flow_cfg->nr_flows == flow_cfg->ntuple_max_flows ||
+           bitmap_weight(&flow_cfg->dmacflt_bmap,
+                         flow_cfg->dmacflt_max_flows))
+               return flow_cfg->ntuple_max_flows + flow_cfg->dmacflt_max_flows;
+       else
+               return flow_cfg->ntuple_max_flows;
+}
+
 int otx2_get_flow(struct otx2_nic *pfvf, struct ethtool_rxnfc *nfc,
                  u32 location)
 {
        struct otx2_flow *iter;
 
-       if (location >= pfvf->flow_cfg->ntuple_max_flows)
+       if (location >= otx2_get_maxflows(pfvf->flow_cfg))
                return -EINVAL;
 
        list_for_each_entry(iter, &pfvf->flow_cfg->flow_list, list) {
@@ -378,7 +416,7 @@ int otx2_get_all_flows(struct otx2_nic *pfvf, struct ethtool_rxnfc *nfc,
        int idx = 0;
        int err = 0;
 
-       nfc->data = pfvf->flow_cfg->ntuple_max_flows;
+       nfc->data = otx2_get_maxflows(pfvf->flow_cfg);
        while ((!err || err == -ENOENT) && idx < rule_cnt) {
                err = otx2_get_flow(pfvf, nfc, location);
                if (!err)
@@ -760,6 +798,32 @@ int otx2_prepare_flow_request(struct ethtool_rx_flow_spec *fsp,
        return 0;
 }
 
+static int otx2_is_flow_rule_dmacfilter(struct otx2_nic *pfvf,
+                                       struct ethtool_rx_flow_spec *fsp)
+{
+       struct ethhdr *eth_mask = &fsp->m_u.ether_spec;
+       struct ethhdr *eth_hdr = &fsp->h_u.ether_spec;
+       u64 ring_cookie = fsp->ring_cookie;
+       u32 flow_type;
+
+       if (!(pfvf->flags & OTX2_FLAG_DMACFLTR_SUPPORT))
+               return false;
+
+       flow_type = fsp->flow_type & ~(FLOW_EXT | FLOW_MAC_EXT | FLOW_RSS);
+
+       /* CGX/RPM block dmac filtering configured for white listing
+        * check for action other than DROP
+        */
+       if (flow_type == ETHER_FLOW && ring_cookie != RX_CLS_FLOW_DISC &&
+           !ethtool_get_flow_spec_ring_vf(ring_cookie)) {
+               if (is_zero_ether_addr(eth_mask->h_dest) &&
+                   is_valid_ether_addr(eth_hdr->h_dest))
+                       return true;
+       }
+
+       return false;
+}
+
 static int otx2_add_flow_msg(struct otx2_nic *pfvf, struct otx2_flow *flow)
 {
        u64 ring_cookie = flow->flow_spec.ring_cookie;
@@ -818,14 +882,46 @@ static int otx2_add_flow_msg(struct otx2_nic *pfvf, struct otx2_flow *flow)
        return err;
 }
 
+static int otx2_add_flow_with_pfmac(struct otx2_nic *pfvf,
+                                   struct otx2_flow *flow)
+{
+       struct otx2_flow *pf_mac;
+       struct ethhdr *eth_hdr;
+
+       pf_mac = kzalloc(sizeof(*pf_mac), GFP_KERNEL);
+       if (!pf_mac)
+               return -ENOMEM;
+
+       pf_mac->entry = 0;
+       pf_mac->dmac_filter = true;
+       pf_mac->location = pfvf->flow_cfg->ntuple_max_flows;
+       memcpy(&pf_mac->flow_spec, &flow->flow_spec,
+              sizeof(struct ethtool_rx_flow_spec));
+       pf_mac->flow_spec.location = pf_mac->location;
+
+       /* Copy PF mac address */
+       eth_hdr = &pf_mac->flow_spec.h_u.ether_spec;
+       ether_addr_copy(eth_hdr->h_dest, pfvf->netdev->dev_addr);
+
+       /* Install DMAC filter with PF mac address */
+       otx2_dmacflt_add(pfvf, eth_hdr->h_dest, 0);
+
+       otx2_add_flow_to_list(pfvf, pf_mac);
+       pfvf->flow_cfg->nr_flows++;
+       set_bit(0, &pfvf->flow_cfg->dmacflt_bmap);
+
+       return 0;
+}
+
 int otx2_add_flow(struct otx2_nic *pfvf, struct ethtool_rxnfc *nfc)
 {
        struct otx2_flow_config *flow_cfg = pfvf->flow_cfg;
        struct ethtool_rx_flow_spec *fsp = &nfc->fs;
        struct otx2_flow *flow;
+       struct ethhdr *eth_hdr;
        bool new = false;
+       int err = 0;
        u32 ring;
-       int err;
 
        ring = ethtool_get_flow_spec_ring(fsp->ring_cookie);
        if (!(pfvf->flags & OTX2_FLAG_NTUPLE_SUPPORT))
@@ -834,16 +930,15 @@ int otx2_add_flow(struct otx2_nic *pfvf, struct ethtool_rxnfc *nfc)
        if (ring >= pfvf->hw.rx_queues && fsp->ring_cookie != RX_CLS_FLOW_DISC)
                return -EINVAL;
 
-       if (fsp->location >= flow_cfg->ntuple_max_flows)
+       if (fsp->location >= otx2_get_maxflows(flow_cfg))
                return -EINVAL;
 
        flow = otx2_find_flow(pfvf, fsp->location);
        if (!flow) {
-               flow = kzalloc(sizeof(*flow), GFP_ATOMIC);
+               flow = kzalloc(sizeof(*flow), GFP_KERNEL);
                if (!flow)
                        return -ENOMEM;
                flow->location = fsp->location;
-               flow->entry = flow_cfg->flow_ent[flow->location];
                new = true;
        }
        /* struct copy */
@@ -852,7 +947,54 @@ int otx2_add_flow(struct otx2_nic *pfvf, struct ethtool_rxnfc *nfc)
        if (fsp->flow_type & FLOW_RSS)
                flow->rss_ctx_id = nfc->rss_context;
 
-       err = otx2_add_flow_msg(pfvf, flow);
+       if (otx2_is_flow_rule_dmacfilter(pfvf, &flow->flow_spec)) {
+               eth_hdr = &flow->flow_spec.h_u.ether_spec;
+
+               /* Sync dmac filter table with updated fields */
+               if (flow->dmac_filter)
+                       return otx2_dmacflt_update(pfvf, eth_hdr->h_dest,
+                                                  flow->entry);
+
+               if (bitmap_full(&flow_cfg->dmacflt_bmap,
+                               flow_cfg->dmacflt_max_flows)) {
+                       netdev_warn(pfvf->netdev,
+                                   "Can't insert the rule %d as max allowed dmac filters are %d\n",
+                                   flow->location +
+                                   flow_cfg->dmacflt_max_flows,
+                                   flow_cfg->dmacflt_max_flows);
+                       err = -EINVAL;
+                       if (new)
+                               kfree(flow);
+                       return err;
+               }
+
+               /* Install PF mac address to DMAC filter list */
+               if (!test_bit(0, &flow_cfg->dmacflt_bmap))
+                       otx2_add_flow_with_pfmac(pfvf, flow);
+
+               flow->dmac_filter = true;
+               flow->entry = find_first_zero_bit(&flow_cfg->dmacflt_bmap,
+                                                 flow_cfg->dmacflt_max_flows);
+               fsp->location = flow_cfg->ntuple_max_flows + flow->entry;
+               flow->flow_spec.location = fsp->location;
+               flow->location = fsp->location;
+
+               set_bit(flow->entry, &flow_cfg->dmacflt_bmap);
+               otx2_dmacflt_add(pfvf, eth_hdr->h_dest, flow->entry);
+
+       } else {
+               if (flow->location >= pfvf->flow_cfg->ntuple_max_flows) {
+                       netdev_warn(pfvf->netdev,
+                                   "Can't insert non dmac ntuple rule at %d, allowed range %d-0\n",
+                                   flow->location,
+                                   flow_cfg->ntuple_max_flows - 1);
+                       err = -EINVAL;
+               } else {
+                       flow->entry = flow_cfg->flow_ent[flow->location];
+                       err = otx2_add_flow_msg(pfvf, flow);
+               }
+       }
+
        if (err) {
                if (new)
                        kfree(flow);
@@ -890,20 +1032,70 @@ static int otx2_remove_flow_msg(struct otx2_nic *pfvf, u16 entry, bool all)
        return err;
 }
 
+static void otx2_update_rem_pfmac(struct otx2_nic *pfvf, int req)
+{
+       struct otx2_flow *iter;
+       struct ethhdr *eth_hdr;
+       bool found = false;
+
+       list_for_each_entry(iter, &pfvf->flow_cfg->flow_list, list) {
+               if (iter->dmac_filter && iter->entry == 0) {
+                       eth_hdr = &iter->flow_spec.h_u.ether_spec;
+                       if (req == DMAC_ADDR_DEL) {
+                               otx2_dmacflt_remove(pfvf, eth_hdr->h_dest,
+                                                   0);
+                               clear_bit(0, &pfvf->flow_cfg->dmacflt_bmap);
+                               found = true;
+                       } else {
+                               ether_addr_copy(eth_hdr->h_dest,
+                                               pfvf->netdev->dev_addr);
+                               otx2_dmacflt_update(pfvf, eth_hdr->h_dest, 0);
+                       }
+                       break;
+               }
+       }
+
+       if (found) {
+               list_del(&iter->list);
+               kfree(iter);
+               pfvf->flow_cfg->nr_flows--;
+       }
+}
+
 int otx2_remove_flow(struct otx2_nic *pfvf, u32 location)
 {
        struct otx2_flow_config *flow_cfg = pfvf->flow_cfg;
        struct otx2_flow *flow;
        int err;
 
-       if (location >= flow_cfg->ntuple_max_flows)
+       if (location >= otx2_get_maxflows(flow_cfg))
                return -EINVAL;
 
        flow = otx2_find_flow(pfvf, location);
        if (!flow)
                return -ENOENT;
 
-       err = otx2_remove_flow_msg(pfvf, flow->entry, false);
+       if (flow->dmac_filter) {
+               struct ethhdr *eth_hdr = &flow->flow_spec.h_u.ether_spec;
+
+               /* user not allowed to remove dmac filter with interface mac */
+               if (ether_addr_equal(pfvf->netdev->dev_addr, eth_hdr->h_dest))
+                       return -EPERM;
+
+               err = otx2_dmacflt_remove(pfvf, eth_hdr->h_dest,
+                                         flow->entry);
+               clear_bit(flow->entry, &flow_cfg->dmacflt_bmap);
+               /* If all dmac filters are removed delete macfilter with
+                * interface mac address and configure CGX/RPM block in
+                * promiscuous mode
+                */
+               if (bitmap_weight(&flow_cfg->dmacflt_bmap,
+                                 flow_cfg->dmacflt_max_flows) == 1)
+                       otx2_update_rem_pfmac(pfvf, DMAC_ADDR_DEL);
+       } else {
+               err = otx2_remove_flow_msg(pfvf, flow->entry, false);
+       }
+
        if (err)
                return err;
 
@@ -1100,3 +1292,22 @@ int otx2_enable_rxvlan(struct otx2_nic *pf, bool enable)
        mutex_unlock(&pf->mbox.lock);
        return rsp_hdr->rc;
 }
+
+void otx2_dmacflt_reinstall_flows(struct otx2_nic *pf)
+{
+       struct otx2_flow *iter;
+       struct ethhdr *eth_hdr;
+
+       list_for_each_entry(iter, &pf->flow_cfg->flow_list, list) {
+               if (iter->dmac_filter) {
+                       eth_hdr = &iter->flow_spec.h_u.ether_spec;
+                       otx2_dmacflt_add(pf, eth_hdr->h_dest,
+                                        iter->entry);
+               }
+       }
+}
+
+void otx2_dmacflt_update_pfmac_flow(struct otx2_nic *pfvf)
+{
+       otx2_update_rem_pfmac(pfvf, DMAC_ADDR_UPDATE);
+}
index 59912f7..f300b80 100644 (file)
@@ -1110,6 +1110,11 @@ static int otx2_cgx_config_loopback(struct otx2_nic *pf, bool enable)
        struct msg_req *msg;
        int err;
 
+       if (enable && bitmap_weight(&pf->flow_cfg->dmacflt_bmap,
+                                   pf->flow_cfg->dmacflt_max_flows))
+               netdev_warn(pf->netdev,
+                           "CGX/RPM internal loopback might not work as DMAC filters are active\n");
+
        mutex_lock(&pf->mbox.lock);
        if (enable)
                msg = otx2_mbox_alloc_msg_cgx_intlbk_enable(&pf->mbox);
@@ -1533,10 +1538,10 @@ int otx2_open(struct net_device *netdev)
 
        if (test_bit(CN10K_LMTST, &pf->hw.cap_flag)) {
                /* Reserve LMT lines for NPA AURA batch free */
-               pf->hw.npa_lmt_base = (__force u64 *)pf->hw.lmt_base;
+               pf->hw.npa_lmt_base = pf->hw.lmt_base;
                /* Reserve LMT lines for NIX TX */
-               pf->hw.nix_lmt_base = (__force u64 *)((u64)pf->hw.npa_lmt_base +
-                                     (NIX_LMTID_BASE * LMT_LINE_SIZE));
+               pf->hw.nix_lmt_base = (u64 *)((u64)pf->hw.npa_lmt_base +
+                                     (pf->npa_lmt_lines * LMT_LINE_SIZE));
        }
 
        err = otx2_init_hw_resources(pf);
@@ -1644,6 +1649,10 @@ int otx2_open(struct net_device *netdev)
        /* Restore pause frame settings */
        otx2_config_pause_frm(pf);
 
+       /* Install DMAC Filters */
+       if (pf->flags & OTX2_FLAG_DMACFLTR_SUPPORT)
+               otx2_dmacflt_reinstall_flows(pf);
+
        err = otx2_rxtx_enable(pf, true);
        if (err)
                goto err_tx_stop_queues;
@@ -2526,7 +2535,7 @@ static int otx2_probe(struct pci_dev *pdev, const struct pci_device_id *id)
        if (err)
                goto err_detach_rsrc;
 
-       err = cn10k_pf_lmtst_init(pf);
+       err = cn10k_lmtst_init(pf);
        if (err)
                goto err_detach_rsrc;
 
@@ -2630,8 +2639,8 @@ err_del_mcam_entries:
 err_ptp_destroy:
        otx2_ptp_destroy(pf);
 err_detach_rsrc:
-       if (hw->lmt_base)
-               iounmap(hw->lmt_base);
+       if (test_bit(CN10K_LMTST, &pf->hw.cap_flag))
+               qmem_free(pf->dev, pf->dync_lmt);
        otx2_detach_resources(&pf->mbox);
 err_disable_mbox_intr:
        otx2_disable_mbox_intr(pf);
@@ -2772,9 +2781,8 @@ static void otx2_remove(struct pci_dev *pdev)
        otx2_mcam_flow_del(pf);
        otx2_shutdown_tc(pf);
        otx2_detach_resources(&pf->mbox);
-       if (pf->hw.lmt_base)
-               iounmap(pf->hw.lmt_base);
-
+       if (test_bit(CN10K_LMTST, &pf->hw.cap_flag))
+               qmem_free(pf->dev, pf->dync_lmt);
        otx2_disable_mbox_intr(pf);
        otx2_pfaf_mbox_destroy(pf);
        pci_free_irq_vectors(pf->pdev);
index 905fc02..972b202 100644 (file)
@@ -288,7 +288,7 @@ static int otx2_tc_parse_actions(struct otx2_nic *nic,
        struct otx2_nic *priv;
        u32 burst, mark = 0;
        u8 nr_police = 0;
-       bool pps;
+       bool pps = false;
        u64 rate;
        int i;
 
index 52486c1..2f144e2 100644 (file)
@@ -83,6 +83,7 @@ struct otx2_snd_queue {
        u16                     num_sqbs;
        u16                     sqe_thresh;
        u8                      sqe_per_sqb;
+       u32                     lmt_id;
        u64                      io_addr;
        u64                     *aura_fc_addr;
        u64                     *lmt_addr;
index 13a908f..a8bee5a 100644 (file)
@@ -609,7 +609,7 @@ static int otx2vf_probe(struct pci_dev *pdev, const struct pci_device_id *id)
        if (err)
                goto err_detach_rsrc;
 
-       err = cn10k_vf_lmtst_init(vf);
+       err = cn10k_lmtst_init(vf);
        if (err)
                goto err_detach_rsrc;
 
@@ -667,8 +667,8 @@ static int otx2vf_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 err_unreg_netdev:
        unregister_netdev(netdev);
 err_detach_rsrc:
-       if (hw->lmt_base)
-               iounmap(hw->lmt_base);
+       if (test_bit(CN10K_LMTST, &vf->hw.cap_flag))
+               qmem_free(vf->dev, vf->dync_lmt);
        otx2_detach_resources(&vf->mbox);
 err_disable_mbox_intr:
        otx2vf_disable_mbox_intr(vf);
@@ -700,10 +700,8 @@ static void otx2vf_remove(struct pci_dev *pdev)
                destroy_workqueue(vf->otx2_wq);
        otx2vf_disable_mbox_intr(vf);
        otx2_detach_resources(&vf->mbox);
-
-       if (vf->hw.lmt_base)
-               iounmap(vf->hw.lmt_base);
-
+       if (test_bit(CN10K_LMTST, &vf->hw.cap_flag))
+               qmem_free(vf->dev, vf->dync_lmt);
        otx2vf_vfaf_mbox_destroy(vf);
        pci_free_irq_vectors(vf->pdev);
        pci_set_drvdata(pdev, NULL);
index a80419d..ac403d4 100644 (file)
@@ -2,6 +2,7 @@ config SPARX5_SWITCH
        tristate "Sparx5 switch driver"
        depends on NET_SWITCHDEV
        depends on HAS_IOMEM
+       depends on OF
        select PHYLINK
        select PHY_SPARX5_SERDES
        select RESET_CONTROLLER
index 5249b64..49def69 100644 (file)
@@ -540,10 +540,8 @@ static int moxart_mac_probe(struct platform_device *pdev)
        SET_NETDEV_DEV(ndev, &pdev->dev);
 
        ret = register_netdev(ndev);
-       if (ret) {
-               free_netdev(ndev);
+       if (ret)
                goto init_fail;
-       }
 
        netdev_dbg(ndev, "%s: IRQ=%d address=%pM\n",
                   __func__, ndev->irq, ndev->dev_addr);
index 3e89e34..e9d260d 100644 (file)
@@ -1298,6 +1298,7 @@ static int ocelot_netdevice_lag_leave(struct net_device *dev,
 }
 
 static int ocelot_netdevice_changeupper(struct net_device *dev,
+                                       struct net_device *brport_dev,
                                        struct netdev_notifier_changeupper_info *info)
 {
        struct netlink_ext_ack *extack;
@@ -1307,11 +1308,11 @@ static int ocelot_netdevice_changeupper(struct net_device *dev,
 
        if (netif_is_bridge_master(info->upper_dev)) {
                if (info->linking)
-                       err = ocelot_netdevice_bridge_join(dev, dev,
+                       err = ocelot_netdevice_bridge_join(dev, brport_dev,
                                                           info->upper_dev,
                                                           extack);
                else
-                       err = ocelot_netdevice_bridge_leave(dev, dev,
+                       err = ocelot_netdevice_bridge_leave(dev, brport_dev,
                                                            info->upper_dev);
        }
        if (netif_is_lag_master(info->upper_dev)) {
@@ -1346,7 +1347,7 @@ ocelot_netdevice_lag_changeupper(struct net_device *dev,
                if (ocelot_port->bond != dev)
                        return NOTIFY_OK;
 
-               err = ocelot_netdevice_changeupper(lower, info);
+               err = ocelot_netdevice_changeupper(lower, dev, info);
                if (err)
                        return notifier_from_errno(err);
        }
@@ -1385,7 +1386,7 @@ static int ocelot_netdevice_event(struct notifier_block *unused,
                struct netdev_notifier_changeupper_info *info = ptr;
 
                if (ocelot_netdevice_dev_check(dev))
-                       return ocelot_netdevice_changeupper(dev, info);
+                       return ocelot_netdevice_changeupper(dev, dev, info);
 
                if (netif_is_lag_master(dev))
                        return ocelot_netdevice_lag_changeupper(dev, info);
index 273d529..062bb2d 100644 (file)
@@ -1141,20 +1141,7 @@ int nfp_fl_ct_del_flow(struct nfp_fl_ct_map_entry *ct_map_ent)
                nfp_fl_ct_clean_flow_entry(ct_entry);
                kfree(ct_map_ent);
 
-               /* If this is the last pre_ct_rule it means that it is
-                * very likely that the nft table will be cleaned up next,
-                * as this happens on the removal of the last act_ct flow.
-                * However we cannot deregister the callback on the removal
-                * of the last nft flow as this runs into a deadlock situation.
-                * So deregister the callback on removal of the last pre_ct flow
-                * and remove any remaining nft flow entries. We also cannot
-                * save this state and delete the callback later since the
-                * nft table would already have been freed at that time.
-                */
                if (!zt->pre_ct_count) {
-                       nf_flow_table_offload_del_cb(zt->nft,
-                                                    nfp_fl_ct_handle_nft_flow,
-                                                    zt);
                        zt->nft = NULL;
                        nfp_fl_ct_clean_nft_entries(zt);
                }
@@ -1172,6 +1159,7 @@ int nfp_fl_ct_del_flow(struct nfp_fl_ct_map_entry *ct_map_ent)
                                       nfp_ct_map_params);
                nfp_fl_ct_clean_flow_entry(ct_map_ent->ct_entry);
                kfree(ct_map_ent);
+               break;
        default:
                break;
        }
index 8543bf3..ad655f0 100644 (file)
@@ -735,12 +735,13 @@ static int emac_remove(struct platform_device *pdev)
 
        put_device(&adpt->phydev->mdio.dev);
        mdiobus_unregister(adpt->mii_bus);
-       free_netdev(netdev);
 
        if (adpt->phy.digital)
                iounmap(adpt->phy.digital);
        iounmap(adpt->phy.base);
 
+       free_netdev(netdev);
+
        return 0;
 }
 
index a3ca406..e5b0d79 100644 (file)
@@ -152,6 +152,7 @@ static int efx_allocate_msix_channels(struct efx_nic *efx,
         * maximum size.
         */
        tx_per_ev = EFX_MAX_EVQ_SIZE / EFX_TXQ_MAX_ENT(efx);
+       tx_per_ev = min(tx_per_ev, EFX_MAX_TXQ_PER_CHANNEL);
        n_xdp_tx = num_possible_cpus();
        n_xdp_ev = DIV_ROUND_UP(n_xdp_tx, tx_per_ev);
 
@@ -169,6 +170,8 @@ static int efx_allocate_msix_channels(struct efx_nic *efx,
                netif_err(efx, drv, efx->net_dev,
                          "Insufficient resources for %d XDP event queues (%d other channels, max %d)\n",
                          n_xdp_ev, n_channels, max_channels);
+               netif_err(efx, drv, efx->net_dev,
+                         "XDP_TX and XDP_REDIRECT will not work on this interface");
                efx->n_xdp_channels = 0;
                efx->xdp_tx_per_channel = 0;
                efx->xdp_tx_queue_count = 0;
@@ -176,12 +179,14 @@ static int efx_allocate_msix_channels(struct efx_nic *efx,
                netif_err(efx, drv, efx->net_dev,
                          "Insufficient resources for %d XDP TX queues (%d other channels, max VIs %d)\n",
                          n_xdp_tx, n_channels, efx->max_vis);
+               netif_err(efx, drv, efx->net_dev,
+                         "XDP_TX and XDP_REDIRECT will not work on this interface");
                efx->n_xdp_channels = 0;
                efx->xdp_tx_per_channel = 0;
                efx->xdp_tx_queue_count = 0;
        } else {
                efx->n_xdp_channels = n_xdp_ev;
-               efx->xdp_tx_per_channel = EFX_MAX_TXQ_PER_CHANNEL;
+               efx->xdp_tx_per_channel = tx_per_ev;
                efx->xdp_tx_queue_count = n_xdp_tx;
                n_channels += n_xdp_ev;
                netif_dbg(efx, drv, efx->net_dev,
@@ -891,18 +896,20 @@ int efx_set_channels(struct efx_nic *efx)
                        if (efx_channel_is_xdp_tx(channel)) {
                                efx_for_each_channel_tx_queue(tx_queue, channel) {
                                        tx_queue->queue = next_queue++;
-                                       netif_dbg(efx, drv, efx->net_dev, "Channel %u TXQ %u is XDP %u, HW %u\n",
-                                                 channel->channel, tx_queue->label,
-                                                 xdp_queue_number, tx_queue->queue);
+
                                        /* We may have a few left-over XDP TX
                                         * queues owing to xdp_tx_queue_count
                                         * not dividing evenly by EFX_MAX_TXQ_PER_CHANNEL.
                                         * We still allocate and probe those
                                         * TXQs, but never use them.
                                         */
-                                       if (xdp_queue_number < efx->xdp_tx_queue_count)
+                                       if (xdp_queue_number < efx->xdp_tx_queue_count) {
+                                               netif_dbg(efx, drv, efx->net_dev, "Channel %u TXQ %u is XDP %u, HW %u\n",
+                                                         channel->channel, tx_queue->label,
+                                                         xdp_queue_number, tx_queue->queue);
                                                efx->xdp_tx_queues[xdp_queue_number] = tx_queue;
-                                       xdp_queue_number++;
+                                               xdp_queue_number++;
+                                       }
                                }
                        } else {
                                efx_for_each_channel_tx_queue(tx_queue, channel) {
@@ -914,8 +921,7 @@ int efx_set_channels(struct efx_nic *efx)
                        }
                }
        }
-       if (xdp_queue_number)
-               efx->xdp_tx_queue_count = xdp_queue_number;
+       WARN_ON(xdp_queue_number != efx->xdp_tx_queue_count);
 
        rc = netif_set_real_num_tx_queues(efx->net_dev, efx->n_tx_channels);
        if (rc)
index e108b0d..4c9a37d 100644 (file)
@@ -49,9 +49,9 @@ static int loongson_dwmac_probe(struct pci_dev *pdev, const struct pci_device_id
 {
        struct plat_stmmacenet_data *plat;
        struct stmmac_resources res;
-       bool mdio = false;
-       int ret, i;
        struct device_node *np;
+       int ret, i, phy_mode;
+       bool mdio = false;
 
        np = dev_of_node(&pdev->dev);
 
@@ -108,10 +108,11 @@ static int loongson_dwmac_probe(struct pci_dev *pdev, const struct pci_device_id
        if (plat->bus_id < 0)
                plat->bus_id = pci_dev_id(pdev);
 
-       plat->phy_interface = device_get_phy_mode(&pdev->dev);
-       if (plat->phy_interface < 0)
+       phy_mode = device_get_phy_mode(&pdev->dev);
+       if (phy_mode < 0)
                dev_err(&pdev->dev, "phy_mode not found\n");
 
+       plat->phy_interface = phy_mode;
        plat->interface = PHY_INTERFACE_MODE_GMII;
 
        pci_set_master(pdev);
index e735134..fcdb1d2 100644 (file)
@@ -349,6 +349,9 @@ void stmmac_enable_rx_queue(struct stmmac_priv *priv, u32 queue);
 void stmmac_disable_tx_queue(struct stmmac_priv *priv, u32 queue);
 void stmmac_enable_tx_queue(struct stmmac_priv *priv, u32 queue);
 int stmmac_xsk_wakeup(struct net_device *dev, u32 queue, u32 flags);
+struct timespec64 stmmac_calc_tas_basetime(ktime_t old_base_time,
+                                          ktime_t current_time,
+                                          u64 cycle_time);
 
 #if IS_ENABLED(CONFIG_STMMAC_SELFTESTS)
 void stmmac_selftest_run(struct net_device *dev,
index 8d9d6ec..7b8404a 100644 (file)
@@ -7171,6 +7171,7 @@ int stmmac_suspend(struct device *dev)
                                     priv->plat->rx_queues_to_use, false);
 
                stmmac_fpe_handshake(priv, false);
+               stmmac_fpe_stop_wq(priv);
        }
 
        priv->speed = SPEED_UNKNOWN;
index 072eff8..5ca7108 100644 (file)
@@ -397,6 +397,7 @@ stmmac_probe_config_dt(struct platform_device *pdev, u8 *mac)
        struct device_node *np = pdev->dev.of_node;
        struct plat_stmmacenet_data *plat;
        struct stmmac_dma_cfg *dma_cfg;
+       int phy_mode;
        void *ret;
        int rc;
 
@@ -412,10 +413,11 @@ stmmac_probe_config_dt(struct platform_device *pdev, u8 *mac)
                eth_zero_addr(mac);
        }
 
-       plat->phy_interface = device_get_phy_mode(&pdev->dev);
-       if (plat->phy_interface < 0)
-               return ERR_PTR(plat->phy_interface);
+       phy_mode = device_get_phy_mode(&pdev->dev);
+       if (phy_mode < 0)
+               return ERR_PTR(phy_mode);
 
+       plat->phy_interface = phy_mode;
        plat->interface = stmmac_of_get_mac_mode(np);
        if (plat->interface < 0)
                plat->interface = plat->phy_interface;
index 4e86cdf..580cc03 100644 (file)
@@ -62,7 +62,8 @@ static int stmmac_adjust_time(struct ptp_clock_info *ptp, s64 delta)
        u32 sec, nsec;
        u32 quotient, reminder;
        int neg_adj = 0;
-       bool xmac;
+       bool xmac, est_rst = false;
+       int ret;
 
        xmac = priv->plat->has_gmac4 || priv->plat->has_xgmac;
 
@@ -75,10 +76,48 @@ static int stmmac_adjust_time(struct ptp_clock_info *ptp, s64 delta)
        sec = quotient;
        nsec = reminder;
 
+       /* If EST is enabled, disabled it before adjust ptp time. */
+       if (priv->plat->est && priv->plat->est->enable) {
+               est_rst = true;
+               mutex_lock(&priv->plat->est->lock);
+               priv->plat->est->enable = false;
+               stmmac_est_configure(priv, priv->ioaddr, priv->plat->est,
+                                    priv->plat->clk_ptp_rate);
+               mutex_unlock(&priv->plat->est->lock);
+       }
+
        spin_lock_irqsave(&priv->ptp_lock, flags);
        stmmac_adjust_systime(priv, priv->ptpaddr, sec, nsec, neg_adj, xmac);
        spin_unlock_irqrestore(&priv->ptp_lock, flags);
 
+       /* Caculate new basetime and re-configured EST after PTP time adjust. */
+       if (est_rst) {
+               struct timespec64 current_time, time;
+               ktime_t current_time_ns, basetime;
+               u64 cycle_time;
+
+               mutex_lock(&priv->plat->est->lock);
+               priv->ptp_clock_ops.gettime64(&priv->ptp_clock_ops, &current_time);
+               current_time_ns = timespec64_to_ktime(current_time);
+               time.tv_nsec = priv->plat->est->btr_reserve[0];
+               time.tv_sec = priv->plat->est->btr_reserve[1];
+               basetime = timespec64_to_ktime(time);
+               cycle_time = priv->plat->est->ctr[1] * NSEC_PER_SEC +
+                            priv->plat->est->ctr[0];
+               time = stmmac_calc_tas_basetime(basetime,
+                                               current_time_ns,
+                                               cycle_time);
+
+               priv->plat->est->btr[0] = (u32)time.tv_nsec;
+               priv->plat->est->btr[1] = (u32)time.tv_sec;
+               priv->plat->est->enable = true;
+               ret = stmmac_est_configure(priv, priv->ioaddr, priv->plat->est,
+                                          priv->plat->clk_ptp_rate);
+               mutex_unlock(&priv->plat->est->lock);
+               if (ret)
+                       netdev_err(priv->dev, "failed to configure EST\n");
+       }
+
        return 0;
 }
 
index 92dab60..4f3b643 100644 (file)
@@ -711,12 +711,35 @@ static int tc_setup_cls(struct stmmac_priv *priv,
        return ret;
 }
 
+struct timespec64 stmmac_calc_tas_basetime(ktime_t old_base_time,
+                                          ktime_t current_time,
+                                          u64 cycle_time)
+{
+       struct timespec64 time;
+
+       if (ktime_after(old_base_time, current_time)) {
+               time = ktime_to_timespec64(old_base_time);
+       } else {
+               s64 n;
+               ktime_t base_time;
+
+               n = div64_s64(ktime_sub_ns(current_time, old_base_time),
+                             cycle_time);
+               base_time = ktime_add_ns(old_base_time,
+                                        (n + 1) * cycle_time);
+
+               time = ktime_to_timespec64(base_time);
+       }
+
+       return time;
+}
+
 static int tc_setup_taprio(struct stmmac_priv *priv,
                           struct tc_taprio_qopt_offload *qopt)
 {
        u32 size, wid = priv->dma_cap.estwid, dep = priv->dma_cap.estdep;
        struct plat_stmmacenet_data *plat = priv->plat;
-       struct timespec64 time, current_time;
+       struct timespec64 time, current_time, qopt_time;
        ktime_t current_time_ns;
        bool fpe = false;
        int i, ret = 0;
@@ -773,14 +796,18 @@ static int tc_setup_taprio(struct stmmac_priv *priv,
                                         GFP_KERNEL);
                if (!plat->est)
                        return -ENOMEM;
+
+               mutex_init(&priv->plat->est->lock);
        } else {
                memset(plat->est, 0, sizeof(*plat->est));
        }
 
        size = qopt->num_entries;
 
+       mutex_lock(&priv->plat->est->lock);
        priv->plat->est->gcl_size = size;
        priv->plat->est->enable = qopt->enable;
+       mutex_unlock(&priv->plat->est->lock);
 
        for (i = 0; i < size; i++) {
                s64 delta_ns = qopt->entries[i].interval;
@@ -811,32 +838,28 @@ static int tc_setup_taprio(struct stmmac_priv *priv,
                priv->plat->est->gcl[i] = delta_ns | (gates << wid);
        }
 
+       mutex_lock(&priv->plat->est->lock);
        /* Adjust for real system time */
        priv->ptp_clock_ops.gettime64(&priv->ptp_clock_ops, &current_time);
        current_time_ns = timespec64_to_ktime(current_time);
-       if (ktime_after(qopt->base_time, current_time_ns)) {
-               time = ktime_to_timespec64(qopt->base_time);
-       } else {
-               ktime_t base_time;
-               s64 n;
-
-               n = div64_s64(ktime_sub_ns(current_time_ns, qopt->base_time),
-                             qopt->cycle_time);
-               base_time = ktime_add_ns(qopt->base_time,
-                                        (n + 1) * qopt->cycle_time);
-
-               time = ktime_to_timespec64(base_time);
-       }
+       time = stmmac_calc_tas_basetime(qopt->base_time, current_time_ns,
+                                       qopt->cycle_time);
 
        priv->plat->est->btr[0] = (u32)time.tv_nsec;
        priv->plat->est->btr[1] = (u32)time.tv_sec;
 
+       qopt_time = ktime_to_timespec64(qopt->base_time);
+       priv->plat->est->btr_reserve[0] = (u32)qopt_time.tv_nsec;
+       priv->plat->est->btr_reserve[1] = (u32)qopt_time.tv_sec;
+
        ctr = qopt->cycle_time;
        priv->plat->est->ctr[0] = do_div(ctr, NSEC_PER_SEC);
        priv->plat->est->ctr[1] = (u32)ctr;
 
-       if (fpe && !priv->dma_cap.fpesel)
+       if (fpe && !priv->dma_cap.fpesel) {
+               mutex_unlock(&priv->plat->est->lock);
                return -EOPNOTSUPP;
+       }
 
        /* Actual FPE register configuration will be done after FPE handshake
         * is success.
@@ -845,6 +868,7 @@ static int tc_setup_taprio(struct stmmac_priv *priv,
 
        ret = stmmac_est_configure(priv, priv->ioaddr, priv->plat->est,
                                   priv->plat->clk_ptp_rate);
+       mutex_unlock(&priv->plat->est->lock);
        if (ret) {
                netdev_err(priv->dev, "failed to configure EST\n");
                goto disable;
@@ -860,9 +884,11 @@ static int tc_setup_taprio(struct stmmac_priv *priv,
        return 0;
 
 disable:
+       mutex_lock(&priv->plat->est->lock);
        priv->plat->est->enable = false;
        stmmac_est_configure(priv, priv->ioaddr, priv->plat->est,
                             priv->plat->clk_ptp_rate);
+       mutex_unlock(&priv->plat->est->lock);
 
        priv->plat->fpe_cfg->enable = false;
        stmmac_fpe_configure(priv, priv->ioaddr,
index 0b2ce4b..e0cb713 100644 (file)
@@ -313,9 +313,8 @@ static void tlan_remove_one(struct pci_dev *pdev)
        pci_release_regions(pdev);
 #endif
 
-       free_netdev(dev);
-
        cancel_work_sync(&priv->tlan_tqueue);
+       free_netdev(dev);
 }
 
 static void tlan_start(struct net_device *dev)
index 14f0705..0de2c45 100644 (file)
@@ -1504,9 +1504,8 @@ err_out_resource:
        release_mem_region(start, len);
 
 err_out_kfree:
-       free_netdev(dev);
-
        pr_err("%s: initialization failure, aborting!\n", fp->name);
+       free_netdev(dev);
        return ret;
 }
 
index 3811f1b..b80ed2f 100644 (file)
@@ -85,7 +85,7 @@ static int nsim_ipsec_parse_proto_keys(struct xfrm_state *xs,
                                       u32 *mykey, u32 *mysalt)
 {
        const char aes_gcm_name[] = "rfc4106(gcm(aes))";
-       struct net_device *dev = xs->xso.dev;
+       struct net_device *dev = xs->xso.real_dev;
        unsigned char *key_data;
        char *alg_name = NULL;
        int key_len;
@@ -134,7 +134,7 @@ static int nsim_ipsec_add_sa(struct xfrm_state *xs)
        u16 sa_idx;
        int ret;
 
-       dev = xs->xso.dev;
+       dev = xs->xso.real_dev;
        ns = netdev_priv(dev);
        ipsec = &ns->ipsec;
 
@@ -194,7 +194,7 @@ static int nsim_ipsec_add_sa(struct xfrm_state *xs)
 
 static void nsim_ipsec_del_sa(struct xfrm_state *xs)
 {
-       struct netdevsim *ns = netdev_priv(xs->xso.dev);
+       struct netdevsim *ns = netdev_priv(xs->xso.real_dev);
        struct nsim_ipsec *ipsec = &ns->ipsec;
        u16 sa_idx;
 
@@ -211,7 +211,7 @@ static void nsim_ipsec_del_sa(struct xfrm_state *xs)
 
 static bool nsim_ipsec_offload_ok(struct sk_buff *skb, struct xfrm_state *xs)
 {
-       struct netdevsim *ns = netdev_priv(xs->xso.dev);
+       struct netdevsim *ns = netdev_priv(xs->xso.real_dev);
        struct nsim_ipsec *ipsec = &ns->ipsec;
 
        ipsec->ok++;
index bbbc6ac..53a4334 100644 (file)
@@ -78,6 +78,11 @@ enum {
        /* Temperature read register (88E2110 only) */
        MV_PCS_TEMP             = 0x8042,
 
+       /* Number of ports on the device */
+       MV_PCS_PORT_INFO        = 0xd00d,
+       MV_PCS_PORT_INFO_NPORTS_MASK    = 0x0380,
+       MV_PCS_PORT_INFO_NPORTS_SHIFT   = 7,
+
        /* These registers appear at 0x800X and 0xa00X - the 0xa00X control
         * registers appear to set themselves to the 0x800X when AN is
         * restarted, but status registers appear readable from either.
@@ -966,6 +971,30 @@ static const struct mv3310_chip mv2111_type = {
 #endif
 };
 
+static int mv3310_get_number_of_ports(struct phy_device *phydev)
+{
+       int ret;
+
+       ret = phy_read_mmd(phydev, MDIO_MMD_PCS, MV_PCS_PORT_INFO);
+       if (ret < 0)
+               return ret;
+
+       ret &= MV_PCS_PORT_INFO_NPORTS_MASK;
+       ret >>= MV_PCS_PORT_INFO_NPORTS_SHIFT;
+
+       return ret + 1;
+}
+
+static int mv3310_match_phy_device(struct phy_device *phydev)
+{
+       return mv3310_get_number_of_ports(phydev) == 1;
+}
+
+static int mv3340_match_phy_device(struct phy_device *phydev)
+{
+       return mv3310_get_number_of_ports(phydev) == 4;
+}
+
 static int mv211x_match_phy_device(struct phy_device *phydev, bool has_5g)
 {
        int val;
@@ -994,7 +1023,8 @@ static int mv2111_match_phy_device(struct phy_device *phydev)
 static struct phy_driver mv3310_drivers[] = {
        {
                .phy_id         = MARVELL_PHY_ID_88X3310,
-               .phy_id_mask    = MARVELL_PHY_ID_88X33X0_MASK,
+               .phy_id_mask    = MARVELL_PHY_ID_MASK,
+               .match_phy_device = mv3310_match_phy_device,
                .name           = "mv88x3310",
                .driver_data    = &mv3310_type,
                .get_features   = mv3310_get_features,
@@ -1011,8 +1041,9 @@ static struct phy_driver mv3310_drivers[] = {
                .set_loopback   = genphy_c45_loopback,
        },
        {
-               .phy_id         = MARVELL_PHY_ID_88X3340,
-               .phy_id_mask    = MARVELL_PHY_ID_88X33X0_MASK,
+               .phy_id         = MARVELL_PHY_ID_88X3310,
+               .phy_id_mask    = MARVELL_PHY_ID_MASK,
+               .match_phy_device = mv3340_match_phy_device,
                .name           = "mv88x3340",
                .driver_data    = &mv3340_type,
                .get_features   = mv3310_get_features,
@@ -1069,8 +1100,7 @@ static struct phy_driver mv3310_drivers[] = {
 module_phy_driver(mv3310_drivers);
 
 static struct mdio_device_id __maybe_unused mv3310_tbl[] = {
-       { MARVELL_PHY_ID_88X3310, MARVELL_PHY_ID_88X33X0_MASK },
-       { MARVELL_PHY_ID_88X3340, MARVELL_PHY_ID_88X33X0_MASK },
+       { MARVELL_PHY_ID_88X3310, MARVELL_PHY_ID_MASK },
        { MARVELL_PHY_ID_88E2110, MARVELL_PHY_ID_MASK },
        { },
 };
index aec97b0..2c11521 100644 (file)
@@ -701,6 +701,7 @@ static int ax88772_init_phy(struct usbnet *dev)
                return ret;
        }
 
+       phy_suspend(priv->phydev);
        priv->phydev->mac_managed_pm = 1;
 
        phy_attached_info(priv->phydev);
index 8a58a2f..56c3f85 100644 (file)
@@ -1771,6 +1771,7 @@ static bool virtnet_send_command(struct virtnet_info *vi, u8 class, u8 cmd,
 {
        struct scatterlist *sgs[4], hdr, stat;
        unsigned out_num = 0, tmp;
+       int ret;
 
        /* Caller should know better */
        BUG_ON(!virtio_has_feature(vi->vdev, VIRTIO_NET_F_CTRL_VQ));
@@ -1790,7 +1791,12 @@ static bool virtnet_send_command(struct virtnet_info *vi, u8 class, u8 cmd,
        sgs[out_num] = &stat;
 
        BUG_ON(out_num + 1 > ARRAY_SIZE(sgs));
-       virtqueue_add_sgs(vi->cvq, sgs, out_num, 1, vi, GFP_ATOMIC);
+       ret = virtqueue_add_sgs(vi->cvq, sgs, out_num, 1, vi, GFP_ATOMIC);
+       if (ret < 0) {
+               dev_warn(&vi->vdev->dev,
+                        "Failed to add sgs for command vq: %d\n.", ret);
+               return false;
+       }
 
        if (unlikely(!virtqueue_kick(vi->cvq)))
                return vi->ctrl->status == VIRTIO_NET_OK;
index c0bd9cb..1b483cf 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Linux driver for VMware's vmxnet3 ethernet NIC.
  *
- * Copyright (C) 2008-2020, VMware, Inc. All Rights Reserved.
+ * Copyright (C) 2008-2021, VMware, Inc. All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the
 
 
 #include "vmxnet3_int.h"
+#include <net/vxlan.h>
+#include <net/geneve.h>
+
+#define VXLAN_UDP_PORT 8472
 
 struct vmxnet3_stat_desc {
        char desc[ETH_GSTRING_LEN];
@@ -262,6 +266,8 @@ netdev_features_t vmxnet3_features_check(struct sk_buff *skb,
        if (VMXNET3_VERSION_GE_4(adapter) &&
            skb->encapsulation && skb->ip_summed == CHECKSUM_PARTIAL) {
                u8 l4_proto = 0;
+               u16 port;
+               struct udphdr *udph;
 
                switch (vlan_get_protocol(skb)) {
                case htons(ETH_P_IP):
@@ -274,8 +280,20 @@ netdev_features_t vmxnet3_features_check(struct sk_buff *skb,
                        return features & ~(NETIF_F_CSUM_MASK | NETIF_F_GSO_MASK);
                }
 
-               if (l4_proto != IPPROTO_UDP)
+               switch (l4_proto) {
+               case IPPROTO_UDP:
+                       udph = udp_hdr(skb);
+                       port = be16_to_cpu(udph->dest);
+                       /* Check if offloaded port is supported */
+                       if (port != GENEVE_UDP_PORT &&
+                           port != IANA_VXLAN_UDP_PORT &&
+                           port != VXLAN_UDP_PORT) {
+                               return features & ~(NETIF_F_CSUM_MASK | NETIF_F_GSO_MASK);
+                       }
+                       break;
+               default:
                        return features & ~(NETIF_F_CSUM_MASK | NETIF_F_GSO_MASK);
+               }
        }
        return features;
 }
index 349ca18..c54fdae 100644 (file)
@@ -364,19 +364,19 @@ static int cisco_ioctl(struct net_device *dev, struct ifreq *ifr)
        return -EINVAL;
 }
 
-static int __init mod_init(void)
+static int __init hdlc_cisco_init(void)
 {
        register_hdlc_protocol(&proto);
        return 0;
 }
 
-static void __exit mod_exit(void)
+static void __exit hdlc_cisco_exit(void)
 {
        unregister_hdlc_protocol(&proto);
 }
 
-module_init(mod_init);
-module_exit(mod_exit);
+module_init(hdlc_cisco_init);
+module_exit(hdlc_cisco_exit);
 
 MODULE_AUTHOR("Krzysztof Halasa <khc@pm.waw.pl>");
 MODULE_DESCRIPTION("Cisco HDLC protocol support for generic HDLC");
index 72250fe..25e3564 100644 (file)
@@ -1279,19 +1279,19 @@ static int fr_ioctl(struct net_device *dev, struct ifreq *ifr)
        return -EINVAL;
 }
 
-static int __init mod_init(void)
+static int __init hdlc_fr_init(void)
 {
        register_hdlc_protocol(&proto);
        return 0;
 }
 
-static void __exit mod_exit(void)
+static void __exit hdlc_fr_exit(void)
 {
        unregister_hdlc_protocol(&proto);
 }
 
-module_init(mod_init);
-module_exit(mod_exit);
+module_init(hdlc_fr_init);
+module_exit(hdlc_fr_exit);
 
 MODULE_AUTHOR("Krzysztof Halasa <khc@pm.waw.pl>");
 MODULE_DESCRIPTION("Frame-Relay protocol support for generic HDLC");
index 834be2a..b81ecf4 100644 (file)
@@ -705,20 +705,20 @@ static int ppp_ioctl(struct net_device *dev, struct ifreq *ifr)
        return -EINVAL;
 }
 
-static int __init mod_init(void)
+static int __init hdlc_ppp_init(void)
 {
        skb_queue_head_init(&tx_queue);
        register_hdlc_protocol(&proto);
        return 0;
 }
 
-static void __exit mod_exit(void)
+static void __exit hdlc_ppp_exit(void)
 {
        unregister_hdlc_protocol(&proto);
 }
 
-module_init(mod_init);
-module_exit(mod_exit);
+module_init(hdlc_ppp_init);
+module_exit(hdlc_ppp_exit);
 
 MODULE_AUTHOR("Krzysztof Halasa <khc@pm.waw.pl>");
 MODULE_DESCRIPTION("PPP protocol support for generic HDLC");
index 388fcc0..54d2849 100644 (file)
@@ -90,7 +90,7 @@ static int raw_ioctl(struct net_device *dev, struct ifreq *ifr)
 }
 
 
-static int __init mod_init(void)
+static int __init hdlc_raw_init(void)
 {
        register_hdlc_protocol(&proto);
        return 0;
@@ -98,14 +98,14 @@ static int __init mod_init(void)
 
 
 
-static void __exit mod_exit(void)
+static void __exit hdlc_raw_exit(void)
 {
        unregister_hdlc_protocol(&proto);
 }
 
 
-module_init(mod_init);
-module_exit(mod_exit);
+module_init(hdlc_raw_init);
+module_exit(hdlc_raw_exit);
 
 MODULE_AUTHOR("Krzysztof Halasa <khc@pm.waw.pl>");
 MODULE_DESCRIPTION("Raw HDLC protocol support for generic HDLC");
index c70a518..9275962 100644 (file)
@@ -110,7 +110,7 @@ static int raw_eth_ioctl(struct net_device *dev, struct ifreq *ifr)
 }
 
 
-static int __init mod_init(void)
+static int __init hdlc_eth_init(void)
 {
        register_hdlc_protocol(&proto);
        return 0;
@@ -118,14 +118,14 @@ static int __init mod_init(void)
 
 
 
-static void __exit mod_exit(void)
+static void __exit hdlc_eth_exit(void)
 {
        unregister_hdlc_protocol(&proto);
 }
 
 
-module_init(mod_init);
-module_exit(mod_exit);
+module_init(hdlc_eth_init);
+module_exit(hdlc_eth_exit);
 
 MODULE_AUTHOR("Krzysztof Halasa <khc@pm.waw.pl>");
 MODULE_DESCRIPTION("Ethernet encapsulation support for generic HDLC");
index d2bf72b..9b7ebf8 100644 (file)
@@ -365,19 +365,19 @@ static int x25_ioctl(struct net_device *dev, struct ifreq *ifr)
        return -EINVAL;
 }
 
-static int __init mod_init(void)
+static int __init hdlc_x25_init(void)
 {
        register_hdlc_protocol(&proto);
        return 0;
 }
 
-static void __exit mod_exit(void)
+static void __exit hdlc_x25_exit(void)
 {
        unregister_hdlc_protocol(&proto);
 }
 
-module_init(mod_init);
-module_exit(mod_exit);
+module_init(hdlc_x25_init);
+module_exit(hdlc_x25_exit);
 
 MODULE_AUTHOR("Krzysztof Halasa <khc@pm.waw.pl>");
 MODULE_DESCRIPTION("X.25 protocol support for generic HDLC");
index 7fd2104..63ec140 100644 (file)
@@ -389,6 +389,7 @@ static int mt7921_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
        case WLAN_CIPHER_SUITE_WEP104:
                if (!mvif->wep_sta)
                        return -EOPNOTSUPP;
+               break;
        case WLAN_CIPHER_SUITE_TKIP:
        case WLAN_CIPHER_SUITE_CCMP:
        case WLAN_CIPHER_SUITE_CCMP_256:
index c2c4dc1..cd690c6 100644 (file)
@@ -931,7 +931,7 @@ static int mt7921_load_firmware(struct mt7921_dev *dev)
        ret = mt76_get_field(dev, MT_CONN_ON_MISC, MT_TOP_MISC2_FW_N9_RDY);
        if (ret) {
                dev_dbg(dev->mt76.dev, "Firmware is already download\n");
-               return -EIO;
+               goto fw_loaded;
        }
 
        ret = mt7921_load_patch(dev);
@@ -949,6 +949,7 @@ static int mt7921_load_firmware(struct mt7921_dev *dev)
                return -EIO;
        }
 
+fw_loaded:
        mt76_queue_tx_cleanup(dev, dev->mt76.q_mcu[MT_MCUQ_FWDL], false);
 
 #ifdef CONFIG_PM
index 46f76e8..0a472ce 100644 (file)
@@ -24,15 +24,7 @@ int ipc_imem_sys_wwan_open(struct iosm_imem *ipc_imem, int if_id)
                return -EIO;
        }
 
-       /* check for the interafce id
-        * if if_id 1 to 8 then create IP MUX channel sessions.
-        * To start MUX session from 0 as network interface id would start
-        * from 1 so map it to if_id = if_id - 1
-        */
-       if (if_id >= IP_MUX_SESSION_START && if_id <= IP_MUX_SESSION_END)
-               return ipc_mux_open_session(ipc_imem->mux, if_id - 1);
-
-       return -EINVAL;
+       return ipc_mux_open_session(ipc_imem->mux, if_id);
 }
 
 /* Release a net link to CP. */
@@ -41,7 +33,7 @@ void ipc_imem_sys_wwan_close(struct iosm_imem *ipc_imem, int if_id,
 {
        if (ipc_imem->mux && if_id >= IP_MUX_SESSION_START &&
            if_id <= IP_MUX_SESSION_END)
-               ipc_mux_close_session(ipc_imem->mux, if_id - 1);
+               ipc_mux_close_session(ipc_imem->mux, if_id);
 }
 
 /* Tasklet call to do uplink transfer. */
@@ -83,13 +75,8 @@ int ipc_imem_sys_wwan_transmit(struct iosm_imem *ipc_imem,
                goto out;
        }
 
-       if (if_id >= IP_MUX_SESSION_START && if_id <= IP_MUX_SESSION_END)
-               /* Route the UL packet through IP MUX Layer */
-               ret = ipc_mux_ul_trigger_encode(ipc_imem->mux,
-                                               if_id - 1, skb);
-       else
-               dev_err(ipc_imem->dev,
-                       "invalid if_id %d: ", if_id);
+       /* Route the UL packet through IP MUX Layer */
+       ret = ipc_mux_ul_trigger_encode(ipc_imem->mux, if_id, skb);
 out:
        return ret;
 }
index fd356da..2007fe2 100644 (file)
 #define BOOT_CHECK_DEFAULT_TIMEOUT 400
 
 /* IP MUX channel range */
-#define IP_MUX_SESSION_START 1
-#define IP_MUX_SESSION_END 8
+#define IP_MUX_SESSION_START 0
+#define IP_MUX_SESSION_END 7
 
 /* Default IP MUX channel */
-#define IP_MUX_SESSION_DEFAULT 1
+#define IP_MUX_SESSION_DEFAULT 0
 
 /**
  * ipc_imem_sys_port_open - Open a port link to CP.
index e634ffc..562de27 100644 (file)
@@ -288,7 +288,7 @@ static int ipc_mux_net_receive(struct iosm_mux *ipc_mux, int if_id,
        /* Pass the packet to the netif layer. */
        dest_skb->priority = service_class;
 
-       return ipc_wwan_receive(wwan, dest_skb, false, if_id + 1);
+       return ipc_wwan_receive(wwan, dest_skb, false, if_id);
 }
 
 /* Decode Flow Credit Table in the block */
index 2229d75..d12188f 100644 (file)
@@ -37,7 +37,7 @@ void ipc_uevent_send(struct device *dev, char *uevent)
 
        /* Store the device and event information */
        info->dev = dev;
-       snprintf(info->uevent, MAX_UEVENT_LEN, "%s: %s", dev_name(dev), uevent);
+       snprintf(info->uevent, MAX_UEVENT_LEN, "IOSM_EVENT=%s", uevent);
 
        /* Schedule uevent in process context using work queue */
        schedule_work(&info->work);
index c999c64..b2357ad 100644 (file)
@@ -107,6 +107,7 @@ static int ipc_wwan_link_transmit(struct sk_buff *skb,
 {
        struct iosm_netdev_priv *priv = wwan_netdev_drvpriv(netdev);
        struct iosm_wwan *ipc_wwan = priv->ipc_wwan;
+       unsigned int len = skb->len;
        int if_id = priv->if_id;
        int ret;
 
@@ -123,6 +124,8 @@ static int ipc_wwan_link_transmit(struct sk_buff *skb,
 
        /* Return code of zero is success */
        if (ret == 0) {
+               netdev->stats.tx_packets++;
+               netdev->stats.tx_bytes += len;
                ret = NETDEV_TX_OK;
        } else if (ret == -EBUSY) {
                ret = NETDEV_TX_BUSY;
@@ -140,7 +143,8 @@ exit:
                        ret);
 
        dev_kfree_skb_any(skb);
-       return ret;
+       netdev->stats.tx_dropped++;
+       return NETDEV_TX_OK;
 }
 
 /* Ops structure for wwan net link */
@@ -158,6 +162,7 @@ static void ipc_wwan_setup(struct net_device *iosm_dev)
        iosm_dev->priv_flags |= IFF_NO_QUEUE;
 
        iosm_dev->type = ARPHRD_NONE;
+       iosm_dev->mtu = ETH_DATA_LEN;
        iosm_dev->min_mtu = ETH_MIN_MTU;
        iosm_dev->max_mtu = ETH_MAX_MTU;
 
@@ -252,8 +257,8 @@ int ipc_wwan_receive(struct iosm_wwan *ipc_wwan, struct sk_buff *skb_arg,
 
        skb->pkt_type = PACKET_HOST;
 
-       if (if_id < (IP_MUX_SESSION_START - 1) ||
-           if_id > (IP_MUX_SESSION_END - 1)) {
+       if (if_id < IP_MUX_SESSION_START ||
+           if_id > IP_MUX_SESSION_END) {
                ret = -EINVAL;
                goto free;
        }
index d3c5086..320051f 100644 (file)
@@ -1554,6 +1554,28 @@ static void nvme_init_queue(struct nvme_queue *nvmeq, u16 qid)
        wmb(); /* ensure the first interrupt sees the initialization */
 }
 
+/*
+ * Try getting shutdown_lock while setting up IO queues.
+ */
+static int nvme_setup_io_queues_trylock(struct nvme_dev *dev)
+{
+       /*
+        * Give up if the lock is being held by nvme_dev_disable.
+        */
+       if (!mutex_trylock(&dev->shutdown_lock))
+               return -ENODEV;
+
+       /*
+        * Controller is in wrong state, fail early.
+        */
+       if (dev->ctrl.state != NVME_CTRL_CONNECTING) {
+               mutex_unlock(&dev->shutdown_lock);
+               return -ENODEV;
+       }
+
+       return 0;
+}
+
 static int nvme_create_queue(struct nvme_queue *nvmeq, int qid, bool polled)
 {
        struct nvme_dev *dev = nvmeq->dev;
@@ -1582,8 +1604,11 @@ static int nvme_create_queue(struct nvme_queue *nvmeq, int qid, bool polled)
                goto release_cq;
 
        nvmeq->cq_vector = vector;
-       nvme_init_queue(nvmeq, qid);
 
+       result = nvme_setup_io_queues_trylock(dev);
+       if (result)
+               return result;
+       nvme_init_queue(nvmeq, qid);
        if (!polled) {
                result = queue_request_irq(nvmeq);
                if (result < 0)
@@ -1591,10 +1616,12 @@ static int nvme_create_queue(struct nvme_queue *nvmeq, int qid, bool polled)
        }
 
        set_bit(NVMEQ_ENABLED, &nvmeq->flags);
+       mutex_unlock(&dev->shutdown_lock);
        return result;
 
 release_sq:
        dev->online_queues--;
+       mutex_unlock(&dev->shutdown_lock);
        adapter_delete_sq(dev, qid);
 release_cq:
        adapter_delete_cq(dev, qid);
@@ -2167,7 +2194,18 @@ static int nvme_setup_io_queues(struct nvme_dev *dev)
        if (nr_io_queues == 0)
                return 0;
 
-       clear_bit(NVMEQ_ENABLED, &adminq->flags);
+       /*
+        * Free IRQ resources as soon as NVMEQ_ENABLED bit transitions
+        * from set to unset. If there is a window to it is truely freed,
+        * pci_free_irq_vectors() jumping into this window will crash.
+        * And take lock to avoid racing with pci_free_irq_vectors() in
+        * nvme_dev_disable() path.
+        */
+       result = nvme_setup_io_queues_trylock(dev);
+       if (result)
+               return result;
+       if (test_and_clear_bit(NVMEQ_ENABLED, &adminq->flags))
+               pci_free_irq(pdev, 0, adminq);
 
        if (dev->cmb_use_sqes) {
                result = nvme_cmb_qdepth(dev, nr_io_queues,
@@ -2183,14 +2221,17 @@ static int nvme_setup_io_queues(struct nvme_dev *dev)
                result = nvme_remap_bar(dev, size);
                if (!result)
                        break;
-               if (!--nr_io_queues)
-                       return -ENOMEM;
+               if (!--nr_io_queues) {
+                       result = -ENOMEM;
+                       goto out_unlock;
+               }
        } while (1);
        adminq->q_db = dev->dbs;
 
  retry:
        /* Deregister the admin queue's interrupt */
-       pci_free_irq(pdev, 0, adminq);
+       if (test_and_clear_bit(NVMEQ_ENABLED, &adminq->flags))
+               pci_free_irq(pdev, 0, adminq);
 
        /*
         * If we enable msix early due to not intx, disable it again before
@@ -2199,8 +2240,10 @@ static int nvme_setup_io_queues(struct nvme_dev *dev)
        pci_free_irq_vectors(pdev);
 
        result = nvme_setup_irqs(dev, nr_io_queues);
-       if (result <= 0)
-               return -EIO;
+       if (result <= 0) {
+               result = -EIO;
+               goto out_unlock;
+       }
 
        dev->num_vecs = result;
        result = max(result - 1, 1);
@@ -2214,8 +2257,9 @@ static int nvme_setup_io_queues(struct nvme_dev *dev)
         */
        result = queue_request_irq(adminq);
        if (result)
-               return result;
+               goto out_unlock;
        set_bit(NVMEQ_ENABLED, &adminq->flags);
+       mutex_unlock(&dev->shutdown_lock);
 
        result = nvme_create_io_queues(dev);
        if (result || dev->online_queues < 2)
@@ -2224,6 +2268,9 @@ static int nvme_setup_io_queues(struct nvme_dev *dev)
        if (dev->online_queues - 1 < dev->max_qid) {
                nr_io_queues = dev->online_queues - 1;
                nvme_disable_io_queues(dev);
+               result = nvme_setup_io_queues_trylock(dev);
+               if (result)
+                       return result;
                nvme_suspend_io_queues(dev);
                goto retry;
        }
@@ -2232,6 +2279,9 @@ static int nvme_setup_io_queues(struct nvme_dev *dev)
                                        dev->io_queues[HCTX_TYPE_READ],
                                        dev->io_queues[HCTX_TYPE_POLL]);
        return 0;
+out_unlock:
+       mutex_unlock(&dev->shutdown_lock);
+       return result;
 }
 
 static void nvme_del_queue_end(struct request *req, blk_status_t error)
@@ -2962,7 +3012,6 @@ static void nvme_remove(struct pci_dev *pdev)
        if (!pci_device_is_present(pdev)) {
                nvme_change_ctrl_state(&dev->ctrl, NVME_CTRL_DEAD);
                nvme_dev_disable(dev, true);
-               nvme_dev_remove_admin(dev);
        }
 
        flush_work(&dev->ctrl.reset_work);
index 12acfe0..8cb15ee 100644 (file)
@@ -123,7 +123,6 @@ struct nvme_tcp_ctrl {
        struct blk_mq_tag_set   admin_tag_set;
        struct sockaddr_storage addr;
        struct sockaddr_storage src_addr;
-       struct net_device       *ndev;
        struct nvme_ctrl        ctrl;
 
        struct work_struct      err_work;
@@ -2533,8 +2532,7 @@ static struct nvme_ctrl *nvme_tcp_create_ctrl(struct device *dev,
        }
 
        if (opts->mask & NVMF_OPT_HOST_IFACE) {
-               ctrl->ndev = dev_get_by_name(&init_net, opts->host_iface);
-               if (!ctrl->ndev) {
+               if (!__dev_get_by_name(&init_net, opts->host_iface)) {
                        pr_err("invalid interface passed: %s\n",
                               opts->host_iface);
                        ret = -ENODEV;
index 9bab073..d32fbfc 100644 (file)
@@ -230,8 +230,8 @@ static long proc_bus_pci_ioctl(struct file *file, unsigned int cmd,
                        break;
                }
                /* If arch decided it can't, fall through... */
-#endif /* HAVE_PCI_MMAP */
                fallthrough;
+#endif /* HAVE_PCI_MMAP */
        default:
                ret = -EINVAL;
                break;
index 3d45ed0..a6ebdb2 100644 (file)
@@ -1728,6 +1728,7 @@ static void ab8500_fg_algorithm_calibrate(struct ab8500_fg *di)
                break;
        case AB8500_FG_CALIB_WAIT:
                dev_dbg(di->dev, "Calibration WFI\n");
+               break;
        default:
                break;
        }
@@ -2224,6 +2225,7 @@ static int ab8500_fg_get_ext_psy_data(struct device *dev, void *data)
                                        queue_work(di->fg_wq, &di->fg_work);
                                        break;
                                }
+                               break;
                        default:
                                break;
                        }
index a17849b..b72826c 100644 (file)
@@ -1150,6 +1150,7 @@ static int abx500_chargalg_get_ext_psy_data(struct device *dev, void *data)
                                default:
                                        break;
                                }
+                               break;
                        default:
                                break;
                        }
index 8673d17..28a6fe3 100644 (file)
@@ -3,7 +3,7 @@
 # Makefile for PTP 1588 clock support.
 #
 
-ptp-y                                  := ptp_clock.o ptp_chardev.o ptp_sysfs.o
+ptp-y                                  := ptp_clock.o ptp_chardev.o ptp_sysfs.o ptp_vclock.o
 ptp_kvm-$(CONFIG_X86)                  := ptp_kvm_x86.o ptp_kvm_common.o
 ptp_kvm-$(CONFIG_HAVE_ARM_SMCCC)       := ptp_kvm_arm.o ptp_kvm_common.o
 obj-$(CONFIG_PTP_1588_CLOCK)           += ptp.o
index a23a37a..4dfc52e 100644 (file)
 #define PTP_PPS_EVENT PPS_CAPTUREASSERT
 #define PTP_PPS_MODE (PTP_PPS_DEFAULTS | PPS_CANWAIT | PPS_TSFMT_TSPEC)
 
+struct class *ptp_class;
+
 /* private globals */
 
 static dev_t ptp_devt;
-static struct class *ptp_class;
 
 static DEFINE_IDA(ptp_clocks_map);
 
@@ -76,6 +77,11 @@ static int ptp_clock_settime(struct posix_clock *pc, const struct timespec64 *tp
 {
        struct ptp_clock *ptp = container_of(pc, struct ptp_clock, clock);
 
+       if (ptp_vclock_in_use(ptp)) {
+               pr_err("ptp: virtual clock in use\n");
+               return -EBUSY;
+       }
+
        return  ptp->info->settime64(ptp->info, tp);
 }
 
@@ -97,6 +103,11 @@ static int ptp_clock_adjtime(struct posix_clock *pc, struct __kernel_timex *tx)
        struct ptp_clock_info *ops;
        int err = -EOPNOTSUPP;
 
+       if (ptp_vclock_in_use(ptp)) {
+               pr_err("ptp: virtual clock in use\n");
+               return -EBUSY;
+       }
+
        ops = ptp->info;
 
        if (tx->modes & ADJ_SETOFFSET) {
@@ -161,6 +172,7 @@ static void ptp_clock_release(struct device *dev)
        ptp_cleanup_pin_groups(ptp);
        mutex_destroy(&ptp->tsevq_mux);
        mutex_destroy(&ptp->pincfg_mux);
+       mutex_destroy(&ptp->n_vclocks_mux);
        ida_simple_remove(&ptp_clocks_map, ptp->index);
        kfree(ptp);
 }
@@ -185,6 +197,7 @@ struct ptp_clock *ptp_clock_register(struct ptp_clock_info *info,
 {
        struct ptp_clock *ptp;
        int err = 0, index, major = MAJOR(ptp_devt);
+       size_t size;
 
        if (info->n_alarm > PTP_MAX_ALARMS)
                return ERR_PTR(-EINVAL);
@@ -208,6 +221,7 @@ struct ptp_clock *ptp_clock_register(struct ptp_clock_info *info,
        spin_lock_init(&ptp->tsevq.lock);
        mutex_init(&ptp->tsevq_mux);
        mutex_init(&ptp->pincfg_mux);
+       mutex_init(&ptp->n_vclocks_mux);
        init_waitqueue_head(&ptp->tsev_wq);
 
        if (ptp->info->do_aux_work) {
@@ -218,7 +232,22 @@ struct ptp_clock *ptp_clock_register(struct ptp_clock_info *info,
                        pr_err("failed to create ptp aux_worker %d\n", err);
                        goto kworker_err;
                }
-               ptp->pps_source->lookup_cookie = ptp;
+       }
+
+       /* PTP virtual clock is being registered under physical clock */
+       if (parent && parent->class && parent->class->name &&
+           strcmp(parent->class->name, "ptp") == 0)
+               ptp->is_virtual_clock = true;
+
+       if (!ptp->is_virtual_clock) {
+               ptp->max_vclocks = PTP_DEFAULT_MAX_VCLOCKS;
+
+               size = sizeof(int) * ptp->max_vclocks;
+               ptp->vclock_index = kzalloc(size, GFP_KERNEL);
+               if (!ptp->vclock_index) {
+                       err = -ENOMEM;
+                       goto no_mem_for_vclocks;
+               }
        }
 
        err = ptp_populate_pin_groups(ptp);
@@ -238,6 +267,7 @@ struct ptp_clock *ptp_clock_register(struct ptp_clock_info *info,
                        pr_err("failed to register pps source\n");
                        goto no_pps;
                }
+               ptp->pps_source->lookup_cookie = ptp;
        }
 
        /* Initialize a new device of our class in our clock structure. */
@@ -265,11 +295,14 @@ no_clock:
 no_pps:
        ptp_cleanup_pin_groups(ptp);
 no_pin_groups:
+       kfree(ptp->vclock_index);
+no_mem_for_vclocks:
        if (ptp->kworker)
                kthread_destroy_worker(ptp->kworker);
 kworker_err:
        mutex_destroy(&ptp->tsevq_mux);
        mutex_destroy(&ptp->pincfg_mux);
+       mutex_destroy(&ptp->n_vclocks_mux);
        ida_simple_remove(&ptp_clocks_map, index);
 no_slot:
        kfree(ptp);
@@ -280,9 +313,16 @@ EXPORT_SYMBOL(ptp_clock_register);
 
 int ptp_clock_unregister(struct ptp_clock *ptp)
 {
+       if (ptp_vclock_in_use(ptp)) {
+               pr_err("ptp: virtual clock in use\n");
+               return -EBUSY;
+       }
+
        ptp->defunct = 1;
        wake_up_interruptible(&ptp->tsev_wq);
 
+       kfree(ptp->vclock_index);
+
        if (ptp->kworker) {
                kthread_cancel_delayed_work_sync(&ptp->aux_work);
                kthread_destroy_worker(ptp->kworker);
index 6b97155..dba6be4 100644 (file)
@@ -18,6 +18,7 @@
 
 #define PTP_MAX_TIMESTAMPS 128
 #define PTP_BUF_TIMESTAMPS 30
+#define PTP_DEFAULT_MAX_VCLOCKS 20
 
 struct timestamp_event_queue {
        struct ptp_extts_event buf[PTP_MAX_TIMESTAMPS];
@@ -46,6 +47,24 @@ struct ptp_clock {
        const struct attribute_group *pin_attr_groups[2];
        struct kthread_worker *kworker;
        struct kthread_delayed_work aux_work;
+       unsigned int max_vclocks;
+       unsigned int n_vclocks;
+       int *vclock_index;
+       struct mutex n_vclocks_mux; /* protect concurrent n_vclocks access */
+       bool is_virtual_clock;
+};
+
+#define info_to_vclock(d) container_of((d), struct ptp_vclock, info)
+#define cc_to_vclock(d) container_of((d), struct ptp_vclock, cc)
+#define dw_to_vclock(d) container_of((d), struct ptp_vclock, refresh_work)
+
+struct ptp_vclock {
+       struct ptp_clock *pclock;
+       struct ptp_clock_info info;
+       struct ptp_clock *clock;
+       struct cyclecounter cc;
+       struct timecounter tc;
+       spinlock_t lock;        /* protects tc/cc */
 };
 
 /*
@@ -61,6 +80,24 @@ static inline int queue_cnt(struct timestamp_event_queue *q)
        return cnt < 0 ? PTP_MAX_TIMESTAMPS + cnt : cnt;
 }
 
+/* Check if ptp virtual clock is in use */
+static inline bool ptp_vclock_in_use(struct ptp_clock *ptp)
+{
+       bool in_use = false;
+
+       if (mutex_lock_interruptible(&ptp->n_vclocks_mux))
+               return true;
+
+       if (!ptp->is_virtual_clock && ptp->n_vclocks)
+               in_use = true;
+
+       mutex_unlock(&ptp->n_vclocks_mux);
+
+       return in_use;
+}
+
+extern struct class *ptp_class;
+
 /*
  * see ptp_chardev.c
  */
@@ -89,4 +126,6 @@ extern const struct attribute_group *ptp_groups[];
 int ptp_populate_pin_groups(struct ptp_clock *ptp);
 void ptp_cleanup_pin_groups(struct ptp_clock *ptp);
 
+struct ptp_vclock *ptp_vclock_register(struct ptp_clock *pclock);
+void ptp_vclock_unregister(struct ptp_vclock *vclock);
 #endif
index be076a9..b3d96b7 100644 (file)
@@ -3,6 +3,7 @@
  * PTP 1588 clock support - sysfs interface.
  *
  * Copyright (C) 2010 OMICRON electronics GmbH
+ * Copyright 2021 NXP
  */
 #include <linux/capability.h>
 #include <linux/slab.h>
@@ -148,6 +149,159 @@ out:
 }
 static DEVICE_ATTR(pps_enable, 0220, NULL, pps_enable_store);
 
+static int unregister_vclock(struct device *dev, void *data)
+{
+       struct ptp_clock *ptp = dev_get_drvdata(dev);
+       struct ptp_clock_info *info = ptp->info;
+       struct ptp_vclock *vclock;
+       u8 *num = data;
+
+       vclock = info_to_vclock(info);
+       dev_info(dev->parent, "delete virtual clock ptp%d\n",
+                vclock->clock->index);
+
+       ptp_vclock_unregister(vclock);
+       (*num)--;
+
+       /* For break. Not error. */
+       if (*num == 0)
+               return -EINVAL;
+
+       return 0;
+}
+
+static ssize_t n_vclocks_show(struct device *dev,
+                             struct device_attribute *attr, char *page)
+{
+       struct ptp_clock *ptp = dev_get_drvdata(dev);
+       ssize_t size;
+
+       if (mutex_lock_interruptible(&ptp->n_vclocks_mux))
+               return -ERESTARTSYS;
+
+       size = snprintf(page, PAGE_SIZE - 1, "%u\n", ptp->n_vclocks);
+
+       mutex_unlock(&ptp->n_vclocks_mux);
+
+       return size;
+}
+
+static ssize_t n_vclocks_store(struct device *dev,
+                              struct device_attribute *attr,
+                              const char *buf, size_t count)
+{
+       struct ptp_clock *ptp = dev_get_drvdata(dev);
+       struct ptp_vclock *vclock;
+       int err = -EINVAL;
+       u32 num, i;
+
+       if (kstrtou32(buf, 0, &num))
+               return err;
+
+       if (mutex_lock_interruptible(&ptp->n_vclocks_mux))
+               return -ERESTARTSYS;
+
+       if (num > ptp->max_vclocks) {
+               dev_err(dev, "max value is %d\n", ptp->max_vclocks);
+               goto out;
+       }
+
+       /* Need to create more vclocks */
+       if (num > ptp->n_vclocks) {
+               for (i = 0; i < num - ptp->n_vclocks; i++) {
+                       vclock = ptp_vclock_register(ptp);
+                       if (!vclock)
+                               goto out;
+
+                       *(ptp->vclock_index + ptp->n_vclocks + i) =
+                               vclock->clock->index;
+
+                       dev_info(dev, "new virtual clock ptp%d\n",
+                                vclock->clock->index);
+               }
+       }
+
+       /* Need to delete vclocks */
+       if (num < ptp->n_vclocks) {
+               i = ptp->n_vclocks - num;
+               device_for_each_child_reverse(dev, &i,
+                                             unregister_vclock);
+
+               for (i = 1; i <= ptp->n_vclocks - num; i++)
+                       *(ptp->vclock_index + ptp->n_vclocks - i) = -1;
+       }
+
+       if (num == 0)
+               dev_info(dev, "only physical clock in use now\n");
+       else
+               dev_info(dev, "guarantee physical clock free running\n");
+
+       ptp->n_vclocks = num;
+       mutex_unlock(&ptp->n_vclocks_mux);
+
+       return count;
+out:
+       mutex_unlock(&ptp->n_vclocks_mux);
+       return err;
+}
+static DEVICE_ATTR_RW(n_vclocks);
+
+static ssize_t max_vclocks_show(struct device *dev,
+                               struct device_attribute *attr, char *page)
+{
+       struct ptp_clock *ptp = dev_get_drvdata(dev);
+       ssize_t size;
+
+       size = snprintf(page, PAGE_SIZE - 1, "%u\n", ptp->max_vclocks);
+
+       return size;
+}
+
+static ssize_t max_vclocks_store(struct device *dev,
+                                struct device_attribute *attr,
+                                const char *buf, size_t count)
+{
+       struct ptp_clock *ptp = dev_get_drvdata(dev);
+       unsigned int *vclock_index;
+       int err = -EINVAL;
+       size_t size;
+       u32 max;
+
+       if (kstrtou32(buf, 0, &max) || max == 0)
+               return -EINVAL;
+
+       if (max == ptp->max_vclocks)
+               return count;
+
+       if (mutex_lock_interruptible(&ptp->n_vclocks_mux))
+               return -ERESTARTSYS;
+
+       if (max < ptp->n_vclocks)
+               goto out;
+
+       size = sizeof(int) * max;
+       vclock_index = kzalloc(size, GFP_KERNEL);
+       if (!vclock_index) {
+               err = -ENOMEM;
+               goto out;
+       }
+
+       size = sizeof(int) * ptp->n_vclocks;
+       memcpy(vclock_index, ptp->vclock_index, size);
+
+       kfree(ptp->vclock_index);
+       ptp->vclock_index = vclock_index;
+       ptp->max_vclocks = max;
+
+       mutex_unlock(&ptp->n_vclocks_mux);
+
+       return count;
+out:
+       mutex_unlock(&ptp->n_vclocks_mux);
+       return err;
+}
+static DEVICE_ATTR_RW(max_vclocks);
+
 static struct attribute *ptp_attrs[] = {
        &dev_attr_clock_name.attr,
 
@@ -162,6 +316,8 @@ static struct attribute *ptp_attrs[] = {
        &dev_attr_fifo.attr,
        &dev_attr_period.attr,
        &dev_attr_pps_enable.attr,
+       &dev_attr_n_vclocks.attr,
+       &dev_attr_max_vclocks.attr,
        NULL
 };
 
@@ -183,6 +339,10 @@ static umode_t ptp_is_attribute_visible(struct kobject *kobj,
        } else if (attr == &dev_attr_pps_enable.attr) {
                if (!info->pps)
                        mode = 0;
+       } else if (attr == &dev_attr_n_vclocks.attr ||
+                  attr == &dev_attr_max_vclocks.attr) {
+               if (ptp->is_virtual_clock)
+                       mode = 0;
        }
 
        return mode;
diff --git a/drivers/ptp/ptp_vclock.c b/drivers/ptp/ptp_vclock.c
new file mode 100644 (file)
index 0000000..e0f87c5
--- /dev/null
@@ -0,0 +1,219 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * PTP virtual clock driver
+ *
+ * Copyright 2021 NXP
+ */
+#include <linux/slab.h>
+#include "ptp_private.h"
+
+#define PTP_VCLOCK_CC_SHIFT            31
+#define PTP_VCLOCK_CC_MULT             (1 << PTP_VCLOCK_CC_SHIFT)
+#define PTP_VCLOCK_FADJ_SHIFT          9
+#define PTP_VCLOCK_FADJ_DENOMINATOR    15625ULL
+#define PTP_VCLOCK_REFRESH_INTERVAL    (HZ * 2)
+
+static int ptp_vclock_adjfine(struct ptp_clock_info *ptp, long scaled_ppm)
+{
+       struct ptp_vclock *vclock = info_to_vclock(ptp);
+       unsigned long flags;
+       s64 adj;
+
+       adj = (s64)scaled_ppm << PTP_VCLOCK_FADJ_SHIFT;
+       adj = div_s64(adj, PTP_VCLOCK_FADJ_DENOMINATOR);
+
+       spin_lock_irqsave(&vclock->lock, flags);
+       timecounter_read(&vclock->tc);
+       vclock->cc.mult = PTP_VCLOCK_CC_MULT + adj;
+       spin_unlock_irqrestore(&vclock->lock, flags);
+
+       return 0;
+}
+
+static int ptp_vclock_adjtime(struct ptp_clock_info *ptp, s64 delta)
+{
+       struct ptp_vclock *vclock = info_to_vclock(ptp);
+       unsigned long flags;
+
+       spin_lock_irqsave(&vclock->lock, flags);
+       timecounter_adjtime(&vclock->tc, delta);
+       spin_unlock_irqrestore(&vclock->lock, flags);
+
+       return 0;
+}
+
+static int ptp_vclock_gettime(struct ptp_clock_info *ptp,
+                             struct timespec64 *ts)
+{
+       struct ptp_vclock *vclock = info_to_vclock(ptp);
+       unsigned long flags;
+       u64 ns;
+
+       spin_lock_irqsave(&vclock->lock, flags);
+       ns = timecounter_read(&vclock->tc);
+       spin_unlock_irqrestore(&vclock->lock, flags);
+       *ts = ns_to_timespec64(ns);
+
+       return 0;
+}
+
+static int ptp_vclock_settime(struct ptp_clock_info *ptp,
+                             const struct timespec64 *ts)
+{
+       struct ptp_vclock *vclock = info_to_vclock(ptp);
+       u64 ns = timespec64_to_ns(ts);
+       unsigned long flags;
+
+       spin_lock_irqsave(&vclock->lock, flags);
+       timecounter_init(&vclock->tc, &vclock->cc, ns);
+       spin_unlock_irqrestore(&vclock->lock, flags);
+
+       return 0;
+}
+
+static long ptp_vclock_refresh(struct ptp_clock_info *ptp)
+{
+       struct ptp_vclock *vclock = info_to_vclock(ptp);
+       struct timespec64 ts;
+
+       ptp_vclock_gettime(&vclock->info, &ts);
+
+       return PTP_VCLOCK_REFRESH_INTERVAL;
+}
+
+static const struct ptp_clock_info ptp_vclock_info = {
+       .owner          = THIS_MODULE,
+       .name           = "ptp virtual clock",
+       /* The maximum ppb value that long scaled_ppm can support */
+       .max_adj        = 32767999,
+       .adjfine        = ptp_vclock_adjfine,
+       .adjtime        = ptp_vclock_adjtime,
+       .gettime64      = ptp_vclock_gettime,
+       .settime64      = ptp_vclock_settime,
+       .do_aux_work    = ptp_vclock_refresh,
+};
+
+static u64 ptp_vclock_read(const struct cyclecounter *cc)
+{
+       struct ptp_vclock *vclock = cc_to_vclock(cc);
+       struct ptp_clock *ptp = vclock->pclock;
+       struct timespec64 ts = {};
+
+       if (ptp->info->gettimex64)
+               ptp->info->gettimex64(ptp->info, &ts, NULL);
+       else
+               ptp->info->gettime64(ptp->info, &ts);
+
+       return timespec64_to_ns(&ts);
+}
+
+static const struct cyclecounter ptp_vclock_cc = {
+       .read   = ptp_vclock_read,
+       .mask   = CYCLECOUNTER_MASK(32),
+       .mult   = PTP_VCLOCK_CC_MULT,
+       .shift  = PTP_VCLOCK_CC_SHIFT,
+};
+
+struct ptp_vclock *ptp_vclock_register(struct ptp_clock *pclock)
+{
+       struct ptp_vclock *vclock;
+
+       vclock = kzalloc(sizeof(*vclock), GFP_KERNEL);
+       if (!vclock)
+               return NULL;
+
+       vclock->pclock = pclock;
+       vclock->info = ptp_vclock_info;
+       vclock->cc = ptp_vclock_cc;
+
+       snprintf(vclock->info.name, PTP_CLOCK_NAME_LEN, "ptp%d_virt",
+                pclock->index);
+
+       spin_lock_init(&vclock->lock);
+
+       vclock->clock = ptp_clock_register(&vclock->info, &pclock->dev);
+       if (IS_ERR_OR_NULL(vclock->clock)) {
+               kfree(vclock);
+               return NULL;
+       }
+
+       timecounter_init(&vclock->tc, &vclock->cc, 0);
+       ptp_schedule_worker(vclock->clock, PTP_VCLOCK_REFRESH_INTERVAL);
+
+       return vclock;
+}
+
+void ptp_vclock_unregister(struct ptp_vclock *vclock)
+{
+       ptp_clock_unregister(vclock->clock);
+       kfree(vclock);
+}
+
+int ptp_get_vclocks_index(int pclock_index, int **vclock_index)
+{
+       char name[PTP_CLOCK_NAME_LEN] = "";
+       struct ptp_clock *ptp;
+       struct device *dev;
+       int num = 0;
+
+       if (pclock_index < 0)
+               return num;
+
+       snprintf(name, PTP_CLOCK_NAME_LEN, "ptp%d", pclock_index);
+       dev = class_find_device_by_name(ptp_class, name);
+       if (!dev)
+               return num;
+
+       ptp = dev_get_drvdata(dev);
+
+       if (mutex_lock_interruptible(&ptp->n_vclocks_mux)) {
+               put_device(dev);
+               return num;
+       }
+
+       *vclock_index = kzalloc(sizeof(int) * ptp->n_vclocks, GFP_KERNEL);
+       if (!(*vclock_index))
+               goto out;
+
+       memcpy(*vclock_index, ptp->vclock_index, sizeof(int) * ptp->n_vclocks);
+       num = ptp->n_vclocks;
+out:
+       mutex_unlock(&ptp->n_vclocks_mux);
+       put_device(dev);
+       return num;
+}
+EXPORT_SYMBOL(ptp_get_vclocks_index);
+
+void ptp_convert_timestamp(struct skb_shared_hwtstamps *hwtstamps,
+                          int vclock_index)
+{
+       char name[PTP_CLOCK_NAME_LEN] = "";
+       struct ptp_vclock *vclock;
+       struct ptp_clock *ptp;
+       unsigned long flags;
+       struct device *dev;
+       u64 ns;
+
+       snprintf(name, PTP_CLOCK_NAME_LEN, "ptp%d", vclock_index);
+       dev = class_find_device_by_name(ptp_class, name);
+       if (!dev)
+               return;
+
+       ptp = dev_get_drvdata(dev);
+       if (!ptp->is_virtual_clock) {
+               put_device(dev);
+               return;
+       }
+
+       vclock = info_to_vclock(ptp->info);
+
+       ns = ktime_to_ns(hwtstamps->hwtstamp);
+
+       spin_lock_irqsave(&vclock->lock, flags);
+       ns = timecounter_cyc2time(&vclock->tc, ns);
+       spin_unlock_irqrestore(&vclock->lock, flags);
+
+       put_device(dev);
+       hwtstamps->hwtstamp = ns_to_ktime(ns);
+}
+EXPORT_SYMBOL(ptp_convert_timestamp);
index 5537b5f..e157273 100644 (file)
@@ -190,12 +190,9 @@ static int berlin_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
                return 0;
        }
 
-       if (state->period != pwm->state.period ||
-           state->duty_cycle != pwm->state.duty_cycle) {
-               err = berlin_pwm_config(chip, pwm, state->duty_cycle, state->period);
-               if (err)
-                       return err;
-       }
+       err = berlin_pwm_config(chip, pwm, state->duty_cycle, state->period);
+       if (err)
+               return err;
 
        if (!enabled)
                return berlin_pwm_enable(chip, pwm);
index 8a3d781..fc3cb7d 100644 (file)
@@ -64,6 +64,11 @@ static int ep93xx_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
        int ret;
        struct ep93xx_pwm *ep93xx_pwm = to_ep93xx_pwm(chip);
        bool enabled = state->enabled;
+       void __iomem *base = ep93xx_pwm->base;
+       unsigned long long c;
+       unsigned long period_cycles;
+       unsigned long duty_cycles;
+       unsigned long term;
 
        if (state->polarity != pwm->state.polarity) {
                if (enabled) {
@@ -97,57 +102,47 @@ static int ep93xx_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
                return 0;
        }
 
-       if (state->period != pwm->state.period ||
-           state->duty_cycle != pwm->state.duty_cycle) {
-               struct ep93xx_pwm *ep93xx_pwm = to_ep93xx_pwm(chip);
-               void __iomem *base = ep93xx_pwm->base;
-               unsigned long long c;
-               unsigned long period_cycles;
-               unsigned long duty_cycles;
-               unsigned long term;
+       /*
+        * The clock needs to be enabled to access the PWM registers.
+        * Configuration can be changed at any time.
+        */
+       if (!pwm_is_enabled(pwm)) {
+               ret = clk_prepare_enable(ep93xx_pwm->clk);
+               if (ret)
+                       return ret;
+       }
 
-               /*
-                * The clock needs to be enabled to access the PWM registers.
-                * Configuration can be changed at any time.
-                */
-               if (!pwm_is_enabled(pwm)) {
-                       ret = clk_prepare_enable(ep93xx_pwm->clk);
-                       if (ret)
-                               return ret;
-               }
+       c = clk_get_rate(ep93xx_pwm->clk);
+       c *= state->period;
+       do_div(c, 1000000000);
+       period_cycles = c;
+
+       c = period_cycles;
+       c *= state->duty_cycle;
+       do_div(c, state->period);
+       duty_cycles = c;
 
-               c = clk_get_rate(ep93xx_pwm->clk);
-               c *= state->period;
-               do_div(c, 1000000000);
-               period_cycles = c;
-
-               c = period_cycles;
-               c *= state->duty_cycle;
-               do_div(c, state->period);
-               duty_cycles = c;
-
-               if (period_cycles < 0x10000 && duty_cycles < 0x10000) {
-                       term = readw(base + EP93XX_PWMx_TERM_COUNT);
-
-                       /* Order is important if PWM is running */
-                       if (period_cycles > term) {
-                               writew(period_cycles, base + EP93XX_PWMx_TERM_COUNT);
-                               writew(duty_cycles, base + EP93XX_PWMx_DUTY_CYCLE);
-                       } else {
-                               writew(duty_cycles, base + EP93XX_PWMx_DUTY_CYCLE);
-                               writew(period_cycles, base + EP93XX_PWMx_TERM_COUNT);
-                       }
-                       ret = 0;
+       if (period_cycles < 0x10000 && duty_cycles < 0x10000) {
+               term = readw(base + EP93XX_PWMx_TERM_COUNT);
+
+               /* Order is important if PWM is running */
+               if (period_cycles > term) {
+                       writew(period_cycles, base + EP93XX_PWMx_TERM_COUNT);
+                       writew(duty_cycles, base + EP93XX_PWMx_DUTY_CYCLE);
                } else {
-                       ret = -EINVAL;
+                       writew(duty_cycles, base + EP93XX_PWMx_DUTY_CYCLE);
+                       writew(period_cycles, base + EP93XX_PWMx_TERM_COUNT);
                }
+               ret = 0;
+       } else {
+               ret = -EINVAL;
+       }
 
-               if (!pwm_is_enabled(pwm))
-                       clk_disable_unprepare(ep93xx_pwm->clk);
+       if (!pwm_is_enabled(pwm))
+               clk_disable_unprepare(ep93xx_pwm->clk);
 
-               if (ret)
-                       return ret;
-       }
+       if (ret)
+               return ret;
 
        if (!enabled) {
                ret = clk_prepare_enable(ep93xx_pwm->clk);
index 48c31da..54c7990 100644 (file)
@@ -177,12 +177,9 @@ static int spear_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
                return 0;
        }
 
-       if (state->period != pwm->state.period ||
-           state->duty_cycle != pwm->state.duty_cycle) {
-               err = spear_pwm_config(chip, pwm, state->duty_cycle, state->period);
-               if (err)
-                       return err;
-       }
+       err = spear_pwm_config(chip, pwm, state->duty_cycle, state->period);
+       if (err)
+               return err;
 
        if (!pwm->state.enabled)
                return spear_pwm_enable(chip, pwm);
index f2a85e8..7004f55 100644 (file)
@@ -183,13 +183,10 @@ static int sprd_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
                        }
                }
 
-               if (state->period != cstate->period ||
-                   state->duty_cycle != cstate->duty_cycle) {
-                       ret = sprd_pwm_config(spc, pwm, state->duty_cycle,
-                                             state->period);
-                       if (ret)
-                               return ret;
-               }
+               ret = sprd_pwm_config(spc, pwm, state->duty_cycle,
+                                     state->period);
+               if (ret)
+                       return ret;
 
                sprd_pwm_write(spc, pwm->hwpwm, SPRD_PWM_ENABLE, 1);
        } else if (cstate->enabled) {
index dec3f1f..35eb19a 100644 (file)
@@ -189,16 +189,13 @@ static int ecap_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
                return 0;
        }
 
-       if (state->period != pwm->state.period ||
-           state->duty_cycle != pwm->state.duty_cycle) {
-               if (state->period > NSEC_PER_SEC)
-                       return -ERANGE;
+       if (state->period > NSEC_PER_SEC)
+               return -ERANGE;
 
-               err = ecap_pwm_config(chip, pwm, state->duty_cycle,
-                                     state->period, enabled);
-               if (err)
-                       return err;
-       }
+       err = ecap_pwm_config(chip, pwm, state->duty_cycle,
+                             state->period, enabled);
+       if (err)
+               return err;
 
        if (!enabled)
                return ecap_pwm_enable(chip, pwm);
index 8abb429..cc8237a 100644 (file)
@@ -371,8 +371,6 @@ __tapechar_ioctl(struct tape_device *device,
                        case MTSEEK:
                                if (device->required_tapemarks)
                                        tape_std_terminate_write(device);
-                       default:
-                               ;
                }
                rc = tape_mtop(device, op.mt_op, op.mt_count);
 
index b341075..377e368 100644 (file)
@@ -1454,6 +1454,7 @@ again:
                                get_ccwdev_lock(ch->cdev), saveflags);
                if (rc != 0)
                        ctcm_ccw_check_rc(ch, rc, "normal RX");
+               break;
        default:
                break;
        }
index d308ff7..f0d6f20 100644 (file)
@@ -434,6 +434,7 @@ static int qeth_l3_correct_routing_type(struct qeth_card *card,
                        if (qeth_is_ipafunc_supported(card, prot,
                                                      IPA_OSA_MC_ROUTER))
                                return 0;
+                       goto out_inval;
                default:
                        goto out_inval;
                }
index 544efd4..b8cd75a 100644 (file)
@@ -487,6 +487,7 @@ static ssize_t zfcp_sysfs_port_fc_security_show(struct device *dev,
        if (0 == (status & ZFCP_STATUS_COMMON_OPEN) ||
            0 == (status & ZFCP_STATUS_COMMON_UNBLOCKED) ||
            0 == (status & ZFCP_STATUS_PORT_PHYS_OPEN) ||
+           0 != (status & ZFCP_STATUS_PORT_LINK_TEST) ||
            0 != (status & ZFCP_STATUS_COMMON_ERP_FAILED) ||
            0 != (status & ZFCP_STATUS_COMMON_ACCESS_BOXED))
                i = sprintf(buf, "unknown\n");
index 30ed3d2..6baa9b3 100644 (file)
@@ -2010,7 +2010,7 @@ static void fas216_rq_sns_done(FAS216_Info *info, struct scsi_cmnd *SCpnt,
                   "request sense complete, result=0x%04x%02x%02x",
                   result, SCpnt->SCp.Message, SCpnt->SCp.Status);
 
-       if (result != DID_OK || SCpnt->SCp.Status != GOOD)
+       if (result != DID_OK || SCpnt->SCp.Status != SAM_STAT_GOOD)
                /*
                 * Something went wrong.  Make sure that we don't
                 * have valid data in the sense buffer that could
index 929a3b0..3f6f14f 100644 (file)
@@ -488,6 +488,7 @@ struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize)
                shost_printk(KERN_WARNING, shost,
                        "error handler thread failed to spawn, error = %ld\n",
                        PTR_ERR(shost->ehandler));
+               shost->ehandler = NULL;
                goto fail;
        }
 
index 9f5068f..dd20541 100644 (file)
@@ -461,7 +461,7 @@ static void sas_discover_domain(struct work_struct *work)
                break;
 #else
                pr_notice("ATA device seen but CONFIG_SCSI_SAS_ATA=N so cannot attach\n");
-               /* Fall through */
+               fallthrough;
 #endif
                /* Fall through - only for the #else condition above. */
        default:
index 9eceafc..2dba2b0 100644 (file)
@@ -2607,14 +2607,13 @@ static int mpi3mr_issue_iocinit(struct mpi3mr_ioc *mrioc)
                goto out;
        }
        drv_info->information_length = cpu_to_le32(data_len);
-       strncpy(drv_info->driver_signature, "Broadcom", sizeof(drv_info->driver_signature));
-       strncpy(drv_info->os_name, utsname()->sysname, sizeof(drv_info->os_name));
-       drv_info->os_name[sizeof(drv_info->os_name) - 1] = 0;
-       strncpy(drv_info->os_version, utsname()->release, sizeof(drv_info->os_version));
-       drv_info->os_version[sizeof(drv_info->os_version) - 1] = 0;
-       strncpy(drv_info->driver_name, MPI3MR_DRIVER_NAME, sizeof(drv_info->driver_name));
-       strncpy(drv_info->driver_version, MPI3MR_DRIVER_VERSION, sizeof(drv_info->driver_version));
-       strncpy(drv_info->driver_release_date, MPI3MR_DRIVER_RELDATE, sizeof(drv_info->driver_release_date));
+       strscpy(drv_info->driver_signature, "Broadcom", sizeof(drv_info->driver_signature));
+       strscpy(drv_info->os_name, utsname()->sysname, sizeof(drv_info->os_name));
+       strscpy(drv_info->os_version, utsname()->release, sizeof(drv_info->os_version));
+       strscpy(drv_info->driver_name, MPI3MR_DRIVER_NAME, sizeof(drv_info->driver_name));
+       strscpy(drv_info->driver_version, MPI3MR_DRIVER_VERSION, sizeof(drv_info->driver_version));
+       strscpy(drv_info->driver_release_date, MPI3MR_DRIVER_RELDATE,
+           sizeof(drv_info->driver_release_date));
        drv_info->driver_capabilities = 0;
        memcpy((u8 *)&mrioc->driver_info, (u8 *)drv_info,
            sizeof(mrioc->driver_info));
index 0b8802b..ec05c42 100644 (file)
@@ -77,7 +77,7 @@ DEVICE_ATTR(interface_rev, S_IRUGO, pm8001_ctl_mpi_interface_rev_show, NULL);
  * @attr: device attribute (unused)
  * @buf: the buffer returned
  *
- * A sysfs 'read only' shost attribute.
+ * A sysfs 'read-only' shost attribute.
  */
 static ssize_t controller_fatal_error_show(struct device *cdev,
                struct device_attribute *attr, char *buf)
@@ -149,7 +149,7 @@ static ssize_t pm8001_ctl_ila_version_show(struct device *cdev,
 static DEVICE_ATTR(ila_version, 0444, pm8001_ctl_ila_version_show, NULL);
 
 /**
- * pm8001_ctl_inactive_fw_version_show - Inacative firmware version number
+ * pm8001_ctl_inactive_fw_version_show - Inactive firmware version number
  * @cdev: pointer to embedded class device
  * @attr: device attribute (unused)
  * @buf: the buffer returned
@@ -396,6 +396,7 @@ static DEVICE_ATTR(aap_log, S_IRUGO, pm8001_ctl_aap_log_show, NULL);
  * @cdev:pointer to embedded class device
  * @attr: device attribute (unused)
  * @buf: the buffer returned
+ *
  * A sysfs 'read-only' shost attribute.
  */
 static ssize_t pm8001_ctl_ib_queue_log_show(struct device *cdev,
@@ -430,6 +431,7 @@ static DEVICE_ATTR(ib_log, S_IRUGO, pm8001_ctl_ib_queue_log_show, NULL);
  * @cdev:pointer to embedded class device
  * @attr: device attribute (unused)
  * @buf: the buffer returned
+ *
  * A sysfs 'read-only' shost attribute.
  */
 
@@ -464,6 +466,7 @@ static DEVICE_ATTR(ob_log, S_IRUGO, pm8001_ctl_ob_queue_log_show, NULL);
  * @cdev:pointer to embedded class device
  * @attr: device attribute (unused)
  * @buf:the buffer returned
+ *
  * A sysfs 'read-only' shost attribute.
  */
 static ssize_t pm8001_ctl_bios_version_show(struct device *cdev,
@@ -555,13 +558,13 @@ static ssize_t pm8001_ctl_iop_log_show(struct device *cdev,
 static DEVICE_ATTR(iop_log, S_IRUGO, pm8001_ctl_iop_log_show, NULL);
 
 /**
- ** pm8001_ctl_fatal_log_show - fatal error logging
- ** @cdev:pointer to embedded class device
- ** @attr: device attribute
- ** @buf: the buffer returned
- **
- ** A sysfs 'read-only' shost attribute.
- **/
+ * pm8001_ctl_fatal_log_show - fatal error logging
+ * @cdev:pointer to embedded class device
+ * @attr: device attribute
+ * @buf: the buffer returned
+ *
+ * A sysfs 'read-only' shost attribute.
+ */
 
 static ssize_t pm8001_ctl_fatal_log_show(struct device *cdev,
        struct device_attribute *attr, char *buf)
@@ -575,13 +578,13 @@ static ssize_t pm8001_ctl_fatal_log_show(struct device *cdev,
 static DEVICE_ATTR(fatal_log, S_IRUGO, pm8001_ctl_fatal_log_show, NULL);
 
 /**
- ** non_fatal_log_show - non fatal error logging
- ** @cdev:pointer to embedded class device
- ** @attr: device attribute
- ** @buf: the buffer returned
- **
- ** A sysfs 'read-only' shost attribute.
- **/
+ * non_fatal_log_show - non fatal error logging
+ * @cdev:pointer to embedded class device
+ * @attr: device attribute
+ * @buf: the buffer returned
+ *
+ * A sysfs 'read-only' shost attribute.
+ */
 static ssize_t non_fatal_log_show(struct device *cdev,
        struct device_attribute *attr, char *buf)
 {
@@ -620,12 +623,13 @@ static ssize_t non_fatal_count_store(struct device *cdev,
 static DEVICE_ATTR_RW(non_fatal_count);
 
 /**
- ** pm8001_ctl_gsm_log_show - gsm dump collection
- ** @cdev:pointer to embedded class device
- ** @attr: device attribute (unused)
- ** @buf: the buffer returned
- ** A sysfs 'read-only' shost attribute.
- **/
+ * pm8001_ctl_gsm_log_show - gsm dump collection
+ * @cdev:pointer to embedded class device
+ * @attr: device attribute (unused)
+ * @buf: the buffer returned
+ *
+ * A sysfs 'read-only' shost attribute.
+ */
 static ssize_t pm8001_ctl_gsm_log_show(struct device *cdev,
        struct device_attribute *attr, char *buf)
 {
index 33f8217..17c0f26 100644 (file)
@@ -384,7 +384,7 @@ static void update_outbnd_queue_table(struct pm8001_hba_info *pm8001_ha,
 
 /**
  * pm8001_bar4_shift - function is called to shift BAR base address
- * @pm8001_ha : our hba card infomation
+ * @pm8001_ha : our hba card information
  * @shiftValue : shifting value in memory bar.
  */
 int pm8001_bar4_shift(struct pm8001_hba_info *pm8001_ha, u32 shiftValue)
@@ -1151,7 +1151,7 @@ static void pm8001_hw_chip_rst(struct pm8001_hba_info *pm8001_ha)
 }
 
 /**
- * pm8001_chip_iounmap - which maped when initialized.
+ * pm8001_chip_iounmap - which mapped when initialized.
  * @pm8001_ha: our hba card information
  */
 void pm8001_chip_iounmap(struct pm8001_hba_info *pm8001_ha)
@@ -1187,10 +1187,10 @@ pm8001_chip_intx_interrupt_enable(struct pm8001_hba_info *pm8001_ha)
        pm8001_cw32(pm8001_ha, 0, MSGU_ODCR, ODCR_CLEAR_ALL);
 }
 
- /**
 * pm8001_chip_intx_interrupt_disable- disable PM8001 chip interrupt
 * @pm8001_ha: our hba card information
 */
+/**
* pm8001_chip_intx_interrupt_disable - disable PM8001 chip interrupt
+ * @pm8001_ha: our hba card information
+ */
 static void
 pm8001_chip_intx_interrupt_disable(struct pm8001_hba_info *pm8001_ha)
 {
@@ -1876,8 +1876,8 @@ static void pm8001_send_read_log(struct pm8001_hba_info *pm8001_ha,
  * @piomb: the message contents of this outbound message.
  *
  * When FW has completed a ssp request for example a IO request, after it has
- * filled the SG data with the data, it will trigger this event represent
- * that he has finished the job,please check the coresponding buffer.
+ * filled the SG data with the data, it will trigger this event representing
+ * that he has finished the job; please check the corresponding buffer.
  * So we will tell the caller who maybe waiting the result to tell upper layer
  * that the task has been finished.
  */
@@ -3522,7 +3522,7 @@ hw_event_phy_down(struct pm8001_hba_info *pm8001_ha, void *piomb)
  *
  * when sas layer find a device it will notify LLDD, then the driver register
  * the domain device to FW, this event is the return device ID which the FW
- * has assigned, from now,inter-communication with FW is no longer using the
+ * has assigned, from now, inter-communication with FW is no longer using the
  * SAS address, use device ID which FW assigned.
  */
 int pm8001_mpi_reg_resp(struct pm8001_hba_info *pm8001_ha, void *piomb)
index 313248c..47db7e0 100644 (file)
@@ -233,7 +233,7 @@ static irqreturn_t pm8001_interrupt_handler_msix(int irq, void *opaque)
 /**
  * pm8001_interrupt_handler_intx - main INTx interrupt handler.
  * @irq: interrupt number
- * @dev_id: sas_ha structure. The HBA is retrieved from sas_has structure.
+ * @dev_id: sas_ha structure. The HBA is retrieved from sas_ha structure.
  */
 
 static irqreturn_t pm8001_interrupt_handler_intx(int irq, void *dev_id)
@@ -439,9 +439,9 @@ err_out:
 }
 
 /**
- * pm8001_ioremap - remap the pci high physical address to kernal virtual
+ * pm8001_ioremap - remap the pci high physical address to kernel virtual
  * address so that we can access them.
- * @pm8001_ha:our hba structure.
+ * @pm8001_ha: our hba structure.
  */
 static int pm8001_ioremap(struct pm8001_hba_info *pm8001_ha)
 {
@@ -652,7 +652,7 @@ static void  pm8001_post_sas_ha_init(struct Scsi_Host *shost,
  * pm8001_init_sas_add - initialize sas address
  * @pm8001_ha: our ha struct.
  *
- * Currently we just set the fixed SAS address to our HBA,for manufacture,
+ * Currently we just set the fixed SAS address to our HBA, for manufacture,
  * it should read from the EEPROM
  */
 static void pm8001_init_sas_add(struct pm8001_hba_info *pm8001_ha)
@@ -790,7 +790,7 @@ struct pm8001_mpi3_phy_pg_trx_config {
 };
 
 /**
- * pm8001_get_internal_phy_settings : Retrieves the internal PHY settings
+ * pm8001_get_internal_phy_settings - Retrieves the internal PHY settings
  * @pm8001_ha : our adapter
  * @phycfg : PHY config page to populate
  */
@@ -810,7 +810,7 @@ void pm8001_get_internal_phy_settings(struct pm8001_hba_info *pm8001_ha,
 }
 
 /**
- * pm8001_get_external_phy_settings : Retrieves the external PHY settings
+ * pm8001_get_external_phy_settings - Retrieves the external PHY settings
  * @pm8001_ha : our adapter
  * @phycfg : PHY config page to populate
  */
@@ -830,7 +830,7 @@ void pm8001_get_external_phy_settings(struct pm8001_hba_info *pm8001_ha,
 }
 
 /**
- * pm8001_get_phy_mask : Retrieves the mask that denotes if a PHY is int/ext
+ * pm8001_get_phy_mask - Retrieves the mask that denotes if a PHY is int/ext
  * @pm8001_ha : our adapter
  * @phymask : The PHY mask
  */
@@ -868,7 +868,7 @@ void pm8001_get_phy_mask(struct pm8001_hba_info *pm8001_ha, int *phymask)
 }
 
 /**
- * pm8001_set_phy_settings_ven_117c_12G() : Configure ATTO 12Gb PHY settings
+ * pm8001_set_phy_settings_ven_117c_12G() - Configure ATTO 12Gb PHY settings
  * @pm8001_ha : our adapter
  */
 static
@@ -903,7 +903,7 @@ int pm8001_set_phy_settings_ven_117c_12G(struct pm8001_hba_info *pm8001_ha)
 }
 
 /**
- * pm8001_configure_phy_settings : Configures PHY settings based on vendor ID.
+ * pm8001_configure_phy_settings - Configures PHY settings based on vendor ID.
  * @pm8001_ha : our hba.
  */
 static int pm8001_configure_phy_settings(struct pm8001_hba_info *pm8001_ha)
@@ -1053,8 +1053,8 @@ intx:
  * @ent: pci device id
  *
  * This function is the main initialization function, when register a new
- * pci driver it is invoked, all struct an hardware initilization should be done
- * here, also, register interrupt
+ * pci driver it is invoked, all struct and hardware initialization should be
+ * done here, also, register interrupt.
  */
 static int pm8001_pci_probe(struct pci_dev *pdev,
                            const struct pci_device_id *ent)
@@ -1172,10 +1172,11 @@ err_out_enable:
        return rc;
 }
 
-/*
+/**
  * pm8001_init_ccb_tag - allocate memory to CCB and tag.
  * @pm8001_ha: our hba card information.
  * @shost: scsi host which has been allocated outside.
+ * @pdev: pci device.
  */
 static int
 pm8001_init_ccb_tag(struct pm8001_hba_info *pm8001_ha, struct Scsi_Host *shost,
@@ -1270,7 +1271,7 @@ static void pm8001_pci_remove(struct pci_dev *pdev)
  * pm8001_pci_suspend - power management suspend main entry point
  * @dev: Device struct
  *
- * Returns 0 success, anything else error.
+ * Return: 0 on success, anything else on error.
  */
 static int __maybe_unused pm8001_pci_suspend(struct device *dev)
 {
@@ -1315,7 +1316,7 @@ static int __maybe_unused pm8001_pci_suspend(struct device *dev)
  * pm8001_pci_resume - power management resume main entry point
  * @dev: Device struct
  *
- * Returns 0 success, anything else error.
+ * Return: 0 on success, anything else on error.
  */
 static int __maybe_unused pm8001_pci_resume(struct device *dev)
 {
index 6f33d82..48548a9 100644 (file)
@@ -98,14 +98,16 @@ void pm8001_tag_init(struct pm8001_hba_info *pm8001_ha)
                pm8001_tag_free(pm8001_ha, i);
 }
 
- /**
-  * pm8001_mem_alloc - allocate memory for pm8001.
-  * @pdev: pci device.
-  * @virt_addr: the allocated virtual address
-  * @pphys_addr_hi: the physical address high byte address.
-  * @pphys_addr_lo: the physical address low byte address.
-  * @mem_size: memory size.
-  */
+/**
+ * pm8001_mem_alloc - allocate memory for pm8001.
+ * @pdev: pci device.
+ * @virt_addr: the allocated virtual address
+ * @pphys_addr: DMA address for this device
+ * @pphys_addr_hi: the physical address high byte address.
+ * @pphys_addr_lo: the physical address low byte address.
+ * @mem_size: memory size.
+ * @align: requested byte alignment
+ */
 int pm8001_mem_alloc(struct pci_dev *pdev, void **virt_addr,
        dma_addr_t *pphys_addr, u32 *pphys_addr_hi,
        u32 *pphys_addr_lo, u32 mem_size, u32 align)
@@ -339,7 +341,7 @@ static int pm8001_task_prep_ssp_tm(struct pm8001_hba_info *pm8001_ha,
 }
 
 /**
-  * pm8001_task_prep_ssp - the dispatcher function,prepare ssp data for ssp task
+  * pm8001_task_prep_ssp - the dispatcher function, prepare ssp data for ssp task
   * @pm8001_ha: our hba card information
   * @ccb: the ccb which attached to ssp task
   */
@@ -554,10 +556,10 @@ void pm8001_ccb_task_free(struct pm8001_hba_info *pm8001_ha,
        pm8001_tag_free(pm8001_ha, ccb_idx);
 }
 
- /**
 * pm8001_alloc_dev - find a empty pm8001_device
 * @pm8001_ha: our hba card information
 */
+/**
+ * pm8001_alloc_dev - find a empty pm8001_device
+ * @pm8001_ha: our hba card information
+ */
 static struct pm8001_device *pm8001_alloc_dev(struct pm8001_hba_info *pm8001_ha)
 {
        u32 dev;
@@ -705,7 +707,7 @@ static void pm8001_tmf_timedout(struct timer_list *t)
   * @parameter: ssp task parameter.
   *
   * when errors or exception happened, we may want to do something, for example
-  * abort the issued task which result in this execption, it is done by calling
+  * abort the issued task which result in this exception, it is done by calling
   * this function, note it is also with the task execute interface.
   */
 static int pm8001_exec_internal_tmf_task(struct domain_device *dev,
@@ -984,11 +986,12 @@ void pm8001_open_reject_retry(
 }
 
 /**
- * pm8001_I_T_nexus_reset()
-  * Standard mandates link reset for ATA  (type 0) and hard reset for
-  * SSP (type 1) , only for RECOVERY
-  * @dev: the device structure for the device to reset.
-  */
+ * pm8001_I_T_nexus_reset() - reset the initiator/target connection
+ * @dev: the device structure for the device to reset.
+ *
+ * Standard mandates link reset for ATA (type 0) and hard reset for
+ * SSP (type 1), only for RECOVERY
+ */
 int pm8001_I_T_nexus_reset(struct domain_device *dev)
 {
        int rc = TMF_RESP_FUNC_FAILED;
index 45ecd96..6ffe17b 100644 (file)
@@ -140,7 +140,7 @@ ssize_t pm80xx_get_fatal_dump(struct device *cdev,
                pm8001_ha->fatal_bar_loc = 0;
        }
 
-       /* Read until accum_len is retrived */
+       /* Read until accum_len is retrieved */
        accum_len = pm8001_mr32(fatal_table_address,
                                MPI_FATAL_EDUMP_TABLE_ACCUM_LEN);
        /* Determine length of data between previously stored transfer length
@@ -1011,7 +1011,7 @@ static int mpi_init_check(struct pm8001_hba_info *pm8001_ha)
                           value);
                return -EBUSY;
        }
-       /* check the MPI-State for initialization upto 100ms*/
+       /* check the MPI-State for initialization up to 100ms*/
        max_wait_count = 5;/* 100 msec */
        do {
                msleep(FW_READY_INTERVAL);
@@ -1093,7 +1093,7 @@ static int init_pci_device_addresses(struct pm8001_hba_info *pm8001_ha)
 
        value = pm8001_cr32(pm8001_ha, 0, MSGU_SCRATCH_PAD_0);
 
-       /**
+       /*
         * lower 26 bits of SCRATCHPAD0 register describes offset within the
         * PCIe BAR where the MPI configuration table is present
         */
@@ -1101,7 +1101,7 @@ static int init_pci_device_addresses(struct pm8001_hba_info *pm8001_ha)
 
        pm8001_dbg(pm8001_ha, DEV, "Scratchpad 0 Offset: 0x%x value 0x%x\n",
                   offset, value);
-       /**
+       /*
         * Upper 6 bits describe the offset within PCI config space where BAR
         * is located.
         */
@@ -1109,7 +1109,7 @@ static int init_pci_device_addresses(struct pm8001_hba_info *pm8001_ha)
        pcibar = get_pci_bar_index(pcilogic);
        pm8001_dbg(pm8001_ha, INIT, "Scratchpad 0 PCI BAR: %d\n", pcibar);
 
-       /**
+       /*
         * Make sure the offset falls inside the ioremapped PCI BAR
         */
        if (offset > pm8001_ha->io_mem[pcibar].memsize) {
@@ -1121,7 +1121,7 @@ static int init_pci_device_addresses(struct pm8001_hba_info *pm8001_ha)
        pm8001_ha->main_cfg_tbl_addr = base_addr =
                pm8001_ha->io_mem[pcibar].memvirtaddr + offset;
 
-       /**
+       /*
         * Validate main configuration table address: first DWord should read
         * "PMCS"
         */
@@ -1385,7 +1385,7 @@ pm80xx_get_encrypt_info(struct pm8001_hba_info *pm8001_ha)
 }
 
 /**
- * pm80xx_encrypt_update - update flash with encryption informtion
+ * pm80xx_encrypt_update - update flash with encryption information
  * @pm8001_ha: our hba card information.
  */
 static int pm80xx_encrypt_update(struct pm8001_hba_info *pm8001_ha)
@@ -1422,7 +1422,7 @@ static int pm80xx_encrypt_update(struct pm8001_hba_info *pm8001_ha)
 }
 
 /**
- * pm80xx_chip_init - the main init function that initialize whole PM8001 chip.
+ * pm80xx_chip_init - the main init function that initializes whole PM8001 chip.
  * @pm8001_ha: our hba card information
  */
 static int pm80xx_chip_init(struct pm8001_hba_info *pm8001_ha)
@@ -1541,7 +1541,7 @@ static int mpi_uninit_check(struct pm8001_hba_info *pm8001_ha)
 }
 
 /**
- * pm80xx_fatal_errors - returns non zero *ONLY* when fatal errors
+ * pm80xx_fatal_errors - returns non-zero *ONLY* when fatal errors
  * @pm8001_ha: our hba card information
  *
  * Fatal errors are recoverable only after a host reboot.
@@ -1576,8 +1576,8 @@ pm80xx_fatal_errors(struct pm8001_hba_info *pm8001_ha)
 }
 
 /**
- * pm80xx_chip_soft_rst - soft reset the PM8001 chip, so that the clear all
- * the FW register status to the originated status.
+ * pm80xx_chip_soft_rst - soft reset the PM8001 chip, so that all
+ * FW register status are reset to the originated status.
  * @pm8001_ha: our hba card information
  */
 
@@ -1895,13 +1895,13 @@ static void pm80xx_send_read_log(struct pm8001_hba_info *pm8001_ha,
 }
 
 /**
- * mpi_ssp_completion- process the event that FW response to the SSP request.
+ * mpi_ssp_completion - process the event that FW response to the SSP request.
  * @pm8001_ha: our hba card information
  * @piomb: the message contents of this outbound message.
  *
  * When FW has completed a ssp request for example a IO request, after it has
- * filled the SG data with the data, it will trigger this event represent
- * that he has finished the job,please check the coresponding buffer.
+ * filled the SG data with the data, it will trigger this event representing
+ * that he has finished the job; please check the corresponding buffer.
  * So we will tell the caller who maybe waiting the result to tell upper layer
  * that the task has been finished.
  */
@@ -3217,7 +3217,7 @@ mpi_smp_completion(struct pm8001_hba_info *pm8001_ha, void *piomb)
 }
 
 /**
- * pm80xx_hw_event_ack_req- For PM8001,some events need to acknowage to FW.
+ * pm80xx_hw_event_ack_req- For PM8001, some events need to acknowledge to FW.
  * @pm8001_ha: our hba card information
  * @Qnum: the outbound queue message number.
  * @SEA: source of event to ack
@@ -3275,7 +3275,7 @@ static void hw_event_port_recover(struct pm8001_hba_info *pm8001_ha,
 }
 
 /**
- * hw_event_sas_phy_up -FW tells me a SAS phy up event.
+ * hw_event_sas_phy_up - FW tells me a SAS phy up event.
  * @pm8001_ha: our hba card information
  * @piomb: IO message buffer
  */
@@ -3353,7 +3353,7 @@ hw_event_sas_phy_up(struct pm8001_hba_info *pm8001_ha, void *piomb)
 }
 
 /**
- * hw_event_sata_phy_up -FW tells me a SATA phy up event.
+ * hw_event_sata_phy_up - FW tells me a SATA phy up event.
  * @pm8001_ha: our hba card information
  * @piomb: IO message buffer
  */
@@ -3400,7 +3400,7 @@ hw_event_sata_phy_up(struct pm8001_hba_info *pm8001_ha, void *piomb)
 }
 
 /**
- * hw_event_phy_down -we should notify the libsas the phy is down.
+ * hw_event_phy_down - we should notify the libsas the phy is down.
  * @pm8001_ha: our hba card information
  * @piomb: IO message buffer
  */
@@ -3500,7 +3500,7 @@ static int mpi_phy_start_resp(struct pm8001_hba_info *pm8001_ha, void *piomb)
 }
 
 /**
- * mpi_thermal_hw_event -The hw event has come.
+ * mpi_thermal_hw_event - a thermal hw event has come.
  * @pm8001_ha: our hba card information
  * @piomb: IO message buffer
  */
@@ -3530,7 +3530,7 @@ static int mpi_thermal_hw_event(struct pm8001_hba_info *pm8001_ha, void *piomb)
 }
 
 /**
- * mpi_hw_event -The hw event has come.
+ * mpi_hw_event - The hw event has come.
  * @pm8001_ha: our hba card information
  * @piomb: IO message buffer
  */
@@ -4025,7 +4025,7 @@ static void process_one_iomb(struct pm8001_hba_info *pm8001_ha, void *piomb)
        case OPC_OUB_SET_DEV_INFO:
                pm8001_dbg(pm8001_ha, MSG, "OPC_OUB_SET_DEV_INFO\n");
                break;
-       /* spcv specifc commands */
+       /* spcv specific commands */
        case OPC_OUB_PHY_START_RESP:
                pm8001_dbg(pm8001_ha, MSG,
                           "OPC_OUB_PHY_START_RESP opcode:%x\n", opc);
@@ -4186,7 +4186,7 @@ static void build_smp_cmd(u32 deviceID, __le32 hTag,
 }
 
 /**
- * pm80xx_chip_smp_req - send a SMP task to FW
+ * pm80xx_chip_smp_req - send an SMP task to FW
  * @pm8001_ha: our hba card information.
  * @ccb: the ccb information this request used.
  */
@@ -4346,7 +4346,7 @@ static int check_enc_sat_cmd(struct sas_task *task)
 }
 
 /**
- * pm80xx_chip_ssp_io_req - send a SSP task to FW
+ * pm80xx_chip_ssp_io_req - send an SSP task to FW
  * @pm8001_ha: our hba card information.
  * @ccb: the ccb information this request used.
  */
@@ -4750,13 +4750,13 @@ pm80xx_chip_phy_start_req(struct pm8001_hba_info *pm8001_ha, u8 phy_id)
        payload.ase_sh_lm_slr_phyid = cpu_to_le32(SPINHOLD_DISABLE |
                        LINKMODE_AUTO | pm8001_ha->link_rate | phy_id);
        /* SSC Disable and SAS Analog ST configuration */
-       /**
+       /*
        payload.ase_sh_lm_slr_phyid =
                cpu_to_le32(SSC_DISABLE_30 | SAS_ASE | SPINHOLD_DISABLE |
                LINKMODE_AUTO | LINKRATE_15 | LINKRATE_30 | LINKRATE_60 |
                phy_id);
        Have to add "SAS PHY Analog Setup SPASTI 1 Byte" Based on need
-       **/
+       */
 
        payload.sas_identify.dev_type = SAS_END_DEVICE;
        payload.sas_identify.initiator_bits = SAS_PROTOCOL_ALL;
index 8f9727e..7456a26 100644 (file)
@@ -194,7 +194,7 @@ void scsi_queue_insert(struct scsi_cmnd *cmd, int reason)
  * @bufflen:   len of buffer
  * @sense:     optional sense buffer
  * @sshdr:     optional decoded sense header
- * @timeout:   request timeout in seconds
+ * @timeout:   request timeout in HZ
  * @retries:   number of times to retry request
  * @flags:     flags for ->cmd_flags
  * @rq_flags:  flags for ->rq_flags
index 6d2d636..b8d55af 100644 (file)
@@ -98,11 +98,7 @@ MODULE_ALIAS_SCSI_DEVICE(TYPE_MOD);
 MODULE_ALIAS_SCSI_DEVICE(TYPE_RBC);
 MODULE_ALIAS_SCSI_DEVICE(TYPE_ZBC);
 
-#if !defined(CONFIG_DEBUG_BLOCK_EXT_DEVT)
 #define SD_MINORS      16
-#else
-#define SD_MINORS      0
-#endif
 
 static void sd_config_discard(struct scsi_disk *, unsigned int);
 static void sd_config_write_same(struct scsi_disk *);
index c98d540..194755c 100644 (file)
@@ -1229,8 +1229,13 @@ static inline int ufshcd_vops_pwr_change_notify(struct ufs_hba *hba,
 static inline void ufshcd_vops_setup_xfer_req(struct ufs_hba *hba, int tag,
                                        bool is_scsi_cmd)
 {
-       if (hba->vops && hba->vops->setup_xfer_req)
-               return hba->vops->setup_xfer_req(hba, tag, is_scsi_cmd);
+       if (hba->vops && hba->vops->setup_xfer_req) {
+               unsigned long flags;
+
+               spin_lock_irqsave(hba->host->host_lock, flags);
+               hba->vops->setup_xfer_req(hba, tag, is_scsi_cmd);
+               spin_unlock_irqrestore(hba->host->host_lock, flags);
+       }
 }
 
 static inline void ufshcd_vops_setup_task_mgmt(struct ufs_hba *hba,
index 8e85889..15db7a3 100644 (file)
@@ -586,6 +586,7 @@ static int qe_ep_init(struct qe_udc *udc,
                        case USB_SPEED_FULL:
                                if (max <= 1023)
                                        break;
+                               fallthrough;
                        default:
                                goto en_done;
                        }
index 98f1930..1c85514 100644 (file)
@@ -970,13 +970,11 @@ fb_set_var(struct fb_info *info, struct fb_var_screeninfo *var)
                fb_var_to_videomode(&mode2, &info->var);
                /* make sure we don't delete the videomode of current var */
                ret = fb_mode_is_equal(&mode1, &mode2);
-
-               if (!ret)
-                       fbcon_mode_deleted(info, &mode1);
-
-               if (!ret)
-                       fb_delete_videomode(&mode1, &info->modelist);
-
+               if (!ret) {
+                       ret = fbcon_mode_deleted(info, &mode1);
+                       if (!ret)
+                               fb_delete_videomode(&mode1, &info->modelist);
+               }
 
                return ret ? -EINVAL : 0;
        }
index ffbf900..438e2c7 100644 (file)
@@ -241,6 +241,8 @@ xilinx_fb_blank(int blank_mode, struct fb_info *fbi)
        case FB_BLANK_POWERDOWN:
                /* turn off panel */
                xilinx_fb_out32(drvdata, REG_CTRL, 0);
+               break;
+
        default:
                break;
        }
index 38b127b..9e7d9d0 100644 (file)
@@ -1498,9 +1498,18 @@ void btrfs_reclaim_bgs_work(struct work_struct *work)
        if (!btrfs_exclop_start(fs_info, BTRFS_EXCLOP_BALANCE))
                return;
 
-       mutex_lock(&fs_info->reclaim_bgs_lock);
+       /*
+        * Long running balances can keep us blocked here for eternity, so
+        * simply skip reclaim if we're unable to get the mutex.
+        */
+       if (!mutex_trylock(&fs_info->reclaim_bgs_lock)) {
+               btrfs_exclop_finish(fs_info);
+               return;
+       }
+
        spin_lock(&fs_info->unused_bgs_lock);
        while (!list_empty(&fs_info->reclaim_bgs)) {
+               u64 zone_unusable;
                int ret = 0;
 
                bg = list_first_entry(&fs_info->reclaim_bgs,
@@ -1534,13 +1543,22 @@ void btrfs_reclaim_bgs_work(struct work_struct *work)
                        goto next;
                }
 
+               /*
+                * Cache the zone_unusable value before turning the block group
+                * to read only. As soon as the blog group is read only it's
+                * zone_unusable value gets moved to the block group's read-only
+                * bytes and isn't available for calculations anymore.
+                */
+               zone_unusable = bg->zone_unusable;
                ret = inc_block_group_ro(bg, 0);
                up_write(&space_info->groups_sem);
                if (ret < 0)
                        goto next;
 
-               btrfs_info(fs_info, "reclaiming chunk %llu with %llu%% used",
-                               bg->start, div_u64(bg->used * 100, bg->length));
+               btrfs_info(fs_info,
+                       "reclaiming chunk %llu with %llu%% used %llu%% unusable",
+                               bg->start, div_u64(bg->used * 100, bg->length),
+                               div64_u64(zone_unusable * 100, bg->length));
                trace_btrfs_reclaim_block_group(bg);
                ret = btrfs_relocate_chunk(fs_info, bg->start);
                if (ret)
@@ -2197,6 +2215,13 @@ error:
        return ret;
 }
 
+/*
+ * This function, insert_block_group_item(), belongs to the phase 2 of chunk
+ * allocation.
+ *
+ * See the comment at btrfs_chunk_alloc() for details about the chunk allocation
+ * phases.
+ */
 static int insert_block_group_item(struct btrfs_trans_handle *trans,
                                   struct btrfs_block_group *block_group)
 {
@@ -2219,15 +2244,19 @@ static int insert_block_group_item(struct btrfs_trans_handle *trans,
        return btrfs_insert_item(trans, root, &key, &bgi, sizeof(bgi));
 }
 
+/*
+ * This function, btrfs_create_pending_block_groups(), belongs to the phase 2 of
+ * chunk allocation.
+ *
+ * See the comment at btrfs_chunk_alloc() for details about the chunk allocation
+ * phases.
+ */
 void btrfs_create_pending_block_groups(struct btrfs_trans_handle *trans)
 {
        struct btrfs_fs_info *fs_info = trans->fs_info;
        struct btrfs_block_group *block_group;
        int ret = 0;
 
-       if (!trans->can_flush_pending_bgs)
-               return;
-
        while (!list_empty(&trans->new_bgs)) {
                int index;
 
@@ -2242,6 +2271,13 @@ void btrfs_create_pending_block_groups(struct btrfs_trans_handle *trans)
                ret = insert_block_group_item(trans, block_group);
                if (ret)
                        btrfs_abort_transaction(trans, ret);
+               if (!block_group->chunk_item_inserted) {
+                       mutex_lock(&fs_info->chunk_mutex);
+                       ret = btrfs_chunk_alloc_add_chunk_item(trans, block_group);
+                       mutex_unlock(&fs_info->chunk_mutex);
+                       if (ret)
+                               btrfs_abort_transaction(trans, ret);
+               }
                ret = btrfs_finish_chunk_alloc(trans, block_group->start,
                                        block_group->length);
                if (ret)
@@ -2265,8 +2301,9 @@ next:
        btrfs_trans_release_chunk_metadata(trans);
 }
 
-int btrfs_make_block_group(struct btrfs_trans_handle *trans, u64 bytes_used,
-                          u64 type, u64 chunk_offset, u64 size)
+struct btrfs_block_group *btrfs_make_block_group(struct btrfs_trans_handle *trans,
+                                                u64 bytes_used, u64 type,
+                                                u64 chunk_offset, u64 size)
 {
        struct btrfs_fs_info *fs_info = trans->fs_info;
        struct btrfs_block_group *cache;
@@ -2276,7 +2313,7 @@ int btrfs_make_block_group(struct btrfs_trans_handle *trans, u64 bytes_used,
 
        cache = btrfs_create_block_group_cache(fs_info, chunk_offset);
        if (!cache)
-               return -ENOMEM;
+               return ERR_PTR(-ENOMEM);
 
        cache->length = size;
        set_free_space_tree_thresholds(cache);
@@ -2290,7 +2327,7 @@ int btrfs_make_block_group(struct btrfs_trans_handle *trans, u64 bytes_used,
        ret = btrfs_load_block_group_zone_info(cache, true);
        if (ret) {
                btrfs_put_block_group(cache);
-               return ret;
+               return ERR_PTR(ret);
        }
 
        ret = exclude_super_stripes(cache);
@@ -2298,7 +2335,7 @@ int btrfs_make_block_group(struct btrfs_trans_handle *trans, u64 bytes_used,
                /* We may have excluded something, so call this just in case */
                btrfs_free_excluded_extents(cache);
                btrfs_put_block_group(cache);
-               return ret;
+               return ERR_PTR(ret);
        }
 
        add_new_free_space(cache, chunk_offset, chunk_offset + size);
@@ -2325,7 +2362,7 @@ int btrfs_make_block_group(struct btrfs_trans_handle *trans, u64 bytes_used,
        if (ret) {
                btrfs_remove_free_space_cache(cache);
                btrfs_put_block_group(cache);
-               return ret;
+               return ERR_PTR(ret);
        }
 
        /*
@@ -2344,7 +2381,7 @@ int btrfs_make_block_group(struct btrfs_trans_handle *trans, u64 bytes_used,
        btrfs_update_delayed_refs_rsv(trans);
 
        set_avail_alloc_bits(fs_info, type);
-       return 0;
+       return cache;
 }
 
 /*
@@ -3222,11 +3259,203 @@ int btrfs_force_chunk_alloc(struct btrfs_trans_handle *trans, u64 type)
        return btrfs_chunk_alloc(trans, alloc_flags, CHUNK_ALLOC_FORCE);
 }
 
+static int do_chunk_alloc(struct btrfs_trans_handle *trans, u64 flags)
+{
+       struct btrfs_block_group *bg;
+       int ret;
+
+       /*
+        * Check if we have enough space in the system space info because we
+        * will need to update device items in the chunk btree and insert a new
+        * chunk item in the chunk btree as well. This will allocate a new
+        * system block group if needed.
+        */
+       check_system_chunk(trans, flags);
+
+       bg = btrfs_alloc_chunk(trans, flags);
+       if (IS_ERR(bg)) {
+               ret = PTR_ERR(bg);
+               goto out;
+       }
+
+       /*
+        * If this is a system chunk allocation then stop right here and do not
+        * add the chunk item to the chunk btree. This is to prevent a deadlock
+        * because this system chunk allocation can be triggered while COWing
+        * some extent buffer of the chunk btree and while holding a lock on a
+        * parent extent buffer, in which case attempting to insert the chunk
+        * item (or update the device item) would result in a deadlock on that
+        * parent extent buffer. In this case defer the chunk btree updates to
+        * the second phase of chunk allocation and keep our reservation until
+        * the second phase completes.
+        *
+        * This is a rare case and can only be triggered by the very few cases
+        * we have where we need to touch the chunk btree outside chunk allocation
+        * and chunk removal. These cases are basically adding a device, removing
+        * a device or resizing a device.
+        */
+       if (flags & BTRFS_BLOCK_GROUP_SYSTEM)
+               return 0;
+
+       ret = btrfs_chunk_alloc_add_chunk_item(trans, bg);
+       /*
+        * Normally we are not expected to fail with -ENOSPC here, since we have
+        * previously reserved space in the system space_info and allocated one
+        * new system chunk if necessary. However there are two exceptions:
+        *
+        * 1) We may have enough free space in the system space_info but all the
+        *    existing system block groups have a profile which can not be used
+        *    for extent allocation.
+        *
+        *    This happens when mounting in degraded mode. For example we have a
+        *    RAID1 filesystem with 2 devices, lose one device and mount the fs
+        *    using the other device in degraded mode. If we then allocate a chunk,
+        *    we may have enough free space in the existing system space_info, but
+        *    none of the block groups can be used for extent allocation since they
+        *    have a RAID1 profile, and because we are in degraded mode with a
+        *    single device, we are forced to allocate a new system chunk with a
+        *    SINGLE profile. Making check_system_chunk() iterate over all system
+        *    block groups and check if they have a usable profile and enough space
+        *    can be slow on very large filesystems, so we tolerate the -ENOSPC and
+        *    try again after forcing allocation of a new system chunk. Like this
+        *    we avoid paying the cost of that search in normal circumstances, when
+        *    we were not mounted in degraded mode;
+        *
+        * 2) We had enough free space info the system space_info, and one suitable
+        *    block group to allocate from when we called check_system_chunk()
+        *    above. However right after we called it, the only system block group
+        *    with enough free space got turned into RO mode by a running scrub,
+        *    and in this case we have to allocate a new one and retry. We only
+        *    need do this allocate and retry once, since we have a transaction
+        *    handle and scrub uses the commit root to search for block groups.
+        */
+       if (ret == -ENOSPC) {
+               const u64 sys_flags = btrfs_system_alloc_profile(trans->fs_info);
+               struct btrfs_block_group *sys_bg;
+
+               sys_bg = btrfs_alloc_chunk(trans, sys_flags);
+               if (IS_ERR(sys_bg)) {
+                       ret = PTR_ERR(sys_bg);
+                       btrfs_abort_transaction(trans, ret);
+                       goto out;
+               }
+
+               ret = btrfs_chunk_alloc_add_chunk_item(trans, sys_bg);
+               if (ret) {
+                       btrfs_abort_transaction(trans, ret);
+                       goto out;
+               }
+
+               ret = btrfs_chunk_alloc_add_chunk_item(trans, bg);
+               if (ret) {
+                       btrfs_abort_transaction(trans, ret);
+                       goto out;
+               }
+       } else if (ret) {
+               btrfs_abort_transaction(trans, ret);
+               goto out;
+       }
+out:
+       btrfs_trans_release_chunk_metadata(trans);
+
+       return ret;
+}
+
 /*
- * If force is CHUNK_ALLOC_FORCE:
+ * Chunk allocation is done in 2 phases:
+ *
+ * 1) Phase 1 - through btrfs_chunk_alloc() we allocate device extents for
+ *    the chunk, the chunk mapping, create its block group and add the items
+ *    that belong in the chunk btree to it - more specifically, we need to
+ *    update device items in the chunk btree and add a new chunk item to it.
+ *
+ * 2) Phase 2 - through btrfs_create_pending_block_groups(), we add the block
+ *    group item to the extent btree and the device extent items to the devices
+ *    btree.
+ *
+ * This is done to prevent deadlocks. For example when COWing a node from the
+ * extent btree we are holding a write lock on the node's parent and if we
+ * trigger chunk allocation and attempted to insert the new block group item
+ * in the extent btree right way, we could deadlock because the path for the
+ * insertion can include that parent node. At first glance it seems impossible
+ * to trigger chunk allocation after starting a transaction since tasks should
+ * reserve enough transaction units (metadata space), however while that is true
+ * most of the time, chunk allocation may still be triggered for several reasons:
+ *
+ * 1) When reserving metadata, we check if there is enough free space in the
+ *    metadata space_info and therefore don't trigger allocation of a new chunk.
+ *    However later when the task actually tries to COW an extent buffer from
+ *    the extent btree or from the device btree for example, it is forced to
+ *    allocate a new block group (chunk) because the only one that had enough
+ *    free space was just turned to RO mode by a running scrub for example (or
+ *    device replace, block group reclaim thread, etc), so we can not use it
+ *    for allocating an extent and end up being forced to allocate a new one;
+ *
+ * 2) Because we only check that the metadata space_info has enough free bytes,
+ *    we end up not allocating a new metadata chunk in that case. However if
+ *    the filesystem was mounted in degraded mode, none of the existing block
+ *    groups might be suitable for extent allocation due to their incompatible
+ *    profile (for e.g. mounting a 2 devices filesystem, where all block groups
+ *    use a RAID1 profile, in degraded mode using a single device). In this case
+ *    when the task attempts to COW some extent buffer of the extent btree for
+ *    example, it will trigger allocation of a new metadata block group with a
+ *    suitable profile (SINGLE profile in the example of the degraded mount of
+ *    the RAID1 filesystem);
+ *
+ * 3) The task has reserved enough transaction units / metadata space, but when
+ *    it attempts to COW an extent buffer from the extent or device btree for
+ *    example, it does not find any free extent in any metadata block group,
+ *    therefore forced to try to allocate a new metadata block group.
+ *    This is because some other task allocated all available extents in the
+ *    meanwhile - this typically happens with tasks that don't reserve space
+ *    properly, either intentionally or as a bug. One example where this is
+ *    done intentionally is fsync, as it does not reserve any transaction units
+ *    and ends up allocating a variable number of metadata extents for log
+ *    tree extent buffers.
+ *
+ * We also need this 2 phases setup when adding a device to a filesystem with
+ * a seed device - we must create new metadata and system chunks without adding
+ * any of the block group items to the chunk, extent and device btrees. If we
+ * did not do it this way, we would get ENOSPC when attempting to update those
+ * btrees, since all the chunks from the seed device are read-only.
+ *
+ * Phase 1 does the updates and insertions to the chunk btree because if we had
+ * it done in phase 2 and have a thundering herd of tasks allocating chunks in
+ * parallel, we risk having too many system chunks allocated by many tasks if
+ * many tasks reach phase 1 without the previous ones completing phase 2. In the
+ * extreme case this leads to exhaustion of the system chunk array in the
+ * superblock. This is easier to trigger if using a btree node/leaf size of 64K
+ * and with RAID filesystems (so we have more device items in the chunk btree).
+ * This has happened before and commit eafa4fd0ad0607 ("btrfs: fix exhaustion of
+ * the system chunk array due to concurrent allocations") provides more details.
+ *
+ * For allocation of system chunks, we defer the updates and insertions into the
+ * chunk btree to phase 2. This is to prevent deadlocks on extent buffers because
+ * if the chunk allocation is triggered while COWing an extent buffer of the
+ * chunk btree, we are holding a lock on the parent of that extent buffer and
+ * doing the chunk btree updates and insertions can require locking that parent.
+ * This is for the very few and rare cases where we update the chunk btree that
+ * are not chunk allocation or chunk removal: adding a device, removing a device
+ * or resizing a device.
+ *
+ * The reservation of system space, done through check_system_chunk(), as well
+ * as all the updates and insertions into the chunk btree must be done while
+ * holding fs_info->chunk_mutex. This is important to guarantee that while COWing
+ * an extent buffer from the chunks btree we never trigger allocation of a new
+ * system chunk, which would result in a deadlock (trying to lock twice an
+ * extent buffer of the chunk btree, first time before triggering the chunk
+ * allocation and the second time during chunk allocation while attempting to
+ * update the chunks btree). The system chunk array is also updated while holding
+ * that mutex. The same logic applies to removing chunks - we must reserve system
+ * space, update the chunk btree and the system chunk array in the superblock
+ * while holding fs_info->chunk_mutex.
+ *
+ * This function, btrfs_chunk_alloc(), belongs to phase 1.
+ *
+ * If @force is CHUNK_ALLOC_FORCE:
  *    - return 1 if it successfully allocates a chunk,
  *    - return errors including -ENOSPC otherwise.
- * If force is NOT CHUNK_ALLOC_FORCE:
+ * If @force is NOT CHUNK_ALLOC_FORCE:
  *    - return 0 if it doesn't need to allocate a new chunk,
  *    - return 1 if it successfully allocates a chunk,
  *    - return errors including -ENOSPC otherwise.
@@ -3243,6 +3472,13 @@ int btrfs_chunk_alloc(struct btrfs_trans_handle *trans, u64 flags,
        /* Don't re-enter if we're already allocating a chunk */
        if (trans->allocating_chunk)
                return -ENOSPC;
+       /*
+        * If we are removing a chunk, don't re-enter or we would deadlock.
+        * System space reservation and system chunk allocation is done by the
+        * chunk remove operation (btrfs_remove_chunk()).
+        */
+       if (trans->removing_chunk)
+               return -ENOSPC;
 
        space_info = btrfs_find_space_info(fs_info, flags);
        ASSERT(space_info);
@@ -3306,13 +3542,7 @@ int btrfs_chunk_alloc(struct btrfs_trans_handle *trans, u64 flags,
                        force_metadata_allocation(fs_info);
        }
 
-       /*
-        * Check if we have enough space in SYSTEM chunk because we may need
-        * to update devices.
-        */
-       check_system_chunk(trans, flags);
-
-       ret = btrfs_alloc_chunk(trans, flags);
+       ret = do_chunk_alloc(trans, flags);
        trans->allocating_chunk = false;
 
        spin_lock(&space_info->lock);
@@ -3331,22 +3561,6 @@ out:
        space_info->chunk_alloc = 0;
        spin_unlock(&space_info->lock);
        mutex_unlock(&fs_info->chunk_mutex);
-       /*
-        * When we allocate a new chunk we reserve space in the chunk block
-        * reserve to make sure we can COW nodes/leafs in the chunk tree or
-        * add new nodes/leafs to it if we end up needing to do it when
-        * inserting the chunk item and updating device items as part of the
-        * second phase of chunk allocation, performed by
-        * btrfs_finish_chunk_alloc(). So make sure we don't accumulate a
-        * large number of new block groups to create in our transaction
-        * handle's new_bgs list to avoid exhausting the chunk block reserve
-        * in extreme cases - like having a single transaction create many new
-        * block groups when starting to write out the free space caches of all
-        * the block groups that were made dirty during the lifetime of the
-        * transaction.
-        */
-       if (trans->chunk_bytes_reserved >= (u64)SZ_2M)
-               btrfs_create_pending_block_groups(trans);
 
        return ret;
 }
@@ -3367,7 +3581,6 @@ static u64 get_profile_num_devs(struct btrfs_fs_info *fs_info, u64 type)
  */
 void check_system_chunk(struct btrfs_trans_handle *trans, u64 type)
 {
-       struct btrfs_transaction *cur_trans = trans->transaction;
        struct btrfs_fs_info *fs_info = trans->fs_info;
        struct btrfs_space_info *info;
        u64 left;
@@ -3382,7 +3595,6 @@ void check_system_chunk(struct btrfs_trans_handle *trans, u64 type)
        lockdep_assert_held(&fs_info->chunk_mutex);
 
        info = btrfs_find_space_info(fs_info, BTRFS_BLOCK_GROUP_SYSTEM);
-again:
        spin_lock(&info->lock);
        left = info->total_bytes - btrfs_space_info_used(info, true);
        spin_unlock(&info->lock);
@@ -3401,76 +3613,39 @@ again:
 
        if (left < thresh) {
                u64 flags = btrfs_system_alloc_profile(fs_info);
-               u64 reserved = atomic64_read(&cur_trans->chunk_bytes_reserved);
-
-               /*
-                * If there's not available space for the chunk tree (system
-                * space) and there are other tasks that reserved space for
-                * creating a new system block group, wait for them to complete
-                * the creation of their system block group and release excess
-                * reserved space. We do this because:
-                *
-                * *) We can end up allocating more system chunks than necessary
-                *    when there are multiple tasks that are concurrently
-                *    allocating block groups, which can lead to exhaustion of
-                *    the system array in the superblock;
-                *
-                * *) If we allocate extra and unnecessary system block groups,
-                *    despite being empty for a long time, and possibly forever,
-                *    they end not being added to the list of unused block groups
-                *    because that typically happens only when deallocating the
-                *    last extent from a block group - which never happens since
-                *    we never allocate from them in the first place. The few
-                *    exceptions are when mounting a filesystem or running scrub,
-                *    which add unused block groups to the list of unused block
-                *    groups, to be deleted by the cleaner kthread.
-                *    And even when they are added to the list of unused block
-                *    groups, it can take a long time until they get deleted,
-                *    since the cleaner kthread might be sleeping or busy with
-                *    other work (deleting subvolumes, running delayed iputs,
-                *    defrag scheduling, etc);
-                *
-                * This is rare in practice, but can happen when too many tasks
-                * are allocating blocks groups in parallel (via fallocate())
-                * and before the one that reserved space for a new system block
-                * group finishes the block group creation and releases the space
-                * reserved in excess (at btrfs_create_pending_block_groups()),
-                * other tasks end up here and see free system space temporarily
-                * not enough for updating the chunk tree.
-                *
-                * We unlock the chunk mutex before waiting for such tasks and
-                * lock it again after the wait, otherwise we would deadlock.
-                * It is safe to do so because allocating a system chunk is the
-                * first thing done while allocating a new block group.
-                */
-               if (reserved > trans->chunk_bytes_reserved) {
-                       const u64 min_needed = reserved - thresh;
-
-                       mutex_unlock(&fs_info->chunk_mutex);
-                       wait_event(cur_trans->chunk_reserve_wait,
-                          atomic64_read(&cur_trans->chunk_bytes_reserved) <=
-                          min_needed);
-                       mutex_lock(&fs_info->chunk_mutex);
-                       goto again;
-               }
+               struct btrfs_block_group *bg;
 
                /*
                 * Ignore failure to create system chunk. We might end up not
                 * needing it, as we might not need to COW all nodes/leafs from
                 * the paths we visit in the chunk tree (they were already COWed
                 * or created in the current transaction for example).
+                *
+                * Also, if our caller is allocating a system chunk, do not
+                * attempt to insert the chunk item in the chunk btree, as we
+                * could deadlock on an extent buffer since our caller may be
+                * COWing an extent buffer from the chunk btree.
                 */
-               ret = btrfs_alloc_chunk(trans, flags);
+               bg = btrfs_alloc_chunk(trans, flags);
+               if (IS_ERR(bg)) {
+                       ret = PTR_ERR(bg);
+               } else if (!(type & BTRFS_BLOCK_GROUP_SYSTEM)) {
+                       /*
+                        * If we fail to add the chunk item here, we end up
+                        * trying again at phase 2 of chunk allocation, at
+                        * btrfs_create_pending_block_groups(). So ignore
+                        * any error here.
+                        */
+                       btrfs_chunk_alloc_add_chunk_item(trans, bg);
+               }
        }
 
        if (!ret) {
                ret = btrfs_block_rsv_add(fs_info->chunk_root,
                                          &fs_info->chunk_block_rsv,
                                          thresh, BTRFS_RESERVE_NO_FLUSH);
-               if (!ret) {
-                       atomic64_add(thresh, &cur_trans->chunk_bytes_reserved);
+               if (!ret)
                        trans->chunk_bytes_reserved += thresh;
-               }
        }
 }
 
index 7b92742..c72a71e 100644 (file)
@@ -97,6 +97,7 @@ struct btrfs_block_group {
        unsigned int removed:1;
        unsigned int to_copy:1;
        unsigned int relocating_repair:1;
+       unsigned int chunk_item_inserted:1;
 
        int disk_cache_state;
 
@@ -268,8 +269,9 @@ void btrfs_reclaim_bgs_work(struct work_struct *work);
 void btrfs_reclaim_bgs(struct btrfs_fs_info *fs_info);
 void btrfs_mark_bg_to_reclaim(struct btrfs_block_group *bg);
 int btrfs_read_block_groups(struct btrfs_fs_info *info);
-int btrfs_make_block_group(struct btrfs_trans_handle *trans, u64 bytes_used,
-                          u64 type, u64 chunk_offset, u64 size);
+struct btrfs_block_group *btrfs_make_block_group(struct btrfs_trans_handle *trans,
+                                                u64 bytes_used, u64 type,
+                                                u64 chunk_offset, u64 size);
 void btrfs_create_pending_block_groups(struct btrfs_trans_handle *trans);
 int btrfs_inc_block_group_ro(struct btrfs_block_group *cache,
                             bool do_chunk_alloc);
index 4bc3ca2..c5c08c8 100644 (file)
@@ -364,49 +364,6 @@ static noinline int update_ref_for_cow(struct btrfs_trans_handle *trans,
        return 0;
 }
 
-static struct extent_buffer *alloc_tree_block_no_bg_flush(
-                                         struct btrfs_trans_handle *trans,
-                                         struct btrfs_root *root,
-                                         u64 parent_start,
-                                         const struct btrfs_disk_key *disk_key,
-                                         int level,
-                                         u64 hint,
-                                         u64 empty_size,
-                                         enum btrfs_lock_nesting nest)
-{
-       struct btrfs_fs_info *fs_info = root->fs_info;
-       struct extent_buffer *ret;
-
-       /*
-        * If we are COWing a node/leaf from the extent, chunk, device or free
-        * space trees, make sure that we do not finish block group creation of
-        * pending block groups. We do this to avoid a deadlock.
-        * COWing can result in allocation of a new chunk, and flushing pending
-        * block groups (btrfs_create_pending_block_groups()) can be triggered
-        * when finishing allocation of a new chunk. Creation of a pending block
-        * group modifies the extent, chunk, device and free space trees,
-        * therefore we could deadlock with ourselves since we are holding a
-        * lock on an extent buffer that btrfs_create_pending_block_groups() may
-        * try to COW later.
-        * For similar reasons, we also need to delay flushing pending block
-        * groups when splitting a leaf or node, from one of those trees, since
-        * we are holding a write lock on it and its parent or when inserting a
-        * new root node for one of those trees.
-        */
-       if (root == fs_info->extent_root ||
-           root == fs_info->chunk_root ||
-           root == fs_info->dev_root ||
-           root == fs_info->free_space_root)
-               trans->can_flush_pending_bgs = false;
-
-       ret = btrfs_alloc_tree_block(trans, root, parent_start,
-                                    root->root_key.objectid, disk_key, level,
-                                    hint, empty_size, nest);
-       trans->can_flush_pending_bgs = true;
-
-       return ret;
-}
-
 /*
  * does the dirty work in cow of a single block.  The parent block (if
  * supplied) is updated to point to the new cow copy.  The new buffer is marked
@@ -455,8 +412,9 @@ static noinline int __btrfs_cow_block(struct btrfs_trans_handle *trans,
        if ((root->root_key.objectid == BTRFS_TREE_RELOC_OBJECTID) && parent)
                parent_start = parent->start;
 
-       cow = alloc_tree_block_no_bg_flush(trans, root, parent_start, &disk_key,
-                                          level, search_start, empty_size, nest);
+       cow = btrfs_alloc_tree_block(trans, root, parent_start,
+                                    root->root_key.objectid, &disk_key, level,
+                                    search_start, empty_size, nest);
        if (IS_ERR(cow))
                return PTR_ERR(cow);
 
@@ -2458,9 +2416,9 @@ static noinline int insert_new_root(struct btrfs_trans_handle *trans,
        else
                btrfs_node_key(lower, &lower_key, 0);
 
-       c = alloc_tree_block_no_bg_flush(trans, root, 0, &lower_key, level,
-                                        root->node->start, 0,
-                                        BTRFS_NESTING_NEW_ROOT);
+       c = btrfs_alloc_tree_block(trans, root, 0, root->root_key.objectid,
+                                  &lower_key, level, root->node->start, 0,
+                                  BTRFS_NESTING_NEW_ROOT);
        if (IS_ERR(c))
                return PTR_ERR(c);
 
@@ -2589,8 +2547,9 @@ static noinline int split_node(struct btrfs_trans_handle *trans,
        mid = (c_nritems + 1) / 2;
        btrfs_node_key(c, &disk_key, mid);
 
-       split = alloc_tree_block_no_bg_flush(trans, root, 0, &disk_key, level,
-                                            c->start, 0, BTRFS_NESTING_SPLIT);
+       split = btrfs_alloc_tree_block(trans, root, 0, root->root_key.objectid,
+                                      &disk_key, level, c->start, 0,
+                                      BTRFS_NESTING_SPLIT);
        if (IS_ERR(split))
                return PTR_ERR(split);
 
@@ -3381,10 +3340,10 @@ again:
         * BTRFS_NESTING_SPLIT_THE_SPLITTENING if we need to, but for now just
         * use BTRFS_NESTING_NEW_ROOT.
         */
-       right = alloc_tree_block_no_bg_flush(trans, root, 0, &disk_key, 0,
-                                            l->start, 0, num_doubles ?
-                                            BTRFS_NESTING_NEW_ROOT :
-                                            BTRFS_NESTING_SPLIT);
+       right = btrfs_alloc_tree_block(trans, root, 0, root->root_key.objectid,
+                                      &disk_key, 0, l->start, 0,
+                                      num_doubles ? BTRFS_NESTING_NEW_ROOT :
+                                      BTRFS_NESTING_SPLIT);
        if (IS_ERR(right))
                return PTR_ERR(right);
 
index e6eb209..8f60314 100644 (file)
@@ -2271,13 +2271,127 @@ static blk_status_t btrfs_submit_bio_start(struct inode *inode, struct bio *bio,
        return btrfs_csum_one_bio(BTRFS_I(inode), bio, 0, 0);
 }
 
+/*
+ * Split an extent_map at [start, start + len]
+ *
+ * This function is intended to be used only for extract_ordered_extent().
+ */
+static int split_zoned_em(struct btrfs_inode *inode, u64 start, u64 len,
+                         u64 pre, u64 post)
+{
+       struct extent_map_tree *em_tree = &inode->extent_tree;
+       struct extent_map *em;
+       struct extent_map *split_pre = NULL;
+       struct extent_map *split_mid = NULL;
+       struct extent_map *split_post = NULL;
+       int ret = 0;
+       int modified;
+       unsigned long flags;
+
+       /* Sanity check */
+       if (pre == 0 && post == 0)
+               return 0;
+
+       split_pre = alloc_extent_map();
+       if (pre)
+               split_mid = alloc_extent_map();
+       if (post)
+               split_post = alloc_extent_map();
+       if (!split_pre || (pre && !split_mid) || (post && !split_post)) {
+               ret = -ENOMEM;
+               goto out;
+       }
+
+       ASSERT(pre + post < len);
+
+       lock_extent(&inode->io_tree, start, start + len - 1);
+       write_lock(&em_tree->lock);
+       em = lookup_extent_mapping(em_tree, start, len);
+       if (!em) {
+               ret = -EIO;
+               goto out_unlock;
+       }
+
+       ASSERT(em->len == len);
+       ASSERT(!test_bit(EXTENT_FLAG_COMPRESSED, &em->flags));
+       ASSERT(em->block_start < EXTENT_MAP_LAST_BYTE);
+
+       flags = em->flags;
+       clear_bit(EXTENT_FLAG_PINNED, &em->flags);
+       clear_bit(EXTENT_FLAG_LOGGING, &flags);
+       modified = !list_empty(&em->list);
+
+       /* First, replace the em with a new extent_map starting from * em->start */
+       split_pre->start = em->start;
+       split_pre->len = (pre ? pre : em->len - post);
+       split_pre->orig_start = split_pre->start;
+       split_pre->block_start = em->block_start;
+       split_pre->block_len = split_pre->len;
+       split_pre->orig_block_len = split_pre->block_len;
+       split_pre->ram_bytes = split_pre->len;
+       split_pre->flags = flags;
+       split_pre->compress_type = em->compress_type;
+       split_pre->generation = em->generation;
+
+       replace_extent_mapping(em_tree, em, split_pre, modified);
+
+       /*
+        * Now we only have an extent_map at:
+        *     [em->start, em->start + pre] if pre != 0
+        *     [em->start, em->start + em->len - post] if pre == 0
+        */
+
+       if (pre) {
+               /* Insert the middle extent_map */
+               split_mid->start = em->start + pre;
+               split_mid->len = em->len - pre - post;
+               split_mid->orig_start = split_mid->start;
+               split_mid->block_start = em->block_start + pre;
+               split_mid->block_len = split_mid->len;
+               split_mid->orig_block_len = split_mid->block_len;
+               split_mid->ram_bytes = split_mid->len;
+               split_mid->flags = flags;
+               split_mid->compress_type = em->compress_type;
+               split_mid->generation = em->generation;
+               add_extent_mapping(em_tree, split_mid, modified);
+       }
+
+       if (post) {
+               split_post->start = em->start + em->len - post;
+               split_post->len = post;
+               split_post->orig_start = split_post->start;
+               split_post->block_start = em->block_start + em->len - post;
+               split_post->block_len = split_post->len;
+               split_post->orig_block_len = split_post->block_len;
+               split_post->ram_bytes = split_post->len;
+               split_post->flags = flags;
+               split_post->compress_type = em->compress_type;
+               split_post->generation = em->generation;
+               add_extent_mapping(em_tree, split_post, modified);
+       }
+
+       /* Once for us */
+       free_extent_map(em);
+       /* Once for the tree */
+       free_extent_map(em);
+
+out_unlock:
+       write_unlock(&em_tree->lock);
+       unlock_extent(&inode->io_tree, start, start + len - 1);
+out:
+       free_extent_map(split_pre);
+       free_extent_map(split_mid);
+       free_extent_map(split_post);
+
+       return ret;
+}
+
 static blk_status_t extract_ordered_extent(struct btrfs_inode *inode,
                                           struct bio *bio, loff_t file_offset)
 {
        struct btrfs_ordered_extent *ordered;
-       struct extent_map *em = NULL, *em_new = NULL;
-       struct extent_map_tree *em_tree = &inode->extent_tree;
        u64 start = (u64)bio->bi_iter.bi_sector << SECTOR_SHIFT;
+       u64 file_len;
        u64 len = bio->bi_iter.bi_size;
        u64 end = start + len;
        u64 ordered_end;
@@ -2317,41 +2431,16 @@ static blk_status_t extract_ordered_extent(struct btrfs_inode *inode,
                goto out;
        }
 
+       file_len = ordered->num_bytes;
        pre = start - ordered->disk_bytenr;
        post = ordered_end - end;
 
        ret = btrfs_split_ordered_extent(ordered, pre, post);
        if (ret)
                goto out;
-
-       read_lock(&em_tree->lock);
-       em = lookup_extent_mapping(em_tree, ordered->file_offset, len);
-       if (!em) {
-               read_unlock(&em_tree->lock);
-               ret = -EIO;
-               goto out;
-       }
-       read_unlock(&em_tree->lock);
-
-       ASSERT(!test_bit(EXTENT_FLAG_COMPRESSED, &em->flags));
-       /*
-        * We cannot reuse em_new here but have to create a new one, as
-        * unpin_extent_cache() expects the start of the extent map to be the
-        * logical offset of the file, which does not hold true anymore after
-        * splitting.
-        */
-       em_new = create_io_em(inode, em->start + pre, len,
-                             em->start + pre, em->block_start + pre, len,
-                             len, len, BTRFS_COMPRESS_NONE,
-                             BTRFS_ORDERED_REGULAR);
-       if (IS_ERR(em_new)) {
-               ret = PTR_ERR(em_new);
-               goto out;
-       }
-       free_extent_map(em_new);
+       ret = split_zoned_em(inode, file_offset, file_len, pre, post);
 
 out:
-       free_extent_map(em);
        btrfs_put_ordered_extent(ordered);
 
        return errno_to_blk_status(ret);
index 5031823..14b9fdc 100644 (file)
@@ -254,23 +254,21 @@ static inline int extwriter_counter_read(struct btrfs_transaction *trans)
 }
 
 /*
- * To be called after all the new block groups attached to the transaction
- * handle have been created (btrfs_create_pending_block_groups()).
+ * To be called after doing the chunk btree updates right after allocating a new
+ * chunk (after btrfs_chunk_alloc_add_chunk_item() is called), when removing a
+ * chunk after all chunk btree updates and after finishing the second phase of
+ * chunk allocation (btrfs_create_pending_block_groups()) in case some block
+ * group had its chunk item insertion delayed to the second phase.
  */
 void btrfs_trans_release_chunk_metadata(struct btrfs_trans_handle *trans)
 {
        struct btrfs_fs_info *fs_info = trans->fs_info;
-       struct btrfs_transaction *cur_trans = trans->transaction;
 
        if (!trans->chunk_bytes_reserved)
                return;
 
-       WARN_ON_ONCE(!list_empty(&trans->new_bgs));
-
        btrfs_block_rsv_release(fs_info, &fs_info->chunk_block_rsv,
                                trans->chunk_bytes_reserved, NULL);
-       atomic64_sub(trans->chunk_bytes_reserved, &cur_trans->chunk_bytes_reserved);
-       cond_wake_up(&cur_trans->chunk_reserve_wait);
        trans->chunk_bytes_reserved = 0;
 }
 
@@ -386,8 +384,6 @@ loop:
        spin_lock_init(&cur_trans->dropped_roots_lock);
        INIT_LIST_HEAD(&cur_trans->releasing_ebs);
        spin_lock_init(&cur_trans->releasing_ebs_lock);
-       atomic64_set(&cur_trans->chunk_bytes_reserved, 0);
-       init_waitqueue_head(&cur_trans->chunk_reserve_wait);
        list_add_tail(&cur_trans->list, &fs_info->trans_list);
        extent_io_tree_init(fs_info, &cur_trans->dirty_pages,
                        IO_TREE_TRANS_DIRTY_PAGES, fs_info->btree_inode);
@@ -701,7 +697,6 @@ again:
        h->fs_info = root->fs_info;
 
        h->type = type;
-       h->can_flush_pending_bgs = true;
        INIT_LIST_HEAD(&h->new_bgs);
 
        smp_mb();
index 07d7602..ba45065 100644 (file)
@@ -96,13 +96,6 @@ struct btrfs_transaction {
 
        spinlock_t releasing_ebs_lock;
        struct list_head releasing_ebs;
-
-       /*
-        * The number of bytes currently reserved, by all transaction handles
-        * attached to this transaction, for metadata extents of the chunk tree.
-        */
-       atomic64_t chunk_bytes_reserved;
-       wait_queue_head_t chunk_reserve_wait;
 };
 
 #define __TRANS_FREEZABLE      (1U << 0)
@@ -139,7 +132,7 @@ struct btrfs_trans_handle {
        short aborted;
        bool adding_csums;
        bool allocating_chunk;
-       bool can_flush_pending_bgs;
+       bool removing_chunk;
        bool reloc_reserved;
        bool in_fsync;
        struct btrfs_root *root;
index cab451d..dc6eb08 100644 (file)
@@ -3173,7 +3173,7 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans,
                if (!log_root_tree->node) {
                        ret = btrfs_alloc_log_tree_node(trans, log_root_tree);
                        if (ret) {
-                               mutex_unlock(&fs_info->tree_log_mutex);
+                               mutex_unlock(&fs_info->tree_root->log_mutex);
                                goto out;
                        }
                }
index 807502c..1e4d43f 100644 (file)
@@ -1745,19 +1745,14 @@ again:
                extent = btrfs_item_ptr(leaf, path->slots[0],
                                        struct btrfs_dev_extent);
        } else {
-               btrfs_handle_fs_error(fs_info, ret, "Slot search failed");
                goto out;
        }
 
        *dev_extent_len = btrfs_dev_extent_length(leaf, extent);
 
        ret = btrfs_del_item(trans, root, path);
-       if (ret) {
-               btrfs_handle_fs_error(fs_info, ret,
-                                     "Failed to remove dev extent item");
-       } else {
+       if (ret == 0)
                set_bit(BTRFS_TRANS_HAVE_FREE_BGS, &trans->transaction->flags);
-       }
 out:
        btrfs_free_path(path);
        return ret;
@@ -2942,7 +2937,7 @@ static int btrfs_del_sys_chunk(struct btrfs_fs_info *fs_info, u64 chunk_offset)
        u32 cur;
        struct btrfs_key key;
 
-       mutex_lock(&fs_info->chunk_mutex);
+       lockdep_assert_held(&fs_info->chunk_mutex);
        array_size = btrfs_super_sys_array_size(super_copy);
 
        ptr = super_copy->sys_chunk_array;
@@ -2972,7 +2967,6 @@ static int btrfs_del_sys_chunk(struct btrfs_fs_info *fs_info, u64 chunk_offset)
                        cur += len;
                }
        }
-       mutex_unlock(&fs_info->chunk_mutex);
        return ret;
 }
 
@@ -3012,6 +3006,29 @@ struct extent_map *btrfs_get_chunk_map(struct btrfs_fs_info *fs_info,
        return em;
 }
 
+static int remove_chunk_item(struct btrfs_trans_handle *trans,
+                            struct map_lookup *map, u64 chunk_offset)
+{
+       int i;
+
+       /*
+        * Removing chunk items and updating the device items in the chunks btree
+        * requires holding the chunk_mutex.
+        * See the comment at btrfs_chunk_alloc() for the details.
+        */
+       lockdep_assert_held(&trans->fs_info->chunk_mutex);
+
+       for (i = 0; i < map->num_stripes; i++) {
+               int ret;
+
+               ret = btrfs_update_device(trans, map->stripes[i].dev);
+               if (ret)
+                       return ret;
+       }
+
+       return btrfs_free_chunk(trans, chunk_offset);
+}
+
 int btrfs_remove_chunk(struct btrfs_trans_handle *trans, u64 chunk_offset)
 {
        struct btrfs_fs_info *fs_info = trans->fs_info;
@@ -3032,14 +3049,16 @@ int btrfs_remove_chunk(struct btrfs_trans_handle *trans, u64 chunk_offset)
                return PTR_ERR(em);
        }
        map = em->map_lookup;
-       mutex_lock(&fs_info->chunk_mutex);
-       check_system_chunk(trans, map->type);
-       mutex_unlock(&fs_info->chunk_mutex);
 
        /*
-        * Take the device list mutex to prevent races with the final phase of
-        * a device replace operation that replaces the device object associated
-        * with map stripes (dev-replace.c:btrfs_dev_replace_finishing()).
+        * First delete the device extent items from the devices btree.
+        * We take the device_list_mutex to avoid racing with the finishing phase
+        * of a device replace operation. See the comment below before acquiring
+        * fs_info->chunk_mutex. Note that here we do not acquire the chunk_mutex
+        * because that can result in a deadlock when deleting the device extent
+        * items from the devices btree - COWing an extent buffer from the btree
+        * may result in allocating a new metadata chunk, which would attempt to
+        * lock again fs_info->chunk_mutex.
         */
        mutex_lock(&fs_devices->device_list_mutex);
        for (i = 0; i < map->num_stripes; i++) {
@@ -3061,18 +3080,73 @@ int btrfs_remove_chunk(struct btrfs_trans_handle *trans, u64 chunk_offset)
                        btrfs_clear_space_info_full(fs_info);
                        mutex_unlock(&fs_info->chunk_mutex);
                }
+       }
+       mutex_unlock(&fs_devices->device_list_mutex);
 
-               ret = btrfs_update_device(trans, device);
+       /*
+        * We acquire fs_info->chunk_mutex for 2 reasons:
+        *
+        * 1) Just like with the first phase of the chunk allocation, we must
+        *    reserve system space, do all chunk btree updates and deletions, and
+        *    update the system chunk array in the superblock while holding this
+        *    mutex. This is for similar reasons as explained on the comment at
+        *    the top of btrfs_chunk_alloc();
+        *
+        * 2) Prevent races with the final phase of a device replace operation
+        *    that replaces the device object associated with the map's stripes,
+        *    because the device object's id can change at any time during that
+        *    final phase of the device replace operation
+        *    (dev-replace.c:btrfs_dev_replace_finishing()), so we could grab the
+        *    replaced device and then see it with an ID of
+        *    BTRFS_DEV_REPLACE_DEVID, which would cause a failure when updating
+        *    the device item, which does not exists on the chunk btree.
+        *    The finishing phase of device replace acquires both the
+        *    device_list_mutex and the chunk_mutex, in that order, so we are
+        *    safe by just acquiring the chunk_mutex.
+        */
+       trans->removing_chunk = true;
+       mutex_lock(&fs_info->chunk_mutex);
+
+       check_system_chunk(trans, map->type);
+
+       ret = remove_chunk_item(trans, map, chunk_offset);
+       /*
+        * Normally we should not get -ENOSPC since we reserved space before
+        * through the call to check_system_chunk().
+        *
+        * Despite our system space_info having enough free space, we may not
+        * be able to allocate extents from its block groups, because all have
+        * an incompatible profile, which will force us to allocate a new system
+        * block group with the right profile, or right after we called
+        * check_system_space() above, a scrub turned the only system block group
+        * with enough free space into RO mode.
+        * This is explained with more detail at do_chunk_alloc().
+        *
+        * So if we get -ENOSPC, allocate a new system chunk and retry once.
+        */
+       if (ret == -ENOSPC) {
+               const u64 sys_flags = btrfs_system_alloc_profile(fs_info);
+               struct btrfs_block_group *sys_bg;
+
+               sys_bg = btrfs_alloc_chunk(trans, sys_flags);
+               if (IS_ERR(sys_bg)) {
+                       ret = PTR_ERR(sys_bg);
+                       btrfs_abort_transaction(trans, ret);
+                       goto out;
+               }
+
+               ret = btrfs_chunk_alloc_add_chunk_item(trans, sys_bg);
                if (ret) {
-                       mutex_unlock(&fs_devices->device_list_mutex);
                        btrfs_abort_transaction(trans, ret);
                        goto out;
                }
-       }
-       mutex_unlock(&fs_devices->device_list_mutex);
 
-       ret = btrfs_free_chunk(trans, chunk_offset);
-       if (ret) {
+               ret = remove_chunk_item(trans, map, chunk_offset);
+               if (ret) {
+                       btrfs_abort_transaction(trans, ret);
+                       goto out;
+               }
+       } else if (ret) {
                btrfs_abort_transaction(trans, ret);
                goto out;
        }
@@ -3087,6 +3161,15 @@ int btrfs_remove_chunk(struct btrfs_trans_handle *trans, u64 chunk_offset)
                }
        }
 
+       mutex_unlock(&fs_info->chunk_mutex);
+       trans->removing_chunk = false;
+
+       /*
+        * We are done with chunk btree updates and deletions, so release the
+        * system space we previously reserved (with check_system_chunk()).
+        */
+       btrfs_trans_release_chunk_metadata(trans);
+
        ret = btrfs_remove_block_group(trans, chunk_offset, em);
        if (ret) {
                btrfs_abort_transaction(trans, ret);
@@ -3094,6 +3177,10 @@ int btrfs_remove_chunk(struct btrfs_trans_handle *trans, u64 chunk_offset)
        }
 
 out:
+       if (trans->removing_chunk) {
+               mutex_unlock(&fs_info->chunk_mutex);
+               trans->removing_chunk = false;
+       }
        /* once for us */
        free_extent_map(em);
        return ret;
@@ -4860,13 +4947,12 @@ static int btrfs_add_system_chunk(struct btrfs_fs_info *fs_info,
        u32 array_size;
        u8 *ptr;
 
-       mutex_lock(&fs_info->chunk_mutex);
+       lockdep_assert_held(&fs_info->chunk_mutex);
+
        array_size = btrfs_super_sys_array_size(super_copy);
        if (array_size + item_size + sizeof(disk_key)
-                       > BTRFS_SYSTEM_CHUNK_ARRAY_SIZE) {
-               mutex_unlock(&fs_info->chunk_mutex);
+                       > BTRFS_SYSTEM_CHUNK_ARRAY_SIZE)
                return -EFBIG;
-       }
 
        ptr = super_copy->sys_chunk_array + array_size;
        btrfs_cpu_key_to_disk(&disk_key, key);
@@ -4875,7 +4961,6 @@ static int btrfs_add_system_chunk(struct btrfs_fs_info *fs_info,
        memcpy(ptr, chunk, item_size);
        item_size += sizeof(disk_key);
        btrfs_set_super_sys_array_size(super_copy, array_size + item_size);
-       mutex_unlock(&fs_info->chunk_mutex);
 
        return 0;
 }
@@ -5225,13 +5310,14 @@ static int decide_stripe_size(struct btrfs_fs_devices *fs_devices,
        }
 }
 
-static int create_chunk(struct btrfs_trans_handle *trans,
+static struct btrfs_block_group *create_chunk(struct btrfs_trans_handle *trans,
                        struct alloc_chunk_ctl *ctl,
                        struct btrfs_device_info *devices_info)
 {
        struct btrfs_fs_info *info = trans->fs_info;
        struct map_lookup *map = NULL;
        struct extent_map_tree *em_tree;
+       struct btrfs_block_group *block_group;
        struct extent_map *em;
        u64 start = ctl->start;
        u64 type = ctl->type;
@@ -5241,7 +5327,7 @@ static int create_chunk(struct btrfs_trans_handle *trans,
 
        map = kmalloc(map_lookup_size(ctl->num_stripes), GFP_NOFS);
        if (!map)
-               return -ENOMEM;
+               return ERR_PTR(-ENOMEM);
        map->num_stripes = ctl->num_stripes;
 
        for (i = 0; i < ctl->ndevs; ++i) {
@@ -5263,7 +5349,7 @@ static int create_chunk(struct btrfs_trans_handle *trans,
        em = alloc_extent_map();
        if (!em) {
                kfree(map);
-               return -ENOMEM;
+               return ERR_PTR(-ENOMEM);
        }
        set_bit(EXTENT_FLAG_FS_MAPPING, &em->flags);
        em->map_lookup = map;
@@ -5279,12 +5365,12 @@ static int create_chunk(struct btrfs_trans_handle *trans,
        if (ret) {
                write_unlock(&em_tree->lock);
                free_extent_map(em);
-               return ret;
+               return ERR_PTR(ret);
        }
        write_unlock(&em_tree->lock);
 
-       ret = btrfs_make_block_group(trans, 0, type, start, ctl->chunk_size);
-       if (ret)
+       block_group = btrfs_make_block_group(trans, 0, type, start, ctl->chunk_size);
+       if (IS_ERR(block_group))
                goto error_del_extent;
 
        for (i = 0; i < map->num_stripes; i++) {
@@ -5304,7 +5390,7 @@ static int create_chunk(struct btrfs_trans_handle *trans,
        check_raid56_incompat_flag(info, type);
        check_raid1c34_incompat_flag(info, type);
 
-       return 0;
+       return block_group;
 
 error_del_extent:
        write_lock(&em_tree->lock);
@@ -5316,34 +5402,36 @@ error_del_extent:
        /* One for the tree reference */
        free_extent_map(em);
 
-       return ret;
+       return block_group;
 }
 
-int btrfs_alloc_chunk(struct btrfs_trans_handle *trans, u64 type)
+struct btrfs_block_group *btrfs_alloc_chunk(struct btrfs_trans_handle *trans,
+                                           u64 type)
 {
        struct btrfs_fs_info *info = trans->fs_info;
        struct btrfs_fs_devices *fs_devices = info->fs_devices;
        struct btrfs_device_info *devices_info = NULL;
        struct alloc_chunk_ctl ctl;
+       struct btrfs_block_group *block_group;
        int ret;
 
        lockdep_assert_held(&info->chunk_mutex);
 
        if (!alloc_profile_is_valid(type, 0)) {
                ASSERT(0);
-               return -EINVAL;
+               return ERR_PTR(-EINVAL);
        }
 
        if (list_empty(&fs_devices->alloc_list)) {
                if (btrfs_test_opt(info, ENOSPC_DEBUG))
                        btrfs_debug(info, "%s: no writable device", __func__);
-               return -ENOSPC;
+               return ERR_PTR(-ENOSPC);
        }
 
        if (!(type & BTRFS_BLOCK_GROUP_TYPE_MASK)) {
                btrfs_err(info, "invalid chunk type 0x%llx requested", type);
                ASSERT(0);
-               return -EINVAL;
+               return ERR_PTR(-EINVAL);
        }
 
        ctl.start = find_next_chunk(info);
@@ -5353,46 +5441,43 @@ int btrfs_alloc_chunk(struct btrfs_trans_handle *trans, u64 type)
        devices_info = kcalloc(fs_devices->rw_devices, sizeof(*devices_info),
                               GFP_NOFS);
        if (!devices_info)
-               return -ENOMEM;
+               return ERR_PTR(-ENOMEM);
 
        ret = gather_device_info(fs_devices, &ctl, devices_info);
-       if (ret < 0)
+       if (ret < 0) {
+               block_group = ERR_PTR(ret);
                goto out;
+       }
 
        ret = decide_stripe_size(fs_devices, &ctl, devices_info);
-       if (ret < 0)
+       if (ret < 0) {
+               block_group = ERR_PTR(ret);
                goto out;
+       }
 
-       ret = create_chunk(trans, &ctl, devices_info);
+       block_group = create_chunk(trans, &ctl, devices_info);
 
 out:
        kfree(devices_info);
-       return ret;
+       return block_group;
 }
 
 /*
- * Chunk allocation falls into two parts. The first part does work
- * that makes the new allocated chunk usable, but does not do any operation
- * that modifies the chunk tree. The second part does the work that
- * requires modifying the chunk tree. This division is important for the
- * bootstrap process of adding storage to a seed btrfs.
+ * This function, btrfs_finish_chunk_alloc(), belongs to phase 2.
+ *
+ * See the comment at btrfs_chunk_alloc() for details about the chunk allocation
+ * phases.
  */
 int btrfs_finish_chunk_alloc(struct btrfs_trans_handle *trans,
                             u64 chunk_offset, u64 chunk_size)
 {
        struct btrfs_fs_info *fs_info = trans->fs_info;
-       struct btrfs_root *extent_root = fs_info->extent_root;
-       struct btrfs_root *chunk_root = fs_info->chunk_root;
-       struct btrfs_key key;
        struct btrfs_device *device;
-       struct btrfs_chunk *chunk;
-       struct btrfs_stripe *stripe;
        struct extent_map *em;
        struct map_lookup *map;
-       size_t item_size;
        u64 dev_offset;
        u64 stripe_size;
-       int i = 0;
+       int i;
        int ret = 0;
 
        em = btrfs_get_chunk_map(fs_info, chunk_offset, chunk_size);
@@ -5400,53 +5485,117 @@ int btrfs_finish_chunk_alloc(struct btrfs_trans_handle *trans,
                return PTR_ERR(em);
 
        map = em->map_lookup;
-       item_size = btrfs_chunk_item_size(map->num_stripes);
        stripe_size = em->orig_block_len;
 
-       chunk = kzalloc(item_size, GFP_NOFS);
-       if (!chunk) {
-               ret = -ENOMEM;
-               goto out;
-       }
-
        /*
         * Take the device list mutex to prevent races with the final phase of
         * a device replace operation that replaces the device object associated
         * with the map's stripes, because the device object's id can change
         * at any time during that final phase of the device replace operation
-        * (dev-replace.c:btrfs_dev_replace_finishing()).
+        * (dev-replace.c:btrfs_dev_replace_finishing()), so we could grab the
+        * replaced device and then see it with an ID of BTRFS_DEV_REPLACE_DEVID,
+        * resulting in persisting a device extent item with such ID.
         */
        mutex_lock(&fs_info->fs_devices->device_list_mutex);
        for (i = 0; i < map->num_stripes; i++) {
                device = map->stripes[i].dev;
                dev_offset = map->stripes[i].physical;
 
-               ret = btrfs_update_device(trans, device);
-               if (ret)
-                       break;
                ret = btrfs_alloc_dev_extent(trans, device, chunk_offset,
                                             dev_offset, stripe_size);
                if (ret)
                        break;
        }
-       if (ret) {
-               mutex_unlock(&fs_info->fs_devices->device_list_mutex);
+       mutex_unlock(&fs_info->fs_devices->device_list_mutex);
+
+       free_extent_map(em);
+       return ret;
+}
+
+/*
+ * This function, btrfs_chunk_alloc_add_chunk_item(), typically belongs to the
+ * phase 1 of chunk allocation. It belongs to phase 2 only when allocating system
+ * chunks.
+ *
+ * See the comment at btrfs_chunk_alloc() for details about the chunk allocation
+ * phases.
+ */
+int btrfs_chunk_alloc_add_chunk_item(struct btrfs_trans_handle *trans,
+                                    struct btrfs_block_group *bg)
+{
+       struct btrfs_fs_info *fs_info = trans->fs_info;
+       struct btrfs_root *extent_root = fs_info->extent_root;
+       struct btrfs_root *chunk_root = fs_info->chunk_root;
+       struct btrfs_key key;
+       struct btrfs_chunk *chunk;
+       struct btrfs_stripe *stripe;
+       struct extent_map *em;
+       struct map_lookup *map;
+       size_t item_size;
+       int i;
+       int ret;
+
+       /*
+        * We take the chunk_mutex for 2 reasons:
+        *
+        * 1) Updates and insertions in the chunk btree must be done while holding
+        *    the chunk_mutex, as well as updating the system chunk array in the
+        *    superblock. See the comment on top of btrfs_chunk_alloc() for the
+        *    details;
+        *
+        * 2) To prevent races with the final phase of a device replace operation
+        *    that replaces the device object associated with the map's stripes,
+        *    because the device object's id can change at any time during that
+        *    final phase of the device replace operation
+        *    (dev-replace.c:btrfs_dev_replace_finishing()), so we could grab the
+        *    replaced device and then see it with an ID of BTRFS_DEV_REPLACE_DEVID,
+        *    which would cause a failure when updating the device item, which does
+        *    not exists, or persisting a stripe of the chunk item with such ID.
+        *    Here we can't use the device_list_mutex because our caller already
+        *    has locked the chunk_mutex, and the final phase of device replace
+        *    acquires both mutexes - first the device_list_mutex and then the
+        *    chunk_mutex. Using any of those two mutexes protects us from a
+        *    concurrent device replace.
+        */
+       lockdep_assert_held(&fs_info->chunk_mutex);
+
+       em = btrfs_get_chunk_map(fs_info, bg->start, bg->length);
+       if (IS_ERR(em)) {
+               ret = PTR_ERR(em);
+               btrfs_abort_transaction(trans, ret);
+               return ret;
+       }
+
+       map = em->map_lookup;
+       item_size = btrfs_chunk_item_size(map->num_stripes);
+
+       chunk = kzalloc(item_size, GFP_NOFS);
+       if (!chunk) {
+               ret = -ENOMEM;
+               btrfs_abort_transaction(trans, ret);
                goto out;
        }
 
+       for (i = 0; i < map->num_stripes; i++) {
+               struct btrfs_device *device = map->stripes[i].dev;
+
+               ret = btrfs_update_device(trans, device);
+               if (ret)
+                       goto out;
+       }
+
        stripe = &chunk->stripe;
        for (i = 0; i < map->num_stripes; i++) {
-               device = map->stripes[i].dev;
-               dev_offset = map->stripes[i].physical;
+               struct btrfs_device *device = map->stripes[i].dev;
+               const u64 dev_offset = map->stripes[i].physical;
 
                btrfs_set_stack_stripe_devid(stripe, device->devid);
                btrfs_set_stack_stripe_offset(stripe, dev_offset);
                memcpy(stripe->dev_uuid, device->uuid, BTRFS_UUID_SIZE);
                stripe++;
        }
-       mutex_unlock(&fs_info->fs_devices->device_list_mutex);
 
-       btrfs_set_stack_chunk_length(chunk, chunk_size);
+       btrfs_set_stack_chunk_length(chunk, bg->length);
        btrfs_set_stack_chunk_owner(chunk, extent_root->root_key.objectid);
        btrfs_set_stack_chunk_stripe_len(chunk, map->stripe_len);
        btrfs_set_stack_chunk_type(chunk, map->type);
@@ -5458,15 +5607,18 @@ int btrfs_finish_chunk_alloc(struct btrfs_trans_handle *trans,
 
        key.objectid = BTRFS_FIRST_CHUNK_TREE_OBJECTID;
        key.type = BTRFS_CHUNK_ITEM_KEY;
-       key.offset = chunk_offset;
+       key.offset = bg->start;
 
        ret = btrfs_insert_item(trans, chunk_root, &key, chunk, item_size);
-       if (ret == 0 && map->type & BTRFS_BLOCK_GROUP_SYSTEM) {
-               /*
-                * TODO: Cleanup of inserted chunk root in case of
-                * failure.
-                */
+       if (ret)
+               goto out;
+
+       bg->chunk_item_inserted = 1;
+
+       if (map->type & BTRFS_BLOCK_GROUP_SYSTEM) {
                ret = btrfs_add_system_chunk(fs_info, &key, chunk, item_size);
+               if (ret)
+                       goto out;
        }
 
 out:
@@ -5479,16 +5631,41 @@ static noinline int init_first_rw_device(struct btrfs_trans_handle *trans)
 {
        struct btrfs_fs_info *fs_info = trans->fs_info;
        u64 alloc_profile;
-       int ret;
+       struct btrfs_block_group *meta_bg;
+       struct btrfs_block_group *sys_bg;
+
+       /*
+        * When adding a new device for sprouting, the seed device is read-only
+        * so we must first allocate a metadata and a system chunk. But before
+        * adding the block group items to the extent, device and chunk btrees,
+        * we must first:
+        *
+        * 1) Create both chunks without doing any changes to the btrees, as
+        *    otherwise we would get -ENOSPC since the block groups from the
+        *    seed device are read-only;
+        *
+        * 2) Add the device item for the new sprout device - finishing the setup
+        *    of a new block group requires updating the device item in the chunk
+        *    btree, so it must exist when we attempt to do it. The previous step
+        *    ensures this does not fail with -ENOSPC.
+        *
+        * After that we can add the block group items to their btrees:
+        * update existing device item in the chunk btree, add a new block group
+        * item to the extent btree, add a new chunk item to the chunk btree and
+        * finally add the new device extent items to the devices btree.
+        */
 
        alloc_profile = btrfs_metadata_alloc_profile(fs_info);
-       ret = btrfs_alloc_chunk(trans, alloc_profile);
-       if (ret)
-               return ret;
+       meta_bg = btrfs_alloc_chunk(trans, alloc_profile);
+       if (IS_ERR(meta_bg))
+               return PTR_ERR(meta_bg);
 
        alloc_profile = btrfs_system_alloc_profile(fs_info);
-       ret = btrfs_alloc_chunk(trans, alloc_profile);
-       return ret;
+       sys_bg = btrfs_alloc_chunk(trans, alloc_profile);
+       if (IS_ERR(sys_bg))
+               return PTR_ERR(sys_bg);
+
+       return 0;
 }
 
 static inline int btrfs_chunk_max_errors(struct map_lookup *map)
@@ -7415,10 +7592,18 @@ int btrfs_read_chunk_tree(struct btrfs_fs_info *fs_info)
                        total_dev++;
                } else if (found_key.type == BTRFS_CHUNK_ITEM_KEY) {
                        struct btrfs_chunk *chunk;
+
+                       /*
+                        * We are only called at mount time, so no need to take
+                        * fs_info->chunk_mutex. Plus, to avoid lockdep warnings,
+                        * we always lock first fs_info->chunk_mutex before
+                        * acquiring any locks on the chunk tree. This is a
+                        * requirement for chunk allocation, see the comment on
+                        * top of btrfs_chunk_alloc() for details.
+                        */
+                       ASSERT(!test_bit(BTRFS_FS_OPEN, &fs_info->flags));
                        chunk = btrfs_item_ptr(leaf, slot, struct btrfs_chunk);
-                       mutex_lock(&fs_info->chunk_mutex);
                        ret = read_one_chunk(&found_key, leaf, chunk);
-                       mutex_unlock(&fs_info->chunk_mutex);
                        if (ret)
                                goto error;
                }
index c7fc7ca..55a8ba2 100644 (file)
@@ -450,7 +450,8 @@ int btrfs_get_io_geometry(struct btrfs_fs_info *fs_info, struct extent_map *map,
                          struct btrfs_io_geometry *io_geom);
 int btrfs_read_sys_array(struct btrfs_fs_info *fs_info);
 int btrfs_read_chunk_tree(struct btrfs_fs_info *fs_info);
-int btrfs_alloc_chunk(struct btrfs_trans_handle *trans, u64 type);
+struct btrfs_block_group *btrfs_alloc_chunk(struct btrfs_trans_handle *trans,
+                                           u64 type);
 void btrfs_mapping_tree_free(struct extent_map_tree *tree);
 blk_status_t btrfs_map_bio(struct btrfs_fs_info *fs_info, struct bio *bio,
                           int mirror_num);
@@ -509,6 +510,8 @@ unsigned long btrfs_full_stripe_len(struct btrfs_fs_info *fs_info,
                                    u64 logical);
 int btrfs_finish_chunk_alloc(struct btrfs_trans_handle *trans,
                             u64 chunk_offset, u64 chunk_size);
+int btrfs_chunk_alloc_add_chunk_item(struct btrfs_trans_handle *trans,
+                                    struct btrfs_block_group *bg);
 int btrfs_remove_chunk(struct btrfs_trans_handle *trans, u64 chunk_offset);
 struct extent_map *btrfs_get_chunk_map(struct btrfs_fs_info *fs_info,
                                       u64 logical, u64 length);
index 57f9131..007427b 100644 (file)
@@ -176,7 +176,7 @@ char *cifs_compose_mount_options(const char *sb_mountdata,
                }
        }
 
-       rc = dns_resolve_server_name_to_ip(name, &srvIP);
+       rc = dns_resolve_server_name_to_ip(name, &srvIP, NULL);
        if (rc < 0) {
                cifs_dbg(FYI, "%s: Failed to resolve server part of %s to IP: %d\n",
                         __func__, name, rc);
@@ -211,6 +211,10 @@ char *cifs_compose_mount_options(const char *sb_mountdata,
                else
                        noff = tkn_e - (sb_mountdata + off) + 1;
 
+               if (strncasecmp(sb_mountdata + off, "cruid=", 6) == 0) {
+                       off += noff;
+                       continue;
+               }
                if (strncasecmp(sb_mountdata + off, "unc=", 4) == 0) {
                        off += noff;
                        continue;
index 3c2e117..c0bfc2f 100644 (file)
@@ -75,6 +75,9 @@
 #define SMB_ECHO_INTERVAL_MAX 600
 #define SMB_ECHO_INTERVAL_DEFAULT 60
 
+/* dns resolution interval in seconds */
+#define SMB_DNS_RESOLVE_INTERVAL_DEFAULT 600
+
 /* maximum number of PDUs in one compound */
 #define MAX_COMPOUND 5
 
@@ -646,6 +649,7 @@ struct TCP_Server_Info {
        /* point to the SMBD connection if RDMA is used instead of socket */
        struct smbd_connection *smbd_conn;
        struct delayed_work     echo; /* echo ping workqueue job */
+       struct delayed_work     resolve; /* dns resolution workqueue job */
        char    *smallbuf;      /* pointer to current "small" buffer */
        char    *bigbuf;        /* pointer to current "big" buffer */
        /* Total size of this PDU. Only valid from cifs_demultiplex_thread */
@@ -689,6 +693,9 @@ struct TCP_Server_Info {
        bool use_swn_dstaddr;
        struct sockaddr_storage swn_dstaddr;
 #endif
+#ifdef CONFIG_CIFS_DFS_UPCALL
+       bool is_dfs_conn; /* if a dfs connection */
+#endif
 };
 
 struct cifs_credits {
index 01dc451..1b04d6e 100644 (file)
@@ -78,6 +78,8 @@ static int reconn_set_ipaddr_from_hostname(struct TCP_Server_Info *server)
        int rc;
        int len;
        char *unc, *ipaddr = NULL;
+       time64_t expiry, now;
+       unsigned long ttl = SMB_DNS_RESOLVE_INTERVAL_DEFAULT;
 
        if (!server->hostname)
                return -EINVAL;
@@ -91,13 +93,13 @@ static int reconn_set_ipaddr_from_hostname(struct TCP_Server_Info *server)
        }
        scnprintf(unc, len, "\\\\%s", server->hostname);
 
-       rc = dns_resolve_server_name_to_ip(unc, &ipaddr);
+       rc = dns_resolve_server_name_to_ip(unc, &ipaddr, &expiry);
        kfree(unc);
 
        if (rc < 0) {
                cifs_dbg(FYI, "%s: failed to resolve server part of %s to IP: %d\n",
                         __func__, server->hostname, rc);
-               return rc;
+               goto requeue_resolve;
        }
 
        spin_lock(&cifs_tcp_ses_lock);
@@ -106,7 +108,45 @@ static int reconn_set_ipaddr_from_hostname(struct TCP_Server_Info *server)
        spin_unlock(&cifs_tcp_ses_lock);
        kfree(ipaddr);
 
-       return !rc ? -1 : 0;
+       /* rc == 1 means success here */
+       if (rc) {
+               now = ktime_get_real_seconds();
+               if (expiry && expiry > now)
+                       /*
+                        * To make sure we don't use the cached entry, retry 1s
+                        * after expiry.
+                        */
+                       ttl = (expiry - now + 1);
+       }
+       rc = !rc ? -1 : 0;
+
+requeue_resolve:
+       cifs_dbg(FYI, "%s: next dns resolution scheduled for %lu seconds in the future\n",
+                __func__, ttl);
+       mod_delayed_work(cifsiod_wq, &server->resolve, (ttl * HZ));
+
+       return rc;
+}
+
+
+static void cifs_resolve_server(struct work_struct *work)
+{
+       int rc;
+       struct TCP_Server_Info *server = container_of(work,
+                                       struct TCP_Server_Info, resolve.work);
+
+       mutex_lock(&server->srv_mutex);
+
+       /*
+        * Resolve the hostname again to make sure that IP address is up-to-date.
+        */
+       rc = reconn_set_ipaddr_from_hostname(server);
+       if (rc) {
+               cifs_dbg(FYI, "%s: failed to resolve hostname: %d\n",
+                               __func__, rc);
+       }
+
+       mutex_unlock(&server->srv_mutex);
 }
 
 #ifdef CONFIG_CIFS_DFS_UPCALL
@@ -680,6 +720,7 @@ static void clean_demultiplex_info(struct TCP_Server_Info *server)
        spin_unlock(&cifs_tcp_ses_lock);
 
        cancel_delayed_work_sync(&server->echo);
+       cancel_delayed_work_sync(&server->resolve);
 
        spin_lock(&GlobalMid_Lock);
        server->tcpStatus = CifsExiting;
@@ -1227,6 +1268,16 @@ cifs_find_tcp_session(struct smb3_fs_context *ctx)
 
        spin_lock(&cifs_tcp_ses_lock);
        list_for_each_entry(server, &cifs_tcp_ses_list, tcp_ses_list) {
+#ifdef CONFIG_CIFS_DFS_UPCALL
+               /*
+                * DFS failover implementation in cifs_reconnect() requires unique tcp sessions for
+                * DFS connections to do failover properly, so avoid sharing them with regular
+                * shares or even links that may connect to same server but having completely
+                * different failover targets.
+                */
+               if (server->is_dfs_conn)
+                       continue;
+#endif
                /*
                 * Skip ses channels since they're only handled in lower layers
                 * (e.g. cifs_send_recv).
@@ -1254,12 +1305,16 @@ cifs_put_tcp_session(struct TCP_Server_Info *server, int from_reconnect)
                return;
        }
 
+       /* srv_count can never go negative */
+       WARN_ON(server->srv_count < 0);
+
        put_net(cifs_net_ns(server));
 
        list_del_init(&server->tcp_ses_list);
        spin_unlock(&cifs_tcp_ses_lock);
 
        cancel_delayed_work_sync(&server->echo);
+       cancel_delayed_work_sync(&server->resolve);
 
        if (from_reconnect)
                /*
@@ -1342,6 +1397,7 @@ cifs_get_tcp_session(struct smb3_fs_context *ctx)
        INIT_LIST_HEAD(&tcp_ses->tcp_ses_list);
        INIT_LIST_HEAD(&tcp_ses->smb_ses_list);
        INIT_DELAYED_WORK(&tcp_ses->echo, cifs_echo_request);
+       INIT_DELAYED_WORK(&tcp_ses->resolve, cifs_resolve_server);
        INIT_DELAYED_WORK(&tcp_ses->reconnect, smb2_reconnect_server);
        mutex_init(&tcp_ses->reconnect_mutex);
        memcpy(&tcp_ses->srcaddr, &ctx->srcaddr,
@@ -1427,6 +1483,12 @@ smbd_connected:
        /* queue echo request delayed work */
        queue_delayed_work(cifsiod_wq, &tcp_ses->echo, tcp_ses->echo_interval);
 
+       /* queue dns resolution delayed work */
+       cifs_dbg(FYI, "%s: next dns resolution scheduled for %d seconds in the future\n",
+                __func__, SMB_DNS_RESOLVE_INTERVAL_DEFAULT);
+
+       queue_delayed_work(cifsiod_wq, &tcp_ses->resolve, (SMB_DNS_RESOLVE_INTERVAL_DEFAULT * HZ));
+
        return tcp_ses;
 
 out_err_crypto_release:
@@ -1605,6 +1667,9 @@ void cifs_put_smb_ses(struct cifs_ses *ses)
        }
        spin_unlock(&cifs_tcp_ses_lock);
 
+       /* ses_count can never go negative */
+       WARN_ON(ses->ses_count < 0);
+
        spin_lock(&GlobalMid_Lock);
        if (ses->status == CifsGood)
                ses->status = CifsExiting;
@@ -1972,6 +2037,9 @@ cifs_put_tcon(struct cifs_tcon *tcon)
                return;
        }
 
+       /* tc_count can never go negative */
+       WARN_ON(tcon->tc_count < 0);
+
        if (tcon->use_witness) {
                int rc;
 
@@ -2910,6 +2978,23 @@ static int mount_setup_tlink(struct cifs_sb_info *cifs_sb, struct cifs_ses *ses,
 }
 
 #ifdef CONFIG_CIFS_DFS_UPCALL
+static int mount_get_dfs_conns(struct smb3_fs_context *ctx, struct cifs_sb_info *cifs_sb,
+                              unsigned int *xid, struct TCP_Server_Info **nserver,
+                              struct cifs_ses **nses, struct cifs_tcon **ntcon)
+{
+       int rc;
+
+       ctx->nosharesock = true;
+       rc = mount_get_conns(ctx, cifs_sb, xid, nserver, nses, ntcon);
+       if (*nserver) {
+               cifs_dbg(FYI, "%s: marking tcp session as a dfs connection\n", __func__);
+               spin_lock(&cifs_tcp_ses_lock);
+               (*nserver)->is_dfs_conn = true;
+               spin_unlock(&cifs_tcp_ses_lock);
+       }
+       return rc;
+}
+
 /*
  * cifs_build_path_to_root returns full path to root when we do not have an
  * existing connection (tcon)
@@ -3105,7 +3190,7 @@ static int do_dfs_failover(const char *path, const char *full_path, struct cifs_
                         tmp_ctx.prepath);
 
                mount_put_conns(cifs_sb, *xid, *server, *ses, *tcon);
-               rc = mount_get_conns(&tmp_ctx, cifs_sb, xid, server, ses, tcon);
+               rc = mount_get_dfs_conns(&tmp_ctx, cifs_sb, xid, server, ses, tcon);
                if (!rc || (*server && *ses)) {
                        /*
                         * We were able to connect to new target server. Update current context with
@@ -3404,7 +3489,12 @@ int cifs_mount(struct cifs_sb_info *cifs_sb, struct smb3_fs_context *ctx)
                        goto error;
        }
 
-       ctx->nosharesock = true;
+       mount_put_conns(cifs_sb, xid, server, ses, tcon);
+       /*
+        * Ignore error check here because we may failover to other targets from cached a
+        * referral.
+        */
+       (void)mount_get_dfs_conns(ctx, cifs_sb, &xid, &server, &ses, &tcon);
 
        /* Get path of DFS root */
        ref_path = build_unc_path_to_root(ctx, cifs_sb, false);
@@ -3433,7 +3523,7 @@ int cifs_mount(struct cifs_sb_info *cifs_sb, struct smb3_fs_context *ctx)
                /* Connect to new DFS target only if we were redirected */
                if (oldmnt != cifs_sb->ctx->mount_options) {
                        mount_put_conns(cifs_sb, xid, server, ses, tcon);
-                       rc = mount_get_conns(ctx, cifs_sb, &xid, &server, &ses, &tcon);
+                       rc = mount_get_dfs_conns(ctx, cifs_sb, &xid, &server, &ses, &tcon);
                }
                if (rc && !server && !ses) {
                        /* Failed to connect. Try to connect to other targets in the referral. */
@@ -3459,7 +3549,7 @@ int cifs_mount(struct cifs_sb_info *cifs_sb, struct smb3_fs_context *ctx)
                        rc = -ELOOP;
        } while (rc == -EREMOTE);
 
-       if (rc || !tcon)
+       if (rc || !tcon || !ses)
                goto error;
 
        kfree(ref_path);
@@ -4095,7 +4185,8 @@ int cifs_tree_connect(const unsigned int xid, struct cifs_tcon *tcon, const stru
        if (!tree)
                return -ENOMEM;
 
-       if (!tcon->dfs_path) {
+       /* If it is not dfs or there was no cached dfs referral, then reconnect to same share */
+       if (!tcon->dfs_path || dfs_cache_noreq_find(tcon->dfs_path + 1, &ref, &tl)) {
                if (tcon->ipc) {
                        scnprintf(tree, MAX_TREE_SIZE, "\\\\%s\\IPC$", server->hostname);
                        rc = ops->tree_connect(xid, tcon->ses, tree, tcon, nlsc);
@@ -4105,9 +4196,6 @@ int cifs_tree_connect(const unsigned int xid, struct cifs_tcon *tcon, const stru
                goto out;
        }
 
-       rc = dfs_cache_noreq_find(tcon->dfs_path + 1, &ref, &tl);
-       if (rc)
-               goto out;
        isroot = ref.server_type == DFS_TYPE_ROOT;
        free_dfs_info_param(&ref);
 
index d15b82d..8c616aa 100644 (file)
@@ -24,6 +24,7 @@
  * dns_resolve_server_name_to_ip - Resolve UNC server name to ip address.
  * @unc: UNC path specifying the server (with '/' as delimiter)
  * @ip_addr: Where to return the IP address.
+ * @expiry: Where to return the expiry time for the dns record.
  *
  * The IP address will be returned in string form, and the caller is
  * responsible for freeing it.
@@ -31,7 +32,7 @@
  * Returns length of result on success, -ve on error.
  */
 int
-dns_resolve_server_name_to_ip(const char *unc, char **ip_addr)
+dns_resolve_server_name_to_ip(const char *unc, char **ip_addr, time64_t *expiry)
 {
        struct sockaddr_storage ss;
        const char *hostname, *sep;
@@ -66,13 +67,14 @@ dns_resolve_server_name_to_ip(const char *unc, char **ip_addr)
 
        /* Perform the upcall */
        rc = dns_query(current->nsproxy->net_ns, NULL, hostname, len,
-                      NULL, ip_addr, NULL, false);
+                      NULL, ip_addr, expiry, false);
        if (rc < 0)
                cifs_dbg(FYI, "%s: unable to resolve: %*.*s\n",
                         __func__, len, len, hostname);
        else
-               cifs_dbg(FYI, "%s: resolved: %*.*s to %s\n",
-                        __func__, len, len, hostname, *ip_addr);
+               cifs_dbg(FYI, "%s: resolved: %*.*s to %s expiry %llu\n",
+                        __func__, len, len, hostname, *ip_addr,
+                        expiry ? (*expiry) : 0);
        return rc;
 
 name_is_IP_address:
index 5be060b..9fa2807 100644 (file)
@@ -12,7 +12,7 @@
 #define _DNS_RESOLVE_H
 
 #ifdef __KERNEL__
-extern int dns_resolve_server_name_to_ip(const char *unc, char **ip_addr);
+extern int dns_resolve_server_name_to_ip(const char *unc, char **ip_addr, time64_t *expiry);
 #endif /* KERNEL */
 
 #endif /* _DNS_RESOLVE_H */
index 184138b..844abeb 100644 (file)
@@ -1187,7 +1187,7 @@ int match_target_ip(struct TCP_Server_Info *server,
 
        cifs_dbg(FYI, "%s: target name: %s\n", __func__, target + 2);
 
-       rc = dns_resolve_server_name_to_ip(target, &tip);
+       rc = dns_resolve_server_name_to_ip(target, &tip, NULL);
        if (rc < 0)
                goto out;
 
index e4c8f60..ba3c58e 100644 (file)
@@ -557,8 +557,8 @@ parse_server_interfaces(struct network_interface_info_ioctl_rsp *buf,
        p = buf;
        while (bytes_left >= sizeof(*p)) {
                info->speed = le64_to_cpu(p->LinkSpeed);
-               info->rdma_capable = le32_to_cpu(p->Capability & RDMA_CAPABLE);
-               info->rss_capable = le32_to_cpu(p->Capability & RSS_CAPABLE);
+               info->rdma_capable = le32_to_cpu(p->Capability & RDMA_CAPABLE) ? 1 : 0;
+               info->rss_capable = le32_to_cpu(p->Capability & RSS_CAPABLE) ? 1 : 0;
 
                cifs_dbg(FYI, "%s: adding iface %zu\n", __func__, *iface_count);
                cifs_dbg(FYI, "%s: speed %zu bps\n", __func__, info->speed);
@@ -2910,6 +2910,8 @@ smb2_get_dfs_refer(const unsigned int xid, struct cifs_ses *ses,
                /* ipc tcons are not refcounted */
                spin_lock(&cifs_tcp_ses_lock);
                tcon->tc_count--;
+               /* tc_count can never go negative */
+               WARN_ON(tcon->tc_count < 0);
                spin_unlock(&cifs_tcp_ses_lock);
        }
        kfree(utf16_path);
index 4b27cb9..e9cac79 100644 (file)
@@ -394,6 +394,7 @@ struct smb2_compression_capabilities_context {
        __u16   Padding;
        __u32   Flags;
        __le16  CompressionAlgorithms[3];
+       __u16   Pad;  /* Some servers require pad to DataLen multiple of 8 */
        /* Check if pad needed */
 } __packed;
 
index 2f63bf3..5a0be99 100644 (file)
@@ -91,7 +91,10 @@ static ssize_t configfs_read_iter(struct kiocb *iocb, struct iov_iter *to)
        }
        pr_debug("%s: count = %zd, pos = %lld, buf = %s\n",
                 __func__, iov_iter_count(to), iocb->ki_pos, buffer->page);
-       retval = copy_to_iter(buffer->page, buffer->count, to);
+       if (iocb->ki_pos >= buffer->count)
+               goto out;
+       retval = copy_to_iter(buffer->page + iocb->ki_pos,
+                             buffer->count - iocb->ki_pos, to);
        iocb->ki_pos += retval;
        if (retval == 0)
                retval = -EFAULT;
@@ -162,7 +165,10 @@ static ssize_t configfs_bin_read_iter(struct kiocb *iocb, struct iov_iter *to)
                buffer->needs_read_fill = 0;
        }
 
-       retval = copy_to_iter(buffer->bin_buffer, buffer->bin_buffer_size, to);
+       if (iocb->ki_pos >= buffer->bin_buffer_size)
+               goto out;
+       retval = copy_to_iter(buffer->bin_buffer + iocb->ki_pos,
+                             buffer->bin_buffer_size - iocb->ki_pos, to);
        iocb->ki_pos += retval;
        if (retval == 0)
                retval = -EFAULT;
@@ -171,21 +177,28 @@ out:
        return retval;
 }
 
-static int fill_write_buffer(struct configfs_buffer *buffer,
+/* Fill [buffer, buffer + pos) with data coming from @from. */
+static int fill_write_buffer(struct configfs_buffer *buffer, loff_t pos,
                             struct iov_iter *from)
 {
+       loff_t to_copy;
        int copied;
+       u8 *to;
 
        if (!buffer->page)
                buffer->page = (char *)__get_free_pages(GFP_KERNEL, 0);
        if (!buffer->page)
                return -ENOMEM;
 
-       copied = copy_from_iter(buffer->page, SIMPLE_ATTR_SIZE - 1, from);
+       to_copy = SIMPLE_ATTR_SIZE - 1 - pos;
+       if (to_copy <= 0)
+               return 0;
+       to = buffer->page + pos;
+       copied = copy_from_iter(to, to_copy, from);
        buffer->needs_read_fill = 1;
        /* if buf is assumed to contain a string, terminate it by \0,
         * so e.g. sscanf() can scan the string easily */
-       buffer->page[copied] = 0;
+       to[copied] = 0;
        return copied ? : -EFAULT;
 }
 
@@ -217,7 +230,7 @@ static ssize_t configfs_write_iter(struct kiocb *iocb, struct iov_iter *from)
        ssize_t len;
 
        mutex_lock(&buffer->mutex);
-       len = fill_write_buffer(buffer, from);
+       len = fill_write_buffer(buffer, iocb->ki_pos, from);
        if (len > 0)
                len = flush_write_buffer(file, buffer, len);
        if (len > 0)
@@ -272,7 +285,9 @@ static ssize_t configfs_bin_write_iter(struct kiocb *iocb,
                buffer->bin_buffer_size = end_offset;
        }
 
-       len = copy_from_iter(buffer->bin_buffer, buffer->bin_buffer_size, from);
+       len = copy_from_iter(buffer->bin_buffer + iocb->ki_pos,
+                            buffer->bin_buffer_size - iocb->ki_pos, from);
+       iocb->ki_pos += len;
 out:
        mutex_unlock(&buffer->mutex);
        return len ? : -EFAULT;
index dfc72f1..f946bec 100644 (file)
@@ -369,8 +369,8 @@ static long do_fcntl(int fd, unsigned int cmd, unsigned long arg,
        /* 32-bit arches must use fcntl64() */
        case F_OFD_SETLK:
        case F_OFD_SETLKW:
-#endif
                fallthrough;
+#endif
        case F_SETLK:
        case F_SETLKW:
                if (copy_from_user(&flock, argp, sizeof(flock)))
index 2834d1a..de1985e 100644 (file)
@@ -79,6 +79,35 @@ static int vfs_parse_sb_flag(struct fs_context *fc, const char *key)
        return -ENOPARAM;
 }
 
+/**
+ * vfs_parse_fs_param_source - Handle setting "source" via parameter
+ * @fc: The filesystem context to modify
+ * @param: The parameter
+ *
+ * This is a simple helper for filesystems to verify that the "source" they
+ * accept is sane.
+ *
+ * Returns 0 on success, -ENOPARAM if this is not  "source" parameter, and
+ * -EINVAL otherwise. In the event of failure, supplementary error information
+ *  is logged.
+ */
+int vfs_parse_fs_param_source(struct fs_context *fc, struct fs_parameter *param)
+{
+       if (strcmp(param->key, "source") != 0)
+               return -ENOPARAM;
+
+       if (param->type != fs_value_is_string)
+               return invalf(fc, "Non-string source");
+
+       if (fc->source)
+               return invalf(fc, "Multiple sources");
+
+       fc->source = param->string;
+       param->string = NULL;
+       return 0;
+}
+EXPORT_SYMBOL(vfs_parse_fs_param_source);
+
 /**
  * vfs_parse_fs_param - Add a single parameter to a superblock config
  * @fc: The filesystem context to modify
@@ -122,15 +151,9 @@ int vfs_parse_fs_param(struct fs_context *fc, struct fs_parameter *param)
        /* If the filesystem doesn't take any arguments, give it the
         * default handling of source.
         */
-       if (strcmp(param->key, "source") == 0) {
-               if (param->type != fs_value_is_string)
-                       return invalf(fc, "VFS: Non-string source");
-               if (fc->source)
-                       return invalf(fc, "VFS: Multiple sources");
-               fc->source = param->string;
-               param->string = NULL;
-               return 0;
-       }
+       ret = vfs_parse_fs_param_source(fc, param);
+       if (ret != -ENOPARAM)
+               return ret;
 
        return invalf(fc, "%s: Unknown parameter '%s'",
                      fc->fs_type->name, param->key);
@@ -504,16 +527,11 @@ static int legacy_parse_param(struct fs_context *fc, struct fs_parameter *param)
        struct legacy_fs_context *ctx = fc->fs_private;
        unsigned int size = ctx->data_size;
        size_t len = 0;
+       int ret;
 
-       if (strcmp(param->key, "source") == 0) {
-               if (param->type != fs_value_is_string)
-                       return invalf(fc, "VFS: Legacy: Non-string source");
-               if (fc->source)
-                       return invalf(fc, "VFS: Legacy: Multiple sources");
-               fc->source = param->string;
-               param->string = NULL;
-               return 0;
-       }
+       ret = vfs_parse_fs_param_source(fc, param);
+       if (ret != -ENOPARAM)
+               return ret;
 
        if (ctx->param_type == LEGACY_FS_MONOLITHIC_PARAMS)
                return invalf(fc, "VFS: Legacy: Can't mix monolithic and individual options");
index 4af318f..ef9498a 100644 (file)
@@ -25,7 +25,19 @@ int hfs_find_init(struct hfs_btree *tree, struct hfs_find_data *fd)
        fd->key = ptr + tree->max_key_len + 2;
        hfs_dbg(BNODE_REFS, "find_init: %d (%p)\n",
                tree->cnid, __builtin_return_address(0));
-       mutex_lock(&tree->tree_lock);
+       switch (tree->cnid) {
+       case HFS_CAT_CNID:
+               mutex_lock_nested(&tree->tree_lock, CATALOG_BTREE_MUTEX);
+               break;
+       case HFS_EXT_CNID:
+               mutex_lock_nested(&tree->tree_lock, EXTENTS_BTREE_MUTEX);
+               break;
+       case HFS_ATTR_CNID:
+               mutex_lock_nested(&tree->tree_lock, ATTR_BTREE_MUTEX);
+               break;
+       default:
+               return -EINVAL;
+       }
        return 0;
 }
 
index b63a4df..c0a73a6 100644 (file)
 
 #include "btree.h"
 
-void hfs_bnode_read(struct hfs_bnode *node, void *buf,
-               int off, int len)
+void hfs_bnode_read(struct hfs_bnode *node, void *buf, int off, int len)
 {
        struct page *page;
+       int pagenum;
+       int bytes_read;
+       int bytes_to_read;
+       void *vaddr;
 
        off += node->page_offset;
-       page = node->page[0];
+       pagenum = off >> PAGE_SHIFT;
+       off &= ~PAGE_MASK; /* compute page offset for the first page */
 
-       memcpy(buf, kmap(page) + off, len);
-       kunmap(page);
+       for (bytes_read = 0; bytes_read < len; bytes_read += bytes_to_read) {
+               if (pagenum >= node->tree->pages_per_bnode)
+                       break;
+               page = node->page[pagenum];
+               bytes_to_read = min_t(int, len - bytes_read, PAGE_SIZE - off);
+
+               vaddr = kmap_atomic(page);
+               memcpy(buf + bytes_read, vaddr + off, bytes_to_read);
+               kunmap_atomic(vaddr);
+
+               pagenum++;
+               off = 0; /* page offset only applies to the first page */
+       }
 }
 
 u16 hfs_bnode_read_u16(struct hfs_bnode *node, int off)
index 4ba45ca..0e6baee 100644 (file)
@@ -13,6 +13,13 @@ typedef int (*btree_keycmp)(const btree_key *, const btree_key *);
 
 #define NODE_HASH_SIZE  256
 
+/* B-tree mutex nested subclasses */
+enum hfs_btree_mutex_classes {
+       CATALOG_BTREE_MUTEX,
+       EXTENTS_BTREE_MUTEX,
+       ATTR_BTREE_MUTEX,
+};
+
 /* A HFS BTree held in memory */
 struct hfs_btree {
        struct super_block *sb;
index 44d07c9..12d9bae 100644 (file)
@@ -420,14 +420,12 @@ static int hfs_fill_super(struct super_block *sb, void *data, int silent)
        if (!res) {
                if (fd.entrylength > sizeof(rec) || fd.entrylength < 0) {
                        res =  -EIO;
-                       goto bail;
+                       goto bail_hfs_find;
                }
                hfs_bnode_read(fd.bnode, &rec, fd.entryoffset, fd.entrylength);
        }
-       if (res) {
-               hfs_find_exit(&fd);
-               goto bail_no_root;
-       }
+       if (res)
+               goto bail_hfs_find;
        res = -EINVAL;
        root_inode = hfs_iget(sb, &fd.search_key->cat, &rec);
        hfs_find_exit(&fd);
@@ -443,6 +441,8 @@ static int hfs_fill_super(struct super_block *sb, void *data, int silent)
        /* everything's okay */
        return 0;
 
+bail_hfs_find:
+       hfs_find_exit(&fd);
 bail_no_root:
        pr_err("get root inode failed\n");
 bail:
index d94fb58..0cac361 100644 (file)
@@ -2016,7 +2016,7 @@ static void io_req_task_submit(struct io_kiocb *req)
 
        /* ctx stays valid until unlock, even if we drop all ours ctx->refs */
        mutex_lock(&ctx->uring_lock);
-       if (!(current->flags & PF_EXITING) && !current->in_execve)
+       if (!(req->task->flags & PF_EXITING) && !req->task->in_execve)
                __io_queue_sqe(req);
        else
                io_req_complete_failed(req, -EFAULT);
@@ -6019,11 +6019,13 @@ static bool io_drain_req(struct io_kiocb *req)
 
        ret = io_req_prep_async(req);
        if (ret)
-               return ret;
+               goto fail;
        io_prep_async_link(req);
        de = kmalloc(sizeof(*de), GFP_KERNEL);
        if (!de) {
-               io_req_complete_failed(req, -ENOMEM);
+               ret = -ENOMEM;
+fail:
+               io_req_complete_failed(req, ret);
                return true;
        }
 
index 41da4f1..87ccb34 100644 (file)
@@ -215,6 +215,7 @@ iomap_read_inline_data(struct inode *inode, struct page *page,
        if (PageUptodate(page))
                return;
 
+       BUG_ON(page_has_private(page));
        BUG_ON(page->index);
        BUG_ON(size > PAGE_SIZE - offset_in_page(iomap->inline_data));
 
@@ -239,7 +240,7 @@ iomap_readpage_actor(struct inode *inode, loff_t pos, loff_t length, void *data,
 {
        struct iomap_readpage_ctx *ctx = data;
        struct page *page = ctx->cur_page;
-       struct iomap_page *iop = iomap_page_create(inode, page);
+       struct iomap_page *iop;
        bool same_page = false, is_contig = false;
        loff_t orig_pos = pos;
        unsigned poff, plen;
@@ -252,6 +253,7 @@ iomap_readpage_actor(struct inode *inode, loff_t pos, loff_t length, void *data,
        }
 
        /* zero post-eof blocks as the page may be mapped */
+       iop = iomap_page_create(inode, page);
        iomap_adjust_read_range(inode, iop, &pos, length, &poff, &plen);
        if (plen == 0)
                goto done;
@@ -967,7 +969,6 @@ iomap_page_mkwrite_actor(struct inode *inode, loff_t pos, loff_t length,
                block_commit_write(page, 0, length);
        } else {
                WARN_ON_ONCE(!PageUptodate(page));
-               iomap_page_create(inode, page);
                set_page_dirty(page);
        }
 
@@ -1304,14 +1305,13 @@ iomap_writepage_map(struct iomap_writepage_ctx *wpc,
                struct writeback_control *wbc, struct inode *inode,
                struct page *page, u64 end_offset)
 {
-       struct iomap_page *iop = to_iomap_page(page);
+       struct iomap_page *iop = iomap_page_create(inode, page);
        struct iomap_ioend *ioend, *next;
        unsigned len = i_blocksize(inode);
        u64 file_offset; /* file offset of page */
        int error = 0, count = 0, i;
        LIST_HEAD(submit_list);
 
-       WARN_ON_ONCE(i_blocks_per_page(inode, page) > 1 && !iop);
        WARN_ON_ONCE(iop && atomic_read(&iop->write_bytes_pending) != 0);
 
        /*
index dab1b02..ce6fb81 100644 (file)
@@ -35,23 +35,20 @@ loff_t
 iomap_seek_hole(struct inode *inode, loff_t offset, const struct iomap_ops *ops)
 {
        loff_t size = i_size_read(inode);
-       loff_t length = size - offset;
        loff_t ret;
 
        /* Nothing to be found before or beyond the end of the file. */
        if (offset < 0 || offset >= size)
                return -ENXIO;
 
-       while (length > 0) {
-               ret = iomap_apply(inode, offset, length, IOMAP_REPORT, ops,
-                                 &offset, iomap_seek_hole_actor);
+       while (offset < size) {
+               ret = iomap_apply(inode, offset, size - offset, IOMAP_REPORT,
+                                 ops, &offset, iomap_seek_hole_actor);
                if (ret < 0)
                        return ret;
                if (ret == 0)
                        break;
-
                offset += ret;
-               length -= ret;
        }
 
        return offset;
@@ -83,27 +80,23 @@ loff_t
 iomap_seek_data(struct inode *inode, loff_t offset, const struct iomap_ops *ops)
 {
        loff_t size = i_size_read(inode);
-       loff_t length = size - offset;
        loff_t ret;
 
        /* Nothing to be found before or beyond the end of the file. */
        if (offset < 0 || offset >= size)
                return -ENXIO;
 
-       while (length > 0) {
-               ret = iomap_apply(inode, offset, length, IOMAP_REPORT, ops,
-                                 &offset, iomap_seek_data_actor);
+       while (offset < size) {
+               ret = iomap_apply(inode, offset, size - offset, IOMAP_REPORT,
+                                 ops, &offset, iomap_seek_data_actor);
                if (ret < 0)
                        return ret;
                if (ret == 0)
-                       break;
-
+                       return offset;
                offset += ret;
-               length -= ret;
        }
 
-       if (length <= 0)
-               return -ENXIO;
-       return offset;
+       /* We've reached the end of the file without finding data */
+       return -ENXIO;
 }
 EXPORT_SYMBOL_GPL(iomap_seek_data);
index eac6788..c4769a9 100644 (file)
@@ -253,7 +253,7 @@ static int vboxsf_dir_instantiate(struct inode *parent, struct dentry *dentry,
 }
 
 static int vboxsf_dir_create(struct inode *parent, struct dentry *dentry,
-                            umode_t mode, int is_dir)
+                            umode_t mode, bool is_dir, bool excl, u64 *handle_ret)
 {
        struct vboxsf_inode *sf_parent_i = VBOXSF_I(parent);
        struct vboxsf_sbi *sbi = VBOXSF_SBI(parent->i_sb);
@@ -261,10 +261,12 @@ static int vboxsf_dir_create(struct inode *parent, struct dentry *dentry,
        int err;
 
        params.handle = SHFL_HANDLE_NIL;
-       params.create_flags = SHFL_CF_ACT_CREATE_IF_NEW |
-                             SHFL_CF_ACT_FAIL_IF_EXISTS |
-                             SHFL_CF_ACCESS_READWRITE |
-                             (is_dir ? SHFL_CF_DIRECTORY : 0);
+       params.create_flags = SHFL_CF_ACT_CREATE_IF_NEW | SHFL_CF_ACCESS_READWRITE;
+       if (is_dir)
+               params.create_flags |= SHFL_CF_DIRECTORY;
+       if (excl)
+               params.create_flags |= SHFL_CF_ACT_FAIL_IF_EXISTS;
+
        params.info.attr.mode = (mode & 0777) |
                                (is_dir ? SHFL_TYPE_DIRECTORY : SHFL_TYPE_FILE);
        params.info.attr.additional = SHFLFSOBJATTRADD_NOTHING;
@@ -276,30 +278,81 @@ static int vboxsf_dir_create(struct inode *parent, struct dentry *dentry,
        if (params.result != SHFL_FILE_CREATED)
                return -EPERM;
 
-       vboxsf_close(sbi->root, params.handle);
-
        err = vboxsf_dir_instantiate(parent, dentry, &params.info);
        if (err)
-               return err;
+               goto out;
 
        /* parent directory access/change time changed */
        sf_parent_i->force_restat = 1;
 
-       return 0;
+out:
+       if (err == 0 && handle_ret)
+               *handle_ret = params.handle;
+       else
+               vboxsf_close(sbi->root, params.handle);
+
+       return err;
 }
 
 static int vboxsf_dir_mkfile(struct user_namespace *mnt_userns,
                             struct inode *parent, struct dentry *dentry,
                             umode_t mode, bool excl)
 {
-       return vboxsf_dir_create(parent, dentry, mode, 0);
+       return vboxsf_dir_create(parent, dentry, mode, false, excl, NULL);
 }
 
 static int vboxsf_dir_mkdir(struct user_namespace *mnt_userns,
                            struct inode *parent, struct dentry *dentry,
                            umode_t mode)
 {
-       return vboxsf_dir_create(parent, dentry, mode, 1);
+       return vboxsf_dir_create(parent, dentry, mode, true, true, NULL);
+}
+
+static int vboxsf_dir_atomic_open(struct inode *parent, struct dentry *dentry,
+                                 struct file *file, unsigned int flags, umode_t mode)
+{
+       struct vboxsf_sbi *sbi = VBOXSF_SBI(parent->i_sb);
+       struct vboxsf_handle *sf_handle;
+       struct dentry *res = NULL;
+       u64 handle;
+       int err;
+
+       if (d_in_lookup(dentry)) {
+               res = vboxsf_dir_lookup(parent, dentry, 0);
+               if (IS_ERR(res))
+                       return PTR_ERR(res);
+
+               if (res)
+                       dentry = res;
+       }
+
+       /* Only creates */
+       if (!(flags & O_CREAT) || d_really_is_positive(dentry))
+               return finish_no_open(file, res);
+
+       err = vboxsf_dir_create(parent, dentry, mode, false, flags & O_EXCL, &handle);
+       if (err)
+               goto out;
+
+       sf_handle = vboxsf_create_sf_handle(d_inode(dentry), handle, SHFL_CF_ACCESS_READWRITE);
+       if (IS_ERR(sf_handle)) {
+               vboxsf_close(sbi->root, handle);
+               err = PTR_ERR(sf_handle);
+               goto out;
+       }
+
+       err = finish_open(file, dentry, generic_file_open);
+       if (err) {
+               /* This also closes the handle passed to vboxsf_create_sf_handle() */
+               vboxsf_release_sf_handle(d_inode(dentry), sf_handle);
+               goto out;
+       }
+
+       file->private_data = sf_handle;
+       file->f_mode |= FMODE_CREATED;
+out:
+       dput(res);
+       return err;
 }
 
 static int vboxsf_dir_unlink(struct inode *parent, struct dentry *dentry)
@@ -422,6 +475,7 @@ const struct inode_operations vboxsf_dir_iops = {
        .lookup  = vboxsf_dir_lookup,
        .create  = vboxsf_dir_mkfile,
        .mkdir   = vboxsf_dir_mkdir,
+       .atomic_open = vboxsf_dir_atomic_open,
        .rmdir   = vboxsf_dir_unlink,
        .unlink  = vboxsf_dir_unlink,
        .rename  = vboxsf_dir_rename,
index c4ab599..864c2fa 100644 (file)
@@ -20,17 +20,39 @@ struct vboxsf_handle {
        struct list_head head;
 };
 
-static int vboxsf_file_open(struct inode *inode, struct file *file)
+struct vboxsf_handle *vboxsf_create_sf_handle(struct inode *inode,
+                                             u64 handle, u32 access_flags)
 {
        struct vboxsf_inode *sf_i = VBOXSF_I(inode);
-       struct shfl_createparms params = {};
        struct vboxsf_handle *sf_handle;
-       u32 access_flags = 0;
-       int err;
 
        sf_handle = kmalloc(sizeof(*sf_handle), GFP_KERNEL);
        if (!sf_handle)
-               return -ENOMEM;
+               return ERR_PTR(-ENOMEM);
+
+       /* the host may have given us different attr then requested */
+       sf_i->force_restat = 1;
+
+       /* init our handle struct and add it to the inode's handles list */
+       sf_handle->handle = handle;
+       sf_handle->root = VBOXSF_SBI(inode->i_sb)->root;
+       sf_handle->access_flags = access_flags;
+       kref_init(&sf_handle->refcount);
+
+       mutex_lock(&sf_i->handle_list_mutex);
+       list_add(&sf_handle->head, &sf_i->handle_list);
+       mutex_unlock(&sf_i->handle_list_mutex);
+
+       return sf_handle;
+}
+
+static int vboxsf_file_open(struct inode *inode, struct file *file)
+{
+       struct vboxsf_sbi *sbi = VBOXSF_SBI(inode->i_sb);
+       struct shfl_createparms params = {};
+       struct vboxsf_handle *sf_handle;
+       u32 access_flags = 0;
+       int err;
 
        /*
         * We check the value of params.handle afterwards to find out if
@@ -83,23 +105,14 @@ static int vboxsf_file_open(struct inode *inode, struct file *file)
        err = vboxsf_create_at_dentry(file_dentry(file), &params);
        if (err == 0 && params.handle == SHFL_HANDLE_NIL)
                err = (params.result == SHFL_FILE_EXISTS) ? -EEXIST : -ENOENT;
-       if (err) {
-               kfree(sf_handle);
+       if (err)
                return err;
-       }
-
-       /* the host may have given us different attr then requested */
-       sf_i->force_restat = 1;
 
-       /* init our handle struct and add it to the inode's handles list */
-       sf_handle->handle = params.handle;
-       sf_handle->root = VBOXSF_SBI(inode->i_sb)->root;
-       sf_handle->access_flags = access_flags;
-       kref_init(&sf_handle->refcount);
-
-       mutex_lock(&sf_i->handle_list_mutex);
-       list_add(&sf_handle->head, &sf_i->handle_list);
-       mutex_unlock(&sf_i->handle_list_mutex);
+       sf_handle = vboxsf_create_sf_handle(inode, params.handle, access_flags);
+       if (IS_ERR(sf_handle)) {
+               vboxsf_close(sbi->root, params.handle);
+               return PTR_ERR(sf_handle);
+       }
 
        file->private_data = sf_handle;
        return 0;
@@ -114,22 +127,26 @@ static void vboxsf_handle_release(struct kref *refcount)
        kfree(sf_handle);
 }
 
-static int vboxsf_file_release(struct inode *inode, struct file *file)
+void vboxsf_release_sf_handle(struct inode *inode, struct vboxsf_handle *sf_handle)
 {
        struct vboxsf_inode *sf_i = VBOXSF_I(inode);
-       struct vboxsf_handle *sf_handle = file->private_data;
 
+       mutex_lock(&sf_i->handle_list_mutex);
+       list_del(&sf_handle->head);
+       mutex_unlock(&sf_i->handle_list_mutex);
+
+       kref_put(&sf_handle->refcount, vboxsf_handle_release);
+}
+
+static int vboxsf_file_release(struct inode *inode, struct file *file)
+{
        /*
         * When a file is closed on our (the guest) side, we want any subsequent
         * accesses done on the host side to see all changes done from our side.
         */
        filemap_write_and_wait(inode->i_mapping);
 
-       mutex_lock(&sf_i->handle_list_mutex);
-       list_del(&sf_handle->head);
-       mutex_unlock(&sf_i->handle_list_mutex);
-
-       kref_put(&sf_handle->refcount, vboxsf_handle_release);
+       vboxsf_release_sf_handle(inode, file->private_data);
        return 0;
 }
 
index 6a7a9ce..9047bef 100644 (file)
@@ -18,6 +18,8 @@
 #define VBOXSF_SBI(sb) ((struct vboxsf_sbi *)(sb)->s_fs_info)
 #define VBOXSF_I(i)    container_of(i, struct vboxsf_inode, vfs_inode)
 
+struct vboxsf_handle;
+
 struct vboxsf_options {
        unsigned long ttl;
        kuid_t uid;
@@ -80,6 +82,11 @@ extern const struct file_operations vboxsf_reg_fops;
 extern const struct address_space_operations vboxsf_reg_aops;
 extern const struct dentry_operations vboxsf_dentry_ops;
 
+/* from file.c */
+struct vboxsf_handle *vboxsf_create_sf_handle(struct inode *inode,
+                                             u64 handle, u32 access_flags);
+void vboxsf_release_sf_handle(struct inode *inode, struct vboxsf_handle *sf_handle);
+
 /* from utils.c */
 struct inode *vboxsf_new_inode(struct super_block *sb);
 int vboxsf_init_inode(struct vboxsf_sbi *sbi, struct inode *inode,
index 778ec52..ee9ec0c 100644 (file)
@@ -803,6 +803,14 @@ xfs_ag_shrink_space(
 
        args.fsbno = XFS_AGB_TO_FSB(mp, agno, aglen - delta);
 
+       /*
+        * Make sure that the last inode cluster cannot overlap with the new
+        * end of the AG, even if it's sparse.
+        */
+       error = xfs_ialloc_check_shrink(*tpp, agno, agibp, aglen - delta);
+       if (error)
+               return error;
+
        /*
         * Disable perag reservations so it doesn't cause the allocation request
         * to fail. We'll reestablish reservation before we return.
index d9d7d51..191d517 100644 (file)
@@ -483,7 +483,7 @@ xfs_attr_set_iter(
                if (error)
                        return error;
 
-               /* fallthrough */
+               fallthrough;
        case XFS_DAS_RM_LBLK:
                /* Set state in case xfs_attr_rmtval_remove returns -EAGAIN */
                dac->dela_state = XFS_DAS_RM_LBLK;
@@ -496,7 +496,7 @@ xfs_attr_set_iter(
                        return -EAGAIN;
                }
 
-               /* fallthrough */
+               fallthrough;
        case XFS_DAS_RD_LEAF:
                /*
                 * This is the last step for leaf format. Read the block with
@@ -528,7 +528,7 @@ xfs_attr_set_iter(
                                return error;
                }
 
-               /* fallthrough */
+               fallthrough;
        case XFS_DAS_ALLOC_NODE:
                /*
                 * If there was an out-of-line value, allocate the blocks we
@@ -590,7 +590,7 @@ xfs_attr_set_iter(
                if (error)
                        return error;
 
-               /* fallthrough */
+               fallthrough;
        case XFS_DAS_RM_NBLK:
                /* Set state in case xfs_attr_rmtval_remove returns -EAGAIN */
                dac->dela_state = XFS_DAS_RM_NBLK;
@@ -603,7 +603,7 @@ xfs_attr_set_iter(
                        return -EAGAIN;
                }
 
-               /* fallthrough */
+               fallthrough;
        case XFS_DAS_CLR_FLAG:
                /*
                 * The last state for node format. Look up the old attr and
@@ -1406,7 +1406,7 @@ xfs_attr_remove_iter(
                        state = dac->da_state;
                }
 
-               /* fallthrough */
+               fallthrough;
        case XFS_DAS_RMTBLK:
                dac->dela_state = XFS_DAS_RMTBLK;
 
@@ -1441,7 +1441,7 @@ xfs_attr_remove_iter(
                        return -EAGAIN;
                }
 
-               /* fallthrough */
+               fallthrough;
        case XFS_DAS_RM_NAME:
                /*
                 * If we came here fresh from a transaction roll, reattach all
@@ -1469,7 +1469,7 @@ xfs_attr_remove_iter(
                        return -EAGAIN;
                }
 
-               /* fallthrough */
+               fallthrough;
        case XFS_DAS_RM_SHRINK:
                /*
                 * If the result is small enough, push it all into the inode.
index 57d9cb6..aaf8805 100644 (file)
@@ -2928,3 +2928,58 @@ xfs_ialloc_calc_rootino(
 
        return XFS_AGINO_TO_INO(mp, 0, XFS_AGB_TO_AGINO(mp, first_bno));
 }
+
+/*
+ * Ensure there are not sparse inode clusters that cross the new EOAG.
+ *
+ * This is a no-op for non-spinode filesystems since clusters are always fully
+ * allocated and checking the bnobt suffices.  However, a spinode filesystem
+ * could have a record where the upper inodes are free blocks.  If those blocks
+ * were removed from the filesystem, the inode record would extend beyond EOAG,
+ * which will be flagged as corruption.
+ */
+int
+xfs_ialloc_check_shrink(
+       struct xfs_trans        *tp,
+       xfs_agnumber_t          agno,
+       struct xfs_buf          *agibp,
+       xfs_agblock_t           new_length)
+{
+       struct xfs_inobt_rec_incore rec;
+       struct xfs_btree_cur    *cur;
+       struct xfs_mount        *mp = tp->t_mountp;
+       struct xfs_perag        *pag;
+       xfs_agino_t             agino = XFS_AGB_TO_AGINO(mp, new_length);
+       int                     has;
+       int                     error;
+
+       if (!xfs_sb_version_hassparseinodes(&mp->m_sb))
+               return 0;
+
+       pag = xfs_perag_get(mp, agno);
+       cur = xfs_inobt_init_cursor(mp, tp, agibp, pag, XFS_BTNUM_INO);
+
+       /* Look up the inobt record that would correspond to the new EOFS. */
+       error = xfs_inobt_lookup(cur, agino, XFS_LOOKUP_LE, &has);
+       if (error || !has)
+               goto out;
+
+       error = xfs_inobt_get_rec(cur, &rec, &has);
+       if (error)
+               goto out;
+
+       if (!has) {
+               error = -EFSCORRUPTED;
+               goto out;
+       }
+
+       /* If the record covers inodes that would be beyond EOFS, bail out. */
+       if (rec.ir_startino + XFS_INODES_PER_CHUNK > agino) {
+               error = -ENOSPC;
+               goto out;
+       }
+out:
+       xfs_btree_del_cursor(cur, error);
+       xfs_perag_put(pag);
+       return error;
+}
index 9df7c80..9a2112b 100644 (file)
@@ -122,4 +122,7 @@ int xfs_ialloc_cluster_alignment(struct xfs_mount *mp);
 void xfs_ialloc_setup_geometry(struct xfs_mount *mp);
 xfs_ino_t xfs_ialloc_calc_rootino(struct xfs_mount *mp, int sunit);
 
+int xfs_ialloc_check_shrink(struct xfs_trans *tp, xfs_agnumber_t agno,
+               struct xfs_buf *agibp, xfs_agblock_t new_length);
+
 #endif /* __XFS_IALLOC_H__ */
index 04ce361..84ea2e0 100644 (file)
@@ -592,23 +592,27 @@ xfs_inode_validate_extsize(
        /*
         * This comment describes a historic gap in this verifier function.
         *
-        * On older kernels, the extent size hint verifier doesn't check that
-        * the extent size hint is an integer multiple of the realtime extent
-        * size on a directory with both RTINHERIT and EXTSZINHERIT flags set.
-        * The verifier has always enforced the alignment rule for regular
-        * files with the REALTIME flag set.
+        * For a directory with both RTINHERIT and EXTSZINHERIT flags set, this
+        * function has never checked that the extent size hint is an integer
+        * multiple of the realtime extent size.  Since we allow users to set
+        * this combination  on non-rt filesystems /and/ to change the rt
+        * extent size when adding a rt device to a filesystem, the net effect
+        * is that users can configure a filesystem anticipating one rt
+        * geometry and change their minds later.  Directories do not use the
+        * extent size hint, so this is harmless for them.
         *
         * If a directory with a misaligned extent size hint is allowed to
         * propagate that hint into a new regular realtime file, the result
         * is that the inode cluster buffer verifier will trigger a corruption
-        * shutdown the next time it is run.
+        * shutdown the next time it is run, because the verifier has always
+        * enforced the alignment rule for regular files.
         *
-        * Unfortunately, there could be filesystems with these misconfigured
-        * directories in the wild, so we cannot add a check to this verifier
-        * at this time because that will result a new source of directory
-        * corruption errors when reading an existing filesystem.  Instead, we
-        * permit the misconfiguration to pass through the verifiers so that
-        * callers of this function can correct and mitigate externally.
+        * Because we allow administrators to set a new rt extent size when
+        * adding a rt section, we cannot add a check to this verifier because
+        * that will result a new source of directory corruption errors when
+        * reading an existing filesystem.  Instead, we rely on callers to
+        * decide when alignment checks are appropriate, and fix things up as
+        * needed.
         */
 
        if (rt_flag)
index 8d595a5..16f723e 100644 (file)
@@ -143,16 +143,14 @@ xfs_trans_log_inode(
        }
 
        /*
-        * Inode verifiers on older kernels don't check that the extent size
-        * hint is an integer multiple of the rt extent size on a directory
-        * with both rtinherit and extszinherit flags set.  If we're logging a
-        * directory that is misconfigured in this way, clear the hint.
+        * Inode verifiers do not check that the extent size hint is an integer
+        * multiple of the rt extent size on a directory with both rtinherit
+        * and extszinherit flags set.  If we're logging a directory that is
+        * misconfigured in this way, clear the hint.
         */
        if ((ip->i_diflags & XFS_DIFLAG_RTINHERIT) &&
            (ip->i_diflags & XFS_DIFLAG_EXTSZINHERIT) &&
            (ip->i_extsize % ip->i_mount->m_sb.sb_rextsize) > 0) {
-               xfs_info_once(ip->i_mount,
-       "Correcting misaligned extent size hint in inode 0x%llx.", ip->i_ino);
                ip->i_diflags &= ~(XFS_DIFLAG_EXTSIZE |
                                   XFS_DIFLAG_EXTSZINHERIT);
                ip->i_extsize = 0;
index 61f90b2..76fbc7c 100644 (file)
@@ -73,11 +73,25 @@ xchk_inode_extsize(
        uint16_t                flags)
 {
        xfs_failaddr_t          fa;
+       uint32_t                value = be32_to_cpu(dip->di_extsize);
 
-       fa = xfs_inode_validate_extsize(sc->mp, be32_to_cpu(dip->di_extsize),
-                       mode, flags);
+       fa = xfs_inode_validate_extsize(sc->mp, value, mode, flags);
        if (fa)
                xchk_ino_set_corrupt(sc, ino);
+
+       /*
+        * XFS allows a sysadmin to change the rt extent size when adding a rt
+        * section to a filesystem after formatting.  If there are any
+        * directories with extszinherit and rtinherit set, the hint could
+        * become misaligned with the new rextsize.  The verifier doesn't check
+        * this, because we allow rtinherit directories even without an rt
+        * device.  Flag this as an administrative warning since we will clean
+        * this up eventually.
+        */
+       if ((flags & XFS_DIFLAG_RTINHERIT) &&
+           (flags & XFS_DIFLAG_EXTSZINHERIT) &&
+           value % sc->mp->m_sb.sb_rextsize > 0)
+               xchk_ino_set_warning(sc, ino);
 }
 
 /*
index a835ceb..990b72a 100644 (file)
@@ -2763,6 +2763,19 @@ xfs_remove(
                error = xfs_droplink(tp, ip);
                if (error)
                        goto out_trans_cancel;
+
+               /*
+                * Point the unlinked child directory's ".." entry to the root
+                * directory to eliminate back-references to inodes that may
+                * get freed before the child directory is closed.  If the fs
+                * gets shrunk, this can lead to dirent inode validation errors.
+                */
+               if (dp->i_ino != tp->t_mountp->m_sb.sb_rootino) {
+                       error = xfs_dir_replace(tp, ip, &xfs_name_dotdot,
+                                       tp->t_mountp->m_sb.sb_rootino, 0);
+                       if (error)
+                               return error;
+               }
        } else {
                /*
                 * When removing a non-directory we need to log the parent
index 65270e6..16039ea 100644 (file)
@@ -1065,7 +1065,24 @@ xfs_fill_fsxattr(
 
        fileattr_fill_xflags(fa, xfs_ip2xflags(ip));
 
-       fa->fsx_extsize = XFS_FSB_TO_B(mp, ip->i_extsize);
+       if (ip->i_diflags & XFS_DIFLAG_EXTSIZE) {
+               fa->fsx_extsize = XFS_FSB_TO_B(mp, ip->i_extsize);
+       } else if (ip->i_diflags & XFS_DIFLAG_EXTSZINHERIT) {
+               /*
+                * Don't let a misaligned extent size hint on a directory
+                * escape to userspace if it won't pass the setattr checks
+                * later.
+                */
+               if ((ip->i_diflags & XFS_DIFLAG_RTINHERIT) &&
+                   ip->i_extsize % mp->m_sb.sb_rextsize > 0) {
+                       fa->fsx_xflags &= ~(FS_XFLAG_EXTSIZE |
+                                           FS_XFLAG_EXTSZINHERIT);
+                       fa->fsx_extsize = 0;
+               } else {
+                       fa->fsx_extsize = XFS_FSB_TO_B(mp, ip->i_extsize);
+               }
+       }
+
        if (ip->i_diflags2 & XFS_DIFLAG2_COWEXTSIZE)
                fa->fsx_cowextsize = XFS_FSB_TO_B(mp, ip->i_cowextsize);
        fa->fsx_projid = ip->i_projid;
@@ -1292,10 +1309,10 @@ xfs_ioctl_setattr_check_extsize(
        new_diflags = xfs_flags2diflags(ip, fa->fsx_xflags);
 
        /*
-        * Inode verifiers on older kernels don't check that the extent size
-        * hint is an integer multiple of the rt extent size on a directory
-        * with both rtinherit and extszinherit flags set.  Don't let sysadmins
-        * misconfigure directories.
+        * Inode verifiers do not check that the extent size hint is an integer
+        * multiple of the rt extent size on a directory with both rtinherit
+        * and extszinherit flags set.  Don't let sysadmins misconfigure
+        * directories.
         */
        if ((new_diflags & XFS_DIFLAG_RTINHERIT) &&
            (new_diflags & XFS_DIFLAG_EXTSZINHERIT)) {
index 4e7be6b..699066f 100644 (file)
@@ -923,16 +923,41 @@ xfs_growfs_rt(
        uint8_t         *rsum_cache;    /* old summary cache */
 
        sbp = &mp->m_sb;
-       /*
-        * Initial error checking.
-        */
+
        if (!capable(CAP_SYS_ADMIN))
                return -EPERM;
-       if (mp->m_rtdev_targp == NULL || mp->m_rbmip == NULL ||
-           (nrblocks = in->newblocks) <= sbp->sb_rblocks ||
-           (sbp->sb_rblocks && (in->extsize != sbp->sb_rextsize)))
+
+       /* Needs to have been mounted with an rt device. */
+       if (!XFS_IS_REALTIME_MOUNT(mp))
+               return -EINVAL;
+       /*
+        * Mount should fail if the rt bitmap/summary files don't load, but
+        * we'll check anyway.
+        */
+       if (!mp->m_rbmip || !mp->m_rsumip)
+               return -EINVAL;
+
+       /* Shrink not supported. */
+       if (in->newblocks <= sbp->sb_rblocks)
+               return -EINVAL;
+
+       /* Can only change rt extent size when adding rt volume. */
+       if (sbp->sb_rblocks > 0 && in->extsize != sbp->sb_rextsize)
+               return -EINVAL;
+
+       /* Range check the extent size. */
+       if (XFS_FSB_TO_B(mp, in->extsize) > XFS_MAX_RTEXTSIZE ||
+           XFS_FSB_TO_B(mp, in->extsize) < XFS_MIN_RTEXTSIZE)
                return -EINVAL;
-       if ((error = xfs_sb_validate_fsb_count(sbp, nrblocks)))
+
+       /* Unsupported realtime features. */
+       if (xfs_sb_version_hasrmapbt(&mp->m_sb) ||
+           xfs_sb_version_hasreflink(&mp->m_sb))
+               return -EOPNOTSUPP;
+
+       nrblocks = in->newblocks;
+       error = xfs_sb_validate_fsb_count(sbp, nrblocks);
+       if (error)
                return error;
        /*
         * Read in the last block of the device, make sure it exists.
@@ -996,7 +1021,8 @@ xfs_growfs_rt(
                     ((sbp->sb_rextents & ((1 << mp->m_blkbit_log) - 1)) != 0);
             bmbno < nrbmblocks;
             bmbno++) {
-               xfs_trans_t     *tp;
+               struct xfs_trans        *tp;
+               xfs_rfsblock_t          nrblocks_step;
 
                *nmp = *mp;
                nsbp = &nmp->m_sb;
@@ -1005,10 +1031,9 @@ xfs_growfs_rt(
                 */
                nsbp->sb_rextsize = in->extsize;
                nsbp->sb_rbmblocks = bmbno + 1;
-               nsbp->sb_rblocks =
-                       XFS_RTMIN(nrblocks,
-                                 nsbp->sb_rbmblocks * NBBY *
-                                 nsbp->sb_blocksize * nsbp->sb_rextsize);
+               nrblocks_step = (bmbno + 1) * NBBY * nsbp->sb_blocksize *
+                               nsbp->sb_rextsize;
+               nsbp->sb_rblocks = min(nrblocks, nrblocks_step);
                nsbp->sb_rextents = nsbp->sb_rblocks;
                do_div(nsbp->sb_rextents, nsbp->sb_rextsize);
                ASSERT(nsbp->sb_rextents != 0);
index dbf0363..70055d4 100644 (file)
@@ -705,9 +705,6 @@ static ssize_t zonefs_file_dio_append(struct kiocb *iocb, struct iov_iter *from)
                return 0;
 
        bio = bio_alloc(GFP_NOFS, nr_pages);
-       if (!bio)
-               return -ENOMEM;
-
        bio_set_dev(bio, bdev);
        bio->bi_iter.bi_sector = zi->i_zsector;
        bio->bi_write_hint = iocb->ki_hint;
diff --git a/include/dt-bindings/clock/mt8192-clk.h b/include/dt-bindings/clock/mt8192-clk.h
new file mode 100644 (file)
index 0000000..5ab68f1
--- /dev/null
@@ -0,0 +1,585 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ * Author: Chun-Jie Chen <chun-jie.chen@mediatek.com>
+ */
+
+#ifndef _DT_BINDINGS_CLK_MT8192_H
+#define _DT_BINDINGS_CLK_MT8192_H
+
+/* TOPCKGEN */
+
+#define CLK_TOP_AXI_SEL                        0
+#define CLK_TOP_SPM_SEL                        1
+#define CLK_TOP_SCP_SEL                        2
+#define CLK_TOP_BUS_AXIMEM_SEL         3
+#define CLK_TOP_DISP_SEL               4
+#define CLK_TOP_MDP_SEL                        5
+#define CLK_TOP_IMG1_SEL               6
+#define CLK_TOP_IMG2_SEL               7
+#define CLK_TOP_IPE_SEL                        8
+#define CLK_TOP_DPE_SEL                        9
+#define CLK_TOP_CAM_SEL                        10
+#define CLK_TOP_CCU_SEL                        11
+#define CLK_TOP_DSP7_SEL               12
+#define CLK_TOP_MFG_REF_SEL            13
+#define CLK_TOP_MFG_PLL_SEL            14
+#define CLK_TOP_CAMTG_SEL              15
+#define CLK_TOP_CAMTG2_SEL             16
+#define CLK_TOP_CAMTG3_SEL             17
+#define CLK_TOP_CAMTG4_SEL             18
+#define CLK_TOP_CAMTG5_SEL             19
+#define CLK_TOP_CAMTG6_SEL             20
+#define CLK_TOP_UART_SEL               21
+#define CLK_TOP_SPI_SEL                        22
+#define CLK_TOP_MSDC50_0_H_SEL         23
+#define CLK_TOP_MSDC50_0_SEL           24
+#define CLK_TOP_MSDC30_1_SEL           25
+#define CLK_TOP_MSDC30_2_SEL           26
+#define CLK_TOP_AUDIO_SEL              27
+#define CLK_TOP_AUD_INTBUS_SEL         28
+#define CLK_TOP_PWRAP_ULPOSC_SEL       29
+#define CLK_TOP_ATB_SEL                        30
+#define CLK_TOP_DPI_SEL                        31
+#define CLK_TOP_SCAM_SEL               32
+#define CLK_TOP_DISP_PWM_SEL           33
+#define CLK_TOP_USB_TOP_SEL            34
+#define CLK_TOP_SSUSB_XHCI_SEL         35
+#define CLK_TOP_I2C_SEL                        36
+#define CLK_TOP_SENINF_SEL             37
+#define CLK_TOP_SENINF1_SEL            38
+#define CLK_TOP_SENINF2_SEL            39
+#define CLK_TOP_SENINF3_SEL            40
+#define CLK_TOP_TL_SEL                 41
+#define CLK_TOP_DXCC_SEL               42
+#define CLK_TOP_AUD_ENGEN1_SEL         43
+#define CLK_TOP_AUD_ENGEN2_SEL         44
+#define CLK_TOP_AES_UFSFDE_SEL         45
+#define CLK_TOP_UFS_SEL                        46
+#define CLK_TOP_AUD_1_SEL              47
+#define CLK_TOP_AUD_2_SEL              48
+#define CLK_TOP_ADSP_SEL               49
+#define CLK_TOP_DPMAIF_MAIN_SEL                50
+#define CLK_TOP_VENC_SEL               51
+#define CLK_TOP_VDEC_SEL               52
+#define CLK_TOP_CAMTM_SEL              53
+#define CLK_TOP_PWM_SEL                        54
+#define CLK_TOP_AUDIO_H_SEL            55
+#define CLK_TOP_SPMI_MST_SEL           56
+#define CLK_TOP_AES_MSDCFDE_SEL                57
+#define CLK_TOP_SFLASH_SEL             58
+#define CLK_TOP_APLL_I2S0_M_SEL                59
+#define CLK_TOP_APLL_I2S1_M_SEL                60
+#define CLK_TOP_APLL_I2S2_M_SEL                61
+#define CLK_TOP_APLL_I2S3_M_SEL                62
+#define CLK_TOP_APLL_I2S4_M_SEL                63
+#define CLK_TOP_APLL_I2S5_M_SEL                64
+#define CLK_TOP_APLL_I2S6_M_SEL                65
+#define CLK_TOP_APLL_I2S7_M_SEL                66
+#define CLK_TOP_APLL_I2S8_M_SEL                67
+#define CLK_TOP_APLL_I2S9_M_SEL                68
+#define CLK_TOP_MAINPLL_D3             69
+#define CLK_TOP_MAINPLL_D4             70
+#define CLK_TOP_MAINPLL_D4_D2          71
+#define CLK_TOP_MAINPLL_D4_D4          72
+#define CLK_TOP_MAINPLL_D4_D8          73
+#define CLK_TOP_MAINPLL_D4_D16         74
+#define CLK_TOP_MAINPLL_D5             75
+#define CLK_TOP_MAINPLL_D5_D2          76
+#define CLK_TOP_MAINPLL_D5_D4          77
+#define CLK_TOP_MAINPLL_D5_D8          78
+#define CLK_TOP_MAINPLL_D6             79
+#define CLK_TOP_MAINPLL_D6_D2          80
+#define CLK_TOP_MAINPLL_D6_D4          81
+#define CLK_TOP_MAINPLL_D7             82
+#define CLK_TOP_MAINPLL_D7_D2          83
+#define CLK_TOP_MAINPLL_D7_D4          84
+#define CLK_TOP_MAINPLL_D7_D8          85
+#define CLK_TOP_UNIVPLL_D3             86
+#define CLK_TOP_UNIVPLL_D4             87
+#define CLK_TOP_UNIVPLL_D4_D2          88
+#define CLK_TOP_UNIVPLL_D4_D4          89
+#define CLK_TOP_UNIVPLL_D4_D8          90
+#define CLK_TOP_UNIVPLL_D5             91
+#define CLK_TOP_UNIVPLL_D5_D2          92
+#define CLK_TOP_UNIVPLL_D5_D4          93
+#define CLK_TOP_UNIVPLL_D5_D8          94
+#define CLK_TOP_UNIVPLL_D6             95
+#define CLK_TOP_UNIVPLL_D6_D2          96
+#define CLK_TOP_UNIVPLL_D6_D4          97
+#define CLK_TOP_UNIVPLL_D6_D8          98
+#define CLK_TOP_UNIVPLL_D6_D16         99
+#define CLK_TOP_UNIVPLL_D7             100
+#define CLK_TOP_APLL1                  101
+#define CLK_TOP_APLL1_D2               102
+#define CLK_TOP_APLL1_D4               103
+#define CLK_TOP_APLL1_D8               104
+#define CLK_TOP_APLL2                  105
+#define CLK_TOP_APLL2_D2               106
+#define CLK_TOP_APLL2_D4               107
+#define CLK_TOP_APLL2_D8               108
+#define CLK_TOP_MMPLL_D4               109
+#define CLK_TOP_MMPLL_D4_D2            110
+#define CLK_TOP_MMPLL_D5               111
+#define CLK_TOP_MMPLL_D5_D2            112
+#define CLK_TOP_MMPLL_D6               113
+#define CLK_TOP_MMPLL_D6_D2            114
+#define CLK_TOP_MMPLL_D7               115
+#define CLK_TOP_MMPLL_D9               116
+#define CLK_TOP_APUPLL                 117
+#define CLK_TOP_NPUPLL                 118
+#define CLK_TOP_TVDPLL                 119
+#define CLK_TOP_TVDPLL_D2              120
+#define CLK_TOP_TVDPLL_D4              121
+#define CLK_TOP_TVDPLL_D8              122
+#define CLK_TOP_TVDPLL_D16             123
+#define CLK_TOP_MSDCPLL                        124
+#define CLK_TOP_MSDCPLL_D2             125
+#define CLK_TOP_MSDCPLL_D4             126
+#define CLK_TOP_ULPOSC                 127
+#define CLK_TOP_OSC_D2                 128
+#define CLK_TOP_OSC_D4                 129
+#define CLK_TOP_OSC_D8                 130
+#define CLK_TOP_OSC_D10                        131
+#define CLK_TOP_OSC_D16                        132
+#define CLK_TOP_OSC_D20                        133
+#define CLK_TOP_CSW_F26M_D2            134
+#define CLK_TOP_ADSPPLL                        135
+#define CLK_TOP_UNIVPLL_192M           136
+#define CLK_TOP_UNIVPLL_192M_D2                137
+#define CLK_TOP_UNIVPLL_192M_D4                138
+#define CLK_TOP_UNIVPLL_192M_D8                139
+#define CLK_TOP_UNIVPLL_192M_D16       140
+#define CLK_TOP_UNIVPLL_192M_D32       141
+#define CLK_TOP_APLL12_DIV0            142
+#define CLK_TOP_APLL12_DIV1            143
+#define CLK_TOP_APLL12_DIV2            144
+#define CLK_TOP_APLL12_DIV3            145
+#define CLK_TOP_APLL12_DIV4            146
+#define CLK_TOP_APLL12_DIVB            147
+#define CLK_TOP_APLL12_DIV5            148
+#define CLK_TOP_APLL12_DIV6            149
+#define CLK_TOP_APLL12_DIV7            150
+#define CLK_TOP_APLL12_DIV8            151
+#define CLK_TOP_APLL12_DIV9            152
+#define CLK_TOP_SSUSB_TOP_REF          153
+#define CLK_TOP_SSUSB_PHY_REF          154
+#define CLK_TOP_NR_CLK                 155
+
+/* INFRACFG */
+
+#define CLK_INFRA_PMIC_TMR             0
+#define CLK_INFRA_PMIC_AP              1
+#define CLK_INFRA_PMIC_MD              2
+#define CLK_INFRA_PMIC_CONN            3
+#define CLK_INFRA_SCPSYS               4
+#define CLK_INFRA_SEJ                  5
+#define CLK_INFRA_APXGPT               6
+#define CLK_INFRA_GCE                  7
+#define CLK_INFRA_GCE2                 8
+#define CLK_INFRA_THERM                        9
+#define CLK_INFRA_I2C0                 10
+#define CLK_INFRA_AP_DMA_PSEUDO                11
+#define CLK_INFRA_I2C2                 12
+#define CLK_INFRA_I2C3                 13
+#define CLK_INFRA_PWM_H                        14
+#define CLK_INFRA_PWM1                 15
+#define CLK_INFRA_PWM2                 16
+#define CLK_INFRA_PWM3                 17
+#define CLK_INFRA_PWM4                 18
+#define CLK_INFRA_PWM                  19
+#define CLK_INFRA_UART0                        20
+#define CLK_INFRA_UART1                        21
+#define CLK_INFRA_UART2                        22
+#define CLK_INFRA_UART3                        23
+#define CLK_INFRA_GCE_26M              24
+#define CLK_INFRA_CQ_DMA_FPC           25
+#define CLK_INFRA_BTIF                 26
+#define CLK_INFRA_SPI0                 27
+#define CLK_INFRA_MSDC0                        28
+#define CLK_INFRA_MSDC1                        29
+#define CLK_INFRA_MSDC2                        30
+#define CLK_INFRA_MSDC0_SRC            31
+#define CLK_INFRA_GCPU                 32
+#define CLK_INFRA_TRNG                 33
+#define CLK_INFRA_AUXADC               34
+#define CLK_INFRA_CPUM                 35
+#define CLK_INFRA_CCIF1_AP             36
+#define CLK_INFRA_CCIF1_MD             37
+#define CLK_INFRA_AUXADC_MD            38
+#define CLK_INFRA_PCIE_TL_26M          39
+#define CLK_INFRA_MSDC1_SRC            40
+#define CLK_INFRA_MSDC2_SRC            41
+#define CLK_INFRA_PCIE_TL_96M          42
+#define CLK_INFRA_PCIE_PL_P_250M       43
+#define CLK_INFRA_DEVICE_APC           44
+#define CLK_INFRA_CCIF_AP              45
+#define CLK_INFRA_DEBUGSYS             46
+#define CLK_INFRA_AUDIO                        47
+#define CLK_INFRA_CCIF_MD              48
+#define CLK_INFRA_DXCC_SEC_CORE                49
+#define CLK_INFRA_DXCC_AO              50
+#define CLK_INFRA_DBG_TRACE            51
+#define CLK_INFRA_DEVMPU_B             52
+#define CLK_INFRA_DRAMC_F26M           53
+#define CLK_INFRA_IRTX                 54
+#define CLK_INFRA_SSUSB                        55
+#define CLK_INFRA_DISP_PWM             56
+#define CLK_INFRA_CLDMA_B              57
+#define CLK_INFRA_AUDIO_26M_B          58
+#define CLK_INFRA_MODEM_TEMP_SHARE     59
+#define CLK_INFRA_SPI1                 60
+#define CLK_INFRA_I2C4                 61
+#define CLK_INFRA_SPI2                 62
+#define CLK_INFRA_SPI3                 63
+#define CLK_INFRA_UNIPRO_SYS           64
+#define CLK_INFRA_UNIPRO_TICK          65
+#define CLK_INFRA_UFS_MP_SAP_B         66
+#define CLK_INFRA_MD32_B               67
+#define CLK_INFRA_UNIPRO_MBIST         68
+#define CLK_INFRA_I2C5                 69
+#define CLK_INFRA_I2C5_ARBITER         70
+#define CLK_INFRA_I2C5_IMM             71
+#define CLK_INFRA_I2C1_ARBITER         72
+#define CLK_INFRA_I2C1_IMM             73
+#define CLK_INFRA_I2C2_ARBITER         74
+#define CLK_INFRA_I2C2_IMM             75
+#define CLK_INFRA_SPI4                 76
+#define CLK_INFRA_SPI5                 77
+#define CLK_INFRA_CQ_DMA               78
+#define CLK_INFRA_UFS                  79
+#define CLK_INFRA_AES_UFSFDE           80
+#define CLK_INFRA_UFS_TICK             81
+#define CLK_INFRA_SSUSB_XHCI           82
+#define CLK_INFRA_MSDC0_SELF           83
+#define CLK_INFRA_MSDC1_SELF           84
+#define CLK_INFRA_MSDC2_SELF           85
+#define CLK_INFRA_UFS_AXI              86
+#define CLK_INFRA_I2C6                 87
+#define CLK_INFRA_AP_MSDC0             88
+#define CLK_INFRA_MD_MSDC0             89
+#define CLK_INFRA_CCIF5_AP             90
+#define CLK_INFRA_CCIF5_MD             91
+#define CLK_INFRA_PCIE_TOP_H_133M      92
+#define CLK_INFRA_FLASHIF_TOP_H_133M   93
+#define CLK_INFRA_PCIE_PERI_26M                94
+#define CLK_INFRA_CCIF2_AP             95
+#define CLK_INFRA_CCIF2_MD             96
+#define CLK_INFRA_CCIF3_AP             97
+#define CLK_INFRA_CCIF3_MD             98
+#define CLK_INFRA_SEJ_F13M             99
+#define CLK_INFRA_AES                  100
+#define CLK_INFRA_I2C7                 101
+#define CLK_INFRA_I2C8                 102
+#define CLK_INFRA_FBIST2FPC            103
+#define CLK_INFRA_DEVICE_APC_SYNC      104
+#define CLK_INFRA_DPMAIF_MAIN          105
+#define CLK_INFRA_PCIE_TL_32K          106
+#define CLK_INFRA_CCIF4_AP             107
+#define CLK_INFRA_CCIF4_MD             108
+#define CLK_INFRA_SPI6                 109
+#define CLK_INFRA_SPI7                 110
+#define CLK_INFRA_133M                 111
+#define CLK_INFRA_66M                  112
+#define CLK_INFRA_66M_PERI_BUS         113
+#define CLK_INFRA_FREE_DCM_133M                114
+#define CLK_INFRA_FREE_DCM_66M         115
+#define CLK_INFRA_PERI_BUS_DCM_133M    116
+#define CLK_INFRA_PERI_BUS_DCM_66M     117
+#define CLK_INFRA_FLASHIF_PERI_26M     118
+#define CLK_INFRA_FLASHIF_SFLASH       119
+#define CLK_INFRA_AP_DMA               120
+#define CLK_INFRA_NR_CLK               121
+
+/* PERICFG */
+
+#define CLK_PERI_PERIAXI               0
+#define CLK_PERI_NR_CLK                        1
+
+/* APMIXEDSYS */
+
+#define CLK_APMIXED_MAINPLL            0
+#define CLK_APMIXED_UNIVPLL            1
+#define CLK_APMIXED_USBPLL             2
+#define CLK_APMIXED_MSDCPLL            3
+#define CLK_APMIXED_MMPLL              4
+#define CLK_APMIXED_ADSPPLL            5
+#define CLK_APMIXED_MFGPLL             6
+#define CLK_APMIXED_TVDPLL             7
+#define CLK_APMIXED_APLL1              8
+#define CLK_APMIXED_APLL2              9
+#define CLK_APMIXED_MIPID26M           10
+#define CLK_APMIXED_NR_CLK             11
+
+/* SCP_ADSP */
+
+#define CLK_SCP_ADSP_AUDIODSP          0
+#define CLK_SCP_ADSP_NR_CLK            1
+
+/* IMP_IIC_WRAP_C */
+
+#define CLK_IMP_IIC_WRAP_C_I2C10       0
+#define CLK_IMP_IIC_WRAP_C_I2C11       1
+#define CLK_IMP_IIC_WRAP_C_I2C12       2
+#define CLK_IMP_IIC_WRAP_C_I2C13       3
+#define CLK_IMP_IIC_WRAP_C_NR_CLK      4
+
+/* AUDSYS */
+
+#define CLK_AUD_AFE                    0
+#define CLK_AUD_22M                    1
+#define CLK_AUD_24M                    2
+#define CLK_AUD_APLL2_TUNER            3
+#define CLK_AUD_APLL_TUNER             4
+#define CLK_AUD_TDM                    5
+#define CLK_AUD_ADC                    6
+#define CLK_AUD_DAC                    7
+#define CLK_AUD_DAC_PREDIS             8
+#define CLK_AUD_TML                    9
+#define CLK_AUD_NLE                    10
+#define CLK_AUD_I2S1_B                 11
+#define CLK_AUD_I2S2_B                 12
+#define CLK_AUD_I2S3_B                 13
+#define CLK_AUD_I2S4_B                 14
+#define CLK_AUD_CONNSYS_I2S_ASRC       15
+#define CLK_AUD_GENERAL1_ASRC          16
+#define CLK_AUD_GENERAL2_ASRC          17
+#define CLK_AUD_DAC_HIRES              18
+#define CLK_AUD_ADC_HIRES              19
+#define CLK_AUD_ADC_HIRES_TML          20
+#define CLK_AUD_ADDA6_ADC              21
+#define CLK_AUD_ADDA6_ADC_HIRES                22
+#define CLK_AUD_3RD_DAC                        23
+#define CLK_AUD_3RD_DAC_PREDIS         24
+#define CLK_AUD_3RD_DAC_TML            25
+#define CLK_AUD_3RD_DAC_HIRES          26
+#define CLK_AUD_I2S5_B                 27
+#define CLK_AUD_I2S6_B                 28
+#define CLK_AUD_I2S7_B                 29
+#define CLK_AUD_I2S8_B                 30
+#define CLK_AUD_I2S9_B                 31
+#define CLK_AUD_NR_CLK                 32
+
+/* IMP_IIC_WRAP_E */
+
+#define CLK_IMP_IIC_WRAP_E_I2C3                0
+#define CLK_IMP_IIC_WRAP_E_NR_CLK      1
+
+/* IMP_IIC_WRAP_S */
+
+#define CLK_IMP_IIC_WRAP_S_I2C7                0
+#define CLK_IMP_IIC_WRAP_S_I2C8                1
+#define CLK_IMP_IIC_WRAP_S_I2C9                2
+#define CLK_IMP_IIC_WRAP_S_NR_CLK      3
+
+/* IMP_IIC_WRAP_WS */
+
+#define CLK_IMP_IIC_WRAP_WS_I2C1       0
+#define CLK_IMP_IIC_WRAP_WS_I2C2       1
+#define CLK_IMP_IIC_WRAP_WS_I2C4       2
+#define CLK_IMP_IIC_WRAP_WS_NR_CLK     3
+
+/* IMP_IIC_WRAP_W */
+
+#define CLK_IMP_IIC_WRAP_W_I2C5                0
+#define CLK_IMP_IIC_WRAP_W_NR_CLK      1
+
+/* IMP_IIC_WRAP_N */
+
+#define CLK_IMP_IIC_WRAP_N_I2C0                0
+#define CLK_IMP_IIC_WRAP_N_I2C6                1
+#define CLK_IMP_IIC_WRAP_N_NR_CLK      2
+
+/* MSDC_TOP */
+
+#define CLK_MSDC_TOP_AES_0P            0
+#define CLK_MSDC_TOP_SRC_0P            1
+#define CLK_MSDC_TOP_SRC_1P            2
+#define CLK_MSDC_TOP_SRC_2P            3
+#define CLK_MSDC_TOP_P_MSDC0           4
+#define CLK_MSDC_TOP_P_MSDC1           5
+#define CLK_MSDC_TOP_P_MSDC2           6
+#define CLK_MSDC_TOP_P_CFG             7
+#define CLK_MSDC_TOP_AXI               8
+#define CLK_MSDC_TOP_H_MST_0P          9
+#define CLK_MSDC_TOP_H_MST_1P          10
+#define CLK_MSDC_TOP_H_MST_2P          11
+#define CLK_MSDC_TOP_MEM_OFF_DLY_26M   12
+#define CLK_MSDC_TOP_32K               13
+#define CLK_MSDC_TOP_AHB2AXI_BRG_AXI   14
+#define CLK_MSDC_TOP_NR_CLK            15
+
+/* MSDC */
+
+#define CLK_MSDC_AXI_WRAP              0
+#define CLK_MSDC_NR_CLK                        1
+
+/* MFGCFG */
+
+#define CLK_MFG_BG3D                   0
+#define CLK_MFG_NR_CLK                 1
+
+/* MMSYS */
+
+#define CLK_MM_DISP_MUTEX0             0
+#define CLK_MM_DISP_CONFIG             1
+#define CLK_MM_DISP_OVL0               2
+#define CLK_MM_DISP_RDMA0              3
+#define CLK_MM_DISP_OVL0_2L            4
+#define CLK_MM_DISP_WDMA0              5
+#define CLK_MM_DISP_UFBC_WDMA0         6
+#define CLK_MM_DISP_RSZ0               7
+#define CLK_MM_DISP_AAL0               8
+#define CLK_MM_DISP_CCORR0             9
+#define CLK_MM_DISP_DITHER0            10
+#define CLK_MM_SMI_INFRA               11
+#define CLK_MM_DISP_GAMMA0             12
+#define CLK_MM_DISP_POSTMASK0          13
+#define CLK_MM_DISP_DSC_WRAP0          14
+#define CLK_MM_DSI0                    15
+#define CLK_MM_DISP_COLOR0             16
+#define CLK_MM_SMI_COMMON              17
+#define CLK_MM_DISP_FAKE_ENG0          18
+#define CLK_MM_DISP_FAKE_ENG1          19
+#define CLK_MM_MDP_TDSHP4              20
+#define CLK_MM_MDP_RSZ4                        21
+#define CLK_MM_MDP_AAL4                        22
+#define CLK_MM_MDP_HDR4                        23
+#define CLK_MM_MDP_RDMA4               24
+#define CLK_MM_MDP_COLOR4              25
+#define CLK_MM_DISP_Y2R0               26
+#define CLK_MM_SMI_GALS                        27
+#define CLK_MM_DISP_OVL2_2L            28
+#define CLK_MM_DISP_RDMA4              29
+#define CLK_MM_DISP_DPI0               30
+#define CLK_MM_SMI_IOMMU               31
+#define CLK_MM_DSI_DSI0                        32
+#define CLK_MM_DPI_DPI0                        33
+#define CLK_MM_26MHZ                   34
+#define CLK_MM_32KHZ                   35
+#define CLK_MM_NR_CLK                  36
+
+/* IMGSYS */
+
+#define CLK_IMG_LARB9                  0
+#define CLK_IMG_LARB10                 1
+#define CLK_IMG_DIP                    2
+#define CLK_IMG_GALS                   3
+#define CLK_IMG_NR_CLK                 4
+
+/* IMGSYS2 */
+
+#define CLK_IMG2_LARB11                        0
+#define CLK_IMG2_LARB12                        1
+#define CLK_IMG2_MFB                   2
+#define CLK_IMG2_WPE                   3
+#define CLK_IMG2_MSS                   4
+#define CLK_IMG2_GALS                  5
+#define CLK_IMG2_NR_CLK                        6
+
+/* VDECSYS_SOC */
+
+#define CLK_VDEC_SOC_LARB1             0
+#define CLK_VDEC_SOC_LAT               1
+#define CLK_VDEC_SOC_LAT_ACTIVE                2
+#define CLK_VDEC_SOC_VDEC              3
+#define CLK_VDEC_SOC_VDEC_ACTIVE       4
+#define CLK_VDEC_SOC_NR_CLK            5
+
+/* VDECSYS */
+
+#define CLK_VDEC_LARB1                 0
+#define CLK_VDEC_LAT                   1
+#define CLK_VDEC_LAT_ACTIVE            2
+#define CLK_VDEC_VDEC                  3
+#define CLK_VDEC_ACTIVE                        4
+#define CLK_VDEC_NR_CLK                        5
+
+/* VENCSYS */
+
+#define CLK_VENC_SET0_LARB             0
+#define CLK_VENC_SET1_VENC             1
+#define CLK_VENC_SET2_JPGENC           2
+#define CLK_VENC_SET5_GALS             3
+#define CLK_VENC_NR_CLK                        4
+
+/* CAMSYS */
+
+#define CLK_CAM_LARB13                 0
+#define CLK_CAM_DFP_VAD                        1
+#define CLK_CAM_LARB14                 2
+#define CLK_CAM_CAM                    3
+#define CLK_CAM_CAMTG                  4
+#define CLK_CAM_SENINF                 5
+#define CLK_CAM_CAMSV0                 6
+#define CLK_CAM_CAMSV1                 7
+#define CLK_CAM_CAMSV2                 8
+#define CLK_CAM_CAMSV3                 9
+#define CLK_CAM_CCU0                   10
+#define CLK_CAM_CCU1                   11
+#define CLK_CAM_MRAW0                  12
+#define CLK_CAM_FAKE_ENG               13
+#define CLK_CAM_CCU_GALS               14
+#define CLK_CAM_CAM2MM_GALS            15
+#define CLK_CAM_NR_CLK                 16
+
+/* CAMSYS_RAWA */
+
+#define CLK_CAM_RAWA_LARBX             0
+#define CLK_CAM_RAWA_CAM               1
+#define CLK_CAM_RAWA_CAMTG             2
+#define CLK_CAM_RAWA_NR_CLK            3
+
+/* CAMSYS_RAWB */
+
+#define CLK_CAM_RAWB_LARBX             0
+#define CLK_CAM_RAWB_CAM               1
+#define CLK_CAM_RAWB_CAMTG             2
+#define CLK_CAM_RAWB_NR_CLK            3
+
+/* CAMSYS_RAWC */
+
+#define CLK_CAM_RAWC_LARBX             0
+#define CLK_CAM_RAWC_CAM               1
+#define CLK_CAM_RAWC_CAMTG             2
+#define CLK_CAM_RAWC_NR_CLK            3
+
+/* IPESYS */
+
+#define CLK_IPE_LARB19                 0
+#define CLK_IPE_LARB20                 1
+#define CLK_IPE_SMI_SUBCOM             2
+#define CLK_IPE_FD                     3
+#define CLK_IPE_FE                     4
+#define CLK_IPE_RSC                    5
+#define CLK_IPE_DPE                    6
+#define CLK_IPE_GALS                   7
+#define CLK_IPE_NR_CLK                 8
+
+/* MDPSYS */
+
+#define CLK_MDP_RDMA0                  0
+#define CLK_MDP_TDSHP0                 1
+#define CLK_MDP_IMG_DL_ASYNC0          2
+#define CLK_MDP_IMG_DL_ASYNC1          3
+#define CLK_MDP_RDMA1                  4
+#define CLK_MDP_TDSHP1                 5
+#define CLK_MDP_SMI0                   6
+#define CLK_MDP_APB_BUS                        7
+#define CLK_MDP_WROT0                  8
+#define CLK_MDP_RSZ0                   9
+#define CLK_MDP_HDR0                   10
+#define CLK_MDP_MUTEX0                 11
+#define CLK_MDP_WROT1                  12
+#define CLK_MDP_RSZ1                   13
+#define CLK_MDP_HDR1                   14
+#define CLK_MDP_FAKE_ENG0              15
+#define CLK_MDP_AAL0                   16
+#define CLK_MDP_AAL1                   17
+#define CLK_MDP_COLOR0                 18
+#define CLK_MDP_COLOR1                 19
+#define CLK_MDP_IMG_DL_RELAY0_ASYNC0   20
+#define CLK_MDP_IMG_DL_RELAY1_ASYNC1   21
+#define CLK_MDP_NR_CLK                 22
+
+#endif /* _DT_BINDINGS_CLK_MT8192_H */
diff --git a/include/dt-bindings/clock/qcom,dispcc-sc7280.h b/include/dt-bindings/clock/qcom,dispcc-sc7280.h
new file mode 100644 (file)
index 0000000..a4a692c
--- /dev/null
@@ -0,0 +1,55 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
+/*
+ * Copyright (c) 2021, The Linux Foundation. All rights reserved.
+ */
+
+#ifndef _DT_BINDINGS_CLK_QCOM_DISP_CC_SC7280_H
+#define _DT_BINDINGS_CLK_QCOM_DISP_CC_SC7280_H
+
+/* DISP_CC clocks */
+#define DISP_CC_PLL0                                   0
+#define DISP_CC_MDSS_AHB_CLK                           1
+#define DISP_CC_MDSS_AHB_CLK_SRC                       2
+#define DISP_CC_MDSS_BYTE0_CLK                         3
+#define DISP_CC_MDSS_BYTE0_CLK_SRC                     4
+#define DISP_CC_MDSS_BYTE0_DIV_CLK_SRC                 5
+#define DISP_CC_MDSS_BYTE0_INTF_CLK                    6
+#define DISP_CC_MDSS_DP_AUX_CLK                                7
+#define DISP_CC_MDSS_DP_AUX_CLK_SRC                    8
+#define DISP_CC_MDSS_DP_CRYPTO_CLK                     9
+#define DISP_CC_MDSS_DP_CRYPTO_CLK_SRC                 10
+#define DISP_CC_MDSS_DP_LINK_CLK                       11
+#define DISP_CC_MDSS_DP_LINK_CLK_SRC                   12
+#define DISP_CC_MDSS_DP_LINK_DIV_CLK_SRC               13
+#define DISP_CC_MDSS_DP_LINK_INTF_CLK                  14
+#define DISP_CC_MDSS_DP_PIXEL_CLK                      15
+#define DISP_CC_MDSS_DP_PIXEL_CLK_SRC                  16
+#define DISP_CC_MDSS_EDP_AUX_CLK                       17
+#define DISP_CC_MDSS_EDP_AUX_CLK_SRC                   18
+#define DISP_CC_MDSS_EDP_LINK_CLK                      19
+#define DISP_CC_MDSS_EDP_LINK_CLK_SRC                  20
+#define DISP_CC_MDSS_EDP_LINK_DIV_CLK_SRC              21
+#define DISP_CC_MDSS_EDP_LINK_INTF_CLK                 22
+#define DISP_CC_MDSS_EDP_PIXEL_CLK                     23
+#define DISP_CC_MDSS_EDP_PIXEL_CLK_SRC                 24
+#define DISP_CC_MDSS_ESC0_CLK                          25
+#define DISP_CC_MDSS_ESC0_CLK_SRC                      26
+#define DISP_CC_MDSS_MDP_CLK                           27
+#define DISP_CC_MDSS_MDP_CLK_SRC                       28
+#define DISP_CC_MDSS_MDP_LUT_CLK                       29
+#define DISP_CC_MDSS_NON_GDSC_AHB_CLK                  30
+#define DISP_CC_MDSS_PCLK0_CLK                         31
+#define DISP_CC_MDSS_PCLK0_CLK_SRC                     32
+#define DISP_CC_MDSS_ROT_CLK                           33
+#define DISP_CC_MDSS_ROT_CLK_SRC                       34
+#define DISP_CC_MDSS_RSCC_AHB_CLK                      35
+#define DISP_CC_MDSS_RSCC_VSYNC_CLK                    36
+#define DISP_CC_MDSS_VSYNC_CLK                         37
+#define DISP_CC_MDSS_VSYNC_CLK_SRC                     38
+#define DISP_CC_SLEEP_CLK                              39
+#define DISP_CC_XO_CLK                                 40
+
+/* DISP_CC power domains */
+#define DISP_CC_MDSS_CORE_GDSC                         0
+
+#endif
diff --git a/include/dt-bindings/clock/qcom,gcc-msm8953.h b/include/dt-bindings/clock/qcom,gcc-msm8953.h
new file mode 100644 (file)
index 0000000..783162d
--- /dev/null
@@ -0,0 +1,234 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
+
+#ifndef _DT_BINDINGS_CLK_MSM_GCC_8953_H
+#define _DT_BINDINGS_CLK_MSM_GCC_8953_H
+
+/* Clocks */
+#define APC0_DROOP_DETECTOR_CLK_SRC            0
+#define APC1_DROOP_DETECTOR_CLK_SRC            1
+#define APSS_AHB_CLK_SRC                       2
+#define BLSP1_QUP1_I2C_APPS_CLK_SRC            3
+#define BLSP1_QUP1_SPI_APPS_CLK_SRC            4
+#define BLSP1_QUP2_I2C_APPS_CLK_SRC            5
+#define BLSP1_QUP2_SPI_APPS_CLK_SRC            6
+#define BLSP1_QUP3_I2C_APPS_CLK_SRC            7
+#define BLSP1_QUP3_SPI_APPS_CLK_SRC            8
+#define BLSP1_QUP4_I2C_APPS_CLK_SRC            9
+#define BLSP1_QUP4_SPI_APPS_CLK_SRC            10
+#define BLSP1_UART1_APPS_CLK_SRC               11
+#define BLSP1_UART2_APPS_CLK_SRC               12
+#define BLSP2_QUP1_I2C_APPS_CLK_SRC            13
+#define BLSP2_QUP1_SPI_APPS_CLK_SRC            14
+#define BLSP2_QUP2_I2C_APPS_CLK_SRC            15
+#define BLSP2_QUP2_SPI_APPS_CLK_SRC            16
+#define BLSP2_QUP3_I2C_APPS_CLK_SRC            17
+#define BLSP2_QUP3_SPI_APPS_CLK_SRC            18
+#define BLSP2_QUP4_I2C_APPS_CLK_SRC            19
+#define BLSP2_QUP4_SPI_APPS_CLK_SRC            20
+#define BLSP2_UART1_APPS_CLK_SRC               21
+#define BLSP2_UART2_APPS_CLK_SRC               22
+#define BYTE0_CLK_SRC                          23
+#define BYTE1_CLK_SRC                          24
+#define CAMSS_GP0_CLK_SRC                      25
+#define CAMSS_GP1_CLK_SRC                      26
+#define CAMSS_TOP_AHB_CLK_SRC                  27
+#define CCI_CLK_SRC                            28
+#define CPP_CLK_SRC                            29
+#define CRYPTO_CLK_SRC                         30
+#define CSI0PHYTIMER_CLK_SRC                   31
+#define CSI0P_CLK_SRC                          32
+#define CSI0_CLK_SRC                           33
+#define CSI1PHYTIMER_CLK_SRC                   34
+#define CSI1P_CLK_SRC                          35
+#define CSI1_CLK_SRC                           36
+#define CSI2PHYTIMER_CLK_SRC                   37
+#define CSI2P_CLK_SRC                          38
+#define CSI2_CLK_SRC                           39
+#define ESC0_CLK_SRC                           40
+#define ESC1_CLK_SRC                           41
+#define GCC_APC0_DROOP_DETECTOR_GPLL0_CLK      42
+#define GCC_APC1_DROOP_DETECTOR_GPLL0_CLK      43
+#define GCC_APSS_AHB_CLK                       44
+#define GCC_APSS_AXI_CLK                       45
+#define GCC_APSS_TCU_ASYNC_CLK                 46
+#define GCC_BIMC_GFX_CLK                       47
+#define GCC_BIMC_GPU_CLK                       48
+#define GCC_BLSP1_AHB_CLK                      49
+#define GCC_BLSP1_QUP1_I2C_APPS_CLK            50
+#define GCC_BLSP1_QUP1_SPI_APPS_CLK            51
+#define GCC_BLSP1_QUP2_I2C_APPS_CLK            52
+#define GCC_BLSP1_QUP2_SPI_APPS_CLK            53
+#define GCC_BLSP1_QUP3_I2C_APPS_CLK            54
+#define GCC_BLSP1_QUP3_SPI_APPS_CLK            55
+#define GCC_BLSP1_QUP4_I2C_APPS_CLK            56
+#define GCC_BLSP1_QUP4_SPI_APPS_CLK            57
+#define GCC_BLSP1_UART1_APPS_CLK               58
+#define GCC_BLSP1_UART2_APPS_CLK               59
+#define GCC_BLSP2_AHB_CLK                      60
+#define GCC_BLSP2_QUP1_I2C_APPS_CLK            61
+#define GCC_BLSP2_QUP1_SPI_APPS_CLK            62
+#define GCC_BLSP2_QUP2_I2C_APPS_CLK            63
+#define GCC_BLSP2_QUP2_SPI_APPS_CLK            64
+#define GCC_BLSP2_QUP3_I2C_APPS_CLK            65
+#define GCC_BLSP2_QUP3_SPI_APPS_CLK            66
+#define GCC_BLSP2_QUP4_I2C_APPS_CLK            67
+#define GCC_BLSP2_QUP4_SPI_APPS_CLK            68
+#define GCC_BLSP2_UART1_APPS_CLK               69
+#define GCC_BLSP2_UART2_APPS_CLK               70
+#define GCC_BOOT_ROM_AHB_CLK                   71
+#define GCC_CAMSS_AHB_CLK                      72
+#define GCC_CAMSS_CCI_AHB_CLK                  73
+#define GCC_CAMSS_CCI_CLK                      74
+#define GCC_CAMSS_CPP_AHB_CLK                  75
+#define GCC_CAMSS_CPP_AXI_CLK                  76
+#define GCC_CAMSS_CPP_CLK                      77
+#define GCC_CAMSS_CSI0PHYTIMER_CLK             78
+#define GCC_CAMSS_CSI0PHY_CLK                  79
+#define GCC_CAMSS_CSI0PIX_CLK                  80
+#define GCC_CAMSS_CSI0RDI_CLK                  81
+#define GCC_CAMSS_CSI0_AHB_CLK                 82
+#define GCC_CAMSS_CSI0_CLK                     83
+#define GCC_CAMSS_CSI0_CSIPHY_3P_CLK           84
+#define GCC_CAMSS_CSI1PHYTIMER_CLK             85
+#define GCC_CAMSS_CSI1PHY_CLK                  86
+#define GCC_CAMSS_CSI1PIX_CLK                  87
+#define GCC_CAMSS_CSI1RDI_CLK                  88
+#define GCC_CAMSS_CSI1_AHB_CLK                 89
+#define GCC_CAMSS_CSI1_CLK                     90
+#define GCC_CAMSS_CSI1_CSIPHY_3P_CLK           91
+#define GCC_CAMSS_CSI2PHYTIMER_CLK             92
+#define GCC_CAMSS_CSI2PHY_CLK                  93
+#define GCC_CAMSS_CSI2PIX_CLK                  94
+#define GCC_CAMSS_CSI2RDI_CLK                  95
+#define GCC_CAMSS_CSI2_AHB_CLK                 96
+#define GCC_CAMSS_CSI2_CLK                     97
+#define GCC_CAMSS_CSI2_CSIPHY_3P_CLK           98
+#define GCC_CAMSS_CSI_VFE0_CLK                 99
+#define GCC_CAMSS_CSI_VFE1_CLK                 100
+#define GCC_CAMSS_GP0_CLK                      101
+#define GCC_CAMSS_GP1_CLK                      102
+#define GCC_CAMSS_ISPIF_AHB_CLK                        103
+#define GCC_CAMSS_JPEG0_CLK                    104
+#define GCC_CAMSS_JPEG_AHB_CLK                 105
+#define GCC_CAMSS_JPEG_AXI_CLK                 106
+#define GCC_CAMSS_MCLK0_CLK                    107
+#define GCC_CAMSS_MCLK1_CLK                    108
+#define GCC_CAMSS_MCLK2_CLK                    109
+#define GCC_CAMSS_MCLK3_CLK                    110
+#define GCC_CAMSS_MICRO_AHB_CLK                        111
+#define GCC_CAMSS_TOP_AHB_CLK                  112
+#define GCC_CAMSS_VFE0_AHB_CLK                 113
+#define GCC_CAMSS_VFE0_AXI_CLK                 114
+#define GCC_CAMSS_VFE0_CLK                     115
+#define GCC_CAMSS_VFE1_AHB_CLK                 116
+#define GCC_CAMSS_VFE1_AXI_CLK                 117
+#define GCC_CAMSS_VFE1_CLK                     118
+#define GCC_CPP_TBU_CLK                                119
+#define GCC_CRYPTO_AHB_CLK                     120
+#define GCC_CRYPTO_AXI_CLK                     121
+#define GCC_CRYPTO_CLK                         122
+#define GCC_DCC_CLK                            123
+#define GCC_GP1_CLK                            124
+#define GCC_GP2_CLK                            125
+#define GCC_GP3_CLK                            126
+#define GCC_JPEG_TBU_CLK                       127
+#define GCC_MDP_TBU_CLK                                128
+#define GCC_MDSS_AHB_CLK                       129
+#define GCC_MDSS_AXI_CLK                       130
+#define GCC_MDSS_BYTE0_CLK                     131
+#define GCC_MDSS_BYTE1_CLK                     132
+#define GCC_MDSS_ESC0_CLK                      133
+#define GCC_MDSS_ESC1_CLK                      134
+#define GCC_MDSS_MDP_CLK                       135
+#define GCC_MDSS_PCLK0_CLK                     136
+#define GCC_MDSS_PCLK1_CLK                     137
+#define GCC_MDSS_VSYNC_CLK                     138
+#define GCC_MSS_CFG_AHB_CLK                    139
+#define GCC_MSS_Q6_BIMC_AXI_CLK                        140
+#define GCC_OXILI_AHB_CLK                      141
+#define GCC_OXILI_AON_CLK                      142
+#define GCC_OXILI_GFX3D_CLK                    143
+#define GCC_OXILI_TIMER_CLK                    144
+#define GCC_PCNOC_USB3_AXI_CLK                 145
+#define GCC_PDM2_CLK                           146
+#define GCC_PDM_AHB_CLK                                147
+#define GCC_PRNG_AHB_CLK                       148
+#define GCC_QDSS_DAP_CLK                       149
+#define GCC_QUSB_REF_CLK                       150
+#define GCC_RBCPR_GFX_CLK                      151
+#define GCC_SDCC1_AHB_CLK                      152
+#define GCC_SDCC1_APPS_CLK                     153
+#define GCC_SDCC1_ICE_CORE_CLK                 154
+#define GCC_SDCC2_AHB_CLK                      155
+#define GCC_SDCC2_APPS_CLK                     156
+#define GCC_SMMU_CFG_CLK                       157
+#define GCC_USB30_MASTER_CLK                   158
+#define GCC_USB30_MOCK_UTMI_CLK                        159
+#define GCC_USB30_SLEEP_CLK                    160
+#define GCC_USB3_AUX_CLK                       161
+#define GCC_USB3_PIPE_CLK                      162
+#define GCC_USB_PHY_CFG_AHB_CLK                        163
+#define GCC_USB_SS_REF_CLK                     164
+#define GCC_VENUS0_AHB_CLK                     165
+#define GCC_VENUS0_AXI_CLK                     166
+#define GCC_VENUS0_CORE0_VCODEC0_CLK           167
+#define GCC_VENUS0_VCODEC0_CLK                 168
+#define GCC_VENUS_TBU_CLK                      169
+#define GCC_VFE1_TBU_CLK                       170
+#define GCC_VFE_TBU_CLK                                171
+#define GFX3D_CLK_SRC                          172
+#define GP1_CLK_SRC                            173
+#define GP2_CLK_SRC                            174
+#define GP3_CLK_SRC                            175
+#define GPLL0                                  176
+#define GPLL0_EARLY                            177
+#define GPLL2                                  178
+#define GPLL2_EARLY                            179
+#define GPLL3                                  180
+#define GPLL3_EARLY                            181
+#define GPLL4                                  182
+#define GPLL4_EARLY                            183
+#define GPLL6                                  184
+#define GPLL6_EARLY                            185
+#define JPEG0_CLK_SRC                          186
+#define MCLK0_CLK_SRC                          187
+#define MCLK1_CLK_SRC                          188
+#define MCLK2_CLK_SRC                          189
+#define MCLK3_CLK_SRC                          190
+#define MDP_CLK_SRC                            191
+#define PCLK0_CLK_SRC                          192
+#define PCLK1_CLK_SRC                          193
+#define PDM2_CLK_SRC                           194
+#define RBCPR_GFX_CLK_SRC                      195
+#define SDCC1_APPS_CLK_SRC                     196
+#define SDCC1_ICE_CORE_CLK_SRC                 197
+#define SDCC2_APPS_CLK_SRC                     198
+#define USB30_MASTER_CLK_SRC                   199
+#define USB30_MOCK_UTMI_CLK_SRC                        200
+#define USB3_AUX_CLK_SRC                       201
+#define VCODEC0_CLK_SRC                                202
+#define VFE0_CLK_SRC                           203
+#define VFE1_CLK_SRC                           204
+#define VSYNC_CLK_SRC                          205
+
+/* GCC block resets */
+#define GCC_CAMSS_MICRO_BCR                    0
+#define GCC_MSS_BCR                            1
+#define GCC_QUSB2_PHY_BCR                      2
+#define GCC_USB3PHY_PHY_BCR                    3
+#define GCC_USB3_PHY_BCR                       4
+#define GCC_USB_30_BCR                         5
+
+/* GDSCs */
+#define CPP_GDSC                               0
+#define JPEG_GDSC                              1
+#define MDSS_GDSC                              2
+#define OXILI_CX_GDSC                          3
+#define OXILI_GX_GDSC                          4
+#define USB30_GDSC                             5
+#define VENUS_CORE0_GDSC                       6
+#define VENUS_GDSC                             7
+#define VFE0_GDSC                              8
+#define VFE1_GDSC                              9
+
+#endif
index 4394f15..3d5724b 100644 (file)
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
 /*
  * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
  */
diff --git a/include/dt-bindings/clock/qcom,gcc-sm6115.h b/include/dt-bindings/clock/qcom,gcc-sm6115.h
new file mode 100644 (file)
index 0000000..b91a7b4
--- /dev/null
@@ -0,0 +1,201 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
+/*
+ * Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
+ */
+
+#ifndef _DT_BINDINGS_CLK_QCOM_GCC_SM6115_H
+#define _DT_BINDINGS_CLK_QCOM_GCC_SM6115_H
+
+/* GCC clocks */
+#define GPLL0                                                  0
+#define GPLL0_OUT_AUX2                                         1
+#define GPLL0_OUT_MAIN                                         2
+#define GPLL10                                                 3
+#define GPLL10_OUT_MAIN                                                4
+#define GPLL11                                                 5
+#define GPLL11_OUT_MAIN                                                6
+#define GPLL3                                                  7
+#define GPLL4                                                  8
+#define GPLL4_OUT_MAIN                                         9
+#define GPLL6                                                  10
+#define GPLL6_OUT_MAIN                                         11
+#define GPLL7                                                  12
+#define GPLL7_OUT_MAIN                                         13
+#define GPLL8                                                  14
+#define GPLL8_OUT_MAIN                                         15
+#define GPLL9                                                  16
+#define GPLL9_OUT_MAIN                                         17
+#define GCC_CAMSS_CSI0PHYTIMER_CLK                             18
+#define GCC_CAMSS_CSI0PHYTIMER_CLK_SRC                         19
+#define GCC_CAMSS_CSI1PHYTIMER_CLK                             20
+#define GCC_CAMSS_CSI1PHYTIMER_CLK_SRC                         21
+#define GCC_CAMSS_CSI2PHYTIMER_CLK                             22
+#define GCC_CAMSS_CSI2PHYTIMER_CLK_SRC                         23
+#define GCC_CAMSS_MCLK0_CLK                                    24
+#define GCC_CAMSS_MCLK0_CLK_SRC                                        25
+#define GCC_CAMSS_MCLK1_CLK                                    26
+#define GCC_CAMSS_MCLK1_CLK_SRC                                        27
+#define GCC_CAMSS_MCLK2_CLK                                    28
+#define GCC_CAMSS_MCLK2_CLK_SRC                                        29
+#define GCC_CAMSS_MCLK3_CLK                                    30
+#define GCC_CAMSS_MCLK3_CLK_SRC                                        31
+#define GCC_CAMSS_NRT_AXI_CLK                                  32
+#define GCC_CAMSS_OPE_AHB_CLK                                  33
+#define GCC_CAMSS_OPE_AHB_CLK_SRC                              34
+#define GCC_CAMSS_OPE_CLK                                      35
+#define GCC_CAMSS_OPE_CLK_SRC                                  36
+#define GCC_CAMSS_RT_AXI_CLK                                   37
+#define GCC_CAMSS_TFE_0_CLK                                    38
+#define GCC_CAMSS_TFE_0_CLK_SRC                                        39
+#define GCC_CAMSS_TFE_0_CPHY_RX_CLK                            40
+#define GCC_CAMSS_TFE_0_CSID_CLK                               41
+#define GCC_CAMSS_TFE_0_CSID_CLK_SRC                           42
+#define GCC_CAMSS_TFE_1_CLK                                    43
+#define GCC_CAMSS_TFE_1_CLK_SRC                                        44
+#define GCC_CAMSS_TFE_1_CPHY_RX_CLK                            45
+#define GCC_CAMSS_TFE_1_CSID_CLK                               46
+#define GCC_CAMSS_TFE_1_CSID_CLK_SRC                           47
+#define GCC_CAMSS_TFE_2_CLK                                    48
+#define GCC_CAMSS_TFE_2_CLK_SRC                                        49
+#define GCC_CAMSS_TFE_2_CPHY_RX_CLK                            50
+#define GCC_CAMSS_TFE_2_CSID_CLK                               51
+#define GCC_CAMSS_TFE_2_CSID_CLK_SRC                           52
+#define GCC_CAMSS_TFE_CPHY_RX_CLK_SRC                          53
+#define GCC_CAMSS_TOP_AHB_CLK                                  54
+#define GCC_CAMSS_TOP_AHB_CLK_SRC                              55
+#define GCC_CFG_NOC_USB3_PRIM_AXI_CLK                          56
+#define GCC_CPUSS_AHB_CLK                                      57
+#define GCC_CPUSS_GNOC_CLK                                     60
+#define GCC_DISP_AHB_CLK                                       61
+#define GCC_DISP_GPLL0_DIV_CLK_SRC                             62
+#define GCC_DISP_HF_AXI_CLK                                    63
+#define GCC_DISP_THROTTLE_CORE_CLK                             64
+#define GCC_DISP_XO_CLK                                                65
+#define GCC_GP1_CLK                                            66
+#define GCC_GP1_CLK_SRC                                                67
+#define GCC_GP2_CLK                                            68
+#define GCC_GP2_CLK_SRC                                                69
+#define GCC_GP3_CLK                                            70
+#define GCC_GP3_CLK_SRC                                                71
+#define GCC_GPU_CFG_AHB_CLK                                    72
+#define GCC_GPU_GPLL0_CLK_SRC                                  73
+#define GCC_GPU_GPLL0_DIV_CLK_SRC                              74
+#define GCC_GPU_IREF_CLK                                       75
+#define GCC_GPU_MEMNOC_GFX_CLK                                 76
+#define GCC_GPU_SNOC_DVM_GFX_CLK                               77
+#define GCC_GPU_THROTTLE_CORE_CLK                              78
+#define GCC_GPU_THROTTLE_XO_CLK                                        79
+#define GCC_PDM2_CLK                                           80
+#define GCC_PDM2_CLK_SRC                                       81
+#define GCC_PDM_AHB_CLK                                                82
+#define GCC_PDM_XO4_CLK                                                83
+#define GCC_PRNG_AHB_CLK                                       84
+#define GCC_QMIP_CAMERA_NRT_AHB_CLK                            85
+#define GCC_QMIP_CAMERA_RT_AHB_CLK                             86
+#define GCC_QMIP_DISP_AHB_CLK                                  87
+#define GCC_QMIP_GPU_CFG_AHB_CLK                               88
+#define GCC_QMIP_VIDEO_VCODEC_AHB_CLK                          89
+#define GCC_QUPV3_WRAP0_CORE_2X_CLK                            90
+#define GCC_QUPV3_WRAP0_CORE_CLK                               91
+#define GCC_QUPV3_WRAP0_S0_CLK                                 92
+#define GCC_QUPV3_WRAP0_S0_CLK_SRC                             93
+#define GCC_QUPV3_WRAP0_S1_CLK                                 94
+#define GCC_QUPV3_WRAP0_S1_CLK_SRC                             95
+#define GCC_QUPV3_WRAP0_S2_CLK                                 96
+#define GCC_QUPV3_WRAP0_S2_CLK_SRC                             97
+#define GCC_QUPV3_WRAP0_S3_CLK                                 98
+#define GCC_QUPV3_WRAP0_S3_CLK_SRC                             99
+#define GCC_QUPV3_WRAP0_S4_CLK                                 100
+#define GCC_QUPV3_WRAP0_S4_CLK_SRC                             101
+#define GCC_QUPV3_WRAP0_S5_CLK                                 102
+#define GCC_QUPV3_WRAP0_S5_CLK_SRC                             103
+#define GCC_QUPV3_WRAP_0_M_AHB_CLK                             104
+#define GCC_QUPV3_WRAP_0_S_AHB_CLK                             105
+#define GCC_SDCC1_AHB_CLK                                      106
+#define GCC_SDCC1_APPS_CLK                                     107
+#define GCC_SDCC1_APPS_CLK_SRC                                 108
+#define GCC_SDCC1_ICE_CORE_CLK                                 109
+#define GCC_SDCC1_ICE_CORE_CLK_SRC                             110
+#define GCC_SDCC2_AHB_CLK                                      111
+#define GCC_SDCC2_APPS_CLK                                     112
+#define GCC_SDCC2_APPS_CLK_SRC                                 113
+#define GCC_SYS_NOC_CPUSS_AHB_CLK                              114
+#define GCC_SYS_NOC_UFS_PHY_AXI_CLK                            115
+#define GCC_SYS_NOC_USB3_PRIM_AXI_CLK                          116
+#define GCC_UFS_PHY_AHB_CLK                                    117
+#define GCC_UFS_PHY_AXI_CLK                                    118
+#define GCC_UFS_PHY_AXI_CLK_SRC                                        119
+#define GCC_UFS_PHY_ICE_CORE_CLK                               120
+#define GCC_UFS_PHY_ICE_CORE_CLK_SRC                           121
+#define GCC_UFS_PHY_PHY_AUX_CLK                                        122
+#define GCC_UFS_PHY_PHY_AUX_CLK_SRC                            123
+#define GCC_UFS_PHY_RX_SYMBOL_0_CLK                            124
+#define GCC_UFS_PHY_TX_SYMBOL_0_CLK                            125
+#define GCC_UFS_PHY_UNIPRO_CORE_CLK                            126
+#define GCC_UFS_PHY_UNIPRO_CORE_CLK_SRC                                127
+#define GCC_USB30_PRIM_MASTER_CLK                              128
+#define GCC_USB30_PRIM_MASTER_CLK_SRC                          129
+#define GCC_USB30_PRIM_MOCK_UTMI_CLK                           130
+#define GCC_USB30_PRIM_MOCK_UTMI_CLK_SRC                       131
+#define GCC_USB30_PRIM_MOCK_UTMI_POSTDIV_CLK_SRC               132
+#define GCC_USB30_PRIM_SLEEP_CLK                               133
+#define GCC_USB3_PRIM_CLKREF_CLK                               134
+#define GCC_USB3_PRIM_PHY_AUX_CLK_SRC                          135
+#define GCC_USB3_PRIM_PHY_COM_AUX_CLK                          136
+#define GCC_USB3_PRIM_PHY_PIPE_CLK                             137
+#define GCC_VCODEC0_AXI_CLK                                    138
+#define GCC_VENUS_AHB_CLK                                      139
+#define GCC_VENUS_CTL_AXI_CLK                                  140
+#define GCC_VIDEO_AHB_CLK                                      141
+#define GCC_VIDEO_AXI0_CLK                                     142
+#define GCC_VIDEO_THROTTLE_CORE_CLK                            143
+#define GCC_VIDEO_VCODEC0_SYS_CLK                              144
+#define GCC_VIDEO_VENUS_CLK_SRC                                        145
+#define GCC_VIDEO_VENUS_CTL_CLK                                        146
+#define GCC_VIDEO_XO_CLK                                       147
+#define GCC_AHB2PHY_CSI_CLK                                    148
+#define GCC_AHB2PHY_USB_CLK                                    149
+#define GCC_BIMC_GPU_AXI_CLK                                   150
+#define GCC_BOOT_ROM_AHB_CLK                                   151
+#define GCC_CAM_THROTTLE_NRT_CLK                               152
+#define GCC_CAM_THROTTLE_RT_CLK                                        153
+#define GCC_CAMERA_AHB_CLK                                     154
+#define GCC_CAMERA_XO_CLK                                      155
+#define GCC_CAMSS_AXI_CLK                                      156
+#define GCC_CAMSS_AXI_CLK_SRC                                  157
+#define GCC_CAMSS_CAMNOC_ATB_CLK                               158
+#define GCC_CAMSS_CAMNOC_NTS_XO_CLK                            159
+#define GCC_CAMSS_CCI_0_CLK                                    160
+#define GCC_CAMSS_CCI_CLK_SRC                                  161
+#define GCC_CAMSS_CPHY_0_CLK                                   162
+#define GCC_CAMSS_CPHY_1_CLK                                   163
+#define GCC_CAMSS_CPHY_2_CLK                                   164
+#define GCC_UFS_CLKREF_CLK                                     165
+#define GCC_DISP_GPLL0_CLK_SRC                                 166
+
+/* GCC resets */
+#define GCC_QUSB2PHY_PRIM_BCR                                  0
+#define GCC_QUSB2PHY_SEC_BCR                                   1
+#define GCC_SDCC1_BCR                                          2
+#define GCC_UFS_PHY_BCR                                                3
+#define GCC_USB30_PRIM_BCR                                     4
+#define GCC_USB_PHY_CFG_AHB2PHY_BCR                            5
+#define GCC_VCODEC0_BCR                                                6
+#define GCC_VENUS_BCR                                          7
+#define GCC_VIDEO_INTERFACE_BCR                                        8
+#define GCC_USB3PHY_PHY_PRIM_SP0_BCR                           9
+#define GCC_USB3_PHY_PRIM_SP0_BCR                              10
+#define GCC_SDCC2_BCR                                          11
+
+/* Indexes for GDSCs */
+#define GCC_CAMSS_TOP_GDSC                     0
+#define GCC_UFS_PHY_GDSC                       1
+#define GCC_USB30_PRIM_GDSC                    2
+#define GCC_VCODEC0_GDSC                       3
+#define GCC_VENUS_GDSC                         4
+#define HLOS1_VOTE_TURING_MMU_TBU1_GDSC                5
+#define HLOS1_VOTE_TURING_MMU_TBU0_GDSC                6
+#define HLOS1_VOTE_MM_SNOC_MMU_TBU_RT_GDSC     7
+#define HLOS1_VOTE_MM_SNOC_MMU_TBU_NRT_GDSC    8
+
+#endif
diff --git a/include/dt-bindings/clock/qcom,gcc-sm6350.h b/include/dt-bindings/clock/qcom,gcc-sm6350.h
new file mode 100644 (file)
index 0000000..ba584ca
--- /dev/null
@@ -0,0 +1,178 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
+/*
+ * Copyright (c) 2021, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2021, Konrad Dybcio <konrad.dybcio@somainline.org>
+ */
+
+#ifndef _DT_BINDINGS_CLK_QCOM_GCC_SM6350_H
+#define _DT_BINDINGS_CLK_QCOM_GCC_SM6350_H
+
+/* GCC clocks */
+#define GPLL0                                  0
+#define GPLL0_OUT_EVEN                         1
+#define GPLL0_OUT_ODD                          2
+#define GPLL6                                  3
+#define GPLL6_OUT_EVEN                         4
+#define GPLL7                                  5
+#define GCC_AGGRE_CNOC_PERIPH_CENTER_AHB_CLK   6
+#define GCC_AGGRE_NOC_CENTER_AHB_CLK           7
+#define GCC_AGGRE_NOC_PCIE_SF_AXI_CLK          8
+#define GCC_AGGRE_NOC_PCIE_TBU_CLK             9
+#define GCC_AGGRE_NOC_WLAN_AXI_CLK             10
+#define GCC_AGGRE_UFS_PHY_AXI_CLK              11
+#define GCC_AGGRE_USB3_PRIM_AXI_CLK            12
+#define GCC_BOOT_ROM_AHB_CLK                   13
+#define GCC_CAMERA_AHB_CLK                     14
+#define GCC_CAMERA_AXI_CLK                     15
+#define GCC_CAMERA_THROTTLE_NRT_AXI_CLK                16
+#define GCC_CAMERA_THROTTLE_RT_AXI_CLK         17
+#define GCC_CAMERA_XO_CLK                      18
+#define GCC_CE1_AHB_CLK                                19
+#define GCC_CE1_AXI_CLK                                20
+#define GCC_CE1_CLK                            21
+#define GCC_CFG_NOC_USB3_PRIM_AXI_CLK          22
+#define GCC_CPUSS_AHB_CLK                      23
+#define GCC_CPUSS_AHB_CLK_SRC                  24
+#define GCC_CPUSS_AHB_DIV_CLK_SRC              25
+#define GCC_CPUSS_GNOC_CLK                     26
+#define GCC_CPUSS_RBCPR_CLK                    27
+#define GCC_DDRSS_GPU_AXI_CLK                  28
+#define GCC_DISP_AHB_CLK                       29
+#define GCC_DISP_AXI_CLK                       30
+#define GCC_DISP_CC_SLEEP_CLK                  31
+#define GCC_DISP_CC_XO_CLK                     32
+#define GCC_DISP_GPLL0_CLK                     33
+#define GCC_DISP_THROTTLE_AXI_CLK              34
+#define GCC_DISP_XO_CLK                                35
+#define GCC_GP1_CLK                            36
+#define GCC_GP1_CLK_SRC                                37
+#define GCC_GP2_CLK                            38
+#define GCC_GP2_CLK_SRC                                39
+#define GCC_GP3_CLK                            40
+#define GCC_GP3_CLK_SRC                                41
+#define GCC_GPU_CFG_AHB_CLK                    42
+#define GCC_GPU_GPLL0_CLK                      43
+#define GCC_GPU_GPLL0_DIV_CLK                  44
+#define GCC_GPU_MEMNOC_GFX_CLK                 45
+#define GCC_GPU_SNOC_DVM_GFX_CLK               46
+#define GCC_NPU_AXI_CLK                                47
+#define GCC_NPU_BWMON_AXI_CLK                  48
+#define GCC_NPU_BWMON_DMA_CFG_AHB_CLK          49
+#define GCC_NPU_BWMON_DSP_CFG_AHB_CLK          50
+#define GCC_NPU_CFG_AHB_CLK                    51
+#define GCC_NPU_DMA_CLK                                52
+#define GCC_NPU_GPLL0_CLK                      53
+#define GCC_NPU_GPLL0_DIV_CLK                  54
+#define GCC_PCIE_0_AUX_CLK                     55
+#define GCC_PCIE_0_AUX_CLK_SRC                 56
+#define GCC_PCIE_0_CFG_AHB_CLK                 57
+#define GCC_PCIE_0_MSTR_AXI_CLK                        58
+#define GCC_PCIE_0_PIPE_CLK                    59
+#define GCC_PCIE_0_SLV_AXI_CLK                 60
+#define GCC_PCIE_0_SLV_Q2A_AXI_CLK             61
+#define GCC_PCIE_PHY_RCHNG_CLK                 62
+#define GCC_PCIE_PHY_RCHNG_CLK_SRC             63
+#define GCC_PDM2_CLK                           64
+#define GCC_PDM2_CLK_SRC                       65
+#define GCC_PDM_AHB_CLK                                66
+#define GCC_PDM_XO4_CLK                                67
+#define GCC_PRNG_AHB_CLK                       68
+#define GCC_QUPV3_WRAP0_CORE_2X_CLK            69
+#define GCC_QUPV3_WRAP0_CORE_CLK               70
+#define GCC_QUPV3_WRAP0_S0_CLK                 71
+#define GCC_QUPV3_WRAP0_S0_CLK_SRC             72
+#define GCC_QUPV3_WRAP0_S1_CLK                 73
+#define GCC_QUPV3_WRAP0_S1_CLK_SRC             74
+#define GCC_QUPV3_WRAP0_S2_CLK                 75
+#define GCC_QUPV3_WRAP0_S2_CLK_SRC             76
+#define GCC_QUPV3_WRAP0_S3_CLK                 77
+#define GCC_QUPV3_WRAP0_S3_CLK_SRC             78
+#define GCC_QUPV3_WRAP0_S4_CLK                 79
+#define GCC_QUPV3_WRAP0_S4_CLK_SRC             80
+#define GCC_QUPV3_WRAP0_S5_CLK                 81
+#define GCC_QUPV3_WRAP0_S5_CLK_SRC             82
+#define GCC_QUPV3_WRAP1_CORE_2X_CLK            83
+#define GCC_QUPV3_WRAP1_CORE_CLK               84
+#define GCC_QUPV3_WRAP1_S0_CLK                 85
+#define GCC_QUPV3_WRAP1_S0_CLK_SRC             86
+#define GCC_QUPV3_WRAP1_S1_CLK                 87
+#define GCC_QUPV3_WRAP1_S1_CLK_SRC             88
+#define GCC_QUPV3_WRAP1_S2_CLK                 89
+#define GCC_QUPV3_WRAP1_S2_CLK_SRC             90
+#define GCC_QUPV3_WRAP1_S3_CLK                 91
+#define GCC_QUPV3_WRAP1_S3_CLK_SRC             92
+#define GCC_QUPV3_WRAP1_S4_CLK                 93
+#define GCC_QUPV3_WRAP1_S4_CLK_SRC             94
+#define GCC_QUPV3_WRAP1_S5_CLK                 95
+#define GCC_QUPV3_WRAP1_S5_CLK_SRC             96
+#define GCC_QUPV3_WRAP_0_M_AHB_CLK             97
+#define GCC_QUPV3_WRAP_0_S_AHB_CLK             98
+#define GCC_QUPV3_WRAP_1_M_AHB_CLK             99
+#define GCC_QUPV3_WRAP_1_S_AHB_CLK             100
+#define GCC_SDCC1_AHB_CLK                      101
+#define GCC_SDCC1_APPS_CLK                     102
+#define GCC_SDCC1_APPS_CLK_SRC                 103
+#define GCC_SDCC1_ICE_CORE_CLK                 104
+#define GCC_SDCC1_ICE_CORE_CLK_SRC             105
+#define GCC_SDCC2_AHB_CLK                      106
+#define GCC_SDCC2_APPS_CLK                     107
+#define GCC_SDCC2_APPS_CLK_SRC                 108
+#define GCC_SYS_NOC_CPUSS_AHB_CLK              109
+#define GCC_UFS_MEM_CLKREF_CLK                 110
+#define GCC_UFS_PHY_AHB_CLK                    111
+#define GCC_UFS_PHY_AXI_CLK                    112
+#define GCC_UFS_PHY_AXI_CLK_SRC                        113
+#define GCC_UFS_PHY_ICE_CORE_CLK               114
+#define GCC_UFS_PHY_ICE_CORE_CLK_SRC           115
+#define GCC_UFS_PHY_PHY_AUX_CLK                        116
+#define GCC_UFS_PHY_PHY_AUX_CLK_SRC            117
+#define GCC_UFS_PHY_RX_SYMBOL_0_CLK            118
+#define GCC_UFS_PHY_RX_SYMBOL_1_CLK            119
+#define GCC_UFS_PHY_TX_SYMBOL_0_CLK            120
+#define GCC_UFS_PHY_UNIPRO_CORE_CLK            121
+#define GCC_UFS_PHY_UNIPRO_CORE_CLK_SRC                122
+#define GCC_USB30_PRIM_MASTER_CLK              123
+#define GCC_USB30_PRIM_MASTER_CLK_SRC          124
+#define GCC_USB30_PRIM_MOCK_UTMI_CLK           125
+#define GCC_USB30_PRIM_MOCK_UTMI_CLK_SRC       126
+#define GCC_USB30_PRIM_MOCK_UTMI_DIV_CLK_SRC   127
+#define GCC_USB3_PRIM_CLKREF_CLK               128
+#define GCC_USB30_PRIM_SLEEP_CLK               129
+#define GCC_USB3_PRIM_PHY_AUX_CLK              130
+#define GCC_USB3_PRIM_PHY_AUX_CLK_SRC          131
+#define GCC_USB3_PRIM_PHY_COM_AUX_CLK          132
+#define GCC_USB3_PRIM_PHY_PIPE_CLK             133
+#define GCC_VIDEO_AHB_CLK                      134
+#define GCC_VIDEO_AXI_CLK                      135
+#define GCC_VIDEO_THROTTLE_AXI_CLK             136
+#define GCC_VIDEO_XO_CLK                       137
+#define GCC_UFS_PHY_PHY_AUX_HW_CTL_CLK         138
+#define GCC_UFS_PHY_AXI_HW_CTL_CLK             139
+#define GCC_AGGRE_UFS_PHY_AXI_HW_CTL_CLK       140
+#define GCC_UFS_PHY_UNIPRO_CORE_HW_CTL_CLK     141
+#define GCC_UFS_PHY_ICE_CORE_HW_CTL_CLK                142
+#define GCC_RX5_PCIE_CLKREF_CLK                        143
+#define GCC_GPU_GPLL0_MAIN_DIV_CLK_SRC         144
+#define GCC_NPU_PLL0_MAIN_DIV_CLK_SRC          145
+
+/* GCC resets */
+#define GCC_QUSB2PHY_PRIM_BCR                  0
+#define GCC_QUSB2PHY_SEC_BCR                   1
+#define GCC_SDCC1_BCR                          2
+#define GCC_SDCC2_BCR                          3
+#define GCC_UFS_PHY_BCR                                4
+#define GCC_USB30_PRIM_BCR                     5
+#define GCC_PCIE_0_BCR                         6
+#define GCC_PCIE_0_PHY_BCR                     7
+#define GCC_QUPV3_WRAPPER_0_BCR                        8
+#define GCC_QUPV3_WRAPPER_1_BCR                        9
+#define GCC_USB3_PHY_PRIM_BCR                  10
+#define GCC_USB3_DP_PHY_PRIM_BCR               11
+
+/* GCC GDSCs */
+#define USB30_PRIM_GDSC                                0
+#define UFS_PHY_GDSC                           1
+#define HLOS1_VOTE_MMNOC_MMU_TBU_HF0_GDSC      2
+#define HLOS1_VOTE_MMNOC_MMU_TBU_HF1_GDSC      3
+
+#endif
diff --git a/include/dt-bindings/clock/qcom,gpucc-sc7280.h b/include/dt-bindings/clock/qcom,gpucc-sc7280.h
new file mode 100644 (file)
index 0000000..669b23b
--- /dev/null
@@ -0,0 +1,35 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
+/*
+ * Copyright (c) 2021, The Linux Foundation. All rights reserved.
+ */
+
+#ifndef _DT_BINDINGS_CLK_QCOM_GPU_CC_SC7280_H
+#define _DT_BINDINGS_CLK_QCOM_GPU_CC_SC7280_H
+
+/* GPU_CC clocks */
+#define GPU_CC_PLL0                            0
+#define GPU_CC_PLL1                            1
+#define GPU_CC_AHB_CLK                         2
+#define GPU_CC_CB_CLK                          3
+#define GPU_CC_CRC_AHB_CLK                     4
+#define GPU_CC_CX_GMU_CLK                      5
+#define GPU_CC_CX_SNOC_DVM_CLK                 6
+#define GPU_CC_CXO_AON_CLK                     7
+#define GPU_CC_CXO_CLK                         8
+#define GPU_CC_GMU_CLK_SRC                     9
+#define GPU_CC_GX_GMU_CLK                      10
+#define GPU_CC_HLOS1_VOTE_GPU_SMMU_CLK         11
+#define GPU_CC_HUB_AHB_DIV_CLK_SRC             12
+#define GPU_CC_HUB_AON_CLK                     13
+#define GPU_CC_HUB_CLK_SRC                     14
+#define GPU_CC_HUB_CX_INT_CLK                  15
+#define GPU_CC_HUB_CX_INT_DIV_CLK_SRC          16
+#define GPU_CC_MND1X_0_GFX3D_CLK               17
+#define GPU_CC_MND1X_1_GFX3D_CLK               18
+#define GPU_CC_SLEEP_CLK                       19
+
+/* GPU_CC power domains */
+#define GPU_CC_CX_GDSC                         0
+#define GPU_CC_GX_GDSC                         1
+
+#endif
diff --git a/include/dt-bindings/clock/qcom,mmcc-msm8994.h b/include/dt-bindings/clock/qcom,mmcc-msm8994.h
new file mode 100644 (file)
index 0000000..4b28909
--- /dev/null
@@ -0,0 +1,155 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2020, Konrad Dybcio
+ */
+
+#ifndef _DT_BINDINGS_CLK_MSM_MMCC_8994_H
+#define _DT_BINDINGS_CLK_MSM_MMCC_8994_H
+
+/* Clocks */
+#define MMPLL0_EARLY                                   0
+#define MMPLL0_PLL                                             1
+#define MMPLL1_EARLY                                   2
+#define MMPLL1_PLL                                             3
+#define MMPLL3_EARLY                                   4
+#define MMPLL3_PLL                                             5
+#define MMPLL4_EARLY                                   6
+#define MMPLL4_PLL                                             7
+#define MMPLL5_EARLY                                   8
+#define MMPLL5_PLL                                             9
+#define AXI_CLK_SRC                                            10
+#define RBBMTIMER_CLK_SRC                              11
+#define PCLK0_CLK_SRC                                  12
+#define PCLK1_CLK_SRC                                  13
+#define MDP_CLK_SRC                                            14
+#define VSYNC_CLK_SRC                                  15
+#define BYTE0_CLK_SRC                                  16
+#define BYTE1_CLK_SRC                                  17
+#define ESC0_CLK_SRC                                   18
+#define ESC1_CLK_SRC                                   19
+#define MDSS_AHB_CLK                                   20
+#define MDSS_PCLK0_CLK                                 21
+#define MDSS_PCLK1_CLK                                 22
+#define MDSS_VSYNC_CLK                                 23
+#define MDSS_BYTE0_CLK                                 24
+#define MDSS_BYTE1_CLK                                 25
+#define MDSS_ESC0_CLK                                  26
+#define MDSS_ESC1_CLK                                  27
+#define CSI0_CLK_SRC                                   28
+#define CSI1_CLK_SRC                                   29
+#define CSI2_CLK_SRC                                   30
+#define CSI3_CLK_SRC                                   31
+#define VFE0_CLK_SRC                                   32
+#define VFE1_CLK_SRC                                   33
+#define CPP_CLK_SRC                                            34
+#define JPEG0_CLK_SRC                                  35
+#define JPEG1_CLK_SRC                                  36
+#define JPEG2_CLK_SRC                                  37
+#define CSI2PHYTIMER_CLK_SRC                   38
+#define FD_CORE_CLK_SRC                                        39
+#define OCMEMNOC_CLK_SRC                               40
+#define CCI_CLK_SRC                                            41
+#define MMSS_GP0_CLK_SRC                               42
+#define MMSS_GP1_CLK_SRC                               43
+#define JPEG_DMA_CLK_SRC                               44
+#define MCLK0_CLK_SRC                                  45
+#define MCLK1_CLK_SRC                                  46
+#define MCLK2_CLK_SRC                                  47
+#define MCLK3_CLK_SRC                                  48
+#define CSI0PHYTIMER_CLK_SRC                   49
+#define CSI1PHYTIMER_CLK_SRC                   50
+#define EXTPCLK_CLK_SRC                                        51
+#define HDMI_CLK_SRC                                   52
+#define CAMSS_AHB_CLK                                  53
+#define CAMSS_CCI_CCI_AHB_CLK                  54
+#define CAMSS_CCI_CCI_CLK                              55
+#define CAMSS_VFE_CPP_AHB_CLK                  56
+#define CAMSS_VFE_CPP_AXI_CLK                  57
+#define CAMSS_VFE_CPP_CLK                              58
+#define CAMSS_CSI0_AHB_CLK                             59
+#define CAMSS_CSI0_CLK                                 60
+#define CAMSS_CSI0PHY_CLK                              61
+#define CAMSS_CSI0PIX_CLK                              62
+#define CAMSS_CSI0RDI_CLK                              63
+#define CAMSS_CSI1_AHB_CLK                             64
+#define CAMSS_CSI1_CLK                                 65
+#define CAMSS_CSI1PHY_CLK                              66
+#define CAMSS_CSI1PIX_CLK                              67
+#define CAMSS_CSI1RDI_CLK                              68
+#define CAMSS_CSI2_AHB_CLK                             69
+#define CAMSS_CSI2_CLK                                 70
+#define CAMSS_CSI2PHY_CLK                              71
+#define CAMSS_CSI2PIX_CLK                              72
+#define CAMSS_CSI2RDI_CLK                              73
+#define CAMSS_CSI3_AHB_CLK                             74
+#define CAMSS_CSI3_CLK                                 75
+#define CAMSS_CSI3PHY_CLK                              76
+#define CAMSS_CSI3PIX_CLK                              77
+#define CAMSS_CSI3RDI_CLK                              78
+#define CAMSS_CSI_VFE0_CLK                             79
+#define CAMSS_CSI_VFE1_CLK                             80
+#define CAMSS_GP0_CLK                                  81
+#define CAMSS_GP1_CLK                                  82
+#define CAMSS_ISPIF_AHB_CLK                            83
+#define CAMSS_JPEG_DMA_CLK                             84
+#define CAMSS_JPEG_JPEG0_CLK                   85
+#define CAMSS_JPEG_JPEG1_CLK                   86
+#define CAMSS_JPEG_JPEG2_CLK                   87
+#define CAMSS_JPEG_JPEG_AHB_CLK                        88
+#define CAMSS_JPEG_JPEG_AXI_CLK                        89
+#define CAMSS_MCLK0_CLK                                        90
+#define CAMSS_MCLK1_CLK                                        91
+#define CAMSS_MCLK2_CLK                                        92
+#define CAMSS_MCLK3_CLK                                        93
+#define CAMSS_MICRO_AHB_CLK                            94
+#define CAMSS_PHY0_CSI0PHYTIMER_CLK            95
+#define CAMSS_PHY1_CSI1PHYTIMER_CLK            96
+#define CAMSS_PHY2_CSI2PHYTIMER_CLK            97
+#define CAMSS_TOP_AHB_CLK                              98
+#define CAMSS_VFE_VFE0_CLK                             99
+#define CAMSS_VFE_VFE1_CLK                             100
+#define CAMSS_VFE_VFE_AHB_CLK                  101
+#define CAMSS_VFE_VFE_AXI_CLK                  102
+#define FD_AXI_CLK                                             103
+#define FD_CORE_CLK                                            104
+#define FD_CORE_UAR_CLK                                        105
+#define MDSS_AXI_CLK                                   106
+#define MDSS_EXTPCLK_CLK                               107
+#define MDSS_HDMI_AHB_CLK                              108
+#define MDSS_HDMI_CLK                                  109
+#define MDSS_MDP_CLK                                   110
+#define MMSS_MISC_AHB_CLK                              111
+#define MMSS_MMSSNOC_AXI_CLK                   112
+#define MMSS_S0_AXI_CLK                                        113
+#define OCMEMCX_OCMEMNOC_CLK                   114
+#define OXILI_GFX3D_CLK                                        115
+#define OXILI_RBBMTIMER_CLK                            116
+#define OXILICX_AHB_CLK                                        117
+#define VENUS0_AHB_CLK                                 118
+#define VENUS0_AXI_CLK                                 119
+#define VENUS0_OCMEMNOC_CLK                            120
+#define VENUS0_VCODEC0_CLK                             121
+#define VENUS0_CORE0_VCODEC_CLK                        122
+#define VENUS0_CORE1_VCODEC_CLK                        123
+#define VENUS0_CORE2_VCODEC_CLK                        124
+#define AHB_CLK_SRC                                            125
+#define FD_AHB_CLK                                             126
+
+/* GDSCs */
+#define VENUS_GDSC                                             0
+#define VENUS_CORE0_GDSC                               1
+#define VENUS_CORE1_GDSC                               2
+#define VENUS_CORE2_GDSC                               3
+#define CAMSS_TOP_GDSC                                 4
+#define MDSS_GDSC                                              5
+#define JPEG_GDSC                                              6
+#define VFE_GDSC                                               7
+#define CPP_GDSC                                               8
+#define OXILI_GX_GDSC                                  9
+#define OXILI_CX_GDSC                                  10
+#define FD_GDSC                                                        11
+
+/* Resets */
+#define CAMSS_MICRO_BCR                                        0
+
+#endif
index 8aaba7c..aa834d5 100644 (file)
 #define RPM_SMD_CE2_A_CLK                      103
 #define RPM_SMD_CE3_CLK                                104
 #define RPM_SMD_CE3_A_CLK                      105
+#define RPM_SMD_QUP_CLK                                106
+#define RPM_SMD_QUP_A_CLK                      107
+#define RPM_SMD_MMRT_CLK                       108
+#define RPM_SMD_MMRT_A_CLK                     109
+#define RPM_SMD_MMNRT_CLK                      110
+#define RPM_SMD_MMNRT_A_CLK                    111
+#define RPM_SMD_SNOC_PERIPH_CLK                        112
+#define RPM_SMD_SNOC_PERIPH_A_CLK              113
+#define RPM_SMD_SNOC_LPASS_CLK                 114
+#define RPM_SMD_SNOC_LPASS_A_CLK               115
 
 #endif
index 583a991..0a7d1be 100644 (file)
@@ -31,5 +31,7 @@
 #define RPMH_RF_CLK5_A                         22
 #define RPMH_PKA_CLK                           23
 #define RPMH_HWKM_CLK                          24
+#define RPMH_QLINK_CLK                         25
+#define RPMH_QLINK_CLK_A                       26
 
 #endif
diff --git a/include/dt-bindings/clock/qcom,videocc-sc7280.h b/include/dt-bindings/clock/qcom,videocc-sc7280.h
new file mode 100644 (file)
index 0000000..9e00c3a
--- /dev/null
@@ -0,0 +1,27 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
+/*
+ * Copyright (c) 2021, The Linux Foundation. All rights reserved.
+ */
+
+#ifndef _DT_BINDINGS_CLK_QCOM_VIDEO_CC_SC7280_H
+#define _DT_BINDINGS_CLK_QCOM_VIDEO_CC_SC7280_H
+
+/* VIDEO_CC clocks */
+#define VIDEO_PLL0                             0
+#define VIDEO_CC_IRIS_AHB_CLK                  1
+#define VIDEO_CC_IRIS_CLK_SRC                  2
+#define VIDEO_CC_MVS0_AXI_CLK                  3
+#define VIDEO_CC_MVS0_CORE_CLK                 4
+#define VIDEO_CC_MVSC_CORE_CLK                 5
+#define VIDEO_CC_MVSC_CTL_AXI_CLK              6
+#define VIDEO_CC_SLEEP_CLK                     7
+#define VIDEO_CC_SLEEP_CLK_SRC                 8
+#define VIDEO_CC_VENUS_AHB_CLK                 9
+#define VIDEO_CC_XO_CLK                                10
+#define VIDEO_CC_XO_CLK_SRC                    11
+
+/* VIDEO_CC power domains */
+#define MVS0_GDSC                              0
+#define MVSC_GDSC                              1
+
+#endif
index 1d89865..0bb17ff 100644 (file)
 #define R9A07G044_CLK_P2               19
 #define R9A07G044_CLK_AT               20
 #define R9A07G044_OSCCLK               21
+#define R9A07G044_CLK_P0_DIV2          22
 
 /* R9A07G044 Module Clocks */
-#define R9A07G044_CLK_GIC600           0
-#define R9A07G044_CLK_IA55             1
-#define R9A07G044_CLK_SYC              2
-#define R9A07G044_CLK_DMAC             3
-#define R9A07G044_CLK_SYSC             4
-#define R9A07G044_CLK_MTU              5
-#define R9A07G044_CLK_GPT              6
-#define R9A07G044_CLK_ETH0             7
-#define R9A07G044_CLK_ETH1             8
-#define R9A07G044_CLK_I2C0             9
-#define R9A07G044_CLK_I2C1             10
-#define R9A07G044_CLK_I2C2             11
-#define R9A07G044_CLK_I2C3             12
-#define R9A07G044_CLK_SCIF0            13
-#define R9A07G044_CLK_SCIF1            14
-#define R9A07G044_CLK_SCIF2            15
-#define R9A07G044_CLK_SCIF3            16
-#define R9A07G044_CLK_SCIF4            17
-#define R9A07G044_CLK_SCI0             18
-#define R9A07G044_CLK_SCI1             19
-#define R9A07G044_CLK_GPIO             20
-#define R9A07G044_CLK_SDHI0            21
-#define R9A07G044_CLK_SDHI1            22
-#define R9A07G044_CLK_USB0             23
-#define R9A07G044_CLK_USB1             24
-#define R9A07G044_CLK_CANFD            25
-#define R9A07G044_CLK_SSI0             26
-#define R9A07G044_CLK_SSI1             27
-#define R9A07G044_CLK_SSI2             28
-#define R9A07G044_CLK_SSI3             29
-#define R9A07G044_CLK_MHU              30
-#define R9A07G044_CLK_OSTM0            31
-#define R9A07G044_CLK_OSTM1            32
-#define R9A07G044_CLK_OSTM2            33
-#define R9A07G044_CLK_WDT0             34
-#define R9A07G044_CLK_WDT1             35
-#define R9A07G044_CLK_WDT2             36
-#define R9A07G044_CLK_WDT_PON          37
-#define R9A07G044_CLK_GPU              38
-#define R9A07G044_CLK_ISU              39
-#define R9A07G044_CLK_H264             40
-#define R9A07G044_CLK_CRU              41
-#define R9A07G044_CLK_MIPI_DSI         42
-#define R9A07G044_CLK_LCDC             43
-#define R9A07G044_CLK_SRC              44
-#define R9A07G044_CLK_RSPI0            45
-#define R9A07G044_CLK_RSPI1            46
-#define R9A07G044_CLK_RSPI2            47
-#define R9A07G044_CLK_ADC              48
-#define R9A07G044_CLK_TSU_PCLK         49
-#define R9A07G044_CLK_SPI              50
-#define R9A07G044_CLK_MIPI_DSI_V       51
-#define R9A07G044_CLK_MIPI_DSI_PIN     52
+#define R9A07G044_CA55_SCLK            0
+#define R9A07G044_CA55_PCLK            1
+#define R9A07G044_CA55_ATCLK           2
+#define R9A07G044_CA55_GICCLK          3
+#define R9A07G044_CA55_PERICLK         4
+#define R9A07G044_CA55_ACLK            5
+#define R9A07G044_CA55_TSCLK           6
+#define R9A07G044_GIC600_GICCLK                7
+#define R9A07G044_IA55_CLK             8
+#define R9A07G044_IA55_PCLK            9
+#define R9A07G044_MHU_PCLK             10
+#define R9A07G044_SYC_CNT_CLK          11
+#define R9A07G044_DMAC_ACLK            12
+#define R9A07G044_DMAC_PCLK            13
+#define R9A07G044_OSTM0_PCLK           14
+#define R9A07G044_OSTM1_PCLK           15
+#define R9A07G044_OSTM2_PCLK           16
+#define R9A07G044_MTU_X_MCK_MTU3       17
+#define R9A07G044_POE3_CLKM_POE                18
+#define R9A07G044_GPT_PCLK             19
+#define R9A07G044_POEG_A_CLKP          20
+#define R9A07G044_POEG_B_CLKP          21
+#define R9A07G044_POEG_C_CLKP          22
+#define R9A07G044_POEG_D_CLKP          23
+#define R9A07G044_WDT0_PCLK            24
+#define R9A07G044_WDT0_CLK             25
+#define R9A07G044_WDT1_PCLK            26
+#define R9A07G044_WDT1_CLK             27
+#define R9A07G044_WDT2_PCLK            28
+#define R9A07G044_WDT2_CLK             29
+#define R9A07G044_SPI_CLK2             30
+#define R9A07G044_SPI_CLK              31
+#define R9A07G044_SDHI0_IMCLK          32
+#define R9A07G044_SDHI0_IMCLK2         33
+#define R9A07G044_SDHI0_CLK_HS         34
+#define R9A07G044_SDHI0_ACLK           35
+#define R9A07G044_SDHI1_IMCLK          36
+#define R9A07G044_SDHI1_IMCLK2         37
+#define R9A07G044_SDHI1_CLK_HS         38
+#define R9A07G044_SDHI1_ACLK           39
+#define R9A07G044_GPU_CLK              40
+#define R9A07G044_GPU_AXI_CLK          41
+#define R9A07G044_GPU_ACE_CLK          42
+#define R9A07G044_ISU_ACLK             43
+#define R9A07G044_ISU_PCLK             44
+#define R9A07G044_H264_CLK_A           45
+#define R9A07G044_H264_CLK_P           46
+#define R9A07G044_CRU_SYSCLK           47
+#define R9A07G044_CRU_VCLK             48
+#define R9A07G044_CRU_PCLK             49
+#define R9A07G044_CRU_ACLK             50
+#define R9A07G044_MIPI_DSI_PLLCLK      51
+#define R9A07G044_MIPI_DSI_SYSCLK      52
+#define R9A07G044_MIPI_DSI_ACLK                53
+#define R9A07G044_MIPI_DSI_PCLK                54
+#define R9A07G044_MIPI_DSI_VCLK                55
+#define R9A07G044_MIPI_DSI_LPCLK       56
+#define R9A07G044_LCDC_CLK_A           57
+#define R9A07G044_LCDC_CLK_P           58
+#define R9A07G044_LCDC_CLK_D           59
+#define R9A07G044_SSI0_PCLK2           60
+#define R9A07G044_SSI0_PCLK_SFR                61
+#define R9A07G044_SSI1_PCLK2           62
+#define R9A07G044_SSI1_PCLK_SFR                63
+#define R9A07G044_SSI2_PCLK2           64
+#define R9A07G044_SSI2_PCLK_SFR                65
+#define R9A07G044_SSI3_PCLK2           66
+#define R9A07G044_SSI3_PCLK_SFR                67
+#define R9A07G044_SRC_CLKP             68
+#define R9A07G044_USB_U2H0_HCLK                69
+#define R9A07G044_USB_U2H1_HCLK                70
+#define R9A07G044_USB_U2P_EXR_CPUCLK   71
+#define R9A07G044_USB_PCLK             72
+#define R9A07G044_ETH0_CLK_AXI         73
+#define R9A07G044_ETH0_CLK_CHI         74
+#define R9A07G044_ETH1_CLK_AXI         75
+#define R9A07G044_ETH1_CLK_CHI         76
+#define R9A07G044_I2C0_PCLK            77
+#define R9A07G044_I2C1_PCLK            78
+#define R9A07G044_I2C2_PCLK            79
+#define R9A07G044_I2C3_PCLK            80
+#define R9A07G044_SCIF0_CLK_PCK                81
+#define R9A07G044_SCIF1_CLK_PCK                82
+#define R9A07G044_SCIF2_CLK_PCK                83
+#define R9A07G044_SCIF3_CLK_PCK                84
+#define R9A07G044_SCIF4_CLK_PCK                85
+#define R9A07G044_SCI0_CLKP            86
+#define R9A07G044_SCI1_CLKP            87
+#define R9A07G044_IRDA_CLKP            88
+#define R9A07G044_RSPI0_CLKB           89
+#define R9A07G044_RSPI1_CLKB           90
+#define R9A07G044_RSPI2_CLKB           91
+#define R9A07G044_CANFD_PCLK           92
+#define R9A07G044_GPIO_HCLK            93
+#define R9A07G044_ADC_ADCLK            94
+#define R9A07G044_ADC_PCLK             95
+#define R9A07G044_TSU_PCLK             96
+
+/* R9A07G044 Resets */
+#define R9A07G044_CA55_RST_1_0         0
+#define R9A07G044_CA55_RST_1_1         1
+#define R9A07G044_CA55_RST_3_0         2
+#define R9A07G044_CA55_RST_3_1         3
+#define R9A07G044_CA55_RST_4           4
+#define R9A07G044_CA55_RST_5           5
+#define R9A07G044_CA55_RST_6           6
+#define R9A07G044_CA55_RST_7           7
+#define R9A07G044_CA55_RST_8           8
+#define R9A07G044_CA55_RST_9           9
+#define R9A07G044_CA55_RST_10          10
+#define R9A07G044_CA55_RST_11          11
+#define R9A07G044_CA55_RST_12          12
+#define R9A07G044_GIC600_GICRESET_N    13
+#define R9A07G044_GIC600_DBG_GICRESET_N        14
+#define R9A07G044_IA55_RESETN          15
+#define R9A07G044_MHU_RESETN           16
+#define R9A07G044_DMAC_ARESETN         17
+#define R9A07G044_DMAC_RST_ASYNC       18
+#define R9A07G044_SYC_RESETN           19
+#define R9A07G044_OSTM0_PRESETZ                20
+#define R9A07G044_OSTM1_PRESETZ                21
+#define R9A07G044_OSTM2_PRESETZ                22
+#define R9A07G044_MTU_X_PRESET_MTU3    23
+#define R9A07G044_POE3_RST_M_REG       24
+#define R9A07G044_GPT_RST_C            25
+#define R9A07G044_POEG_A_RST           26
+#define R9A07G044_POEG_B_RST           27
+#define R9A07G044_POEG_C_RST           28
+#define R9A07G044_POEG_D_RST           29
+#define R9A07G044_WDT0_PRESETN         30
+#define R9A07G044_WDT1_PRESETN         31
+#define R9A07G044_WDT2_PRESETN         32
+#define R9A07G044_SPI_RST              33
+#define R9A07G044_SDHI0_IXRST          34
+#define R9A07G044_SDHI1_IXRST          35
+#define R9A07G044_GPU_RESETN           36
+#define R9A07G044_GPU_AXI_RESETN       37
+#define R9A07G044_GPU_ACE_RESETN       38
+#define R9A07G044_ISU_ARESETN          39
+#define R9A07G044_ISU_PRESETN          40
+#define R9A07G044_H264_X_RESET_VCP     41
+#define R9A07G044_H264_CP_PRESET_P     42
+#define R9A07G044_CRU_CMN_RSTB         43
+#define R9A07G044_CRU_PRESETN          44
+#define R9A07G044_CRU_ARESETN          45
+#define R9A07G044_MIPI_DSI_CMN_RSTB    46
+#define R9A07G044_MIPI_DSI_ARESET_N    47
+#define R9A07G044_MIPI_DSI_PRESET_N    48
+#define R9A07G044_LCDC_RESET_N         49
+#define R9A07G044_SSI0_RST_M2_REG      50
+#define R9A07G044_SSI1_RST_M2_REG      51
+#define R9A07G044_SSI2_RST_M2_REG      52
+#define R9A07G044_SSI3_RST_M2_REG      53
+#define R9A07G044_SRC_RST              54
+#define R9A07G044_USB_U2H0_HRESETN     55
+#define R9A07G044_USB_U2H1_HRESETN     56
+#define R9A07G044_USB_U2P_EXL_SYSRST   57
+#define R9A07G044_USB_PRESETN          58
+#define R9A07G044_ETH0_RST_HW_N                59
+#define R9A07G044_ETH1_RST_HW_N                60
+#define R9A07G044_I2C0_MRST            61
+#define R9A07G044_I2C1_MRST            62
+#define R9A07G044_I2C2_MRST            63
+#define R9A07G044_I2C3_MRST            64
+#define R9A07G044_SCIF0_RST_SYSTEM_N   65
+#define R9A07G044_SCIF1_RST_SYSTEM_N   66
+#define R9A07G044_SCIF2_RST_SYSTEM_N   67
+#define R9A07G044_SCIF3_RST_SYSTEM_N   68
+#define R9A07G044_SCIF4_RST_SYSTEM_N   69
+#define R9A07G044_SCI0_RST             70
+#define R9A07G044_SCI1_RST             71
+#define R9A07G044_IRDA_RST             72
+#define R9A07G044_RSPI0_RST            73
+#define R9A07G044_RSPI1_RST            74
+#define R9A07G044_RSPI2_RST            75
+#define R9A07G044_CANFD_RSTP_N         76
+#define R9A07G044_CANFD_RSTC_N         77
+#define R9A07G044_GPIO_RSTN            78
+#define R9A07G044_GPIO_PORT_RESETN     79
+#define R9A07G044_GPIO_SPARE_RESETN    80
+#define R9A07G044_ADC_PRESETN          81
+#define R9A07G044_ADC_ADRST_N          82
+#define R9A07G044_TSU_PRESETN          83
 
 #endif /* __DT_BINDINGS_CLOCK_R9A07G044_CPG_H__ */
index f309fc1..e8e2b03 100644 (file)
@@ -780,6 +780,7 @@ struct bpf_jit_poke_descriptor {
        void *tailcall_target;
        void *tailcall_bypass;
        void *bypass_addr;
+       void *aux;
        union {
                struct {
                        struct bpf_map *map;
index d83b829..7be81d5 100644 (file)
@@ -342,7 +342,7 @@ struct clk_fixed_rate {
        unsigned long   flags;
 };
 
-#define CLK_FIXED_RATE_PARENT_ACCURACY         BIT(0)
+#define CLK_FIXED_RATE_PARENT_ACCURACY BIT(0)
 
 extern const struct clk_ops clk_fixed_rate_ops;
 struct clk_hw *__clk_hw_register_fixed_rate(struct device *dev,
@@ -1020,8 +1020,8 @@ struct clk_fractional_divider {
 
 #define to_clk_fd(_hw) container_of(_hw, struct clk_fractional_divider, hw)
 
-#define CLK_FRAC_DIVIDER_ZERO_BASED            BIT(0)
-#define CLK_FRAC_DIVIDER_BIG_ENDIAN            BIT(1)
+#define CLK_FRAC_DIVIDER_ZERO_BASED    BIT(0)
+#define CLK_FRAC_DIVIDER_BIG_ENDIAN    BIT(1)
 
 extern const struct clk_ops clk_fractional_divider_ops;
 struct clk *clk_register_fractional_divider(struct device *dev,
@@ -1069,9 +1069,9 @@ struct clk_multiplier {
 
 #define to_clk_multiplier(_hw) container_of(_hw, struct clk_multiplier, hw)
 
-#define CLK_MULTIPLIER_ZERO_BYPASS             BIT(0)
+#define CLK_MULTIPLIER_ZERO_BYPASS     BIT(0)
 #define CLK_MULTIPLIER_ROUND_CLOSEST   BIT(1)
-#define CLK_MULTIPLIER_BIG_ENDIAN              BIT(2)
+#define CLK_MULTIPLIER_BIG_ENDIAN      BIT(2)
 
 extern const struct clk_ops clk_multiplier_ops;
 
index 29dbb60..232daae 100644 (file)
@@ -757,6 +757,16 @@ void
 ethtool_params_from_link_mode(struct ethtool_link_ksettings *link_ksettings,
                              enum ethtool_link_mode_bit_indices link_mode);
 
+/**
+ * ethtool_get_phc_vclocks - Derive phc vclocks information, and caller
+ *                           is responsible to free memory of vclock_index
+ * @dev: pointer to net_device structure
+ * @vclock_index: pointer to pointer of vclock index
+ *
+ * Return number of phc vclocks
+ */
+int ethtool_get_phc_vclocks(struct net_device *dev, int **vclock_index);
+
 /**
  * ethtool_sprintf - Write formatted string to ethtool string data
  * @data: Pointer to start of string to update
index 37e1e8f..e2bc163 100644 (file)
@@ -139,6 +139,8 @@ extern int vfs_parse_fs_string(struct fs_context *fc, const char *key,
 extern int generic_parse_monolithic(struct fs_context *fc, void *data);
 extern int vfs_get_tree(struct fs_context *fc);
 extern void put_fs_context(struct fs_context *fc);
+extern int vfs_parse_fs_param_source(struct fs_context *fc,
+                                    struct fs_parameter *param);
 
 /*
  * sget() wrappers to be called from the ->get_tree() op.
index 5310e21..dd874a1 100644 (file)
@@ -3,6 +3,7 @@
 #define _LINUX_KASAN_H
 
 #include <linux/bug.h>
+#include <linux/kernel.h>
 #include <linux/static_key.h>
 #include <linux/types.h>
 
index acee44b..0f06c22 100644 (file)
 #define MARVELL_PHY_ID_88E1545         0x01410ea0
 #define MARVELL_PHY_ID_88E1548P                0x01410ec0
 #define MARVELL_PHY_ID_88E3016         0x01410e60
+#define MARVELL_PHY_ID_88X3310         0x002b09a0
 #define MARVELL_PHY_ID_88E2110         0x002b09b0
 #define MARVELL_PHY_ID_88X2222         0x01410f10
 
-/* PHY IDs and mask for Alaska 10G PHYs */
-#define MARVELL_PHY_ID_88X33X0_MASK    0xfffffff8
-#define MARVELL_PHY_ID_88X3310         0x002b09a0
-#define MARVELL_PHY_ID_88X3340         0x002b09a8
-
 /* Marvel 88E1111 in Finisar SFP module with modified PHY ID */
 #define MARVELL_PHY_ID_88E1111_FINISAR 0x01ff0cc0
 
index 9b7b7cd..23dadf7 100644 (file)
@@ -51,7 +51,6 @@ extern int migrate_huge_page_move_mapping(struct address_space *mapping,
                                  struct page *newpage, struct page *page);
 extern int migrate_page_move_mapping(struct address_space *mapping,
                struct page *newpage, struct page *page, int extra_count);
-extern void copy_huge_page(struct page *dst, struct page *src);
 #else
 
 static inline void putback_movable_pages(struct list_head *l) {}
@@ -77,10 +76,6 @@ static inline int migrate_huge_page_move_mapping(struct address_space *mapping,
 {
        return -ENOSYS;
 }
-
-static inline void copy_huge_page(struct page *dst, struct page *src)
-{
-}
 #endif /* CONFIG_MIGRATION */
 
 #ifdef CONFIG_COMPACTION
index 57453db..7ca22e6 100644 (file)
@@ -906,6 +906,7 @@ void __put_page(struct page *page);
 void put_pages_list(struct list_head *pages);
 
 void split_page(struct page *page, unsigned int order);
+void copy_huge_page(struct page *dst, struct page *src);
 
 /*
  * Compound pages have a destructor function.  Provide a
index 207e1a3..41df326 100644 (file)
@@ -15,6 +15,6 @@ struct lpss_clk_data {
        struct clk *clk;
 };
 
-extern int lpt_clk_init(void);
+extern int lpss_atom_clk_init(void);
 
 #endif /* __CLK_LPSS_H */
index 8ddc786..ada3a0a 100644 (file)
@@ -47,6 +47,7 @@ extern void pm_clk_remove(struct device *dev, const char *con_id);
 extern void pm_clk_remove_clk(struct device *dev, struct clk *clk);
 extern int pm_clk_suspend(struct device *dev);
 extern int pm_clk_resume(struct device *dev);
+extern int devm_pm_clk_create(struct device *dev);
 #else
 static inline bool pm_clk_no_clocks(struct device *dev)
 {
@@ -83,6 +84,10 @@ static inline void pm_clk_remove(struct device *dev, const char *con_id)
 static inline void pm_clk_remove_clk(struct device *dev, struct clk *clk)
 {
 }
+static inline int devm_pm_clk_create(struct device *dev)
+{
+       return -EINVAL;
+}
 #endif
 
 #ifdef CONFIG_HAVE_CLK
index aab8b35..222da43 100644 (file)
@@ -59,6 +59,8 @@ extern void pm_runtime_put_suppliers(struct device *dev);
 extern void pm_runtime_new_link(struct device *dev);
 extern void pm_runtime_drop_link(struct device_link *link);
 
+extern int devm_pm_runtime_enable(struct device *dev);
+
 /**
  * pm_runtime_get_if_in_use - Conditionally bump up runtime PM usage counter.
  * @dev: Target device.
@@ -253,6 +255,8 @@ static inline void __pm_runtime_disable(struct device *dev, bool c) {}
 static inline void pm_runtime_allow(struct device *dev) {}
 static inline void pm_runtime_forbid(struct device *dev) {}
 
+static inline int devm_pm_runtime_enable(struct device *dev) { return 0; }
+
 static inline void pm_suspend_ignore_children(struct device *dev, bool enable) {}
 static inline void pm_runtime_get_noresume(struct device *dev) {}
 static inline void pm_runtime_put_noidle(struct device *dev) {}
index aba237c..71fac92 100644 (file)
 #include <linux/device.h>
 #include <linux/pps_kernel.h>
 #include <linux/ptp_clock.h>
+#include <linux/timecounter.h>
+#include <linux/skbuff.h>
 
+#define PTP_CLOCK_NAME_LEN     32
 /**
  * struct ptp_clock_request - request PTP clock event
  *
@@ -134,7 +137,7 @@ struct ptp_system_timestamp {
 
 struct ptp_clock_info {
        struct module *owner;
-       char name[16];
+       char name[PTP_CLOCK_NAME_LEN];
        s32 max_adj;
        int n_alarm;
        int n_ext_ts;
@@ -304,6 +307,27 @@ int ptp_schedule_worker(struct ptp_clock *ptp, unsigned long delay);
  */
 void ptp_cancel_worker_sync(struct ptp_clock *ptp);
 
+/**
+ * ptp_get_vclocks_index() - get all vclocks index on pclock, and
+ *                           caller is responsible to free memory
+ *                           of vclock_index
+ *
+ * @pclock_index: phc index of ptp pclock.
+ * @vclock_index: pointer to pointer of vclock index.
+ *
+ * return number of vclocks.
+ */
+int ptp_get_vclocks_index(int pclock_index, int **vclock_index);
+
+/**
+ * ptp_convert_timestamp() - convert timestamp to a ptp vclock time
+ *
+ * @hwtstamps:    skb_shared_hwtstamps structure pointer
+ * @vclock_index: phc index of ptp vclock.
+ */
+void ptp_convert_timestamp(struct skb_shared_hwtstamps *hwtstamps,
+                          int vclock_index);
+
 #else
 static inline struct ptp_clock *ptp_clock_register(struct ptp_clock_info *info,
                                                   struct device *parent)
@@ -323,6 +347,11 @@ static inline int ptp_schedule_worker(struct ptp_clock *ptp,
 { return -EOPNOTSUPP; }
 static inline void ptp_cancel_worker_sync(struct ptp_clock *ptp)
 { }
+static inline int ptp_get_vclocks_index(int pclock_index, int **vclock_index)
+{ return 0; }
+static inline void ptp_convert_timestamp(struct skb_shared_hwtstamps *hwtstamps,
+                                        int vclock_index)
+{ }
 
 #endif
 
index 83fb861..c976cc6 100644 (file)
@@ -291,7 +291,9 @@ static inline int page_referenced(struct page *page, int is_locked,
        return 0;
 }
 
-#define try_to_unmap(page, refs) false
+static inline void try_to_unmap(struct page *page, enum ttu_flags flags)
+{
+}
 
 static inline int page_mkclean(struct page *page)
 {
index 79d0a12..80e781c 100644 (file)
@@ -101,6 +101,10 @@ struct scmi_clk_proto_ops {
  *     to sustained performance level mapping
  * @est_power_get: gets the estimated power cost for a given performance domain
  *     at a given frequency
+ * @fast_switch_possible: indicates if fast DVFS switching is possible or not
+ *     for a given device
+ * @power_scale_mw_get: indicates if the power values provided are in milliWatts
+ *     or in some other (abstract) scale
  */
 struct scmi_perf_proto_ops {
        int (*limits_set)(const struct scmi_protocol_handle *ph, u32 domain,
@@ -153,7 +157,7 @@ struct scmi_power_proto_ops {
 };
 
 /**
- * scmi_sensor_reading  - represent a timestamped read
+ * struct scmi_sensor_reading  - represent a timestamped read
  *
  * Used by @reading_get_timestamped method.
  *
@@ -167,7 +171,7 @@ struct scmi_sensor_reading {
 };
 
 /**
- * scmi_range_attrs  - specifies a sensor or axis values' range
+ * struct scmi_range_attrs  - specifies a sensor or axis values' range
  * @min_range: The minimum value which can be represented by the sensor/axis.
  * @max_range: The maximum value which can be represented by the sensor/axis.
  */
@@ -177,7 +181,7 @@ struct scmi_range_attrs {
 };
 
 /**
- * scmi_sensor_axis_info  - describes one sensor axes
+ * struct scmi_sensor_axis_info  - describes one sensor axes
  * @id: The axes ID.
  * @type: Axes type. Chosen amongst one of @enum scmi_sensor_class.
  * @scale: Power-of-10 multiplier applied to the axis unit.
@@ -205,8 +209,8 @@ struct scmi_sensor_axis_info {
 };
 
 /**
- * scmi_sensor_intervals_info  - describes number and type of available update
- * intervals
+ * struct scmi_sensor_intervals_info  - describes number and type of available
+ *     update intervals
  * @segmented: Flag for segmented intervals' representation. When True there
  *            will be exactly 3 intervals in @desc, with each entry
  *            representing a member of a segment in this order:
index afbf803..d2176a5 100644 (file)
@@ -51,6 +51,14 @@ struct scpi_sensor_info {
  *     OPP is an index to the list return by @dvfs_get_info
  * @dvfs_get_info: returns the DVFS capabilities of the given power
  *     domain. It includes the OPP list and the latency information
+ * @device_domain_id: gets the scpi domain id for a given device
+ * @get_transition_latency: gets the DVFS transition latency for a given device
+ * @add_opps_to_device: adds all the OPPs for a given device
+ * @sensor_get_capability: get the list of capabilities for the sensors
+ * @sensor_get_info: get the information of the specified sensor
+ * @sensor_get_value: gets the current value of the sensor
+ * @device_get_power_state: gets the power state of a power domain
+ * @device_set_power_state: sets the power state of a power domain
  */
 struct scpi_ops {
        u32 (*get_version)(void);
index f2645ec..60e66fc 100644 (file)
@@ -29,6 +29,7 @@ struct qcom_smd_rpm;
 #define QCOM_SMD_RPM_NCPB      0x6270636E
 #define QCOM_SMD_RPM_OCMEM_PWR 0x706d636f
 #define QCOM_SMD_RPM_QPIC_CLK  0x63697071
+#define QCOM_SMD_RPM_QUP_CLK   0x707571
 #define QCOM_SMD_RPM_SMPA      0x61706d73
 #define QCOM_SMD_RPM_SMPB      0x62706d73
 #define QCOM_SMD_RPM_SPDM      0x63707362
index d5ae621..a6f03b3 100644 (file)
@@ -115,7 +115,9 @@ struct stmmac_axi {
 
 #define EST_GCL                1024
 struct stmmac_est {
+       struct mutex lock;
        int enable;
+       u32 btr_reserve[2];
        u32 btr_offset[2];
        u32 btr[2];
        u32 ctr[2];
index 143568d..4b57bbb 100644 (file)
@@ -338,7 +338,7 @@ do {                                                                             \
        FP_SET_EXCEPTION(FP_EX_INVALID | FP_EX_INVALID_ISI);                 \
        break;                                                               \
       }                                                                             \
-    /* FALLTHRU */                                                          \
+    fallthrough;                                                            \
                                                                             \
   case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NORMAL):                           \
   case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_ZERO):                                     \
index 1533573..625d9c7 100644 (file)
@@ -201,6 +201,11 @@ struct bond_up_slave {
  */
 #define BOND_LINK_NOCHANGE -1
 
+struct bond_ipsec {
+       struct list_head list;
+       struct xfrm_state *xs;
+};
+
 /*
  * Here are the locking policies for the two bonding locks:
  * Get rcu_read_lock when reading or RTNL when writing slave list.
@@ -249,7 +254,9 @@ struct bonding {
 #endif /* CONFIG_DEBUG_FS */
        struct rtnl_link_stats64 bond_stats;
 #ifdef CONFIG_XFRM_OFFLOAD
-       struct xfrm_state *xs;
+       struct list_head ipsec_list;
+       /* protecting ipsec_list */
+       spinlock_t ipsec_lock;
 #endif /* CONFIG_XFRM_OFFLOAD */
 };
 
index 73af4a6..40296ed 100644 (file)
@@ -38,7 +38,7 @@ static inline bool net_busy_loop_on(void)
 
 static inline bool sk_can_busy_loop(const struct sock *sk)
 {
-       return sk->sk_ll_usec && !signal_pending(current);
+       return READ_ONCE(sk->sk_ll_usec) && !signal_pending(current);
 }
 
 bool sk_busy_loop_end(void *p, unsigned long start_time);
diff --git a/include/net/caif/caif_hsi.h b/include/net/caif/caif_hsi.h
deleted file mode 100644 (file)
index 552cf68..0000000
+++ /dev/null
@@ -1,200 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * Copyright (C) ST-Ericsson AB 2010
- * Author:  Daniel Martensson / daniel.martensson@stericsson.com
- *         Dmitry.Tarnyagin  / dmitry.tarnyagin@stericsson.com
- */
-
-#ifndef CAIF_HSI_H_
-#define CAIF_HSI_H_
-
-#include <net/caif/caif_layer.h>
-#include <net/caif/caif_device.h>
-#include <linux/atomic.h>
-
-/*
- * Maximum number of CAIF frames that can reside in the same HSI frame.
- */
-#define CFHSI_MAX_PKTS 15
-
-/*
- * Maximum number of bytes used for the frame that can be embedded in the
- * HSI descriptor.
- */
-#define CFHSI_MAX_EMB_FRM_SZ 96
-
-/*
- * Decides if HSI buffers should be prefilled with 0xFF pattern for easier
- * debugging. Both TX and RX buffers will be filled before the transfer.
- */
-#define CFHSI_DBG_PREFILL              0
-
-/* Structure describing a HSI packet descriptor. */
-#pragma pack(1) /* Byte alignment. */
-struct cfhsi_desc {
-       u8 header;
-       u8 offset;
-       u16 cffrm_len[CFHSI_MAX_PKTS];
-       u8 emb_frm[CFHSI_MAX_EMB_FRM_SZ];
-};
-#pragma pack() /* Default alignment. */
-
-/* Size of the complete HSI packet descriptor. */
-#define CFHSI_DESC_SZ (sizeof(struct cfhsi_desc))
-
-/*
- * Size of the complete HSI packet descriptor excluding the optional embedded
- * CAIF frame.
- */
-#define CFHSI_DESC_SHORT_SZ (CFHSI_DESC_SZ - CFHSI_MAX_EMB_FRM_SZ)
-
-/*
- * Maximum bytes transferred in one transfer.
- */
-#define CFHSI_MAX_CAIF_FRAME_SZ 4096
-
-#define CFHSI_MAX_PAYLOAD_SZ (CFHSI_MAX_PKTS * CFHSI_MAX_CAIF_FRAME_SZ)
-
-/* Size of the complete HSI TX buffer. */
-#define CFHSI_BUF_SZ_TX (CFHSI_DESC_SZ + CFHSI_MAX_PAYLOAD_SZ)
-
-/* Size of the complete HSI RX buffer. */
-#define CFHSI_BUF_SZ_RX ((2 * CFHSI_DESC_SZ) + CFHSI_MAX_PAYLOAD_SZ)
-
-/* Bitmasks for the HSI descriptor. */
-#define CFHSI_PIGGY_DESC               (0x01 << 7)
-
-#define CFHSI_TX_STATE_IDLE                    0
-#define CFHSI_TX_STATE_XFER                    1
-
-#define CFHSI_RX_STATE_DESC                    0
-#define CFHSI_RX_STATE_PAYLOAD                 1
-
-/* Bitmasks for power management. */
-#define CFHSI_WAKE_UP                          0
-#define CFHSI_WAKE_UP_ACK                      1
-#define CFHSI_WAKE_DOWN_ACK                    2
-#define CFHSI_AWAKE                            3
-#define CFHSI_WAKELOCK_HELD                    4
-#define CFHSI_SHUTDOWN                         5
-#define CFHSI_FLUSH_FIFO                       6
-
-#ifndef CFHSI_INACTIVITY_TOUT
-#define CFHSI_INACTIVITY_TOUT                  (1 * HZ)
-#endif /* CFHSI_INACTIVITY_TOUT */
-
-#ifndef CFHSI_WAKE_TOUT
-#define CFHSI_WAKE_TOUT                        (3 * HZ)
-#endif /* CFHSI_WAKE_TOUT */
-
-#ifndef CFHSI_MAX_RX_RETRIES
-#define CFHSI_MAX_RX_RETRIES           (10 * HZ)
-#endif
-
-/* Structure implemented by the CAIF HSI driver. */
-struct cfhsi_cb_ops {
-       void (*tx_done_cb) (struct cfhsi_cb_ops *drv);
-       void (*rx_done_cb) (struct cfhsi_cb_ops *drv);
-       void (*wake_up_cb) (struct cfhsi_cb_ops *drv);
-       void (*wake_down_cb) (struct cfhsi_cb_ops *drv);
-};
-
-/* Structure implemented by HSI device. */
-struct cfhsi_ops {
-       int (*cfhsi_up) (struct cfhsi_ops *dev);
-       int (*cfhsi_down) (struct cfhsi_ops *dev);
-       int (*cfhsi_tx) (u8 *ptr, int len, struct cfhsi_ops *dev);
-       int (*cfhsi_rx) (u8 *ptr, int len, struct cfhsi_ops *dev);
-       int (*cfhsi_wake_up) (struct cfhsi_ops *dev);
-       int (*cfhsi_wake_down) (struct cfhsi_ops *dev);
-       int (*cfhsi_get_peer_wake) (struct cfhsi_ops *dev, bool *status);
-       int (*cfhsi_fifo_occupancy) (struct cfhsi_ops *dev, size_t *occupancy);
-       int (*cfhsi_rx_cancel)(struct cfhsi_ops *dev);
-       struct cfhsi_cb_ops *cb_ops;
-};
-
-/* Structure holds status of received CAIF frames processing */
-struct cfhsi_rx_state {
-       int state;
-       int nfrms;
-       int pld_len;
-       int retries;
-       bool piggy_desc;
-};
-
-/* Priority mapping */
-enum {
-       CFHSI_PRIO_CTL = 0,
-       CFHSI_PRIO_VI,
-       CFHSI_PRIO_VO,
-       CFHSI_PRIO_BEBK,
-       CFHSI_PRIO_LAST,
-};
-
-struct cfhsi_config {
-       u32 inactivity_timeout;
-       u32 aggregation_timeout;
-       u32 head_align;
-       u32 tail_align;
-       u32 q_high_mark;
-       u32 q_low_mark;
-};
-
-/* Structure implemented by CAIF HSI drivers. */
-struct cfhsi {
-       struct caif_dev_common cfdev;
-       struct net_device *ndev;
-       struct platform_device *pdev;
-       struct sk_buff_head qhead[CFHSI_PRIO_LAST];
-       struct cfhsi_cb_ops cb_ops;
-       struct cfhsi_ops *ops;
-       int tx_state;
-       struct cfhsi_rx_state rx_state;
-       struct cfhsi_config cfg;
-       int rx_len;
-       u8 *rx_ptr;
-       u8 *tx_buf;
-       u8 *rx_buf;
-       u8 *rx_flip_buf;
-       spinlock_t lock;
-       int flow_off_sent;
-       struct list_head list;
-       struct work_struct wake_up_work;
-       struct work_struct wake_down_work;
-       struct work_struct out_of_sync_work;
-       struct workqueue_struct *wq;
-       wait_queue_head_t wake_up_wait;
-       wait_queue_head_t wake_down_wait;
-       wait_queue_head_t flush_fifo_wait;
-       struct timer_list inactivity_timer;
-       struct timer_list rx_slowpath_timer;
-
-       /* TX aggregation */
-       int aggregation_len;
-       struct timer_list aggregation_timer;
-
-       unsigned long bits;
-};
-extern struct platform_driver cfhsi_driver;
-
-/**
- * enum ifla_caif_hsi - CAIF HSI NetlinkRT parameters.
- * @IFLA_CAIF_HSI_INACTIVITY_TOUT: Inactivity timeout before
- *                     taking the HSI wakeline down, in milliseconds.
- * When using RT Netlink to create, destroy or configure a CAIF HSI interface,
- * enum ifla_caif_hsi is used to specify the configuration attributes.
- */
-enum ifla_caif_hsi {
-       __IFLA_CAIF_HSI_UNSPEC,
-       __IFLA_CAIF_HSI_INACTIVITY_TOUT,
-       __IFLA_CAIF_HSI_AGGREGATION_TOUT,
-       __IFLA_CAIF_HSI_HEAD_ALIGN,
-       __IFLA_CAIF_HSI_TAIL_ALIGN,
-       __IFLA_CAIF_HSI_QHIGH_WATERMARK,
-       __IFLA_CAIF_HSI_QLOW_WATERMARK,
-       __IFLA_CAIF_HSI_MAX
-};
-
-struct cfhsi_ops *cfhsi_get_ops(void);
-
-#endif         /* CAIF_HSI_H_ */
index 56cb3c3..14efa0d 100644 (file)
@@ -45,7 +45,9 @@ skb_tunnel_info(const struct sk_buff *skb)
                return &md_dst->u.tun_info;
 
        dst = skb_dst(skb);
-       if (dst && dst->lwtstate)
+       if (dst && dst->lwtstate &&
+           (dst->lwtstate->type == LWTUNNEL_ENCAP_IP ||
+            dst->lwtstate->type == LWTUNNEL_ENCAP_IP6))
                return lwt_tun_info(dst->lwtstate);
 
        return NULL;
index f14149d..625a38c 100644 (file)
@@ -263,7 +263,7 @@ static inline bool ipv6_anycast_destination(const struct dst_entry *dst,
 int ip6_fragment(struct net *net, struct sock *sk, struct sk_buff *skb,
                 int (*output)(struct net *, struct sock *, struct sk_buff *));
 
-static inline int ip6_skb_dst_mtu(struct sk_buff *skb)
+static inline unsigned int ip6_skb_dst_mtu(struct sk_buff *skb)
 {
        int mtu;
 
index cb580b0..8b5af68 100644 (file)
@@ -105,7 +105,7 @@ bool mptcp_synack_options(const struct request_sock *req, unsigned int *size,
 bool mptcp_established_options(struct sock *sk, struct sk_buff *skb,
                               unsigned int *size, unsigned int remaining,
                               struct mptcp_out_options *opts);
-void mptcp_incoming_options(struct sock *sk, struct sk_buff *skb);
+bool mptcp_incoming_options(struct sock *sk, struct sk_buff *skb);
 
 void mptcp_write_options(__be32 *ptr, const struct tcp_sock *tp,
                         struct mptcp_out_options *opts);
@@ -227,9 +227,10 @@ static inline bool mptcp_established_options(struct sock *sk,
        return false;
 }
 
-static inline void mptcp_incoming_options(struct sock *sk,
+static inline bool mptcp_incoming_options(struct sock *sk,
                                          struct sk_buff *skb)
 {
+       return true;
 }
 
 static inline void mptcp_skb_ext_move(struct sk_buff *to,
index 09f2efe..13807ea 100644 (file)
@@ -30,7 +30,6 @@ void nf_conntrack_cleanup_net(struct net *net);
 void nf_conntrack_cleanup_net_list(struct list_head *net_exit_list);
 
 void nf_conntrack_proto_pernet_init(struct net *net);
-void nf_conntrack_proto_pernet_fini(struct net *net);
 
 int nf_conntrack_proto_init(void);
 void nf_conntrack_proto_fini(void);
index c3094b8..37e5300 100644 (file)
@@ -27,6 +27,7 @@ struct nf_tcp_net {
        u8 tcp_loose;
        u8 tcp_be_liberal;
        u8 tcp_max_retrans;
+       u8 tcp_ignore_invalid_rst;
 #if IS_ENABLED(CONFIG_NF_FLOW_TABLE)
        unsigned int offload_timeout;
        unsigned int offload_pickup;
index 265fffa..5859e0a 100644 (file)
@@ -360,8 +360,7 @@ enum {
 #define SCTP_SCOPE_POLICY_MAX  SCTP_SCOPE_POLICY_LINK
 
 /* Based on IPv4 scoping <draft-stewart-tsvwg-sctp-ipv4-00.txt>,
- * SCTP IPv4 unusable addresses: 0.0.0.0/8, 224.0.0.0/4, 198.18.0.0/24,
- * 192.88.99.0/24.
+ * SCTP IPv4 unusable addresses: 0.0.0.0/8, 224.0.0.0/4, 192.88.99.0/24.
  * Also, RFC 8.4, non-unicast addresses are not considered valid SCTP
  * addresses.
  */
@@ -369,7 +368,6 @@ enum {
        ((htonl(INADDR_BROADCAST) == a) ||  \
         ipv4_is_multicast(a) ||            \
         ipv4_is_zeronet(a) ||              \
-        ipv4_is_test_198(a) ||             \
         ipv4_is_anycast_6to4(a))
 
 /* Flags used for the bind address copy functions.  */
index 8bdd800..f23cb25 100644 (file)
@@ -316,7 +316,9 @@ struct bpf_local_storage;
   *    @sk_timer: sock cleanup timer
   *    @sk_stamp: time stamp of last packet received
   *    @sk_stamp_seq: lock for accessing sk_stamp on 32 bit architectures only
-  *    @sk_tsflags: SO_TIMESTAMPING socket options
+  *    @sk_tsflags: SO_TIMESTAMPING flags
+  *    @sk_bind_phc: SO_TIMESTAMPING bind PHC index of PTP virtual clock
+  *                  for timestamping
   *    @sk_tskey: counter to disambiguate concurrent tstamp requests
   *    @sk_zckey: counter to order MSG_ZEROCOPY notifications
   *    @sk_socket: Identd and reporting IO signals
@@ -493,6 +495,7 @@ struct sock {
        seqlock_t               sk_stamp_seq;
 #endif
        u16                     sk_tsflags;
+       int                     sk_bind_phc;
        u8                      sk_shutdown;
        u32                     sk_tskey;
        atomic_t                sk_zckey;
@@ -2755,7 +2758,8 @@ void sock_def_readable(struct sock *sk);
 
 int sock_bindtoindex(struct sock *sk, int ifindex, bool lock_sk);
 void sock_set_timestamp(struct sock *sk, int optname, bool valbool);
-int sock_set_timestamping(struct sock *sk, int optname, int val);
+int sock_set_timestamping(struct sock *sk, int optname,
+                         struct so_timestamping timestamping);
 
 void sock_enable_timestamps(struct sock *sk);
 void sock_no_linger(struct sock *sk);
index e668f1b..17df9b0 100644 (file)
@@ -686,6 +686,10 @@ static inline u32 __tcp_set_rto(const struct tcp_sock *tp)
 
 static inline void __tcp_fast_path_on(struct tcp_sock *tp, u32 snd_wnd)
 {
+       /* mptcp hooks are only on the slow path */
+       if (sk_is_mptcp((struct sock *)tp))
+               return;
+
        tp->pred_flags = htonl((tp->tcp_header_len << 26) |
                               ntohl(TCP_FLAG_ACK) |
                               snd_wnd);
index e19c250..1066b11 100644 (file)
@@ -237,14 +237,19 @@ unsigned int tegra_mc_get_emem_device_count(struct tegra_mc *mc);
 
 #ifdef CONFIG_TEGRA_MC
 struct tegra_mc *devm_tegra_memory_controller_get(struct device *dev);
+int tegra_mc_probe_device(struct tegra_mc *mc, struct device *dev);
 #else
 static inline struct tegra_mc *
 devm_tegra_memory_controller_get(struct device *dev)
 {
        return ERR_PTR(-ENODEV);
 }
-#endif
 
-int tegra_mc_probe_device(struct tegra_mc *mc, struct device *dev);
+static inline int
+tegra_mc_probe_device(struct tegra_mc *mc, struct device *dev)
+{
+       return -ENODEV;
+}
+#endif
 
 #endif /* __SOC_TEGRA_MC_H__ */
index c7135c9..b3b9371 100644 (file)
@@ -46,6 +46,7 @@ enum {
        ETHTOOL_MSG_FEC_SET,
        ETHTOOL_MSG_MODULE_EEPROM_GET,
        ETHTOOL_MSG_STATS_GET,
+       ETHTOOL_MSG_PHC_VCLOCKS_GET,
 
        /* add new constants above here */
        __ETHTOOL_MSG_USER_CNT,
@@ -88,6 +89,7 @@ enum {
        ETHTOOL_MSG_FEC_NTF,
        ETHTOOL_MSG_MODULE_EEPROM_GET_REPLY,
        ETHTOOL_MSG_STATS_GET_REPLY,
+       ETHTOOL_MSG_PHC_VCLOCKS_GET_REPLY,
 
        /* add new constants above here */
        __ETHTOOL_MSG_KERNEL_CNT,
@@ -440,6 +442,19 @@ enum {
        ETHTOOL_A_TSINFO_MAX = (__ETHTOOL_A_TSINFO_CNT - 1)
 };
 
+/* PHC VCLOCKS */
+
+enum {
+       ETHTOOL_A_PHC_VCLOCKS_UNSPEC,
+       ETHTOOL_A_PHC_VCLOCKS_HEADER,                   /* nest - _A_HEADER_* */
+       ETHTOOL_A_PHC_VCLOCKS_NUM,                      /* u32 */
+       ETHTOOL_A_PHC_VCLOCKS_INDEX,                    /* array, s32 */
+
+       /* add new constants above here */
+       __ETHTOOL_A_PHC_VCLOCKS_CNT,
+       ETHTOOL_A_PHC_VCLOCKS_MAX = (__ETHTOOL_A_PHC_VCLOCKS_CNT - 1)
+};
+
 /* CABLE TEST */
 
 enum {
index 7ed0b3d..fcc61c7 100644 (file)
@@ -13,7 +13,7 @@
 #include <linux/types.h>
 #include <linux/socket.h>   /* for SO_TIMESTAMPING */
 
-/* SO_TIMESTAMPING gets an integer bit field comprised of these values */
+/* SO_TIMESTAMPING flags */
 enum {
        SOF_TIMESTAMPING_TX_HARDWARE = (1<<0),
        SOF_TIMESTAMPING_TX_SOFTWARE = (1<<1),
@@ -30,8 +30,9 @@ enum {
        SOF_TIMESTAMPING_OPT_STATS = (1<<12),
        SOF_TIMESTAMPING_OPT_PKTINFO = (1<<13),
        SOF_TIMESTAMPING_OPT_TX_SWHW = (1<<14),
+       SOF_TIMESTAMPING_BIND_PHC = (1 << 15),
 
-       SOF_TIMESTAMPING_LAST = SOF_TIMESTAMPING_OPT_TX_SWHW,
+       SOF_TIMESTAMPING_LAST = SOF_TIMESTAMPING_BIND_PHC,
        SOF_TIMESTAMPING_MASK = (SOF_TIMESTAMPING_LAST - 1) |
                                 SOF_TIMESTAMPING_LAST
 };
@@ -46,6 +47,18 @@ enum {
                                         SOF_TIMESTAMPING_TX_SCHED | \
                                         SOF_TIMESTAMPING_TX_ACK)
 
+/**
+ * struct so_timestamping - SO_TIMESTAMPING parameter
+ *
+ * @flags:     SO_TIMESTAMPING flags
+ * @bind_phc:  Index of PTP virtual clock bound to sock. This is available
+ *             if flag SOF_TIMESTAMPING_BIND_PHC is set.
+ */
+struct so_timestamping {
+       int flags;
+       int bind_phc;
+};
+
 /**
  * struct hwtstamp_config - %SIOCGHWTSTAMP and %SIOCSHWTSTAMP parameter
  *
index 45c8d3b..0af9c11 100644 (file)
@@ -61,7 +61,7 @@ enum nfulnl_attr_type {
        NFULA_HWTYPE,                   /* hardware type */
        NFULA_HWHEADER,                 /* hardware header */
        NFULA_HWLEN,                    /* hardware header length */
-       NFULA_CT,                       /* nf_conntrack_netlink.h */
+       NFULA_CT,                       /* nfnetlink_conntrack.h */
        NFULA_CT_INFO,                  /* enum ip_conntrack_info */
        NFULA_VLAN,                     /* nested attribute: packet vlan info */
        NFULA_L2HDR,                    /* full L2 header */
index bcb2cb5..aed90c4 100644 (file)
@@ -51,11 +51,11 @@ enum nfqnl_attr_type {
        NFQA_IFINDEX_PHYSOUTDEV,        /* __u32 ifindex */
        NFQA_HWADDR,                    /* nfqnl_msg_packet_hw */
        NFQA_PAYLOAD,                   /* opaque data payload */
-       NFQA_CT,                        /* nf_conntrack_netlink.h */
+       NFQA_CT,                        /* nfnetlink_conntrack.h */
        NFQA_CT_INFO,                   /* enum ip_conntrack_info */
        NFQA_CAP_LEN,                   /* __u32 length of captured packet */
        NFQA_SKB_INFO,                  /* __u32 skb meta information */
-       NFQA_EXP,                       /* nf_conntrack_netlink.h */
+       NFQA_EXP,                       /* nfnetlink_conntrack.h */
        NFQA_UID,                       /* __u32 sk uid */
        NFQA_GID,                       /* __u32 sk gid */
        NFQA_SECCTX,                    /* security context string */
index bb0d6e6..55f9f77 100644 (file)
@@ -1847,7 +1847,6 @@ config SLUB_DEBUG
        default y
        bool "Enable SLUB debugging support" if EXPERT
        depends on SLUB && SYSFS
-       select STACKDEPOT if STACKTRACE_SUPPORT
        help
          SLUB has extensive debug support features. Disabling these can
          result in significant savings in code size. This also disables
index 034ad93..9b15774 100644 (file)
@@ -2236,8 +2236,14 @@ static void bpf_prog_free_deferred(struct work_struct *work)
 #endif
        if (aux->dst_trampoline)
                bpf_trampoline_put(aux->dst_trampoline);
-       for (i = 0; i < aux->func_cnt; i++)
+       for (i = 0; i < aux->func_cnt; i++) {
+               /* We can just unlink the subprog poke descriptor table as
+                * it was originally linked to the main program and is also
+                * released along with it.
+                */
+               aux->func[i]->aux->poke_tab = NULL;
                bpf_jit_free(aux->func[i]);
+       }
        if (aux->func_cnt) {
                kfree(aux->func);
                bpf_prog_unlock_free(aux->prog);
index 2546daf..fdc2089 100644 (file)
@@ -558,7 +558,8 @@ int dev_map_enqueue_multi(struct xdp_buff *xdp, struct net_device *dev_rx,
 
        if (map->map_type == BPF_MAP_TYPE_DEVMAP) {
                for (i = 0; i < map->max_entries; i++) {
-                       dst = READ_ONCE(dtab->netdev_map[i]);
+                       dst = rcu_dereference_check(dtab->netdev_map[i],
+                                                   rcu_read_lock_bh_held());
                        if (!is_valid_dst(dst, xdp, exclude_ifindex))
                                continue;
 
@@ -654,7 +655,8 @@ int dev_map_redirect_multi(struct net_device *dev, struct sk_buff *skb,
 
        if (map->map_type == BPF_MAP_TYPE_DEVMAP) {
                for (i = 0; i < map->max_entries; i++) {
-                       dst = READ_ONCE(dtab->netdev_map[i]);
+                       dst = rcu_dereference_check(dtab->netdev_map[i],
+                                                   rcu_read_lock_bh_held());
                        if (!dst || dst->dev->ifindex == exclude_ifindex)
                                continue;
 
index be38bb9..42a4063 100644 (file)
@@ -12121,33 +12121,19 @@ static int jit_subprogs(struct bpf_verifier_env *env)
                        goto out_free;
                func[i]->is_func = 1;
                func[i]->aux->func_idx = i;
-               /* the btf and func_info will be freed only at prog->aux */
+               /* Below members will be freed only at prog->aux */
                func[i]->aux->btf = prog->aux->btf;
                func[i]->aux->func_info = prog->aux->func_info;
+               func[i]->aux->poke_tab = prog->aux->poke_tab;
+               func[i]->aux->size_poke_tab = prog->aux->size_poke_tab;
 
                for (j = 0; j < prog->aux->size_poke_tab; j++) {
-                       u32 insn_idx = prog->aux->poke_tab[j].insn_idx;
-                       int ret;
+                       struct bpf_jit_poke_descriptor *poke;
 
-                       if (!(insn_idx >= subprog_start &&
-                             insn_idx <= subprog_end))
-                               continue;
-
-                       ret = bpf_jit_add_poke_descriptor(func[i],
-                                                         &prog->aux->poke_tab[j]);
-                       if (ret < 0) {
-                               verbose(env, "adding tail call poke descriptor failed\n");
-                               goto out_free;
-                       }
-
-                       func[i]->insnsi[insn_idx - subprog_start].imm = ret + 1;
-
-                       map_ptr = func[i]->aux->poke_tab[ret].tail_call.map;
-                       ret = map_ptr->ops->map_poke_track(map_ptr, func[i]->aux);
-                       if (ret < 0) {
-                               verbose(env, "tracking tail call prog failed\n");
-                               goto out_free;
-                       }
+                       poke = &prog->aux->poke_tab[j];
+                       if (poke->insn_idx < subprog_end &&
+                           poke->insn_idx >= subprog_start)
+                               poke->aux = func[i]->aux;
                }
 
                /* Use bpf_prog_F_tag to indicate functions in stack traces.
@@ -12178,18 +12164,6 @@ static int jit_subprogs(struct bpf_verifier_env *env)
                cond_resched();
        }
 
-       /* Untrack main program's aux structs so that during map_poke_run()
-        * we will not stumble upon the unfilled poke descriptors; each
-        * of the main program's poke descs got distributed across subprogs
-        * and got tracked onto map, so we are sure that none of them will
-        * be missed after the operation below
-        */
-       for (i = 0; i < prog->aux->size_poke_tab; i++) {
-               map_ptr = prog->aux->poke_tab[i].tail_call.map;
-
-               map_ptr->ops->map_poke_untrack(map_ptr, prog->aux);
-       }
-
        /* at this point all bpf functions were successfully JITed
         * now populate all bpf_calls with correct addresses and
         * run last pass of JIT
@@ -12267,14 +12241,22 @@ static int jit_subprogs(struct bpf_verifier_env *env)
        bpf_prog_jit_attempt_done(prog);
        return 0;
 out_free:
+       /* We failed JIT'ing, so at this point we need to unregister poke
+        * descriptors from subprogs, so that kernel is not attempting to
+        * patch it anymore as we're freeing the subprog JIT memory.
+        */
+       for (i = 0; i < prog->aux->size_poke_tab; i++) {
+               map_ptr = prog->aux->poke_tab[i].tail_call.map;
+               map_ptr->ops->map_poke_untrack(map_ptr, prog->aux);
+       }
+       /* At this point we're guaranteed that poke descriptors are not
+        * live anymore. We can just unlink its descriptor table as it's
+        * released with the main prog.
+        */
        for (i = 0; i < env->subprog_cnt; i++) {
                if (!func[i])
                        continue;
-
-               for (j = 0; j < func[i]->aux->size_poke_tab; j++) {
-                       map_ptr = func[i]->aux->poke_tab[j].tail_call.map;
-                       map_ptr->ops->map_poke_untrack(map_ptr, func[i]->aux);
-               }
+               func[i]->aux->poke_tab = NULL;
                bpf_jit_free(func[i]);
        }
        kfree(func);
index ee93b6e..8d6bf56 100644 (file)
@@ -911,13 +911,11 @@ int cgroup1_parse_param(struct fs_context *fc, struct fs_parameter *param)
 
        opt = fs_parse(fc, cgroup1_fs_parameters, param, &result);
        if (opt == -ENOPARAM) {
-               if (strcmp(param->key, "source") == 0) {
-                       if (fc->source)
-                               return invalf(fc, "Multiple sources not supported");
-                       fc->source = param->string;
-                       param->string = NULL;
-                       return 0;
-               }
+               int ret;
+
+               ret = vfs_parse_fs_param_source(fc, param);
+               if (ret != -ENOPARAM)
+                       return ret;
                for_each_subsys(ss, i) {
                        if (strcmp(param->key, ss->legacy_name))
                                continue;
index 8372897..b6f28fa 100644 (file)
@@ -1045,8 +1045,8 @@ int gdb_serial_stub(struct kgdb_state *ks)
                                gdb_cmd_detachkill(ks);
                                return DBG_PASS_EVENT;
                        }
-#endif
                        fallthrough;
+#endif
                case 'C': /* Exception passing */
                        tmp = gdb_cmd_exception_pass(ks);
                        if (tmp > 0)
index 313d454..d998a76 100644 (file)
@@ -487,13 +487,13 @@ ref_scale_reader(void *arg)
        s64 duration;
 
        VERBOSE_SCALEOUT_BATCH("ref_scale_reader %ld: task started", me);
-       set_cpus_allowed_ptr(current, cpumask_of(me % nr_cpu_ids));
+       WARN_ON_ONCE(set_cpus_allowed_ptr(current, cpumask_of(me % nr_cpu_ids)));
        set_user_nice(current, MAX_NICE);
        atomic_inc(&n_init);
        if (holdoff)
                schedule_timeout_interruptible(holdoff * HZ);
 repeat:
-       VERBOSE_SCALEOUT_BATCH("ref_scale_reader %ld: waiting to start next experiment on cpu %d", me, smp_processor_id());
+       VERBOSE_SCALEOUT_BATCH("ref_scale_reader %ld: waiting to start next experiment on cpu %d", me, raw_smp_processor_id());
 
        // Wait for signal that this reader can start.
        wait_event(rt->wq, (atomic_read(&nreaders_exp) && smp_load_acquire(&rt->start_reader)) ||
@@ -503,7 +503,7 @@ repeat:
                goto end;
 
        // Make sure that the CPU is affinitized appropriately during testing.
-       WARN_ON_ONCE(smp_processor_id() != me);
+       WARN_ON_ONCE(raw_smp_processor_id() != me);
 
        WRITE_ONCE(rt->start_reader, 0);
        if (!atomic_dec_return(&n_started))
index 03a118d..8536c55 100644 (file)
@@ -953,10 +953,9 @@ static bool trc_inspect_reader(struct task_struct *t, void *arg)
                in_qs = likely(!t->trc_reader_nesting);
        }
 
-       // Mark as checked.  Because this is called from the grace-period
-       // kthread, also remove the task from the holdout list.
+       // Mark as checked so that the grace-period kthread will
+       // remove it from the holdout list.
        t->trc_reader_checked = true;
-       trc_del_holdout(t);
 
        if (in_qs)
                return true;  // Already in quiescent state, done!!!
@@ -983,7 +982,6 @@ static void trc_wait_for_one_reader(struct task_struct *t,
        // The current task had better be in a quiescent state.
        if (t == current) {
                t->trc_reader_checked = true;
-               trc_del_holdout(t);
                WARN_ON_ONCE(t->trc_reader_nesting);
                return;
        }
index 3f937b2..6c76988 100644 (file)
@@ -795,9 +795,9 @@ void show_rcu_gp_kthreads(void)
        jr = j - data_race(rcu_state.gp_req_activity);
        js = j - data_race(rcu_state.gp_start);
        jw = j - data_race(rcu_state.gp_wake_time);
-       pr_info("%s: wait state: %s(%d) ->state: %#lx ->rt_priority %u delta ->gp_start %lu ->gp_activity %lu ->gp_req_activity %lu ->gp_wake_time %lu ->gp_wake_seq %ld ->gp_seq %ld ->gp_seq_needed %ld ->gp_max %lu ->gp_flags %#x\n",
+       pr_info("%s: wait state: %s(%d) ->state: %#x ->rt_priority %u delta ->gp_start %lu ->gp_activity %lu ->gp_req_activity %lu ->gp_wake_time %lu ->gp_wake_seq %ld ->gp_seq %ld ->gp_seq_needed %ld ->gp_max %lu ->gp_flags %#x\n",
                rcu_state.name, gp_state_getname(rcu_state.gp_state),
-               rcu_state.gp_state, t ? t->__state : 0x1ffffL, t ? t->rt_priority : 0xffU,
+               rcu_state.gp_state, t ? t->__state : 0x1ffff, t ? t->rt_priority : 0xffU,
                js, ja, jr, jw, (long)data_race(rcu_state.gp_wake_seq),
                (long)data_race(rcu_state.gp_seq),
                (long)data_race(rcu_get_root()->gp_seq_needed),
index 2377cbb..29e8fc5 100644 (file)
@@ -405,15 +405,15 @@ static int scftorture_invoker(void *arg)
 
        VERBOSE_SCFTORTOUT("scftorture_invoker %d: task started", scfp->cpu);
        cpu = scfp->cpu % nr_cpu_ids;
-       set_cpus_allowed_ptr(current, cpumask_of(cpu));
+       WARN_ON_ONCE(set_cpus_allowed_ptr(current, cpumask_of(cpu)));
        set_user_nice(current, MAX_NICE);
        if (holdoff)
                schedule_timeout_interruptible(holdoff * HZ);
 
-       VERBOSE_SCFTORTOUT("scftorture_invoker %d: Waiting for all SCF torturers from cpu %d", scfp->cpu, smp_processor_id());
+       VERBOSE_SCFTORTOUT("scftorture_invoker %d: Waiting for all SCF torturers from cpu %d", scfp->cpu, raw_smp_processor_id());
 
        // Make sure that the CPU is affinitized appropriately during testing.
-       curcpu = smp_processor_id();
+       curcpu = raw_smp_processor_id();
        WARN_ONCE(curcpu != scfp->cpu % nr_cpu_ids,
                  "%s: Wanted CPU %d, running on %d, nr_cpu_ids = %d\n",
                  __func__, scfp->cpu, curcpu, nr_cpu_ids);
index 0207aee..16a9dfc 100644 (file)
@@ -1689,7 +1689,9 @@ static struct hist_field *create_hist_field(struct hist_trigger_data *hist_data,
        if (WARN_ON_ONCE(!field))
                goto out;
 
-       if (is_string_field(field)) {
+       /* Pointers to strings are just pointers and dangerous to dereference */
+       if (is_string_field(field) &&
+           (field->filter_type != FILTER_PTR_STRING)) {
                flags |= HIST_FIELD_FL_STRING;
 
                hist_field->size = MAX_FILTER_STR_VAL;
@@ -4495,8 +4497,6 @@ static inline void add_to_key(char *compound_key, void *key,
                field = key_field->field;
                if (field->filter_type == FILTER_DYN_STRING)
                        size = *(u32 *)(rec + field->offset) >> 16;
-               else if (field->filter_type == FILTER_PTR_STRING)
-                       size = strlen(key);
                else if (field->filter_type == FILTER_STATIC_STRING)
                        size = field->size;
 
index 8c55c47..c259842 100644 (file)
@@ -628,10 +628,8 @@ static int dmirror_check_atomic(struct dmirror *dmirror, unsigned long start,
 
        for (pfn = start >> PAGE_SHIFT; pfn < (end >> PAGE_SHIFT); pfn++) {
                void *entry;
-               struct page *page;
 
                entry = xa_load(&dmirror->pt, pfn);
-               page = xa_untag_pointer(entry);
                if (xa_pointer_tag(entry) == DPT_XA_TAG_ATOMIC)
                        return -EPERM;
        }
index 924553a..dfc940d 100644 (file)
@@ -5440,8 +5440,9 @@ long follow_hugetlb_page(struct mm_struct *mm, struct vm_area_struct *vma,
                        continue;
                }
 
-               refs = min3(pages_per_huge_page(h) - pfn_offset,
-                           (vma->vm_end - vaddr) >> PAGE_SHIFT, remainder);
+               /* vaddr may not be aligned to PAGE_SIZE */
+               refs = min3(pages_per_huge_page(h) - pfn_offset, remainder,
+                   (vma->vm_end - ALIGN_DOWN(vaddr, PAGE_SIZE)) >> PAGE_SHIFT);
 
                if (pages || vmas)
                        record_subpages_vmas(mem_map_offset(page, pfn_offset),
index 98e3059..d739cdd 100644 (file)
@@ -9,6 +9,7 @@
 #ifdef CONFIG_KASAN_HW_TAGS
 
 #include <linux/static_key.h>
+#include "../slab.h"
 
 DECLARE_STATIC_KEY_FALSE(kasan_flag_stacktrace);
 extern bool kasan_flag_async __ro_after_init;
@@ -387,6 +388,17 @@ static inline void kasan_unpoison(const void *addr, size_t size, bool init)
 
        if (WARN_ON((unsigned long)addr & KASAN_GRANULE_MASK))
                return;
+       /*
+        * Explicitly initialize the memory with the precise object size to
+        * avoid overwriting the SLAB redzone. This disables initialization in
+        * the arch code and may thus lead to performance penalty. The penalty
+        * is accepted since SLAB redzones aren't enabled in production builds.
+        */
+       if (__slub_debug_enabled() &&
+           init && ((unsigned long)size & KASAN_GRANULE_MASK)) {
+               init = false;
+               memzero_explicit((void *)addr, size);
+       }
        size = round_up(size, KASAN_GRANULE_SIZE);
 
        hw_set_mem_tag_range((void *)addr, size, tag, init);
index 23cbd9d..34a9ad3 100644 (file)
@@ -536,54 +536,6 @@ int migrate_huge_page_move_mapping(struct address_space *mapping,
        return MIGRATEPAGE_SUCCESS;
 }
 
-/*
- * Gigantic pages are so large that we do not guarantee that page++ pointer
- * arithmetic will work across the entire page.  We need something more
- * specialized.
- */
-static void __copy_gigantic_page(struct page *dst, struct page *src,
-                               int nr_pages)
-{
-       int i;
-       struct page *dst_base = dst;
-       struct page *src_base = src;
-
-       for (i = 0; i < nr_pages; ) {
-               cond_resched();
-               copy_highpage(dst, src);
-
-               i++;
-               dst = mem_map_next(dst, dst_base, i);
-               src = mem_map_next(src, src_base, i);
-       }
-}
-
-void copy_huge_page(struct page *dst, struct page *src)
-{
-       int i;
-       int nr_pages;
-
-       if (PageHuge(src)) {
-               /* hugetlbfs page */
-               struct hstate *h = page_hstate(src);
-               nr_pages = pages_per_huge_page(h);
-
-               if (unlikely(nr_pages > MAX_ORDER_NR_PAGES)) {
-                       __copy_gigantic_page(dst, src, nr_pages);
-                       return;
-               }
-       } else {
-               /* thp page */
-               BUG_ON(!PageTransHuge(src));
-               nr_pages = thp_nr_pages(src);
-       }
-
-       for (i = 0; i < nr_pages; i++) {
-               cond_resched();
-               copy_highpage(dst + i, src + i);
-       }
-}
-
 /*
  * Copy the page to its new location
  */
index 3b97e17..3e97e68 100644 (file)
@@ -3820,7 +3820,7 @@ static inline bool __should_fail_alloc_page(gfp_t gfp_mask, unsigned int order)
 
 #endif /* CONFIG_FAIL_PAGE_ALLOC */
 
-static noinline bool should_fail_alloc_page(gfp_t gfp_mask, unsigned int order)
+noinline bool should_fail_alloc_page(gfp_t gfp_mask, unsigned int order)
 {
        return __should_fail_alloc_page(gfp_mask, order);
 }
@@ -5221,9 +5221,6 @@ unsigned long __alloc_pages_bulk(gfp_t gfp, int preferred_nid,
        unsigned int alloc_flags = ALLOC_WMARK_LOW;
        int nr_populated = 0, nr_account = 0;
 
-       if (unlikely(nr_pages <= 0))
-               return 0;
-
        /*
         * Skip populated array elements to determine if any pages need
         * to be allocated before disabling IRQs.
@@ -5231,19 +5228,35 @@ unsigned long __alloc_pages_bulk(gfp_t gfp, int preferred_nid,
        while (page_array && nr_populated < nr_pages && page_array[nr_populated])
                nr_populated++;
 
+       /* No pages requested? */
+       if (unlikely(nr_pages <= 0))
+               goto out;
+
        /* Already populated array? */
        if (unlikely(page_array && nr_pages - nr_populated == 0))
-               return nr_populated;
+               goto out;
 
        /* Use the single page allocator for one page. */
        if (nr_pages - nr_populated == 1)
                goto failed;
 
+#ifdef CONFIG_PAGE_OWNER
+       /*
+        * PAGE_OWNER may recurse into the allocator to allocate space to
+        * save the stack with pagesets.lock held. Releasing/reacquiring
+        * removes much of the performance benefit of bulk allocation so
+        * force the caller to allocate one page at a time as it'll have
+        * similar performance to added complexity to the bulk allocator.
+        */
+       if (static_branch_unlikely(&page_owner_inited))
+               goto failed;
+#endif
+
        /* May set ALLOC_NOFRAGMENT, fragmentation will return 1 page. */
        gfp &= gfp_allowed_mask;
        alloc_gfp = gfp;
        if (!prepare_alloc_pages(gfp, 0, preferred_nid, nodemask, &ac, &alloc_gfp, &alloc_flags))
-               return 0;
+               goto out;
        gfp = alloc_gfp;
 
        /* Find an allowed local zone that meets the low watermark. */
@@ -5311,6 +5324,7 @@ unsigned long __alloc_pages_bulk(gfp_t gfp, int preferred_nid,
        __count_zid_vm_events(PGALLOC, zone_idx(zone), nr_account);
        zone_statistics(ac.preferred_zoneref->zone, zone, nr_account);
 
+out:
        return nr_populated;
 
 failed_irq:
@@ -5326,7 +5340,7 @@ failed:
                nr_populated++;
        }
 
-       return nr_populated;
+       goto out;
 }
 EXPORT_SYMBOL_GPL(__alloc_pages_bulk);
 
index 795f9d5..b9eb5c1 100644 (file)
--- a/mm/rmap.c
+++ b/mm/rmap.c
@@ -1440,21 +1440,20 @@ static bool try_to_unmap_one(struct page *page, struct vm_area_struct *vma,
                /*
                 * If the page is mlock()d, we cannot swap it out.
                 */
-               if (!(flags & TTU_IGNORE_MLOCK)) {
-                       if (vma->vm_flags & VM_LOCKED) {
-                               /* PTE-mapped THP are never marked as mlocked */
-                               if (!PageTransCompound(page) ||
-                                   (PageHead(page) && !PageDoubleMap(page))) {
-                                       /*
-                                        * Holding pte lock, we do *not* need
-                                        * mmap_lock here
-                                        */
-                                       mlock_vma_page(page);
-                               }
-                               ret = false;
-                               page_vma_mapped_walk_done(&pvmw);
-                               break;
-                       }
+               if (!(flags & TTU_IGNORE_MLOCK) &&
+                   (vma->vm_flags & VM_LOCKED)) {
+                       /*
+                        * PTE-mapped THP are never marked as mlocked: so do
+                        * not set it on a DoubleMap THP, nor on an Anon THP
+                        * (which may still be PTE-mapped after DoubleMap was
+                        * cleared).  But stop unmapping even in those cases.
+                        */
+                       if (!PageTransCompound(page) || (PageHead(page) &&
+                            !PageDoubleMap(page) && !PageAnon(page)))
+                               mlock_vma_page(page);
+                       page_vma_mapped_walk_done(&pvmw);
+                       ret = false;
+                       break;
                }
 
                /* Unexpected PMD-mapped THP? */
@@ -1986,8 +1985,10 @@ static bool page_mlock_one(struct page *page, struct vm_area_struct *vma,
                 */
                if (vma->vm_flags & VM_LOCKED) {
                        /*
-                        * PTE-mapped THP are never marked as mlocked, but
-                        * this function is never called when PageDoubleMap().
+                        * PTE-mapped THP are never marked as mlocked; but
+                        * this function is never called on a DoubleMap THP,
+                        * nor on an Anon THP (which may still be PTE-mapped
+                        * after DoubleMap was cleared).
                         */
                        mlock_vma_page(page);
                        /*
@@ -2022,6 +2023,10 @@ void page_mlock(struct page *page)
        VM_BUG_ON_PAGE(!PageLocked(page) || PageLRU(page), page);
        VM_BUG_ON_PAGE(PageCompound(page) && PageDoubleMap(page), page);
 
+       /* Anon THP are only marked as mlocked when singly mapped */
+       if (PageTransCompound(page) && PageAnon(page))
+               return;
+
        rmap_walk(page, &rwc);
 }
 
index 67e0663..f997fd5 100644 (file)
--- a/mm/slab.h
+++ b/mm/slab.h
@@ -216,10 +216,18 @@ DECLARE_STATIC_KEY_FALSE(slub_debug_enabled);
 #endif
 extern void print_tracking(struct kmem_cache *s, void *object);
 long validate_slab_cache(struct kmem_cache *s);
+static inline bool __slub_debug_enabled(void)
+{
+       return static_branch_unlikely(&slub_debug_enabled);
+}
 #else
 static inline void print_tracking(struct kmem_cache *s, void *object)
 {
 }
+static inline bool __slub_debug_enabled(void)
+{
+       return false;
+}
 #endif
 
 /*
@@ -229,11 +237,10 @@ static inline void print_tracking(struct kmem_cache *s, void *object)
  */
 static inline bool kmem_cache_debug_flags(struct kmem_cache *s, slab_flags_t flags)
 {
-#ifdef CONFIG_SLUB_DEBUG
-       VM_WARN_ON_ONCE(!(flags & SLAB_DEBUG_FLAGS));
-       if (static_branch_unlikely(&slub_debug_enabled))
+       if (IS_ENABLED(CONFIG_SLUB_DEBUG))
+               VM_WARN_ON_ONCE(!(flags & SLAB_DEBUG_FLAGS));
+       if (__slub_debug_enabled())
                return s->flags & flags;
-#endif
        return false;
 }
 
index dc863c1..090fa14 100644 (file)
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -26,7 +26,6 @@
 #include <linux/cpuset.h>
 #include <linux/mempolicy.h>
 #include <linux/ctype.h>
-#include <linux/stackdepot.h>
 #include <linux/debugobjects.h>
 #include <linux/kallsyms.h>
 #include <linux/kfence.h>
  */
 
 #ifdef CONFIG_SLUB_DEBUG
-
 #ifdef CONFIG_SLUB_DEBUG_ON
 DEFINE_STATIC_KEY_TRUE(slub_debug_enabled);
 #else
 DEFINE_STATIC_KEY_FALSE(slub_debug_enabled);
 #endif
-
-static inline bool __slub_debug_enabled(void)
-{
-       return static_branch_unlikely(&slub_debug_enabled);
-}
-
-#else          /* CONFIG_SLUB_DEBUG */
-
-static inline bool __slub_debug_enabled(void)
-{
-       return false;
-}
-
 #endif         /* CONFIG_SLUB_DEBUG */
 
 static inline bool kmem_cache_debug(struct kmem_cache *s)
@@ -221,8 +206,8 @@ static inline bool kmem_cache_has_cpu_partial(struct kmem_cache *s)
 #define TRACK_ADDRS_COUNT 16
 struct track {
        unsigned long addr;     /* Called from address */
-#ifdef CONFIG_STACKDEPOT
-       depot_stack_handle_t handle;
+#ifdef CONFIG_STACKTRACE
+       unsigned long addrs[TRACK_ADDRS_COUNT]; /* Called from address */
 #endif
        int cpu;                /* Was running on cpu */
        int pid;                /* Pid context */
@@ -626,27 +611,22 @@ static struct track *get_track(struct kmem_cache *s, void *object,
        return kasan_reset_tag(p + alloc);
 }
 
-#ifdef CONFIG_STACKDEPOT
-static depot_stack_handle_t save_stack_depot_trace(gfp_t flags)
-{
-       unsigned long entries[TRACK_ADDRS_COUNT];
-       depot_stack_handle_t handle;
-       unsigned int nr_entries;
-
-       nr_entries = stack_trace_save(entries, ARRAY_SIZE(entries), 4);
-       handle = stack_depot_save(entries, nr_entries, flags);
-       return handle;
-}
-#endif
-
 static void set_track(struct kmem_cache *s, void *object,
                        enum track_item alloc, unsigned long addr)
 {
        struct track *p = get_track(s, object, alloc);
 
        if (addr) {
-#ifdef CONFIG_STACKDEPOT
-               p->handle = save_stack_depot_trace(GFP_NOWAIT);
+#ifdef CONFIG_STACKTRACE
+               unsigned int nr_entries;
+
+               metadata_access_enable();
+               nr_entries = stack_trace_save(kasan_reset_tag(p->addrs),
+                                             TRACK_ADDRS_COUNT, 3);
+               metadata_access_disable();
+
+               if (nr_entries < TRACK_ADDRS_COUNT)
+                       p->addrs[nr_entries] = 0;
 #endif
                p->addr = addr;
                p->cpu = smp_processor_id();
@@ -673,19 +653,14 @@ static void print_track(const char *s, struct track *t, unsigned long pr_time)
 
        pr_err("%s in %pS age=%lu cpu=%u pid=%d\n",
               s, (void *)t->addr, pr_time - t->when, t->cpu, t->pid);
-#ifdef CONFIG_STACKDEPOT
+#ifdef CONFIG_STACKTRACE
        {
-               depot_stack_handle_t handle;
-               unsigned long *entries;
-               unsigned int nr_entries;
-
-               handle = READ_ONCE(t->handle);
-               if (!handle) {
-                       pr_err("object allocation/free stack trace missing\n");
-               } else {
-                       nr_entries = stack_depot_fetch(handle, &entries);
-                       stack_trace_print(entries, nr_entries, 0);
-               }
+               int i;
+               for (i = 0; i < TRACK_ADDRS_COUNT; i++)
+                       if (t->addrs[i])
+                               pr_err("\t%pS\n", (void *)t->addrs[i]);
+                       else
+                               break;
        }
 #endif
 }
@@ -4059,26 +4034,18 @@ void kmem_obj_info(struct kmem_obj_info *kpp, void *object, struct page *page)
        objp = fixup_red_left(s, objp);
        trackp = get_track(s, objp, TRACK_ALLOC);
        kpp->kp_ret = (void *)trackp->addr;
-#ifdef CONFIG_STACKDEPOT
-       {
-               depot_stack_handle_t handle;
-               unsigned long *entries;
-               unsigned int nr_entries;
-
-               handle = READ_ONCE(trackp->handle);
-               if (handle) {
-                       nr_entries = stack_depot_fetch(handle, &entries);
-                       for (i = 0; i < KS_ADDRS_COUNT && i < nr_entries; i++)
-                               kpp->kp_stack[i] = (void *)entries[i];
-               }
+#ifdef CONFIG_STACKTRACE
+       for (i = 0; i < KS_ADDRS_COUNT && i < TRACK_ADDRS_COUNT; i++) {
+               kpp->kp_stack[i] = (void *)trackp->addrs[i];
+               if (!kpp->kp_stack[i])
+                       break;
+       }
 
-               trackp = get_track(s, objp, TRACK_FREE);
-               handle = READ_ONCE(trackp->handle);
-               if (handle) {
-                       nr_entries = stack_depot_fetch(handle, &entries);
-                       for (i = 0; i < KS_ADDRS_COUNT && i < nr_entries; i++)
-                               kpp->kp_free_stack[i] = (void *)entries[i];
-               }
+       trackp = get_track(s, objp, TRACK_FREE);
+       for (i = 0; i < KS_ADDRS_COUNT && i < TRACK_ADDRS_COUNT; i++) {
+               kpp->kp_free_stack[i] = (void *)trackp->addrs[i];
+               if (!kpp->kp_free_stack[i])
+                       break;
        }
 #endif
 #endif
index 99c6cc7..9043d03 100644 (file)
--- a/mm/util.c
+++ b/mm/util.c
@@ -731,6 +731,16 @@ int __page_mapcount(struct page *page)
 }
 EXPORT_SYMBOL_GPL(__page_mapcount);
 
+void copy_huge_page(struct page *dst, struct page *src)
+{
+       unsigned i, nr = compound_nr(src);
+
+       for (i = 0; i < nr; i++) {
+               cond_resched();
+               copy_highpage(nth_page(dst, i), nth_page(src, i));
+       }
+}
+
 int sysctl_overcommit_memory __read_mostly = OVERCOMMIT_GUESS;
 int sysctl_overcommit_ratio __read_mostly = 50;
 unsigned long sysctl_overcommit_kbytes __read_mostly;
index 400bd85..f6012f8 100644 (file)
@@ -203,6 +203,19 @@ static void garp_attr_destroy(struct garp_applicant *app, struct garp_attr *attr
        kfree(attr);
 }
 
+static void garp_attr_destroy_all(struct garp_applicant *app)
+{
+       struct rb_node *node, *next;
+       struct garp_attr *attr;
+
+       for (node = rb_first(&app->gid);
+            next = node ? rb_next(node) : NULL, node != NULL;
+            node = next) {
+               attr = rb_entry(node, struct garp_attr, node);
+               garp_attr_destroy(app, attr);
+       }
+}
+
 static int garp_pdu_init(struct garp_applicant *app)
 {
        struct sk_buff *skb;
@@ -609,6 +622,7 @@ void garp_uninit_applicant(struct net_device *dev, struct garp_application *appl
 
        spin_lock_bh(&app->lock);
        garp_gid_event(app, GARP_EVENT_TRANSMIT_PDU);
+       garp_attr_destroy_all(app);
        garp_pdu_queue(app);
        spin_unlock_bh(&app->lock);
 
index bea6e43..35e04cc 100644 (file)
@@ -292,6 +292,19 @@ static void mrp_attr_destroy(struct mrp_applicant *app, struct mrp_attr *attr)
        kfree(attr);
 }
 
+static void mrp_attr_destroy_all(struct mrp_applicant *app)
+{
+       struct rb_node *node, *next;
+       struct mrp_attr *attr;
+
+       for (node = rb_first(&app->mad);
+            next = node ? rb_next(node) : NULL, node != NULL;
+            node = next) {
+               attr = rb_entry(node, struct mrp_attr, node);
+               mrp_attr_destroy(app, attr);
+       }
+}
+
 static int mrp_pdu_init(struct mrp_applicant *app)
 {
        struct sk_buff *skb;
@@ -895,6 +908,7 @@ void mrp_uninit_applicant(struct net_device *dev, struct mrp_application *appl)
 
        spin_lock_bh(&app->lock);
        mrp_mad_event(app, MRP_EVENT_TX);
+       mrp_attr_destroy_all(app);
        mrp_pdu_queue(app);
        spin_unlock_bh(&app->lock);
 
index f7d2f47..6e4a323 100644 (file)
@@ -562,7 +562,7 @@ int br_add_if(struct net_bridge *br, struct net_device *dev,
        struct net_bridge_port *p;
        int err = 0;
        unsigned br_hr, dev_hr;
-       bool changed_addr;
+       bool changed_addr, fdb_synced = false;
 
        /* Don't allow bridging non-ethernet like devices. */
        if ((dev->flags & IFF_LOOPBACK) ||
@@ -652,6 +652,19 @@ int br_add_if(struct net_bridge *br, struct net_device *dev,
        list_add_rcu(&p->list, &br->port_list);
 
        nbp_update_port_count(br);
+       if (!br_promisc_port(p) && (p->dev->priv_flags & IFF_UNICAST_FLT)) {
+               /* When updating the port count we also update all ports'
+                * promiscuous mode.
+                * A port leaving promiscuous mode normally gets the bridge's
+                * fdb synced to the unicast filter (if supported), however,
+                * `br_port_clear_promisc` does not distinguish between
+                * non-promiscuous ports and *new* ports, so we need to
+                * sync explicitly here.
+                */
+               fdb_synced = br_fdb_sync_static(br, p) == 0;
+               if (!fdb_synced)
+                       netdev_err(dev, "failed to sync bridge static fdb addresses to this port\n");
+       }
 
        netdev_update_features(br->dev);
 
@@ -701,6 +714,8 @@ int br_add_if(struct net_bridge *br, struct net_device *dev,
        return 0;
 
 err7:
+       if (fdb_synced)
+               br_fdb_unsync_static(br, p);
        list_del_rcu(&p->list);
        br_fdb_delete_by_port(br, p, 0, 1);
        nbp_update_port_count(br);
index 53c3a9d..d0434dc 100644 (file)
@@ -3264,7 +3264,9 @@ static void br_multicast_pim(struct net_bridge *br,
            pim_hdr_type(pimhdr) != PIM_TYPE_HELLO)
                return;
 
+       spin_lock(&br->multicast_lock);
        br_ip4_multicast_mark_router(br, port);
+       spin_unlock(&br->multicast_lock);
 }
 
 static int br_ip4_multicast_mrd_rcv(struct net_bridge *br,
@@ -3275,7 +3277,9 @@ static int br_ip4_multicast_mrd_rcv(struct net_bridge *br,
            igmp_hdr(skb)->type != IGMP_MRDISC_ADV)
                return -ENOMSG;
 
+       spin_lock(&br->multicast_lock);
        br_ip4_multicast_mark_router(br, port);
+       spin_unlock(&br->multicast_lock);
 
        return 0;
 }
@@ -3343,7 +3347,9 @@ static void br_ip6_multicast_mrd_rcv(struct net_bridge *br,
        if (icmp6_hdr(skb)->icmp6_type != ICMPV6_MRDISC_ADV)
                return;
 
+       spin_lock(&br->multicast_lock);
        br_ip6_multicast_mark_router(br, port);
+       spin_unlock(&br->multicast_lock);
 }
 
 static int br_multicast_ipv6_rcv(struct net_bridge *br,
index c253c2a..64b21f0 100644 (file)
@@ -6008,6 +6008,19 @@ static void gro_list_prepare(const struct list_head *head,
                        diffs = memcmp(skb_mac_header(p),
                                       skb_mac_header(skb),
                                       maclen);
+
+               diffs |= skb_get_nfct(p) ^ skb_get_nfct(skb);
+#if IS_ENABLED(CONFIG_SKB_EXTENSIONS) && IS_ENABLED(CONFIG_NET_TC_SKB_EXT)
+               if (!diffs) {
+                       struct tc_skb_ext *skb_ext = skb_ext_find(skb, TC_SKB_EXT);
+                       struct tc_skb_ext *p_ext = skb_ext_find(p, TC_SKB_EXT);
+
+                       diffs |= (!!p_ext) ^ (!!skb_ext);
+                       if (!diffs && unlikely(skb_ext))
+                               diffs |= p_ext->chain ^ skb_ext->chain;
+               }
+#endif
+
                NAPI_GRO_CB(p)->same_flow = !diffs;
        }
 }
@@ -6221,6 +6234,8 @@ static gro_result_t napi_skb_finish(struct napi_struct *napi,
        case GRO_MERGED_FREE:
                if (NAPI_GRO_CB(skb)->free == NAPI_GRO_FREE_STOLEN_HEAD)
                        napi_skb_free_stolen_head(skb);
+               else if (skb->fclone != SKB_FCLONE_UNAVAILABLE)
+                       __kfree_skb(skb);
                else
                        __kfree_skb_defer(skb);
                break;
@@ -6270,6 +6285,7 @@ static void napi_reuse_skb(struct napi_struct *napi, struct sk_buff *skb)
        skb_shinfo(skb)->gso_type = 0;
        skb->truesize = SKB_TRUESIZE(skb_end_offset(skb));
        skb_ext_reset(skb);
+       nf_reset_ct(skb);
 
        napi->skb = skb;
 }
index 12aabcd..f63de96 100644 (file)
@@ -943,6 +943,7 @@ void __kfree_skb_defer(struct sk_buff *skb)
 
 void napi_skb_free_stolen_head(struct sk_buff *skb)
 {
+       nf_reset_ct(skb);
        skb_dst_drop(skb);
        skb_ext_put(skb);
        napi_skb_cache_put(skb);
index ba1c0f7..a3eea6e 100644 (file)
 #include <net/tcp.h>
 #include <net/busy_poll.h>
 
+#include <linux/ethtool.h>
+
 static DEFINE_MUTEX(proto_list_mutex);
 static LIST_HEAD(proto_list);
 
@@ -810,8 +812,47 @@ void sock_set_timestamp(struct sock *sk, int optname, bool valbool)
        }
 }
 
-int sock_set_timestamping(struct sock *sk, int optname, int val)
+static int sock_timestamping_bind_phc(struct sock *sk, int phc_index)
+{
+       struct net *net = sock_net(sk);
+       struct net_device *dev = NULL;
+       bool match = false;
+       int *vclock_index;
+       int i, num;
+
+       if (sk->sk_bound_dev_if)
+               dev = dev_get_by_index(net, sk->sk_bound_dev_if);
+
+       if (!dev) {
+               pr_err("%s: sock not bind to device\n", __func__);
+               return -EOPNOTSUPP;
+       }
+
+       num = ethtool_get_phc_vclocks(dev, &vclock_index);
+       for (i = 0; i < num; i++) {
+               if (*(vclock_index + i) == phc_index) {
+                       match = true;
+                       break;
+               }
+       }
+
+       if (num > 0)
+               kfree(vclock_index);
+
+       if (!match)
+               return -EINVAL;
+
+       sk->sk_bind_phc = phc_index;
+
+       return 0;
+}
+
+int sock_set_timestamping(struct sock *sk, int optname,
+                         struct so_timestamping timestamping)
 {
+       int val = timestamping.flags;
+       int ret;
+
        if (val & ~SOF_TIMESTAMPING_MASK)
                return -EINVAL;
 
@@ -832,6 +873,12 @@ int sock_set_timestamping(struct sock *sk, int optname, int val)
            !(val & SOF_TIMESTAMPING_OPT_TSONLY))
                return -EINVAL;
 
+       if (val & SOF_TIMESTAMPING_BIND_PHC) {
+               ret = sock_timestamping_bind_phc(sk, timestamping.bind_phc);
+               if (ret)
+                       return ret;
+       }
+
        sk->sk_tsflags = val;
        sock_valbool_flag(sk, SOCK_TSTAMP_NEW, optname == SO_TIMESTAMPING_NEW);
 
@@ -907,6 +954,7 @@ EXPORT_SYMBOL(sock_set_mark);
 int sock_setsockopt(struct socket *sock, int level, int optname,
                    sockptr_t optval, unsigned int optlen)
 {
+       struct so_timestamping timestamping;
        struct sock_txtime sk_txtime;
        struct sock *sk = sock->sk;
        int val;
@@ -1068,12 +1116,22 @@ set_sndbuf:
        case SO_TIMESTAMP_NEW:
        case SO_TIMESTAMPNS_OLD:
        case SO_TIMESTAMPNS_NEW:
-               sock_set_timestamp(sk, valbool, optname);
+               sock_set_timestamp(sk, optname, valbool);
                break;
 
        case SO_TIMESTAMPING_NEW:
        case SO_TIMESTAMPING_OLD:
-               ret = sock_set_timestamping(sk, optname, val);
+               if (optlen == sizeof(timestamping)) {
+                       if (copy_from_sockptr(&timestamping, optval,
+                                             sizeof(timestamping))) {
+                               ret = -EFAULT;
+                               break;
+                       }
+               } else {
+                       memset(&timestamping, 0, sizeof(timestamping));
+                       timestamping.flags = val;
+               }
+               ret = sock_set_timestamping(sk, optname, timestamping);
                break;
 
        case SO_RCVLOWAT:
@@ -1201,7 +1259,7 @@ set_sndbuf:
                        if (val < 0)
                                ret = -EINVAL;
                        else
-                               sk->sk_ll_usec = val;
+                               WRITE_ONCE(sk->sk_ll_usec, val);
                }
                break;
        case SO_PREFER_BUSY_POLL:
@@ -1348,6 +1406,7 @@ int sock_getsockopt(struct socket *sock, int level, int optname,
                struct __kernel_old_timeval tm;
                struct  __kernel_sock_timeval stm;
                struct sock_txtime txtime;
+               struct so_timestamping timestamping;
        } v;
 
        int lv = sizeof(int);
@@ -1451,7 +1510,9 @@ int sock_getsockopt(struct socket *sock, int level, int optname,
                break;
 
        case SO_TIMESTAMPING_OLD:
-               v.val = sk->sk_tsflags;
+               lv = sizeof(v.timestamping);
+               v.timestamping.flags = sk->sk_tsflags;
+               v.timestamping.bind_phc = sk->sk_bind_phc;
                break;
 
        case SO_RCVTIMEO_OLD:
index af71b86..5ece05d 100644 (file)
@@ -113,11 +113,11 @@ static int dsa_switch_bridge_leave(struct dsa_switch *ds,
        int err, port;
 
        if (dst->index == info->tree_index && ds->index == info->sw_index &&
-           ds->ops->port_bridge_join)
+           ds->ops->port_bridge_leave)
                ds->ops->port_bridge_leave(ds, info->port, info->br);
 
        if ((dst->index != info->tree_index || ds->index != info->sw_index) &&
-           ds->ops->crosschip_bridge_join)
+           ds->ops->crosschip_bridge_leave)
                ds->ops->crosschip_bridge_leave(ds, info->tree_index,
                                                info->sw_index, info->port,
                                                info->br);
@@ -427,7 +427,7 @@ static int dsa_switch_lag_join(struct dsa_switch *ds,
                                                   info->port, info->lag,
                                                   info->info);
 
-       return 0;
+       return -EOPNOTSUPP;
 }
 
 static int dsa_switch_lag_leave(struct dsa_switch *ds,
@@ -440,7 +440,7 @@ static int dsa_switch_lag_leave(struct dsa_switch *ds,
                return ds->ops->crosschip_lag_leave(ds, info->sw_index,
                                                    info->port, info->lag);
 
-       return 0;
+       return -EOPNOTSUPP;
 }
 
 static int dsa_switch_mdb_add(struct dsa_switch *ds,
index 723c9a8..0a19470 100644 (file)
@@ -7,4 +7,4 @@ obj-$(CONFIG_ETHTOOL_NETLINK)   += ethtool_nl.o
 ethtool_nl-y   := netlink.o bitset.o strset.o linkinfo.o linkmodes.o \
                   linkstate.o debug.o wol.o features.o privflags.o rings.o \
                   channels.o coalesce.o pause.o eee.o tsinfo.o cabletest.o \
-                  tunnels.o fec.o eeprom.o stats.o
+                  tunnels.o fec.o eeprom.o stats.o phc_vclocks.o
index f9dcbad..c63e073 100644 (file)
@@ -4,6 +4,7 @@
 #include <linux/net_tstamp.h>
 #include <linux/phy.h>
 #include <linux/rtnetlink.h>
+#include <linux/ptp_clock_kernel.h>
 
 #include "common.h"
 
@@ -397,6 +398,7 @@ const char sof_timestamping_names[][ETH_GSTRING_LEN] = {
        [const_ilog2(SOF_TIMESTAMPING_OPT_STATS)]    = "option-stats",
        [const_ilog2(SOF_TIMESTAMPING_OPT_PKTINFO)]  = "option-pktinfo",
        [const_ilog2(SOF_TIMESTAMPING_OPT_TX_SWHW)]  = "option-tx-swhw",
+       [const_ilog2(SOF_TIMESTAMPING_BIND_PHC)]     = "bind-phc",
 };
 static_assert(ARRAY_SIZE(sof_timestamping_names) == __SOF_TIMESTAMPING_CNT);
 
@@ -554,6 +556,18 @@ int __ethtool_get_ts_info(struct net_device *dev, struct ethtool_ts_info *info)
        return 0;
 }
 
+int ethtool_get_phc_vclocks(struct net_device *dev, int **vclock_index)
+{
+       struct ethtool_ts_info info = { };
+       int num = 0;
+
+       if (!__ethtool_get_ts_info(dev, &info))
+               num = ptp_get_vclocks_index(info.phc_index, vclock_index);
+
+       return num;
+}
+EXPORT_SYMBOL(ethtool_get_phc_vclocks);
+
 const struct ethtool_phy_ops *ethtool_phy_ops;
 
 void ethtool_set_ethtool_phy_ops(const struct ethtool_phy_ops *ops)
index a734634..73e0f5b 100644 (file)
@@ -248,6 +248,7 @@ ethnl_default_requests[__ETHTOOL_MSG_USER_CNT] = {
        [ETHTOOL_MSG_TSINFO_GET]        = &ethnl_tsinfo_request_ops,
        [ETHTOOL_MSG_MODULE_EEPROM_GET] = &ethnl_module_eeprom_request_ops,
        [ETHTOOL_MSG_STATS_GET]         = &ethnl_stats_request_ops,
+       [ETHTOOL_MSG_PHC_VCLOCKS_GET]   = &ethnl_phc_vclocks_request_ops,
 };
 
 static struct ethnl_dump_ctx *ethnl_dump_context(struct netlink_callback *cb)
@@ -958,6 +959,15 @@ static const struct genl_ops ethtool_genl_ops[] = {
                .policy = ethnl_stats_get_policy,
                .maxattr = ARRAY_SIZE(ethnl_stats_get_policy) - 1,
        },
+       {
+               .cmd    = ETHTOOL_MSG_PHC_VCLOCKS_GET,
+               .doit   = ethnl_default_doit,
+               .start  = ethnl_default_start,
+               .dumpit = ethnl_default_dumpit,
+               .done   = ethnl_default_done,
+               .policy = ethnl_phc_vclocks_get_policy,
+               .maxattr = ARRAY_SIZE(ethnl_phc_vclocks_get_policy) - 1,
+       },
 };
 
 static const struct genl_multicast_group ethtool_nl_mcgrps[] = {
index 3e25a47..3fc395c 100644 (file)
@@ -347,6 +347,7 @@ extern const struct ethnl_request_ops ethnl_tsinfo_request_ops;
 extern const struct ethnl_request_ops ethnl_fec_request_ops;
 extern const struct ethnl_request_ops ethnl_module_eeprom_request_ops;
 extern const struct ethnl_request_ops ethnl_stats_request_ops;
+extern const struct ethnl_request_ops ethnl_phc_vclocks_request_ops;
 
 extern const struct nla_policy ethnl_header_policy[ETHTOOL_A_HEADER_FLAGS + 1];
 extern const struct nla_policy ethnl_header_policy_stats[ETHTOOL_A_HEADER_FLAGS + 1];
@@ -382,6 +383,7 @@ extern const struct nla_policy ethnl_fec_get_policy[ETHTOOL_A_FEC_HEADER + 1];
 extern const struct nla_policy ethnl_fec_set_policy[ETHTOOL_A_FEC_AUTO + 1];
 extern const struct nla_policy ethnl_module_eeprom_get_policy[ETHTOOL_A_MODULE_EEPROM_I2C_ADDRESS + 1];
 extern const struct nla_policy ethnl_stats_get_policy[ETHTOOL_A_STATS_GROUPS + 1];
+extern const struct nla_policy ethnl_phc_vclocks_get_policy[ETHTOOL_A_PHC_VCLOCKS_HEADER + 1];
 
 int ethnl_set_linkinfo(struct sk_buff *skb, struct genl_info *info);
 int ethnl_set_linkmodes(struct sk_buff *skb, struct genl_info *info);
diff --git a/net/ethtool/phc_vclocks.c b/net/ethtool/phc_vclocks.c
new file mode 100644 (file)
index 0000000..637b2f5
--- /dev/null
@@ -0,0 +1,94 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright 2021 NXP
+ */
+#include "netlink.h"
+#include "common.h"
+
+struct phc_vclocks_req_info {
+       struct ethnl_req_info           base;
+};
+
+struct phc_vclocks_reply_data {
+       struct ethnl_reply_data         base;
+       int                             num;
+       int                             *index;
+};
+
+#define PHC_VCLOCKS_REPDATA(__reply_base) \
+       container_of(__reply_base, struct phc_vclocks_reply_data, base)
+
+const struct nla_policy ethnl_phc_vclocks_get_policy[] = {
+       [ETHTOOL_A_PHC_VCLOCKS_HEADER] = NLA_POLICY_NESTED(ethnl_header_policy),
+};
+
+static int phc_vclocks_prepare_data(const struct ethnl_req_info *req_base,
+                                   struct ethnl_reply_data *reply_base,
+                                   struct genl_info *info)
+{
+       struct phc_vclocks_reply_data *data = PHC_VCLOCKS_REPDATA(reply_base);
+       struct net_device *dev = reply_base->dev;
+       int ret;
+
+       ret = ethnl_ops_begin(dev);
+       if (ret < 0)
+               return ret;
+       data->num = ethtool_get_phc_vclocks(dev, &data->index);
+       ethnl_ops_complete(dev);
+
+       return ret;
+}
+
+static int phc_vclocks_reply_size(const struct ethnl_req_info *req_base,
+                                 const struct ethnl_reply_data *reply_base)
+{
+       const struct phc_vclocks_reply_data *data =
+               PHC_VCLOCKS_REPDATA(reply_base);
+       int len = 0;
+
+       if (data->num > 0) {
+               len += nla_total_size(sizeof(u32));
+               len += nla_total_size(sizeof(s32) * data->num);
+       }
+
+       return len;
+}
+
+static int phc_vclocks_fill_reply(struct sk_buff *skb,
+                                 const struct ethnl_req_info *req_base,
+                                 const struct ethnl_reply_data *reply_base)
+{
+       const struct phc_vclocks_reply_data *data =
+               PHC_VCLOCKS_REPDATA(reply_base);
+
+       if (data->num <= 0)
+               return 0;
+
+       if (nla_put_u32(skb, ETHTOOL_A_PHC_VCLOCKS_NUM, data->num) ||
+           nla_put(skb, ETHTOOL_A_PHC_VCLOCKS_INDEX,
+                   sizeof(s32) * data->num, data->index))
+               return -EMSGSIZE;
+
+       return 0;
+}
+
+static void phc_vclocks_cleanup_data(struct ethnl_reply_data *reply_base)
+{
+       const struct phc_vclocks_reply_data *data =
+               PHC_VCLOCKS_REPDATA(reply_base);
+
+       kfree(data->index);
+}
+
+const struct ethnl_request_ops ethnl_phc_vclocks_request_ops = {
+       .request_cmd            = ETHTOOL_MSG_PHC_VCLOCKS_GET,
+       .reply_cmd              = ETHTOOL_MSG_PHC_VCLOCKS_GET_REPLY,
+       .hdr_attr               = ETHTOOL_A_PHC_VCLOCKS_HEADER,
+       .req_info_size          = sizeof(struct phc_vclocks_req_info),
+       .reply_data_size        = sizeof(struct phc_vclocks_reply_data),
+
+       .prepare_data           = phc_vclocks_prepare_data,
+       .reply_size             = phc_vclocks_reply_size,
+       .fill_reply             = phc_vclocks_fill_reply,
+       .cleanup_data           = phc_vclocks_cleanup_data,
+};
index a933bd6..9fe13e4 100644 (file)
@@ -1376,7 +1376,7 @@ static void nl_fib_input(struct sk_buff *skb)
        portid = NETLINK_CB(skb).portid;      /* netlink portid */
        NETLINK_CB(skb).portid = 0;        /* from kernel */
        NETLINK_CB(skb).dst_group = 0;  /* unicast */
-       netlink_unicast(net->ipv4.fibnl, skb, portid, MSG_DONTWAIT);
+       nlmsg_unicast(net->ipv4.fibnl, skb, portid);
 }
 
 static int __net_init nl_fib_lookup_init(struct net *net)
index e65f4ef..ef78972 100644 (file)
@@ -580,10 +580,7 @@ int inet_diag_dump_one_icsk(struct inet_hashinfo *hashinfo,
                nlmsg_free(rep);
                goto out;
        }
-       err = netlink_unicast(net->diag_nlsk, rep, NETLINK_CB(in_skb).portid,
-                             MSG_DONTWAIT);
-       if (err > 0)
-               err = 0;
+       err = nlmsg_unicast(net->diag_nlsk, rep, NETLINK_CB(in_skb).portid);
 
 out:
        if (sk)
index f6cc26d..0dca007 100644 (file)
@@ -317,7 +317,7 @@ static int ip_tunnel_bind_dev(struct net_device *dev)
        }
 
        dev->needed_headroom = t_hlen + hlen;
-       mtu -= t_hlen;
+       mtu -= t_hlen + (dev->type == ARPHRD_ETHER ? dev->hard_header_len : 0);
 
        if (mtu < IPV4_MIN_MTU)
                mtu = IPV4_MIN_MTU;
@@ -348,6 +348,9 @@ static struct ip_tunnel *ip_tunnel_create(struct net *net,
        t_hlen = nt->hlen + sizeof(struct iphdr);
        dev->min_mtu = ETH_MIN_MTU;
        dev->max_mtu = IP_MAX_MTU - t_hlen;
+       if (dev->type == ARPHRD_ETHER)
+               dev->max_mtu -= dev->hard_header_len;
+
        ip_tunnel_add(itn, nt);
        return nt;
 
@@ -489,11 +492,14 @@ static int tnl_update_pmtu(struct net_device *dev, struct sk_buff *skb,
 
        tunnel_hlen = md ? tunnel_hlen : tunnel->hlen;
        pkt_size = skb->len - tunnel_hlen;
+       pkt_size -= dev->type == ARPHRD_ETHER ? dev->hard_header_len : 0;
 
-       if (df)
+       if (df) {
                mtu = dst_mtu(&rt->dst) - (sizeof(struct iphdr) + tunnel_hlen);
-       else
+               mtu -= dev->type == ARPHRD_ETHER ? dev->hard_header_len : 0;
+       } else {
                mtu = skb_valid_dst(skb) ? dst_mtu(skb_dst(skb)) : dev->mtu;
+       }
 
        if (skb_valid_dst(skb))
                skb_dst_update_pmtu_no_confirm(skb, mtu);
@@ -972,6 +978,9 @@ int __ip_tunnel_change_mtu(struct net_device *dev, int new_mtu, bool strict)
        int t_hlen = tunnel->hlen + sizeof(struct iphdr);
        int max_mtu = IP_MAX_MTU - t_hlen;
 
+       if (dev->type == ARPHRD_ETHER)
+               max_mtu -= dev->hard_header_len;
+
        if (new_mtu < ETH_MIN_MTU)
                return -EINVAL;
 
@@ -1149,6 +1158,9 @@ int ip_tunnel_newlink(struct net_device *dev, struct nlattr *tb[],
        if (tb[IFLA_MTU]) {
                unsigned int max = IP_MAX_MTU - (nt->hlen + sizeof(struct iphdr));
 
+               if (dev->type == ARPHRD_ETHER)
+                       max -= dev->hard_header_len;
+
                mtu = clamp(dev->mtu, (unsigned int)ETH_MIN_MTU, max);
        }
 
index 7b12a40..2dda856 100644 (file)
@@ -2119,7 +2119,7 @@ int ip_mr_input(struct sk_buff *skb)
                                raw_rcv(mroute_sk, skb);
                                return 0;
                        }
-                   }
+               }
        }
 
        /* already under rcu_read_lock() */
index 1b5b8af..ccacbde 100644 (file)
@@ -119,11 +119,8 @@ static int raw_diag_dump_one(struct netlink_callback *cb,
                return err;
        }
 
-       err = netlink_unicast(net->diag_nlsk, rep,
-                             NETLINK_CB(in_skb).portid,
-                             MSG_DONTWAIT);
-       if (err > 0)
-               err = 0;
+       err = nlmsg_unicast(net->diag_nlsk, rep, NETLINK_CB(in_skb).portid);
+
        return err;
 }
 
index d5ab5f2..8cb4404 100644 (file)
@@ -1375,6 +1375,9 @@ new_segment:
                        }
                        pfrag->offset += copy;
                } else {
+                       if (!sk_wmem_schedule(sk, copy))
+                               goto wait_for_space;
+
                        err = skb_zerocopy_iter_stream(sk, skb, msg, copy, uarg);
                        if (err == -EMSGSIZE || err == -EEXIST) {
                                tcp_mark_push(tp, skb);
index e6ca5a1..149ceb5 100644 (file)
@@ -4247,6 +4247,9 @@ void tcp_reset(struct sock *sk, struct sk_buff *skb)
 {
        trace_tcp_receive_reset(sk);
 
+       /* mptcp can't tell us to ignore reset pkts,
+        * so just ignore the return value of mptcp_incoming_options().
+        */
        if (sk_is_mptcp(sk))
                mptcp_incoming_options(sk, skb);
 
@@ -4941,8 +4944,13 @@ static void tcp_data_queue(struct sock *sk, struct sk_buff *skb)
        bool fragstolen;
        int eaten;
 
-       if (sk_is_mptcp(sk))
-               mptcp_incoming_options(sk, skb);
+       /* If a subflow has been reset, the packet should not continue
+        * to be processed, drop the packet.
+        */
+       if (sk_is_mptcp(sk) && !mptcp_incoming_options(sk, skb)) {
+               __kfree_skb(skb);
+               return;
+       }
 
        if (TCP_SKB_CB(skb)->seq == TCP_SKB_CB(skb)->end_seq) {
                __kfree_skb(skb);
@@ -5922,8 +5930,8 @@ void tcp_init_transfer(struct sock *sk, int bpf_op, struct sk_buff *skb)
                tp->snd_cwnd = tcp_init_cwnd(tp, __sk_dst_get(sk));
        tp->snd_cwnd_stamp = tcp_jiffies32;
 
-       icsk->icsk_ca_initialized = 0;
        bpf_skops_established(sk, bpf_op, skb);
+       /* Initialize congestion control unless BPF initialized it already: */
        if (!icsk->icsk_ca_initialized)
                tcp_init_congestion_control(sk);
        tcp_init_buffer_space(sk);
@@ -6523,8 +6531,11 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb)
        case TCP_CLOSING:
        case TCP_LAST_ACK:
                if (!before(TCP_SKB_CB(skb)->seq, tp->rcv_nxt)) {
-                       if (sk_is_mptcp(sk))
-                               mptcp_incoming_options(sk, skb);
+                       /* If a subflow has been reset, the packet should not
+                        * continue to be processed, drop the packet.
+                        */
+                       if (sk_is_mptcp(sk) && !mptcp_incoming_options(sk, skb))
+                               goto discard;
                        break;
                }
                fallthrough;
index e66ad6b..b9dc2d6 100644 (file)
@@ -342,7 +342,7 @@ void tcp_v4_mtu_reduced(struct sock *sk)
 
        if ((1 << sk->sk_state) & (TCPF_LISTEN | TCPF_CLOSE))
                return;
-       mtu = tcp_sk(sk)->mtu_info;
+       mtu = READ_ONCE(tcp_sk(sk)->mtu_info);
        dst = inet_csk_update_pmtu(sk, mtu);
        if (!dst)
                return;
@@ -546,7 +546,7 @@ int tcp_v4_err(struct sk_buff *skb, u32 info)
                        if (sk->sk_state == TCP_LISTEN)
                                goto out;
 
-                       tp->mtu_info = info;
+                       WRITE_ONCE(tp->mtu_info, info);
                        if (!sock_owned_by_user(sk)) {
                                tcp_v4_mtu_reduced(sk);
                        } else {
index bde781f..29553fc 100644 (file)
@@ -1732,6 +1732,7 @@ int tcp_mtu_to_mss(struct sock *sk, int pmtu)
        return __tcp_mtu_to_mss(sk, pmtu) -
               (tcp_sk(sk)->tcp_header_len - sizeof(struct tcphdr));
 }
+EXPORT_SYMBOL(tcp_mtu_to_mss);
 
 /* Inverse of above */
 int tcp_mss_to_mtu(struct sock *sk, int mss)
index 6268280..62cd4cd 100644 (file)
@@ -1102,7 +1102,7 @@ int udp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
        }
 
        ipcm_init_sk(&ipc, inet);
-       ipc.gso_size = up->gso_size;
+       ipc.gso_size = READ_ONCE(up->gso_size);
 
        if (msg->msg_controllen) {
                err = udp_cmsg_send(sk, msg, &ipc.gso_size);
@@ -2695,7 +2695,7 @@ int udp_lib_setsockopt(struct sock *sk, int level, int optname,
        case UDP_SEGMENT:
                if (val < 0 || val > USHRT_MAX)
                        return -EINVAL;
-               up->gso_size = val;
+               WRITE_ONCE(up->gso_size, val);
                break;
 
        case UDP_GRO:
@@ -2790,7 +2790,7 @@ int udp_lib_getsockopt(struct sock *sk, int level, int optname,
                break;
 
        case UDP_SEGMENT:
-               val = up->gso_size;
+               val = READ_ONCE(up->gso_size);
                break;
 
        case UDP_GRO:
index b2cee9a..1ed8c4d 100644 (file)
@@ -77,10 +77,8 @@ static int udp_dump_one(struct udp_table *tbl,
                kfree_skb(rep);
                goto out;
        }
-       err = netlink_unicast(net->diag_nlsk, rep, NETLINK_CB(in_skb).portid,
-                             MSG_DONTWAIT);
-       if (err > 0)
-               err = 0;
+       err = nlmsg_unicast(net->diag_nlsk, rep, NETLINK_CB(in_skb).portid);
+
 out:
        if (sk)
                sock_put(sk);
index 54e06b8..9dde1e5 100644 (file)
@@ -525,8 +525,10 @@ struct sk_buff *udp_gro_receive(struct list_head *head, struct sk_buff *skb,
 
                if ((!sk && (skb->dev->features & NETIF_F_GRO_UDP_FWD)) ||
                    (sk && udp_sk(sk)->gro_enabled) || NAPI_GRO_CB(skb)->is_flist)
-                       pp = call_gro_receive(udp_gro_receive_segment, head, skb);
-               return pp;
+                       return call_gro_receive(udp_gro_receive_segment, head, skb);
+
+               /* no GRO, be sure flush the current packet */
+               goto out;
        }
 
        if (NAPI_GRO_CB(skb)->encap_mark ||
index 984050f..01bea76 100644 (file)
@@ -60,10 +60,38 @@ static int ip6_finish_output2(struct net *net, struct sock *sk, struct sk_buff *
 {
        struct dst_entry *dst = skb_dst(skb);
        struct net_device *dev = dst->dev;
+       unsigned int hh_len = LL_RESERVED_SPACE(dev);
+       int delta = hh_len - skb_headroom(skb);
        const struct in6_addr *nexthop;
        struct neighbour *neigh;
        int ret;
 
+       /* Be paranoid, rather than too clever. */
+       if (unlikely(delta > 0) && dev->header_ops) {
+               /* pskb_expand_head() might crash, if skb is shared */
+               if (skb_shared(skb)) {
+                       struct sk_buff *nskb = skb_clone(skb, GFP_ATOMIC);
+
+                       if (likely(nskb)) {
+                               if (skb->sk)
+                                       skb_set_owner_w(skb, skb->sk);
+                               consume_skb(skb);
+                       } else {
+                               kfree_skb(skb);
+                       }
+                       skb = nskb;
+               }
+               if (skb &&
+                   pskb_expand_head(skb, SKB_DATA_ALIGN(delta), 0, GFP_ATOMIC)) {
+                       kfree_skb(skb);
+                       skb = NULL;
+               }
+               if (!skb) {
+                       IP6_INC_STATS(net, ip6_dst_idev(dst), IPSTATS_MIB_OUTDISCARDS);
+                       return -ENOMEM;
+               }
+       }
+
        if (ipv6_addr_is_multicast(&ipv6_hdr(skb)->daddr)) {
                struct inet6_dev *idev = ip6_dst_idev(skb_dst(skb));
 
@@ -479,7 +507,9 @@ int ip6_forward(struct sk_buff *skb)
        if (skb_warn_if_lro(skb))
                goto drop;
 
-       if (!xfrm6_policy_check(NULL, XFRM_POLICY_FWD, skb)) {
+       if (!net->ipv6.devconf_all->disable_policy &&
+           !idev->cnf.disable_policy &&
+           !xfrm6_policy_check(NULL, XFRM_POLICY_FWD, skb)) {
                __IP6_INC_STATS(net, idev, IPSTATS_MIB_INDISCARDS);
                goto drop;
        }
index 578ab63..0ce52d4 100644 (file)
@@ -348,11 +348,20 @@ failure:
 static void tcp_v6_mtu_reduced(struct sock *sk)
 {
        struct dst_entry *dst;
+       u32 mtu;
 
        if ((1 << sk->sk_state) & (TCPF_LISTEN | TCPF_CLOSE))
                return;
 
-       dst = inet6_csk_update_pmtu(sk, tcp_sk(sk)->mtu_info);
+       mtu = READ_ONCE(tcp_sk(sk)->mtu_info);
+
+       /* Drop requests trying to increase our current mss.
+        * Check done in __ip6_rt_update_pmtu() is too late.
+        */
+       if (tcp_mtu_to_mss(sk, mtu) >= tcp_sk(sk)->mss_cache)
+               return;
+
+       dst = inet6_csk_update_pmtu(sk, mtu);
        if (!dst)
                return;
 
@@ -433,6 +442,8 @@ static int tcp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
        }
 
        if (type == ICMPV6_PKT_TOOBIG) {
+               u32 mtu = ntohl(info);
+
                /* We are not interested in TCP_LISTEN and open_requests
                 * (SYN-ACKs send out by Linux are always <576bytes so
                 * they should go through unfragmented).
@@ -443,7 +454,11 @@ static int tcp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
                if (!ip6_sk_accept_pmtu(sk))
                        goto out;
 
-               tp->mtu_info = ntohl(info);
+               if (mtu < IPV6_MIN_MTU)
+                       goto out;
+
+               WRITE_ONCE(tp->mtu_info, mtu);
+
                if (!sock_owned_by_user(sk))
                        tcp_v6_mtu_reduced(sk);
                else if (!test_and_set_bit(TCP_MTU_REDUCED_DEFERRED,
@@ -540,7 +555,7 @@ static int tcp_v6_send_synack(const struct sock *sk, struct dst_entry *dst,
                opt = ireq->ipv6_opt;
                if (!opt)
                        opt = rcu_dereference(np->opt);
-               err = ip6_xmit(sk, skb, fl6, sk->sk_mark, opt,
+               err = ip6_xmit(sk, skb, fl6, skb->mark ? : sk->sk_mark, opt,
                               tclass, sk->sk_priority);
                rcu_read_unlock();
                err = net_xmit_eval(err);
index 368972d..0cc7ba5 100644 (file)
@@ -1296,7 +1296,7 @@ int udpv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
        int (*getfrag)(void *, char *, int, int, int, struct sk_buff *);
 
        ipcm6_init(&ipc6);
-       ipc6.gso_size = up->gso_size;
+       ipc6.gso_size = READ_ONCE(up->gso_size);
        ipc6.sockc.tsflags = sk->sk_tsflags;
        ipc6.sockc.mark = sk->sk_mark;
 
index 57fa27c..d0d2800 100644 (file)
@@ -49,7 +49,7 @@ static int __xfrm6_output(struct net *net, struct sock *sk, struct sk_buff *skb)
 {
        struct dst_entry *dst = skb_dst(skb);
        struct xfrm_state *x = dst->xfrm;
-       int mtu;
+       unsigned int mtu;
        bool toobig;
 
 #ifdef CONFIG_NETFILTER
index 349c6ac..e6795d5 100644 (file)
@@ -1635,14 +1635,16 @@ struct iucv_message_pending {
        u8  iptype;
        u32 ipmsgid;
        u32 iptrgcls;
-       union {
-               u32 iprmmsg1_u32;
-               u8  iprmmsg1[4];
-       } ln1msg1;
-       union {
-               u32 ipbfln1f;
-               u8  iprmmsg2[4];
-       } ln1msg2;
+       struct {
+               union {
+                       u32 iprmmsg1_u32;
+                       u8  iprmmsg1[4];
+               } ln1msg1;
+               union {
+                       u32 ipbfln1f;
+                       u8  iprmmsg2[4];
+               } ln1msg2;
+       } rmmsg;
        u32 res1[3];
        u32 ipbfln2f;
        u8  ippollfg;
@@ -1660,10 +1662,10 @@ static void iucv_message_pending(struct iucv_irq_data *data)
                msg.id = imp->ipmsgid;
                msg.class = imp->iptrgcls;
                if (imp->ipflags1 & IUCV_IPRMDATA) {
-                       memcpy(msg.rmmsg, imp->ln1msg1.iprmmsg1, 8);
+                       memcpy(msg.rmmsg, &imp->rmmsg, 8);
                        msg.length = 8;
                } else
-                       msg.length = imp->ln1msg2.ipbfln1f;
+                       msg.length = imp->rmmsg.ln1msg2.ipbfln1f;
                msg.reply_size = imp->ipbfln2f;
                path->handler->message_pending(path, &msg);
        }
index 52ea251..ff2cc0e 100644 (file)
@@ -44,6 +44,7 @@ static const struct snmp_mib mptcp_snmp_list[] = {
        SNMP_MIB_ITEM("RmSubflow", MPTCP_MIB_RMSUBFLOW),
        SNMP_MIB_ITEM("MPPrioTx", MPTCP_MIB_MPPRIOTX),
        SNMP_MIB_ITEM("MPPrioRx", MPTCP_MIB_MPPRIORX),
+       SNMP_MIB_ITEM("RcvPruned", MPTCP_MIB_RCVPRUNED),
        SNMP_MIB_SENTINEL
 };
 
index 193466c..0663cb1 100644 (file)
@@ -37,6 +37,7 @@ enum linux_mptcp_mib_field {
        MPTCP_MIB_RMSUBFLOW,            /* Remove a subflow */
        MPTCP_MIB_MPPRIOTX,             /* Transmit a MP_PRIO */
        MPTCP_MIB_MPPRIORX,             /* Received a MP_PRIO */
+       MPTCP_MIB_RCVPRUNED,            /* Incoming packet dropped due to memory limit */
        __MPTCP_MIB_MAX
 };
 
index 8f88dde..f48eb63 100644 (file)
@@ -57,10 +57,8 @@ static int mptcp_diag_dump_one(struct netlink_callback *cb,
                kfree_skb(rep);
                goto out;
        }
-       err = netlink_unicast(net->diag_nlsk, rep, NETLINK_CB(in_skb).portid,
-                             MSG_DONTWAIT);
-       if (err > 0)
-               err = 0;
+       err = nlmsg_unicast(net->diag_nlsk, rep, NETLINK_CB(in_skb).portid);
+
 out:
        sock_put(sk);
 
index b5850af..4452455 100644 (file)
@@ -1035,7 +1035,8 @@ static bool add_addr_hmac_valid(struct mptcp_sock *msk,
        return hmac == mp_opt->ahmac;
 }
 
-void mptcp_incoming_options(struct sock *sk, struct sk_buff *skb)
+/* Return false if a subflow has been reset, else return true */
+bool mptcp_incoming_options(struct sock *sk, struct sk_buff *skb)
 {
        struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(sk);
        struct mptcp_sock *msk = mptcp_sk(subflow->conn);
@@ -1053,12 +1054,16 @@ void mptcp_incoming_options(struct sock *sk, struct sk_buff *skb)
                        __mptcp_check_push(subflow->conn, sk);
                __mptcp_data_acked(subflow->conn);
                mptcp_data_unlock(subflow->conn);
-               return;
+               return true;
        }
 
        mptcp_get_options(sk, skb, &mp_opt);
+
+       /* The subflow can be in close state only if check_fully_established()
+        * just sent a reset. If so, tell the caller to ignore the current packet.
+        */
        if (!check_fully_established(msk, sk, subflow, skb, &mp_opt))
-               return;
+               return sk->sk_state != TCP_CLOSE;
 
        if (mp_opt.fastclose &&
            msk->local_key == mp_opt.rcvr_key) {
@@ -1100,7 +1105,7 @@ void mptcp_incoming_options(struct sock *sk, struct sk_buff *skb)
        }
 
        if (!mp_opt.dss)
-               return;
+               return true;
 
        /* we can't wait for recvmsg() to update the ack_seq, otherwise
         * monodirectional flows will stuck
@@ -1119,12 +1124,12 @@ void mptcp_incoming_options(struct sock *sk, struct sk_buff *skb)
                    schedule_work(&msk->work))
                        sock_hold(subflow->conn);
 
-               return;
+               return true;
        }
 
        mpext = skb_ext_add(skb, SKB_EXT_MPTCP);
        if (!mpext)
-               return;
+               return true;
 
        memset(mpext, 0, sizeof(*mpext));
 
@@ -1153,6 +1158,8 @@ void mptcp_incoming_options(struct sock *sk, struct sk_buff *skb)
                if (mpext->csum_reqd)
                        mpext->csum = mp_opt.csum;
        }
+
+       return true;
 }
 
 static void mptcp_set_rwin(const struct tcp_sock *tp)
index 7a5afa8..a889249 100644 (file)
@@ -474,7 +474,7 @@ static void mptcp_cleanup_rbuf(struct mptcp_sock *msk)
        bool cleanup, rx_empty;
 
        cleanup = (space > 0) && (space >= (old_space << 1));
-       rx_empty = !atomic_read(&sk->sk_rmem_alloc);
+       rx_empty = !__mptcp_rmem(sk);
 
        mptcp_for_each_subflow(msk, subflow) {
                struct sock *ssk = mptcp_subflow_tcp_sock(subflow);
@@ -720,8 +720,10 @@ void mptcp_data_ready(struct sock *sk, struct sock *ssk)
                sk_rbuf = ssk_rbuf;
 
        /* over limit? can't append more skbs to msk, Also, no need to wake-up*/
-       if (atomic_read(&sk->sk_rmem_alloc) > sk_rbuf)
+       if (__mptcp_rmem(sk) > sk_rbuf) {
+               MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_RCVPRUNED);
                return;
+       }
 
        /* Wake-up the reader only for in-sequence data */
        mptcp_data_lock(sk);
@@ -1754,7 +1756,7 @@ static int __mptcp_recvmsg_mskq(struct mptcp_sock *msk,
                if (!(flags & MSG_PEEK)) {
                        /* we will bulk release the skb memory later */
                        skb->destructor = NULL;
-                       msk->rmem_released += skb->truesize;
+                       WRITE_ONCE(msk->rmem_released, msk->rmem_released + skb->truesize);
                        __skb_unlink(skb, &msk->receive_queue);
                        __kfree_skb(skb);
                }
@@ -1873,7 +1875,7 @@ static void __mptcp_update_rmem(struct sock *sk)
 
        atomic_sub(msk->rmem_released, &sk->sk_rmem_alloc);
        sk_mem_uncharge(sk, msk->rmem_released);
-       msk->rmem_released = 0;
+       WRITE_ONCE(msk->rmem_released, 0);
 }
 
 static void __mptcp_splice_receive_queue(struct sock *sk)
@@ -2380,7 +2382,7 @@ static int __mptcp_init_sock(struct sock *sk)
        msk->out_of_order_queue = RB_ROOT;
        msk->first_pending = NULL;
        msk->wmem_reserved = 0;
-       msk->rmem_released = 0;
+       WRITE_ONCE(msk->rmem_released, 0);
        msk->tx_pending_data = 0;
 
        msk->first = NULL;
index 426ed80..0f0c026 100644 (file)
@@ -296,9 +296,17 @@ static inline struct mptcp_sock *mptcp_sk(const struct sock *sk)
        return (struct mptcp_sock *)sk;
 }
 
+/* the msk socket don't use the backlog, also account for the bulk
+ * free memory
+ */
+static inline int __mptcp_rmem(const struct sock *sk)
+{
+       return atomic_read(&sk->sk_rmem_alloc) - READ_ONCE(mptcp_sk(sk)->rmem_released);
+}
+
 static inline int __mptcp_space(const struct sock *sk)
 {
-       return tcp_space(sk) + READ_ONCE(mptcp_sk(sk)->rmem_released);
+       return tcp_win_from_space(sk, READ_ONCE(sk->sk_rcvbuf) - __mptcp_rmem(sk));
 }
 
 static inline struct mptcp_data_frag *mptcp_send_head(const struct sock *sk)
index 092d1f6..8c03afa 100644 (file)
@@ -157,19 +157,7 @@ static int mptcp_setsockopt_sol_socket_tstamp(struct mptcp_sock *msk, int optnam
                struct sock *ssk = mptcp_subflow_tcp_sock(subflow);
                bool slow = lock_sock_fast(ssk);
 
-               switch (optname) {
-               case SO_TIMESTAMP_OLD:
-               case SO_TIMESTAMP_NEW:
-               case SO_TIMESTAMPNS_OLD:
-               case SO_TIMESTAMPNS_NEW:
-                       sock_set_timestamp(sk, optname, !!val);
-                       break;
-               case SO_TIMESTAMPING_NEW:
-               case SO_TIMESTAMPING_OLD:
-                       sock_set_timestamping(sk, optname, val);
-                       break;
-               }
-
+               sock_set_timestamp(sk, optname, !!val);
                unlock_sock_fast(ssk, slow);
        }
 
@@ -178,7 +166,8 @@ static int mptcp_setsockopt_sol_socket_tstamp(struct mptcp_sock *msk, int optnam
 }
 
 static int mptcp_setsockopt_sol_socket_int(struct mptcp_sock *msk, int optname,
-                                          sockptr_t optval, unsigned int optlen)
+                                          sockptr_t optval,
+                                          unsigned int optlen)
 {
        int val, ret;
 
@@ -205,14 +194,56 @@ static int mptcp_setsockopt_sol_socket_int(struct mptcp_sock *msk, int optname,
        case SO_TIMESTAMP_NEW:
        case SO_TIMESTAMPNS_OLD:
        case SO_TIMESTAMPNS_NEW:
-       case SO_TIMESTAMPING_OLD:
-       case SO_TIMESTAMPING_NEW:
                return mptcp_setsockopt_sol_socket_tstamp(msk, optname, val);
        }
 
        return -ENOPROTOOPT;
 }
 
+static int mptcp_setsockopt_sol_socket_timestamping(struct mptcp_sock *msk,
+                                                   int optname,
+                                                   sockptr_t optval,
+                                                   unsigned int optlen)
+{
+       struct mptcp_subflow_context *subflow;
+       struct sock *sk = (struct sock *)msk;
+       struct so_timestamping timestamping;
+       int ret;
+
+       if (optlen == sizeof(timestamping)) {
+               if (copy_from_sockptr(&timestamping, optval,
+                                     sizeof(timestamping)))
+                       return -EFAULT;
+       } else if (optlen == sizeof(int)) {
+               memset(&timestamping, 0, sizeof(timestamping));
+
+               if (copy_from_sockptr(&timestamping.flags, optval, sizeof(int)))
+                       return -EFAULT;
+       } else {
+               return -EINVAL;
+       }
+
+       ret = sock_setsockopt(sk->sk_socket, SOL_SOCKET, optname,
+                             KERNEL_SOCKPTR(&timestamping),
+                             sizeof(timestamping));
+       if (ret)
+               return ret;
+
+       lock_sock(sk);
+
+       mptcp_for_each_subflow(msk, subflow) {
+               struct sock *ssk = mptcp_subflow_tcp_sock(subflow);
+               bool slow = lock_sock_fast(ssk);
+
+               sock_set_timestamping(sk, optname, timestamping);
+               unlock_sock_fast(ssk, slow);
+       }
+
+       release_sock(sk);
+
+       return 0;
+}
+
 static int mptcp_setsockopt_sol_socket_linger(struct mptcp_sock *msk, sockptr_t optval,
                                              unsigned int optlen)
 {
@@ -299,9 +330,12 @@ static int mptcp_setsockopt_sol_socket(struct mptcp_sock *msk, int optname,
        case SO_TIMESTAMP_NEW:
        case SO_TIMESTAMPNS_OLD:
        case SO_TIMESTAMPNS_NEW:
+               return mptcp_setsockopt_sol_socket_int(msk, optname, optval,
+                                                      optlen);
        case SO_TIMESTAMPING_OLD:
        case SO_TIMESTAMPING_NEW:
-               return mptcp_setsockopt_sol_socket_int(msk, optname, optval, optlen);
+               return mptcp_setsockopt_sol_socket_timestamping(msk, optname,
+                                                               optval, optlen);
        case SO_LINGER:
                return mptcp_setsockopt_sol_socket_linger(msk, optval, optlen);
        case SO_RCVLOWAT:
index 66d0b18..966f777 100644 (file)
@@ -214,11 +214,6 @@ again:
                                 ntohs(inet_sk(sk_listener)->inet_sport),
                                 ntohs(inet_sk((struct sock *)subflow_req->msk)->inet_sport));
                        if (!mptcp_pm_sport_in_anno_list(subflow_req->msk, sk_listener)) {
-                               sock_put((struct sock *)subflow_req->msk);
-                               mptcp_token_destroy_request(req);
-                               tcp_request_sock_ops.destructor(req);
-                               subflow_req->msk = NULL;
-                               subflow_req->mp_join = 0;
                                SUBFLOW_REQ_INC_STATS(req, MPTCP_MIB_MISMATCHPORTSYNRX);
                                return -EPERM;
                        }
@@ -230,6 +225,8 @@ again:
                if (unlikely(req->syncookie)) {
                        if (mptcp_can_accept_new_subflow(subflow_req->msk))
                                subflow_init_req_cookie_join_save(subflow_req, skb);
+                       else
+                               return -EPERM;
                }
 
                pr_debug("token=%u, remote_nonce=%u msk=%p", subflow_req->token,
@@ -269,9 +266,7 @@ int mptcp_subflow_init_cookie_req(struct request_sock *req,
                if (!mptcp_token_join_cookie_init_state(subflow_req, skb))
                        return -EINVAL;
 
-               if (mptcp_can_accept_new_subflow(subflow_req->msk))
-                       subflow_req->mp_join = 1;
-
+               subflow_req->mp_join = 1;
                subflow_req->ssn_offset = TCP_SKB_CB(skb)->seq - 1;
        }
 
index abe0fd0..3712778 100644 (file)
@@ -37,7 +37,21 @@ static spinlock_t join_entry_locks[COOKIE_JOIN_SLOTS] __cacheline_aligned_in_smp
 
 static u32 mptcp_join_entry_hash(struct sk_buff *skb, struct net *net)
 {
-       u32 i = skb_get_hash(skb) ^ net_hash_mix(net);
+       static u32 mptcp_join_hash_secret __read_mostly;
+       struct tcphdr *th = tcp_hdr(skb);
+       u32 seq, i;
+
+       net_get_random_once(&mptcp_join_hash_secret,
+                           sizeof(mptcp_join_hash_secret));
+
+       if (th->syn)
+               seq = TCP_SKB_CB(skb)->seq;
+       else
+               seq = TCP_SKB_CB(skb)->seq - 1;
+
+       i = jhash_3words(seq, net_hash_mix(net),
+                        (__force __u32)th->source << 16 | (__force __u32)th->dest,
+                        mptcp_join_hash_secret);
 
        return i % ARRAY_SIZE(join_entries);
 }
index 9330908..ea1dd32 100644 (file)
@@ -17,3 +17,9 @@ config NCSI_OEM_CMD_GET_MAC
        help
          This allows to get MAC address from NCSI firmware and set them back to
                controller.
+config NCSI_OEM_CMD_KEEP_PHY
+       bool "Keep PHY Link up"
+       depends on NET_NCSI
+       help
+         This allows to keep PHY link up and prevents any channel resets during
+         the host load.
index cbbb0de..0b6cfd3 100644 (file)
@@ -78,6 +78,9 @@ enum {
 /* OEM Vendor Manufacture ID */
 #define NCSI_OEM_MFR_MLX_ID             0x8119
 #define NCSI_OEM_MFR_BCM_ID             0x113d
+#define NCSI_OEM_MFR_INTEL_ID           0x157
+/* Intel specific OEM command */
+#define NCSI_OEM_INTEL_CMD_KEEP_PHY     0x20   /* CMD ID for Keep PHY up */
 /* Broadcom specific OEM Command */
 #define NCSI_OEM_BCM_CMD_GMA            0x01   /* CMD ID for Get MAC */
 /* Mellanox specific OEM Command */
@@ -86,6 +89,7 @@ enum {
 #define NCSI_OEM_MLX_CMD_SMAF           0x01   /* CMD ID for Set MC Affinity */
 #define NCSI_OEM_MLX_CMD_SMAF_PARAM     0x07   /* Parameter for SMAF         */
 /* OEM Command payload lengths*/
+#define NCSI_OEM_INTEL_CMD_KEEP_PHY_LEN 7
 #define NCSI_OEM_BCM_CMD_GMA_LEN        12
 #define NCSI_OEM_MLX_CMD_GMA_LEN        8
 #define NCSI_OEM_MLX_CMD_SMAF_LEN        60
@@ -271,6 +275,7 @@ enum {
        ncsi_dev_state_probe_mlx_gma,
        ncsi_dev_state_probe_mlx_smaf,
        ncsi_dev_state_probe_cis,
+       ncsi_dev_state_probe_keep_phy,
        ncsi_dev_state_probe_gvi,
        ncsi_dev_state_probe_gc,
        ncsi_dev_state_probe_gls,
index ca04b6d..89c7742 100644 (file)
@@ -689,6 +689,35 @@ static int set_one_vid(struct ncsi_dev_priv *ndp, struct ncsi_channel *nc,
        return 0;
 }
 
+#if IS_ENABLED(CONFIG_NCSI_OEM_CMD_KEEP_PHY)
+
+static int ncsi_oem_keep_phy_intel(struct ncsi_cmd_arg *nca)
+{
+       unsigned char data[NCSI_OEM_INTEL_CMD_KEEP_PHY_LEN];
+       int ret = 0;
+
+       nca->payload = NCSI_OEM_INTEL_CMD_KEEP_PHY_LEN;
+
+       memset(data, 0, NCSI_OEM_INTEL_CMD_KEEP_PHY_LEN);
+       *(unsigned int *)data = ntohl((__force __be32)NCSI_OEM_MFR_INTEL_ID);
+
+       data[4] = NCSI_OEM_INTEL_CMD_KEEP_PHY;
+
+       /* PHY Link up attribute */
+       data[6] = 0x1;
+
+       nca->data = data;
+
+       ret = ncsi_xmit_cmd(nca);
+       if (ret)
+               netdev_err(nca->ndp->ndev.dev,
+                          "NCSI: Failed to transmit cmd 0x%x during configure\n",
+                          nca->type);
+       return ret;
+}
+
+#endif
+
 #if IS_ENABLED(CONFIG_NCSI_OEM_CMD_GET_MAC)
 
 /* NCSI OEM Command APIs */
@@ -700,7 +729,7 @@ static int ncsi_oem_gma_handler_bcm(struct ncsi_cmd_arg *nca)
        nca->payload = NCSI_OEM_BCM_CMD_GMA_LEN;
 
        memset(data, 0, NCSI_OEM_BCM_CMD_GMA_LEN);
-       *(unsigned int *)data = ntohl(NCSI_OEM_MFR_BCM_ID);
+       *(unsigned int *)data = ntohl((__force __be32)NCSI_OEM_MFR_BCM_ID);
        data[5] = NCSI_OEM_BCM_CMD_GMA;
 
        nca->data = data;
@@ -724,7 +753,7 @@ static int ncsi_oem_gma_handler_mlx(struct ncsi_cmd_arg *nca)
        nca->payload = NCSI_OEM_MLX_CMD_GMA_LEN;
 
        memset(&u, 0, sizeof(u));
-       u.data_u32[0] = ntohl(NCSI_OEM_MFR_MLX_ID);
+       u.data_u32[0] = ntohl((__force __be32)NCSI_OEM_MFR_MLX_ID);
        u.data_u8[5] = NCSI_OEM_MLX_CMD_GMA;
        u.data_u8[6] = NCSI_OEM_MLX_CMD_GMA_PARAM;
 
@@ -747,7 +776,7 @@ static int ncsi_oem_smaf_mlx(struct ncsi_cmd_arg *nca)
        int ret = 0;
 
        memset(&u, 0, sizeof(u));
-       u.data_u32[0] = ntohl(NCSI_OEM_MFR_MLX_ID);
+       u.data_u32[0] = ntohl((__force __be32)NCSI_OEM_MFR_MLX_ID);
        u.data_u8[5] = NCSI_OEM_MLX_CMD_SMAF;
        u.data_u8[6] = NCSI_OEM_MLX_CMD_SMAF_PARAM;
        memcpy(&u.data_u8[MLX_SMAF_MAC_ADDR_OFFSET],
@@ -1391,8 +1420,24 @@ static void ncsi_probe_channel(struct ncsi_dev_priv *ndp)
                                goto error;
                }
 
+               nd->state = ncsi_dev_state_probe_gvi;
+               if (IS_ENABLED(CONFIG_NCSI_OEM_CMD_KEEP_PHY))
+                       nd->state = ncsi_dev_state_probe_keep_phy;
+               break;
+#if IS_ENABLED(CONFIG_NCSI_OEM_CMD_KEEP_PHY)
+       case ncsi_dev_state_probe_keep_phy:
+               ndp->pending_req_num = 1;
+
+               nca.type = NCSI_PKT_CMD_OEM;
+               nca.package = ndp->active_package->id;
+               nca.channel = 0;
+               ret = ncsi_oem_keep_phy_intel(&nca);
+               if (ret)
+                       goto error;
+
                nd->state = ncsi_dev_state_probe_gvi;
                break;
+#endif /* CONFIG_NCSI_OEM_CMD_KEEP_PHY */
        case ncsi_dev_state_probe_gvi:
        case ncsi_dev_state_probe_gc:
        case ncsi_dev_state_probe_gls:
index 888ccc2..d483748 100644 (file)
@@ -403,7 +403,7 @@ static int ncsi_rsp_handler_ev(struct ncsi_request *nr)
        /* Update to VLAN mode */
        cmd = (struct ncsi_cmd_ev_pkt *)skb_network_header(nr->cmd);
        ncm->enable = 1;
-       ncm->data[0] = ntohl(cmd->mode);
+       ncm->data[0] = ntohl((__force __be32)cmd->mode);
 
        return 0;
 }
@@ -699,12 +699,19 @@ static int ncsi_rsp_handler_oem_bcm(struct ncsi_request *nr)
        return 0;
 }
 
+/* Response handler for Intel card */
+static int ncsi_rsp_handler_oem_intel(struct ncsi_request *nr)
+{
+       return 0;
+}
+
 static struct ncsi_rsp_oem_handler {
        unsigned int    mfr_id;
        int             (*handler)(struct ncsi_request *nr);
 } ncsi_rsp_oem_handlers[] = {
        { NCSI_OEM_MFR_MLX_ID, ncsi_rsp_handler_oem_mlx },
-       { NCSI_OEM_MFR_BCM_ID, ncsi_rsp_handler_oem_bcm }
+       { NCSI_OEM_MFR_BCM_ID, ncsi_rsp_handler_oem_bcm },
+       { NCSI_OEM_MFR_INTEL_ID, ncsi_rsp_handler_oem_intel }
 };
 
 /* Response handler for OEM command */
index 96ba19f..83c52df 100644 (file)
@@ -149,7 +149,15 @@ static void nf_conntrack_all_lock(void)
 
        spin_lock(&nf_conntrack_locks_all_lock);
 
-       nf_conntrack_locks_all = true;
+       /* For nf_contrack_locks_all, only the latest time when another
+        * CPU will see an update is controlled, by the "release" of the
+        * spin_lock below.
+        * The earliest time is not controlled, an thus KCSAN could detect
+        * a race when nf_conntract_lock() reads the variable.
+        * WRITE_ONCE() is used to ensure the compiler will not
+        * optimize the write.
+        */
+       WRITE_ONCE(nf_conntrack_locks_all, true);
 
        for (i = 0; i < CONNTRACK_LOCKS; i++) {
                spin_lock(&nf_conntrack_locks[i]);
@@ -2457,7 +2465,6 @@ i_see_dead_people:
        }
 
        list_for_each_entry(net, net_exit_list, exit_list) {
-               nf_conntrack_proto_pernet_fini(net);
                nf_conntrack_ecache_pernet_fini(net);
                nf_conntrack_expect_pernet_fini(net);
                free_percpu(net->ct.stat);
index 4e1a9db..e81af33 100644 (file)
@@ -218,6 +218,7 @@ static int ctnetlink_dump_helpinfo(struct sk_buff *skb,
        if (!help)
                return 0;
 
+       rcu_read_lock();
        helper = rcu_dereference(help->helper);
        if (!helper)
                goto out;
@@ -233,9 +234,11 @@ static int ctnetlink_dump_helpinfo(struct sk_buff *skb,
 
        nla_nest_end(skb, nest_helper);
 out:
+       rcu_read_unlock();
        return 0;
 
 nla_put_failure:
+       rcu_read_unlock();
        return -1;
 }
 
index 5564740..8f7a983 100644 (file)
@@ -697,13 +697,6 @@ void nf_conntrack_proto_pernet_init(struct net *net)
 #endif
 }
 
-void nf_conntrack_proto_pernet_fini(struct net *net)
-{
-#ifdef CONFIG_NF_CT_PROTO_GRE
-       nf_ct_gre_keymap_flush(net);
-#endif
-}
-
 module_param_call(hashsize, nf_conntrack_set_hashsize, param_get_uint,
                  &nf_conntrack_htable_size, 0600);
 
index db11e40..728eeb0 100644 (file)
@@ -55,19 +55,6 @@ static inline struct nf_gre_net *gre_pernet(struct net *net)
        return &net->ct.nf_ct_proto.gre;
 }
 
-void nf_ct_gre_keymap_flush(struct net *net)
-{
-       struct nf_gre_net *net_gre = gre_pernet(net);
-       struct nf_ct_gre_keymap *km, *tmp;
-
-       spin_lock_bh(&keymap_lock);
-       list_for_each_entry_safe(km, tmp, &net_gre->keymap_list, list) {
-               list_del_rcu(&km->list);
-               kfree_rcu(km, rcu);
-       }
-       spin_unlock_bh(&keymap_lock);
-}
-
 static inline int gre_key_cmpfn(const struct nf_ct_gre_keymap *km,
                                const struct nf_conntrack_tuple *t)
 {
index f7e8baf..3259416 100644 (file)
@@ -823,6 +823,22 @@ static noinline bool tcp_new(struct nf_conn *ct, const struct sk_buff *skb,
        return true;
 }
 
+static bool tcp_can_early_drop(const struct nf_conn *ct)
+{
+       switch (ct->proto.tcp.state) {
+       case TCP_CONNTRACK_FIN_WAIT:
+       case TCP_CONNTRACK_LAST_ACK:
+       case TCP_CONNTRACK_TIME_WAIT:
+       case TCP_CONNTRACK_CLOSE:
+       case TCP_CONNTRACK_CLOSE_WAIT:
+               return true;
+       default:
+               break;
+       }
+
+       return false;
+}
+
 /* Returns verdict for packet, or -1 for invalid. */
 int nf_conntrack_tcp_packet(struct nf_conn *ct,
                            struct sk_buff *skb,
@@ -1030,10 +1046,30 @@ int nf_conntrack_tcp_packet(struct nf_conn *ct,
                if (index != TCP_RST_SET)
                        break;
 
-               if (ct->proto.tcp.seen[!dir].flags & IP_CT_TCP_FLAG_MAXACK_SET) {
+               /* If we are closing, tuple might have been re-used already.
+                * last_index, last_ack, and all other ct fields used for
+                * sequence/window validation are outdated in that case.
+                *
+                * As the conntrack can already be expired by GC under pressure,
+                * just skip validation checks.
+                */
+               if (tcp_can_early_drop(ct))
+                       goto in_window;
+
+               /* td_maxack might be outdated if we let a SYN through earlier */
+               if ((ct->proto.tcp.seen[!dir].flags & IP_CT_TCP_FLAG_MAXACK_SET) &&
+                   ct->proto.tcp.last_index != TCP_SYN_SET) {
                        u32 seq = ntohl(th->seq);
 
-                       if (before(seq, ct->proto.tcp.seen[!dir].td_maxack)) {
+                       /* If we are not in established state and SEQ=0 this is most
+                        * likely an answer to a SYN we let go through above (last_index
+                        * can be updated due to out-of-order ACKs).
+                        */
+                       if (seq == 0 && !nf_conntrack_tcp_established(ct))
+                               break;
+
+                       if (before(seq, ct->proto.tcp.seen[!dir].td_maxack) &&
+                           !tn->tcp_ignore_invalid_rst) {
                                /* Invalid RST  */
                                spin_unlock_bh(&ct->lock);
                                nf_ct_l4proto_log_invalid(skb, ct, state, "invalid rst");
@@ -1134,6 +1170,16 @@ int nf_conntrack_tcp_packet(struct nf_conn *ct,
                        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.
                 */
@@ -1155,22 +1201,6 @@ int nf_conntrack_tcp_packet(struct nf_conn *ct,
        return NF_ACCEPT;
 }
 
-static bool tcp_can_early_drop(const struct nf_conn *ct)
-{
-       switch (ct->proto.tcp.state) {
-       case TCP_CONNTRACK_FIN_WAIT:
-       case TCP_CONNTRACK_LAST_ACK:
-       case TCP_CONNTRACK_TIME_WAIT:
-       case TCP_CONNTRACK_CLOSE:
-       case TCP_CONNTRACK_CLOSE_WAIT:
-               return true;
-       default:
-               break;
-       }
-
-       return false;
-}
-
 #if IS_ENABLED(CONFIG_NF_CT_NETLINK)
 
 #include <linux/netfilter/nfnetlink.h>
@@ -1437,6 +1467,9 @@ void nf_conntrack_tcp_init_net(struct net *net)
         */
        tn->tcp_be_liberal = 0;
 
+       /* If it's non-zero, we turn off RST sequence number check */
+       tn->tcp_ignore_invalid_rst = 0;
+
        /* Max number of the retransmitted packets without receiving an (acceptable)
         * ACK from the destination. If this number is reached, a shorter timer
         * will be started.
index f57a951..214d9f9 100644 (file)
@@ -579,6 +579,7 @@ enum nf_ct_sysctl_index {
 #endif
        NF_SYSCTL_CT_PROTO_TCP_LOOSE,
        NF_SYSCTL_CT_PROTO_TCP_LIBERAL,
+       NF_SYSCTL_CT_PROTO_TCP_IGNORE_INVALID_RST,
        NF_SYSCTL_CT_PROTO_TCP_MAX_RETRANS,
        NF_SYSCTL_CT_PROTO_TIMEOUT_UDP,
        NF_SYSCTL_CT_PROTO_TIMEOUT_UDP_STREAM,
@@ -798,6 +799,14 @@ static struct ctl_table nf_ct_sysctl_table[] = {
                .extra1         = SYSCTL_ZERO,
                .extra2         = SYSCTL_ONE,
        },
+       [NF_SYSCTL_CT_PROTO_TCP_IGNORE_INVALID_RST] = {
+               .procname       = "nf_conntrack_tcp_ignore_invalid_rst",
+               .maxlen         = sizeof(u8),
+               .mode           = 0644,
+               .proc_handler   = proc_dou8vec_minmax,
+               .extra1         = SYSCTL_ZERO,
+               .extra2         = SYSCTL_ONE,
+       },
        [NF_SYSCTL_CT_PROTO_TCP_MAX_RETRANS] = {
                .procname       = "nf_conntrack_tcp_max_retrans",
                .maxlen         = sizeof(u8),
@@ -1004,6 +1013,7 @@ static void nf_conntrack_standalone_init_tcp_sysctl(struct net *net,
        XASSIGN(LOOSE, &tn->tcp_loose);
        XASSIGN(LIBERAL, &tn->tcp_be_liberal);
        XASSIGN(MAX_RETRANS, &tn->tcp_max_retrans);
+       XASSIGN(IGNORE_INVALID_RST, &tn->tcp_ignore_invalid_rst);
 #undef XASSIGN
 
 #if IS_ENABLED(CONFIG_NF_FLOW_TABLE)
index 390d446..de182d1 100644 (file)
@@ -3446,7 +3446,8 @@ static int nf_tables_newrule(struct sk_buff *skb, const struct nfnl_info *info,
        return 0;
 
 err_destroy_flow_rule:
-       nft_flow_rule_destroy(flow);
+       if (flow)
+               nft_flow_rule_destroy(flow);
 err_release_rule:
        nf_tables_rule_release(&ctx, rule);
 err_release_expr:
index 913ac45..8088b99 100644 (file)
@@ -23,15 +23,21 @@ static int nft_last_init(const struct nft_ctx *ctx, const struct nft_expr *expr,
 {
        struct nft_last_priv *priv = nft_expr_priv(expr);
        u64 last_jiffies;
+       u32 last_set = 0;
        int err;
 
-       if (tb[NFTA_LAST_MSECS]) {
+       if (tb[NFTA_LAST_SET]) {
+               last_set = ntohl(nla_get_be32(tb[NFTA_LAST_SET]));
+               if (last_set == 1)
+                       priv->last_set = 1;
+       }
+
+       if (last_set && tb[NFTA_LAST_MSECS]) {
                err = nf_msecs_to_jiffies64(tb[NFTA_LAST_MSECS], &last_jiffies);
                if (err < 0)
                        return err;
 
-               priv->last_jiffies = jiffies + (unsigned long)last_jiffies;
-               priv->last_set = 1;
+               priv->last_jiffies = jiffies - (unsigned long)last_jiffies;
        }
 
        return 0;
index d233ac4..380f95a 100644 (file)
@@ -2471,7 +2471,7 @@ void netlink_ack(struct sk_buff *in_skb, struct nlmsghdr *nlh, int err,
 
        nlmsg_end(skb, rep);
 
-       netlink_unicast(in_skb->sk, skb, NETLINK_CB(in_skb).portid, MSG_DONTWAIT);
+       nlmsg_unicast(in_skb->sk, skb, NETLINK_CB(in_skb).portid);
 }
 EXPORT_SYMBOL(netlink_ack);
 
index c89c8da..d4a2db0 100644 (file)
@@ -670,13 +670,13 @@ static bool cmp_key(const struct sw_flow_key *key1,
 {
        const long *cp1 = (const long *)((const u8 *)key1 + key_start);
        const long *cp2 = (const long *)((const u8 *)key2 + key_start);
-       long diffs = 0;
        int i;
 
        for (i = key_start; i < key_end; i += sizeof(long))
-               diffs |= *cp1++ ^ *cp2++;
+               if (*cp1++ ^ *cp2++)
+                       return false;
 
-       return diffs == 0;
+       return true;
 }
 
 static bool flow_cmp_masked_key(const struct sw_flow *flow,
index a656baa..1b4b351 100644 (file)
@@ -322,11 +322,22 @@ err_alloc:
 
 static void tcf_ct_flow_table_cleanup_work(struct work_struct *work)
 {
+       struct flow_block_cb *block_cb, *tmp_cb;
        struct tcf_ct_flow_table *ct_ft;
+       struct flow_block *block;
 
        ct_ft = container_of(to_rcu_work(work), struct tcf_ct_flow_table,
                             rwork);
        nf_flow_table_free(&ct_ft->nf_ft);
+
+       /* Remove any remaining callbacks before cleanup */
+       block = &ct_ft->nf_ft.flow_block;
+       down_write(&ct_ft->nf_ft.flow_block_lock);
+       list_for_each_entry_safe(block_cb, tmp_cb, &block->cb_list, list) {
+               list_del(&block_cb->list);
+               flow_block_cb_free(block_cb);
+       }
+       up_write(&ct_ft->nf_ft.flow_block_lock);
        kfree(ct_ft);
 
        module_put(THIS_MODULE);
@@ -1026,7 +1037,8 @@ do_nat:
                /* This will take care of sending queued events
                 * even if the connection is already confirmed.
                 */
-               nf_conntrack_confirm(skb);
+               if (nf_conntrack_confirm(skb) != NF_ACCEPT)
+                       goto drop;
        }
 
        if (!skip_add)
index 66fe2b8..07b30d0 100644 (file)
@@ -564,7 +564,7 @@ static struct sk_buff *taprio_dequeue_soft(struct Qdisc *sch)
        /* if there's no entry, it means that the schedule didn't
         * start yet, so force all gates to be open, this is in
         * accordance to IEEE 802.1Qbv-2015 Section 8.6.9.4.5
-        * "AdminGateSates"
+        * "AdminGateStates"
         */
        gate_mask = entry ? entry->gate_mask : TAPRIO_ALL_GATES_OPEN;
 
index 493fc01..760b367 100644 (file)
@@ -284,10 +284,8 @@ static int sctp_tsp_dump_one(struct sctp_transport *tsp, void *p)
                goto out;
        }
 
-       err = netlink_unicast(net->diag_nlsk, rep, NETLINK_CB(in_skb).portid,
-                             MSG_DONTWAIT);
-       if (err > 0)
-               err = 0;
+       err = nlmsg_unicast(net->diag_nlsk, rep, NETLINK_CB(in_skb).portid);
+
 out:
        return err;
 }
index 3c1fbf3..ec0f525 100644 (file)
@@ -398,7 +398,8 @@ static enum sctp_scope sctp_v4_scope(union sctp_addr *addr)
                retval = SCTP_SCOPE_LINK;
        } else if (ipv4_is_private_10(addr->v4.sin_addr.s_addr) ||
                   ipv4_is_private_172(addr->v4.sin_addr.s_addr) ||
-                  ipv4_is_private_192(addr->v4.sin_addr.s_addr)) {
+                  ipv4_is_private_192(addr->v4.sin_addr.s_addr) ||
+                  ipv4_is_test_198(addr->v4.sin_addr.s_addr)) {
                retval = SCTP_SCOPE_PRIVATE;
        } else {
                retval = SCTP_SCOPE_GLOBAL;
index 6c08e50..b8fa8f1 100644 (file)
@@ -1163,7 +1163,7 @@ struct sctp_chunk *sctp_make_heartbeat(const struct sctp_association *asoc,
                                       const struct sctp_transport *transport,
                                       __u32 probe_size)
 {
-       struct sctp_sender_hb_info hbinfo;
+       struct sctp_sender_hb_info hbinfo = {};
        struct sctp_chunk *retval;
 
        retval = sctp_make_control(asoc, SCTP_CID_HEARTBEAT, 0,
index 5f23804..397a624 100644 (file)
@@ -335,10 +335,13 @@ void sctp_transport_pl_recv(struct sctp_transport *t)
                        t->pathmtu = t->pl.pmtu + sctp_transport_pl_hlen(t);
                        sctp_assoc_sync_pmtu(t->asoc);
                }
-       } else if (t->pl.state == SCTP_PL_COMPLETE && ++t->pl.raise_count == 30) {
-               /* Raise probe_size again after 30 * interval in Search Complete */
-               t->pl.state = SCTP_PL_SEARCH; /* Search Complete -> Search */
-               t->pl.probe_size += SCTP_PL_MIN_STEP;
+       } else if (t->pl.state == SCTP_PL_COMPLETE) {
+               t->pl.raise_count++;
+               if (t->pl.raise_count == 30) {
+                       /* Raise probe_size again after 30 * interval in Search Complete */
+                       t->pl.state = SCTP_PL_SEARCH; /* Search Complete -> Search */
+                       t->pl.probe_size += SCTP_PL_MIN_STEP;
+               }
        }
 }
 
index bd9233d..0b2dad3 100644 (file)
 #include <linux/sockios.h>
 #include <net/busy_poll.h>
 #include <linux/errqueue.h>
+#include <linux/ptp_clock_kernel.h>
 
 #ifdef CONFIG_NET_RX_BUSY_POLL
 unsigned int sysctl_net_busy_read __read_mostly;
@@ -873,12 +874,18 @@ void __sock_recv_timestamp(struct msghdr *msg, struct sock *sk,
                empty = 0;
        if (shhwtstamps &&
            (sk->sk_tsflags & SOF_TIMESTAMPING_RAW_HARDWARE) &&
-           !skb_is_swtx_tstamp(skb, false_tstamp) &&
-           ktime_to_timespec64_cond(shhwtstamps->hwtstamp, tss.ts + 2)) {
-               empty = 0;
-               if ((sk->sk_tsflags & SOF_TIMESTAMPING_OPT_PKTINFO) &&
-                   !skb_is_err_queue(skb))
-                       put_ts_pktinfo(msg, skb);
+           !skb_is_swtx_tstamp(skb, false_tstamp)) {
+               if (sk->sk_tsflags & SOF_TIMESTAMPING_BIND_PHC)
+                       ptp_convert_timestamp(shhwtstamps, sk->sk_bind_phc);
+
+               if (ktime_to_timespec64_cond(shhwtstamps->hwtstamp,
+                                            tss.ts + 2)) {
+                       empty = 0;
+
+                       if ((sk->sk_tsflags & SOF_TIMESTAMPING_OPT_PKTINFO) &&
+                           !skb_is_err_queue(skb))
+                               put_ts_pktinfo(msg, skb);
+               }
        }
        if (!empty) {
                if (sock_flag(sk, SOCK_TSTAMP_NEW))
index 9ff64f9..7e7d7f4 100644 (file)
@@ -295,10 +295,8 @@ again:
 
                goto again;
        }
-       err = netlink_unicast(net->diag_nlsk, rep, NETLINK_CB(in_skb).portid,
-                             MSG_DONTWAIT);
-       if (err > 0)
-               err = 0;
+       err = nlmsg_unicast(net->diag_nlsk, rep, NETLINK_CB(in_skb).portid);
+
 out:
        if (sk)
                sock_put(sk);
index 520434e..036998d 100644 (file)
@@ -331,6 +331,7 @@ $(obj)/%.o: $(src)/%.c
                -Wno-gnu-variable-sized-type-not-at-end \
                -Wno-address-of-packed-member -Wno-tautological-compare \
                -Wno-unknown-warning-option $(CLANG_ARCH_ARGS) \
+               -fno-asynchronous-unwind-tables \
                -I$(srctree)/samples/bpf/ -include asm_goto_workaround.h \
                -O2 -emit-llvm -Xclang -disable-llvm-passes -c $< -o - | \
                $(OPT) -O2 -mtriple=bpf-pc-linux | $(LLVM_DIS) | \
index 53e300f..33d0bde 100644 (file)
@@ -96,6 +96,7 @@ static int opt_xsk_frame_size = XSK_UMEM__DEFAULT_FRAME_SIZE;
 static int opt_timeout = 1000;
 static bool opt_need_wakeup = true;
 static u32 opt_num_xsks = 1;
+static u32 prog_id;
 static bool opt_busy_poll;
 static bool opt_reduced_cap;
 
@@ -461,6 +462,23 @@ static void *poller(void *arg)
        return NULL;
 }
 
+static void remove_xdp_program(void)
+{
+       u32 curr_prog_id = 0;
+
+       if (bpf_get_link_xdp_id(opt_ifindex, &curr_prog_id, opt_xdp_flags)) {
+               printf("bpf_get_link_xdp_id failed\n");
+               exit(EXIT_FAILURE);
+       }
+
+       if (prog_id == curr_prog_id)
+               bpf_set_link_xdp_fd(opt_ifindex, -1, opt_xdp_flags);
+       else if (!curr_prog_id)
+               printf("couldn't find a prog id on a given interface\n");
+       else
+               printf("program on interface changed, not removing\n");
+}
+
 static void int_exit(int sig)
 {
        benchmark_done = true;
@@ -471,6 +489,9 @@ static void __exit_with_error(int error, const char *file, const char *func,
 {
        fprintf(stderr, "%s:%s:%i: errno: %d/\"%s\"\n", file, func,
                line, error, strerror(error));
+
+       if (opt_num_xsks > 1)
+               remove_xdp_program();
        exit(EXIT_FAILURE);
 }
 
@@ -490,6 +511,9 @@ static void xdpsock_cleanup(void)
                if (write(sock, &cmd, sizeof(int)) < 0)
                        exit_with_error(errno);
        }
+
+       if (opt_num_xsks > 1)
+               remove_xdp_program();
 }
 
 static void swap_mac_addresses(void *data)
@@ -857,6 +881,10 @@ static struct xsk_socket_info *xsk_configure_socket(struct xsk_umem_info *umem,
        if (ret)
                exit_with_error(-ret);
 
+       ret = bpf_get_link_xdp_id(opt_ifindex, &prog_id, opt_xdp_flags);
+       if (ret)
+               exit_with_error(-ret);
+
        xsk->app_stats.rx_empty_polls = 0;
        xsk->app_stats.fill_fail_polls = 0;
        xsk->app_stats.copy_tx_sendtos = 0;
index 10b2f23..02197cb 100644 (file)
@@ -386,7 +386,7 @@ ifeq ($(CONFIG_LTO_CLANG) $(CONFIG_MODVERSIONS),y y)
       cmd_update_lto_symversions =                                     \
        rm -f $@.symversions                                            \
        $(foreach n, $(filter-out FORCE,$^),                            \
-               $(if $(wildcard $(n).symversions),                      \
+               $(if $(shell test -s $(n).symversions && echo y),       \
                        ; cat $(n).symversions >> $@.symversions))
 else
       cmd_update_lto_symversions = echo >/dev/null
index 151f049..6b54e46 100755 (executable)
@@ -131,11 +131,14 @@ res="${res}${CONFIG_LOCALVERSION}${LOCALVERSION}"
 if test "$CONFIG_LOCALVERSION_AUTO" = "y"; then
        # full scm version string
        res="$res$(scm_version)"
-elif [ -z "${LOCALVERSION}" ]; then
-       # append a plus sign if the repository is not in a clean
-       # annotated or signed tagged state (as git describe only
-       # looks at signed or annotated tags - git tag -a/-s) and
-       # LOCALVERSION= is not specified
+elif [ "${LOCALVERSION+set}" != "set" ]; then
+       # If the variable LOCALVERSION is not set, append a plus
+       # sign if the repository is not in a clean annotated or
+       # signed tagged state (as git describe only looks at signed
+       # or annotated tags - git tag -a/-s).
+       #
+       # If the variable LOCALVERSION is set (including being set
+       # to an empty string), we don't want to append a plus sign.
        scm=$(scm_version --short)
        res="$res${scm:++}"
 fi
index 3e784cf..ebd06ae 100755 (executable)
@@ -44,7 +44,7 @@ def read_spdxdata(repo):
                 continue
 
             exception = None
-            for l in open(el.path).readlines():
+            for l in open(el.path, encoding="utf-8").readlines():
                 if l.startswith('Valid-License-Identifier:'):
                     lid = l.split(':')[1].strip().upper()
                     if lid in spdx.licenses:
index 2b758a1..5b8a274 100644 (file)
@@ -341,6 +341,7 @@ static int set_mtkaif_rx(struct mtk_base_afe *afe)
        case MT8183_MTKAIF_PROTOCOL_1:
                regmap_write(afe->regmap, AFE_AUD_PAD_TOP, 0x31);
                regmap_write(afe->regmap, AFE_ADDA_MTKAIF_CFG0, 0x0);
+               break;
        default:
                break;
        }
index f83a70e..ce2ee8f 100644 (file)
@@ -20,5 +20,6 @@
 #define __ARCH_WANT_SET_GET_RLIMIT
 #define __ARCH_WANT_TIME32_SYSCALLS
 #define __ARCH_WANT_SYS_CLONE3
+#define __ARCH_WANT_MEMFD_SECRET
 
 #include <asm-generic/unistd.h>
index 39bb322..b11cfc8 100644 (file)
@@ -97,7 +97,7 @@ clean: bpftool_clean runqslower_clean resolve_btfids_clean
        $(Q)$(RM) -- $(OUTPUT)FEATURE-DUMP.bpf
        $(Q)$(RM) -r -- $(OUTPUT)feature
 
-install: $(PROGS) bpftool_install runqslower_install
+install: $(PROGS) bpftool_install
        $(call QUIET_INSTALL, bpf_jit_disasm)
        $(Q)$(INSTALL) -m 0755 -d $(DESTDIR)$(prefix)/bin
        $(Q)$(INSTALL) $(OUTPUT)bpf_jit_disasm $(DESTDIR)$(prefix)/bin/bpf_jit_disasm
@@ -118,9 +118,6 @@ bpftool_clean:
 runqslower:
        $(call descend,runqslower)
 
-runqslower_install:
-       $(call descend,runqslower,install)
-
 runqslower_clean:
        $(call descend,runqslower,clean)
 
@@ -131,5 +128,5 @@ resolve_btfids_clean:
        $(call descend,resolve_btfids,clean)
 
 .PHONY: all install clean bpftool bpftool_install bpftool_clean \
-       runqslower runqslower_install runqslower_clean \
+       runqslower runqslower_clean \
        resolve_btfids resolve_btfids_clean
index e7e7eee..24734f2 100644 (file)
@@ -43,11 +43,13 @@ static int fprintf_json(void *out, const char *fmt, ...)
 {
        va_list ap;
        char *s;
+       int err;
 
        va_start(ap, fmt);
-       if (vasprintf(&s, fmt, ap) < 0)
-               return -1;
+       err = vasprintf(&s, fmt, ap);
        va_end(ap);
+       if (err < 0)
+               return -1;
 
        if (!oper_count) {
                int i;
index 645530c..ab9353f 100644 (file)
@@ -74,7 +74,7 @@ int handle__sched_switch(u64 *ctx)
        u32 pid;
 
        /* ivcsw: treat like an enqueue event and store timestamp */
-       if (prev->state == TASK_RUNNING)
+       if (prev->__state == TASK_RUNNING)
                trace_enqueue(prev);
 
        pid = next->pid;
index 1555a0c..13b86bd 100644 (file)
@@ -4,12 +4,6 @@
 
 /* CONFIG_CC_VERSION_TEXT (Do not delete this comment. See help in Kconfig) */
 
-#ifdef CONFIG_CPU_BIG_ENDIAN
-#define __BIG_ENDIAN 4321
-#else
-#define __LITTLE_ENDIAN 1234
-#endif
-
 #define __ARG_PLACEHOLDER_1 0,
 #define __take_second_arg(__ignored, val, ...) val
 
index f211961..a9d6fcd 100644 (file)
@@ -873,8 +873,13 @@ __SYSCALL(__NR_landlock_add_rule, sys_landlock_add_rule)
 #define __NR_landlock_restrict_self 446
 __SYSCALL(__NR_landlock_restrict_self, sys_landlock_restrict_self)
 
+#ifdef __ARCH_WANT_MEMFD_SECRET
+#define __NR_memfd_secret 447
+__SYSCALL(__NR_memfd_secret, sys_memfd_secret)
+#endif
+
 #undef __NR_syscalls
-#define __NR_syscalls 447
+#define __NR_syscalls 448
 
 /*
  * 32 bit systems traditionally used different
index 1e04ce7..6f5e275 100644 (file)
@@ -10136,7 +10136,7 @@ int bpf_link__unpin(struct bpf_link *link)
 
        err = unlink(link->pin_path);
        if (err != 0)
-               return libbpf_err_errno(err);
+               return -errno;
 
        pr_debug("link fd=%d: unpinned from %s\n", link->fd, link->pin_path);
        zfree(&link->pin_path);
@@ -11197,7 +11197,7 @@ int perf_buffer__poll(struct perf_buffer *pb, int timeout_ms)
 
        cnt = epoll_wait(pb->epoll_fd, pb->events, pb->cpu_cnt, timeout_ms);
        if (cnt < 0)
-               return libbpf_err_errno(cnt);
+               return -errno;
 
        for (i = 0; i < cnt; i++) {
                struct perf_cpu_buf *cpu_buf = pb->events[i].data.ptr;
index af973e4..f6b5779 100644 (file)
 444    common  landlock_create_ruleset sys_landlock_create_ruleset
 445    common  landlock_add_rule       sys_landlock_add_rule
 446    common  landlock_restrict_self  sys_landlock_restrict_self
+447    common  memfd_secret            sys_memfd_secret
 
 #
 # Due to a historical design error, certain syscalls are numbered differently
index 5d6f583..c88c61e 100644 (file)
@@ -361,9 +361,10 @@ static struct dso *findnew_dso(int pid, int tid, const char *filename,
                dso = machine__findnew_dso_id(machine, filename, id);
        }
 
-       if (dso)
+       if (dso) {
+               nsinfo__put(dso->nsinfo);
                dso->nsinfo = nsi;
-       else
+       else
                nsinfo__put(nsi);
 
        thread__put(thread);
@@ -992,8 +993,10 @@ int cmd_inject(int argc, const char **argv)
 
        data.path = inject.input_name;
        inject.session = perf_session__new(&data, inject.output.is_pipe, &inject.tool);
-       if (IS_ERR(inject.session))
-               return PTR_ERR(inject.session);
+       if (IS_ERR(inject.session)) {
+               ret = PTR_ERR(inject.session);
+               goto out_close_output;
+       }
 
        if (zstd_init(&(inject.session->zstd_data), 0) < 0)
                pr_warning("Decompression initialization failed.\n");
@@ -1035,6 +1038,8 @@ int cmd_inject(int argc, const char **argv)
 out_delete:
        zstd_fini(&(inject.session->zstd_data));
        perf_session__delete(inject.session);
+out_close_output:
+       perf_data__close(&inject.output);
        free(inject.itrace_synth_opts.vm_tm_corr_args);
        return ret;
 }
index 6386af6..dc0364f 100644 (file)
@@ -1175,6 +1175,8 @@ int cmd_report(int argc, const char **argv)
                .annotation_opts         = annotation__default_options,
                .skip_empty              = true,
        };
+       char *sort_order_help = sort_help("sort by key(s):");
+       char *field_order_help = sort_help("output field(s): overhead period sample ");
        const struct option options[] = {
        OPT_STRING('i', "input", &input_name, "file",
                    "input file name"),
@@ -1209,9 +1211,9 @@ int cmd_report(int argc, const char **argv)
        OPT_BOOLEAN(0, "header-only", &report.header_only,
                    "Show only data header."),
        OPT_STRING('s', "sort", &sort_order, "key[,key2...]",
-                  sort_help("sort by key(s):")),
+                  sort_order_help),
        OPT_STRING('F', "fields", &field_order, "key[,keys...]",
-                  sort_help("output field(s): overhead period sample ")),
+                  field_order_help),
        OPT_BOOLEAN(0, "show-cpu-utilization", &symbol_conf.show_cpu_utilization,
                    "Show sample percentage for different cpu modes"),
        OPT_BOOLEAN_FLAG(0, "showcpuutilization", &symbol_conf.show_cpu_utilization,
@@ -1344,11 +1346,11 @@ int cmd_report(int argc, const char **argv)
        char sort_tmp[128];
 
        if (ret < 0)
-               return ret;
+               goto exit;
 
        ret = perf_config(report__config, &report);
        if (ret)
-               return ret;
+               goto exit;
 
        argc = parse_options(argc, argv, options, report_usage, 0);
        if (argc) {
@@ -1362,8 +1364,10 @@ int cmd_report(int argc, const char **argv)
                report.symbol_filter_str = argv[0];
        }
 
-       if (annotate_check_args(&report.annotation_opts) < 0)
-               return -EINVAL;
+       if (annotate_check_args(&report.annotation_opts) < 0) {
+               ret = -EINVAL;
+               goto exit;
+       }
 
        if (report.mmaps_mode)
                report.tasks_mode = true;
@@ -1377,12 +1381,14 @@ int cmd_report(int argc, const char **argv)
        if (symbol_conf.vmlinux_name &&
            access(symbol_conf.vmlinux_name, R_OK)) {
                pr_err("Invalid file: %s\n", symbol_conf.vmlinux_name);
-               return -EINVAL;
+               ret = -EINVAL;
+               goto exit;
        }
        if (symbol_conf.kallsyms_name &&
            access(symbol_conf.kallsyms_name, R_OK)) {
                pr_err("Invalid file: %s\n", symbol_conf.kallsyms_name);
-               return -EINVAL;
+               ret = -EINVAL;
+               goto exit;
        }
 
        if (report.inverted_callchain)
@@ -1406,12 +1412,14 @@ int cmd_report(int argc, const char **argv)
 
 repeat:
        session = perf_session__new(&data, false, &report.tool);
-       if (IS_ERR(session))
-               return PTR_ERR(session);
+       if (IS_ERR(session)) {
+               ret = PTR_ERR(session);
+               goto exit;
+       }
 
        ret = evswitch__init(&report.evswitch, session->evlist, stderr);
        if (ret)
-               return ret;
+               goto exit;
 
        if (zstd_init(&(session->zstd_data), 0) < 0)
                pr_warning("Decompression initialization failed. Reported data may be incomplete.\n");
@@ -1646,5 +1654,8 @@ error:
 
        zstd_fini(&(session->zstd_data));
        perf_session__delete(session);
+exit:
+       free(sort_order_help);
+       free(field_order_help);
        return ret;
 }
index 954ce2f..1ff10d4 100644 (file)
@@ -670,7 +670,7 @@ static void create_tasks(struct perf_sched *sched)
        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);
@@ -3335,6 +3335,16 @@ static void setup_sorting(struct perf_sched *sched, const struct option *options
        sort_dimension__add("pid", &sched->cmp_pid);
 }
 
+static bool schedstat_events_exposed(void)
+{
+       /*
+        * Select "sched:sched_stat_wait" event to check
+        * whether schedstat tracepoints are exposed.
+        */
+       return IS_ERR(trace_event__tp_format("sched", "sched_stat_wait")) ?
+               false : true;
+}
+
 static int __cmd_record(int argc, const char **argv)
 {
        unsigned int rec_argc, i, j;
@@ -3346,21 +3356,33 @@ static int __cmd_record(int argc, const char **argv)
                "-m", "1024",
                "-c", "1",
                "-e", "sched:sched_switch",
-               "-e", "sched:sched_stat_wait",
-               "-e", "sched:sched_stat_sleep",
-               "-e", "sched:sched_stat_iowait",
                "-e", "sched:sched_stat_runtime",
                "-e", "sched:sched_process_fork",
                "-e", "sched:sched_wakeup_new",
                "-e", "sched:sched_migrate_task",
        };
+
+       /*
+        * The tracepoints trace_sched_stat_{wait, sleep, iowait}
+        * are not exposed to user if CONFIG_SCHEDSTATS is not set,
+        * to prevent "perf sched record" execution failure, determine
+        * whether to record schedstat events according to actual situation.
+        */
+       const char * const schedstat_args[] = {
+               "-e", "sched:sched_stat_wait",
+               "-e", "sched:sched_stat_sleep",
+               "-e", "sched:sched_stat_iowait",
+       };
+       unsigned int schedstat_argc = schedstat_events_exposed() ?
+               ARRAY_SIZE(schedstat_args) : 0;
+
        struct tep_event *waking_event;
 
        /*
         * +2 for either "-e", "sched:sched_wakeup" or
         * "-e", "sched:sched_waking"
         */
-       rec_argc = ARRAY_SIZE(record_args) + 2 + argc - 1;
+       rec_argc = ARRAY_SIZE(record_args) + 2 + schedstat_argc + argc - 1;
        rec_argv = calloc(rec_argc + 1, sizeof(char *));
 
        if (rec_argv == NULL)
@@ -3376,6 +3398,9 @@ static int __cmd_record(int argc, const char **argv)
        else
                rec_argv[i++] = strdup("sched:sched_wakeup");
 
+       for (j = 0; j < schedstat_argc; j++)
+               rec_argv[i++] = strdup(schedstat_args[j]);
+
        for (j = 1; j < (unsigned int)argc; j++, i++)
                rec_argv[i] = argv[j];
 
index 8c03a98..064da7f 100644 (file)
@@ -2601,6 +2601,12 @@ static void perf_script__exit_per_event_dump_stats(struct perf_script *script)
        }
 }
 
+static void perf_script__exit(struct perf_script *script)
+{
+       perf_thread_map__put(script->threads);
+       perf_cpu_map__put(script->cpus);
+}
+
 static int __cmd_script(struct perf_script *script)
 {
        int ret;
@@ -4143,8 +4149,10 @@ out_delete:
                zfree(&script.ptime_range);
        }
 
+       zstd_fini(&(session->zstd_data));
        evlist__free_stats(session->evlist);
        perf_session__delete(session);
+       perf_script__exit(&script);
 
        if (script_started)
                cleanup_scripting();
index d25cb80..6343759 100644 (file)
@@ -2445,9 +2445,6 @@ int cmd_stat(int argc, const char **argv)
 
        evlist__check_cpu_maps(evsel_list);
 
-       if (perf_pmu__has_hybrid())
-               stat_config.no_merge = true;
-
        /*
         * Initialize thread_map with comm names,
         * so we could print it out on output.
index 7ec18ff..9c265fa 100644 (file)
@@ -2266,6 +2266,14 @@ static void *syscall__augmented_args(struct syscall *sc, struct perf_sample *sam
        return augmented_args;
 }
 
+static void syscall__exit(struct syscall *sc)
+{
+       if (!sc)
+               return;
+
+       free(sc->arg_fmt);
+}
+
 static int trace__sys_enter(struct trace *trace, struct evsel *evsel,
                            union perf_event *event __maybe_unused,
                            struct perf_sample *sample)
@@ -3095,6 +3103,21 @@ static struct evsel *evsel__new_pgfault(u64 config)
        return evsel;
 }
 
+static void evlist__free_syscall_tp_fields(struct evlist *evlist)
+{
+       struct evsel *evsel;
+
+       evlist__for_each_entry(evlist, evsel) {
+               struct evsel_trace *et = evsel->priv;
+
+               if (!et || !evsel->tp_format || strcmp(evsel->tp_format->system, "syscalls"))
+                       continue;
+
+               free(et->fmt);
+               free(et);
+       }
+}
+
 static void trace__handle_event(struct trace *trace, union perf_event *event, struct perf_sample *sample)
 {
        const u32 type = event->header.type;
@@ -4130,7 +4153,7 @@ out_disable:
 
 out_delete_evlist:
        trace__symbols__exit(trace);
-
+       evlist__free_syscall_tp_fields(evlist);
        evlist__delete(evlist);
        cgroup__put(trace->cgroup);
        trace->evlist = NULL;
@@ -4636,6 +4659,9 @@ do_concat:
                err = parse_events_option(&o, lists[0], 0);
        }
 out:
+       free(strace_groups_dir);
+       free(lists[0]);
+       free(lists[1]);
        if (sep)
                *sep = ',';
 
@@ -4701,6 +4727,21 @@ out:
        return err;
 }
 
+static void trace__exit(struct trace *trace)
+{
+       int i;
+
+       strlist__delete(trace->ev_qualifier);
+       free(trace->ev_qualifier_ids.entries);
+       if (trace->syscalls.table) {
+               for (i = 0; i <= trace->sctbl->syscalls.max_id; i++)
+                       syscall__exit(&trace->syscalls.table[i]);
+               free(trace->syscalls.table);
+       }
+       syscalltbl__delete(trace->sctbl);
+       zfree(&trace->perfconfig_events);
+}
+
 int cmd_trace(int argc, const char **argv)
 {
        const char *trace_usage[] = {
@@ -5135,6 +5176,6 @@ out_close:
        if (output_name != NULL)
                fclose(trace.output);
 out:
-       zfree(&trace.perfconfig_events);
+       trace__exit(&trace);
        return err;
 }
index 33bda9c..dbf5f52 100644 (file)
@@ -1,6 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0
 #include <errno.h>
 #include <stdio.h>
+#include <stdlib.h>
 #include <sys/epoll.h>
 #include <sys/types.h>
 #include <sys/stat.h>
@@ -276,6 +277,7 @@ static int __test__bpf(int idx)
        }
 
 out:
+       free(obj_buf);
        bpf__clear();
        return ret;
 }
index 6562181..44a5052 100644 (file)
@@ -88,6 +88,7 @@ int test__event_update(struct test *test __maybe_unused, int subtest __maybe_unu
        struct evsel *evsel;
        struct event_name tmp;
        struct evlist *evlist = evlist__new_default();
+       char *unit = strdup("KRAVA");
 
        TEST_ASSERT_VAL("failed to get evlist", evlist);
 
@@ -98,7 +99,7 @@ int test__event_update(struct test *test __maybe_unused, int subtest __maybe_unu
 
        perf_evlist__id_add(&evlist->core, &evsel->core, 0, 0, 123);
 
-       evsel->unit = strdup("KRAVA");
+       evsel->unit = unit;
 
        TEST_ASSERT_VAL("failed to synthesize attr update unit",
                        !perf_event__synthesize_event_update_unit(NULL, evsel, process_event_unit));
@@ -118,6 +119,7 @@ int test__event_update(struct test *test __maybe_unused, int subtest __maybe_unu
        TEST_ASSERT_VAL("failed to synthesize attr update cpus",
                        !perf_event__synthesize_event_update_cpus(&tmp.tool, evsel, process_event_cpus));
 
-       perf_cpu_map__put(evsel->core.own_cpus);
+       free(unit);
+       evlist__delete(evlist);
        return 0;
 }
index 5ebf563..4e09f0a 100644 (file)
@@ -5,6 +5,7 @@
 #include "tests.h"
 #include "debug.h"
 #include "pmu.h"
+#include "pmu-hybrid.h"
 #include <errno.h>
 #include <linux/kernel.h>
 
@@ -102,7 +103,7 @@ int test__perf_evsel__roundtrip_name_test(struct test *test __maybe_unused, int
 {
        int err = 0, ret = 0;
 
-       if (perf_pmu__has_hybrid())
+       if (perf_pmu__has_hybrid() && perf_pmu__hybrid_mounted("cpu_atom"))
                return perf_evsel__name_array_test(evsel__hw_names, 2);
 
        err = perf_evsel__name_array_test(evsel__hw_names, 1);
index edcbc70..1ac7291 100644 (file)
@@ -116,5 +116,7 @@ int test__maps__merge_in(struct test *t __maybe_unused, int subtest __maybe_unus
 
        ret = check_maps(merged3, ARRAY_SIZE(merged3), &maps);
        TEST_ASSERT_VAL("merge check failed", !ret);
+
+       maps__exit(&maps);
        return TEST_OK;
 }
index 56a7b6a..8d48667 100644 (file)
@@ -6,6 +6,7 @@
 #include "tests.h"
 #include "debug.h"
 #include "pmu.h"
+#include "pmu-hybrid.h"
 #include <dirent.h>
 #include <errno.h>
 #include <sys/types.h>
@@ -1596,6 +1597,13 @@ static int test__hybrid_raw1(struct evlist *evlist)
 {
        struct evsel *evsel = evlist__first(evlist);
 
+       if (!perf_pmu__hybrid_mounted("cpu_atom")) {
+               TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->core.nr_entries);
+               TEST_ASSERT_VAL("wrong type", PERF_TYPE_RAW == evsel->core.attr.type);
+               TEST_ASSERT_VAL("wrong config", 0x1a == evsel->core.attr.config);
+               return 0;
+       }
+
        TEST_ASSERT_VAL("wrong number of entries", 2 == evlist->core.nr_entries);
        TEST_ASSERT_VAL("wrong type", PERF_TYPE_RAW == evsel->core.attr.type);
        TEST_ASSERT_VAL("wrong config", 0x1a == evsel->core.attr.config);
@@ -1620,13 +1628,9 @@ static int test__hybrid_cache_event(struct evlist *evlist)
 {
        struct evsel *evsel = evlist__first(evlist);
 
-       TEST_ASSERT_VAL("wrong number of entries", 2 == evlist->core.nr_entries);
+       TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->core.nr_entries);
        TEST_ASSERT_VAL("wrong type", PERF_TYPE_HW_CACHE == evsel->core.attr.type);
        TEST_ASSERT_VAL("wrong config", 0x2 == (evsel->core.attr.config & 0xffffffff));
-
-       evsel = evsel__next(evsel);
-       TEST_ASSERT_VAL("wrong type", PERF_TYPE_HW_CACHE == evsel->core.attr.type);
-       TEST_ASSERT_VAL("wrong config", 0x10002 == (evsel->core.attr.config & 0xffffffff));
        return 0;
 }
 
@@ -2028,7 +2032,7 @@ static struct evlist_test test__hybrid_events[] = {
                .id    = 7,
        },
        {
-               .name  = "cpu_core/LLC-loads/,cpu_atom/LLC-load-misses/",
+               .name  = "cpu_core/LLC-loads/",
                .check = test__hybrid_cache_event,
                .id    = 8,
        },
index 85d75b9..7c56bc1 100644 (file)
@@ -21,6 +21,7 @@
 #include "mmap.h"
 #include "tests.h"
 #include "pmu.h"
+#include "pmu-hybrid.h"
 
 #define CHECK__(x) {                           \
        while ((x) < 0) {                       \
@@ -93,7 +94,7 @@ int test__perf_time_to_tsc(struct test *test __maybe_unused, int subtest __maybe
         * For hybrid "cycles:u", it creates two events.
         * Init the second evsel here.
         */
-       if (perf_pmu__has_hybrid()) {
+       if (perf_pmu__has_hybrid() && perf_pmu__hybrid_mounted("cpu_atom")) {
                evsel = evsel__next(evsel);
                evsel->core.attr.comm = 1;
                evsel->core.attr.disabled = 1;
index ec4e3b2..b5efe67 100644 (file)
@@ -61,6 +61,7 @@ static int session_write_header(char *path)
        TEST_ASSERT_VAL("failed to write header",
                        !perf_session__write_header(session, session->evlist, data.file.fd, true));
 
+       evlist__delete(session->evlist);
        perf_session__delete(session);
 
        return 0;
index 32ad92d..22f8326 100644 (file)
@@ -2683,6 +2683,172 @@ static u64 *cs_etm__create_meta_blk(u64 *buff_in, int *buff_in_offset,
        return metadata;
 }
 
+/**
+ * Puts a fragment of an auxtrace buffer into the auxtrace queues based
+ * on the bounds of aux_event, if it matches with the buffer that's at
+ * file_offset.
+ *
+ * Normally, whole auxtrace buffers would be added to the queue. But we
+ * want to reset the decoder for every PERF_RECORD_AUX event, and the decoder
+ * is reset across each buffer, so splitting the buffers up in advance has
+ * the same effect.
+ */
+static int cs_etm__queue_aux_fragment(struct perf_session *session, off_t file_offset, size_t sz,
+                                     struct perf_record_aux *aux_event, struct perf_sample *sample)
+{
+       int err;
+       char buf[PERF_SAMPLE_MAX_SIZE];
+       union perf_event *auxtrace_event_union;
+       struct perf_record_auxtrace *auxtrace_event;
+       union perf_event auxtrace_fragment;
+       __u64 aux_offset, aux_size;
+
+       struct cs_etm_auxtrace *etm = container_of(session->auxtrace,
+                                                  struct cs_etm_auxtrace,
+                                                  auxtrace);
+
+       /*
+        * There should be a PERF_RECORD_AUXTRACE event at the file_offset that we got
+        * from looping through the auxtrace index.
+        */
+       err = perf_session__peek_event(session, file_offset, buf,
+                                      PERF_SAMPLE_MAX_SIZE, &auxtrace_event_union, NULL);
+       if (err)
+               return err;
+       auxtrace_event = &auxtrace_event_union->auxtrace;
+       if (auxtrace_event->header.type != PERF_RECORD_AUXTRACE)
+               return -EINVAL;
+
+       if (auxtrace_event->header.size < sizeof(struct perf_record_auxtrace) ||
+               auxtrace_event->header.size != sz) {
+               return -EINVAL;
+       }
+
+       /*
+        * In per-thread mode, CPU is set to -1, but TID will be set instead. See
+        * auxtrace_mmap_params__set_idx(). Return 'not found' if neither CPU nor TID match.
+        */
+       if ((auxtrace_event->cpu == (__u32) -1 && auxtrace_event->tid != sample->tid) ||
+                       auxtrace_event->cpu != sample->cpu)
+               return 1;
+
+       if (aux_event->flags & PERF_AUX_FLAG_OVERWRITE) {
+               /*
+                * Clamp size in snapshot mode. The buffer size is clamped in
+                * __auxtrace_mmap__read() for snapshots, so the aux record size doesn't reflect
+                * the buffer size.
+                */
+               aux_size = min(aux_event->aux_size, auxtrace_event->size);
+
+               /*
+                * In this mode, the head also points to the end of the buffer so aux_offset
+                * needs to have the size subtracted so it points to the beginning as in normal mode
+                */
+               aux_offset = aux_event->aux_offset - aux_size;
+       } else {
+               aux_size = aux_event->aux_size;
+               aux_offset = aux_event->aux_offset;
+       }
+
+       if (aux_offset >= auxtrace_event->offset &&
+           aux_offset + aux_size <= auxtrace_event->offset + auxtrace_event->size) {
+               /*
+                * If this AUX event was inside this buffer somewhere, create a new auxtrace event
+                * based on the sizes of the aux event, and queue that fragment.
+                */
+               auxtrace_fragment.auxtrace = *auxtrace_event;
+               auxtrace_fragment.auxtrace.size = aux_size;
+               auxtrace_fragment.auxtrace.offset = aux_offset;
+               file_offset += aux_offset - auxtrace_event->offset + auxtrace_event->header.size;
+
+               pr_debug3("CS ETM: Queue buffer size: %#"PRI_lx64" offset: %#"PRI_lx64
+                         " tid: %d cpu: %d\n", aux_size, aux_offset, sample->tid, sample->cpu);
+               return auxtrace_queues__add_event(&etm->queues, session, &auxtrace_fragment,
+                                                 file_offset, NULL);
+       }
+
+       /* Wasn't inside this buffer, but there were no parse errors. 1 == 'not found' */
+       return 1;
+}
+
+static int cs_etm__queue_aux_records_cb(struct perf_session *session, union perf_event *event,
+                                       u64 offset __maybe_unused, void *data __maybe_unused)
+{
+       struct perf_sample sample;
+       int ret;
+       struct auxtrace_index_entry *ent;
+       struct auxtrace_index *auxtrace_index;
+       struct evsel *evsel;
+       size_t i;
+
+       /* Don't care about any other events, we're only queuing buffers for AUX events */
+       if (event->header.type != PERF_RECORD_AUX)
+               return 0;
+
+       if (event->header.size < sizeof(struct perf_record_aux))
+               return -EINVAL;
+
+       /* Truncated Aux records can have 0 size and shouldn't result in anything being queued. */
+       if (!event->aux.aux_size)
+               return 0;
+
+       /*
+        * Parse the sample, we need the sample_id_all data that comes after the event so that the
+        * CPU or PID can be matched to an AUXTRACE buffer's CPU or PID.
+        */
+       evsel = evlist__event2evsel(session->evlist, event);
+       if (!evsel)
+               return -EINVAL;
+       ret = evsel__parse_sample(evsel, event, &sample);
+       if (ret)
+               return ret;
+
+       /*
+        * Loop through the auxtrace index to find the buffer that matches up with this aux event.
+        */
+       list_for_each_entry(auxtrace_index, &session->auxtrace_index, list) {
+               for (i = 0; i < auxtrace_index->nr; i++) {
+                       ent = &auxtrace_index->entries[i];
+                       ret = cs_etm__queue_aux_fragment(session, ent->file_offset,
+                                                        ent->sz, &event->aux, &sample);
+                       /*
+                        * Stop search on error or successful values. Continue search on
+                        * 1 ('not found')
+                        */
+                       if (ret != 1)
+                               return ret;
+               }
+       }
+
+       /*
+        * Couldn't find the buffer corresponding to this aux record, something went wrong. Warn but
+        * don't exit with an error because it will still be possible to decode other aux records.
+        */
+       pr_err("CS ETM: Couldn't find auxtrace buffer for aux_offset: %#"PRI_lx64
+              " tid: %d cpu: %d\n", event->aux.aux_offset, sample.tid, sample.cpu);
+       return 0;
+}
+
+static int cs_etm__queue_aux_records(struct perf_session *session)
+{
+       struct auxtrace_index *index = list_first_entry_or_null(&session->auxtrace_index,
+                                                               struct auxtrace_index, list);
+       if (index && index->nr > 0)
+               return perf_session__peek_events(session, session->header.data_offset,
+                                                session->header.data_size,
+                                                cs_etm__queue_aux_records_cb, NULL);
+
+       /*
+        * We would get here if there are no entries in the index (either no auxtrace
+        * buffers or no index at all). Fail silently as there is the possibility of
+        * queueing them in cs_etm__process_auxtrace_event() if etm->data_queued is still
+        * false.
+        *
+        * In that scenario, buffers will not be split by AUX records.
+        */
+       return 0;
+}
+
 int cs_etm__process_auxtrace_info(union perf_event *event,
                                  struct perf_session *session)
 {
@@ -2883,7 +3049,7 @@ int cs_etm__process_auxtrace_info(union perf_event *event,
        if (err)
                goto err_delete_thread;
 
-       err = auxtrace_queues__process_index(&etm->queues, session);
+       err = cs_etm__queue_aux_records(session);
        if (err)
                goto err_delete_thread;
 
index a9c102e..f5d260b 100644 (file)
@@ -20,7 +20,7 @@
 
 static void close_dir(struct perf_data_file *files, int nr)
 {
-       while (--nr >= 1) {
+       while (--nr >= 0) {
                close(files[nr].fd);
                zfree(&files[nr].path);
        }
index d786cf6..ee15db2 100644 (file)
@@ -1154,8 +1154,10 @@ struct map *dso__new_map(const char *name)
        struct map *map = NULL;
        struct dso *dso = dso__new(name);
 
-       if (dso)
+       if (dso) {
                map = map__new2(0, dso);
+               dso__put(dso);
+       }
 
        return map;
 }
index 7d2ba84..609ca16 100644 (file)
@@ -113,14 +113,14 @@ static Dwarf_Line *cu_getsrc_die(Dwarf_Die *cu_die, Dwarf_Addr addr)
  *
  * Find a line number and file name for @addr in @cu_die.
  */
-int cu_find_lineinfo(Dwarf_Die *cu_die, unsigned long addr,
-                   const char **fname, int *lineno)
+int cu_find_lineinfo(Dwarf_Die *cu_die, Dwarf_Addr addr,
+                    const char **fname, int *lineno)
 {
        Dwarf_Line *line;
        Dwarf_Die die_mem;
        Dwarf_Addr faddr;
 
-       if (die_find_realfunc(cu_die, (Dwarf_Addr)addr, &die_mem)
+       if (die_find_realfunc(cu_die, addr, &die_mem)
            && die_entrypc(&die_mem, &faddr) == 0 &&
            faddr == addr) {
                *fname = dwarf_decl_file(&die_mem);
@@ -128,7 +128,7 @@ int cu_find_lineinfo(Dwarf_Die *cu_die, unsigned long addr,
                goto out;
        }
 
-       line = cu_getsrc_die(cu_die, (Dwarf_Addr)addr);
+       line = cu_getsrc_die(cu_die, addr);
        if (line && dwarf_lineno(line, lineno) == 0) {
                *fname = dwarf_linesrc(line, NULL, NULL);
                if (!*fname)
index cb99646..7ee0fa1 100644 (file)
@@ -19,7 +19,7 @@ const char *cu_find_realpath(Dwarf_Die *cu_die, const char *fname);
 const char *cu_get_comp_dir(Dwarf_Die *cu_die);
 
 /* Get a line number and file name for given address */
-int cu_find_lineinfo(Dwarf_Die *cudie, unsigned long addr,
+int cu_find_lineinfo(Dwarf_Die *cudie, Dwarf_Addr addr,
                     const char **fname, int *lineno);
 
 /* Walk on functions at given address */
index ebc5e9a..cec2e6c 100644 (file)
@@ -186,10 +186,12 @@ void perf_env__exit(struct perf_env *env)
        zfree(&env->cpuid);
        zfree(&env->cmdline);
        zfree(&env->cmdline_argv);
+       zfree(&env->sibling_dies);
        zfree(&env->sibling_cores);
        zfree(&env->sibling_threads);
        zfree(&env->pmu_mappings);
        zfree(&env->cpu);
+       zfree(&env->cpu_pmu_caps);
        zfree(&env->numa_map);
 
        for (i = 0; i < env->nr_numa_nodes; i++)
index 39062df..51424cd 100644 (file)
@@ -69,7 +69,7 @@ int lzma_decompress_to_file(const char *input, int output_fd)
 
                        if (ferror(infile)) {
                                pr_err("lzma: read error: %s\n", strerror(errno));
-                               goto err_fclose;
+                               goto err_lzma_end;
                        }
 
                        if (feof(infile))
@@ -83,7 +83,7 @@ int lzma_decompress_to_file(const char *input, int output_fd)
 
                        if (writen(output_fd, buf_out, write_size) != write_size) {
                                pr_err("lzma: write error: %s\n", strerror(errno));
-                               goto err_fclose;
+                               goto err_lzma_end;
                        }
 
                        strm.next_out  = buf_out;
@@ -95,11 +95,13 @@ int lzma_decompress_to_file(const char *input, int output_fd)
                                break;
 
                        pr_err("lzma: failed %s\n", lzma_strerror(ret));
-                       goto err_fclose;
+                       goto err_lzma_end;
                }
        }
 
        err = 0;
+err_lzma_end:
+       lzma_end(&strm);
 err_fclose:
        fclose(infile);
        return err;
index 8af693d..72e7f36 100644 (file)
@@ -192,6 +192,8 @@ struct map *map__new(struct machine *machine, u64 start, u64 len,
                        if (!(prot & PROT_EXEC))
                                dso__set_loaded(dso);
                }
+
+               nsinfo__put(dso->nsinfo);
                dso->nsinfo = nsi;
 
                if (build_id__is_defined(bid))
index dd9ed56..756295d 100644 (file)
@@ -99,7 +99,7 @@ int parse_libpfm_events_option(const struct option *opt, const char *str,
                        grp_leader = evsel;
 
                if (grp_evt > -1) {
-                       evsel->leader = grp_leader;
+                       evsel__set_leader(evsel, grp_leader);
                        grp_leader->core.nr_members++;
                        grp_evt++;
                }
index 44b90d6..a1bd700 100644 (file)
@@ -950,6 +950,13 @@ static struct perf_pmu *pmu_lookup(const char *name)
        LIST_HEAD(format);
        LIST_HEAD(aliases);
        __u32 type;
+       bool is_hybrid = perf_pmu__hybrid_mounted(name);
+
+       /*
+        * Check pmu name for hybrid and the pmu may be invalid in sysfs
+        */
+       if (!strncmp(name, "cpu_", 4) && !is_hybrid)
+               return NULL;
 
        /*
         * The pmu data we store & need consists of the pmu
@@ -978,7 +985,7 @@ static struct perf_pmu *pmu_lookup(const char *name)
        pmu->is_uncore = pmu_is_uncore(name);
        if (pmu->is_uncore)
                pmu->id = pmu_id(name);
-       pmu->is_hybrid = perf_pmu__hybrid_mounted(name);
+       pmu->is_hybrid = is_hybrid;
        pmu->max_precise = pmu_max_precise(name);
        pmu_add_cpu_aliases(&aliases, pmu);
        pmu_add_sys_aliases(&aliases, pmu);
index c14e1d2..b2a02c9 100644 (file)
@@ -179,8 +179,10 @@ struct map *get_target_map(const char *target, struct nsinfo *nsi, bool user)
                struct map *map;
 
                map = dso__new_map(target);
-               if (map && map->dso)
+               if (map && map->dso) {
+                       nsinfo__put(map->dso->nsinfo);
                        map->dso->nsinfo = nsinfo__get(nsi);
+               }
                return map;
        } else {
                return kernel_get_module_map(target);
@@ -237,8 +239,8 @@ static void clear_probe_trace_events(struct probe_trace_event *tevs, int ntevs)
                clear_probe_trace_event(tevs + i);
 }
 
-static bool kprobe_blacklist__listed(unsigned long address);
-static bool kprobe_warn_out_range(const char *symbol, unsigned long address)
+static bool kprobe_blacklist__listed(u64 address);
+static bool kprobe_warn_out_range(const char *symbol, u64 address)
 {
        struct map *map;
        bool ret = false;
@@ -398,8 +400,7 @@ static int find_alternative_probe_point(struct debuginfo *dinfo,
        pr_debug("Symbol %s address found : %" PRIx64 "\n",
                        pp->function, address);
 
-       ret = debuginfo__find_probe_point(dinfo, (unsigned long)address,
-                                         result);
+       ret = debuginfo__find_probe_point(dinfo, address, result);
        if (ret <= 0)
                ret = (!ret) ? -ENOENT : ret;
        else {
@@ -587,7 +588,7 @@ static void debuginfo_cache__exit(void)
 }
 
 
-static int get_text_start_address(const char *exec, unsigned long *address,
+static int get_text_start_address(const char *exec, u64 *address,
                                  struct nsinfo *nsi)
 {
        Elf *elf;
@@ -632,7 +633,7 @@ static int find_perf_probe_point_from_dwarf(struct probe_trace_point *tp,
                                            bool is_kprobe)
 {
        struct debuginfo *dinfo = NULL;
-       unsigned long stext = 0;
+       u64 stext = 0;
        u64 addr = tp->address;
        int ret = -ENOENT;
 
@@ -660,8 +661,7 @@ static int find_perf_probe_point_from_dwarf(struct probe_trace_point *tp,
 
        dinfo = debuginfo_cache__open(tp->module, verbose <= 0);
        if (dinfo)
-               ret = debuginfo__find_probe_point(dinfo,
-                                                (unsigned long)addr, pp);
+               ret = debuginfo__find_probe_point(dinfo, addr, pp);
        else
                ret = -ENOENT;
 
@@ -676,7 +676,7 @@ error:
 
 /* Adjust symbol name and address */
 static int post_process_probe_trace_point(struct probe_trace_point *tp,
-                                          struct map *map, unsigned long offs)
+                                          struct map *map, u64 offs)
 {
        struct symbol *sym;
        u64 addr = tp->address - offs;
@@ -719,7 +719,7 @@ post_process_offline_probe_trace_events(struct probe_trace_event *tevs,
                                        int ntevs, const char *pathname)
 {
        struct map *map;
-       unsigned long stext = 0;
+       u64 stext = 0;
        int i, ret = 0;
 
        /* Prepare a map for offline binary */
@@ -745,7 +745,7 @@ static int add_exec_to_probe_trace_events(struct probe_trace_event *tevs,
                                          struct nsinfo *nsi)
 {
        int i, ret = 0;
-       unsigned long stext = 0;
+       u64 stext = 0;
 
        if (!exec)
                return 0;
@@ -790,7 +790,7 @@ post_process_module_probe_trace_events(struct probe_trace_event *tevs,
        mod_name = find_module_name(module);
        for (i = 0; i < ntevs; i++) {
                ret = post_process_probe_trace_point(&tevs[i].point,
-                                               map, (unsigned long)text_offs);
+                                               map, text_offs);
                if (ret < 0)
                        break;
                tevs[i].point.module =
@@ -1534,7 +1534,7 @@ static int parse_perf_probe_point(char *arg, struct perf_probe_event *pev)
                 * so tmp[1] should always valid (but could be '\0').
                 */
                if (tmp && !strncmp(tmp, "0x", 2)) {
-                       pp->abs_address = strtoul(pp->function, &tmp, 0);
+                       pp->abs_address = strtoull(pp->function, &tmp, 0);
                        if (*tmp != '\0') {
                                semantic_error("Invalid absolute address.\n");
                                return -EINVAL;
@@ -1909,7 +1909,7 @@ int parse_probe_trace_command(const char *cmd, struct probe_trace_event *tev)
                        argv[i] = NULL;
                        argc -= 1;
                } else
-                       tp->address = strtoul(fmt1_str, NULL, 0);
+                       tp->address = strtoull(fmt1_str, NULL, 0);
        } else {
                /* Only the symbol-based probe has offset */
                tp->symbol = strdup(fmt1_str);
@@ -2155,7 +2155,7 @@ synthesize_uprobe_trace_def(struct probe_trace_point *tp, struct strbuf *buf)
                return -EINVAL;
 
        /* Use the tp->address for uprobes */
-       err = strbuf_addf(buf, "%s:0x%lx", tp->module, tp->address);
+       err = strbuf_addf(buf, "%s:0x%" PRIx64, tp->module, tp->address);
 
        if (err >= 0 && tp->ref_ctr_offset) {
                if (!uprobe_ref_ctr_is_supported())
@@ -2170,7 +2170,7 @@ synthesize_kprobe_trace_def(struct probe_trace_point *tp, struct strbuf *buf)
 {
        if (!strncmp(tp->symbol, "0x", 2)) {
                /* Absolute address. See try_to_find_absolute_address() */
-               return strbuf_addf(buf, "%s%s0x%lx", tp->module ?: "",
+               return strbuf_addf(buf, "%s%s0x%" PRIx64, tp->module ?: "",
                                  tp->module ? ":" : "", tp->address);
        } else {
                return strbuf_addf(buf, "%s%s%s+%lu", tp->module ?: "",
@@ -2269,7 +2269,7 @@ static int convert_to_perf_probe_point(struct probe_trace_point *tp,
                pp->function = strdup(tp->symbol);
                pp->offset = tp->offset;
        } else {
-               ret = e_snprintf(buf, 128, "0x%" PRIx64, (u64)tp->address);
+               ret = e_snprintf(buf, 128, "0x%" PRIx64, tp->address);
                if (ret < 0)
                        return ret;
                pp->function = strdup(buf);
@@ -2450,8 +2450,8 @@ void clear_probe_trace_event(struct probe_trace_event *tev)
 
 struct kprobe_blacklist_node {
        struct list_head list;
-       unsigned long start;
-       unsigned long end;
+       u64 start;
+       u64 end;
        char *symbol;
 };
 
@@ -2496,7 +2496,7 @@ static int kprobe_blacklist__load(struct list_head *blacklist)
                }
                INIT_LIST_HEAD(&node->list);
                list_add_tail(&node->list, blacklist);
-               if (sscanf(buf, "0x%lx-0x%lx", &node->start, &node->end) != 2) {
+               if (sscanf(buf, "0x%" PRIx64 "-0x%" PRIx64, &node->start, &node->end) != 2) {
                        ret = -EINVAL;
                        break;
                }
@@ -2512,7 +2512,7 @@ static int kprobe_blacklist__load(struct list_head *blacklist)
                        ret = -ENOMEM;
                        break;
                }
-               pr_debug2("Blacklist: 0x%lx-0x%lx, %s\n",
+               pr_debug2("Blacklist: 0x%" PRIx64 "-0x%" PRIx64 ", %s\n",
                          node->start, node->end, node->symbol);
                ret++;
        }
@@ -2524,8 +2524,7 @@ static int kprobe_blacklist__load(struct list_head *blacklist)
 }
 
 static struct kprobe_blacklist_node *
-kprobe_blacklist__find_by_address(struct list_head *blacklist,
-                                 unsigned long address)
+kprobe_blacklist__find_by_address(struct list_head *blacklist, u64 address)
 {
        struct kprobe_blacklist_node *node;
 
@@ -2553,7 +2552,7 @@ static void kprobe_blacklist__release(void)
        kprobe_blacklist__delete(&kprobe_blacklist);
 }
 
-static bool kprobe_blacklist__listed(unsigned long address)
+static bool kprobe_blacklist__listed(u64 address)
 {
        return !!kprobe_blacklist__find_by_address(&kprobe_blacklist, address);
 }
@@ -3221,7 +3220,7 @@ static int try_to_find_absolute_address(struct perf_probe_event *pev,
         * In __add_probe_trace_events, a NULL symbol is interpreted as
         * invalid.
         */
-       if (asprintf(&tp->symbol, "0x%lx", tp->address) < 0)
+       if (asprintf(&tp->symbol, "0x%" PRIx64, tp->address) < 0)
                goto errout;
 
        /* For kprobe, check range */
@@ -3232,7 +3231,7 @@ static int try_to_find_absolute_address(struct perf_probe_event *pev,
                goto errout;
        }
 
-       if (asprintf(&tp->realname, "abs_%lx", tp->address) < 0)
+       if (asprintf(&tp->realname, "abs_%" PRIx64, tp->address) < 0)
                goto errout;
 
        if (pev->target) {
index 65769d7..8ad5b15 100644 (file)
@@ -33,7 +33,7 @@ struct probe_trace_point {
        char            *module;        /* Module name */
        unsigned long   offset;         /* Offset from symbol */
        unsigned long   ref_ctr_offset; /* SDT reference counter offset */
-       unsigned long   address;        /* Actual address of the trace point */
+       u64             address;        /* Actual address of the trace point */
        bool            retprobe;       /* Return probe flag */
 };
 
@@ -70,7 +70,7 @@ struct perf_probe_point {
        bool            retprobe;       /* Return probe flag */
        char            *lazy_line;     /* Lazy matching pattern */
        unsigned long   offset;         /* Offset from function entry */
-       unsigned long   abs_address;    /* Absolute address of the point */
+       u64             abs_address;    /* Absolute address of the point */
 };
 
 /* Perf probe probing argument field chain */
index f9a6cbc..3d50de3 100644 (file)
@@ -377,11 +377,11 @@ int probe_file__del_events(int fd, struct strfilter *filter)
 
        ret = probe_file__get_events(fd, filter, namelist);
        if (ret < 0)
-               return ret;
+               goto out;
 
        ret = probe_file__del_strlist(fd, namelist);
+out:
        strlist__delete(namelist);
-
        return ret;
 }
 
index 02ef0d7..50d861a 100644 (file)
@@ -668,7 +668,7 @@ static int convert_to_trace_point(Dwarf_Die *sp_die, Dwfl_Module *mod,
        }
 
        tp->offset = (unsigned long)(paddr - eaddr);
-       tp->address = (unsigned long)paddr;
+       tp->address = paddr;
        tp->symbol = strdup(symbol);
        if (!tp->symbol)
                return -ENOMEM;
@@ -1707,7 +1707,7 @@ int debuginfo__get_text_offset(struct debuginfo *dbg, Dwarf_Addr *offs,
 }
 
 /* Reverse search */
-int debuginfo__find_probe_point(struct debuginfo *dbg, unsigned long addr,
+int debuginfo__find_probe_point(struct debuginfo *dbg, u64 addr,
                                struct perf_probe_point *ppt)
 {
        Dwarf_Die cudie, spdie, indie;
@@ -1720,14 +1720,14 @@ int debuginfo__find_probe_point(struct debuginfo *dbg, unsigned long addr,
                addr += baseaddr;
        /* Find cu die */
        if (!dwarf_addrdie(dbg->dbg, (Dwarf_Addr)addr, &cudie)) {
-               pr_warning("Failed to find debug information for address %lx\n",
+               pr_warning("Failed to find debug information for address %" PRIx64 "\n",
                           addr);
                ret = -EINVAL;
                goto end;
        }
 
        /* Find a corresponding line (filename and lineno) */
-       cu_find_lineinfo(&cudie, addr, &fname, &lineno);
+       cu_find_lineinfo(&cudie, (Dwarf_Addr)addr, &fname, &lineno);
        /* Don't care whether it failed or not */
 
        /* Find a corresponding function (name, baseline and baseaddr) */
@@ -1742,7 +1742,7 @@ int debuginfo__find_probe_point(struct debuginfo *dbg, unsigned long addr,
                }
 
                fname = dwarf_decl_file(&spdie);
-               if (addr == (unsigned long)baseaddr) {
+               if (addr == baseaddr) {
                        /* Function entry - Relative line number is 0 */
                        lineno = baseline;
                        goto post;
@@ -1788,7 +1788,7 @@ post:
        if (lineno)
                ppt->line = lineno - baseline;
        else if (basefunc) {
-               ppt->offset = addr - (unsigned long)baseaddr;
+               ppt->offset = addr - baseaddr;
                func = basefunc;
        }
 
@@ -1828,8 +1828,7 @@ static int line_range_add_line(const char *src, unsigned int lineno,
 }
 
 static int line_range_walk_cb(const char *fname, int lineno,
-                             Dwarf_Addr addr __maybe_unused,
-                             void *data)
+                             Dwarf_Addr addr, void *data)
 {
        struct line_finder *lf = data;
        const char *__fname;
index 2febb58..8bc1c80 100644 (file)
@@ -46,7 +46,7 @@ int debuginfo__find_trace_events(struct debuginfo *dbg,
                                 struct probe_trace_event **tevs);
 
 /* Find a perf_probe_point from debuginfo */
-int debuginfo__find_probe_point(struct debuginfo *dbg, unsigned long addr,
+int debuginfo__find_probe_point(struct debuginfo *dbg, u64 addr,
                                struct perf_probe_point *ppt);
 
 int debuginfo__get_text_offset(struct debuginfo *dbg, Dwarf_Addr *offs,
index e9c929a..51f7274 100644 (file)
@@ -306,6 +306,7 @@ void perf_session__delete(struct perf_session *session)
                        evlist__delete(session->evlist);
                perf_data__close(session->data);
        }
+       trace_event__cleanup(&session->tevent);
        free(session);
 }
 
index 88ce47f..568a88c 100644 (file)
@@ -3370,7 +3370,7 @@ static void add_hpp_sort_string(struct strbuf *sb, struct hpp_dimension *s, int
                add_key(sb, s[i].name, llen);
 }
 
-const char *sort_help(const char *prefix)
+char *sort_help(const char *prefix)
 {
        struct strbuf sb;
        char *s;
index 87a0926..b67c469 100644 (file)
@@ -302,7 +302,7 @@ void reset_output_field(void);
 void sort__setup_elide(FILE *fp);
 void perf_hpp__set_elide(int idx, bool elide);
 
-const char *sort_help(const char *prefix);
+char *sort_help(const char *prefix);
 
 int report_parse_ignore_callees_opt(const struct option *opt, const char *arg, int unset);
 
index 83a2bc0..5886010 100644 (file)
@@ -596,6 +596,18 @@ static void collect_all_aliases(struct perf_stat_config *config, struct evsel *c
        }
 }
 
+static bool is_uncore(struct evsel *evsel)
+{
+       struct perf_pmu *pmu = evsel__find_pmu(evsel);
+
+       return pmu && pmu->is_uncore;
+}
+
+static bool hybrid_uniquify(struct evsel *evsel)
+{
+       return perf_pmu__has_hybrid() && !is_uncore(evsel);
+}
+
 static bool collect_data(struct perf_stat_config *config, struct evsel *counter,
                            void (*cb)(struct perf_stat_config *config, struct evsel *counter, void *data,
                                       bool first),
@@ -604,7 +616,7 @@ static bool collect_data(struct perf_stat_config *config, struct evsel *counter,
        if (counter->merged_stat)
                return false;
        cb(config, counter, data, true);
-       if (config->no_merge)
+       if (config->no_merge || hybrid_uniquify(counter))
                uniquify_event_name(counter);
        else if (counter->auto_merge_stats)
                collect_all_aliases(config, counter, cb, data);
index be8d8d4..6276ce0 100755 (executable)
@@ -12,6 +12,8 @@ import sys
 import os
 import time
 
+assert sys.version_info >= (3, 7), "Python version is too old"
+
 from collections import namedtuple
 from enum import Enum, auto
 
index 90bc007..2c6f916 100644 (file)
@@ -6,15 +6,13 @@
 # Author: Felix Guo <felixguoxiuping@gmail.com>
 # Author: Brendan Higgins <brendanhiggins@google.com>
 
-from __future__ import annotations
 import importlib.util
 import logging
 import subprocess
 import os
 import shutil
 import signal
-from typing import Iterator
-from typing import Optional
+from typing import Iterator, Optional, Tuple
 
 from contextlib import ExitStack
 
@@ -208,7 +206,7 @@ def get_source_tree_ops(arch: str, cross_compile: Optional[str]) -> LinuxSourceT
                raise ConfigError(arch + ' is not a valid arch')
 
 def get_source_tree_ops_from_qemu_config(config_path: str,
-                                        cross_compile: Optional[str]) -> tuple[
+                                        cross_compile: Optional[str]) -> Tuple[
                                                         str, LinuxSourceTreeOperations]:
        # The module name/path has very little to do with where the actual file
        # exists (I learned this through experimentation and could not find it
index c3c524b..b88db3f 100644 (file)
@@ -338,9 +338,11 @@ def bubble_up_suite_errors(test_suites: Iterable[TestSuite]) -> TestStatus:
 def parse_test_result(lines: LineStream) -> TestResult:
        consume_non_diagnostic(lines)
        if not lines or not parse_tap_header(lines):
-               return TestResult(TestStatus.NO_TESTS, [], lines)
+               return TestResult(TestStatus.FAILURE_TO_PARSE_TESTS, [], lines)
        expected_test_suite_num = parse_test_plan(lines)
-       if not expected_test_suite_num:
+       if expected_test_suite_num == 0:
+               return TestResult(TestStatus.NO_TESTS, [], lines)
+       elif expected_test_suite_num is None:
                return TestResult(TestStatus.FAILURE_TO_PARSE_TESTS, [], lines)
        test_suites = []
        for i in range(1, expected_test_suite_num + 1):
index bdae0e5..75045aa 100755 (executable)
@@ -157,8 +157,18 @@ class KUnitParserTest(unittest.TestCase):
                        kunit_parser.TestStatus.FAILURE,
                        result.status)
 
+       def test_no_header(self):
+               empty_log = test_data_path('test_is_test_passed-no_tests_run_no_header.log')
+               with open(empty_log) as file:
+                       result = kunit_parser.parse_run_tests(
+                               kunit_parser.extract_tap_lines(file.readlines()))
+               self.assertEqual(0, len(result.suites))
+               self.assertEqual(
+                       kunit_parser.TestStatus.FAILURE_TO_PARSE_TESTS,
+                       result.status)
+
        def test_no_tests(self):
-               empty_log = test_data_path('test_is_test_passed-no_tests_run.log')
+               empty_log = test_data_path('test_is_test_passed-no_tests_run_with_header.log')
                with open(empty_log) as file:
                        result = kunit_parser.parse_run_tests(
                                kunit_parser.extract_tap_lines(file.readlines()))
@@ -173,7 +183,7 @@ class KUnitParserTest(unittest.TestCase):
                with open(crash_log) as file:
                        result = kunit_parser.parse_run_tests(
                                kunit_parser.extract_tap_lines(file.readlines()))
-               print_mock.assert_any_call(StrContains('no tests run!'))
+               print_mock.assert_any_call(StrContains('could not parse test results!'))
                print_mock.stop()
                file.close()
 
@@ -309,7 +319,7 @@ class KUnitJsonTest(unittest.TestCase):
                        result["sub_groups"][1]["test_cases"][0])
 
        def test_no_tests_json(self):
-               result = self._json_for('test_is_test_passed-no_tests_run.log')
+               result = self._json_for('test_is_test_passed-no_tests_run_with_header.log')
                self.assertEqual(0, len(result['sub_groups']))
 
 class StrContains(str):
diff --git a/tools/testing/kunit/test_data/test_is_test_passed-no_tests_run.log b/tools/testing/kunit/test_data/test_is_test_passed-no_tests_run.log
deleted file mode 100644 (file)
index ba69f5c..0000000
+++ /dev/null
@@ -1,75 +0,0 @@
-Core dump limits :
-       soft - 0
-       hard - NONE
-Checking environment variables for a tempdir...none found
-Checking if /dev/shm is on tmpfs...OK
-Checking PROT_EXEC mmap in /dev/shm...OK
-Adding 24743936 bytes to physical memory to account for exec-shield gap
-Linux version 4.12.0-rc3-00010-g7319eb35f493-dirty (brendanhiggins@mactruck.svl.corp.google.com) (gcc version 7.3.0 (Debian 7.3.0-5) ) #29 Thu Mar 15 14:57:19 PDT 2018
-Built 1 zonelists in Zone order, mobility grouping on.  Total pages: 14038
-Kernel command line: root=98:0
-PID hash table entries: 256 (order: -1, 2048 bytes)
-Dentry cache hash table entries: 8192 (order: 4, 65536 bytes)
-Inode-cache hash table entries: 4096 (order: 3, 32768 bytes)
-Memory: 27868K/56932K available (1681K kernel code, 480K rwdata, 400K rodata, 89K init, 205K bss, 29064K reserved, 0K cma-reserved)
-SLUB: HWalign=64, Order=0-3, MinObjects=0, CPUs=1, Nodes=1
-NR_IRQS:15
-clocksource: timer: mask: 0xffffffffffffffff max_cycles: 0x1cd42e205, max_idle_ns: 881590404426 ns
-Calibrating delay loop... 7384.26 BogoMIPS (lpj=36921344)
-pid_max: default: 32768 minimum: 301
-Mount-cache hash table entries: 512 (order: 0, 4096 bytes)
-Mountpoint-cache hash table entries: 512 (order: 0, 4096 bytes)
-Checking that host ptys support output SIGIO...Yes
-Checking that host ptys support SIGIO on close...No, enabling workaround
-Using 2.6 host AIO
-clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 19112604462750000 ns
-futex hash table entries: 256 (order: 0, 6144 bytes)
-clocksource: Switched to clocksource timer
-console [stderr0] disabled
-mconsole (version 2) initialized on /usr/local/google/home/brendanhiggins/.uml/6Ijecl/mconsole
-Checking host MADV_REMOVE support...OK
-workingset: timestamp_bits=62 max_order=13 bucket_order=0
-Block layer SCSI generic (bsg) driver version 0.4 loaded (major 254)
-io scheduler noop registered
-io scheduler deadline registered
-io scheduler cfq registered (default)
-io scheduler mq-deadline registered
-io scheduler kyber registered
-Initialized stdio console driver
-Using a channel type which is configured out of UML
-setup_one_line failed for device 1 : Configuration failed
-Using a channel type which is configured out of UML
-setup_one_line failed for device 2 : Configuration failed
-Using a channel type which is configured out of UML
-setup_one_line failed for device 3 : Configuration failed
-Using a channel type which is configured out of UML
-setup_one_line failed for device 4 : Configuration failed
-Using a channel type which is configured out of UML
-setup_one_line failed for device 5 : Configuration failed
-Using a channel type which is configured out of UML
-setup_one_line failed for device 6 : Configuration failed
-Using a channel type which is configured out of UML
-setup_one_line failed for device 7 : Configuration failed
-Using a channel type which is configured out of UML
-setup_one_line failed for device 8 : Configuration failed
-Using a channel type which is configured out of UML
-setup_one_line failed for device 9 : Configuration failed
-Using a channel type which is configured out of UML
-setup_one_line failed for device 10 : Configuration failed
-Using a channel type which is configured out of UML
-setup_one_line failed for device 11 : Configuration failed
-Using a channel type which is configured out of UML
-setup_one_line failed for device 12 : Configuration failed
-Using a channel type which is configured out of UML
-setup_one_line failed for device 13 : Configuration failed
-Using a channel type which is configured out of UML
-setup_one_line failed for device 14 : Configuration failed
-Using a channel type which is configured out of UML
-setup_one_line failed for device 15 : Configuration failed
-Console initialized on /dev/tty0
-console [tty0] enabled
-console [mc-1] enabled
-List of all partitions:
-No filesystem could mount root, tried:
-
-Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(98,0)
diff --git a/tools/testing/kunit/test_data/test_is_test_passed-no_tests_run_no_header.log b/tools/testing/kunit/test_data/test_is_test_passed-no_tests_run_no_header.log
new file mode 100644 (file)
index 0000000..ba69f5c
--- /dev/null
@@ -0,0 +1,75 @@
+Core dump limits :
+       soft - 0
+       hard - NONE
+Checking environment variables for a tempdir...none found
+Checking if /dev/shm is on tmpfs...OK
+Checking PROT_EXEC mmap in /dev/shm...OK
+Adding 24743936 bytes to physical memory to account for exec-shield gap
+Linux version 4.12.0-rc3-00010-g7319eb35f493-dirty (brendanhiggins@mactruck.svl.corp.google.com) (gcc version 7.3.0 (Debian 7.3.0-5) ) #29 Thu Mar 15 14:57:19 PDT 2018
+Built 1 zonelists in Zone order, mobility grouping on.  Total pages: 14038
+Kernel command line: root=98:0
+PID hash table entries: 256 (order: -1, 2048 bytes)
+Dentry cache hash table entries: 8192 (order: 4, 65536 bytes)
+Inode-cache hash table entries: 4096 (order: 3, 32768 bytes)
+Memory: 27868K/56932K available (1681K kernel code, 480K rwdata, 400K rodata, 89K init, 205K bss, 29064K reserved, 0K cma-reserved)
+SLUB: HWalign=64, Order=0-3, MinObjects=0, CPUs=1, Nodes=1
+NR_IRQS:15
+clocksource: timer: mask: 0xffffffffffffffff max_cycles: 0x1cd42e205, max_idle_ns: 881590404426 ns
+Calibrating delay loop... 7384.26 BogoMIPS (lpj=36921344)
+pid_max: default: 32768 minimum: 301
+Mount-cache hash table entries: 512 (order: 0, 4096 bytes)
+Mountpoint-cache hash table entries: 512 (order: 0, 4096 bytes)
+Checking that host ptys support output SIGIO...Yes
+Checking that host ptys support SIGIO on close...No, enabling workaround
+Using 2.6 host AIO
+clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 19112604462750000 ns
+futex hash table entries: 256 (order: 0, 6144 bytes)
+clocksource: Switched to clocksource timer
+console [stderr0] disabled
+mconsole (version 2) initialized on /usr/local/google/home/brendanhiggins/.uml/6Ijecl/mconsole
+Checking host MADV_REMOVE support...OK
+workingset: timestamp_bits=62 max_order=13 bucket_order=0
+Block layer SCSI generic (bsg) driver version 0.4 loaded (major 254)
+io scheduler noop registered
+io scheduler deadline registered
+io scheduler cfq registered (default)
+io scheduler mq-deadline registered
+io scheduler kyber registered
+Initialized stdio console driver
+Using a channel type which is configured out of UML
+setup_one_line failed for device 1 : Configuration failed
+Using a channel type which is configured out of UML
+setup_one_line failed for device 2 : Configuration failed
+Using a channel type which is configured out of UML
+setup_one_line failed for device 3 : Configuration failed
+Using a channel type which is configured out of UML
+setup_one_line failed for device 4 : Configuration failed
+Using a channel type which is configured out of UML
+setup_one_line failed for device 5 : Configuration failed
+Using a channel type which is configured out of UML
+setup_one_line failed for device 6 : Configuration failed
+Using a channel type which is configured out of UML
+setup_one_line failed for device 7 : Configuration failed
+Using a channel type which is configured out of UML
+setup_one_line failed for device 8 : Configuration failed
+Using a channel type which is configured out of UML
+setup_one_line failed for device 9 : Configuration failed
+Using a channel type which is configured out of UML
+setup_one_line failed for device 10 : Configuration failed
+Using a channel type which is configured out of UML
+setup_one_line failed for device 11 : Configuration failed
+Using a channel type which is configured out of UML
+setup_one_line failed for device 12 : Configuration failed
+Using a channel type which is configured out of UML
+setup_one_line failed for device 13 : Configuration failed
+Using a channel type which is configured out of UML
+setup_one_line failed for device 14 : Configuration failed
+Using a channel type which is configured out of UML
+setup_one_line failed for device 15 : Configuration failed
+Console initialized on /dev/tty0
+console [tty0] enabled
+console [mc-1] enabled
+List of all partitions:
+No filesystem could mount root, tried:
+
+Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(98,0)
diff --git a/tools/testing/kunit/test_data/test_is_test_passed-no_tests_run_with_header.log b/tools/testing/kunit/test_data/test_is_test_passed-no_tests_run_with_header.log
new file mode 100644 (file)
index 0000000..5f48ee6
--- /dev/null
@@ -0,0 +1,2 @@
+TAP version 14
+1..0
index ee27d68..b5940e6 100644 (file)
@@ -715,6 +715,8 @@ out:
        bpf_object__close(obj);
 }
 
+#include "tailcall_bpf2bpf4.skel.h"
+
 /* test_tailcall_bpf2bpf_4 checks that tailcall counter is correctly preserved
  * across tailcalls combined with bpf2bpf calls. for making sure that tailcall
  * counter behaves correctly, bpf program will go through following flow:
@@ -727,10 +729,15 @@ out:
  * the loop begins. At the end of the test make sure that the global counter is
  * equal to 31, because tailcall counter includes the first two tailcalls
  * whereas global counter is incremented only on loop presented on flow above.
+ *
+ * The noise parameter is used to insert bpf_map_update calls into the logic
+ * to force verifier to patch instructions. This allows us to ensure jump
+ * logic remains correct with instruction movement.
  */
-static void test_tailcall_bpf2bpf_4(void)
+static void test_tailcall_bpf2bpf_4(bool noise)
 {
-       int err, map_fd, prog_fd, main_fd, data_fd, i, val;
+       int err, map_fd, prog_fd, main_fd, data_fd, i;
+       struct tailcall_bpf2bpf4__bss val;
        struct bpf_map *prog_array, *data_map;
        struct bpf_program *prog;
        struct bpf_object *obj;
@@ -774,11 +781,6 @@ static void test_tailcall_bpf2bpf_4(void)
                        goto out;
        }
 
-       err = bpf_prog_test_run(main_fd, 1, &pkt_v4, sizeof(pkt_v4), 0,
-                               &duration, &retval, NULL);
-       CHECK(err || retval != sizeof(pkt_v4) * 3, "tailcall", "err %d errno %d retval %d\n",
-             err, errno, retval);
-
        data_map = bpf_object__find_map_by_name(obj, "tailcall.bss");
        if (CHECK_FAIL(!data_map || !bpf_map__is_internal(data_map)))
                return;
@@ -787,10 +789,22 @@ static void test_tailcall_bpf2bpf_4(void)
        if (CHECK_FAIL(map_fd < 0))
                return;
 
+       i = 0;
+       val.noise = noise;
+       val.count = 0;
+       err = bpf_map_update_elem(data_fd, &i, &val, BPF_ANY);
+       if (CHECK_FAIL(err))
+               goto out;
+
+       err = bpf_prog_test_run(main_fd, 1, &pkt_v4, sizeof(pkt_v4), 0,
+                               &duration, &retval, NULL);
+       CHECK(err || retval != sizeof(pkt_v4) * 3, "tailcall", "err %d errno %d retval %d\n",
+             err, errno, retval);
+
        i = 0;
        err = bpf_map_lookup_elem(data_fd, &i, &val);
-       CHECK(err || val != 31, "tailcall count", "err %d errno %d count %d\n",
-             err, errno, val);
+       CHECK(err || val.count != 31, "tailcall count", "err %d errno %d count %d\n",
+             err, errno, val.count);
 
 out:
        bpf_object__close(obj);
@@ -815,5 +829,7 @@ void test_tailcalls(void)
        if (test__start_subtest("tailcall_bpf2bpf_3"))
                test_tailcall_bpf2bpf_3();
        if (test__start_subtest("tailcall_bpf2bpf_4"))
-               test_tailcall_bpf2bpf_4();
+               test_tailcall_bpf2bpf_4(false);
+       if (test__start_subtest("tailcall_bpf2bpf_5"))
+               test_tailcall_bpf2bpf_4(true);
 }
index 77df6d4..e89368a 100644 (file)
@@ -2,6 +2,13 @@
 #include <linux/bpf.h>
 #include <bpf/bpf_helpers.h>
 
+struct {
+       __uint(type, BPF_MAP_TYPE_ARRAY);
+       __uint(max_entries, 1);
+       __uint(key_size, sizeof(__u32));
+       __uint(value_size, sizeof(__u32));
+} nop_table SEC(".maps");
+
 struct {
        __uint(type, BPF_MAP_TYPE_PROG_ARRAY);
        __uint(max_entries, 3);
@@ -10,10 +17,21 @@ struct {
 } jmp_table SEC(".maps");
 
 int count = 0;
+int noise = 0;
+
+__always_inline int subprog_noise(void)
+{
+       __u32 key = 0;
+
+       bpf_map_lookup_elem(&nop_table, &key);
+       return 0;
+}
 
 __noinline
 int subprog_tail_2(struct __sk_buff *skb)
 {
+       if (noise)
+               subprog_noise();
        bpf_tail_call_static(skb, &jmp_table, 2);
        return skb->len * 3;
 }
index 615ab25..010b59b 100644 (file)
@@ -45,6 +45,7 @@ enum vm_guest_mode {
        VM_MODE_P40V48_64K,
        VM_MODE_PXXV48_4K,      /* For 48bits VA but ANY bits PA */
        VM_MODE_P47V64_4K,
+       VM_MODE_P44V64_4K,
        NUM_VM_MODES,
 };
 
@@ -62,7 +63,7 @@ enum vm_guest_mode {
 
 #elif defined(__s390x__)
 
-#define VM_MODE_DEFAULT                        VM_MODE_P47V64_4K
+#define VM_MODE_DEFAULT                        VM_MODE_P44V64_4K
 #define MIN_PAGE_SHIFT                 12U
 #define ptes_per_page(page_size)       ((page_size) / 16)
 
index 9f49f6c..632b74d 100644 (file)
@@ -401,7 +401,7 @@ unexpected_exception:
 void vm_init_descriptor_tables(struct kvm_vm *vm)
 {
        vm->handlers = vm_vaddr_alloc(vm, sizeof(struct handlers),
-                       vm->page_size, 0, 0);
+                       vm->page_size);
 
        *(vm_vaddr_t *)addr_gva2hva(vm, (vm_vaddr_t)(&exception_handlers)) = vm->handlers;
 }
index 25bff30..c330f41 100644 (file)
@@ -22,6 +22,22 @@ void guest_modes_append_default(void)
                }
        }
 #endif
+#ifdef __s390x__
+       {
+               int kvm_fd, vm_fd;
+               struct kvm_s390_vm_cpu_processor info;
+
+               kvm_fd = open_kvm_dev_path_or_exit();
+               vm_fd = ioctl(kvm_fd, KVM_CREATE_VM, 0);
+               kvm_device_access(vm_fd, KVM_S390_VM_CPU_MODEL,
+                                 KVM_S390_VM_CPU_PROCESSOR, &info, false);
+               close(vm_fd);
+               close(kvm_fd);
+               /* Starting with z13 we have 47bits of physical address */
+               if (info.ibc >= 0x30)
+                       guest_mode_append(VM_MODE_P47V64_4K, true, true);
+       }
+#endif
 }
 
 void for_each_guest_mode(void (*func)(enum vm_guest_mode, void *), void *arg)
index 5b56b57..10a8ed6 100644 (file)
@@ -176,6 +176,7 @@ const char *vm_guest_mode_string(uint32_t i)
                [VM_MODE_P40V48_64K]    = "PA-bits:40,  VA-bits:48, 64K pages",
                [VM_MODE_PXXV48_4K]     = "PA-bits:ANY, VA-bits:48,  4K pages",
                [VM_MODE_P47V64_4K]     = "PA-bits:47,  VA-bits:64,  4K pages",
+               [VM_MODE_P44V64_4K]     = "PA-bits:44,  VA-bits:64,  4K pages",
        };
        _Static_assert(sizeof(strings)/sizeof(char *) == NUM_VM_MODES,
                       "Missing new mode strings?");
@@ -194,6 +195,7 @@ const struct vm_guest_mode_params vm_guest_mode_params[] = {
        { 40, 48, 0x10000, 16 },
        {  0,  0,  0x1000, 12 },
        { 47, 64,  0x1000, 12 },
+       { 44, 64,  0x1000, 12 },
 };
 _Static_assert(sizeof(vm_guest_mode_params)/sizeof(struct vm_guest_mode_params) == NUM_VM_MODES,
               "Missing new mode params?");
@@ -282,6 +284,9 @@ struct kvm_vm *vm_create(enum vm_guest_mode mode, uint64_t phy_pages, int perm)
        case VM_MODE_P47V64_4K:
                vm->pgtable_levels = 5;
                break;
+       case VM_MODE_P44V64_4K:
+               vm->pgtable_levels = 5;
+               break;
        default:
                TEST_FAIL("Unknown guest mode, mode: 0x%x", mode);
        }
index 85b18bb..72a1c9b 100644 (file)
@@ -377,7 +377,8 @@ static void test_add_max_memory_regions(void)
                (max_mem_slots - 1), MEM_REGION_SIZE >> 10);
 
        mem = mmap(NULL, (size_t)max_mem_slots * MEM_REGION_SIZE + alignment,
-                  PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+                  PROT_READ | PROT_WRITE,
+                  MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE, -1, 0);
        TEST_ASSERT(mem != MAP_FAILED, "Failed to mmap() host");
        mem_aligned = (void *)(((size_t) mem + alignment - 1) & ~(alignment - 1));
 
index 42bd658..af27c7e 100644 (file)
@@ -615,7 +615,7 @@ int main(void)
 
        vm_init_descriptor_tables(vm);
        vcpu_init_descriptor_tables(vm, VCPU_ID);
-       vm_handle_exception(vm, GP_VECTOR, guest_gp_handler);
+       vm_install_exception_handler(vm, GP_VECTOR, guest_gp_handler);
 
        pr_info("Testing access to Hyper-V specific MSRs\n");
        guest_test_msrs_access(vm, addr_gva2hva(vm, msr_gva),
index 523371c..da2325f 100644 (file)
@@ -71,7 +71,7 @@ static void mmu_role_test(u32 *cpuid_reg, u32 evil_cpuid_val)
        /* Set up a #PF handler to eat the RSVD #PF and signal all done! */
        vm_init_descriptor_tables(vm);
        vcpu_init_descriptor_tables(vm, VCPU_ID);
-       vm_handle_exception(vm, PF_VECTOR, guest_pf_handler);
+       vm_install_exception_handler(vm, PF_VECTOR, guest_pf_handler);
 
        r = _vcpu_run(vm, VCPU_ID);
        TEST_ASSERT(r == 0, "vcpu_run failed: %d\n", r);
index c1f8318..d0fe2fd 100644 (file)
@@ -53,15 +53,28 @@ static inline void sync_with_host(uint64_t phase)
                     : "+a" (phase));
 }
 
-void self_smi(void)
+static void self_smi(void)
 {
        x2apic_write_reg(APIC_ICR,
                         APIC_DEST_SELF | APIC_INT_ASSERT | APIC_DM_SMI);
 }
 
-void guest_code(void *arg)
+static void l2_guest_code(void)
 {
+       sync_with_host(8);
+
+       sync_with_host(10);
+
+       vmcall();
+}
+
+static void guest_code(void *arg)
+{
+       #define L2_GUEST_STACK_SIZE 64
+       unsigned long l2_guest_stack[L2_GUEST_STACK_SIZE];
        uint64_t apicbase = rdmsr(MSR_IA32_APICBASE);
+       struct svm_test_data *svm = arg;
+       struct vmx_pages *vmx_pages = arg;
 
        sync_with_host(1);
 
@@ -74,21 +87,50 @@ void guest_code(void *arg)
        sync_with_host(4);
 
        if (arg) {
-               if (cpu_has_svm())
-                       generic_svm_setup(arg, NULL, NULL);
-               else
-                       GUEST_ASSERT(prepare_for_vmx_operation(arg));
+               if (cpu_has_svm()) {
+                       generic_svm_setup(svm, l2_guest_code,
+                                         &l2_guest_stack[L2_GUEST_STACK_SIZE]);
+               } else {
+                       GUEST_ASSERT(prepare_for_vmx_operation(vmx_pages));
+                       GUEST_ASSERT(load_vmcs(vmx_pages));
+                       prepare_vmcs(vmx_pages, l2_guest_code,
+                                    &l2_guest_stack[L2_GUEST_STACK_SIZE]);
+               }
 
                sync_with_host(5);
 
                self_smi();
 
                sync_with_host(7);
+
+               if (cpu_has_svm()) {
+                       run_guest(svm->vmcb, svm->vmcb_gpa);
+                       svm->vmcb->save.rip += 3;
+                       run_guest(svm->vmcb, svm->vmcb_gpa);
+               } else {
+                       vmlaunch();
+                       vmresume();
+               }
+
+               /* Stages 8-11 are eaten by SMM (SMRAM_STAGE reported instead) */
+               sync_with_host(12);
        }
 
        sync_with_host(DONE);
 }
 
+void inject_smi(struct kvm_vm *vm)
+{
+       struct kvm_vcpu_events events;
+
+       vcpu_events_get(vm, VCPU_ID, &events);
+
+       events.smi.pending = 1;
+       events.flags |= KVM_VCPUEVENT_VALID_SMM;
+
+       vcpu_events_set(vm, VCPU_ID, &events);
+}
+
 int main(int argc, char *argv[])
 {
        vm_vaddr_t nested_gva = 0;
@@ -147,6 +189,22 @@ int main(int argc, char *argv[])
                            "Unexpected stage: #%x, got %x",
                            stage, stage_reported);
 
+               /*
+                * Enter SMM during L2 execution and check that we correctly
+                * return from it. Do not perform save/restore while in SMM yet.
+                */
+               if (stage == 8) {
+                       inject_smi(vm);
+                       continue;
+               }
+
+               /*
+                * Perform save/restore while the guest is in SMM triggered
+                * during L2 execution.
+                */
+               if (stage == 10)
+                       inject_smi(vm);
+
                state = vcpu_save_state(vm, VCPU_ID);
                kvm_vm_release(vm);
                kvm_vm_restart(vm, O_RDWR);
index b37585e..46a97f3 100755 (executable)
@@ -282,7 +282,9 @@ done
 #
 echo $error > $NOTIFIER_ERR_INJECT_DIR/actions/MEM_GOING_OFFLINE/error
 for memory in `hotpluggable_online_memory`; do
-       offline_memory_expect_fail $memory
+       if [ $((RANDOM % 100)) -lt $ratio ]; then
+               offline_memory_expect_fail $memory
+       fi
 done
 
 echo 0 > $NOTIFIER_ERR_INJECT_DIR/actions/MEM_GOING_OFFLINE/error
index c19ecc6..ecbf57f 100755 (executable)
@@ -313,9 +313,10 @@ check_exception()
        fi
        log_test $? 0 "IPv4: ${desc}"
 
-       if [ "$with_redirect" = "yes" ]; then
+       # No PMTU info for test "redirect" and "mtu exception plus redirect"
+       if [ "$with_redirect" = "yes" ] && [ "$desc" != "redirect exception plus mtu" ]; then
                ip -netns h1 -6 ro get ${H1_VRF_ARG} ${H2_N2_IP6} | \
-               grep -q "${H2_N2_IP6} from :: via ${R2_LLADDR} dev br0.*${mtu}"
+               grep -v "mtu" | grep -q "${H2_N2_IP6} .*via ${R2_LLADDR} dev br0"
        elif [ -n "${mtu}" ]; then
                ip -netns h1 -6 ro get ${H1_VRF_ARG} ${H2_N2_IP6} | \
                grep -q "${mtu}"
index 9a191c1..f02f4de 100755 (executable)
@@ -1409,7 +1409,7 @@ syncookies_tests()
        ip netns exec $ns2 ./pm_nl_ctl add 10.0.3.2 flags subflow
        ip netns exec $ns2 ./pm_nl_ctl add 10.0.2.2 flags subflow
        run_tests $ns1 $ns2 10.0.1.1
-       chk_join_nr "subflows limited by server w cookies" 2 2 1
+       chk_join_nr "subflows limited by server w cookies" 2 1 1
 
        # test signal address with cookies
        reset_with_cookies
index 21091be..aee631c 100644 (file)
@@ -47,7 +47,7 @@ static void usage(const char *error)
 {
        if (error)
                printf("invalid option: %s\n", error);
-       printf("timestamping interface option*\n\n"
+       printf("timestamping <interface> [bind_phc_index] [option]*\n\n"
               "Options:\n"
               "  IP_MULTICAST_LOOP - looping outgoing multicasts\n"
               "  SO_TIMESTAMP - normal software time stamping, ms resolution\n"
@@ -58,6 +58,7 @@ static void usage(const char *error)
               "  SOF_TIMESTAMPING_RX_SOFTWARE - software fallback for incoming packets\n"
               "  SOF_TIMESTAMPING_SOFTWARE - request reporting of software time stamps\n"
               "  SOF_TIMESTAMPING_RAW_HARDWARE - request reporting of raw HW time stamps\n"
+              "  SOF_TIMESTAMPING_BIND_PHC - request to bind a PHC of PTP vclock\n"
               "  SIOCGSTAMP - check last socket time stamp\n"
               "  SIOCGSTAMPNS - more accurate socket time stamp\n"
               "  PTPV2 - use PTPv2 messages\n");
@@ -311,7 +312,6 @@ static void recvpacket(int sock, int recvmsg_flags,
 
 int main(int argc, char **argv)
 {
-       int so_timestamping_flags = 0;
        int so_timestamp = 0;
        int so_timestampns = 0;
        int siocgstamp = 0;
@@ -325,6 +325,8 @@ int main(int argc, char **argv)
        struct ifreq device;
        struct ifreq hwtstamp;
        struct hwtstamp_config hwconfig, hwconfig_requested;
+       struct so_timestamping so_timestamping_get = { 0, -1 };
+       struct so_timestamping so_timestamping = { 0, -1 };
        struct sockaddr_in addr;
        struct ip_mreq imr;
        struct in_addr iaddr;
@@ -342,7 +344,12 @@ int main(int argc, char **argv)
                exit(1);
        }
 
-       for (i = 2; i < argc; i++) {
+       if (argc >= 3 && sscanf(argv[2], "%d", &so_timestamping.bind_phc) == 1)
+               val = 3;
+       else
+               val = 2;
+
+       for (i = val; i < argc; i++) {
                if (!strcasecmp(argv[i], "SO_TIMESTAMP"))
                        so_timestamp = 1;
                else if (!strcasecmp(argv[i], "SO_TIMESTAMPNS"))
@@ -356,17 +363,19 @@ int main(int argc, char **argv)
                else if (!strcasecmp(argv[i], "PTPV2"))
                        ptpv2 = 1;
                else if (!strcasecmp(argv[i], "SOF_TIMESTAMPING_TX_HARDWARE"))
-                       so_timestamping_flags |= SOF_TIMESTAMPING_TX_HARDWARE;
+                       so_timestamping.flags |= SOF_TIMESTAMPING_TX_HARDWARE;
                else if (!strcasecmp(argv[i], "SOF_TIMESTAMPING_TX_SOFTWARE"))
-                       so_timestamping_flags |= SOF_TIMESTAMPING_TX_SOFTWARE;
+                       so_timestamping.flags |= SOF_TIMESTAMPING_TX_SOFTWARE;
                else if (!strcasecmp(argv[i], "SOF_TIMESTAMPING_RX_HARDWARE"))
-                       so_timestamping_flags |= SOF_TIMESTAMPING_RX_HARDWARE;
+                       so_timestamping.flags |= SOF_TIMESTAMPING_RX_HARDWARE;
                else if (!strcasecmp(argv[i], "SOF_TIMESTAMPING_RX_SOFTWARE"))
-                       so_timestamping_flags |= SOF_TIMESTAMPING_RX_SOFTWARE;
+                       so_timestamping.flags |= SOF_TIMESTAMPING_RX_SOFTWARE;
                else if (!strcasecmp(argv[i], "SOF_TIMESTAMPING_SOFTWARE"))
-                       so_timestamping_flags |= SOF_TIMESTAMPING_SOFTWARE;
+                       so_timestamping.flags |= SOF_TIMESTAMPING_SOFTWARE;
                else if (!strcasecmp(argv[i], "SOF_TIMESTAMPING_RAW_HARDWARE"))
-                       so_timestamping_flags |= SOF_TIMESTAMPING_RAW_HARDWARE;
+                       so_timestamping.flags |= SOF_TIMESTAMPING_RAW_HARDWARE;
+               else if (!strcasecmp(argv[i], "SOF_TIMESTAMPING_BIND_PHC"))
+                       so_timestamping.flags |= SOF_TIMESTAMPING_BIND_PHC;
                else
                        usage(argv[i]);
        }
@@ -385,10 +394,10 @@ int main(int argc, char **argv)
        hwtstamp.ifr_data = (void *)&hwconfig;
        memset(&hwconfig, 0, sizeof(hwconfig));
        hwconfig.tx_type =
-               (so_timestamping_flags & SOF_TIMESTAMPING_TX_HARDWARE) ?
+               (so_timestamping.flags & SOF_TIMESTAMPING_TX_HARDWARE) ?
                HWTSTAMP_TX_ON : HWTSTAMP_TX_OFF;
        hwconfig.rx_filter =
-               (so_timestamping_flags & SOF_TIMESTAMPING_RX_HARDWARE) ?
+               (so_timestamping.flags & SOF_TIMESTAMPING_RX_HARDWARE) ?
                ptpv2 ? HWTSTAMP_FILTER_PTP_V2_L4_SYNC :
                HWTSTAMP_FILTER_PTP_V1_L4_SYNC : HWTSTAMP_FILTER_NONE;
        hwconfig_requested = hwconfig;
@@ -413,6 +422,9 @@ int main(int argc, char **argv)
                 sizeof(struct sockaddr_in)) < 0)
                bail("bind");
 
+       if (setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, interface, if_len))
+               bail("bind device");
+
        /* set multicast group for outgoing packets */
        inet_aton("224.0.1.130", &iaddr); /* alternate PTP domain 1 */
        addr.sin_addr = iaddr;
@@ -444,10 +456,9 @@ int main(int argc, char **argv)
                           &enabled, sizeof(enabled)) < 0)
                bail("setsockopt SO_TIMESTAMPNS");
 
-       if (so_timestamping_flags &&
-               setsockopt(sock, SOL_SOCKET, SO_TIMESTAMPING,
-                          &so_timestamping_flags,
-                          sizeof(so_timestamping_flags)) < 0)
+       if (so_timestamping.flags &&
+           setsockopt(sock, SOL_SOCKET, SO_TIMESTAMPING, &so_timestamping,
+                      sizeof(so_timestamping)) < 0)
                bail("setsockopt SO_TIMESTAMPING");
 
        /* request IP_PKTINFO for debugging purposes */
@@ -468,14 +479,18 @@ int main(int argc, char **argv)
        else
                printf("SO_TIMESTAMPNS %d\n", val);
 
-       if (getsockopt(sock, SOL_SOCKET, SO_TIMESTAMPING, &val, &len) < 0) {
+       len = sizeof(so_timestamping_get);
+       if (getsockopt(sock, SOL_SOCKET, SO_TIMESTAMPING, &so_timestamping_get,
+                      &len) < 0) {
                printf("%s: %s\n", "getsockopt SO_TIMESTAMPING",
                       strerror(errno));
        } else {
-               printf("SO_TIMESTAMPING %d\n", val);
-               if (val != so_timestamping_flags)
-                       printf("   not the expected value %d\n",
-                              so_timestamping_flags);
+               printf("SO_TIMESTAMPING flags %d, bind phc %d\n",
+                      so_timestamping_get.flags, so_timestamping_get.bind_phc);
+               if (so_timestamping_get.flags != so_timestamping.flags ||
+                   so_timestamping_get.bind_phc != so_timestamping.bind_phc)
+                       printf("   not expected, flags %d, bind phc %d\n",
+                              so_timestamping.flags, so_timestamping.bind_phc);
        }
 
        /* send packets forever every five seconds */
index cd6430b..8748199 100644 (file)
@@ -5,7 +5,7 @@ TEST_PROGS := nft_trans_stress.sh nft_fib.sh nft_nat.sh bridge_brouter.sh \
        conntrack_icmp_related.sh nft_flowtable.sh ipvs.sh \
        nft_concat_range.sh nft_conntrack_helper.sh \
        nft_queue.sh nft_meta.sh nf_nat_edemux.sh \
-       ipip-conntrack-mtu.sh
+       ipip-conntrack-mtu.sh conntrack_tcp_unreplied.sh
 
 LDLIBS = -lmnl
 TEST_GEN_FILES =  nf-queue
diff --git a/tools/testing/selftests/netfilter/conntrack_tcp_unreplied.sh b/tools/testing/selftests/netfilter/conntrack_tcp_unreplied.sh
new file mode 100755 (executable)
index 0000000..e7d7bf1
--- /dev/null
@@ -0,0 +1,167 @@
+#!/bin/bash
+# SPDX-License-Identifier: GPL-2.0
+#
+# Check that UNREPLIED tcp conntrack will eventually timeout.
+#
+
+# Kselftest framework requirement - SKIP code is 4.
+ksft_skip=4
+ret=0
+
+waittime=20
+sfx=$(mktemp -u "XXXXXXXX")
+ns1="ns1-$sfx"
+ns2="ns2-$sfx"
+
+nft --version > /dev/null 2>&1
+if [ $? -ne 0 ];then
+       echo "SKIP: Could not run test without nft tool"
+       exit $ksft_skip
+fi
+
+ip -Version > /dev/null 2>&1
+if [ $? -ne 0 ];then
+       echo "SKIP: Could not run test without ip tool"
+       exit $ksft_skip
+fi
+
+cleanup() {
+       ip netns pids $ns1 | xargs kill 2>/dev/null
+       ip netns pids $ns2 | xargs kill 2>/dev/null
+
+       ip netns del $ns1
+       ip netns del $ns2
+}
+
+ipv4() {
+    echo -n 192.168.$1.2
+}
+
+check_counter()
+{
+       ns=$1
+       name=$2
+       expect=$3
+       local lret=0
+
+       cnt=$(ip netns exec $ns2 nft list counter inet filter "$name" | grep -q "$expect")
+       if [ $? -ne 0 ]; then
+               echo "ERROR: counter $name in $ns2 has unexpected value (expected $expect)" 1>&2
+               ip netns exec $ns2 nft list counter inet filter "$name" 1>&2
+               lret=1
+       fi
+
+       return $lret
+}
+
+# Create test namespaces
+ip netns add $ns1 || exit 1
+
+trap cleanup EXIT
+
+ip netns add $ns2 || exit 1
+
+# Connect the namespace to the host using a veth pair
+ip -net $ns1 link add name veth1 type veth peer name veth2
+ip -net $ns1 link set netns $ns2 dev veth2
+
+ip -net $ns1 link set up dev lo
+ip -net $ns2 link set up dev lo
+ip -net $ns1 link set up dev veth1
+ip -net $ns2 link set up dev veth2
+
+ip -net $ns2 addr add 10.11.11.2/24 dev veth2
+ip -net $ns2 route add default via 10.11.11.1
+
+ip netns exec $ns2 sysctl -q net.ipv4.conf.veth2.forwarding=1
+
+# add a rule inside NS so we enable conntrack
+ip netns exec $ns1 iptables -A INPUT -m state --state established,related -j ACCEPT
+
+ip -net $ns1 addr add 10.11.11.1/24 dev veth1
+ip -net $ns1 route add 10.99.99.99 via 10.11.11.2
+
+# Check connectivity works
+ip netns exec $ns1 ping -q -c 2 10.11.11.2 >/dev/null || exit 1
+
+ip netns exec $ns2 nc -l -p 8080 < /dev/null &
+
+# however, conntrack entries are there
+
+ip netns exec $ns2 nft -f - <<EOF
+table inet filter {
+       counter connreq { }
+       counter redir { }
+       chain input {
+               type filter hook input priority 0; policy accept;
+               ct state new tcp flags syn ip daddr 10.99.99.99 tcp dport 80 counter name "connreq" accept
+               ct state new ct status dnat tcp dport 8080 counter name "redir" accept
+       }
+}
+EOF
+if [ $? -ne 0 ]; then
+       echo "ERROR: Could not load nft rules"
+       exit 1
+fi
+
+ip netns exec $ns2 sysctl -q net.netfilter.nf_conntrack_tcp_timeout_syn_sent=10
+
+echo "INFO: connect $ns1 -> $ns2 to the virtual ip"
+ip netns exec $ns1 bash -c 'while true ; do
+       nc -p 60000 10.99.99.99 80
+       sleep 1
+       done' &
+
+sleep 1
+
+ip netns exec $ns2 nft -f - <<EOF
+table inet nat {
+       chain prerouting {
+               type nat hook prerouting priority 0; policy accept;
+               ip daddr 10.99.99.99 tcp dport 80 redirect to :8080
+       }
+}
+EOF
+if [ $? -ne 0 ]; then
+       echo "ERROR: Could not load nat redirect"
+       exit 1
+fi
+
+count=$(ip netns exec $ns2 conntrack -L -p tcp --dport 80 2>/dev/null | wc -l)
+if [ $count -eq 0 ]; then
+       echo "ERROR: $ns2 did not pick up tcp connection from peer"
+       exit 1
+fi
+
+echo "INFO: NAT redirect added in ns $ns2, waiting for $waittime seconds for nat to take effect"
+for i in $(seq 1 $waittime); do
+       echo -n "."
+
+       sleep 1
+
+       count=$(ip netns exec $ns2 conntrack -L -p tcp --reply-port-src 8080 2>/dev/null | wc -l)
+       if [ $count -gt 0 ]; then
+               echo
+               echo "PASS: redirection took effect after $i seconds"
+               break
+       fi
+
+       m=$((i%20))
+       if [ $m -eq 0 ]; then
+               echo " waited for $i seconds"
+       fi
+done
+
+expect="packets 1 bytes 60"
+check_counter "$ns2" "redir" "$expect"
+if [ $? -ne 0 ]; then
+       ret=1
+fi
+
+if [ $ret -eq 0 ];then
+       echo "PASS: redirection counter has expected values"
+else
+       echo "ERROR: no tcp connection was redirected"
+fi
+
+exit $ret
index f08f5e8..0be80c2 100644 (file)
@@ -186,7 +186,6 @@ int kvm_vm_ioctl_unregister_coalesced_mmio(struct kvm *kvm,
                    coalesced_mmio_in_range(dev, zone->addr, zone->size)) {
                        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
@@ -196,6 +195,7 @@ int kvm_vm_ioctl_unregister_coalesced_mmio(struct kvm *kvm,
                         */
                        if (r)
                                break;
+                       kvm_iodevice_destructor(&dev->dev);
                }
        }
 
index 7d95126..9869598 100644 (file)
@@ -935,7 +935,7 @@ static int kvm_create_vm_debugfs(struct kvm *kvm, int fd)
                stat_data->kvm = kvm;
                stat_data->desc = pdesc;
                stat_data->kind = KVM_STAT_VCPU;
-               kvm->debugfs_stat_data[i] = stat_data;
+               kvm->debugfs_stat_data[i + kvm_vm_stats_header.num_desc] = stat_data;
                debugfs_create_file(pdesc->name, kvm_stats_debugfs_mode(pdesc),
                                    kvm->debugfs_dentry, stat_data,
                                    &stat_fops_per_vm);