Merge tag 'objtool_urgent_for_v5.15_rc6' of git://git.kernel.org/pub/scm/linux/kernel...
authorLinus Torvalds <torvalds@linux-foundation.org>
Mon, 18 Oct 2021 03:41:39 +0000 (17:41 -1000)
committerLinus Torvalds <torvalds@linux-foundation.org>
Mon, 18 Oct 2021 03:41:39 +0000 (17:41 -1000)
Pull objtool fixes from Borislav Petkov:

 - Update section headers before the respective relocations to not
   trigger a safety check in elftoolchain's implementation of libelf

 - Do not add garbage data to the .rela.orc_unwind_ip section

* tag 'objtool_urgent_for_v5.15_rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  objtool: Update section header before relocations
  objtool: Check for gelf_update_rel[a] failures

621 files changed:
CREDITS
Documentation/admin-guide/cgroup-v2.rst
Documentation/admin-guide/kernel-parameters.txt
Documentation/devicetree/bindings/display/bridge/ti,sn65dsi83.yaml
Documentation/devicetree/bindings/display/bridge/ti,sn65dsi86.yaml
Documentation/devicetree/bindings/display/panel/ilitek,ili9341.yaml
Documentation/devicetree/bindings/media/i2c/ovti,ov5647.yaml
Documentation/devicetree/bindings/media/i2c/ovti,ov9282.yaml
Documentation/devicetree/bindings/media/i2c/sony,imx335.yaml
Documentation/devicetree/bindings/media/i2c/sony,imx412.yaml
Documentation/devicetree/bindings/mmc/snps,dwcmshc-sdhci.yaml
Documentation/devicetree/bindings/net/dsa/marvell.txt
Documentation/devicetree/bindings/net/nxp,dwmac-imx.yaml
Documentation/devicetree/bindings/net/snps,dwmac.yaml
Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.yaml
Documentation/devicetree/bindings/spi/snps,dw-apb-ssi.yaml
Documentation/filesystems/ntfs3.rst
Documentation/gpu/amdgpu.rst
Documentation/gpu/drm-internals.rst
MAINTAINERS
Makefile
arch/arc/include/asm/pgtable.h
arch/arm/Kconfig
arch/arm/boot/dts/at91-sama5d27_som1_ek.dts
arch/arm/boot/dts/at91-sama7g5ek.dts
arch/arm/boot/dts/bcm2711-rpi-4-b.dts
arch/arm/boot/dts/bcm2711.dtsi
arch/arm/boot/dts/bcm2835-common.dtsi
arch/arm/boot/dts/bcm283x.dtsi
arch/arm/boot/dts/imx53-m53menlo.dts
arch/arm/boot/dts/imx6dl-yapp4-common.dtsi
arch/arm/boot/dts/imx6qdl-pico.dtsi
arch/arm/boot/dts/imx6sx-sdb.dts
arch/arm/boot/dts/imx6ul-14x14-evk.dtsi
arch/arm/boot/dts/omap3430-sdp.dts
arch/arm/boot/dts/qcom-apq8064.dtsi
arch/arm/boot/dts/sama7g5.dtsi
arch/arm/boot/dts/spear3xx.dtsi
arch/arm/boot/dts/vexpress-v2m-rs1.dtsi
arch/arm/boot/dts/vexpress-v2m.dtsi
arch/arm/boot/dts/vexpress-v2p-ca15-tc1.dts
arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts
arch/arm/boot/dts/vexpress-v2p-ca5s.dts
arch/arm/boot/dts/vexpress-v2p-ca9.dts
arch/arm/common/sharpsl_param.c
arch/arm/configs/gemini_defconfig
arch/arm/configs/imx_v6_v7_defconfig
arch/arm/configs/multi_v7_defconfig
arch/arm/configs/oxnas_v6_defconfig
arch/arm/configs/shmobile_defconfig
arch/arm/mach-at91/pm.c
arch/arm/mach-at91/pm_suspend.S
arch/arm/mach-dove/include/mach/uncompress.h
arch/arm/mach-imx/mach-imx6q.c
arch/arm/mach-imx/pm-imx6.c
arch/arm/mach-imx/src.c
arch/arm/mach-omap1/include/mach/memory.h
arch/arm/mach-omap1/usb.c
arch/arm/mach-omap2/Kconfig
arch/arm/mach-omap2/omap_hwmod.c
arch/arm/net/bpf_jit_32.c
arch/arm64/Kconfig
arch/arm64/boot/dts/arm/foundation-v8.dtsi
arch/arm64/boot/dts/arm/fvp-base-revc.dts
arch/arm64/boot/dts/arm/juno-base.dtsi
arch/arm64/boot/dts/arm/juno-motherboard.dtsi
arch/arm64/boot/dts/arm/rtsm_ve-aemv8a.dts
arch/arm64/boot/dts/arm/rtsm_ve-motherboard-rs2.dtsi
arch/arm64/boot/dts/arm/rtsm_ve-motherboard.dtsi
arch/arm64/boot/dts/arm/vexpress-v2f-1xv7-ca53x2.dts
arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi
arch/arm64/boot/dts/freescale/imx8mm-beacon-som.dtsi
arch/arm64/boot/dts/freescale/imx8mm-evk.dts
arch/arm64/boot/dts/freescale/imx8mm-kontron-n801x-som.dtsi
arch/arm64/boot/dts/freescale/imx8mm-venice-gw7902.dts
arch/arm64/boot/dts/freescale/imx8mn-beacon-som.dtsi
arch/arm64/boot/dts/freescale/imx8mn-venice-gw7902.dts
arch/arm64/boot/dts/freescale/imx8mp-phycore-som.dtsi
arch/arm64/boot/dts/freescale/imx8mq-evk.dts
arch/arm64/boot/dts/freescale/imx8mq-kontron-pitx-imx8m.dts
arch/arm64/boot/dts/qcom/pm8150.dtsi
arch/arm64/boot/dts/qcom/qrb5165-rb5.dts
arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi
arch/arm64/boot/dts/qcom/sc7280.dtsi
arch/arm64/boot/dts/qcom/sdm630.dtsi
arch/arm64/boot/dts/qcom/sdm845.dtsi
arch/arm64/boot/dts/qcom/sdm850-lenovo-yoga-c630.dts
arch/arm64/configs/defconfig
arch/arm64/mm/hugetlbpage.c
arch/csky/Kconfig
arch/csky/include/asm/bitops.h
arch/csky/kernel/ptrace.c
arch/csky/kernel/signal.c
arch/ia64/Kconfig
arch/mips/Kconfig
arch/mips/include/asm/mips-cps.h
arch/parisc/Kconfig
arch/powerpc/boot/dts/fsl/t1023rdb.dts
arch/powerpc/include/asm/book3s/32/kup.h
arch/powerpc/include/asm/code-patching.h
arch/powerpc/include/asm/interrupt.h
arch/powerpc/include/asm/security_features.h
arch/powerpc/kernel/dma-iommu.c
arch/powerpc/kernel/exceptions-64s.S
arch/powerpc/kernel/irq.c
arch/powerpc/kernel/security.c
arch/powerpc/kernel/traps.c
arch/powerpc/lib/code-patching.c
arch/powerpc/net/bpf_jit.h
arch/powerpc/net/bpf_jit64.h
arch/powerpc/net/bpf_jit_comp.c
arch/powerpc/net/bpf_jit_comp32.c
arch/powerpc/net/bpf_jit_comp64.c
arch/powerpc/platforms/pseries/eeh_pseries.c
arch/powerpc/platforms/pseries/msi.c
arch/riscv/Kconfig
arch/riscv/include/asm/syscall.h
arch/riscv/include/asm/vdso.h
arch/riscv/include/uapi/asm/unistd.h
arch/riscv/kernel/syscall_table.c
arch/riscv/kernel/vdso.c
arch/riscv/kernel/vdso/vdso.lds.S
arch/riscv/mm/cacheflush.c
arch/s390/include/asm/pci.h
arch/s390/lib/string.c
arch/s390/net/bpf_jit_comp.c
arch/s390/pci/pci.c
arch/s390/pci/pci_event.c
arch/x86/Kconfig
arch/x86/events/msr.c
arch/x86/hyperv/hv_apic.c
arch/x86/include/asm/entry-common.h
arch/x86/include/asm/xen/pci.h
arch/x86/kernel/cpu/common.c
arch/x86/kernel/cpu/resctrl/core.c
arch/x86/kernel/early-quirks.c
arch/x86/kernel/fpu/signal.c
arch/x86/kernel/hpet.c
arch/x86/kernel/sev-shared.c
arch/x86/pci/xen.c
arch/x86/platform/olpc/olpc.c
arch/x86/platform/pvh/enlighten.c
arch/x86/xen/Kconfig
arch/x86/xen/Makefile
arch/x86/xen/enlighten.c
arch/x86/xen/enlighten_pv.c
arch/x86/xen/enlighten_pvh.c
arch/x86/xen/mmu_pv.c
arch/x86/xen/xen-ops.h
arch/xtensa/include/asm/kmem_layout.h
arch/xtensa/kernel/irq.c
arch/xtensa/kernel/setup.c
arch/xtensa/mm/mmu.c
arch/xtensa/platforms/xtfpga/setup.c
block/bdev.c
block/blk-mq-debugfs.c
block/genhd.c
drivers/Kconfig
drivers/acpi/arm64/gtdt.c
drivers/acpi/x86/s2idle.c
drivers/base/core.c
drivers/base/test/Makefile
drivers/bus/Kconfig
drivers/bus/Makefile
drivers/bus/simple-pm-bus.c
drivers/bus/ti-sysc.c
drivers/clk/qcom/Kconfig
drivers/clk/qcom/gcc-sm6115.c
drivers/clk/renesas/r9a07g044-cpg.c
drivers/clk/renesas/rzg2l-cpg.c
drivers/clk/socfpga/clk-agilex.c
drivers/edac/armada_xp_edac.c
drivers/firmware/Kconfig
drivers/firmware/arm_ffa/bus.c
drivers/firmware/arm_scmi/Kconfig
drivers/firmware/arm_scmi/virtio.c
drivers/firmware/efi/cper.c
drivers/firmware/efi/libstub/fdt.c
drivers/firmware/efi/runtime-wrappers.c
drivers/fpga/ice40-spi.c
drivers/gpio/gpio-74x164.c
drivers/gpio/gpio-mockup.c
drivers/gpio/gpio-pca953x.c
drivers/gpu/drm/amd/amdgpu/amdgpu.h
drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c
drivers/gpu/drm/amd/amdkfd/kfd_device.c
drivers/gpu/drm/amd/display/Kconfig
drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.h
drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dio_link_encoder.c
drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dio_link_encoder.h
drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c
drivers/gpu/drm/amd/display/include/dal_asic_id.h
drivers/gpu/drm/amd/include/asic_reg/dpcs/dpcs_4_2_0_offset.h
drivers/gpu/drm/drm_edid.c
drivers/gpu/drm/drm_fb_helper.c
drivers/gpu/drm/hyperv/hyperv_drm.h
drivers/gpu/drm/hyperv/hyperv_drm_modeset.c
drivers/gpu/drm/hyperv/hyperv_drm_proto.c
drivers/gpu/drm/i915/display/icl_dsi.c
drivers/gpu/drm/i915/display/intel_acpi.c
drivers/gpu/drm/i915/display/intel_audio.c
drivers/gpu/drm/i915/display/intel_bios.c
drivers/gpu/drm/i915/display/intel_ddi.c
drivers/gpu/drm/i915/display/intel_display.c
drivers/gpu/drm/i915/display/intel_vbt_defs.h
drivers/gpu/drm/i915/gem/i915_gem_context.c
drivers/gpu/drm/i915/gem/i915_gem_shrinker.c
drivers/gpu/drm/i915/gt/intel_context.c
drivers/gpu/drm/i915/i915_reg.h
drivers/gpu/drm/i915/intel_pm.c
drivers/gpu/drm/kmb/kmb_drv.c
drivers/gpu/drm/kmb/kmb_drv.h
drivers/gpu/drm/kmb/kmb_plane.c
drivers/gpu/drm/kmb/kmb_plane.h
drivers/gpu/drm/kmb/kmb_regs.h
drivers/gpu/drm/mediatek/mtk_drm_crtc.c
drivers/gpu/drm/msm/Kconfig
drivers/gpu/drm/msm/adreno/a3xx_gpu.c
drivers/gpu/drm/msm/adreno/a4xx_gpu.c
drivers/gpu/drm/msm/adreno/a6xx_gmu.c
drivers/gpu/drm/msm/adreno/a6xx_gmu.h
drivers/gpu/drm/msm/adreno/a6xx_gpu.c
drivers/gpu/drm/msm/adreno/a6xx_gpu.h
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c
drivers/gpu/drm/msm/dp/dp_display.c
drivers/gpu/drm/msm/dsi/dsi.c
drivers/gpu/drm/msm/dsi/dsi_host.c
drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c
drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm_8960.c
drivers/gpu/drm/msm/edp/edp_ctrl.c
drivers/gpu/drm/msm/msm_drv.c
drivers/gpu/drm/msm/msm_drv.h
drivers/gpu/drm/msm/msm_gem_submit.c
drivers/gpu/drm/msm/msm_gpu.h
drivers/gpu/drm/msm/msm_gpu_devfreq.c
drivers/gpu/drm/msm/msm_submitqueue.c
drivers/gpu/drm/nouveau/dispnv50/crc.c
drivers/gpu/drm/nouveau/dispnv50/head.c
drivers/gpu/drm/nouveau/include/nvif/class.h
drivers/gpu/drm/nouveau/include/nvkm/engine/fifo.h
drivers/gpu/drm/nouveau/nouveau_bo.c
drivers/gpu/drm/nouveau/nouveau_chan.c
drivers/gpu/drm/nouveau/nouveau_debugfs.c
drivers/gpu/drm/nouveau/nouveau_drm.c
drivers/gpu/drm/nouveau/nouveau_gem.c
drivers/gpu/drm/nouveau/nv84_fence.c
drivers/gpu/drm/nouveau/nvkm/engine/device/base.c
drivers/gpu/drm/nouveau/nvkm/engine/fifo/Kbuild
drivers/gpu/drm/nouveau/nvkm/engine/fifo/chang84.c
drivers/gpu/drm/nouveau/nvkm/engine/fifo/ga102.c [new file with mode: 0644]
drivers/gpu/drm/nouveau/nvkm/subdev/top/ga100.c
drivers/gpu/drm/panel/Kconfig
drivers/gpu/drm/panel/panel-abt-y030xx067a.c
drivers/gpu/drm/r128/ati_pcigart.c
drivers/gpu/drm/rcar-du/rcar_du_encoder.c
drivers/gpu/drm/rcar-du/rcar_lvds.c
drivers/gpu/drm/rcar-du/rcar_lvds.h
drivers/gpu/drm/rockchip/rockchip_drm_vop.c
drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c
drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h
drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c
drivers/gpu/drm/vc4/vc4_hdmi.c
drivers/i2c/busses/i2c-mlxcpld.c
drivers/i2c/busses/i2c-mt65xx.c
drivers/i2c/i2c-core-acpi.c
drivers/iio/accel/fxls8962af-core.c
drivers/iio/adc/ad7192.c
drivers/iio/adc/ad7780.c
drivers/iio/adc/ad7793.c
drivers/iio/adc/aspeed_adc.c
drivers/iio/adc/max1027.c
drivers/iio/adc/mt6577_auxadc.c
drivers/iio/adc/rzg2l_adc.c
drivers/iio/adc/ti-adc128s052.c
drivers/iio/common/ssp_sensors/ssp_spi.c
drivers/iio/dac/ti-dac5571.c
drivers/iio/imu/adis16475.c
drivers/iio/imu/adis16480.c
drivers/iio/light/opt3001.c
drivers/iio/test/Makefile
drivers/input/joystick/xpad.c
drivers/input/keyboard/snvs_pwrkey.c
drivers/input/touchscreen.c
drivers/input/touchscreen/resistive-adc-touch.c
drivers/iommu/Kconfig
drivers/iommu/arm/arm-smmu/Makefile
drivers/iommu/arm/arm-smmu/arm-smmu-impl.c
drivers/isdn/capi/kcapi.c
drivers/isdn/hardware/mISDN/netjet.c
drivers/md/dm-clone-target.c
drivers/md/dm-rq.c
drivers/md/dm-verity-target.c
drivers/md/dm.c
drivers/media/platform/Kconfig
drivers/misc/Kconfig
drivers/misc/cb710/sgbuf2.c
drivers/misc/eeprom/at25.c
drivers/misc/eeprom/eeprom_93xx46.c
drivers/misc/fastrpc.c
drivers/misc/gehc-achc.c
drivers/misc/habanalabs/common/command_submission.c
drivers/misc/mei/hbm.c
drivers/misc/mei/hw-me-regs.h
drivers/misc/mei/pci-me.c
drivers/mmc/host/Kconfig
drivers/mmc/host/meson-gx-mmc.c
drivers/mmc/host/sdhci-of-at91.c
drivers/mtd/nand/raw/qcom_nandc.c
drivers/net/dsa/microchip/ksz_common.c
drivers/net/dsa/mv88e6xxx/chip.c
drivers/net/dsa/mv88e6xxx/chip.h
drivers/net/dsa/mv88e6xxx/port.c
drivers/net/dsa/mv88e6xxx/port.h
drivers/net/dsa/ocelot/felix.c
drivers/net/dsa/ocelot/felix.h
drivers/net/dsa/sja1105/sja1105_main.c
drivers/net/dsa/sja1105/sja1105_ptp.c
drivers/net/dsa/sja1105/sja1105_ptp.h
drivers/net/ethernet/Kconfig
drivers/net/ethernet/arc/Kconfig
drivers/net/ethernet/google/gve/gve.h
drivers/net/ethernet/google/gve/gve_main.c
drivers/net/ethernet/google/gve/gve_rx.c
drivers/net/ethernet/intel/i40e/i40e_main.c
drivers/net/ethernet/intel/iavf/iavf_main.c
drivers/net/ethernet/intel/ice/ice_ptp.c
drivers/net/ethernet/mellanox/mlx5/core/cq.c
drivers/net/ethernet/mellanox/mlx5/core/en.h
drivers/net/ethernet/mellanox/mlx5/core/en/hv_vhca_stats.c
drivers/net/ethernet/mellanox/mlx5/core/en/ptp.c
drivers/net/ethernet/mellanox/mlx5/core/en/ptp.h
drivers/net/ethernet/mellanox/mlx5/core/en/rep/bridge.c
drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c
drivers/net/ethernet/mellanox/mlx5/core/en_main.c
drivers/net/ethernet/mellanox/mlx5/core/en_rep.c
drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
drivers/net/ethernet/mellanox/mlx5/core/en_stats.c
drivers/net/ethernet/mellanox/mlx5/core/esw/acl/egress_lgcy.c
drivers/net/ethernet/mellanox/mlx5/core/esw/acl/ingress_lgcy.c
drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib.c
drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c
drivers/net/ethernet/mellanox/mlx5/core/pci_irq.c
drivers/net/ethernet/mellanox/mlxsw/core_thermal.c
drivers/net/ethernet/microchip/encx24j600-regmap.c
drivers/net/ethernet/microchip/encx24j600.c
drivers/net/ethernet/microchip/encx24j600_hw.h
drivers/net/ethernet/microsoft/mana/mana_en.c
drivers/net/ethernet/mscc/ocelot.c
drivers/net/ethernet/mscc/ocelot_net.c
drivers/net/ethernet/mscc/ocelot_vcap.c
drivers/net/ethernet/neterion/s2io.c
drivers/net/ethernet/netronome/nfp/flower/main.c
drivers/net/ethernet/pensando/ionic/ionic_lif.c
drivers/net/ethernet/pensando/ionic/ionic_rx_filter.c
drivers/net/ethernet/qlogic/qed/qed_main.c
drivers/net/ethernet/stmicro/stmmac/dwmac-generic.c
drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c
drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c
drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c
drivers/net/ethernet/stmicro/stmmac/hwif.h
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
drivers/net/ipa/Kconfig
drivers/net/pcs/pcs-xpcs.c
drivers/net/phy/mdio_bus.c
drivers/net/phy/phy_device.c
drivers/net/phy/sfp.c
drivers/net/usb/Kconfig
drivers/net/usb/r8152.c
drivers/net/virtio_net.c
drivers/net/wireless/ath/ath10k/Kconfig
drivers/net/wireless/ath/ath5k/Kconfig
drivers/net/wireless/ath/ath5k/led.c
drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
drivers/net/wireless/intel/iwlwifi/mvm/d3.c
drivers/net/wireless/intel/iwlwifi/mvm/time-event.c
drivers/net/wireless/intel/iwlwifi/pcie/drv.c
drivers/net/wireless/marvell/mwifiex/sta_tx.c
drivers/net/wireless/marvell/mwifiex/uap_txrx.c
drivers/nvmem/core.c
drivers/of/base.c
drivers/pci/controller/pci-hyperv.c
drivers/pci/hotplug/s390_pci_hpc.c
drivers/pci/msi.c
drivers/pci/pci-acpi.c
drivers/pinctrl/qcom/Kconfig
drivers/platform/mellanox/mlxreg-io.c
drivers/platform/x86/amd-pmc.c
drivers/platform/x86/dell/Kconfig
drivers/platform/x86/gigabyte-wmi.c
drivers/platform/x86/intel/int1092/intel_sar.c
drivers/platform/x86/intel/int3472/intel_skl_int3472_discrete.c
drivers/platform/x86/intel_scu_ipc.c
drivers/ptp/ptp_pch.c
drivers/scsi/arm/acornscsi.c
drivers/scsi/elx/efct/efct_scsi.c
drivers/scsi/libiscsi.c
drivers/scsi/lpfc/lpfc_sli.c
drivers/scsi/ufs/ufshcd.c
drivers/scsi/ufs/ufshcd.h
drivers/soc/canaan/Kconfig
drivers/soc/qcom/mdt_loader.c
drivers/soc/qcom/socinfo.c
drivers/soc/ti/omap_prm.c
drivers/spi/spi-atmel.c
drivers/spi/spi-bcm-qspi.c
drivers/spi/spi-mt65xx.c
drivers/spi/spi-mux.c
drivers/spi/spi-nxp-fspi.c
drivers/spi/spi-tegra20-slink.c
drivers/spi/spi.c
drivers/spi/spidev.c
drivers/staging/media/atomisp/pci/hive_isp_css_common/host/input_system.c
drivers/staging/r8188eu/hal/hal_intf.c
drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c
drivers/tee/optee/core.c
drivers/tee/optee/device.c
drivers/tee/optee/optee_private.h
drivers/tee/optee/shm_pool.c
drivers/thunderbolt/Makefile
drivers/tty/hvc/hvc_xen.c
drivers/tty/serial/8250/Kconfig
drivers/usb/chipidea/ci_hdrc_imx.c
drivers/usb/class/cdc-acm.c
drivers/usb/class/cdc-wdm.c
drivers/usb/common/Kconfig
drivers/usb/dwc3/gadget.c
drivers/usb/gadget/function/f_uac2.c
drivers/usb/host/ohci-omap.c
drivers/usb/host/xhci-dbgtty.c
drivers/usb/host/xhci-pci.c
drivers/usb/host/xhci-ring.c
drivers/usb/host/xhci-tegra.c
drivers/usb/host/xhci.c
drivers/usb/host/xhci.h
drivers/usb/musb/musb_dsps.c
drivers/usb/serial/option.c
drivers/usb/serial/qcserial.c
drivers/usb/typec/tcpm/tcpci.c
drivers/usb/typec/tcpm/tcpm.c
drivers/usb/typec/tipd/core.c
drivers/video/fbdev/Kconfig
drivers/video/fbdev/gbefb.c
drivers/xen/Kconfig
drivers/xen/balloon.c
drivers/xen/privcmd.c
fs/9p/cache.c
fs/9p/fid.c
fs/9p/v9fs.c
fs/9p/vfs_addr.c
fs/9p/vfs_file.c
fs/9p/vfs_inode.c
fs/9p/vfs_inode_dotl.c
fs/afs/dir_silly.c
fs/afs/write.c
fs/btrfs/ctree.h
fs/btrfs/dir-item.c
fs/btrfs/extent-tree.c
fs/btrfs/file.c
fs/btrfs/tree-log.c
fs/fscache/object.c
fs/fscache/operation.c
fs/kernfs/dir.c
fs/ksmbd/connection.c
fs/ksmbd/glob.h
fs/ksmbd/smb2misc.c
fs/ksmbd/smb2ops.c
fs/ksmbd/smb2pdu.c
fs/ksmbd/smb2pdu.h
fs/ksmbd/smb_common.c
fs/ksmbd/smb_common.h
fs/netfs/read_helper.c
fs/nfs_common/grace.c
fs/nfsd/filecache.c
fs/nfsd/nfs4xdr.c
fs/nfsd/nfsctl.c
fs/ntfs3/attrib.c
fs/ntfs3/attrlist.c
fs/ntfs3/bitfunc.c
fs/ntfs3/bitmap.c
fs/ntfs3/debug.h
fs/ntfs3/dir.c
fs/ntfs3/file.c
fs/ntfs3/frecord.c
fs/ntfs3/fslog.c
fs/ntfs3/fsntfs.c
fs/ntfs3/index.c
fs/ntfs3/inode.c
fs/ntfs3/lib/decompress_common.h
fs/ntfs3/lib/lib.h
fs/ntfs3/lznt.c
fs/ntfs3/namei.c
fs/ntfs3/ntfs.h
fs/ntfs3/ntfs_fs.h
fs/ntfs3/record.c
fs/ntfs3/run.c
fs/ntfs3/super.c
fs/ntfs3/upcase.c
fs/ntfs3/xattr.c
fs/overlayfs/dir.c
fs/overlayfs/file.c
include/asm-generic/io.h
include/kunit/test.h
include/linux/arm-smccc.h
include/linux/dsa/mv88e6xxx.h [new file with mode: 0644]
include/linux/dsa/ocelot.h
include/linux/dsa/sja1105.h
include/linux/etherdevice.h
include/linux/mlx5/mlx5_ifc.h
include/linux/platform_data/usb-omap1.h
include/linux/qcom_scm.h
include/linux/spi/spi.h
include/linux/workqueue.h
include/net/netfilter/ipv6/nf_defrag_ipv6.h
include/net/netfilter/nf_tables.h
include/net/netns/netfilter.h
include/net/sock.h
include/soc/mscc/ocelot.h
include/soc/mscc/ocelot_ptp.h
include/soc/mscc/ocelot_vcap.h
include/sound/hda_codec.h
include/trace/events/cachefiles.h
include/uapi/linux/hyperv.h
include/uapi/linux/xfrm.h
include/uapi/misc/habanalabs.h
include/xen/xen-ops.h
init/main.c
kernel/bpf/stackmap.c
kernel/cgroup/cpuset.c
kernel/module.c
kernel/trace/trace.c
kernel/trace/trace_eprobe.c
kernel/trace/trace_events_hist.c
kernel/workqueue.c
lib/Makefile
lib/kunit/executor_test.c
mm/memblock.c
net/bridge/br_netlink.c
net/core/net-procfs.c
net/core/rtnetlink.c
net/dsa/Kconfig
net/dsa/dsa2.c
net/dsa/switch.c
net/dsa/tag_dsa.c
net/dsa/tag_ocelot.c
net/dsa/tag_ocelot_8021q.c
net/dsa/tag_sja1105.c
net/ipv4/icmp.c
net/ipv4/inet_hashtables.c
net/ipv4/netfilter/nf_defrag_ipv4.c
net/ipv4/udp.c
net/ipv6/inet6_hashtables.c
net/ipv6/ioam6.c
net/ipv6/ioam6_iptunnel.c
net/ipv6/netfilter/nf_conntrack_reasm.c
net/ipv6/netfilter/nf_defrag_ipv6_hooks.c
net/ipv6/udp.c
net/mptcp/protocol.c
net/netfilter/nf_tables_api.c
net/netfilter/nft_quota.c
net/netlink/af_netlink.c
net/nfc/af_nfc.c
net/nfc/digital_core.c
net/nfc/digital_technology.c
net/nfc/nci/rsp.c
net/sched/sch_fifo.c
net/sched/sch_mqprio.c
net/sched/sch_taprio.c
net/sctp/sm_make_chunk.c
net/smc/smc_cdc.c
net/smc/smc_core.c
net/smc/smc_llc.c
net/smc/smc_tx.c
net/smc/smc_wr.h
net/sunrpc/auth_gss/svcauth_gss.c
net/unix/af_unix.c
net/xfrm/xfrm_user.c
samples/bpf/Makefile
samples/bpf/bpf_insn.h
samples/bpf/xdp_redirect_map_multi.bpf.c
scripts/Makefile.gcc-plugins
scripts/checksyscalls.sh
scripts/recordmcount.pl
security/selinux/nlmsgtab.c
sound/core/pcm_compat.c
sound/core/seq_device.c
sound/hda/hdac_controller.c
sound/pci/hda/hda_bind.c
sound/pci/hda/hda_codec.c
sound/pci/hda/hda_controller.c
sound/pci/hda/hda_controller.h
sound/pci/hda/hda_intel.c
sound/pci/hda/hda_intel.h
sound/pci/hda/patch_realtek.c
sound/usb/mixer_scarlett_gen2.c
sound/usb/quirks-table.h
sound/usb/quirks.c
tools/include/uapi/sound/asound.h
tools/lib/bpf/libbpf.c
tools/lib/bpf/strset.c
tools/lib/perf/tests/test-evlist.c
tools/lib/perf/tests/test-evsel.c
tools/perf/Makefile.config
tools/perf/Makefile.perf
tools/perf/pmu-events/jevents.c
tools/perf/tests/attr/test-stat-default
tools/perf/tests/attr/test-stat-detailed-1
tools/perf/tests/attr/test-stat-detailed-2
tools/perf/tests/attr/test-stat-detailed-3
tools/perf/util/session.c
tools/testing/kunit/kunit.py
tools/testing/kunit/kunit_tool_test.py
tools/testing/selftests/drivers/dma-buf/udmabuf.c
tools/testing/selftests/ftrace/test.d/dynevent/add_remove_eprobe.tc
tools/testing/selftests/net/ioam6.sh
tools/testing/selftests/net/ioam6_parser.c

diff --git a/CREDITS b/CREDITS
index 7ef7b13..d8f63e8 100644 (file)
--- a/CREDITS
+++ b/CREDITS
@@ -971,6 +971,7 @@ D: PowerPC
 N: Daniel Drake
 E: dsd@gentoo.org
 D: USBAT02 CompactFlash support in usb-storage
+D: ZD1211RW wireless driver
 S: UK
 
 N: Oleg Drokin
index babbe04..4d8c27e 100644 (file)
@@ -1226,7 +1226,7 @@ PAGE_SIZE multiple when read back.
 
        Note that all fields in this file are hierarchical and the
        file modified event can be generated due to an event down the
-       hierarchy. For for the local events at the cgroup level see
+       hierarchy. For the local events at the cgroup level see
        memory.events.local.
 
          low
@@ -2170,19 +2170,19 @@ existing device files.
 
 Cgroup v2 device controller has no interface files and is implemented
 on top of cgroup BPF. To control access to device files, a user may
-create bpf programs of the BPF_CGROUP_DEVICE type and attach them
-to cgroups. On an attempt to access a device file, corresponding
-BPF programs will be executed, and depending on the return value
-the attempt will succeed or fail with -EPERM.
-
-A BPF_CGROUP_DEVICE program takes a pointer to the bpf_cgroup_dev_ctx
-structure, which describes the device access attempt: access type
-(mknod/read/write) and device (type, major and minor numbers).
-If the program returns 0, the attempt fails with -EPERM, otherwise
-it succeeds.
-
-An example of BPF_CGROUP_DEVICE program may be found in the kernel
-source tree in the tools/testing/selftests/bpf/progs/dev_cgroup.c file.
+create bpf programs of type BPF_PROG_TYPE_CGROUP_DEVICE and attach
+them to cgroups with BPF_CGROUP_DEVICE flag. On an attempt to access a
+device file, corresponding BPF programs will be executed, and depending
+on the return value the attempt will succeed or fail with -EPERM.
+
+A BPF_PROG_TYPE_CGROUP_DEVICE program takes a pointer to the
+bpf_cgroup_dev_ctx structure, which describes the device access attempt:
+access type (mknod/read/write) and device (type, major and minor numbers).
+If the program returns 0, the attempt fails with -EPERM, otherwise it
+succeeds.
+
+An example of BPF_PROG_TYPE_CGROUP_DEVICE program may be found in
+tools/testing/selftests/bpf/progs/dev_cgroup.c in the kernel source tree.
 
 
 RDMA
index 91ba391..43dc35f 100644 (file)
                        The VGA and EFI output is eventually overwritten by
                        the real console.
 
-                       The xen output can only be used by Xen PV guests.
+                       The xen option can only be used in Xen domains.
 
                        The sclp output can only be used on s390.
 
index 07b2038..b446d0f 100644 (file)
@@ -50,7 +50,6 @@ properties:
               data-lanes:
                 description: array of physical DSI data lane indexes.
                 minItems: 1
-                maxItems: 4
                 items:
                   - const: 1
                   - const: 2
@@ -71,7 +70,6 @@ properties:
               data-lanes:
                 description: array of physical DSI data lane indexes.
                 minItems: 1
-                maxItems: 4
                 items:
                   - const: 1
                   - const: 2
index 1c2daf7..9115644 100644 (file)
@@ -18,7 +18,7 @@ properties:
     const: ti,sn65dsi86
 
   reg:
-    const: 0x2d
+    enum: [ 0x2c, 0x2d ]
 
   enable-gpios:
     maxItems: 1
index 2ed010f..20ce88a 100644 (file)
@@ -22,7 +22,7 @@ properties:
     items:
       - enum:
           # ili9341 240*320 Color on stm32f429-disco board
-        - st,sf-tc240t-9370-t
+          - st,sf-tc240t-9370-t
       - const: ilitek,ili9341
 
   reg: true
index 3e5d82d..a2abed0 100644 (file)
@@ -31,7 +31,7 @@ properties:
     maxItems: 1
 
   port:
-    $ref: /schemas/graph.yaml#/properties/port
+    $ref: /schemas/graph.yaml#/$defs/port-base
     additionalProperties: false
 
     properties:
index ad42992..bf115ab 100644 (file)
@@ -38,7 +38,7 @@ properties:
 
   port:
     additionalProperties: false
-    $ref: /schemas/graph.yaml#/properties/port
+    $ref: /schemas/graph.yaml#/$defs/port-base
 
     properties:
       endpoint:
index 881f795..cf2ca27 100644 (file)
@@ -38,7 +38,7 @@ properties:
 
   port:
     additionalProperties: false
-    $ref: /schemas/graph.yaml#/properties/port
+    $ref: /schemas/graph.yaml#/$defs/port-base
 
     properties:
       endpoint:
index 1edeabf..afcf709 100644 (file)
@@ -38,7 +38,7 @@ properties:
 
   port:
     additionalProperties: false
-    $ref: /schemas/graph.yaml#/properties/port
+    $ref: /schemas/graph.yaml#/$defs/port-base
 
     properties:
       endpoint:
index e6c9a2f..f300ced 100644 (file)
@@ -20,9 +20,7 @@ properties:
       - snps,dwcmshc-sdhci
 
   reg:
-    minItems: 1
-    items:
-      - description: Offset and length of the register set for the device
+    maxItems: 1
 
   interrupts:
     maxItems: 1
index 30c11fe..2363b41 100644 (file)
@@ -83,7 +83,7 @@ Example:
                #interrupt-cells = <2>;
 
                switch0: switch@0 {
-                       compatible = "marvell,mv88e6390";
+                       compatible = "marvell,mv88e6190";
                        reg = <0>;
                        reset-gpios = <&gpio5 1 GPIO_ACTIVE_LOW>;
 
index 5629b2e..ee4afe3 100644 (file)
@@ -34,7 +34,6 @@ properties:
 
   clocks:
     minItems: 3
-    maxItems: 5
     items:
       - description: MAC host clock
       - description: MAC apb clock
index 42689b7..c115c95 100644 (file)
@@ -21,6 +21,7 @@ select:
       contains:
         enum:
           - snps,dwmac
+          - snps,dwmac-3.40a
           - snps,dwmac-3.50a
           - snps,dwmac-3.610
           - snps,dwmac-3.70a
@@ -76,6 +77,7 @@ properties:
         - rockchip,rk3399-gmac
         - rockchip,rv1108-gmac
         - snps,dwmac
+        - snps,dwmac-3.40a
         - snps,dwmac-3.50a
         - snps,dwmac-3.610
         - snps,dwmac-3.70a
index 2911e56..acea1cd 100644 (file)
@@ -41,7 +41,6 @@ properties:
       - description: builtin MSI controller.
 
   interrupt-names:
-    minItems: 1
     items:
       - const: msi
 
index ca91201..d7e08b0 100644 (file)
@@ -171,7 +171,7 @@ examples:
       cs-gpios = <&gpio0 13 0>,
                  <&gpio0 14 0>;
       rx-sample-delay-ns = <3>;
-      spi-flash@1 {
+      flash@1 {
         compatible = "spi-nand";
         reg = <1>;
         rx-sample-delay-ns = <7>;
index ffe9ea0..d67ccd2 100644 (file)
 NTFS3
 =====
 
-
 Summary and Features
 ====================
 
-NTFS3 is fully functional NTFS Read-Write driver. The driver works with
-NTFS versions up to 3.1, normal/compressed/sparse files
-and journal replaying. File system type to use on mount is 'ntfs3'.
+NTFS3 is fully functional NTFS Read-Write driver. The driver works with NTFS
+versions up to 3.1. File system type to use on mount is *ntfs3*.
 
 - This driver implements NTFS read/write support for normal, sparse and
   compressed files.
-- Supports native journal replaying;
-- Supports extended attributes
-       Predefined extended attributes:
-       - 'system.ntfs_security' gets/sets security
-                       descriptor (SECURITY_DESCRIPTOR_RELATIVE)
-       - 'system.ntfs_attrib' gets/sets ntfs file/dir attributes.
-               Note: applied to empty files, this allows to switch type between
-               sparse(0x200), compressed(0x800) and normal;
+- Supports native journal replaying.
 - Supports NFS export of mounted NTFS volumes.
+- Supports extended attributes. Predefined extended attributes:
+
+       - *system.ntfs_security* gets/sets security
+
+               Descriptor: SECURITY_DESCRIPTOR_RELATIVE
+
+       - *system.ntfs_attrib* gets/sets ntfs file/dir attributes.
+
+         Note: Applied to empty files, this allows to switch type between
+         sparse(0x200), compressed(0x800) and normal.
 
 Mount Options
 =============
 
 The list below describes mount options supported by NTFS3 driver in addition to
-generic ones.
+generic ones. You can use every mount option with **no** option. If it is in
+this table marked with no it means default is without **no**.
 
-===============================================================================
+.. flat-table::
+   :widths: 1 5
+   :fill-cells:
 
-nls=name               This option informs the driver how to interpret path
-                       strings and translate them to Unicode and back. If
-                       this option is not set, the default codepage will be
-                       used (CONFIG_NLS_DEFAULT).
-                       Examples:
-                               'nls=utf8'
+   * - iocharset=name
+     - This option informs the driver how to interpret path strings and
+       translate them to Unicode and back. If this option is not set, the
+       default codepage will be used (CONFIG_NLS_DEFAULT).
 
-uid=
-gid=
-umask=                 Controls the default permissions for files/directories created
-                       after the NTFS volume is mounted.
+       Example: iocharset=utf8
 
-fmask=
-dmask=                 Instead of specifying umask which applies both to
-                       files and directories, fmask applies only to files and
-                       dmask only to directories.
+   * - uid=
+     - :rspan:`1`
+   * - gid=
 
-nohidden               Files with the Windows-specific HIDDEN (FILE_ATTRIBUTE_HIDDEN)
-                       attribute will not be shown under Linux.
+   * - umask=
+     - Controls the default permissions for files/directories created after
+       the NTFS volume is mounted.
 
-sys_immutable          Files with the Windows-specific SYSTEM
-                       (FILE_ATTRIBUTE_SYSTEM) attribute will be marked as system
-                       immutable files.
+   * - dmask=
+     - :rspan:`1` Instead of specifying umask which applies both to files and
+       directories, fmask applies only to files and dmask only to directories.
+   * - fmask=
 
-discard                        Enable support of the TRIM command for improved performance
-                       on delete operations, which is recommended for use with the
-                       solid-state drives (SSD).
+   * - noacsrules
+     - "No access rules" mount option sets access rights for files/folders to
+       777 and owner/group to root. This mount option absorbs all other
+       permissions.
 
-force                  Forces the driver to mount partitions even if 'dirty' flag
-                       (volume dirty) is set. Not recommended for use.
+       - Permissions change for files/folders will be reported as successful,
+        but they will remain 777.
 
-sparse                 Create new files as "sparse".
+       - Owner/group change will be reported as successful, butthey will stay
+        as root.
 
-showmeta               Use this parameter to show all meta-files (System Files) on
-                       a mounted NTFS partition.
-                       By default, all meta-files are hidden.
+   * - nohidden
+     - Files with the Windows-specific HIDDEN (FILE_ATTRIBUTE_HIDDEN) attribute
+       will not be shown under Linux.
 
-prealloc               Preallocate space for files excessively when file size is
-                       increasing on writes. Decreases fragmentation in case of
-                       parallel write operations to different files.
+   * - sys_immutable
+     - Files with the Windows-specific SYSTEM (FILE_ATTRIBUTE_SYSTEM) attribute
+       will be marked as system immutable files.
 
-no_acs_rules           "No access rules" mount option sets access rights for
-                       files/folders to 777 and owner/group to root. This mount
-                       option absorbs all other permissions:
-                       - permissions change for files/folders will be reported
-                               as successful, but they will remain 777;
-                       - owner/group change will be reported as successful, but
-                               they will stay as root
+   * - discard
+     - Enable support of the TRIM command for improved performance on delete
+       operations, which is recommended for use with the solid-state drives
+       (SSD).
 
-acl                    Support POSIX ACLs (Access Control Lists). Effective if
-                       supported by Kernel. Not to be confused with NTFS ACLs.
-                       The option specified as acl enables support for POSIX ACLs.
+   * - force
+     - Forces the driver to mount partitions even if volume is marked dirty.
+       Not recommended for use.
 
-noatime                        All files and directories will not update their last access
-                       time attribute if a partition is mounted with this parameter.
-                       This option can speed up file system operation.
+   * - sparse
+     - Create new files as sparse.
 
-===============================================================================
+   * - showmeta
+     - Use this parameter to show all meta-files (System Files) on a mounted
+       NTFS partition. By default, all meta-files are hidden.
 
-ToDo list
-=========
+   * - prealloc
+     - Preallocate space for files excessively when file size is increasing on
+       writes. Decreases fragmentation in case of parallel write operations to
+       different files.
 
-- Full journaling support (currently journal replaying is supported) over JBD.
+   * - acl
+     - Support POSIX ACLs (Access Control Lists). Effective if supported by
+       Kernel. Not to be confused with NTFS ACLs. The option specified as acl
+       enables support for POSIX ACLs.
 
+Todo list
+=========
+- Full journaling support over JBD. Currently journal replaying is supported
+  which is not necessarily as effectice as JBD would be.
 
 References
 ==========
-https://www.paragon-software.com/home/ntfs-linux-professional/
-       - Commercial version of the NTFS driver for Linux.
+- Commercial version of the NTFS driver for Linux.
+       https://www.paragon-software.com/home/ntfs-linux-professional/
 
-almaz.alexandrovich@paragon-software.com
-       - Direct e-mail address for feedback and requests on the NTFS3 implementation.
+- Direct e-mail address for feedback and requests on the NTFS3 implementation.
+       almaz.alexandrovich@paragon-software.com
index 364680c..8ba72e8 100644 (file)
@@ -300,8 +300,8 @@ pcie_replay_count
 .. kernel-doc:: drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
    :doc: pcie_replay_count
 
-+GPU SmartShift Information
-============================
+GPU SmartShift Information
+==========================
 
 GPU SmartShift information via sysfs
 
index 06af044..607f78f 100644 (file)
@@ -111,15 +111,6 @@ Component Helper Usage
 .. kernel-doc:: drivers/gpu/drm/drm_drv.c
    :doc: component helper usage recommendations
 
-IRQ Helper Library
-~~~~~~~~~~~~~~~~~~
-
-.. kernel-doc:: drivers/gpu/drm/drm_irq.c
-   :doc: irq helpers
-
-.. kernel-doc:: drivers/gpu/drm/drm_irq.c
-   :export:
-
 Memory Manager Initialization
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
index abdcbcf..8d118d7 100644 (file)
@@ -1276,6 +1276,7 @@ F:        drivers/input/mouse/bcm5974.c
 
 APPLE DART IOMMU DRIVER
 M:     Sven Peter <sven@svenpeter.dev>
+R:     Alyssa Rosenzweig <alyssa@rosenzweig.io>
 L:     iommu@lists.linux-foundation.org
 S:     Maintained
 F:     Documentation/devicetree/bindings/iommu/apple,dart.yaml
@@ -1712,6 +1713,8 @@ F:        drivers/*/*alpine*
 
 ARM/APPLE MACHINE SUPPORT
 M:     Hector Martin <marcan@marcan.st>
+M:     Sven Peter <sven@svenpeter.dev>
+R:     Alyssa Rosenzweig <alyssa@rosenzweig.io>
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 S:     Maintained
 W:     https://asahilinux.org
@@ -2237,6 +2240,7 @@ F:        arch/arm/mach-pxa/mioa701.c
 
 ARM/MStar/Sigmastar Armv7 SoC support
 M:     Daniel Palmer <daniel@thingy.jp>
+M:     Romain Perier <romain.perier@gmail.com>
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 S:     Maintained
 W:     http://linux-chenxing.org/
@@ -2713,6 +2717,7 @@ F:        drivers/power/reset/keystone-reset.c
 
 ARM/TEXAS INSTRUMENTS K3 ARCHITECTURE
 M:     Nishanth Menon <nm@ti.com>
+M:     Vignesh Raghavendra <vigneshr@ti.com>
 M:     Tero Kristo <kristo@kernel.org>
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 S:     Supported
@@ -7338,10 +7343,11 @@ F:      include/uapi/linux/fpga-dfl.h
 
 FPGA MANAGER FRAMEWORK
 M:     Moritz Fischer <mdf@kernel.org>
+M:     Wu Hao <hao.wu@intel.com>
+M:     Xu Yilun <yilun.xu@intel.com>
 R:     Tom Rix <trix@redhat.com>
 L:     linux-fpga@vger.kernel.org
 S:     Maintained
-W:     http://www.rocketboards.org
 Q:     http://patchwork.kernel.org/project/linux-fpga/list/
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/mdf/linux-fpga.git
 F:     Documentation/devicetree/bindings/fpga/
@@ -7435,7 +7441,7 @@ FREESCALE IMX / MXC FEC DRIVER
 M:     Joakim Zhang <qiangqing.zhang@nxp.com>
 L:     netdev@vger.kernel.org
 S:     Maintained
-F:     Documentation/devicetree/bindings/net/fsl-fec.txt
+F:     Documentation/devicetree/bindings/net/fsl,fec.yaml
 F:     drivers/net/ethernet/freescale/fec.h
 F:     drivers/net/ethernet/freescale/fec_main.c
 F:     drivers/net/ethernet/freescale/fec_ptp.c
@@ -8609,9 +8615,8 @@ F:        Documentation/devicetree/bindings/iio/humidity/st,hts221.yaml
 F:     drivers/iio/humidity/hts221*
 
 HUAWEI ETHERNET DRIVER
-M:     Bin Luo <luobin9@huawei.com>
 L:     netdev@vger.kernel.org
-S:     Supported
+S:     Orphan
 F:     Documentation/networking/device_drivers/ethernet/huawei/hinic.rst
 F:     drivers/net/ethernet/huawei/hinic/
 
@@ -9303,7 +9308,7 @@ S:        Maintained
 F:     drivers/platform/x86/intel/atomisp2/led.c
 
 INTEL BIOS SAR INT1092 DRIVER
-M:     Shravan S <s.shravan@intel.com>
+M:     Shravan Sudhakar <s.shravan@intel.com>
 M:     Intel Corporation <linuxwwan@intel.com>
 L:     platform-driver-x86@vger.kernel.org
 S:     Maintained
@@ -9625,7 +9630,7 @@ F:        include/uapi/linux/isst_if.h
 F:     tools/power/x86/intel-speed-select/
 
 INTEL STRATIX10 FIRMWARE DRIVERS
-M:     Richard Gong <richard.gong@linux.intel.com>
+M:     Dinh Nguyen <dinguyen@kernel.org>
 L:     linux-kernel@vger.kernel.org
 S:     Maintained
 F:     Documentation/ABI/testing/sysfs-devices-platform-stratix10-rsu
@@ -10275,7 +10280,6 @@ KERNEL VIRTUAL MACHINE for s390 (KVM/s390)
 M:     Christian Borntraeger <borntraeger@de.ibm.com>
 M:     Janosch Frank <frankja@linux.ibm.com>
 R:     David Hildenbrand <david@redhat.com>
-R:     Cornelia Huck <cohuck@redhat.com>
 R:     Claudio Imbrenda <imbrenda@linux.ibm.com>
 L:     kvm@vger.kernel.org
 S:     Supported
@@ -11149,6 +11153,7 @@ S:      Maintained
 F:     Documentation/devicetree/bindings/net/dsa/marvell.txt
 F:     Documentation/networking/devlink/mv88e6xxx.rst
 F:     drivers/net/dsa/mv88e6xxx/
+F:     include/linux/dsa/mv88e6xxx.h
 F:     include/linux/platform_data/mv88e6xxx.h
 
 MARVELL ARMADA 3700 PHY DRIVERS
@@ -16297,6 +16302,7 @@ S390
 M:     Heiko Carstens <hca@linux.ibm.com>
 M:     Vasily Gorbik <gor@linux.ibm.com>
 M:     Christian Borntraeger <borntraeger@de.ibm.com>
+R:     Alexander Gordeev <agordeev@linux.ibm.com>
 L:     linux-s390@vger.kernel.org
 S:     Supported
 W:     http://www.ibm.com/developerworks/linux/linux390/
@@ -16375,7 +16381,6 @@ F:      drivers/s390/crypto/vfio_ap_ops.c
 F:     drivers/s390/crypto/vfio_ap_private.h
 
 S390 VFIO-CCW DRIVER
-M:     Cornelia Huck <cohuck@redhat.com>
 M:     Eric Farman <farman@linux.ibm.com>
 M:     Matthew Rosato <mjrosato@linux.ibm.com>
 R:     Halil Pasic <pasic@linux.ibm.com>
@@ -17794,7 +17799,6 @@ F:      drivers/staging/nvec/
 
 STAGING - OLPC SECONDARY DISPLAY CONTROLLER (DCON)
 M:     Jens Frederich <jfrederich@gmail.com>
-M:     Daniel Drake <dsd@laptop.org>
 M:     Jon Nettleton <jon.nettleton@gmail.com>
 S:     Maintained
 W:     http://wiki.laptop.org/go/DCON
@@ -17983,7 +17987,7 @@ F:      net/switchdev/
 SY8106A REGULATOR DRIVER
 M:     Icenowy Zheng <icenowy@aosc.io>
 S:     Maintained
-F:     Documentation/devicetree/bindings/regulator/sy8106a-regulator.txt
+F:     Documentation/devicetree/bindings/regulator/silergy,sy8106a.yaml
 F:     drivers/regulator/sy8106a-regulator.c
 
 SYNC FILE FRAMEWORK
@@ -20700,7 +20704,6 @@ S:      Maintained
 F:     mm/zbud.c
 
 ZD1211RW WIRELESS DRIVER
-M:     Daniel Drake <dsd@gentoo.org>
 M:     Ulrich Kunitz <kune@deine-taler.de>
 L:     linux-wireless@vger.kernel.org
 L:     zd1211-devs@lists.sourceforge.net (subscribers-only)
index 7b74223..4d0c0ed 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -2,7 +2,7 @@
 VERSION = 5
 PATCHLEVEL = 15
 SUBLEVEL = 0
-EXTRAVERSION = -rc4
+EXTRAVERSION = -rc5
 NAME = Opossums on Parade
 
 # *DOCUMENTATION*
index 9320b04..4cf45a9 100644 (file)
@@ -26,11 +26,6 @@ extern char empty_zero_page[PAGE_SIZE];
 
 extern pgd_t swapper_pg_dir[] __aligned(PAGE_SIZE);
 
-/* Macro to mark a page protection as uncacheable */
-#define pgprot_noncached(prot) (__pgprot(pgprot_val(prot) & ~_PAGE_CACHEABLE))
-
-extern pgd_t swapper_pg_dir[] __aligned(PAGE_SIZE);
-
 /* to cope with aliasing VIPT cache */
 #define HAVE_ARCH_UNMAPPED_AREA
 
index fc19642..59baf6c 100644 (file)
@@ -1989,8 +1989,6 @@ config ARCH_HIBERNATION_POSSIBLE
 
 endmenu
 
-source "drivers/firmware/Kconfig"
-
 if CRYPTO
 source "arch/arm/crypto/Kconfig"
 endif
index 614999d..cd46725 100644 (file)
@@ -71,7 +71,6 @@
                        isc: isc@f0008000 {
                                pinctrl-names = "default";
                                pinctrl-0 = <&pinctrl_isc_base &pinctrl_isc_data_8bit &pinctrl_isc_data_9_10 &pinctrl_isc_data_11_12>;
-                               status = "okay";
                        };
 
                        qspi1: spi@f0024000 {
index 4cbed98..f3d6aaa 100644 (file)
 
                                        regulator-state-standby {
                                                regulator-on-in-suspend;
+                                               regulator-suspend-microvolt = <1350000>;
                                                regulator-mode = <4>;
                                        };
 
                                        regulator-state-mem {
                                                regulator-on-in-suspend;
+                                               regulator-suspend-microvolt = <1350000>;
                                                regulator-mode = <4>;
                                        };
                                };
        #address-cells = <1>;
        #size-cells = <0>;
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_gmac0_default &pinctrl_gmac0_txck_default &pinctrl_gmac0_phy_irq>;
+       pinctrl-0 = <&pinctrl_gmac0_default
+                    &pinctrl_gmac0_mdio_default
+                    &pinctrl_gmac0_txck_default
+                    &pinctrl_gmac0_phy_irq>;
        phy-mode = "rgmii-id";
        status = "okay";
 
        #address-cells = <1>;
        #size-cells = <0>;
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_gmac1_default &pinctrl_gmac1_phy_irq>;
+       pinctrl-0 = <&pinctrl_gmac1_default
+                    &pinctrl_gmac1_mdio_default
+                    &pinctrl_gmac1_phy_irq>;
        phy-mode = "rmii";
        status = "okay";
 
                         <PIN_PA15__G0_TXEN>,
                         <PIN_PA30__G0_RXCK>,
                         <PIN_PA18__G0_RXDV>,
-                        <PIN_PA22__G0_MDC>,
-                        <PIN_PA23__G0_MDIO>,
                         <PIN_PA25__G0_125CK>;
+               slew-rate = <0>;
+               bias-disable;
+       };
+
+       pinctrl_gmac0_mdio_default: gmac0_mdio_default {
+               pinmux = <PIN_PA22__G0_MDC>,
+                        <PIN_PA23__G0_MDIO>;
                bias-disable;
        };
 
        pinctrl_gmac0_txck_default: gmac0_txck_default {
                pinmux = <PIN_PA24__G0_TXCK>;
+               slew-rate = <0>;
                bias-pull-up;
        };
 
                         <PIN_PD25__G1_RX0>,
                         <PIN_PD26__G1_RX1>,
                         <PIN_PD27__G1_RXER>,
-                        <PIN_PD24__G1_RXDV>,
-                        <PIN_PD28__G1_MDC>,
+                        <PIN_PD24__G1_RXDV>;
+               slew-rate = <0>;
+               bias-disable;
+       };
+
+       pinctrl_gmac1_mdio_default: gmac1_mdio_default {
+               pinmux = <PIN_PD28__G1_MDC>,
                         <PIN_PD29__G1_MDIO>;
                bias-disable;
        };
                                 <PIN_PA8__SDMMC0_DAT5>,
                                 <PIN_PA9__SDMMC0_DAT6>,
                                 <PIN_PA10__SDMMC0_DAT7>;
+                       slew-rate = <0>;
                        bias-pull-up;
                };
 
                        pinmux = <PIN_PA0__SDMMC0_CK>,
                                 <PIN_PA2__SDMMC0_RSTN>,
                                 <PIN_PA11__SDMMC0_DS>;
+                       slew-rate = <0>;
                        bias-pull-up;
                };
        };
                                 <PIN_PC0__SDMMC1_DAT1>,
                                 <PIN_PC1__SDMMC1_DAT2>,
                                 <PIN_PC2__SDMMC1_DAT3>;
+                       slew-rate = <0>;
                        bias-pull-up;
                };
 
                                 <PIN_PB28__SDMMC1_RSTN>,
                                 <PIN_PC5__SDMMC1_1V8SEL>,
                                 <PIN_PC4__SDMMC1_CD>;
+                       slew-rate = <0>;
                        bias-pull-up;
                };
        };
                                 <PIN_PD6__SDMMC2_DAT1>,
                                 <PIN_PD7__SDMMC2_DAT2>,
                                 <PIN_PD8__SDMMC2_DAT3>;
+                       slew-rate = <0>;
                        bias-pull-up;
                };
 
                ck {
                        pinmux = <PIN_PD4__SDMMC2_CK>;
+                       slew-rate = <0>;
                        bias-pull-up;
                };
        };
        pinctrl-0 = <&pinctrl_sdmmc2_default>;
 };
 
+&shdwc {
+       atmel,shdwc-debouncer = <976>;
+       status = "okay";
+
+       input@0 {
+               reg = <0>;
+       };
+};
+
 &spdifrx {
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_spdifrx_default>;
index f24bdd0..72ce80f 100644 (file)
@@ -40,8 +40,8 @@
                regulator-always-on;
                regulator-settling-time-us = <5000>;
                gpios = <&expgpio 4 GPIO_ACTIVE_HIGH>;
-               states = <1800000 0x1
-                         3300000 0x0>;
+               states = <1800000 0x1>,
+                        <3300000 0x0>;
                status = "okay";
        };
 
 };
 
 &pcie0 {
-       pci@1,0 {
+       pci@0,0 {
+               device_type = "pci";
                #address-cells = <3>;
                #size-cells = <2>;
                ranges;
 
                reg = <0 0 0 0 0>;
 
-               usb@1,0 {
-                       reg = <0x10000 0 0 0 0>;
+               usb@0,0 {
+                       reg = <0 0 0 0 0>;
                        resets = <&reset RASPBERRYPI_FIRMWARE_RESET_ID_USB>;
                };
        };
index b8a4096..3b60297 100644 (file)
                        status = "disabled";
                };
 
+               vec: vec@7ec13000 {
+                       compatible = "brcm,bcm2711-vec";
+                       reg = <0x7ec13000 0x1000>;
+                       clocks = <&clocks BCM2835_CLOCK_VEC>;
+                       interrupts = <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>;
+                       status = "disabled";
+               };
+
                dvp: clock@7ef00000 {
                        compatible = "brcm,brcm2711-dvp";
                        reg = <0x7ef00000 0x10>;
                                compatible = "brcm,genet-mdio-v5";
                                reg = <0xe14 0x8>;
                                reg-names = "mdio";
-                               #address-cells = <0x0>;
-                               #size-cells = <0x1>;
+                               #address-cells = <0x1>;
+                               #size-cells = <0x0>;
                        };
                };
        };
index 4119271..c25e797 100644 (file)
                        status = "okay";
                };
 
+               vec: vec@7e806000 {
+                       compatible = "brcm,bcm2835-vec";
+                       reg = <0x7e806000 0x1000>;
+                       clocks = <&clocks BCM2835_CLOCK_VEC>;
+                       interrupts = <2 27>;
+                       status = "disabled";
+               };
+
                pixelvalve@7e807000 {
                        compatible = "brcm,bcm2835-pixelvalve2";
                        reg = <0x7e807000 0x100>;
index 0f3be55..a3e06b6 100644 (file)
                        status = "disabled";
                };
 
-               vec: vec@7e806000 {
-                       compatible = "brcm,bcm2835-vec";
-                       reg = <0x7e806000 0x1000>;
-                       clocks = <&clocks BCM2835_CLOCK_VEC>;
-                       interrupts = <2 27>;
-                       status = "disabled";
-               };
-
                usb: usb@7e980000 {
                        compatible = "brcm,bcm2835-usb";
                        reg = <0x7e980000 0x10000>;
index d3082b9..4f88e96 100644 (file)
@@ -56,6 +56,7 @@
        panel {
                compatible = "edt,etm0700g0dh6";
                pinctrl-0 = <&pinctrl_display_gpio>;
+               pinctrl-names = "default";
                enable-gpios = <&gpio6 0 GPIO_ACTIVE_HIGH>;
 
                port {
@@ -76,8 +77,7 @@
                regulator-name = "vbus";
                regulator-min-microvolt = <5000000>;
                regulator-max-microvolt = <5000000>;
-               gpio = <&gpio1 2 GPIO_ACTIVE_HIGH>;
-               enable-active-high;
+               gpio = <&gpio1 2 0>;
        };
 };
 
index cb8b539..e5c4dc6 100644 (file)
@@ -5,6 +5,7 @@
 #include <dt-bindings/gpio/gpio.h>
 #include <dt-bindings/interrupt-controller/irq.h>
 #include <dt-bindings/input/input.h>
+#include <dt-bindings/leds/common.h>
 #include <dt-bindings/pwm/pwm.h>
 
 / {
                        led-cur = /bits/ 8 <0x20>;
                        max-cur = /bits/ 8 <0x60>;
                        reg = <0>;
+                       color = <LED_COLOR_ID_RED>;
                };
 
                chan@1 {
                        led-cur = /bits/ 8 <0x20>;
                        max-cur = /bits/ 8 <0x60>;
                        reg = <1>;
+                       color = <LED_COLOR_ID_GREEN>;
                };
 
                chan@2 {
                        led-cur = /bits/ 8 <0x20>;
                        max-cur = /bits/ 8 <0x60>;
                        reg = <2>;
+                       color = <LED_COLOR_ID_BLUE>;
                };
 
                chan@3 {
                        led-cur = /bits/ 8 <0x0>;
                        max-cur = /bits/ 8 <0x0>;
                        reg = <3>;
+                       color = <LED_COLOR_ID_WHITE>;
                };
        };
 
index 5de4ccb..f7a56d6 100644 (file)
        pinctrl-0 = <&pinctrl_enet>;
        phy-mode = "rgmii-id";
        phy-reset-gpios = <&gpio1 26 GPIO_ACTIVE_LOW>;
+       phy-handle = <&phy>;
        status = "okay";
+
+       mdio {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               phy: ethernet-phy@1 {
+                       reg = <1>;
+                       qca,clk-out-frequency = <125000000>;
+               };
+       };
 };
 
 &hdmi {
index 5a63ca6..99f4cf7 100644 (file)
                compatible = "micron,n25q256a", "jedec,spi-nor";
                spi-max-frequency = <29000000>;
                spi-rx-bus-width = <4>;
-               spi-tx-bus-width = <4>;
+               spi-tx-bus-width = <1>;
                reg = <0>;
        };
 
                compatible = "micron,n25q256a", "jedec,spi-nor";
                spi-max-frequency = <29000000>;
                spi-rx-bus-width = <4>;
-               spi-tx-bus-width = <4>;
+               spi-tx-bus-width = <1>;
                reg = <2>;
        };
 };
index 779cc53..a3fde33 100644 (file)
                compatible = "micron,n25q256a", "jedec,spi-nor";
                spi-max-frequency = <29000000>;
                spi-rx-bus-width = <4>;
-               spi-tx-bus-width = <4>;
+               spi-tx-bus-width = <1>;
                reg = <0>;
        };
 };
index c5b9037..7d530ae 100644 (file)
 
        nand@1,0 {
                compatible = "ti,omap2-nand";
-               reg = <0 0 4>; /* CS0, offset 0, IO size 4 */
+               reg = <1 0 4>; /* CS1, offset 0, IO size 4 */
                interrupt-parent = <&gpmc>;
                interrupts = <0 IRQ_TYPE_NONE>, /* fifoevent */
                             <1 IRQ_TYPE_NONE>; /* termcount */
index 0b2bed6..d1c1c6a 100644 (file)
                        clock-frequency = <19200000>;
                };
 
-               pxo_board {
+               pxo_board: pxo_board {
                        compatible = "fixed-clock";
                        #clock-cells = <0>;
                        clock-frequency = <27000000>;
                };
 
                gpu: adreno-3xx@4300000 {
-                       compatible = "qcom,adreno-3xx";
+                       compatible = "qcom,adreno-320.2", "qcom,adreno";
                        reg = <0x04300000 0x20000>;
                        reg-names = "kgsl_3d0_reg_memory";
                        interrupts = <GIC_SPI 80 IRQ_TYPE_LEVEL_HIGH>;
                        interrupt-names = "kgsl_3d0_irq";
                        clock-names =
-                           "core_clk",
-                           "iface_clk",
-                           "mem_clk",
-                           "mem_iface_clk";
+                           "core",
+                           "iface",
+                           "mem",
+                           "mem_iface";
                        clocks =
                            <&mmcc GFX3D_CLK>,
                            <&mmcc GFX3D_AHB_CLK>,
                            <&mmcc GFX3D_AXI_CLK>,
                            <&mmcc MMSS_IMEM_AHB_CLK>;
-                       qcom,chipid = <0x03020002>;
 
                        iommus = <&gfx3d 0
                                  &gfx3d 1
                        reg-names = "dsi_pll", "dsi_phy", "dsi_phy_regulator";
                        clock-names = "iface_clk", "ref";
                        clocks = <&mmcc DSI_M_AHB_CLK>,
-                                <&cxo_board>;
+                                <&pxo_board>;
                };
 
 
index cc6be6d..6c58c15 100644 (file)
                #size-cells = <1>;
                ranges;
 
+               securam: securam@e0000000 {
+                       compatible = "microchip,sama7g5-securam", "atmel,sama5d2-securam", "mmio-sram";
+                       reg = <0xe0000000 0x4000>;
+                       clocks = <&pmc PMC_TYPE_PERIPHERAL 18>;
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0 0xe0000000 0x4000>;
+                       no-memory-wc;
+                       status = "okay";
+               };
+
                secumod: secumod@e0004000 {
                        compatible = "microchip,sama7g5-secumod", "atmel,sama5d2-secumod", "syscon";
                        reg = <0xe0004000 0x4000>;
                        clock-names = "td_slck", "md_slck", "main_xtal";
                };
 
+               shdwc: shdwc@e001d010 {
+                       compatible = "microchip,sama7g5-shdwc", "syscon";
+                       reg = <0xe001d010 0x10>;
+                       clocks = <&clk32k 0>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       atmel,wakeup-rtc-timer;
+                       atmel,wakeup-rtt-timer;
+                       status = "disabled";
+               };
+
                rtt: rtt@e001d020 {
                        compatible = "microchip,sama7g5-rtt", "microchip,sam9x60-rtt", "atmel,at91sam9260-rtt";
                        reg = <0xe001d020 0x30>;
                        clocks = <&clk32k 0>;
                };
 
+               chipid@e0020000 {
+                       compatible = "microchip,sama7g5-chipid";
+                       reg = <0xe0020000 0x8>;
+               };
+
                sdmmc0: mmc@e1204000 {
                        compatible = "microchip,sama7g5-sdhci", "microchip,sam9x60-sdhci";
                        reg = <0xe1204000 0x4000>;
                        };
                };
 
+               uddrc: uddrc@e3800000 {
+                       compatible = "microchip,sama7g5-uddrc";
+                       reg = <0xe3800000 0x4000>;
+                       status = "okay";
+               };
+
+               ddr3phy: ddr3phy@e3804000 {
+                       compatible = "microchip,sama7g5-ddr3phy";
+                       reg = <0xe3804000 0x1000>;
+                       status = "okay";
+               };
+
                gic: interrupt-controller@e8c11000 {
                        compatible = "arm,cortex-a7-gic";
                        #interrupt-cells = <3>;
index f266b7b..cc88ebe 100644 (file)
@@ -47,7 +47,7 @@
                };
 
                gmac: eth@e0800000 {
-                       compatible = "st,spear600-gmac";
+                       compatible = "snps,dwmac-3.40a";
                        reg = <0xe0800000 0x8000>;
                        interrupts = <23 22>;
                        interrupt-names = "macirq", "eth_wake_irq";
index 2ad9fd7..8af4b77 100644 (file)
@@ -17,6 +17,7 @@
  * TAKE CARE WHEN MAINTAINING THIS FILE TO PROPAGATE ANY RELEVANT
  * CHANGES TO vexpress-v2m.dtsi!
  */
+#include <dt-bindings/interrupt-controller/arm-gic.h>
 
 / {
        v2m_fixed_3v3: fixed-regulator-0 {
        };
 
        bus@8000000 {
-               motherboard-bus {
-                       model = "V2M-P1";
+               compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <1>;
+
+               #interrupt-cells = <1>;
+               interrupt-map-mask = <0 63>;
+               interrupt-map = <0  0 &gic GIC_SPI  0 IRQ_TYPE_LEVEL_HIGH>,
+                               <0  1 &gic GIC_SPI  1 IRQ_TYPE_LEVEL_HIGH>,
+                               <0  2 &gic GIC_SPI  2 IRQ_TYPE_LEVEL_HIGH>,
+                               <0  3 &gic GIC_SPI  3 IRQ_TYPE_LEVEL_HIGH>,
+                               <0  4 &gic GIC_SPI  4 IRQ_TYPE_LEVEL_HIGH>,
+                               <0  5 &gic GIC_SPI  5 IRQ_TYPE_LEVEL_HIGH>,
+                               <0  6 &gic GIC_SPI  6 IRQ_TYPE_LEVEL_HIGH>,
+                               <0  7 &gic GIC_SPI  7 IRQ_TYPE_LEVEL_HIGH>,
+                               <0  8 &gic GIC_SPI  8 IRQ_TYPE_LEVEL_HIGH>,
+                               <0  9 &gic GIC_SPI  9 IRQ_TYPE_LEVEL_HIGH>,
+                               <0 10 &gic GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>,
+                               <0 11 &gic GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>,
+                               <0 12 &gic GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>,
+                               <0 13 &gic GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>,
+                               <0 14 &gic GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>,
+                               <0 15 &gic GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>,
+                               <0 16 &gic GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>,
+                               <0 17 &gic GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>,
+                               <0 18 &gic GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>,
+                               <0 19 &gic GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>,
+                               <0 20 &gic GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>,
+                               <0 21 &gic GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>,
+                               <0 22 &gic GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>,
+                               <0 23 &gic GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>,
+                               <0 24 &gic GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>,
+                               <0 25 &gic GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>,
+                               <0 26 &gic GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>,
+                               <0 27 &gic GIC_SPI 27 IRQ_TYPE_LEVEL_HIGH>,
+                               <0 28 &gic GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>,
+                               <0 29 &gic GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>,
+                               <0 30 &gic GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>,
+                               <0 31 &gic GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>,
+                               <0 32 &gic GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>,
+                               <0 33 &gic GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>,
+                               <0 34 &gic GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>,
+                               <0 35 &gic GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>,
+                               <0 36 &gic GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>,
+                               <0 37 &gic GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>,
+                               <0 38 &gic GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>,
+                               <0 39 &gic GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>,
+                               <0 40 &gic GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>,
+                               <0 41 &gic GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>,
+                               <0 42 &gic GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>;
+
+               motherboard-bus@8000000 {
                        arm,hbi = <0x190>;
                        arm,vexpress,site = <0>;
-                       arm,v2m-memory-map = "rs1";
                        compatible = "arm,vexpress,v2m-p1", "simple-bus";
                        #address-cells = <2>; /* SMB chipselect number and offset */
                        #size-cells = <1>;
-                       #interrupt-cells = <1>;
-                       ranges;
+                       ranges = <0 0 0x08000000 0x04000000>,
+                                <1 0 0x14000000 0x04000000>,
+                                <2 0 0x18000000 0x04000000>,
+                                <3 0 0x1c000000 0x04000000>,
+                                <4 0 0x0c000000 0x04000000>,
+                                <5 0 0x10000000 0x04000000>;
 
                        nor_flash: flash@0 {
                                compatible = "arm,vexpress-flash", "cfi-flash";
                                        clock-names = "apb_pclk";
                                };
 
-                               mmci@50000 {
+                               mmc@50000 {
                                        compatible = "arm,pl180", "arm,primecell";
                                        reg = <0x050000 0x1000>;
                                        interrupts = <9>, <10>;
                                        clock-names = "uartclk", "apb_pclk";
                                };
 
-                               wdt@f0000 {
+                               watchdog@f0000 {
                                        compatible = "arm,sp805", "arm,primecell";
                                        reg = <0x0f0000 0x1000>;
                                        interrupts = <0>;
index ec13ceb..f434fe5 100644 (file)
  * TAKE CARE WHEN MAINTAINING THIS FILE TO PROPAGATE ANY RELEVANT
  * CHANGES TO vexpress-v2m-rs1.dtsi!
  */
+#include <dt-bindings/interrupt-controller/arm-gic.h>
 
 / {
-       bus@4000000 {
-               motherboard {
-                       model = "V2M-P1";
+       bus@40000000 {
+               compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <1>;
+               ranges = <0x40000000 0x40000000 0x10000000>,
+                        <0x10000000 0x10000000 0x00020000>;
+
+               #interrupt-cells = <1>;
+               interrupt-map-mask = <0 63>;
+               interrupt-map = <0  0 &gic GIC_SPI  0 IRQ_TYPE_LEVEL_HIGH>,
+                               <0  1 &gic GIC_SPI  1 IRQ_TYPE_LEVEL_HIGH>,
+                               <0  2 &gic GIC_SPI  2 IRQ_TYPE_LEVEL_HIGH>,
+                               <0  3 &gic GIC_SPI  3 IRQ_TYPE_LEVEL_HIGH>,
+                               <0  4 &gic GIC_SPI  4 IRQ_TYPE_LEVEL_HIGH>,
+                               <0  5 &gic GIC_SPI  5 IRQ_TYPE_LEVEL_HIGH>,
+                               <0  6 &gic GIC_SPI  6 IRQ_TYPE_LEVEL_HIGH>,
+                               <0  7 &gic GIC_SPI  7 IRQ_TYPE_LEVEL_HIGH>,
+                               <0  8 &gic GIC_SPI  8 IRQ_TYPE_LEVEL_HIGH>,
+                               <0  9 &gic GIC_SPI  9 IRQ_TYPE_LEVEL_HIGH>,
+                               <0 10 &gic GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>,
+                               <0 11 &gic GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>,
+                               <0 12 &gic GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>,
+                               <0 13 &gic GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>,
+                               <0 14 &gic GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>,
+                               <0 15 &gic GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>,
+                               <0 16 &gic GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>,
+                               <0 17 &gic GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>,
+                               <0 18 &gic GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>,
+                               <0 19 &gic GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>,
+                               <0 20 &gic GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>,
+                               <0 21 &gic GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>,
+                               <0 22 &gic GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>,
+                               <0 23 &gic GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>,
+                               <0 24 &gic GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>,
+                               <0 25 &gic GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>,
+                               <0 26 &gic GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>,
+                               <0 27 &gic GIC_SPI 27 IRQ_TYPE_LEVEL_HIGH>,
+                               <0 28 &gic GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>,
+                               <0 29 &gic GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>,
+                               <0 30 &gic GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>,
+                               <0 31 &gic GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>,
+                               <0 32 &gic GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>,
+                               <0 33 &gic GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>,
+                               <0 34 &gic GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>,
+                               <0 35 &gic GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>,
+                               <0 36 &gic GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>,
+                               <0 37 &gic GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>,
+                               <0 38 &gic GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>,
+                               <0 39 &gic GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>,
+                               <0 40 &gic GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>,
+                               <0 41 &gic GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>,
+                               <0 42 &gic GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>;
+
+               motherboard-bus@40000000 {
                        arm,hbi = <0x190>;
                        arm,vexpress,site = <0>;
                        compatible = "arm,vexpress,v2m-p1", "simple-bus";
                        #address-cells = <2>; /* SMB chipselect number and offset */
                        #size-cells = <1>;
-                       #interrupt-cells = <1>;
-                       ranges;
+                       ranges = <0 0 0x40000000 0x04000000>,
+                                <1 0 0x44000000 0x04000000>,
+                                <2 0 0x48000000 0x04000000>,
+                                <3 0 0x4c000000 0x04000000>,
+                                <7 0 0x10000000 0x00020000>;
 
                        flash@0,00000000 {
                                compatible = "arm,vexpress-flash", "cfi-flash";
index e63c5c0..679537e 100644 (file)
        };
 
        bus@8000000 {
-               compatible = "simple-bus";
-
-               #address-cells = <2>;
-               #size-cells = <1>;
-               ranges = <0 0 0 0x08000000 0x04000000>,
-                        <1 0 0 0x14000000 0x04000000>,
-                        <2 0 0 0x18000000 0x04000000>,
-                        <3 0 0 0x1c000000 0x04000000>,
-                        <4 0 0 0x0c000000 0x04000000>,
-                        <5 0 0 0x10000000 0x04000000>;
-
-               #interrupt-cells = <1>;
-               interrupt-map-mask = <0 0 63>;
-               interrupt-map = <0 0  0 &gic 0  0 4>,
-                               <0 0  1 &gic 0  1 4>,
-                               <0 0  2 &gic 0  2 4>,
-                               <0 0  3 &gic 0  3 4>,
-                               <0 0  4 &gic 0  4 4>,
-                               <0 0  5 &gic 0  5 4>,
-                               <0 0  6 &gic 0  6 4>,
-                               <0 0  7 &gic 0  7 4>,
-                               <0 0  8 &gic 0  8 4>,
-                               <0 0  9 &gic 0  9 4>,
-                               <0 0 10 &gic 0 10 4>,
-                               <0 0 11 &gic 0 11 4>,
-                               <0 0 12 &gic 0 12 4>,
-                               <0 0 13 &gic 0 13 4>,
-                               <0 0 14 &gic 0 14 4>,
-                               <0 0 15 &gic 0 15 4>,
-                               <0 0 16 &gic 0 16 4>,
-                               <0 0 17 &gic 0 17 4>,
-                               <0 0 18 &gic 0 18 4>,
-                               <0 0 19 &gic 0 19 4>,
-                               <0 0 20 &gic 0 20 4>,
-                               <0 0 21 &gic 0 21 4>,
-                               <0 0 22 &gic 0 22 4>,
-                               <0 0 23 &gic 0 23 4>,
-                               <0 0 24 &gic 0 24 4>,
-                               <0 0 25 &gic 0 25 4>,
-                               <0 0 26 &gic 0 26 4>,
-                               <0 0 27 &gic 0 27 4>,
-                               <0 0 28 &gic 0 28 4>,
-                               <0 0 29 &gic 0 29 4>,
-                               <0 0 30 &gic 0 30 4>,
-                               <0 0 31 &gic 0 31 4>,
-                               <0 0 32 &gic 0 32 4>,
-                               <0 0 33 &gic 0 33 4>,
-                               <0 0 34 &gic 0 34 4>,
-                               <0 0 35 &gic 0 35 4>,
-                               <0 0 36 &gic 0 36 4>,
-                               <0 0 37 &gic 0 37 4>,
-                               <0 0 38 &gic 0 38 4>,
-                               <0 0 39 &gic 0 39 4>,
-                               <0 0 40 &gic 0 40 4>,
-                               <0 0 41 &gic 0 41 4>,
-                               <0 0 42 &gic 0 42 4>;
+               ranges = <0x8000000 0 0x8000000 0x18000000>;
        };
 
        site2: hsb@40000000 {
index 012d40a..511e87c 100644 (file)
        };
 
        smb: bus@8000000 {
-               compatible = "simple-bus";
-
-               #address-cells = <2>;
-               #size-cells = <1>;
-               ranges = <0 0 0 0x08000000 0x04000000>,
-                        <1 0 0 0x14000000 0x04000000>,
-                        <2 0 0 0x18000000 0x04000000>,
-                        <3 0 0 0x1c000000 0x04000000>,
-                        <4 0 0 0x0c000000 0x04000000>,
-                        <5 0 0 0x10000000 0x04000000>;
-
-               #interrupt-cells = <1>;
-               interrupt-map-mask = <0 0 63>;
-               interrupt-map = <0 0  0 &gic 0  0 4>,
-                               <0 0  1 &gic 0  1 4>,
-                               <0 0  2 &gic 0  2 4>,
-                               <0 0  3 &gic 0  3 4>,
-                               <0 0  4 &gic 0  4 4>,
-                               <0 0  5 &gic 0  5 4>,
-                               <0 0  6 &gic 0  6 4>,
-                               <0 0  7 &gic 0  7 4>,
-                               <0 0  8 &gic 0  8 4>,
-                               <0 0  9 &gic 0  9 4>,
-                               <0 0 10 &gic 0 10 4>,
-                               <0 0 11 &gic 0 11 4>,
-                               <0 0 12 &gic 0 12 4>,
-                               <0 0 13 &gic 0 13 4>,
-                               <0 0 14 &gic 0 14 4>,
-                               <0 0 15 &gic 0 15 4>,
-                               <0 0 16 &gic 0 16 4>,
-                               <0 0 17 &gic 0 17 4>,
-                               <0 0 18 &gic 0 18 4>,
-                               <0 0 19 &gic 0 19 4>,
-                               <0 0 20 &gic 0 20 4>,
-                               <0 0 21 &gic 0 21 4>,
-                               <0 0 22 &gic 0 22 4>,
-                               <0 0 23 &gic 0 23 4>,
-                               <0 0 24 &gic 0 24 4>,
-                               <0 0 25 &gic 0 25 4>,
-                               <0 0 26 &gic 0 26 4>,
-                               <0 0 27 &gic 0 27 4>,
-                               <0 0 28 &gic 0 28 4>,
-                               <0 0 29 &gic 0 29 4>,
-                               <0 0 30 &gic 0 30 4>,
-                               <0 0 31 &gic 0 31 4>,
-                               <0 0 32 &gic 0 32 4>,
-                               <0 0 33 &gic 0 33 4>,
-                               <0 0 34 &gic 0 34 4>,
-                               <0 0 35 &gic 0 35 4>,
-                               <0 0 36 &gic 0 36 4>,
-                               <0 0 37 &gic 0 37 4>,
-                               <0 0 38 &gic 0 38 4>,
-                               <0 0 39 &gic 0 39 4>,
-                               <0 0 40 &gic 0 40 4>,
-                               <0 0 41 &gic 0 41 4>,
-                               <0 0 42 &gic 0 42 4>;
+               ranges = <0x8000000 0 0x8000000 0x18000000>;
        };
 
        site2: hsb@40000000 {
index 7aa64ae..3b88209 100644 (file)
        };
 
        smb: bus@8000000 {
-               compatible = "simple-bus";
-
-               #address-cells = <2>;
-               #size-cells = <1>;
-               ranges = <0 0 0x08000000 0x04000000>,
-                        <1 0 0x14000000 0x04000000>,
-                        <2 0 0x18000000 0x04000000>,
-                        <3 0 0x1c000000 0x04000000>,
-                        <4 0 0x0c000000 0x04000000>,
-                        <5 0 0x10000000 0x04000000>;
-
-               #interrupt-cells = <1>;
-               interrupt-map-mask = <0 0 63>;
-               interrupt-map = <0 0  0 &gic 0  0 4>,
-                               <0 0  1 &gic 0  1 4>,
-                               <0 0  2 &gic 0  2 4>,
-                               <0 0  3 &gic 0  3 4>,
-                               <0 0  4 &gic 0  4 4>,
-                               <0 0  5 &gic 0  5 4>,
-                               <0 0  6 &gic 0  6 4>,
-                               <0 0  7 &gic 0  7 4>,
-                               <0 0  8 &gic 0  8 4>,
-                               <0 0  9 &gic 0  9 4>,
-                               <0 0 10 &gic 0 10 4>,
-                               <0 0 11 &gic 0 11 4>,
-                               <0 0 12 &gic 0 12 4>,
-                               <0 0 13 &gic 0 13 4>,
-                               <0 0 14 &gic 0 14 4>,
-                               <0 0 15 &gic 0 15 4>,
-                               <0 0 16 &gic 0 16 4>,
-                               <0 0 17 &gic 0 17 4>,
-                               <0 0 18 &gic 0 18 4>,
-                               <0 0 19 &gic 0 19 4>,
-                               <0 0 20 &gic 0 20 4>,
-                               <0 0 21 &gic 0 21 4>,
-                               <0 0 22 &gic 0 22 4>,
-                               <0 0 23 &gic 0 23 4>,
-                               <0 0 24 &gic 0 24 4>,
-                               <0 0 25 &gic 0 25 4>,
-                               <0 0 26 &gic 0 26 4>,
-                               <0 0 27 &gic 0 27 4>,
-                               <0 0 28 &gic 0 28 4>,
-                               <0 0 29 &gic 0 29 4>,
-                               <0 0 30 &gic 0 30 4>,
-                               <0 0 31 &gic 0 31 4>,
-                               <0 0 32 &gic 0 32 4>,
-                               <0 0 33 &gic 0 33 4>,
-                               <0 0 34 &gic 0 34 4>,
-                               <0 0 35 &gic 0 35 4>,
-                               <0 0 36 &gic 0 36 4>,
-                               <0 0 37 &gic 0 37 4>,
-                               <0 0 38 &gic 0 38 4>,
-                               <0 0 39 &gic 0 39 4>,
-                               <0 0 40 &gic 0 40 4>,
-                               <0 0 41 &gic 0 41 4>,
-                               <0 0 42 &gic 0 42 4>;
+               ranges = <0 0x8000000 0x18000000>;
        };
 
        site2: hsb@40000000 {
index 4c58479..5916e48 100644 (file)
                };
        };
 
-       smb: bus@4000000 {
-               compatible = "simple-bus";
-
-               #address-cells = <2>;
-               #size-cells = <1>;
-               ranges = <0 0 0x40000000 0x04000000>,
-                        <1 0 0x44000000 0x04000000>,
-                        <2 0 0x48000000 0x04000000>,
-                        <3 0 0x4c000000 0x04000000>,
-                        <7 0 0x10000000 0x00020000>;
-
-               #interrupt-cells = <1>;
-               interrupt-map-mask = <0 0 63>;
-               interrupt-map = <0 0  0 &gic 0  0 4>,
-                               <0 0  1 &gic 0  1 4>,
-                               <0 0  2 &gic 0  2 4>,
-                               <0 0  3 &gic 0  3 4>,
-                               <0 0  4 &gic 0  4 4>,
-                               <0 0  5 &gic 0  5 4>,
-                               <0 0  6 &gic 0  6 4>,
-                               <0 0  7 &gic 0  7 4>,
-                               <0 0  8 &gic 0  8 4>,
-                               <0 0  9 &gic 0  9 4>,
-                               <0 0 10 &gic 0 10 4>,
-                               <0 0 11 &gic 0 11 4>,
-                               <0 0 12 &gic 0 12 4>,
-                               <0 0 13 &gic 0 13 4>,
-                               <0 0 14 &gic 0 14 4>,
-                               <0 0 15 &gic 0 15 4>,
-                               <0 0 16 &gic 0 16 4>,
-                               <0 0 17 &gic 0 17 4>,
-                               <0 0 18 &gic 0 18 4>,
-                               <0 0 19 &gic 0 19 4>,
-                               <0 0 20 &gic 0 20 4>,
-                               <0 0 21 &gic 0 21 4>,
-                               <0 0 22 &gic 0 22 4>,
-                               <0 0 23 &gic 0 23 4>,
-                               <0 0 24 &gic 0 24 4>,
-                               <0 0 25 &gic 0 25 4>,
-                               <0 0 26 &gic 0 26 4>,
-                               <0 0 27 &gic 0 27 4>,
-                               <0 0 28 &gic 0 28 4>,
-                               <0 0 29 &gic 0 29 4>,
-                               <0 0 30 &gic 0 30 4>,
-                               <0 0 31 &gic 0 31 4>,
-                               <0 0 32 &gic 0 32 4>,
-                               <0 0 33 &gic 0 33 4>,
-                               <0 0 34 &gic 0 34 4>,
-                               <0 0 35 &gic 0 35 4>,
-                               <0 0 36 &gic 0 36 4>,
-                               <0 0 37 &gic 0 37 4>,
-                               <0 0 38 &gic 0 38 4>,
-                               <0 0 39 &gic 0 39 4>,
-                               <0 0 40 &gic 0 40 4>,
-                               <0 0 41 &gic 0 41 4>,
-                               <0 0 42 &gic 0 42 4>;
-       };
-
        site2: hsb@e0000000 {
                compatible = "simple-bus";
                #address-cells = <1>;
index efeb572..6237ede 100644 (file)
@@ -40,7 +40,9 @@ EXPORT_SYMBOL(sharpsl_param);
 
 void sharpsl_save_param(void)
 {
-       memcpy(&sharpsl_param, param_start(PARAM_BASE), sizeof(struct sharpsl_param_info));
+       struct sharpsl_param_info *params = param_start(PARAM_BASE);
+
+       memcpy(&sharpsl_param, params, sizeof(*params));
 
        if (sharpsl_param.comadj_keyword != COMADJ_MAGIC)
                sharpsl_param.comadj=-1;
index d2d5f1c..e6ff844 100644 (file)
@@ -76,6 +76,7 @@ CONFIG_REGULATOR_FIXED_VOLTAGE=y
 CONFIG_DRM=y
 CONFIG_DRM_PANEL_ILITEK_IL9322=y
 CONFIG_DRM_TVE200=y
+CONFIG_FB=y
 CONFIG_LOGO=y
 CONFIG_USB=y
 CONFIG_USB_MON=y
index ccee86d..5e4128d 100644 (file)
@@ -292,6 +292,7 @@ CONFIG_DRM_IMX_LDB=y
 CONFIG_DRM_IMX_HDMI=y
 CONFIG_DRM_ETNAVIV=y
 CONFIG_DRM_MXSFB=y
+CONFIG_FB=y
 CONFIG_FB_MODE_HELPERS=y
 CONFIG_LCD_CLASS_DEVICE=y
 CONFIG_LCD_L4F00242T03=y
index ba67c47..3357299 100644 (file)
@@ -197,7 +197,6 @@ CONFIG_PCI_EPF_TEST=m
 CONFIG_DEVTMPFS=y
 CONFIG_DEVTMPFS_MOUNT=y
 CONFIG_OMAP_OCP2SCP=y
-CONFIG_SIMPLE_PM_BUS=y
 CONFIG_MTD=y
 CONFIG_MTD_CMDLINE_PARTS=y
 CONFIG_MTD_BLOCK=y
@@ -456,6 +455,7 @@ CONFIG_PINCTRL_STMFX=y
 CONFIG_PINCTRL_PALMAS=y
 CONFIG_PINCTRL_OWL=y
 CONFIG_PINCTRL_S500=y
+CONFIG_PINCTRL_MSM=y
 CONFIG_PINCTRL_APQ8064=y
 CONFIG_PINCTRL_APQ8084=y
 CONFIG_PINCTRL_IPQ8064=y
@@ -725,6 +725,7 @@ CONFIG_DRM_PL111=m
 CONFIG_DRM_LIMA=m
 CONFIG_DRM_PANFROST=m
 CONFIG_DRM_ASPEED_GFX=m
+CONFIG_FB=y
 CONFIG_FB_EFI=y
 CONFIG_FB_WM8505=y
 CONFIG_FB_SH_MOBILE_LCDC=y
@@ -1122,6 +1123,7 @@ CONFIG_PHY_DM816X_USB=m
 CONFIG_OMAP_USB2=y
 CONFIG_TI_PIPE3=y
 CONFIG_TWL4030_USB=m
+CONFIG_RAS=y
 CONFIG_NVMEM_IMX_OCOTP=y
 CONFIG_ROCKCHIP_EFUSE=m
 CONFIG_NVMEM_SUNXI_SID=y
index cae0db6..de37f7e 100644 (file)
@@ -46,7 +46,6 @@ CONFIG_DEVTMPFS=y
 CONFIG_DEVTMPFS_MOUNT=y
 CONFIG_DMA_CMA=y
 CONFIG_CMA_SIZE_MBYTES=64
-CONFIG_SIMPLE_PM_BUS=y
 CONFIG_MTD=y
 CONFIG_MTD_CMDLINE_PARTS=y
 CONFIG_MTD_BLOCK=y
index d9a27e4..18d2a96 100644 (file)
@@ -40,7 +40,6 @@ CONFIG_PCI_RCAR_GEN2=y
 CONFIG_PCIE_RCAR_HOST=y
 CONFIG_DEVTMPFS=y
 CONFIG_DEVTMPFS_MOUNT=y
-CONFIG_SIMPLE_PM_BUS=y
 CONFIG_MTD=y
 CONFIG_MTD_BLOCK=y
 CONFIG_MTD_CFI=y
index d6cfe7c..8711d68 100644 (file)
@@ -47,12 +47,26 @@ struct at91_pm_bu {
        unsigned long ddr_phy_calibration[BACKUP_DDR_PHY_CALIBRATION];
 };
 
+/*
+ * struct at91_pm_sfrbu_offsets: registers mapping for SFRBU
+ * @pswbu: power switch BU control registers
+ */
+struct at91_pm_sfrbu_regs {
+       struct {
+               u32 key;
+               u32 ctrl;
+               u32 state;
+               u32 softsw;
+       } pswbu;
+};
+
 /**
  * struct at91_soc_pm - AT91 SoC power management data structure
  * @config_shdwc_ws: wakeup sources configuration function for SHDWC
  * @config_pmc_ws: wakeup srouces configuration function for PMC
  * @ws_ids: wakup sources of_device_id array
  * @data: PM data to be used on last phase of suspend
+ * @sfrbu_regs: SFRBU registers mapping
  * @bu: backup unit mapped data (for backup mode)
  * @memcs: memory chip select
  */
@@ -62,6 +76,7 @@ struct at91_soc_pm {
        const struct of_device_id *ws_ids;
        struct at91_pm_bu *bu;
        struct at91_pm_data data;
+       struct at91_pm_sfrbu_regs sfrbu_regs;
        void *memcs;
 };
 
@@ -356,9 +371,36 @@ static int at91_suspend_finish(unsigned long val)
        return 0;
 }
 
+static void at91_pm_switch_ba_to_vbat(void)
+{
+       unsigned int offset = offsetof(struct at91_pm_sfrbu_regs, pswbu);
+       unsigned int val;
+
+       /* Just for safety. */
+       if (!soc_pm.data.sfrbu)
+               return;
+
+       val = readl(soc_pm.data.sfrbu + offset);
+
+       /* Already on VBAT. */
+       if (!(val & soc_pm.sfrbu_regs.pswbu.state))
+               return;
+
+       val &= ~soc_pm.sfrbu_regs.pswbu.softsw;
+       val |= soc_pm.sfrbu_regs.pswbu.key | soc_pm.sfrbu_regs.pswbu.ctrl;
+       writel(val, soc_pm.data.sfrbu + offset);
+
+       /* Wait for update. */
+       val = readl(soc_pm.data.sfrbu + offset);
+       while (val & soc_pm.sfrbu_regs.pswbu.state)
+               val = readl(soc_pm.data.sfrbu + offset);
+}
+
 static void at91_pm_suspend(suspend_state_t state)
 {
        if (soc_pm.data.mode == AT91_PM_BACKUP) {
+               at91_pm_switch_ba_to_vbat();
+
                cpu_suspend(0, at91_suspend_finish);
 
                /* The SRAM is lost between suspend cycles */
@@ -589,18 +631,22 @@ static const struct of_device_id ramc_phy_ids[] __initconst = {
        { /* Sentinel. */ },
 };
 
-static __init void at91_dt_ramc(bool phy_mandatory)
+static __init int at91_dt_ramc(bool phy_mandatory)
 {
        struct device_node *np;
        const struct of_device_id *of_id;
        int idx = 0;
        void *standby = NULL;
        const struct ramc_info *ramc;
+       int ret;
 
        for_each_matching_node_and_match(np, ramc_ids, &of_id) {
                soc_pm.data.ramc[idx] = of_iomap(np, 0);
-               if (!soc_pm.data.ramc[idx])
-                       panic(pr_fmt("unable to map ramc[%d] cpu registers\n"), idx);
+               if (!soc_pm.data.ramc[idx]) {
+                       pr_err("unable to map ramc[%d] cpu registers\n", idx);
+                       ret = -ENOMEM;
+                       goto unmap_ramc;
+               }
 
                ramc = of_id->data;
                if (ramc) {
@@ -612,25 +658,42 @@ static __init void at91_dt_ramc(bool phy_mandatory)
                idx++;
        }
 
-       if (!idx)
-               panic(pr_fmt("unable to find compatible ram controller node in dtb\n"));
+       if (!idx) {
+               pr_err("unable to find compatible ram controller node in dtb\n");
+               ret = -ENODEV;
+               goto unmap_ramc;
+       }
 
        /* Lookup for DDR PHY node, if any. */
        for_each_matching_node_and_match(np, ramc_phy_ids, &of_id) {
                soc_pm.data.ramc_phy = of_iomap(np, 0);
-               if (!soc_pm.data.ramc_phy)
-                       panic(pr_fmt("unable to map ramc phy cpu registers\n"));
+               if (!soc_pm.data.ramc_phy) {
+                       pr_err("unable to map ramc phy cpu registers\n");
+                       ret = -ENOMEM;
+                       goto unmap_ramc;
+               }
        }
 
-       if (phy_mandatory && !soc_pm.data.ramc_phy)
-               panic(pr_fmt("DDR PHY is mandatory!\n"));
+       if (phy_mandatory && !soc_pm.data.ramc_phy) {
+               pr_err("DDR PHY is mandatory!\n");
+               ret = -ENODEV;
+               goto unmap_ramc;
+       }
 
        if (!standby) {
                pr_warn("ramc no standby function available\n");
-               return;
+               return 0;
        }
 
        at91_cpuidle_device.dev.platform_data = standby;
+
+       return 0;
+
+unmap_ramc:
+       while (idx)
+               iounmap(soc_pm.data.ramc[--idx]);
+
+       return ret;
 }
 
 static void at91rm9200_idle(void)
@@ -1017,6 +1080,8 @@ static void __init at91_pm_init(void (*pm_idle)(void))
 
 void __init at91rm9200_pm_init(void)
 {
+       int ret;
+
        if (!IS_ENABLED(CONFIG_SOC_AT91RM9200))
                return;
 
@@ -1028,7 +1093,9 @@ void __init at91rm9200_pm_init(void)
        soc_pm.data.standby_mode = AT91_PM_STANDBY;
        soc_pm.data.suspend_mode = AT91_PM_ULP0;
 
-       at91_dt_ramc(false);
+       ret = at91_dt_ramc(false);
+       if (ret)
+               return;
 
        /*
         * AT91RM9200 SDRAM low-power mode cannot be used with self-refresh.
@@ -1046,13 +1113,17 @@ void __init sam9x60_pm_init(void)
        static const int iomaps[] __initconst = {
                [AT91_PM_ULP1]          = AT91_PM_IOMAP(SHDWC),
        };
+       int ret;
 
        if (!IS_ENABLED(CONFIG_SOC_SAM9X60))
                return;
 
        at91_pm_modes_validate(modes, ARRAY_SIZE(modes));
        at91_pm_modes_init(iomaps, ARRAY_SIZE(iomaps));
-       at91_dt_ramc(false);
+       ret = at91_dt_ramc(false);
+       if (ret)
+               return;
+
        at91_pm_init(NULL);
 
        soc_pm.ws_ids = sam9x60_ws_ids;
@@ -1061,6 +1132,8 @@ void __init sam9x60_pm_init(void)
 
 void __init at91sam9_pm_init(void)
 {
+       int ret;
+
        if (!IS_ENABLED(CONFIG_SOC_AT91SAM9))
                return;
 
@@ -1072,7 +1145,10 @@ void __init at91sam9_pm_init(void)
        soc_pm.data.standby_mode = AT91_PM_STANDBY;
        soc_pm.data.suspend_mode = AT91_PM_ULP0;
 
-       at91_dt_ramc(false);
+       ret = at91_dt_ramc(false);
+       if (ret)
+               return;
+
        at91_pm_init(at91sam9_idle);
 }
 
@@ -1081,12 +1157,16 @@ void __init sama5_pm_init(void)
        static const int modes[] __initconst = {
                AT91_PM_STANDBY, AT91_PM_ULP0, AT91_PM_ULP0_FAST,
        };
+       int ret;
 
        if (!IS_ENABLED(CONFIG_SOC_SAMA5))
                return;
 
        at91_pm_modes_validate(modes, ARRAY_SIZE(modes));
-       at91_dt_ramc(false);
+       ret = at91_dt_ramc(false);
+       if (ret)
+               return;
+
        at91_pm_init(NULL);
 }
 
@@ -1101,18 +1181,27 @@ void __init sama5d2_pm_init(void)
                [AT91_PM_BACKUP]        = AT91_PM_IOMAP(SHDWC) |
                                          AT91_PM_IOMAP(SFRBU),
        };
+       int ret;
 
        if (!IS_ENABLED(CONFIG_SOC_SAMA5D2))
                return;
 
        at91_pm_modes_validate(modes, ARRAY_SIZE(modes));
        at91_pm_modes_init(iomaps, ARRAY_SIZE(iomaps));
-       at91_dt_ramc(false);
+       ret = at91_dt_ramc(false);
+       if (ret)
+               return;
+
        at91_pm_init(NULL);
 
        soc_pm.ws_ids = sama5d2_ws_ids;
        soc_pm.config_shdwc_ws = at91_sama5d2_config_shdwc_ws;
        soc_pm.config_pmc_ws = at91_sama5d2_config_pmc_ws;
+
+       soc_pm.sfrbu_regs.pswbu.key = (0x4BD20C << 8);
+       soc_pm.sfrbu_regs.pswbu.ctrl = BIT(0);
+       soc_pm.sfrbu_regs.pswbu.softsw = BIT(1);
+       soc_pm.sfrbu_regs.pswbu.state = BIT(3);
 }
 
 void __init sama7_pm_init(void)
@@ -1127,18 +1216,27 @@ void __init sama7_pm_init(void)
                [AT91_PM_BACKUP]        = AT91_PM_IOMAP(SFRBU) |
                                          AT91_PM_IOMAP(SHDWC),
        };
+       int ret;
 
        if (!IS_ENABLED(CONFIG_SOC_SAMA7))
                return;
 
        at91_pm_modes_validate(modes, ARRAY_SIZE(modes));
 
-       at91_dt_ramc(true);
+       ret = at91_dt_ramc(true);
+       if (ret)
+               return;
+
        at91_pm_modes_init(iomaps, ARRAY_SIZE(iomaps));
        at91_pm_init(NULL);
 
        soc_pm.ws_ids = sama7g5_ws_ids;
        soc_pm.config_pmc_ws = at91_sam9x60_config_pmc_ws;
+
+       soc_pm.sfrbu_regs.pswbu.key = (0x4BD20C << 8);
+       soc_pm.sfrbu_regs.pswbu.ctrl = BIT(0);
+       soc_pm.sfrbu_regs.pswbu.softsw = BIT(1);
+       soc_pm.sfrbu_regs.pswbu.state = BIT(2);
 }
 
 static int __init at91_pm_modes_select(char *str)
index cbd61a3..fdb4f63 100644 (file)
@@ -1014,31 +1014,55 @@ ENTRY(at91_pm_suspend_in_sram)
        mov     tmp1, #0
        mcr     p15, 0, tmp1, c7, c10, 4
 
+       /* Flush tlb. */
+       mov     r4, #0
+       mcr     p15, 0, r4, c8, c7, 0
+
+       ldr     tmp1, [r0, #PM_DATA_PMC_MCKR_OFFSET]
+       str     tmp1, .mckr_offset
+       ldr     tmp1, [r0, #PM_DATA_PMC_VERSION]
+       str     tmp1, .pmc_version
+       ldr     tmp1, [r0, #PM_DATA_MEMCTRL]
+       str     tmp1, .memtype
+       ldr     tmp1, [r0, #PM_DATA_MODE]
+       str     tmp1, .pm_mode
+
+       /*
+        * ldrne below are here to preload their address in the TLB as access
+        * to RAM may be limited while in self-refresh.
+        */
        ldr     tmp1, [r0, #PM_DATA_PMC]
        str     tmp1, .pmc_base
+       cmp     tmp1, #0
+       ldrne   tmp2, [tmp1, #0]
+
        ldr     tmp1, [r0, #PM_DATA_RAMC0]
        str     tmp1, .sramc_base
+       cmp     tmp1, #0
+       ldrne   tmp2, [tmp1, #0]
+
        ldr     tmp1, [r0, #PM_DATA_RAMC1]
        str     tmp1, .sramc1_base
+       cmp     tmp1, #0
+       ldrne   tmp2, [tmp1, #0]
+
+#ifndef CONFIG_SOC_SAM_V4_V5
+       /* ldrne below are here to preload their address in the TLB */
        ldr     tmp1, [r0, #PM_DATA_RAMC_PHY]
        str     tmp1, .sramc_phy_base
-       ldr     tmp1, [r0, #PM_DATA_MEMCTRL]
-       str     tmp1, .memtype
-       ldr     tmp1, [r0, #PM_DATA_MODE]
-       str     tmp1, .pm_mode
-       ldr     tmp1, [r0, #PM_DATA_PMC_MCKR_OFFSET]
-       str     tmp1, .mckr_offset
-       ldr     tmp1, [r0, #PM_DATA_PMC_VERSION]
-       str     tmp1, .pmc_version
-       /* Both ldrne below are here to preload their address in the TLB */
+       cmp     tmp1, #0
+       ldrne   tmp2, [tmp1, #0]
+
        ldr     tmp1, [r0, #PM_DATA_SHDWC]
        str     tmp1, .shdwc
        cmp     tmp1, #0
        ldrne   tmp2, [tmp1, #0]
+
        ldr     tmp1, [r0, #PM_DATA_SFRBU]
        str     tmp1, .sfrbu
        cmp     tmp1, #0
        ldrne   tmp2, [tmp1, #0x10]
+#endif
 
        /* Active the self-refresh mode */
        at91_sramc_self_refresh_ena
index 7a4bd88..ddf873f 100644 (file)
@@ -11,7 +11,7 @@
 
 #define LSR_THRE       0x20
 
-static void putc(const char c)
+static inline void putc(const char c)
 {
        int i;
 
@@ -24,7 +24,7 @@ static void putc(const char c)
        *UART_THR = c;
 }
 
-static void flush(void)
+static inline void flush(void)
 {
 }
 
index 11dcc36..c9d7c29 100644 (file)
@@ -172,6 +172,9 @@ static void __init imx6q_init_machine(void)
                                imx_get_soc_revision());
 
        imx6q_enet_phy_init();
+
+       of_platform_default_populate(NULL, NULL, NULL);
+
        imx_anatop_init();
        cpu_is_imx6q() ?  imx6q_pm_init() : imx6dl_pm_init();
        imx6q_1588_init();
index 9244437..f2ecca3 100644 (file)
@@ -10,6 +10,7 @@
 #include <linux/io.h>
 #include <linux/irq.h>
 #include <linux/genalloc.h>
+#include <linux/irqchip/arm-gic.h>
 #include <linux/mfd/syscon.h>
 #include <linux/mfd/syscon/imx6q-iomuxc-gpr.h>
 #include <linux/of.h>
@@ -619,6 +620,7 @@ static void __init imx6_pm_common_init(const struct imx6_pm_socdata
 
 static void imx6_pm_stby_poweroff(void)
 {
+       gic_cpu_if_down(0);
        imx6_set_lpm(STOP_POWER_OFF);
        imx6q_suspend_finish(0);
 
index 95fd1fb..59a8e8c 100644 (file)
@@ -9,6 +9,7 @@
 #include <linux/iopoll.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
+#include <linux/platform_device.h>
 #include <linux/reset-controller.h>
 #include <linux/smp.h>
 #include <asm/smp_plat.h>
@@ -81,11 +82,6 @@ static const struct reset_control_ops imx_src_ops = {
        .reset = imx_src_reset_module,
 };
 
-static struct reset_controller_dev imx_reset_controller = {
-       .ops = &imx_src_ops,
-       .nr_resets = ARRAY_SIZE(sw_reset_bits),
-};
-
 static void imx_gpcv2_set_m_core_pgc(bool enable, u32 offset)
 {
        writel_relaxed(enable, gpc_base + offset);
@@ -177,10 +173,6 @@ void __init imx_src_init(void)
        src_base = of_iomap(np, 0);
        WARN_ON(!src_base);
 
-       imx_reset_controller.of_node = np;
-       if (IS_ENABLED(CONFIG_RESET_CONTROLLER))
-               reset_controller_register(&imx_reset_controller);
-
        /*
         * force warm reset sources to generate cold reset
         * for a more reliable restart
@@ -214,3 +206,33 @@ void __init imx7_src_init(void)
        if (!gpc_base)
                return;
 }
+
+static const struct of_device_id imx_src_dt_ids[] = {
+       { .compatible = "fsl,imx51-src" },
+       { /* sentinel */ }
+};
+
+static int imx_src_probe(struct platform_device *pdev)
+{
+       struct reset_controller_dev *rcdev;
+
+       rcdev = devm_kzalloc(&pdev->dev, sizeof(*rcdev), GFP_KERNEL);
+       if (!rcdev)
+               return -ENOMEM;
+
+       rcdev->ops = &imx_src_ops;
+       rcdev->dev = &pdev->dev;
+       rcdev->of_node = pdev->dev.of_node;
+       rcdev->nr_resets = ARRAY_SIZE(sw_reset_bits);
+
+       return devm_reset_controller_register(&pdev->dev, rcdev);
+}
+
+static struct platform_driver imx_src_driver = {
+       .driver = {
+               .name = "imx-src",
+               .of_match_table = imx_src_dt_ids,
+       },
+       .probe = imx_src_probe,
+};
+builtin_platform_driver(imx_src_driver);
index 36bc000..ba3a350 100644 (file)
@@ -9,16 +9,4 @@
 /* REVISIT: omap1 legacy drivers still rely on this */
 #include <mach/soc.h>
 
-/*
- * Bus address is physical address, except for OMAP-1510 Local Bus.
- * OMAP-1510 bus address is translated into a Local Bus address if the
- * OMAP bus type is lbus. We do the address translation based on the
- * device overriding the defaults used in the dma-mapping API.
- */
-
-/*
- * OMAP-1510 Local Bus address offset
- */
-#define OMAP1510_LB_OFFSET     UL(0x30000000)
-
 #endif
index 86d3b3c..e60831c 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/platform_device.h>
 #include <linux/dma-map-ops.h>
 #include <linux/io.h>
+#include <linux/delay.h>
 
 #include <asm/irq.h>
 
@@ -206,8 +207,6 @@ static inline void udc_device_init(struct omap_usb_config *pdata)
 
 #endif
 
-#if    IS_ENABLED(CONFIG_USB_OHCI_HCD)
-
 /* The dmamask must be set for OHCI to work */
 static u64 ohci_dmamask = ~(u32)0;
 
@@ -236,20 +235,15 @@ static struct platform_device ohci_device = {
 
 static inline void ohci_device_init(struct omap_usb_config *pdata)
 {
+       if (!IS_ENABLED(CONFIG_USB_OHCI_HCD))
+               return;
+
        if (cpu_is_omap7xx())
                ohci_resources[1].start = INT_7XX_USB_HHC_1;
        pdata->ohci_device = &ohci_device;
        pdata->ocpi_enable = &ocpi_enable;
 }
 
-#else
-
-static inline void ohci_device_init(struct omap_usb_config *pdata)
-{
-}
-
-#endif
-
 #if    defined(CONFIG_USB_OTG) && defined(CONFIG_ARCH_OMAP_OTG)
 
 static struct resource otg_resources[] = {
@@ -534,33 +528,87 @@ bad:
 }
 
 #ifdef CONFIG_ARCH_OMAP15XX
+/* OMAP-1510 OHCI has its own MMU for DMA */
+#define OMAP1510_LB_MEMSIZE    32      /* Should be same as SDRAM size */
+#define OMAP1510_LB_CLOCK_DIV  0xfffec10c
+#define OMAP1510_LB_MMU_CTL    0xfffec208
+#define OMAP1510_LB_MMU_LCK    0xfffec224
+#define OMAP1510_LB_MMU_LD_TLB 0xfffec228
+#define OMAP1510_LB_MMU_CAM_H  0xfffec22c
+#define OMAP1510_LB_MMU_CAM_L  0xfffec230
+#define OMAP1510_LB_MMU_RAM_H  0xfffec234
+#define OMAP1510_LB_MMU_RAM_L  0xfffec238
 
-/* ULPD_DPLL_CTRL */
-#define DPLL_IOB               (1 << 13)
-#define DPLL_PLL_ENABLE                (1 << 4)
-#define DPLL_LOCK              (1 << 0)
+/*
+ * Bus address is physical address, except for OMAP-1510 Local Bus.
+ * OMAP-1510 bus address is translated into a Local Bus address if the
+ * OMAP bus type is lbus.
+ */
+#define OMAP1510_LB_OFFSET        UL(0x30000000)
 
-/* ULPD_APLL_CTRL */
-#define APLL_NDPLL_SWITCH      (1 << 0)
+/*
+ * OMAP-1510 specific Local Bus clock on/off
+ */
+static int omap_1510_local_bus_power(int on)
+{
+       if (on) {
+               omap_writel((1 << 1) | (1 << 0), OMAP1510_LB_MMU_CTL);
+               udelay(200);
+       } else {
+               omap_writel(0, OMAP1510_LB_MMU_CTL);
+       }
 
-static int omap_1510_usb_ohci_notifier(struct notifier_block *nb,
-               unsigned long event, void *data)
+       return 0;
+}
+
+/*
+ * OMAP-1510 specific Local Bus initialization
+ * NOTE: This assumes 32MB memory size in OMAP1510LB_MEMSIZE.
+ *       See also arch/mach-omap/memory.h for __virt_to_dma() and
+ *       __dma_to_virt() which need to match with the physical
+ *       Local Bus address below.
+ */
+static int omap_1510_local_bus_init(void)
 {
-       struct device *dev = data;
+       unsigned int tlb;
+       unsigned long lbaddr, physaddr;
+
+       omap_writel((omap_readl(OMAP1510_LB_CLOCK_DIV) & 0xfffffff8) | 0x4,
+              OMAP1510_LB_CLOCK_DIV);
+
+       /* Configure the Local Bus MMU table */
+       for (tlb = 0; tlb < OMAP1510_LB_MEMSIZE; tlb++) {
+               lbaddr = tlb * 0x00100000 + OMAP1510_LB_OFFSET;
+               physaddr = tlb * 0x00100000 + PHYS_OFFSET;
+               omap_writel((lbaddr & 0x0fffffff) >> 22, OMAP1510_LB_MMU_CAM_H);
+               omap_writel(((lbaddr & 0x003ffc00) >> 6) | 0xc,
+                      OMAP1510_LB_MMU_CAM_L);
+               omap_writel(physaddr >> 16, OMAP1510_LB_MMU_RAM_H);
+               omap_writel((physaddr & 0x0000fc00) | 0x300, OMAP1510_LB_MMU_RAM_L);
+               omap_writel(tlb << 4, OMAP1510_LB_MMU_LCK);
+               omap_writel(0x1, OMAP1510_LB_MMU_LD_TLB);
+       }
 
-       if (event != BUS_NOTIFY_ADD_DEVICE)
-               return NOTIFY_DONE;
+       /* Enable the walking table */
+       omap_writel(omap_readl(OMAP1510_LB_MMU_CTL) | (1 << 3), OMAP1510_LB_MMU_CTL);
+       udelay(200);
 
-       if (strncmp(dev_name(dev), "ohci", 4) == 0 &&
-           dma_direct_set_offset(dev, PHYS_OFFSET, OMAP1510_LB_OFFSET,
-                       (u64)-1))
-               WARN_ONCE(1, "failed to set DMA offset\n");
-       return NOTIFY_OK;
+       return 0;
 }
 
-static struct notifier_block omap_1510_usb_ohci_nb = {
-       .notifier_call          = omap_1510_usb_ohci_notifier,
-};
+static void omap_1510_local_bus_reset(void)
+{
+       omap_1510_local_bus_power(1);
+       omap_1510_local_bus_init();
+}
+
+/* ULPD_DPLL_CTRL */
+#define DPLL_IOB               (1 << 13)
+#define DPLL_PLL_ENABLE                (1 << 4)
+#define DPLL_LOCK              (1 << 0)
+
+/* ULPD_APLL_CTRL */
+#define APLL_NDPLL_SWITCH      (1 << 0)
 
 static void __init omap_1510_usb_init(struct omap_usb_config *config)
 {
@@ -616,19 +664,19 @@ static void __init omap_1510_usb_init(struct omap_usb_config *config)
        }
 #endif
 
-#if    IS_ENABLED(CONFIG_USB_OHCI_HCD)
-       if (config->register_host) {
+       if (IS_ENABLED(CONFIG_USB_OHCI_HCD) && config->register_host) {
                int status;
 
-               bus_register_notifier(&platform_bus_type,
-                                     &omap_1510_usb_ohci_nb);
                ohci_device.dev.platform_data = config;
+               dma_direct_set_offset(&ohci_device.dev, PHYS_OFFSET,
+                                     OMAP1510_LB_OFFSET, (u64)-1);
                status = platform_device_register(&ohci_device);
                if (status)
                        pr_debug("can't register OHCI device, %d\n", status);
                /* hcd explicitly gates 48MHz */
+
+               config->lb_reset = omap_1510_local_bus_reset;
        }
-#endif
 }
 
 #else
index 7f13adf..02c253d 100644 (file)
@@ -112,7 +112,6 @@ config ARCH_OMAP2PLUS
        select PM_GENERIC_DOMAINS
        select PM_GENERIC_DOMAINS_OF
        select RESET_CONTROLLER
-       select SIMPLE_PM_BUS
        select SOC_BUS
        select TI_SYSC
        select OMAP_IRQCHIP
index 12b26e0..0c2936c 100644 (file)
@@ -3614,6 +3614,8 @@ int omap_hwmod_init_module(struct device *dev,
                oh->flags |= HWMOD_SWSUP_SIDLE_ACT;
        if (data->cfg->quirks & SYSC_QUIRK_SWSUP_MSTANDBY)
                oh->flags |= HWMOD_SWSUP_MSTANDBY;
+       if (data->cfg->quirks & SYSC_QUIRK_CLKDM_NOAUTO)
+               oh->flags |= HWMOD_CLKDM_NOAUTO;
 
        error = omap_hwmod_check_module(dev, oh, data, sysc_fields,
                                        rev_offs, sysc_offs, syss_offs,
index a951276..a903b26 100644 (file)
  *                        +-----+
  *                        |RSVD | JIT scratchpad
  * current ARM_SP =>      +-----+ <= (BPF_FP - STACK_SIZE + SCRATCH_SIZE)
+ *                        | ... | caller-saved registers
+ *                        +-----+
+ *                        | ... | arguments passed on stack
+ * ARM_SP during call =>  +-----|
  *                        |     |
  *                        | ... | Function call stack
  *                        |     |
  *
  * When popping registers off the stack at the end of a BPF function, we
  * reference them via the current ARM_FP register.
+ *
+ * Some eBPF operations are implemented via a call to a helper function.
+ * Such calls are "invisible" in the eBPF code, so it is up to the calling
+ * program to preserve any caller-saved ARM registers during the call. The
+ * JIT emits code to push and pop those registers onto the stack, immediately
+ * above the callee stack frame.
  */
 #define CALLEE_MASK    (1 << ARM_R4 | 1 << ARM_R5 | 1 << ARM_R6 | \
                         1 << ARM_R7 | 1 << ARM_R8 | 1 << ARM_R9 | \
@@ -70,6 +80,8 @@
 #define CALLEE_PUSH_MASK (CALLEE_MASK | 1 << ARM_LR)
 #define CALLEE_POP_MASK  (CALLEE_MASK | 1 << ARM_PC)
 
+#define CALLER_MASK    (1 << ARM_R0 | 1 << ARM_R1 | 1 << ARM_R2 | 1 << ARM_R3)
+
 enum {
        /* Stack layout - these are offsets from (top of stack - 4) */
        BPF_R2_HI,
@@ -464,6 +476,7 @@ static inline int epilogue_offset(const struct jit_ctx *ctx)
 
 static inline void emit_udivmod(u8 rd, u8 rm, u8 rn, struct jit_ctx *ctx, u8 op)
 {
+       const int exclude_mask = BIT(ARM_R0) | BIT(ARM_R1);
        const s8 *tmp = bpf2a32[TMP_REG_1];
 
 #if __LINUX_ARM_ARCH__ == 7
@@ -495,11 +508,17 @@ static inline void emit_udivmod(u8 rd, u8 rm, u8 rn, struct jit_ctx *ctx, u8 op)
                emit(ARM_MOV_R(ARM_R0, rm), ctx);
        }
 
+       /* Push caller-saved registers on stack */
+       emit(ARM_PUSH(CALLER_MASK & ~exclude_mask), ctx);
+
        /* Call appropriate function */
        emit_mov_i(ARM_IP, op == BPF_DIV ?
                   (u32)jit_udiv32 : (u32)jit_mod32, ctx);
        emit_blx_r(ARM_IP, ctx);
 
+       /* Restore caller-saved registers from stack */
+       emit(ARM_POP(CALLER_MASK & ~exclude_mask), ctx);
+
        /* Save return value */
        if (rd != ARM_R0)
                emit(ARM_MOV_R(rd, ARM_R0), ctx);
index 5c7ae4c..fee914c 100644 (file)
@@ -1931,8 +1931,6 @@ source "drivers/cpufreq/Kconfig"
 
 endmenu
 
-source "drivers/firmware/Kconfig"
-
 source "drivers/acpi/Kconfig"
 
 source "arch/arm64/kvm/Kconfig"
index 05ae893..fbf13f7 100644 (file)
 
        bus@8000000 {
                compatible = "arm,vexpress,v2m-p1", "simple-bus";
-               arm,v2m-memory-map = "rs1";
                #address-cells = <2>; /* SMB chipselect number and offset */
                #size-cells = <1>;
 
index b8a2109..269b649 100644 (file)
                                remote-endpoint = <&clcd_pads>;
                        };
                };
-
-              panel-timing {
-                      clock-frequency = <63500127>;
-                      hactive = <1024>;
-                      hback-porch = <152>;
-                      hfront-porch = <48>;
-                      hsync-len = <104>;
-                      vactive = <768>;
-                      vback-porch = <23>;
-                      vfront-porch = <3>;
-                      vsync-len = <4>;
-              };
        };
 
        bus@8000000 {
-               compatible = "simple-bus";
-
-               #address-cells = <2>;
-               #size-cells = <1>;
-               ranges = <0 0 0 0x08000000 0x04000000>,
-                        <1 0 0 0x14000000 0x04000000>,
-                        <2 0 0 0x18000000 0x04000000>,
-                        <3 0 0 0x1c000000 0x04000000>,
-                        <4 0 0 0x0c000000 0x04000000>,
-                        <5 0 0 0x10000000 0x04000000>;
-
                #interrupt-cells = <1>;
                interrupt-map-mask = <0 0 63>;
                interrupt-map = <0 0  0 &gic 0 0 GIC_SPI  0 IRQ_TYPE_LEVEL_HIGH>,
index 8e7a669..6288e10 100644 (file)
@@ -27,8 +27,6 @@
                reg = <0x0 0x2b1f0000 0x0 0x1000>;
                interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>,
                             <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>;
-               interrupt-names = "mhu_lpri_rx",
-                                 "mhu_hpri_rx";
                #mbox-cells = <1>;
                clocks = <&soc_refclk100mhz>;
                clock-names = "apb_pclk";
        };
 
        bus@8000000 {
-               compatible = "simple-bus";
-               #address-cells = <2>;
-               #size-cells = <1>;
-               ranges = <0 0 0 0x08000000 0x04000000>,
-                        <1 0 0 0x14000000 0x04000000>,
-                        <2 0 0 0x18000000 0x04000000>,
-                        <3 0 0 0x1c000000 0x04000000>,
-                        <4 0 0 0x0c000000 0x04000000>,
-                        <5 0 0 0x10000000 0x04000000>;
-
                #interrupt-cells = <1>;
                interrupt-map-mask = <0 0 15>;
                interrupt-map = <0 0  0 &gic 0 GIC_SPI  68 IRQ_TYPE_LEVEL_HIGH>,
index 40d95c5..fefd2b5 100644 (file)
        };
 
        bus@8000000 {
-               motherboard-bus {
+               compatible = "simple-bus";
+               #address-cells = <2>;
+               #size-cells = <1>;
+               ranges = <0 0x8000000 0 0x8000000 0x18000000>;
+
+               motherboard-bus@8000000 {
                        compatible = "arm,vexpress,v2p-p1", "simple-bus";
                        #address-cells = <2>;  /* SMB chipselect number and offset */
                        #size-cells = <1>;
-                       #interrupt-cells = <1>;
-                       ranges;
-                       model = "V2M-Juno";
+                       ranges = <0 0 0 0x08000000 0x04000000>,
+                                <1 0 0 0x14000000 0x04000000>,
+                                <2 0 0 0x18000000 0x04000000>,
+                                <3 0 0 0x1c000000 0x04000000>,
+                                <4 0 0 0x0c000000 0x04000000>,
+                                <5 0 0 0x10000000 0x04000000>;
                        arm,hbi = <0x252>;
                        arm,vexpress,site = <0>;
-                       arm,v2m-memory-map = "rs1";
 
                        flash@0 {
                                /* 2 * 32MiB NOR Flash memory mounted on CS0 */
                                        };
                                };
 
-                               mmci@50000 {
+                               mmc@50000 {
                                        compatible = "arm,pl180", "arm,primecell";
                                        reg = <0x050000 0x1000>;
                                        interrupts = <5>;
                                        clock-names = "KMIREFCLK", "apb_pclk";
                                };
 
-                               wdt@f0000 {
+                               watchdog@f0000 {
                                        compatible = "arm,sp805", "arm,primecell";
                                        reg = <0x0f0000 0x10000>;
                                        interrupts = <7>;
index 3050f45..258991a 100644 (file)
        };
 
        bus@8000000 {
-               compatible = "simple-bus";
-
-               #address-cells = <2>;
-               #size-cells = <1>;
-               ranges = <0 0 0 0x08000000 0x04000000>,
-                        <1 0 0 0x14000000 0x04000000>,
-                        <2 0 0 0x18000000 0x04000000>,
-                        <3 0 0 0x1c000000 0x04000000>,
-                        <4 0 0 0x0c000000 0x04000000>,
-                        <5 0 0 0x10000000 0x04000000>;
-
                #interrupt-cells = <1>;
                interrupt-map-mask = <0 0 63>;
                interrupt-map = <0 0  0 &gic GIC_SPI  0 IRQ_TYPE_LEVEL_HIGH>,
index b917d9d..33182d9 100644 (file)
@@ -6,7 +6,7 @@
  */
 / {
        bus@8000000 {
-               motherboard-bus {
+               motherboard-bus@8000000 {
                        arm,v2m-memory-map = "rs2";
 
                        iofpga-bus@300000000 {
index 4c4a381..5f6cab6 100644 (file)
        };
 
        bus@8000000 {
-               motherboard-bus {
-                       arm,v2m-memory-map = "rs1";
+               compatible = "simple-bus";
+               #address-cells = <2>;
+               #size-cells = <1>;
+               ranges = <0 0x8000000 0 0x8000000 0x18000000>;
+
+               motherboard-bus@8000000 {
                        compatible = "arm,vexpress,v2m-p1", "simple-bus";
                        #address-cells = <2>; /* SMB chipselect number and offset */
                        #size-cells = <1>;
-                       #interrupt-cells = <1>;
-                       ranges;
+                       ranges = <0 0 0 0x08000000 0x04000000>,
+                                <1 0 0 0x14000000 0x04000000>,
+                                <2 0 0 0x18000000 0x04000000>,
+                                <3 0 0 0x1c000000 0x04000000>,
+                                <4 0 0 0x0c000000 0x04000000>,
+                                <5 0 0 0x10000000 0x04000000>;
 
                        flash@0 {
                                compatible = "arm,vexpress-flash", "cfi-flash";
                                        clock-names = "apb_pclk";
                                };
 
-                               mmci@50000 {
+                               mmc@50000 {
                                        compatible = "arm,pl180", "arm,primecell";
                                        reg = <0x050000 0x1000>;
                                        interrupts = <9>, <10>;
                                        clock-names = "uartclk", "apb_pclk";
                                };
 
-                               wdt@f0000 {
+                               watchdog@f0000 {
                                        compatible = "arm,sp805", "arm,primecell";
                                        reg = <0x0f0000 0x1000>;
                                        interrupts = <0>;
index d859914..5b6d9d8 100644 (file)
        };
 
        smb: bus@8000000 {
-               compatible = "simple-bus";
-
-               #address-cells = <2>;
-               #size-cells = <1>;
-               ranges = <0 0 0 0x08000000 0x04000000>,
-                        <1 0 0 0x14000000 0x04000000>,
-                        <2 0 0 0x18000000 0x04000000>,
-                        <3 0 0 0x1c000000 0x04000000>,
-                        <4 0 0 0x0c000000 0x04000000>,
-                        <5 0 0 0x10000000 0x04000000>;
-
-               #interrupt-cells = <1>;
-               interrupt-map-mask = <0 0 63>;
-               interrupt-map = <0 0  0 &gic GIC_SPI  0 IRQ_TYPE_LEVEL_HIGH>,
-                               <0 0  1 &gic GIC_SPI  1 IRQ_TYPE_LEVEL_HIGH>,
-                               <0 0  2 &gic GIC_SPI  2 IRQ_TYPE_LEVEL_HIGH>,
-                               <0 0  3 &gic GIC_SPI  3 IRQ_TYPE_LEVEL_HIGH>,
-                               <0 0  4 &gic GIC_SPI  4 IRQ_TYPE_LEVEL_HIGH>,
-                               <0 0  5 &gic GIC_SPI  5 IRQ_TYPE_LEVEL_HIGH>,
-                               <0 0  6 &gic GIC_SPI  6 IRQ_TYPE_LEVEL_HIGH>,
-                               <0 0  7 &gic GIC_SPI  7 IRQ_TYPE_LEVEL_HIGH>,
-                               <0 0  8 &gic GIC_SPI  8 IRQ_TYPE_LEVEL_HIGH>,
-                               <0 0  9 &gic GIC_SPI  9 IRQ_TYPE_LEVEL_HIGH>,
-                               <0 0 10 &gic GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>,
-                               <0 0 11 &gic GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>,
-                               <0 0 12 &gic GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>,
-                               <0 0 13 &gic GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>,
-                               <0 0 14 &gic GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>,
-                               <0 0 15 &gic GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>,
-                               <0 0 16 &gic GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>,
-                               <0 0 17 &gic GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>,
-                               <0 0 18 &gic GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>,
-                               <0 0 19 &gic GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>,
-                               <0 0 20 &gic GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>,
-                               <0 0 21 &gic GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>,
-                               <0 0 22 &gic GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>,
-                               <0 0 23 &gic GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>,
-                               <0 0 24 &gic GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>,
-                               <0 0 25 &gic GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>,
-                               <0 0 26 &gic GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>,
-                               <0 0 27 &gic GIC_SPI 27 IRQ_TYPE_LEVEL_HIGH>,
-                               <0 0 28 &gic GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>,
-                               <0 0 29 &gic GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>,
-                               <0 0 30 &gic GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>,
-                               <0 0 31 &gic GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>,
-                               <0 0 32 &gic GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>,
-                               <0 0 33 &gic GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>,
-                               <0 0 34 &gic GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>,
-                               <0 0 35 &gic GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>,
-                               <0 0 36 &gic GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>,
-                               <0 0 37 &gic GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>,
-                               <0 0 38 &gic GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>,
-                               <0 0 39 &gic GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>,
-                               <0 0 40 &gic GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>,
-                               <0 0 41 &gic GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>,
-                               <0 0 42 &gic GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>;
+               ranges = <0x8000000 0 0x8000000 0x18000000>;
        };
 };
index 343ecf0..06b36cc 100644 (file)
                        interrupts = <GIC_SPI 63 IRQ_TYPE_LEVEL_HIGH>;
                        clock-frequency = <0>; /* fixed up by bootloader */
                        clocks = <&clockgen QORIQ_CLK_HWACCEL 1>;
-                       voltage-ranges = <1800 1800 3300 3300>;
+                       voltage-ranges = <1800 1800>;
                        sdhci,auto-cmd12;
-                       broken-cd;
+                       non-removable;
                        little-endian;
                        bus-width = <4>;
                        status = "disabled";
index 988f8ab..40f5e7a 100644 (file)
@@ -91,7 +91,7 @@
                #size-cells = <1>;
                compatible = "jedec,spi-nor";
                spi-max-frequency = <80000000>;
-               spi-tx-bus-width = <4>;
+               spi-tx-bus-width = <1>;
                spi-rx-bus-width = <4>;
        };
 };
index 4e2820d..a2b24d4 100644 (file)
@@ -48,7 +48,7 @@
                #size-cells = <1>;
                compatible = "jedec,spi-nor";
                spi-max-frequency = <80000000>;
-               spi-tx-bus-width = <4>;
+               spi-tx-bus-width = <1>;
                spi-rx-bus-width = <4>;
        };
 };
index d0456da..9db9b90 100644 (file)
                                regulator-min-microvolt = <850000>;
                                regulator-max-microvolt = <950000>;
                                regulator-boot-on;
+                               regulator-always-on;
                                regulator-ramp-delay = <3125>;
                                nxp,dvs-run-voltage = <950000>;
                                nxp,dvs-standby-voltage = <850000>;
index 05cb609..d52686f 100644 (file)
        pinctrl_hog: hoggrp {
                fsl,pins = <
                        MX8MM_IOMUXC_NAND_CE0_B_GPIO3_IO1       0x40000159 /* M2_GDIS# */
-                       MX8MM_IOMUXC_GPIO1_IO12_GPIO1_IO12      0x40000041 /* M2_RST# */
+                       MX8MM_IOMUXC_GPIO1_IO13_GPIO1_IO13      0x40000041 /* M2_RST# */
                        MX8MM_IOMUXC_NAND_DATA01_GPIO3_IO7      0x40000119 /* M2_OFF# */
                        MX8MM_IOMUXC_GPIO1_IO15_GPIO1_IO15      0x40000159 /* M2_WDIS# */
                        MX8MM_IOMUXC_SAI1_TXD2_GPIO4_IO14       0x40000041 /* AMP GPIO1 */
index 54eaf3d..3b2d627 100644 (file)
                #size-cells = <1>;
                compatible = "jedec,spi-nor";
                spi-max-frequency = <80000000>;
-               spi-tx-bus-width = <4>;
+               spi-tx-bus-width = <1>;
                spi-rx-bus-width = <4>;
        };
 };
index e77db49..236f425 100644 (file)
        pinctrl_hog: hoggrp {
                fsl,pins = <
                        MX8MN_IOMUXC_NAND_CE0_B_GPIO3_IO1       0x40000159 /* M2_GDIS# */
-                       MX8MN_IOMUXC_GPIO1_IO12_GPIO1_IO12      0x40000041 /* M2_RST# */
+                       MX8MN_IOMUXC_GPIO1_IO13_GPIO1_IO13      0x40000041 /* M2_RST# */
                        MX8MN_IOMUXC_NAND_DATA01_GPIO3_IO7      0x40000119 /* M2_OFF# */
                        MX8MN_IOMUXC_GPIO1_IO15_GPIO1_IO15      0x40000159 /* M2_WDIS# */
                        MX8MN_IOMUXC_SAI2_RXFS_GPIO4_IO21       0x40000041 /* APP GPIO1 */
index aa78e0d..fc178ee 100644 (file)
@@ -74,7 +74,7 @@
                compatible = "jedec,spi-nor";
                reg = <0>;
                spi-max-frequency = <80000000>;
-               spi-tx-bus-width = <4>;
+               spi-tx-bus-width = <1>;
                spi-rx-bus-width = <4>;
        };
 };
index 49f9db9..b83df77 100644 (file)
                #size-cells = <1>;
                compatible = "micron,n25q256a", "jedec,spi-nor";
                spi-max-frequency = <29000000>;
+               spi-tx-bus-width = <1>;
+               spi-rx-bus-width = <4>;
        };
 };
 
index f593e4f..564746d 100644 (file)
                #address-cells = <1>;
                #size-cells = <1>;
                reg = <0>;
-               spi-tx-bus-width = <4>;
+               spi-tx-bus-width = <1>;
                spi-rx-bus-width = <4>;
                m25p,fast-read;
                spi-max-frequency = <50000000>;
index c566a64..0df76f7 100644 (file)
                #size-cells = <0>;
 
                pon: power-on@800 {
-                       compatible = "qcom,pm8916-pon";
+                       compatible = "qcom,pm8998-pon";
                        reg = <0x0800>;
+                       mode-bootloader = <0x2>;
+                       mode-recovery = <0x1>;
 
                        pon_pwrkey: pwrkey {
                                compatible = "qcom,pm8941-pwrkey";
index 8ac96f8..28d5b55 100644 (file)
        };
 };
 
+&pon_pwrkey {
+       status = "okay";
+};
+
+&pon_resin {
+       status = "okay";
+
+       linux,code = <KEY_VOLUMEDOWN>;
+};
+
 &qupv3_id_0 {
        status = "okay";
 };
index 0f2b3c0..70c88c3 100644 (file)
                        "Headphone Jack", "HPOL",
                        "Headphone Jack", "HPOR";
 
-               #sound-dai-cells = <0>;
                #address-cells = <1>;
                #size-cells = <0>;
 
                        };
                };
 
-               dai-link@2 {
+               dai-link@5 {
                        link-name = "MultiMedia2";
-                       reg = <2>;
+                       reg = <LPASS_DP_RX>;
                        cpu {
-                               sound-dai = <&lpass_cpu 2>;
+                               sound-dai = <&lpass_cpu LPASS_DP_RX>;
                        };
 
                        codec {
@@ -782,7 +781,7 @@ hp_i2c: &i2c9 {
                qcom,playback-sd-lines = <0>;
        };
 
-       hdmi-primary@0 {
+       hdmi@5 {
                reg = <LPASS_DP_RX>;
        };
 };
index 53a21d0..fd78f16 100644 (file)
 
                cpufreq_hw: cpufreq@18591000 {
                        compatible = "qcom,cpufreq-epss";
-                       reg = <0 0x18591100 0 0x900>,
-                             <0 0x18592100 0 0x900>,
-                             <0 0x18593100 0 0x900>;
+                       reg = <0 0x18591000 0 0x1000>,
+                             <0 0x18592000 0 0x1000>,
+                             <0 0x18593000 0 0x1000>;
                        clocks = <&rpmhcc RPMH_CXO_CLK>, <&gcc GCC_GPLL0>;
                        clock-names = "xo", "alternate";
                        #freq-domain-cells = <1>;
index 9153e66..9c7f87e 100644 (file)
                        compatible = "qcom,sdm660-a2noc";
                        reg = <0x01704000 0xc100>;
                        #interconnect-cells = <1>;
-                       clock-names = "bus", "bus_a";
+                       clock-names = "bus",
+                                     "bus_a",
+                                     "ipa",
+                                     "ufs_axi",
+                                     "aggre2_ufs_axi",
+                                     "aggre2_usb3_axi",
+                                     "cfg_noc_usb2_axi";
                        clocks = <&rpmcc RPM_SMD_AGGR2_NOC_CLK>,
-                                <&rpmcc RPM_SMD_AGGR2_NOC_A_CLK>;
+                                <&rpmcc RPM_SMD_AGGR2_NOC_A_CLK>,
+                                <&rpmcc RPM_SMD_IPA_CLK>,
+                                <&gcc GCC_UFS_AXI_CLK>,
+                                <&gcc GCC_AGGRE2_UFS_AXI_CLK>,
+                                <&gcc GCC_AGGRE2_USB3_AXI_CLK>,
+                                <&gcc GCC_CFG_NOC_USB2_AXI_CLK>;
                };
 
                mnoc: interconnect@1745000 {
index 6d7172e..b3b9119 100644 (file)
                        no-map;
                };
 
-               wlan_msa_mem: memory@8c400000 {
-                       reg = <0 0x8c400000 0 0x100000>;
+               ipa_fw_mem: memory@8c400000 {
+                       reg = <0 0x8c400000 0 0x10000>;
                        no-map;
                };
 
-               gpu_mem: memory@8c515000 {
-                       reg = <0 0x8c515000 0 0x2000>;
+               ipa_gsi_mem: memory@8c410000 {
+                       reg = <0 0x8c410000 0 0x5000>;
                        no-map;
                };
 
-               ipa_fw_mem: memory@8c517000 {
-                       reg = <0 0x8c517000 0 0x5a000>;
+               gpu_mem: memory@8c415000 {
+                       reg = <0 0x8c415000 0 0x2000>;
                        no-map;
                };
 
-               adsp_mem: memory@8c600000 {
-                       reg = <0 0x8c600000 0 0x1a00000>;
+               adsp_mem: memory@8c500000 {
+                       reg = <0 0x8c500000 0 0x1a00000>;
+                       no-map;
+               };
+
+               wlan_msa_mem: memory@8df00000 {
+                       reg = <0 0x8df00000 0 0x100000>;
                        no-map;
                };
 
index 385e502..2ba23aa 100644 (file)
 #include "sdm850.dtsi"
 #include "pm8998.dtsi"
 
+/*
+ * Update following upstream (sdm845.dtsi) reserved
+ * memory mappings for firmware loading to succeed
+ * and enable the IPA device.
+ */
+/delete-node/ &ipa_fw_mem;
+/delete-node/ &ipa_gsi_mem;
+/delete-node/ &gpu_mem;
+/delete-node/ &adsp_mem;
+/delete-node/ &wlan_msa_mem;
+
 / {
        model = "Lenovo Yoga C630";
        compatible = "lenovo,yoga-c630", "qcom,sdm845";
                };
        };
 
+       /* Reserved memory changes for IPA */
+       reserved-memory {
+               wlan_msa_mem: memory@8c400000 {
+                       reg = <0 0x8c400000 0 0x100000>;
+                       no-map;
+               };
+
+               gpu_mem: memory@8c515000 {
+                       reg = <0 0x8c515000 0 0x2000>;
+                       no-map;
+               };
+
+               ipa_fw_mem: memory@8c517000 {
+                       reg = <0 0x8c517000 0 0x5a000>;
+                       no-map;
+               };
+
+               adsp_mem: memory@8c600000 {
+                       reg = <0 0x8c600000 0 0x1a00000>;
+                       no-map;
+               };
+       };
+
        sn65dsi86_refclk: sn65dsi86-refclk {
                compatible = "fixed-clock";
                #clock-cells = <0>;
index 156d96a..545197b 100644 (file)
@@ -245,7 +245,6 @@ CONFIG_DEVTMPFS_MOUNT=y
 CONFIG_FW_LOADER_USER_HELPER=y
 CONFIG_FW_LOADER_USER_HELPER_FALLBACK=y
 CONFIG_HISILICON_LPC=y
-CONFIG_SIMPLE_PM_BUS=y
 CONFIG_FSL_MC_BUS=y
 CONFIG_TEGRA_ACONNECT=m
 CONFIG_GNSS=m
index 23505fc..a8158c9 100644 (file)
@@ -43,7 +43,7 @@ void __init arm64_hugetlb_cma_reserve(void)
 #ifdef CONFIG_ARM64_4K_PAGES
        order = PUD_SHIFT - PAGE_SHIFT;
 #else
-       order = CONT_PMD_SHIFT + PMD_SHIFT - PAGE_SHIFT;
+       order = CONT_PMD_SHIFT - PAGE_SHIFT;
 #endif
        /*
         * HugeTLB CMA reservation is required for gigantic
index 9d4d898..823d3d5 100644 (file)
@@ -8,7 +8,7 @@ config CSKY
        select ARCH_HAS_SYNC_DMA_FOR_DEVICE
        select ARCH_USE_BUILTIN_BSWAP
        select ARCH_USE_QUEUED_RWLOCKS
-       select ARCH_WANT_FRAME_POINTERS if !CPU_CK610
+       select ARCH_WANT_FRAME_POINTERS if !CPU_CK610 && $(cc-option,-mbacktrace)
        select ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT
        select COMMON_CLK
        select CLKSRC_MMIO
@@ -241,6 +241,7 @@ endchoice
 
 menuconfig HAVE_TCM
        bool "Tightly-Coupled/Sram Memory"
+       depends on !COMPILE_TEST
        help
          The implementation are not only used by TCM (Tightly-Coupled Meory)
          but also used by sram on SOC bus. It follow existed linux tcm
index 9181878..02b72a0 100644 (file)
@@ -74,7 +74,6 @@ static __always_inline unsigned long __fls(unsigned long x)
  * bug fix, why only could use atomic!!!!
  */
 #include <asm-generic/bitops/non-atomic.h>
-#define __clear_bit(nr, vaddr) clear_bit(nr, vaddr)
 
 #include <asm-generic/bitops/le.h>
 #include <asm-generic/bitops/ext2-atomic.h>
index 0105ac8..1a5f54e 100644 (file)
@@ -99,7 +99,8 @@ static int gpr_set(struct task_struct *target,
        if (ret)
                return ret;
 
-       regs.sr = task_pt_regs(target)->sr;
+       /* BIT(0) of regs.sr is Condition Code/Carry bit */
+       regs.sr = (regs.sr & BIT(0)) | (task_pt_regs(target)->sr & ~BIT(0));
 #ifdef CONFIG_CPU_HAS_HILO
        regs.dcsr = task_pt_regs(target)->dcsr;
 #endif
index bc4238b..c7b763d 100644 (file)
@@ -52,10 +52,14 @@ static long restore_sigcontext(struct pt_regs *regs,
        struct sigcontext __user *sc)
 {
        int err = 0;
+       unsigned long sr = regs->sr;
 
        /* sc_pt_regs is structured the same as the start of pt_regs */
        err |= __copy_from_user(regs, &sc->sc_pt_regs, sizeof(struct pt_regs));
 
+       /* BIT(0) of regs->sr is Condition Code/Carry bit */
+       regs->sr = (sr & ~1) | (regs->sr & 1);
+
        /* Restore the floating-point state. */
        err |= restore_fpu_state(sc);
 
index 045792c..1e33666 100644 (file)
@@ -388,8 +388,6 @@ config CRASH_DUMP
          help
            Generate crash dump after being started by kexec.
 
-source "drivers/firmware/Kconfig"
-
 endmenu
 
 menu "Power management and ACPI options"
index 771ca53..6b8f591 100644 (file)
@@ -3316,8 +3316,6 @@ source "drivers/cpuidle/Kconfig"
 
 endmenu
 
-source "drivers/firmware/Kconfig"
-
 source "arch/mips/kvm/Kconfig"
 
 source "arch/mips/vdso/Kconfig"
index 35fb8ee..fd43d87 100644 (file)
@@ -10,8 +10,6 @@
 #include <linux/io.h>
 #include <linux/types.h>
 
-#include <asm/mips-boards/launch.h>
-
 extern unsigned long __cps_access_bad_size(void)
        __compiletime_error("Bad size for CPS accessor");
 
@@ -167,30 +165,11 @@ static inline uint64_t mips_cps_cluster_config(unsigned int cluster)
  */
 static inline unsigned int mips_cps_numcores(unsigned int cluster)
 {
-       unsigned int ncores;
-
        if (!mips_cm_present())
                return 0;
 
        /* Add one before masking to handle 0xff indicating no cores */
-       ncores = (mips_cps_cluster_config(cluster) + 1) & CM_GCR_CONFIG_PCORES;
-
-       if (IS_ENABLED(CONFIG_SOC_MT7621)) {
-               struct cpulaunch *launch;
-
-               /*
-                * Ralink MT7621S SoC is single core, but the GCR_CONFIG method
-                * always reports 2 cores. Check the second core's LAUNCH_FREADY
-                * flag to detect if the second core is missing. This method
-                * only works before the core has been started.
-                */
-               launch = (struct cpulaunch *)CKSEG0ADDR(CPULAUNCH);
-               launch += 2; /* MT7621 has 2 VPEs per core */
-               if (!(launch->flags & LAUNCH_FREADY))
-                       ncores = 1;
-       }
-
-       return ncores;
+       return (mips_cps_cluster_config(cluster) + 1) & CM_GCR_CONFIG_PCORES;
 }
 
 /**
index 4742b6f..27a8b49 100644 (file)
@@ -384,6 +384,4 @@ config KEXEC_FILE
 
 endmenu
 
-source "drivers/firmware/Kconfig"
-
 source "drivers/parisc/Kconfig"
index 5ba6fbf..f82f85c 100644 (file)
 
                        fm1mac3: ethernet@e4000 {
                                phy-handle = <&sgmii_aqr_phy3>;
-                               phy-connection-type = "sgmii-2500";
+                               phy-connection-type = "2500base-x";
                                sleep = <&rcpm 0x20000000>;
                        };
 
index d4b145b..9f38040 100644 (file)
@@ -136,6 +136,14 @@ static inline void kuap_kernel_restore(struct pt_regs *regs, unsigned long kuap)
        if (kuap_is_disabled())
                return;
 
+       if (unlikely(kuap != KUAP_NONE)) {
+               current->thread.kuap = KUAP_NONE;
+               kuap_lock(kuap, false);
+       }
+
+       if (likely(regs->kuap == KUAP_NONE))
+               return;
+
        current->thread.kuap = regs->kuap;
 
        kuap_unlock(regs->kuap, false);
index a95f637..4ba8345 100644 (file)
@@ -23,6 +23,7 @@
 #define BRANCH_ABSOLUTE        0x2
 
 bool is_offset_in_branch_range(long offset);
+bool is_offset_in_cond_branch_range(long offset);
 int create_branch(struct ppc_inst *instr, const u32 *addr,
                  unsigned long target, int flags);
 int create_cond_branch(struct ppc_inst *instr, const u32 *addr,
index 6b800d3..a1d2382 100644 (file)
@@ -265,13 +265,16 @@ static inline void interrupt_nmi_enter_prepare(struct pt_regs *regs, struct inte
        local_paca->irq_soft_mask = IRQS_ALL_DISABLED;
        local_paca->irq_happened |= PACA_IRQ_HARD_DIS;
 
-       if (is_implicit_soft_masked(regs)) {
-               // Adjust regs->softe soft implicit soft-mask, so
-               // arch_irq_disabled_regs(regs) behaves as expected.
+       if (!(regs->msr & MSR_EE) || is_implicit_soft_masked(regs)) {
+               /*
+                * Adjust regs->softe to be soft-masked if it had not been
+                * reconcied (e.g., interrupt entry with MSR[EE]=0 but softe
+                * not yet set disabled), or if it was in an implicit soft
+                * masked state. This makes arch_irq_disabled_regs(regs)
+                * behave as expected.
+                */
                regs->softe = IRQS_ALL_DISABLED;
        }
-       if (IS_ENABLED(CONFIG_PPC_IRQ_SOFT_MASK_DEBUG))
-               BUG_ON(!arch_irq_disabled_regs(regs) && !(regs->msr & MSR_EE));
 
        /* Don't do any per-CPU operations until interrupt state is fixed */
 
@@ -525,10 +528,9 @@ static __always_inline long ____##func(struct pt_regs *regs)
 /* kernel/traps.c */
 DECLARE_INTERRUPT_HANDLER_NMI(system_reset_exception);
 #ifdef CONFIG_PPC_BOOK3S_64
-DECLARE_INTERRUPT_HANDLER_ASYNC(machine_check_exception);
-#else
-DECLARE_INTERRUPT_HANDLER_NMI(machine_check_exception);
+DECLARE_INTERRUPT_HANDLER_ASYNC(machine_check_exception_async);
 #endif
+DECLARE_INTERRUPT_HANDLER_NMI(machine_check_exception);
 DECLARE_INTERRUPT_HANDLER(SMIException);
 DECLARE_INTERRUPT_HANDLER(handle_hmi_exception);
 DECLARE_INTERRUPT_HANDLER(unknown_exception);
index 792eefa..27574f2 100644 (file)
@@ -39,6 +39,11 @@ static inline bool security_ftr_enabled(u64 feature)
        return !!(powerpc_security_features & feature);
 }
 
+#ifdef CONFIG_PPC_BOOK3S_64
+enum stf_barrier_type stf_barrier_type_get(void);
+#else
+static inline enum stf_barrier_type stf_barrier_type_get(void) { return STF_BARRIER_NONE; }
+#endif
 
 // Features indicating support for Spectre/Meltdown mitigations
 
index 111249f..038ce8d 100644 (file)
@@ -184,6 +184,15 @@ u64 dma_iommu_get_required_mask(struct device *dev)
        struct iommu_table *tbl = get_iommu_table_base(dev);
        u64 mask;
 
+       if (dev_is_pci(dev)) {
+               u64 bypass_mask = dma_direct_get_required_mask(dev);
+
+               if (dma_iommu_dma_supported(dev, bypass_mask)) {
+                       dev_info(dev, "%s: returning bypass mask 0x%llx\n", __func__, bypass_mask);
+                       return bypass_mask;
+               }
+       }
+
        if (!tbl)
                return 0;
 
index 37859e6..eaf1f72 100644 (file)
@@ -1243,7 +1243,7 @@ EXC_COMMON_BEGIN(machine_check_common)
        li      r10,MSR_RI
        mtmsrd  r10,1
        addi    r3,r1,STACK_FRAME_OVERHEAD
-       bl      machine_check_exception
+       bl      machine_check_exception_async
        b       interrupt_return_srr
 
 
@@ -1303,7 +1303,11 @@ END_FTR_SECTION_IFSET(CPU_FTR_HVMODE)
        subi    r12,r12,1
        sth     r12,PACA_IN_MCE(r13)
 
-       /* Invoke machine_check_exception to print MCE event and panic. */
+       /*
+        * Invoke machine_check_exception to print MCE event and panic.
+        * This is the NMI version of the handler because we are called from
+        * the early handler which is a true NMI.
+        */
        addi    r3,r1,STACK_FRAME_OVERHEAD
        bl      machine_check_exception
 
@@ -1665,27 +1669,30 @@ EXC_COMMON_BEGIN(program_check_common)
         */
 
        andi.   r10,r12,MSR_PR
-       bne     2f                      /* If userspace, go normal path */
+       bne     .Lnormal_stack          /* If userspace, go normal path */
 
        andis.  r10,r12,(SRR1_PROGTM)@h
-       bne     1f                      /* If TM, emergency             */
+       bne     .Lemergency_stack       /* If TM, emergency             */
 
        cmpdi   r1,-INT_FRAME_SIZE      /* check if r1 is in userspace  */
-       blt     2f                      /* normal path if not           */
+       blt     .Lnormal_stack          /* normal path if not           */
 
        /* Use the emergency stack                                      */
-1:     andi.   r10,r12,MSR_PR          /* Set CR0 correctly for label  */
+.Lemergency_stack:
+       andi.   r10,r12,MSR_PR          /* Set CR0 correctly for label  */
                                        /* 3 in EXCEPTION_PROLOG_COMMON */
        mr      r10,r1                  /* Save r1                      */
        ld      r1,PACAEMERGSP(r13)     /* Use emergency stack          */
        subi    r1,r1,INT_FRAME_SIZE    /* alloc stack frame            */
        __ISTACK(program_check)=0
        __GEN_COMMON_BODY program_check
-       b 3f
-2:
+       b .Ldo_program_check
+
+.Lnormal_stack:
        __ISTACK(program_check)=1
        __GEN_COMMON_BODY program_check
-3:
+
+.Ldo_program_check:
        addi    r3,r1,STACK_FRAME_OVERHEAD
        bl      program_check_exception
        REST_NVGPRS(r1) /* instruction emulation may change GPRs */
index 551b653..c4f1d6b 100644 (file)
@@ -229,6 +229,9 @@ notrace void arch_local_irq_restore(unsigned long mask)
                return;
        }
 
+       if (IS_ENABLED(CONFIG_PPC_IRQ_SOFT_MASK_DEBUG))
+               WARN_ON_ONCE(in_nmi() || in_hardirq());
+
        /*
         * After the stb, interrupts are unmasked and there are no interrupts
         * pending replay. The restart sequence makes this atomic with
@@ -321,6 +324,9 @@ notrace void arch_local_irq_restore(unsigned long mask)
        if (mask)
                return;
 
+       if (IS_ENABLED(CONFIG_PPC_IRQ_SOFT_MASK_DEBUG))
+               WARN_ON_ONCE(in_nmi() || in_hardirq());
+
        /*
         * From this point onward, we can take interrupts, preempt,
         * etc... unless we got hard-disabled. We check if an event
index 1a99849..15fb5ea 100644 (file)
@@ -263,6 +263,11 @@ static int __init handle_no_stf_barrier(char *p)
 
 early_param("no_stf_barrier", handle_no_stf_barrier);
 
+enum stf_barrier_type stf_barrier_type_get(void)
+{
+       return stf_enabled_flush_types;
+}
+
 /* This is the generic flag used by other architectures */
 static int __init handle_ssbd(char *p)
 {
index aac8c04..1174170 100644 (file)
@@ -340,10 +340,16 @@ static bool exception_common(int signr, struct pt_regs *regs, int code,
                return false;
        }
 
-       show_signal_msg(signr, regs, code, addr);
+       /*
+        * Must not enable interrupts even for user-mode exception, because
+        * this can be called from machine check, which may be a NMI or IRQ
+        * which don't like interrupts being enabled. Could check for
+        * in_hardirq || in_nmi perhaps, but there doesn't seem to be a good
+        * reason why _exception() should enable irqs for an exception handler,
+        * the handlers themselves do that directly.
+        */
 
-       if (arch_irqs_disabled())
-               interrupt_cond_local_irq_enable(regs);
+       show_signal_msg(signr, regs, code, addr);
 
        current->thread.trap_nr = code;
 
@@ -790,24 +796,22 @@ void die_mce(const char *str, struct pt_regs *regs, long err)
         * do_exit() checks for in_interrupt() and panics in that case, so
         * exit the irq/nmi before calling die.
         */
-       if (IS_ENABLED(CONFIG_PPC_BOOK3S_64))
-               irq_exit();
-       else
+       if (in_nmi())
                nmi_exit();
+       else
+               irq_exit();
        die(str, regs, err);
 }
 
 /*
- * BOOK3S_64 does not call this handler as a non-maskable interrupt
+ * BOOK3S_64 does not usually call this handler as a non-maskable interrupt
  * (it uses its own early real-mode handler to handle the MCE proper
  * and then raises irq_work to call this handler when interrupts are
- * enabled).
+ * enabled). The only time when this is not true is if the early handler
+ * is unrecoverable, then it does call this directly to try to get a
+ * message out.
  */
-#ifdef CONFIG_PPC_BOOK3S_64
-DEFINE_INTERRUPT_HANDLER_ASYNC(machine_check_exception)
-#else
-DEFINE_INTERRUPT_HANDLER_NMI(machine_check_exception)
-#endif
+static void __machine_check_exception(struct pt_regs *regs)
 {
        int recover = 0;
 
@@ -841,12 +845,19 @@ bail:
        /* Must die if the interrupt is not recoverable */
        if (regs_is_unrecoverable(regs))
                die_mce("Unrecoverable Machine check", regs, SIGBUS);
+}
 
 #ifdef CONFIG_PPC_BOOK3S_64
-       return;
-#else
-       return 0;
+DEFINE_INTERRUPT_HANDLER_ASYNC(machine_check_exception_async)
+{
+       __machine_check_exception(regs);
+}
 #endif
+DEFINE_INTERRUPT_HANDLER_NMI(machine_check_exception)
+{
+       __machine_check_exception(regs);
+
+       return 0;
 }
 
 DEFINE_INTERRUPT_HANDLER(SMIException) /* async? */
index f9a3019..c5ed988 100644 (file)
@@ -228,6 +228,11 @@ bool is_offset_in_branch_range(long offset)
        return (offset >= -0x2000000 && offset <= 0x1fffffc && !(offset & 0x3));
 }
 
+bool is_offset_in_cond_branch_range(long offset)
+{
+       return offset >= -0x8000 && offset <= 0x7fff && !(offset & 0x3);
+}
+
 /*
  * Helper to check if a given instruction is a conditional branch
  * Derived from the conditional checks in analyse_instr()
@@ -280,7 +285,7 @@ int create_cond_branch(struct ppc_inst *instr, const u32 *addr,
                offset = offset - (unsigned long)addr;
 
        /* Check we can represent the target in the instruction format */
-       if (offset < -0x8000 || offset > 0x7FFF || offset & 0x3)
+       if (!is_offset_in_cond_branch_range(offset))
                return 1;
 
        /* Mask out the flags and target, so they don't step on each other. */
index 99fad09..7e9b978 100644 (file)
 #define EMIT(instr)            PLANT_INSTR(image, ctx->idx, instr)
 
 /* Long jump; (unconditional 'branch') */
-#define PPC_JMP(dest)          EMIT(PPC_INST_BRANCH |                        \
-                                    (((dest) - (ctx->idx * 4)) & 0x03fffffc))
+#define PPC_JMP(dest)                                                        \
+       do {                                                                  \
+               long offset = (long)(dest) - (ctx->idx * 4);                  \
+               if (!is_offset_in_branch_range(offset)) {                     \
+                       pr_err_ratelimited("Branch offset 0x%lx (@%u) out of range\n", offset, ctx->idx);                       \
+                       return -ERANGE;                                       \
+               }                                                             \
+               EMIT(PPC_INST_BRANCH | (offset & 0x03fffffc));                \
+       } while (0)
+
 /* blr; (unconditional 'branch' with link) to absolute address */
 #define PPC_BL_ABS(dest)       EMIT(PPC_INST_BL |                            \
                                     (((dest) - (unsigned long)(image + ctx->idx)) & 0x03fffffc))
 /* "cond" here covers BO:BI fields. */
-#define PPC_BCC_SHORT(cond, dest)      EMIT(PPC_INST_BRANCH_COND |           \
-                                            (((cond) & 0x3ff) << 16) |       \
-                                            (((dest) - (ctx->idx * 4)) &     \
-                                             0xfffc))
+#define PPC_BCC_SHORT(cond, dest)                                            \
+       do {                                                                  \
+               long offset = (long)(dest) - (ctx->idx * 4);                  \
+               if (!is_offset_in_cond_branch_range(offset)) {                \
+                       pr_err_ratelimited("Conditional branch offset 0x%lx (@%u) out of range\n", offset, ctx->idx);           \
+                       return -ERANGE;                                       \
+               }                                                             \
+               EMIT(PPC_INST_BRANCH_COND | (((cond) & 0x3ff) << 16) | (offset & 0xfffc));                                      \
+       } while (0)
+
 /* Sign-extended 32-bit immediate load */
 #define PPC_LI32(d, i)         do {                                          \
                if ((int)(uintptr_t)(i) >= -32768 &&                          \
 #define PPC_FUNC_ADDR(d,i) do { PPC_LI32(d, i); } while(0)
 #endif
 
-static inline bool is_nearbranch(int offset)
-{
-       return (offset < 32768) && (offset >= -32768);
-}
-
 /*
  * The fly in the ointment of code size changing from pass to pass is
  * avoided by padding the short branch case with a NOP.         If code size differs
@@ -91,7 +100,7 @@ static inline bool is_nearbranch(int offset)
  * state.
  */
 #define PPC_BCC(cond, dest)    do {                                          \
-               if (is_nearbranch((dest) - (ctx->idx * 4))) {                 \
+               if (is_offset_in_cond_branch_range((long)(dest) - (ctx->idx * 4))) {    \
                        PPC_BCC_SHORT(cond, dest);                            \
                        EMIT(PPC_RAW_NOP());                                  \
                } else {                                                      \
index 7b713ed..b63b35e 100644 (file)
  * with our redzone usage.
  *
  *             [       prev sp         ] <-------------
- *             [   nv gpr save area    ] 6*8           |
+ *             [   nv gpr save area    ] 5*8           |
  *             [    tail_call_cnt      ] 8             |
- *             [    local_tmp_var      ]             |
+ *             [    local_tmp_var      ] 16            |
  * fp (r31) -->        [   ebpf stack space    ] upto 512      |
  *             [     frame header      ] 32/112        |
  * sp (r1) --->        [    stack pointer      ] --------------
  */
 
 /* for gpr non volatile registers BPG_REG_6 to 10 */
-#define BPF_PPC_STACK_SAVE     (6*8)
+#define BPF_PPC_STACK_SAVE     (5*8)
 /* for bpf JIT code internal usage */
-#define BPF_PPC_STACK_LOCALS   16
+#define BPF_PPC_STACK_LOCALS   24
 /* stack frame excluding BPF stack, ensure this is quadword aligned */
 #define BPF_PPC_STACKFRAME     (STACK_FRAME_MIN_SIZE + \
                                 BPF_PPC_STACK_LOCALS + BPF_PPC_STACK_SAVE)
index 53aefee..fcbf7a9 100644 (file)
@@ -210,7 +210,11 @@ skip_init_ctx:
                /* Now build the prologue, body code & epilogue for real. */
                cgctx.idx = 0;
                bpf_jit_build_prologue(code_base, &cgctx);
-               bpf_jit_build_body(fp, code_base, &cgctx, addrs, extra_pass);
+               if (bpf_jit_build_body(fp, code_base, &cgctx, addrs, extra_pass)) {
+                       bpf_jit_binary_free(bpf_hdr);
+                       fp = org_fp;
+                       goto out_addrs;
+               }
                bpf_jit_build_epilogue(code_base, &cgctx);
 
                if (bpf_jit_enable > 1)
index beb12cb..0da31d4 100644 (file)
@@ -200,7 +200,7 @@ void bpf_jit_emit_func_call_rel(u32 *image, struct codegen_context *ctx, u64 fun
        }
 }
 
-static void bpf_jit_emit_tail_call(u32 *image, struct codegen_context *ctx, u32 out)
+static int bpf_jit_emit_tail_call(u32 *image, struct codegen_context *ctx, u32 out)
 {
        /*
         * By now, the eBPF program has already setup parameters in r3-r6
@@ -261,7 +261,9 @@ static void bpf_jit_emit_tail_call(u32 *image, struct codegen_context *ctx, u32
        bpf_jit_emit_common_epilogue(image, ctx);
 
        EMIT(PPC_RAW_BCTR());
+
        /* out: */
+       return 0;
 }
 
 /* Assemble the body code between the prologue & epilogue */
@@ -355,7 +357,7 @@ int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, struct codegen_context *
                                PPC_LI32(_R0, imm);
                                EMIT(PPC_RAW_ADDC(dst_reg, dst_reg, _R0));
                        }
-                       if (imm >= 0)
+                       if (imm >= 0 || (BPF_OP(code) == BPF_SUB && imm == 0x80000000))
                                EMIT(PPC_RAW_ADDZE(dst_reg_h, dst_reg_h));
                        else
                                EMIT(PPC_RAW_ADDME(dst_reg_h, dst_reg_h));
@@ -623,7 +625,7 @@ int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, struct codegen_context *
                        EMIT(PPC_RAW_LI(dst_reg_h, 0));
                        break;
                case BPF_ALU | BPF_ARSH | BPF_X: /* (s32) dst >>= src */
-                       EMIT(PPC_RAW_SRAW(dst_reg_h, dst_reg, src_reg));
+                       EMIT(PPC_RAW_SRAW(dst_reg, dst_reg, src_reg));
                        break;
                case BPF_ALU64 | BPF_ARSH | BPF_X: /* (s64) dst >>= src */
                        bpf_set_seen_register(ctx, tmp_reg);
@@ -1073,7 +1075,7 @@ cond_branch:
                                break;
                        case BPF_JMP32 | BPF_JSET | BPF_K:
                                /* andi does not sign-extend the immediate */
-                               if (imm >= -32768 && imm < 32768) {
+                               if (imm >= 0 && imm < 32768) {
                                        /* PPC_ANDI is _only/always_ dot-form */
                                        EMIT(PPC_RAW_ANDI(_R0, dst_reg, imm));
                                } else {
@@ -1090,7 +1092,9 @@ cond_branch:
                 */
                case BPF_JMP | BPF_TAIL_CALL:
                        ctx->seen |= SEEN_TAILCALL;
-                       bpf_jit_emit_tail_call(image, ctx, addrs[i + 1]);
+                       ret = bpf_jit_emit_tail_call(image, ctx, addrs[i + 1]);
+                       if (ret < 0)
+                               return ret;
                        break;
 
                default:
@@ -1103,7 +1107,7 @@ cond_branch:
                        return -EOPNOTSUPP;
                }
                if (BPF_CLASS(code) == BPF_ALU && !fp->aux->verifier_zext &&
-                   !insn_is_zext(&insn[i + 1]))
+                   !insn_is_zext(&insn[i + 1]) && !(BPF_OP(code) == BPF_END && imm == 64))
                        EMIT(PPC_RAW_LI(dst_reg_h, 0));
        }
 
index b87a63d..8b5157c 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/if_vlan.h>
 #include <asm/kprobes.h>
 #include <linux/bpf.h>
+#include <asm/security_features.h>
 
 #include "bpf_jit64.h"
 
@@ -35,9 +36,9 @@ static inline bool bpf_has_stack_frame(struct codegen_context *ctx)
  *             [       prev sp         ] <-------------
  *             [         ...           ]               |
  * sp (r1) --->        [    stack pointer      ] --------------
- *             [   nv gpr save area    ] 6*8
+ *             [   nv gpr save area    ] 5*8
  *             [    tail_call_cnt      ] 8
- *             [    local_tmp_var      ] 8
+ *             [    local_tmp_var      ] 16
  *             [   unused red zone     ] 208 bytes protected
  */
 static int bpf_jit_stack_local(struct codegen_context *ctx)
@@ -45,12 +46,12 @@ static int bpf_jit_stack_local(struct codegen_context *ctx)
        if (bpf_has_stack_frame(ctx))
                return STACK_FRAME_MIN_SIZE + ctx->stack_size;
        else
-               return -(BPF_PPC_STACK_SAVE + 16);
+               return -(BPF_PPC_STACK_SAVE + 24);
 }
 
 static int bpf_jit_stack_tailcallcnt(struct codegen_context *ctx)
 {
-       return bpf_jit_stack_local(ctx) + 8;
+       return bpf_jit_stack_local(ctx) + 16;
 }
 
 static int bpf_jit_stack_offsetof(struct codegen_context *ctx, int reg)
@@ -206,7 +207,7 @@ void bpf_jit_emit_func_call_rel(u32 *image, struct codegen_context *ctx, u64 fun
        EMIT(PPC_RAW_BCTRL());
 }
 
-static void bpf_jit_emit_tail_call(u32 *image, struct codegen_context *ctx, u32 out)
+static int bpf_jit_emit_tail_call(u32 *image, struct codegen_context *ctx, u32 out)
 {
        /*
         * By now, the eBPF program has already setup parameters in r3, r4 and r5
@@ -267,13 +268,38 @@ static void bpf_jit_emit_tail_call(u32 *image, struct codegen_context *ctx, u32
        bpf_jit_emit_common_epilogue(image, ctx);
 
        EMIT(PPC_RAW_BCTR());
+
        /* out: */
+       return 0;
 }
 
+/*
+ * We spill into the redzone always, even if the bpf program has its own stackframe.
+ * Offsets hardcoded based on BPF_PPC_STACK_SAVE -- see bpf_jit_stack_local()
+ */
+void bpf_stf_barrier(void);
+
+asm (
+"              .global bpf_stf_barrier         ;"
+"      bpf_stf_barrier:                        ;"
+"              std     21,-64(1)               ;"
+"              std     22,-56(1)               ;"
+"              sync                            ;"
+"              ld      21,-64(1)               ;"
+"              ld      22,-56(1)               ;"
+"              ori     31,31,0                 ;"
+"              .rept 14                        ;"
+"              b       1f                      ;"
+"      1:                                      ;"
+"              .endr                           ;"
+"              blr                             ;"
+);
+
 /* Assemble the body code between the prologue & epilogue */
 int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, struct codegen_context *ctx,
                       u32 *addrs, bool extra_pass)
 {
+       enum stf_barrier_type stf_barrier = stf_barrier_type_get();
        const struct bpf_insn *insn = fp->insnsi;
        int flen = fp->len;
        int i, ret;
@@ -328,18 +354,25 @@ int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, struct codegen_context *
                        EMIT(PPC_RAW_SUB(dst_reg, dst_reg, src_reg));
                        goto bpf_alu32_trunc;
                case BPF_ALU | BPF_ADD | BPF_K: /* (u32) dst += (u32) imm */
-               case BPF_ALU | BPF_SUB | BPF_K: /* (u32) dst -= (u32) imm */
                case BPF_ALU64 | BPF_ADD | BPF_K: /* dst += imm */
+                       if (!imm) {
+                               goto bpf_alu32_trunc;
+                       } else if (imm >= -32768 && imm < 32768) {
+                               EMIT(PPC_RAW_ADDI(dst_reg, dst_reg, IMM_L(imm)));
+                       } else {
+                               PPC_LI32(b2p[TMP_REG_1], imm);
+                               EMIT(PPC_RAW_ADD(dst_reg, dst_reg, b2p[TMP_REG_1]));
+                       }
+                       goto bpf_alu32_trunc;
+               case BPF_ALU | BPF_SUB | BPF_K: /* (u32) dst -= (u32) imm */
                case BPF_ALU64 | BPF_SUB | BPF_K: /* dst -= imm */
-                       if (BPF_OP(code) == BPF_SUB)
-                               imm = -imm;
-                       if (imm) {
-                               if (imm >= -32768 && imm < 32768)
-                                       EMIT(PPC_RAW_ADDI(dst_reg, dst_reg, IMM_L(imm)));
-                               else {
-                                       PPC_LI32(b2p[TMP_REG_1], imm);
-                                       EMIT(PPC_RAW_ADD(dst_reg, dst_reg, b2p[TMP_REG_1]));
-                               }
+                       if (!imm) {
+                               goto bpf_alu32_trunc;
+                       } else if (imm > -32768 && imm <= 32768) {
+                               EMIT(PPC_RAW_ADDI(dst_reg, dst_reg, IMM_L(-imm)));
+                       } else {
+                               PPC_LI32(b2p[TMP_REG_1], imm);
+                               EMIT(PPC_RAW_SUB(dst_reg, dst_reg, b2p[TMP_REG_1]));
                        }
                        goto bpf_alu32_trunc;
                case BPF_ALU | BPF_MUL | BPF_X: /* (u32) dst *= (u32) src */
@@ -389,8 +422,14 @@ int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, struct codegen_context *
                case BPF_ALU64 | BPF_DIV | BPF_K: /* dst /= imm */
                        if (imm == 0)
                                return -EINVAL;
-                       else if (imm == 1)
-                               goto bpf_alu32_trunc;
+                       if (imm == 1) {
+                               if (BPF_OP(code) == BPF_DIV) {
+                                       goto bpf_alu32_trunc;
+                               } else {
+                                       EMIT(PPC_RAW_LI(dst_reg, 0));
+                                       break;
+                               }
+                       }
 
                        PPC_LI32(b2p[TMP_REG_1], imm);
                        switch (BPF_CLASS(code)) {
@@ -631,6 +670,29 @@ emit_clear:
                 * BPF_ST NOSPEC (speculation barrier)
                 */
                case BPF_ST | BPF_NOSPEC:
+                       if (!security_ftr_enabled(SEC_FTR_FAVOUR_SECURITY) ||
+                                       !security_ftr_enabled(SEC_FTR_STF_BARRIER))
+                               break;
+
+                       switch (stf_barrier) {
+                       case STF_BARRIER_EIEIO:
+                               EMIT(PPC_RAW_EIEIO() | 0x02000000);
+                               break;
+                       case STF_BARRIER_SYNC_ORI:
+                               EMIT(PPC_RAW_SYNC());
+                               EMIT(PPC_RAW_LD(b2p[TMP_REG_1], _R13, 0));
+                               EMIT(PPC_RAW_ORI(_R31, _R31, 0));
+                               break;
+                       case STF_BARRIER_FALLBACK:
+                               EMIT(PPC_RAW_MFLR(b2p[TMP_REG_1]));
+                               PPC_LI64(12, dereference_kernel_function_descriptor(bpf_stf_barrier));
+                               EMIT(PPC_RAW_MTCTR(12));
+                               EMIT(PPC_RAW_BCTRL());
+                               EMIT(PPC_RAW_MTLR(b2p[TMP_REG_1]));
+                               break;
+                       case STF_BARRIER_NONE:
+                               break;
+                       }
                        break;
 
                /*
@@ -993,7 +1055,9 @@ cond_branch:
                 */
                case BPF_JMP | BPF_TAIL_CALL:
                        ctx->seen |= SEEN_TAILCALL;
-                       bpf_jit_emit_tail_call(image, ctx, addrs[i + 1]);
+                       ret = bpf_jit_emit_tail_call(image, ctx, addrs[i + 1]);
+                       if (ret < 0)
+                               return ret;
                        break;
 
                default:
index bc15200..09fafcf 100644 (file)
@@ -867,6 +867,10 @@ static int __init eeh_pseries_init(void)
        if (is_kdump_kernel() || reset_devices) {
                pr_info("Issue PHB reset ...\n");
                list_for_each_entry(phb, &hose_list, list_node) {
+                       // Skip if the slot is empty
+                       if (list_empty(&PCI_DN(phb->dn)->child_list))
+                               continue;
+
                        pdn = list_first_entry(&PCI_DN(phb->dn)->child_list, struct pci_dn, list);
                        config_addr = pseries_eeh_get_pe_config_addr(pdn);
 
index 1b305e4..8627362 100644 (file)
@@ -507,12 +507,27 @@ static void pseries_msi_unmask(struct irq_data *d)
        irq_chip_unmask_parent(d);
 }
 
+static void pseries_msi_write_msg(struct irq_data *data, struct msi_msg *msg)
+{
+       struct msi_desc *entry = irq_data_get_msi_desc(data);
+
+       /*
+        * Do not update the MSIx vector table. It's not strictly necessary
+        * because the table is initialized by the underlying hypervisor, PowerVM
+        * or QEMU/KVM. However, if the MSIx vector entry is cleared, any further
+        * activation will fail. This can happen in some drivers (eg. IPR) which
+        * deactivate an IRQ used for testing MSI support.
+        */
+       entry->msg = *msg;
+}
+
 static struct irq_chip pseries_pci_msi_irq_chip = {
        .name           = "pSeries-PCI-MSI",
        .irq_shutdown   = pseries_msi_shutdown,
        .irq_mask       = pseries_msi_mask,
        .irq_unmask     = pseries_msi_unmask,
        .irq_eoi        = irq_chip_eoi_parent,
+       .irq_write_msi_msg      = pseries_msi_write_msg,
 };
 
 static struct msi_domain_info pseries_msi_domain_info = {
index 301a542..6a6fa9e 100644 (file)
@@ -561,5 +561,3 @@ menu "Power management options"
 source "kernel/power/Kconfig"
 
 endmenu
-
-source "drivers/firmware/Kconfig"
index b933b15..34fbb3e 100644 (file)
@@ -82,4 +82,5 @@ static inline int syscall_get_arch(struct task_struct *task)
 #endif
 }
 
+asmlinkage long sys_riscv_flush_icache(uintptr_t, uintptr_t, uintptr_t);
 #endif /* _ASM_RISCV_SYSCALL_H */
index 893e471..208e31b 100644 (file)
 #ifdef CONFIG_MMU
 
 #include <linux/types.h>
-#include <generated/vdso-offsets.h>
+/*
+ * All systems with an MMU have a VDSO, but systems without an MMU don't
+ * support shared libraries and therefor don't have one.
+ */
+#ifdef CONFIG_MMU
+
+#define __VVAR_PAGES    1
 
-#ifndef CONFIG_GENERIC_TIME_VSYSCALL
-struct vdso_data {
-};
-#endif
+#ifndef __ASSEMBLY__
+#include <generated/vdso-offsets.h>
 
 #define VDSO_SYMBOL(base, name)                                                        \
        (void __user *)((unsigned long)(base) + __vdso_##name##_offset)
 
 #endif /* CONFIG_MMU */
 
-asmlinkage long sys_riscv_flush_icache(uintptr_t, uintptr_t, uintptr_t);
+#endif /* !__ASSEMBLY__ */
+
+#endif /* CONFIG_MMU */
 
 #endif /* _ASM_RISCV_VDSO_H */
index 4b989ae..8062996 100644 (file)
 #ifdef __LP64__
 #define __ARCH_WANT_NEW_STAT
 #define __ARCH_WANT_SET_GET_RLIMIT
-#define __ARCH_WANT_SYS_CLONE3
 #endif /* __LP64__ */
 
+#define __ARCH_WANT_SYS_CLONE3
+
 #include <asm-generic/unistd.h>
 
 /*
index a63c667..44b1420 100644 (file)
@@ -7,7 +7,6 @@
 #include <linux/linkage.h>
 #include <linux/syscalls.h>
 #include <asm-generic/syscalls.h>
-#include <asm/vdso.h>
 #include <asm/syscall.h>
 
 #undef __SYSCALL
index 25a3b88..b70956d 100644 (file)
 #include <linux/binfmts.h>
 #include <linux/err.h>
 #include <asm/page.h>
+#include <asm/vdso.h>
+
 #ifdef CONFIG_GENERIC_TIME_VSYSCALL
 #include <vdso/datapage.h>
 #else
-#include <asm/vdso.h>
+struct vdso_data {
+};
 #endif
 
 extern char vdso_start[], vdso_end[];
 
+enum vvar_pages {
+       VVAR_DATA_PAGE_OFFSET,
+       VVAR_NR_PAGES,
+};
+
+#define VVAR_SIZE  (VVAR_NR_PAGES << PAGE_SHIFT)
+
 static unsigned int vdso_pages __ro_after_init;
 static struct page **vdso_pagelist __ro_after_init;
 
@@ -38,7 +48,7 @@ static int __init vdso_init(void)
 
        vdso_pages = (vdso_end - vdso_start) >> PAGE_SHIFT;
        vdso_pagelist =
-               kcalloc(vdso_pages + 1, sizeof(struct page *), GFP_KERNEL);
+               kcalloc(vdso_pages + VVAR_NR_PAGES, sizeof(struct page *), GFP_KERNEL);
        if (unlikely(vdso_pagelist == NULL)) {
                pr_err("vdso: pagelist allocation failed\n");
                return -ENOMEM;
@@ -63,38 +73,41 @@ int arch_setup_additional_pages(struct linux_binprm *bprm,
        unsigned long vdso_base, vdso_len;
        int ret;
 
-       vdso_len = (vdso_pages + 1) << PAGE_SHIFT;
+       BUILD_BUG_ON(VVAR_NR_PAGES != __VVAR_PAGES);
+
+       vdso_len = (vdso_pages + VVAR_NR_PAGES) << PAGE_SHIFT;
+
+       if (mmap_write_lock_killable(mm))
+               return -EINTR;
 
-       mmap_write_lock(mm);
        vdso_base = get_unmapped_area(NULL, 0, vdso_len, 0, 0);
        if (IS_ERR_VALUE(vdso_base)) {
                ret = vdso_base;
                goto end;
        }
 
-       /*
-        * Put vDSO base into mm struct. We need to do this before calling
-        * install_special_mapping or the perf counter mmap tracking code
-        * will fail to recognise it as a vDSO (since arch_vma_name fails).
-        */
-       mm->context.vdso = (void *)vdso_base;
+       mm->context.vdso = NULL;
+       ret = install_special_mapping(mm, vdso_base, VVAR_SIZE,
+               (VM_READ | VM_MAYREAD), &vdso_pagelist[vdso_pages]);
+       if (unlikely(ret))
+               goto end;
 
        ret =
-          install_special_mapping(mm, vdso_base, vdso_pages << PAGE_SHIFT,
+          install_special_mapping(mm, vdso_base + VVAR_SIZE,
+               vdso_pages << PAGE_SHIFT,
                (VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC),
                vdso_pagelist);
 
-       if (unlikely(ret)) {
-               mm->context.vdso = NULL;
+       if (unlikely(ret))
                goto end;
-       }
 
-       vdso_base += (vdso_pages << PAGE_SHIFT);
-       ret = install_special_mapping(mm, vdso_base, PAGE_SIZE,
-               (VM_READ | VM_MAYREAD), &vdso_pagelist[vdso_pages]);
+       /*
+        * Put vDSO base into mm struct. We need to do this before calling
+        * install_special_mapping or the perf counter mmap tracking code
+        * will fail to recognise it as a vDSO (since arch_vma_name fails).
+        */
+       mm->context.vdso = (void *)vdso_base + VVAR_SIZE;
 
-       if (unlikely(ret))
-               mm->context.vdso = NULL;
 end:
        mmap_write_unlock(mm);
        return ret;
@@ -105,7 +118,7 @@ const char *arch_vma_name(struct vm_area_struct *vma)
        if (vma->vm_mm && (vma->vm_start == (long)vma->vm_mm->context.vdso))
                return "[vdso]";
        if (vma->vm_mm && (vma->vm_start ==
-                          (long)vma->vm_mm->context.vdso + PAGE_SIZE))
+                          (long)vma->vm_mm->context.vdso - VVAR_SIZE))
                return "[vdso_data]";
        return NULL;
 }
index e6f558b..e9111f7 100644 (file)
@@ -3,12 +3,13 @@
  * Copyright (C) 2012 Regents of the University of California
  */
 #include <asm/page.h>
+#include <asm/vdso.h>
 
 OUTPUT_ARCH(riscv)
 
 SECTIONS
 {
-       PROVIDE(_vdso_data = . + PAGE_SIZE);
+       PROVIDE(_vdso_data = . - __VVAR_PAGES * PAGE_SIZE);
        . = SIZEOF_HEADERS;
 
        .hash           : { *(.hash) }                  :text
index 0941186..89f8106 100644 (file)
@@ -16,6 +16,8 @@ static void ipi_remote_fence_i(void *info)
 
 void flush_icache_all(void)
 {
+       local_flush_icache_all();
+
        if (IS_ENABLED(CONFIG_RISCV_SBI))
                sbi_remote_fence_i(NULL);
        else
index e4803ec..6b3c366 100644 (file)
@@ -207,6 +207,8 @@ int zpci_enable_device(struct zpci_dev *);
 int zpci_disable_device(struct zpci_dev *);
 int zpci_scan_configured_device(struct zpci_dev *zdev, u32 fh);
 int zpci_deconfigure_device(struct zpci_dev *zdev);
+void zpci_device_reserved(struct zpci_dev *zdev);
+bool zpci_is_device_configured(struct zpci_dev *zdev);
 
 int zpci_register_ioat(struct zpci_dev *, u8, u64, u64, u64);
 int zpci_unregister_ioat(struct zpci_dev *, u8);
index cfcdf76..a95ca6d 100644 (file)
@@ -259,14 +259,13 @@ EXPORT_SYMBOL(strcmp);
 #ifdef __HAVE_ARCH_STRRCHR
 char *strrchr(const char *s, int c)
 {
-       size_t len = __strend(s) - s;
-
-       if (len)
-              do {
-                      if (s[len] == (char) c)
-                              return (char *) s + len;
-              } while (--len > 0);
-       return NULL;
+       ssize_t len = __strend(s) - s;
+
+       do {
+               if (s[len] == (char)c)
+                       return (char *)s + len;
+       } while (--len >= 0);
+       return NULL;
 }
 EXPORT_SYMBOL(strrchr);
 #endif
index 840d859..1a374d0 100644 (file)
@@ -1826,7 +1826,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *fp)
        jit.addrs = kvcalloc(fp->len + 1, sizeof(*jit.addrs), GFP_KERNEL);
        if (jit.addrs == NULL) {
                fp = orig_fp;
-               goto out;
+               goto free_addrs;
        }
        /*
         * Three initial passes:
index e7e6788..b833155 100644 (file)
@@ -92,7 +92,7 @@ void zpci_remove_reserved_devices(void)
        spin_unlock(&zpci_list_lock);
 
        list_for_each_entry_safe(zdev, tmp, &remove, entry)
-               zpci_zdev_put(zdev);
+               zpci_device_reserved(zdev);
 }
 
 int pci_domain_nr(struct pci_bus *bus)
@@ -751,6 +751,14 @@ error:
        return ERR_PTR(rc);
 }
 
+bool zpci_is_device_configured(struct zpci_dev *zdev)
+{
+       enum zpci_state state = zdev->state;
+
+       return state != ZPCI_FN_STATE_RESERVED &&
+               state != ZPCI_FN_STATE_STANDBY;
+}
+
 /**
  * zpci_scan_configured_device() - Scan a freshly configured zpci_dev
  * @zdev: The zpci_dev to be configured
@@ -822,6 +830,31 @@ int zpci_deconfigure_device(struct zpci_dev *zdev)
        return 0;
 }
 
+/**
+ * zpci_device_reserved() - Mark device as resverved
+ * @zdev: the zpci_dev that was reserved
+ *
+ * Handle the case that a given zPCI function was reserved by another system.
+ * After a call to this function the zpci_dev can not be found via
+ * get_zdev_by_fid() anymore but may still be accessible via existing
+ * references though it will not be functional anymore.
+ */
+void zpci_device_reserved(struct zpci_dev *zdev)
+{
+       if (zdev->has_hp_slot)
+               zpci_exit_slot(zdev);
+       /*
+        * Remove device from zpci_list as it is going away. This also
+        * makes sure we ignore subsequent zPCI events for this device.
+        */
+       spin_lock(&zpci_list_lock);
+       list_del(&zdev->entry);
+       spin_unlock(&zpci_list_lock);
+       zdev->state = ZPCI_FN_STATE_RESERVED;
+       zpci_dbg(3, "rsv fid:%x\n", zdev->fid);
+       zpci_zdev_put(zdev);
+}
+
 void zpci_release_device(struct kref *kref)
 {
        struct zpci_dev *zdev = container_of(kref, struct zpci_dev, kref);
@@ -843,6 +876,12 @@ void zpci_release_device(struct kref *kref)
        case ZPCI_FN_STATE_STANDBY:
                if (zdev->has_hp_slot)
                        zpci_exit_slot(zdev);
+               spin_lock(&zpci_list_lock);
+               list_del(&zdev->entry);
+               spin_unlock(&zpci_list_lock);
+               zpci_dbg(3, "rsv fid:%x\n", zdev->fid);
+               fallthrough;
+       case ZPCI_FN_STATE_RESERVED:
                if (zdev->has_resources)
                        zpci_cleanup_bus_resources(zdev);
                zpci_bus_device_unregister(zdev);
@@ -851,10 +890,6 @@ void zpci_release_device(struct kref *kref)
        default:
                break;
        }
-
-       spin_lock(&zpci_list_lock);
-       list_del(&zdev->entry);
-       spin_unlock(&zpci_list_lock);
        zpci_dbg(3, "rem fid:%x\n", zdev->fid);
        kfree(zdev);
 }
index c856f80..5b8d647 100644 (file)
@@ -140,7 +140,7 @@ static void __zpci_event_availability(struct zpci_ccdf_avail *ccdf)
                        /* The 0x0304 event may immediately reserve the device */
                        if (!clp_get_state(zdev->fid, &state) &&
                            state == ZPCI_FN_STATE_RESERVED) {
-                               zpci_zdev_put(zdev);
+                               zpci_device_reserved(zdev);
                        }
                }
                break;
@@ -151,7 +151,7 @@ static void __zpci_event_availability(struct zpci_ccdf_avail *ccdf)
        case 0x0308: /* Standby -> Reserved */
                if (!zdev)
                        break;
-               zpci_zdev_put(zdev);
+               zpci_device_reserved(zdev);
                break;
        default:
                break;
index ab83c22..d9830e7 100644 (file)
@@ -1405,7 +1405,7 @@ config HIGHMEM4G
 
 config HIGHMEM64G
        bool "64GB"
-       depends on !M486SX && !M486 && !M586 && !M586TSC && !M586MMX && !MGEODE_LX && !MGEODEGX1 && !MCYRIXIII && !MELAN && !MWINCHIPC6 && !WINCHIP3D && !MK6
+       depends on !M486SX && !M486 && !M586 && !M586TSC && !M586MMX && !MGEODE_LX && !MGEODEGX1 && !MCYRIXIII && !MELAN && !MWINCHIPC6 && !MWINCHIP3D && !MK6
        select X86_PAE
        help
          Select this if you have a 32-bit processor and more than 4
@@ -1525,7 +1525,6 @@ config AMD_MEM_ENCRYPT
 
 config AMD_MEM_ENCRYPT_ACTIVE_BY_DEFAULT
        bool "Activate AMD Secure Memory Encryption (SME) by default"
-       default y
        depends on AMD_MEM_ENCRYPT
        help
          Say yes to have system memory encrypted by default if running on
@@ -2832,8 +2831,6 @@ config HAVE_ATOMIC_IOMAP
        def_bool y
        depends on X86_32
 
-source "drivers/firmware/Kconfig"
-
 source "arch/x86/kvm/Kconfig"
 
 source "arch/x86/Kconfig.assembler"
index c853b28..96c775a 100644 (file)
@@ -68,6 +68,7 @@ static bool test_intel(int idx, void *data)
        case INTEL_FAM6_BROADWELL_D:
        case INTEL_FAM6_BROADWELL_G:
        case INTEL_FAM6_BROADWELL_X:
+       case INTEL_FAM6_SAPPHIRERAPIDS_X:
 
        case INTEL_FAM6_ATOM_SILVERMONT:
        case INTEL_FAM6_ATOM_SILVERMONT_D:
index 32a1ad3..db2d92f 100644 (file)
@@ -122,17 +122,27 @@ static bool __send_ipi_mask_ex(const struct cpumask *mask, int vector,
        ipi_arg->reserved = 0;
        ipi_arg->vp_set.valid_bank_mask = 0;
 
-       if (!cpumask_equal(mask, cpu_present_mask)) {
+       /*
+        * Use HV_GENERIC_SET_ALL and avoid converting cpumask to VP_SET
+        * when the IPI is sent to all currently present CPUs.
+        */
+       if (!cpumask_equal(mask, cpu_present_mask) || exclude_self) {
                ipi_arg->vp_set.format = HV_GENERIC_SET_SPARSE_4K;
                if (exclude_self)
                        nr_bank = cpumask_to_vpset_noself(&(ipi_arg->vp_set), mask);
                else
                        nr_bank = cpumask_to_vpset(&(ipi_arg->vp_set), mask);
-       }
-       if (nr_bank < 0)
-               goto ipi_mask_ex_done;
-       if (!nr_bank)
+
+               /*
+                * 'nr_bank <= 0' means some CPUs in cpumask can't be
+                * represented in VP_SET. Return an error and fall back to
+                * native (architectural) method of sending IPIs.
+                */
+               if (nr_bank <= 0)
+                       goto ipi_mask_ex_done;
+       } else {
                ipi_arg->vp_set.format = HV_GENERIC_SET_ALL;
+       }
 
        status = hv_do_rep_hypercall(HVCALL_SEND_IPI_EX, 0, nr_bank,
                              ipi_arg, NULL);
index 14ebd21..4318464 100644 (file)
@@ -25,7 +25,7 @@ static __always_inline void arch_check_user_regs(struct pt_regs *regs)
                 * For !SMAP hardware we patch out CLAC on entry.
                 */
                if (boot_cpu_has(X86_FEATURE_SMAP) ||
-                   (IS_ENABLED(CONFIG_64_BIT) && boot_cpu_has(X86_FEATURE_XENPV)))
+                   (IS_ENABLED(CONFIG_64BIT) && boot_cpu_has(X86_FEATURE_XENPV)))
                        mask |= X86_EFLAGS_AC;
 
                WARN_ON_ONCE(flags & mask);
index 3506d8c..4557f7c 100644 (file)
@@ -14,16 +14,19 @@ static inline int pci_xen_hvm_init(void)
        return -1;
 }
 #endif
-#if defined(CONFIG_XEN_DOM0)
+#ifdef CONFIG_XEN_PV_DOM0
 int __init pci_xen_initial_domain(void);
-int xen_find_device_domain_owner(struct pci_dev *dev);
-int xen_register_device_domain_owner(struct pci_dev *dev, uint16_t domain);
-int xen_unregister_device_domain_owner(struct pci_dev *dev);
 #else
 static inline int __init pci_xen_initial_domain(void)
 {
        return -1;
 }
+#endif
+#ifdef CONFIG_XEN_DOM0
+int xen_find_device_domain_owner(struct pci_dev *dev);
+int xen_register_device_domain_owner(struct pci_dev *dev, uint16_t domain);
+int xen_unregister_device_domain_owner(struct pci_dev *dev);
+#else
 static inline int xen_find_device_domain_owner(struct pci_dev *dev)
 {
        return -1;
index 0f88859..b3410f1 100644 (file)
@@ -326,6 +326,7 @@ static __always_inline void setup_smap(struct cpuinfo_x86 *c)
 #ifdef CONFIG_X86_SMAP
                cr4_set_bits(X86_CR4_SMAP);
 #else
+               clear_cpu_cap(c, X86_FEATURE_SMAP);
                cr4_clear_bits(X86_CR4_SMAP);
 #endif
        }
index 4b8813b..bb1c3f5 100644 (file)
@@ -527,12 +527,14 @@ static void domain_add_cpu(int cpu, struct rdt_resource *r)
        rdt_domain_reconfigure_cdp(r);
 
        if (r->alloc_capable && domain_setup_ctrlval(r, d)) {
-               kfree(d);
+               kfree(hw_dom);
                return;
        }
 
        if (r->mon_capable && domain_setup_mon_state(r, d)) {
-               kfree(d);
+               kfree(hw_dom->ctrl_val);
+               kfree(hw_dom->mbps_val);
+               kfree(hw_dom);
                return;
        }
 
index 38837da..391a4e2 100644 (file)
@@ -714,12 +714,6 @@ static struct chipset early_qrk[] __initdata = {
         */
        { PCI_VENDOR_ID_INTEL, 0x0f00,
                PCI_CLASS_BRIDGE_HOST, PCI_ANY_ID, 0, force_disable_hpet},
-       { PCI_VENDOR_ID_INTEL, 0x3e20,
-               PCI_CLASS_BRIDGE_HOST, PCI_ANY_ID, 0, force_disable_hpet},
-       { PCI_VENDOR_ID_INTEL, 0x3ec4,
-               PCI_CLASS_BRIDGE_HOST, PCI_ANY_ID, 0, force_disable_hpet},
-       { PCI_VENDOR_ID_INTEL, 0x8a12,
-               PCI_CLASS_BRIDGE_HOST, PCI_ANY_ID, 0, force_disable_hpet},
        { PCI_VENDOR_ID_BROADCOM, 0x4331,
          PCI_CLASS_NETWORK_OTHER, PCI_ANY_ID, 0, apple_airport_reset},
        {}
index 445c57c..831b25c 100644 (file)
@@ -379,9 +379,14 @@ static int __fpu_restore_sig(void __user *buf, void __user *buf_fx,
                                     sizeof(fpu->state.fxsave)))
                        return -EFAULT;
 
-               /* Reject invalid MXCSR values. */
-               if (fpu->state.fxsave.mxcsr & ~mxcsr_feature_mask)
-                       return -EINVAL;
+               if (IS_ENABLED(CONFIG_X86_64)) {
+                       /* Reject invalid MXCSR values. */
+                       if (fpu->state.fxsave.mxcsr & ~mxcsr_feature_mask)
+                               return -EINVAL;
+               } else {
+                       /* Mask invalid bits out for historical reasons (broken hardware). */
+                       fpu->state.fxsave.mxcsr &= mxcsr_feature_mask;
+               }
 
                /* Enforce XFEATURE_MASK_FPSSE when XSAVE is enabled */
                if (use_xsave())
index 42fc41d..882213d 100644 (file)
@@ -10,6 +10,7 @@
 #include <asm/irq_remapping.h>
 #include <asm/hpet.h>
 #include <asm/time.h>
+#include <asm/mwait.h>
 
 #undef  pr_fmt
 #define pr_fmt(fmt) "hpet: " fmt
@@ -916,6 +917,83 @@ static bool __init hpet_counting(void)
        return false;
 }
 
+static bool __init mwait_pc10_supported(void)
+{
+       unsigned int eax, ebx, ecx, mwait_substates;
+
+       if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL)
+               return false;
+
+       if (!cpu_feature_enabled(X86_FEATURE_MWAIT))
+               return false;
+
+       if (boot_cpu_data.cpuid_level < CPUID_MWAIT_LEAF)
+               return false;
+
+       cpuid(CPUID_MWAIT_LEAF, &eax, &ebx, &ecx, &mwait_substates);
+
+       return (ecx & CPUID5_ECX_EXTENSIONS_SUPPORTED) &&
+              (ecx & CPUID5_ECX_INTERRUPT_BREAK) &&
+              (mwait_substates & (0xF << 28));
+}
+
+/*
+ * Check whether the system supports PC10. If so force disable HPET as that
+ * stops counting in PC10. This check is overbroad as it does not take any
+ * of the following into account:
+ *
+ *     - ACPI tables
+ *     - Enablement of intel_idle
+ *     - Command line arguments which limit intel_idle C-state support
+ *
+ * That's perfectly fine. HPET is a piece of hardware designed by committee
+ * and the only reasons why it is still in use on modern systems is the
+ * fact that it is impossible to reliably query TSC and CPU frequency via
+ * CPUID or firmware.
+ *
+ * If HPET is functional it is useful for calibrating TSC, but this can be
+ * done via PMTIMER as well which seems to be the last remaining timer on
+ * X86/INTEL platforms that has not been completely wreckaged by feature
+ * creep.
+ *
+ * In theory HPET support should be removed altogether, but there are older
+ * systems out there which depend on it because TSC and APIC timer are
+ * dysfunctional in deeper C-states.
+ *
+ * It's only 20 years now that hardware people have been asked to provide
+ * reliable and discoverable facilities which can be used for timekeeping
+ * and per CPU timer interrupts.
+ *
+ * The probability that this problem is going to be solved in the
+ * forseeable future is close to zero, so the kernel has to be cluttered
+ * with heuristics to keep up with the ever growing amount of hardware and
+ * firmware trainwrecks. Hopefully some day hardware people will understand
+ * that the approach of "This can be fixed in software" is not sustainable.
+ * Hope dies last...
+ */
+static bool __init hpet_is_pc10_damaged(void)
+{
+       unsigned long long pcfg;
+
+       /* Check whether PC10 substates are supported */
+       if (!mwait_pc10_supported())
+               return false;
+
+       /* Check whether PC10 is enabled in PKG C-state limit */
+       rdmsrl(MSR_PKG_CST_CONFIG_CONTROL, pcfg);
+       if ((pcfg & 0xF) < 8)
+               return false;
+
+       if (hpet_force_user) {
+               pr_warn("HPET force enabled via command line, but dysfunctional in PC10.\n");
+               return false;
+       }
+
+       pr_info("HPET dysfunctional in PC10. Force disabled.\n");
+       boot_hpet_disable = true;
+       return true;
+}
+
 /**
  * hpet_enable - Try to setup the HPET timer. Returns 1 on success.
  */
@@ -929,6 +1007,9 @@ int __init hpet_enable(void)
        if (!is_hpet_capable())
                return 0;
 
+       if (hpet_is_pc10_damaged())
+               return 0;
+
        hpet_set_mapping();
        if (!hpet_virt_address)
                return 0;
index 9f90f46..bf1033a 100644 (file)
@@ -130,6 +130,8 @@ static enum es_result sev_es_ghcb_hv_call(struct ghcb *ghcb,
                } else {
                        ret = ES_VMM_ERROR;
                }
+       } else if (ghcb->save.sw_exit_info_1 & 0xffffffff) {
+               ret = ES_VMM_ERROR;
        } else {
                ret = ES_OK;
        }
index 3d41a09..5debe4a 100644 (file)
@@ -113,7 +113,7 @@ static int acpi_register_gsi_xen_hvm(struct device *dev, u32 gsi,
                                 false /* no mapping of GSI to PIRQ */);
 }
 
-#ifdef CONFIG_XEN_DOM0
+#ifdef CONFIG_XEN_PV_DOM0
 static int xen_register_gsi(u32 gsi, int triggering, int polarity)
 {
        int rc, irq;
@@ -261,7 +261,7 @@ error:
        return irq;
 }
 
-#ifdef CONFIG_XEN_DOM0
+#ifdef CONFIG_XEN_PV_DOM0
 static bool __read_mostly pci_seg_supported = true;
 
 static int xen_initdom_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
@@ -375,10 +375,10 @@ static void xen_initdom_restore_msi_irqs(struct pci_dev *dev)
                WARN(ret && ret != -ENOSYS, "restore_msi -> %d\n", ret);
        }
 }
-#else /* CONFIG_XEN_DOM0 */
+#else /* CONFIG_XEN_PV_DOM0 */
 #define xen_initdom_setup_msi_irqs     NULL
 #define xen_initdom_restore_msi_irqs   NULL
-#endif /* !CONFIG_XEN_DOM0 */
+#endif /* !CONFIG_XEN_PV_DOM0 */
 
 static void xen_teardown_msi_irqs(struct pci_dev *dev)
 {
@@ -555,7 +555,7 @@ int __init pci_xen_hvm_init(void)
        return 0;
 }
 
-#ifdef CONFIG_XEN_DOM0
+#ifdef CONFIG_XEN_PV_DOM0
 int __init pci_xen_initial_domain(void)
 {
        int irq;
@@ -583,6 +583,9 @@ int __init pci_xen_initial_domain(void)
        }
        return 0;
 }
+#endif
+
+#ifdef CONFIG_XEN_DOM0
 
 struct xen_device_domain_owner {
        domid_t domain;
@@ -656,4 +659,4 @@ int xen_unregister_device_domain_owner(struct pci_dev *dev)
        return 0;
 }
 EXPORT_SYMBOL_GPL(xen_unregister_device_domain_owner);
-#endif
+#endif /* CONFIG_XEN_DOM0 */
index ee2beda..1d4a00e 100644 (file)
@@ -274,7 +274,7 @@ static struct olpc_ec_driver ec_xo1_driver = {
 
 static struct olpc_ec_driver ec_xo1_5_driver = {
        .ec_cmd = olpc_xo1_ec_cmd,
-#ifdef CONFIG_OLPC_XO1_5_SCI
+#ifdef CONFIG_OLPC_XO15_SCI
        /*
         * XO-1.5 EC wakeups are available when olpc-xo15-sci driver is
         * compiled in
index 9ac7457..ed0442e 100644 (file)
 /*
  * PVH variables.
  *
- * pvh_bootparams and pvh_start_info need to live in the data segment since
+ * pvh_bootparams and pvh_start_info need to live in a data segment since
  * they are used after startup_{32|64}, which clear .bss, are invoked.
  */
-struct boot_params pvh_bootparams __section(".data");
-struct hvm_start_info pvh_start_info __section(".data");
+struct boot_params __initdata pvh_bootparams;
+struct hvm_start_info __initdata pvh_start_info;
 
-unsigned int pvh_start_info_sz = sizeof(pvh_start_info);
+const unsigned int __initconst pvh_start_info_sz = sizeof(pvh_start_info);
 
-static u64 pvh_get_root_pointer(void)
+static u64 __init pvh_get_root_pointer(void)
 {
        return pvh_start_info.rsdp_paddr;
 }
@@ -107,7 +107,7 @@ void __init __weak xen_pvh_init(struct boot_params *boot_params)
        BUG();
 }
 
-static void hypervisor_specific_init(bool xen_guest)
+static void __init hypervisor_specific_init(bool xen_guest)
 {
        if (xen_guest)
                xen_pvh_init(&pvh_bootparams);
index afc1da6..6bcd3d8 100644 (file)
@@ -43,13 +43,9 @@ config XEN_PV_SMP
        def_bool y
        depends on XEN_PV && SMP
 
-config XEN_DOM0
-       bool "Xen PV Dom0 support"
-       default y
-       depends on XEN_PV && PCI_XEN && SWIOTLB_XEN
-       depends on X86_IO_APIC && ACPI && PCI
-       help
-         Support running as a Xen PV Dom0 guest.
+config XEN_PV_DOM0
+       def_bool y
+       depends on XEN_PV && XEN_DOM0
 
 config XEN_PVHVM
        def_bool y
@@ -86,3 +82,12 @@ config XEN_PVH
        def_bool n
        help
          Support for running as a Xen PVH guest.
+
+config XEN_DOM0
+       bool "Xen Dom0 support"
+       default XEN_PV
+       depends on (XEN_PV && SWIOTLB_XEN) || (XEN_PVH && X86_64)
+       depends on X86_IO_APIC && ACPI && PCI
+       select X86_X2APIC if XEN_PVH && X86_64
+       help
+         Support running as a Xen Dom0 guest.
index 40b5779..4953260 100644 (file)
@@ -45,7 +45,7 @@ obj-$(CONFIG_PARAVIRT_SPINLOCKS)+= spinlock.o
 
 obj-$(CONFIG_XEN_DEBUG_FS)     += debugfs.o
 
-obj-$(CONFIG_XEN_DOM0)         += vga.o
+obj-$(CONFIG_XEN_PV_DOM0)      += vga.o
 
 obj-$(CONFIG_SWIOTLB_XEN)      += pci-swiotlb-xen.o
 
index c79bd0a..95d9703 100644 (file)
@@ -3,6 +3,7 @@
 #ifdef CONFIG_XEN_BALLOON_MEMORY_HOTPLUG
 #include <linux/memblock.h>
 #endif
+#include <linux/console.h>
 #include <linux/cpu.h>
 #include <linux/kexec.h>
 #include <linux/slab.h>
 
 #include <xen/xen.h>
 #include <xen/features.h>
+#include <xen/interface/sched.h>
+#include <xen/interface/version.h>
 #include <xen/page.h>
 
 #include <asm/xen/hypercall.h>
 #include <asm/xen/hypervisor.h>
 #include <asm/cpu.h>
 #include <asm/e820/api.h> 
+#include <asm/setup.h>
 
 #include "xen-ops.h"
 #include "smp.h"
@@ -52,9 +56,6 @@ DEFINE_PER_CPU(struct vcpu_info, xen_vcpu_info);
 DEFINE_PER_CPU(uint32_t, xen_vcpu_id);
 EXPORT_PER_CPU_SYMBOL(xen_vcpu_id);
 
-enum xen_domain_type xen_domain_type = XEN_NATIVE;
-EXPORT_SYMBOL_GPL(xen_domain_type);
-
 unsigned long *machine_to_phys_mapping = (void *)MACH2PHYS_VIRT_START;
 EXPORT_SYMBOL(machine_to_phys_mapping);
 unsigned long  machine_to_phys_nr;
@@ -69,10 +70,12 @@ __read_mostly int xen_have_vector_callback;
 EXPORT_SYMBOL_GPL(xen_have_vector_callback);
 
 /*
- * NB: needs to live in .data because it's used by xen_prepare_pvh which runs
- * before clearing the bss.
+ * NB: These need to live in .data or alike because they're used by
+ * xen_prepare_pvh() which runs before clearing the bss.
  */
-uint32_t xen_start_flags __section(".data") = 0;
+enum xen_domain_type __ro_after_init xen_domain_type = XEN_NATIVE;
+EXPORT_SYMBOL_GPL(xen_domain_type);
+uint32_t __ro_after_init xen_start_flags;
 EXPORT_SYMBOL(xen_start_flags);
 
 /*
@@ -258,6 +261,45 @@ int xen_vcpu_setup(int cpu)
        return ((per_cpu(xen_vcpu, cpu) == NULL) ? -ENODEV : 0);
 }
 
+void __init xen_banner(void)
+{
+       unsigned version = HYPERVISOR_xen_version(XENVER_version, NULL);
+       struct xen_extraversion extra;
+
+       HYPERVISOR_xen_version(XENVER_extraversion, &extra);
+
+       pr_info("Booting kernel on %s\n", pv_info.name);
+       pr_info("Xen version: %u.%u%s%s\n",
+               version >> 16, version & 0xffff, extra.extraversion,
+               xen_feature(XENFEAT_mmu_pt_update_preserve_ad)
+               ? " (preserve-AD)" : "");
+}
+
+/* Check if running on Xen version (major, minor) or later */
+bool xen_running_on_version_or_later(unsigned int major, unsigned int minor)
+{
+       unsigned int version;
+
+       if (!xen_domain())
+               return false;
+
+       version = HYPERVISOR_xen_version(XENVER_version, NULL);
+       if ((((version >> 16) == major) && ((version & 0xffff) >= minor)) ||
+               ((version >> 16) > major))
+               return true;
+       return false;
+}
+
+void __init xen_add_preferred_consoles(void)
+{
+       add_preferred_console("xenboot", 0, NULL);
+       if (!boot_params.screen_info.orig_video_isVGA)
+               add_preferred_console("tty", 0, NULL);
+       add_preferred_console("hvc", 0, NULL);
+       if (boot_params.screen_info.orig_video_isVGA)
+               add_preferred_console("tty", 0, NULL);
+}
+
 void xen_reboot(int reason)
 {
        struct sched_shutdown r = { .reason = reason };
index 6e0d075..a7b7d67 100644 (file)
@@ -28,7 +28,6 @@
 #include <linux/mm.h>
 #include <linux/page-flags.h>
 #include <linux/highmem.h>
-#include <linux/console.h>
 #include <linux/pci.h>
 #include <linux/gfp.h>
 #include <linux/edd.h>
@@ -109,17 +108,6 @@ struct tls_descs {
  */
 static DEFINE_PER_CPU(struct tls_descs, shadow_tls_desc);
 
-static void __init xen_banner(void)
-{
-       unsigned version = HYPERVISOR_xen_version(XENVER_version, NULL);
-       struct xen_extraversion extra;
-       HYPERVISOR_xen_version(XENVER_extraversion, &extra);
-
-       pr_info("Booting paravirtualized kernel on %s\n", pv_info.name);
-       pr_info("Xen version: %d.%d%s (preserve-AD)\n",
-               version >> 16, version & 0xffff, extra.extraversion);
-}
-
 static void __init xen_pv_init_platform(void)
 {
        populate_extra_pte(fix_to_virt(FIX_PARAVIRT_BOOTMAP));
@@ -142,22 +130,6 @@ static void __init xen_pv_guest_late_init(void)
 #endif
 }
 
-/* Check if running on Xen version (major, minor) or later */
-bool
-xen_running_on_version_or_later(unsigned int major, unsigned int minor)
-{
-       unsigned int version;
-
-       if (!xen_domain())
-               return false;
-
-       version = HYPERVISOR_xen_version(XENVER_version, NULL);
-       if ((((version >> 16) == major) && ((version & 0xffff) >= minor)) ||
-               ((version >> 16) > major))
-               return true;
-       return false;
-}
-
 static __read_mostly unsigned int cpuid_leaf5_ecx_val;
 static __read_mostly unsigned int cpuid_leaf5_edx_val;
 
@@ -1364,7 +1336,6 @@ asmlinkage __visible void __init xen_start_kernel(void)
        boot_params.hdr.hardware_subarch = X86_SUBARCH_XEN;
 
        if (!xen_initial_domain()) {
-               add_preferred_console("xenboot", 0, NULL);
                if (pci_xen)
                        x86_init.pci.arch_init = pci_xen_init;
                x86_platform.set_legacy_features =
@@ -1409,11 +1380,7 @@ asmlinkage __visible void __init xen_start_kernel(void)
 #endif
        }
 
-       if (!boot_params.screen_info.orig_video_isVGA)
-               add_preferred_console("tty", 0, NULL);
-       add_preferred_console("hvc", 0, NULL);
-       if (boot_params.screen_info.orig_video_isVGA)
-               add_preferred_console("tty", 0, NULL);
+       xen_add_preferred_consoles();
 
 #ifdef CONFIG_PCI
        /* PCI BIOS service won't work from a PV guest. */
index 0d5e34b..bcae606 100644 (file)
@@ -1,5 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0
 #include <linux/acpi.h>
+#include <linux/export.h>
 
 #include <xen/hvc-console.h>
 
 /*
  * PVH variables.
  *
- * The variable xen_pvh needs to live in the data segment since it is used
+ * The variable xen_pvh needs to live in a data segment since it is used
  * after startup_{32|64} is invoked, which will clear the .bss segment.
  */
-bool xen_pvh __section(".data") = 0;
+bool __ro_after_init xen_pvh;
+EXPORT_SYMBOL_GPL(xen_pvh);
 
 void __init xen_pvh_init(struct boot_params *boot_params)
 {
@@ -36,6 +38,10 @@ void __init xen_pvh_init(struct boot_params *boot_params)
        pfn = __pa(hypercall_page);
        wrmsr_safe(msr, (u32)pfn, (u32)(pfn >> 32));
 
+       if (xen_initial_domain())
+               x86_init.oem.arch_setup = xen_add_preferred_consoles;
+       x86_init.oem.banner = xen_banner;
+
        xen_efi_init(boot_params);
 }
 
index 8d75193..3359c23 100644 (file)
@@ -2398,7 +2398,7 @@ static int remap_area_pfn_pte_fn(pte_t *ptep, unsigned long addr, void *data)
 
 int xen_remap_pfn(struct vm_area_struct *vma, unsigned long addr,
                  xen_pfn_t *pfn, int nr, int *err_ptr, pgprot_t prot,
-                 unsigned int domid, bool no_translate, struct page **pages)
+                 unsigned int domid, bool no_translate)
 {
        int err = 0;
        struct remap_data rmd;
index 8d7ec49..8bc8b72 100644 (file)
@@ -51,6 +51,7 @@ void __init xen_remap_memory(void);
 phys_addr_t __init xen_find_free_area(phys_addr_t size);
 char * __init xen_memory_setup(void);
 void __init xen_arch_setup(void);
+void xen_banner(void);
 void xen_enable_sysenter(void);
 void xen_enable_syscall(void);
 void xen_vcpu_restore(void);
@@ -109,7 +110,7 @@ static inline void xen_uninit_lock_cpu(int cpu)
 
 struct dom0_vga_console_info;
 
-#ifdef CONFIG_XEN_DOM0
+#ifdef CONFIG_XEN_PV_DOM0
 void __init xen_init_vga(const struct dom0_vga_console_info *, size_t size);
 #else
 static inline void __init xen_init_vga(const struct dom0_vga_console_info *info,
@@ -118,6 +119,8 @@ static inline void __init xen_init_vga(const struct dom0_vga_console_info *info,
 }
 #endif
 
+void xen_add_preferred_consoles(void);
+
 void __init xen_init_apic(void);
 
 #ifdef CONFIG_XEN_EFI
index 7cbf68c..6fc05cb 100644 (file)
@@ -78,7 +78,7 @@
 #endif
 #define XCHAL_KIO_SIZE                 0x10000000
 
-#if (!XCHAL_HAVE_PTP_MMU || XCHAL_HAVE_SPANNING_WAY) && defined(CONFIG_OF)
+#if (!XCHAL_HAVE_PTP_MMU || XCHAL_HAVE_SPANNING_WAY) && defined(CONFIG_USE_OF)
 #define XCHAL_KIO_PADDR                        xtensa_get_kio_paddr()
 #ifndef __ASSEMBLY__
 extern unsigned long xtensa_kio_paddr;
index 764b54b..15051a8 100644 (file)
@@ -143,7 +143,7 @@ unsigned xtensa_get_ext_irq_no(unsigned irq)
 
 void __init init_IRQ(void)
 {
-#ifdef CONFIG_OF
+#ifdef CONFIG_USE_OF
        irqchip_init();
 #else
 #ifdef CONFIG_HAVE_SMP
index ed18410..ee9082a 100644 (file)
@@ -63,7 +63,7 @@ extern unsigned long initrd_end;
 extern int initrd_below_start_ok;
 #endif
 
-#ifdef CONFIG_OF
+#ifdef CONFIG_USE_OF
 void *dtb_start = __dtb_start;
 #endif
 
@@ -125,7 +125,7 @@ __tagtable(BP_TAG_INITRD, parse_tag_initrd);
 
 #endif /* CONFIG_BLK_DEV_INITRD */
 
-#ifdef CONFIG_OF
+#ifdef CONFIG_USE_OF
 
 static int __init parse_tag_fdt(const bp_tag_t *tag)
 {
@@ -135,7 +135,7 @@ static int __init parse_tag_fdt(const bp_tag_t *tag)
 
 __tagtable(BP_TAG_FDT, parse_tag_fdt);
 
-#endif /* CONFIG_OF */
+#endif /* CONFIG_USE_OF */
 
 static int __init parse_tag_cmdline(const bp_tag_t* tag)
 {
@@ -183,7 +183,7 @@ static int __init parse_bootparam(const bp_tag_t *tag)
 }
 #endif
 
-#ifdef CONFIG_OF
+#ifdef CONFIG_USE_OF
 
 #if !XCHAL_HAVE_PTP_MMU || XCHAL_HAVE_SPANNING_WAY
 unsigned long xtensa_kio_paddr = XCHAL_KIO_DEFAULT_PADDR;
@@ -232,7 +232,7 @@ void __init early_init_devtree(void *params)
                strlcpy(command_line, boot_command_line, COMMAND_LINE_SIZE);
 }
 
-#endif /* CONFIG_OF */
+#endif /* CONFIG_USE_OF */
 
 /*
  * Initialize architecture. (Early stage)
@@ -253,7 +253,7 @@ void __init init_arch(bp_tag_t *bp_start)
        if (bp_start)
                parse_bootparam(bp_start);
 
-#ifdef CONFIG_OF
+#ifdef CONFIG_USE_OF
        early_init_devtree(dtb_start);
 #endif
 
index 7e4d97d..38acda4 100644 (file)
@@ -101,7 +101,7 @@ void init_mmu(void)
 
 void init_kio(void)
 {
-#if XCHAL_HAVE_PTP_MMU && XCHAL_HAVE_SPANNING_WAY && defined(CONFIG_OF)
+#if XCHAL_HAVE_PTP_MMU && XCHAL_HAVE_SPANNING_WAY && defined(CONFIG_USE_OF)
        /*
         * Update the IO area mapping in case xtensa_kio_paddr has changed
         */
index 4f7d614..538e674 100644 (file)
@@ -51,8 +51,12 @@ void platform_power_off(void)
 
 void platform_restart(void)
 {
-       /* Flush and reset the mmu, simulate a processor reset, and
-        * jump to the reset vector. */
+       /* Try software reset first. */
+       WRITE_ONCE(*(u32 *)XTFPGA_SWRST_VADDR, 0xdead);
+
+       /* If software reset did not work, flush and reset the mmu,
+        * simulate a processor reset, and jump to the reset vector.
+        */
        cpu_reset();
        /* control never gets here */
 }
@@ -66,7 +70,7 @@ void __init platform_calibrate_ccount(void)
 
 #endif
 
-#ifdef CONFIG_OF
+#ifdef CONFIG_USE_OF
 
 static void __init xtfpga_clk_setup(struct device_node *np)
 {
@@ -284,4 +288,4 @@ static int __init xtavnet_init(void)
  */
 arch_initcall(xtavnet_init);
 
-#endif /* CONFIG_OF */
+#endif /* CONFIG_USE_OF */
index cf2780c..485a258 100644 (file)
@@ -490,7 +490,6 @@ struct block_device *bdev_alloc(struct gendisk *disk, u8 partno)
        bdev = I_BDEV(inode);
        mutex_init(&bdev->bd_fsfreeze_mutex);
        spin_lock_init(&bdev->bd_size_lock);
-       bdev->bd_disk = disk;
        bdev->bd_partno = partno;
        bdev->bd_inode = inode;
        bdev->bd_stats = alloc_percpu(struct disk_stats);
@@ -498,6 +497,7 @@ struct block_device *bdev_alloc(struct gendisk *disk, u8 partno)
                iput(inode);
                return NULL;
        }
+       bdev->bd_disk = disk;
        return bdev;
 }
 
index 4b66d27..3b38d15 100644 (file)
@@ -129,6 +129,7 @@ static const char *const blk_queue_flag_name[] = {
        QUEUE_FLAG_NAME(PCI_P2PDMA),
        QUEUE_FLAG_NAME(ZONE_RESETALL),
        QUEUE_FLAG_NAME(RQ_ALLOC_TIME),
+       QUEUE_FLAG_NAME(HCTX_ACTIVE),
        QUEUE_FLAG_NAME(NOWAIT),
 };
 #undef QUEUE_FLAG_NAME
index 7b6e5e1..496e845 100644 (file)
@@ -1268,6 +1268,7 @@ struct gendisk *__alloc_disk_node(struct request_queue *q, int node_id,
 
 out_destroy_part_tbl:
        xa_destroy(&disk->part_tbl);
+       disk->part0->bd_disk = NULL;
        iput(disk->part0->bd_inode);
 out_free_bdi:
        bdi_put(disk->bdi);
index 30d2db3..0d399dd 100644 (file)
@@ -17,6 +17,8 @@ source "drivers/bus/Kconfig"
 
 source "drivers/connector/Kconfig"
 
+source "drivers/firmware/Kconfig"
+
 source "drivers/gnss/Kconfig"
 
 source "drivers/mtd/Kconfig"
index 0a0a982..c0e77c1 100644 (file)
@@ -36,7 +36,7 @@ struct acpi_gtdt_descriptor {
 
 static struct acpi_gtdt_descriptor acpi_gtdt_desc __initdata;
 
-static inline void *next_platform_timer(void *platform_timer)
+static inline __init void *next_platform_timer(void *platform_timer)
 {
        struct acpi_gtdt_header *gh = platform_timer;
 
index bd92b54..1c48358 100644 (file)
@@ -371,7 +371,7 @@ static int lps0_device_attach(struct acpi_device *adev,
                return 0;
 
        if (acpi_s2idle_vendor_amd()) {
-               /* AMD0004, AMDI0005:
+               /* AMD0004, AMD0005, AMDI0005:
                 * - Should use rev_id 0x0
                 * - function mask > 0x3: Should use AMD method, but has off by one bug
                 * - function mask = 0x3: Should use Microsoft method
@@ -390,6 +390,7 @@ static int lps0_device_attach(struct acpi_device *adev,
                                        ACPI_LPS0_DSM_UUID_MICROSOFT, 0,
                                        &lps0_dsm_guid_microsoft);
                if (lps0_dsm_func_mask > 0x3 && (!strcmp(hid, "AMD0004") ||
+                                                !strcmp(hid, "AMD0005") ||
                                                 !strcmp(hid, "AMDI0005"))) {
                        lps0_dsm_func_mask = (lps0_dsm_func_mask << 1) | 0x1;
                        acpi_handle_debug(adev->handle, "_DSM UUID %s: Adjusted function mask: 0x%x\n",
index 15986cc..249da49 100644 (file)
@@ -687,7 +687,8 @@ struct device_link *device_link_add(struct device *consumer,
 {
        struct device_link *link;
 
-       if (!consumer || !supplier || flags & ~DL_ADD_VALID_FLAGS ||
+       if (!consumer || !supplier || consumer == supplier ||
+           flags & ~DL_ADD_VALID_FLAGS ||
            (flags & DL_FLAG_STATELESS && flags & DL_MANAGED_LINK_FLAGS) ||
            (flags & DL_FLAG_SYNC_STATE_ONLY &&
             (flags & ~DL_FLAG_INFERRED) != DL_FLAG_SYNC_STATE_ONLY) ||
index 64b2f3d..7f76fee 100644 (file)
@@ -2,4 +2,4 @@
 obj-$(CONFIG_TEST_ASYNC_DRIVER_PROBE)  += test_async_driver_probe.o
 
 obj-$(CONFIG_DRIVER_PE_KUNIT_TEST) += property-entry-test.o
-CFLAGS_REMOVE_property-entry-test.o += -fplugin-arg-structleak_plugin-byref -fplugin-arg-structleak_plugin-byref-all
+CFLAGS_property-entry-test.o += $(DISABLE_STRUCTLEAK_PLUGIN)
index a5b96f3..a4cf3d6 100644 (file)
@@ -152,18 +152,6 @@ config QCOM_EBI2
          Interface 2, which can be used to connect things like NAND Flash,
          SRAM, ethernet adapters, FPGAs and LCD displays.
 
-config SIMPLE_PM_BUS
-       tristate "Simple Power-Managed Bus Driver"
-       depends on OF && PM
-       help
-         Driver for transparent busses that don't need a real driver, but
-         where the bus controller is part of a PM domain, or under the control
-         of a functional clock, and thus relies on runtime PM for managing
-         this PM domain and/or clock.
-         An example of such a bus controller is the Renesas Bus State
-         Controller (BSC, sometimes called "LBSC within Bus Bridge", or
-         "External Bus Interface") as found on several Renesas ARM SoCs.
-
 config SUN50I_DE2_BUS
        bool "Allwinner A64 DE2 Bus Driver"
          default ARM64
index 1c29c5e..52c2f35 100644 (file)
@@ -27,7 +27,7 @@ obj-$(CONFIG_OMAP_OCP2SCP)    += omap-ocp2scp.o
 obj-$(CONFIG_QCOM_EBI2)                += qcom-ebi2.o
 obj-$(CONFIG_SUN50I_DE2_BUS)   += sun50i-de2.o
 obj-$(CONFIG_SUNXI_RSB)                += sunxi-rsb.o
-obj-$(CONFIG_SIMPLE_PM_BUS)    += simple-pm-bus.o
+obj-$(CONFIG_OF)               += simple-pm-bus.o
 obj-$(CONFIG_TEGRA_ACONNECT)   += tegra-aconnect.o
 obj-$(CONFIG_TEGRA_GMI)                += tegra-gmi.o
 obj-$(CONFIG_TI_PWMSS)         += ti-pwmss.o
index 01a3d0c..6b8d625 100644 (file)
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
 
-
 static int simple_pm_bus_probe(struct platform_device *pdev)
 {
-       const struct of_dev_auxdata *lookup = dev_get_platdata(&pdev->dev);
-       struct device_node *np = pdev->dev.of_node;
+       const struct device *dev = &pdev->dev;
+       const struct of_dev_auxdata *lookup = dev_get_platdata(dev);
+       struct device_node *np = dev->of_node;
+       const struct of_device_id *match;
+
+       /*
+        * Allow user to use driver_override to bind this driver to a
+        * transparent bus device which has a different compatible string
+        * that's not listed in simple_pm_bus_of_match. We don't want to do any
+        * of the simple-pm-bus tasks for these devices, so return early.
+        */
+       if (pdev->driver_override)
+               return 0;
+
+       match = of_match_device(dev->driver->of_match_table, dev);
+       /*
+        * These are transparent bus devices (not simple-pm-bus matches) that
+        * have their child nodes populated automatically.  So, don't need to
+        * do anything more. We only match with the device if this driver is
+        * the most specific match because we don't want to incorrectly bind to
+        * a device that has a more specific driver.
+        */
+       if (match && match->data) {
+               if (of_property_match_string(np, "compatible", match->compatible) == 0)
+                       return 0;
+               else
+                       return -ENODEV;
+       }
 
        dev_dbg(&pdev->dev, "%s\n", __func__);
 
@@ -31,14 +56,25 @@ static int simple_pm_bus_probe(struct platform_device *pdev)
 
 static int simple_pm_bus_remove(struct platform_device *pdev)
 {
+       const void *data = of_device_get_match_data(&pdev->dev);
+
+       if (pdev->driver_override || data)
+               return 0;
+
        dev_dbg(&pdev->dev, "%s\n", __func__);
 
        pm_runtime_disable(&pdev->dev);
        return 0;
 }
 
+#define ONLY_BUS       ((void *) 1) /* Match if the device is only a bus. */
+
 static const struct of_device_id simple_pm_bus_of_match[] = {
        { .compatible = "simple-pm-bus", },
+       { .compatible = "simple-bus",   .data = ONLY_BUS },
+       { .compatible = "simple-mfd",   .data = ONLY_BUS },
+       { .compatible = "isa",          .data = ONLY_BUS },
+       { .compatible = "arm,amba-bus", .data = ONLY_BUS },
        { /* sentinel */ }
 };
 MODULE_DEVICE_TABLE(of, simple_pm_bus_of_match);
index a51c2a8..6a8b7fb 100644 (file)
@@ -1464,6 +1464,9 @@ static const struct sysc_revision_quirk sysc_revision_quirks[] = {
        /* Quirks that need to be set based on detected module */
        SYSC_QUIRK("aess", 0, 0, 0x10, -ENODEV, 0x40000000, 0xffffffff,
                   SYSC_MODULE_QUIRK_AESS),
+       /* Errata i893 handling for dra7 dcan1 and 2 */
+       SYSC_QUIRK("dcan", 0x4ae3c000, 0x20, -ENODEV, -ENODEV, 0xa3170504, 0xffffffff,
+                  SYSC_QUIRK_CLKDM_NOAUTO),
        SYSC_QUIRK("dcan", 0x48480000, 0x20, -ENODEV, -ENODEV, 0xa3170504, 0xffffffff,
                   SYSC_QUIRK_CLKDM_NOAUTO),
        SYSC_QUIRK("dss", 0x4832a000, 0, 0x10, 0x14, 0x00000020, 0xffffffff,
@@ -2954,6 +2957,7 @@ static int sysc_init_soc(struct sysc *ddata)
                        break;
                case SOC_AM3:
                        sysc_add_disabled(0x48310000);  /* rng */
+                       break;
                default:
                        break;
                }
index 0a55967..9ef007b 100644 (file)
@@ -564,6 +564,7 @@ config SM_GCC_6125
 
 config SM_GCC_6350
        tristate "SM6350 Global Clock Controller"
+       select QCOM_GDSC
        help
          Support for the global clock controller on SM6350 devices.
          Say Y if you want to use peripheral devices such as UART,
index bc09736..68fe9f6 100644 (file)
@@ -3242,7 +3242,7 @@ static struct gdsc hlos1_vote_turing_mmu_tbu1_gdsc = {
 };
 
 static struct gdsc hlos1_vote_turing_mmu_tbu0_gdsc = {
-       .gdscr = 0x7d060,
+       .gdscr = 0x7d07c,
        .pd = {
                .name = "hlos1_vote_turing_mmu_tbu0",
        },
index 4c94b94..1490446 100644 (file)
@@ -186,6 +186,8 @@ static struct rzg2l_reset r9a07g044_resets[] = {
 
 static const unsigned int r9a07g044_crit_mod_clks[] __initconst = {
        MOD_CLK_BASE + R9A07G044_GIC600_GICCLK,
+       MOD_CLK_BASE + R9A07G044_IA55_CLK,
+       MOD_CLK_BASE + R9A07G044_DMAC_ACLK,
 };
 
 const struct rzg2l_cpg_info r9a07g044_cpg_info = {
index 3b3b2c3..761922e 100644 (file)
@@ -391,7 +391,7 @@ static int rzg2l_mod_clock_is_enabled(struct clk_hw *hw)
 
        value = readl(priv->base + CLK_MON_R(clock->off));
 
-       return !(value & bitmask);
+       return value & bitmask;
 }
 
 static const struct clk_ops rzg2l_mod_clock_ops = {
index 242e94c..bf8cd92 100644 (file)
@@ -165,13 +165,6 @@ static const struct clk_parent_data mpu_mux[] = {
          .name = "boot_clk", },
 };
 
-static const struct clk_parent_data s2f_usr0_mux[] = {
-       { .fw_name = "f2s-free-clk",
-         .name = "f2s-free-clk", },
-       { .fw_name = "boot_clk",
-         .name = "boot_clk", },
-};
-
 static const struct clk_parent_data emac_mux[] = {
        { .fw_name = "emaca_free_clk",
          .name = "emaca_free_clk", },
@@ -312,8 +305,6 @@ static const struct stratix10_gate_clock agilex_gate_clks[] = {
          4, 0x44, 28, 1, 0, 0, 0},
        { AGILEX_CS_TIMER_CLK, "cs_timer_clk", NULL, noc_mux, ARRAY_SIZE(noc_mux), 0, 0x24,
          5, 0, 0, 0, 0x30, 1, 0},
-       { AGILEX_S2F_USER0_CLK, "s2f_user0_clk", NULL, s2f_usr0_mux, ARRAY_SIZE(s2f_usr0_mux), 0, 0x24,
-         6, 0, 0, 0, 0, 0, 0},
        { AGILEX_EMAC0_CLK, "emac0_clk", NULL, emac_mux, ARRAY_SIZE(emac_mux), 0, 0x7C,
          0, 0, 0, 0, 0x94, 26, 0},
        { AGILEX_EMAC1_CLK, "emac1_clk", NULL, emac_mux, ARRAY_SIZE(emac_mux), 0, 0x7C,
index e3e7575..b1f46a9 100644 (file)
@@ -178,7 +178,7 @@ static void axp_mc_check(struct mem_ctl_info *mci)
                                     "details unavailable (multiple errors)");
        if (cnt_dbe)
                edac_mc_handle_error(HW_EVENT_ERR_UNCORRECTED, mci,
-                                    cnt_sbe, /* error count */
+                                    cnt_dbe, /* error count */
                                     0, 0, 0, /* pfn, offset, syndrome */
                                     -1, -1, -1, /* top, mid, low layer */
                                     mci->ctl_name,
index 220a58c..cda7d71 100644 (file)
@@ -203,10 +203,7 @@ config INTEL_STRATIX10_RSU
          Say Y here if you want Intel RSU support.
 
 config QCOM_SCM
-       tristate "Qcom SCM driver"
-       depends on ARM || ARM64
-       depends on HAVE_ARM_SMCCC
-       select RESET_CONTROLLER
+       tristate
 
 config QCOM_SCM_DOWNLOAD_MODE_DEFAULT
        bool "Qualcomm download mode enabled by default"
index 00fe595..641a918 100644 (file)
@@ -49,6 +49,13 @@ static int ffa_device_probe(struct device *dev)
        return ffa_drv->probe(ffa_dev);
 }
 
+static void ffa_device_remove(struct device *dev)
+{
+       struct ffa_driver *ffa_drv = to_ffa_driver(dev->driver);
+
+       ffa_drv->remove(to_ffa_dev(dev));
+}
+
 static int ffa_device_uevent(struct device *dev, struct kobj_uevent_env *env)
 {
        struct ffa_device *ffa_dev = to_ffa_dev(dev);
@@ -86,6 +93,7 @@ struct bus_type ffa_bus_type = {
        .name           = "arm_ffa",
        .match          = ffa_device_match,
        .probe          = ffa_device_probe,
+       .remove         = ffa_device_remove,
        .uevent         = ffa_device_uevent,
        .dev_groups     = ffa_device_attributes_groups,
 };
@@ -127,7 +135,7 @@ static void ffa_release_device(struct device *dev)
 
 static int __ffa_devices_unregister(struct device *dev, void *data)
 {
-       ffa_release_device(dev);
+       device_unregister(dev);
 
        return 0;
 }
index 7f4d243..3d7081e 100644 (file)
@@ -68,7 +68,7 @@ config ARM_SCMI_TRANSPORT_SMC
 
 config ARM_SCMI_TRANSPORT_VIRTIO
        bool "SCMI transport based on VirtIO"
-       depends on VIRTIO
+       depends on VIRTIO=y || VIRTIO=ARM_SCMI_PROTOCOL
        select ARM_SCMI_HAVE_TRANSPORT
        select ARM_SCMI_HAVE_MSG
        help
index 224577f..11e8efb 100644 (file)
@@ -110,18 +110,16 @@ static void scmi_finalize_message(struct scmi_vio_channel *vioch,
        if (vioch->is_rx) {
                scmi_vio_feed_vq_rx(vioch, msg);
        } else {
-               unsigned long flags;
-
-               spin_lock_irqsave(&vioch->lock, flags);
+               /* Here IRQs are assumed to be already disabled by the caller */
+               spin_lock(&vioch->lock);
                list_add(&msg->list, &vioch->free_list);
-               spin_unlock_irqrestore(&vioch->lock, flags);
+               spin_unlock(&vioch->lock);
        }
 }
 
 static void scmi_vio_complete_cb(struct virtqueue *vqueue)
 {
        unsigned long ready_flags;
-       unsigned long flags;
        unsigned int length;
        struct scmi_vio_channel *vioch;
        struct scmi_vio_msg *msg;
@@ -140,7 +138,8 @@ static void scmi_vio_complete_cb(struct virtqueue *vqueue)
                        goto unlock_ready_out;
                }
 
-               spin_lock_irqsave(&vioch->lock, flags);
+               /* IRQs already disabled here no need to irqsave */
+               spin_lock(&vioch->lock);
                if (cb_enabled) {
                        virtqueue_disable_cb(vqueue);
                        cb_enabled = false;
@@ -151,7 +150,7 @@ static void scmi_vio_complete_cb(struct virtqueue *vqueue)
                                goto unlock_out;
                        cb_enabled = true;
                }
-               spin_unlock_irqrestore(&vioch->lock, flags);
+               spin_unlock(&vioch->lock);
 
                if (msg) {
                        msg->rx_len = length;
@@ -161,11 +160,18 @@ static void scmi_vio_complete_cb(struct virtqueue *vqueue)
                        scmi_finalize_message(vioch, msg);
                }
 
+               /*
+                * Release ready_lock and re-enable IRQs between loop iterations
+                * to allow virtio_chan_free() to possibly kick in and set the
+                * flag vioch->ready to false even in between processing of
+                * messages, so as to force outstanding messages to be ignored
+                * when system is shutting down.
+                */
                spin_unlock_irqrestore(&vioch->ready_lock, ready_flags);
        }
 
 unlock_out:
-       spin_unlock_irqrestore(&vioch->lock, flags);
+       spin_unlock(&vioch->lock);
 unlock_ready_out:
        spin_unlock_irqrestore(&vioch->ready_lock, ready_flags);
 }
@@ -384,8 +390,11 @@ static int scmi_vio_probe(struct virtio_device *vdev)
        struct virtqueue *vqs[VIRTIO_SCMI_VQ_MAX_CNT];
 
        /* Only one SCMI VirtiO device allowed */
-       if (scmi_vdev)
-               return -EINVAL;
+       if (scmi_vdev) {
+               dev_err(dev,
+                       "One SCMI Virtio device was already initialized: only one allowed.\n");
+               return -EBUSY;
+       }
 
        have_vq_rx = scmi_vio_have_vq_rx(vdev);
        vq_cnt = have_vq_rx ? VIRTIO_SCMI_VQ_MAX_CNT : 1;
@@ -428,16 +437,25 @@ static int scmi_vio_probe(struct virtio_device *vdev)
        }
 
        vdev->priv = channels;
-       scmi_vdev = vdev;
+       /* Ensure initialized scmi_vdev is visible */
+       smp_store_mb(scmi_vdev, vdev);
 
        return 0;
 }
 
 static void scmi_vio_remove(struct virtio_device *vdev)
 {
+       /*
+        * Once we get here, virtio_chan_free() will have already been called by
+        * the SCMI core for any existing channel and, as a consequence, all the
+        * virtio channels will have been already marked NOT ready, causing any
+        * outstanding message on any vqueue to be ignored by complete_cb: now
+        * we can just stop processing buffers and destroy the vqueues.
+        */
        vdev->config->reset(vdev);
        vdev->config->del_vqs(vdev);
-       scmi_vdev = NULL;
+       /* Ensure scmi_vdev is visible as NULL */
+       smp_store_mb(scmi_vdev, NULL);
 }
 
 static int scmi_vio_validate(struct virtio_device *vdev)
@@ -476,7 +494,7 @@ static int __init virtio_scmi_init(void)
        return register_virtio_driver(&virtio_scmi_driver);
 }
 
-static void __exit virtio_scmi_exit(void)
+static void virtio_scmi_exit(void)
 {
        unregister_virtio_driver(&virtio_scmi_driver);
 }
index 73bdbd2..6ec8ede 100644 (file)
@@ -25,8 +25,6 @@
 #include <acpi/ghes.h>
 #include <ras/ras_event.h>
 
-static char rcd_decode_str[CPER_REC_LEN];
-
 /*
  * CPER record ID need to be unique even after reboot, because record
  * ID is used as index for ERST storage, while CPER records from
@@ -312,6 +310,7 @@ const char *cper_mem_err_unpack(struct trace_seq *p,
                                struct cper_mem_err_compact *cmem)
 {
        const char *ret = trace_seq_buffer_ptr(p);
+       char rcd_decode_str[CPER_REC_LEN];
 
        if (cper_mem_err_location(cmem, rcd_decode_str))
                trace_seq_printf(p, "%s", rcd_decode_str);
@@ -326,6 +325,7 @@ static void cper_print_mem(const char *pfx, const struct cper_sec_mem_err *mem,
        int len)
 {
        struct cper_mem_err_compact cmem;
+       char rcd_decode_str[CPER_REC_LEN];
 
        /* Don't trust UEFI 2.1/2.2 structure with bad validation bits */
        if (len == sizeof(struct cper_sec_mem_err_old) &&
index 365c3a4..fe567be 100644 (file)
@@ -271,7 +271,7 @@ efi_status_t allocate_new_fdt_and_exit_boot(void *handle,
                return status;
        }
 
-       efi_info("Exiting boot services and installing virtual address map...\n");
+       efi_info("Exiting boot services...\n");
 
        map.map = &memory_map;
        status = efi_allocate_pages(MAX_FDT_SIZE, new_fdt_addr, ULONG_MAX);
index 1410bea..f3e54f6 100644 (file)
@@ -414,7 +414,7 @@ static void virt_efi_reset_system(int reset_type,
                                  unsigned long data_size,
                                  efi_char16_t *data)
 {
-       if (down_interruptible(&efi_runtime_lock)) {
+       if (down_trylock(&efi_runtime_lock)) {
                pr_warn("failed to invoke the reset_system() runtime service:\n"
                        "could not get exclusive access to the firmware\n");
                return;
index 69dec5a..029d3cd 100644 (file)
@@ -192,12 +192,19 @@ static const struct of_device_id ice40_fpga_of_match[] = {
 };
 MODULE_DEVICE_TABLE(of, ice40_fpga_of_match);
 
+static const struct spi_device_id ice40_fpga_spi_ids[] = {
+       { .name = "ice40-fpga-mgr", },
+       {},
+};
+MODULE_DEVICE_TABLE(spi, ice40_fpga_spi_ids);
+
 static struct spi_driver ice40_fpga_driver = {
        .probe = ice40_fpga_probe,
        .driver = {
                .name = "ice40spi",
                .of_match_table = of_match_ptr(ice40_fpga_of_match),
        },
+       .id_table = ice40_fpga_spi_ids,
 };
 
 module_spi_driver(ice40_fpga_driver);
index 05637d5..4a55cdf 100644 (file)
@@ -174,6 +174,13 @@ static int gen_74x164_remove(struct spi_device *spi)
        return 0;
 }
 
+static const struct spi_device_id gen_74x164_spi_ids[] = {
+       { .name = "74hc595" },
+       { .name = "74lvc594" },
+       {},
+};
+MODULE_DEVICE_TABLE(spi, gen_74x164_spi_ids);
+
 static const struct of_device_id gen_74x164_dt_ids[] = {
        { .compatible = "fairchild,74hc595" },
        { .compatible = "nxp,74lvc594" },
@@ -188,6 +195,7 @@ static struct spi_driver gen_74x164_driver = {
        },
        .probe          = gen_74x164_probe,
        .remove         = gen_74x164_remove,
+       .id_table       = gen_74x164_spi_ids,
 };
 module_spi_driver(gen_74x164_driver);
 
index 0a9d746..d26bff2 100644 (file)
@@ -476,10 +476,19 @@ static struct platform_device *gpio_mockup_pdevs[GPIO_MOCKUP_MAX_GC];
 
 static void gpio_mockup_unregister_pdevs(void)
 {
+       struct platform_device *pdev;
+       struct fwnode_handle *fwnode;
        int i;
 
-       for (i = 0; i < GPIO_MOCKUP_MAX_GC; i++)
-               platform_device_unregister(gpio_mockup_pdevs[i]);
+       for (i = 0; i < GPIO_MOCKUP_MAX_GC; i++) {
+               pdev = gpio_mockup_pdevs[i];
+               if (!pdev)
+                       continue;
+
+               fwnode = dev_fwnode(&pdev->dev);
+               platform_device_unregister(pdev);
+               fwnode_remove_software_node(fwnode);
+       }
 }
 
 static __init char **gpio_mockup_make_line_names(const char *label,
@@ -508,6 +517,7 @@ static int __init gpio_mockup_register_chip(int idx)
        struct property_entry properties[GPIO_MOCKUP_MAX_PROP];
        struct platform_device_info pdevinfo;
        struct platform_device *pdev;
+       struct fwnode_handle *fwnode;
        char **line_names = NULL;
        char chip_label[32];
        int prop = 0, base;
@@ -536,13 +546,18 @@ static int __init gpio_mockup_register_chip(int idx)
                                        "gpio-line-names", line_names, ngpio);
        }
 
+       fwnode = fwnode_create_software_node(properties, NULL);
+       if (IS_ERR(fwnode))
+               return PTR_ERR(fwnode);
+
        pdevinfo.name = "gpio-mockup";
        pdevinfo.id = idx;
-       pdevinfo.properties = properties;
+       pdevinfo.fwnode = fwnode;
 
        pdev = platform_device_register_full(&pdevinfo);
        kfree_strarray(line_names, ngpio);
        if (IS_ERR(pdev)) {
+               fwnode_remove_software_node(fwnode);
                pr_err("error registering device");
                return PTR_ERR(pdev);
        }
index 8ebf369..d2fe76f 100644 (file)
@@ -559,21 +559,21 @@ static int pca953x_gpio_set_pull_up_down(struct pca953x_chip *chip,
 
        mutex_lock(&chip->i2c_lock);
 
-       /* Disable pull-up/pull-down */
-       ret = regmap_write_bits(chip->regmap, pull_en_reg, bit, 0);
-       if (ret)
-               goto exit;
-
        /* Configure pull-up/pull-down */
        if (config == PIN_CONFIG_BIAS_PULL_UP)
                ret = regmap_write_bits(chip->regmap, pull_sel_reg, bit, bit);
        else if (config == PIN_CONFIG_BIAS_PULL_DOWN)
                ret = regmap_write_bits(chip->regmap, pull_sel_reg, bit, 0);
+       else
+               ret = 0;
        if (ret)
                goto exit;
 
-       /* Enable pull-up/pull-down */
-       ret = regmap_write_bits(chip->regmap, pull_en_reg, bit, bit);
+       /* Disable/Enable pull-up/pull-down */
+       if (config == PIN_CONFIG_BIAS_DISABLE)
+               ret = regmap_write_bits(chip->regmap, pull_en_reg, bit, 0);
+       else
+               ret = regmap_write_bits(chip->regmap, pull_en_reg, bit, bit);
 
 exit:
        mutex_unlock(&chip->i2c_lock);
@@ -587,7 +587,9 @@ static int pca953x_gpio_set_config(struct gpio_chip *gc, unsigned int offset,
 
        switch (pinconf_to_config_param(config)) {
        case PIN_CONFIG_BIAS_PULL_UP:
+       case PIN_CONFIG_BIAS_PULL_PIN_DEFAULT:
        case PIN_CONFIG_BIAS_PULL_DOWN:
+       case PIN_CONFIG_BIAS_DISABLE:
                return pca953x_gpio_set_pull_up_down(chip, offset, config);
        default:
                return -ENOTSUPP;
index d356e32..269437b 100644 (file)
@@ -1087,6 +1087,7 @@ struct amdgpu_device {
 
        bool                            no_hw_access;
        struct pci_saved_state          *pci_state;
+       pci_channel_state_t             pci_channel_state;
 
        struct amdgpu_reset_control     *reset_cntl;
 };
index 2d6b2d7..054c1a2 100644 (file)
@@ -563,6 +563,7 @@ kfd_mem_dmaunmap_userptr(struct kgd_mem *mem,
 
        dma_unmap_sgtable(adev->dev, ttm->sg, direction, 0);
        sg_free_table(ttm->sg);
+       kfree(ttm->sg);
        ttm->sg = NULL;
 }
 
index ab3794c..af9bdf1 100644 (file)
@@ -2394,10 +2394,6 @@ static int amdgpu_device_ip_init(struct amdgpu_device *adev)
        if (r)
                goto init_failed;
 
-       r = amdgpu_amdkfd_resume_iommu(adev);
-       if (r)
-               goto init_failed;
-
        r = amdgpu_device_ip_hw_init_phase1(adev);
        if (r)
                goto init_failed;
@@ -2436,6 +2432,10 @@ static int amdgpu_device_ip_init(struct amdgpu_device *adev)
        if (!adev->gmc.xgmi.pending_reset)
                amdgpu_amdkfd_device_init(adev);
 
+       r = amdgpu_amdkfd_resume_iommu(adev);
+       if (r)
+               goto init_failed;
+
        amdgpu_fru_get_product_info(adev);
 
 init_failed:
@@ -5399,6 +5399,8 @@ pci_ers_result_t amdgpu_pci_error_detected(struct pci_dev *pdev, pci_channel_sta
                return PCI_ERS_RESULT_DISCONNECT;
        }
 
+       adev->pci_channel_state = state;
+
        switch (state) {
        case pci_channel_io_normal:
                return PCI_ERS_RESULT_CAN_RECOVER;
@@ -5541,6 +5543,10 @@ void amdgpu_pci_resume(struct pci_dev *pdev)
 
        DRM_INFO("PCI error: resume callback!!\n");
 
+       /* Only continue execution for the case of pci_channel_io_frozen */
+       if (adev->pci_channel_state != pci_channel_io_frozen)
+               return;
+
        for (i = 0; i < AMDGPU_MAX_RINGS; ++i) {
                struct amdgpu_ring *ring = adev->rings[i];
 
index e7f06bd..1916ec8 100644 (file)
@@ -31,6 +31,8 @@
 /* delay 0.1 second to enable gfx off feature */
 #define GFX_OFF_DELAY_ENABLE         msecs_to_jiffies(100)
 
+#define GFX_OFF_NO_DELAY 0
+
 /*
  * GPU GFX IP block helpers function.
  */
@@ -558,6 +560,8 @@ int amdgpu_gfx_enable_kcq(struct amdgpu_device *adev)
 
 void amdgpu_gfx_off_ctrl(struct amdgpu_device *adev, bool enable)
 {
+       unsigned long delay = GFX_OFF_DELAY_ENABLE;
+
        if (!(adev->pm.pp_feature & PP_GFXOFF_MASK))
                return;
 
@@ -573,8 +577,14 @@ void amdgpu_gfx_off_ctrl(struct amdgpu_device *adev, bool enable)
 
                adev->gfx.gfx_off_req_count--;
 
-               if (adev->gfx.gfx_off_req_count == 0 && !adev->gfx.gfx_off_state)
-                       schedule_delayed_work(&adev->gfx.gfx_off_delay_work, GFX_OFF_DELAY_ENABLE);
+               if (adev->gfx.gfx_off_req_count == 0 &&
+                   !adev->gfx.gfx_off_state) {
+                       /* If going to s2idle, no need to wait */
+                       if (adev->in_s0ix)
+                               delay = GFX_OFF_NO_DELAY;
+                       schedule_delayed_work(&adev->gfx.gfx_off_delay_work,
+                                             delay);
+               }
        } else {
                if (adev->gfx.gfx_off_req_count == 0) {
                        cancel_delayed_work_sync(&adev->gfx.gfx_off_delay_work);
index c2a4d92..4a41623 100644 (file)
@@ -1085,18 +1085,12 @@ static int kfd_resume(struct kfd_dev *kfd)
        int err = 0;
 
        err = kfd->dqm->ops.start(kfd->dqm);
-       if (err) {
+       if (err)
                dev_err(kfd_device,
                        "Error starting queue manager for device %x:%x\n",
                        kfd->pdev->vendor, kfd->pdev->device);
-               goto dqm_start_error;
-       }
 
        return err;
-
-dqm_start_error:
-       kfd_iommu_suspend(kfd);
-       return err;
 }
 
 static inline void kfd_queue_work(struct workqueue_struct *wq,
index 7dffc04..127667e 100644 (file)
@@ -25,6 +25,8 @@ config DRM_AMD_DC_HDCP
 
 config DRM_AMD_DC_SI
        bool "AMD DC support for Southern Islands ASICs"
+       depends on DRM_AMDGPU_SI
+       depends on DRM_AMD_DC
        default n
        help
          Choose this option to enable new AMD DC support for SI asics
index 05eaec0..6d655e1 100644 (file)
@@ -1306,12 +1306,6 @@ static void override_training_settings(
 {
        uint32_t lane;
 
-       /* Override link settings */
-       if (link->preferred_link_setting.link_rate != LINK_RATE_UNKNOWN)
-               lt_settings->link_settings.link_rate = link->preferred_link_setting.link_rate;
-       if (link->preferred_link_setting.lane_count != LANE_COUNT_UNKNOWN)
-               lt_settings->link_settings.lane_count = link->preferred_link_setting.lane_count;
-
        /* Override link spread */
        if (!link->dp_ss_off && overrides->downspread != NULL)
                lt_settings->link_settings.link_spread = *overrides->downspread ?
index d8b2261..c337588 100644 (file)
@@ -118,6 +118,7 @@ struct dcn10_link_enc_registers {
        uint32_t RDPCSTX_PHY_CNTL4;
        uint32_t RDPCSTX_PHY_CNTL5;
        uint32_t RDPCSTX_PHY_CNTL6;
+       uint32_t RDPCSPIPE_PHY_CNTL6;
        uint32_t RDPCSTX_PHY_CNTL7;
        uint32_t RDPCSTX_PHY_CNTL8;
        uint32_t RDPCSTX_PHY_CNTL9;
index 90127c1..b089244 100644 (file)
@@ -37,6 +37,7 @@
 
 #include "link_enc_cfg.h"
 #include "dc_dmub_srv.h"
+#include "dal_asic_id.h"
 
 #define CTX \
        enc10->base.ctx
 #define AUX_REG_WRITE(reg_name, val) \
                        dm_write_reg(CTX, AUX_REG(reg_name), val)
 
+#ifndef MIN
+#define MIN(X, Y) ((X) < (Y) ? (X) : (Y))
+#endif
+
 void dcn31_link_encoder_set_dio_phy_mux(
        struct link_encoder *enc,
        enum encoder_type_select sel,
@@ -215,8 +220,8 @@ static const struct link_encoder_funcs dcn31_link_enc_funcs = {
        .fec_is_active = enc2_fec_is_active,
        .get_dig_frontend = dcn10_get_dig_frontend,
        .get_dig_mode = dcn10_get_dig_mode,
-       .is_in_alt_mode = dcn20_link_encoder_is_in_alt_mode,
-       .get_max_link_cap = dcn20_link_encoder_get_max_link_cap,
+       .is_in_alt_mode = dcn31_link_encoder_is_in_alt_mode,
+       .get_max_link_cap = dcn31_link_encoder_get_max_link_cap,
        .set_dio_phy_mux = dcn31_link_encoder_set_dio_phy_mux,
 };
 
@@ -404,3 +409,60 @@ void dcn31_link_encoder_disable_output(
        }
 }
 
+bool dcn31_link_encoder_is_in_alt_mode(struct link_encoder *enc)
+{
+       struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
+       uint32_t dp_alt_mode_disable;
+       bool is_usb_c_alt_mode = false;
+
+       if (enc->features.flags.bits.DP_IS_USB_C) {
+               if (enc->ctx->asic_id.hw_internal_rev != YELLOW_CARP_B0) {
+                       // [Note] no need to check hw_internal_rev once phy mux selection is ready
+                       REG_GET(RDPCSTX_PHY_CNTL6, RDPCS_PHY_DPALT_DISABLE, &dp_alt_mode_disable);
+               } else {
+               /*
+                * B0 phys use a new set of registers to check whether alt mode is disabled.
+                * if value == 1 alt mode is disabled, otherwise it is enabled.
+                */
+                       if ((enc10->base.transmitter == TRANSMITTER_UNIPHY_A)
+                                       || (enc10->base.transmitter == TRANSMITTER_UNIPHY_B)
+                                       || (enc10->base.transmitter == TRANSMITTER_UNIPHY_E)) {
+                               REG_GET(RDPCSTX_PHY_CNTL6, RDPCS_PHY_DPALT_DISABLE, &dp_alt_mode_disable);
+                       } else {
+                       // [Note] need to change TRANSMITTER_UNIPHY_C/D to F/G once phy mux selection is ready
+                               REG_GET(RDPCSPIPE_PHY_CNTL6, RDPCS_PHY_DPALT_DISABLE, &dp_alt_mode_disable);
+                       }
+               }
+
+               is_usb_c_alt_mode = (dp_alt_mode_disable == 0);
+       }
+
+       return is_usb_c_alt_mode;
+}
+
+void dcn31_link_encoder_get_max_link_cap(struct link_encoder *enc,
+                                                                                struct dc_link_settings *link_settings)
+{
+       struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
+       uint32_t is_in_usb_c_dp4_mode = 0;
+
+       dcn10_link_encoder_get_max_link_cap(enc, link_settings);
+
+       /* in usb c dp2 mode, max lane count is 2 */
+       if (enc->funcs->is_in_alt_mode && enc->funcs->is_in_alt_mode(enc)) {
+               if (enc->ctx->asic_id.hw_internal_rev != YELLOW_CARP_B0) {
+                       // [Note] no need to check hw_internal_rev once phy mux selection is ready
+                       REG_GET(RDPCSTX_PHY_CNTL6, RDPCS_PHY_DPALT_DP4, &is_in_usb_c_dp4_mode);
+               } else {
+                       if ((enc10->base.transmitter == TRANSMITTER_UNIPHY_A)
+                                       || (enc10->base.transmitter == TRANSMITTER_UNIPHY_B)
+                                       || (enc10->base.transmitter == TRANSMITTER_UNIPHY_E)) {
+                               REG_GET(RDPCSTX_PHY_CNTL6, RDPCS_PHY_DPALT_DP4, &is_in_usb_c_dp4_mode);
+                       } else {
+                               REG_GET(RDPCSPIPE_PHY_CNTL6, RDPCS_PHY_DPALT_DP4, &is_in_usb_c_dp4_mode);
+                       }
+               }
+               if (!is_in_usb_c_dp4_mode)
+                       link_settings->lane_count = MIN(LANE_COUNT_TWO, link_settings->lane_count);
+       }
+}
index 32d1463..3454f1e 100644 (file)
@@ -69,6 +69,7 @@
        SRI(RDPCSTX_PHY_CNTL4, RDPCSTX, id), \
        SRI(RDPCSTX_PHY_CNTL5, RDPCSTX, id), \
        SRI(RDPCSTX_PHY_CNTL6, RDPCSTX, id), \
+       SRI(RDPCSPIPE_PHY_CNTL6, RDPCSPIPE, id), \
        SRI(RDPCSTX_PHY_CNTL7, RDPCSTX, id), \
        SRI(RDPCSTX_PHY_CNTL8, RDPCSTX, id), \
        SRI(RDPCSTX_PHY_CNTL9, RDPCSTX, id), \
        LE_SF(RDPCSTX0_RDPCSTX_PHY_CNTL6, RDPCS_PHY_DP_TX2_MPLL_EN, mask_sh),\
        LE_SF(RDPCSTX0_RDPCSTX_PHY_CNTL6, RDPCS_PHY_DP_TX3_MPLL_EN, mask_sh),\
        LE_SF(RDPCSTX0_RDPCSTX_PHY_CNTL6, RDPCS_PHY_DPALT_DP4, mask_sh),\
-       LE_SF(RDPCSTX0_RDPCSTX_PHY_CNTL6, RDPCS_PHY_DPALT_DISABLE, mask_sh),\
+       LE_SF(RDPCSPIPE0_RDPCSPIPE_PHY_CNTL6, RDPCS_PHY_DPALT_DP4, mask_sh),\
+       LE_SF(RDPCSPIPE0_RDPCSPIPE_PHY_CNTL6, RDPCS_PHY_DPALT_DISABLE, mask_sh),\
+       LE_SF(RDPCSPIPE0_RDPCSPIPE_PHY_CNTL6, RDPCS_PHY_DPALT_DISABLE_ACK, mask_sh),\
        LE_SF(RDPCSTX0_RDPCSTX_PHY_CNTL7, RDPCS_PHY_DP_MPLLB_FRACN_QUOT, mask_sh),\
        LE_SF(RDPCSTX0_RDPCSTX_PHY_CNTL7, RDPCS_PHY_DP_MPLLB_FRACN_DEN, mask_sh),\
        LE_SF(RDPCSTX0_RDPCSTX_PHY_CNTL8, RDPCS_PHY_DP_MPLLB_SSC_PEAK, mask_sh),\
@@ -243,4 +246,13 @@ void dcn31_link_encoder_disable_output(
        struct link_encoder *enc,
        enum signal_type signal);
 
+/*
+ * Check whether USB-C DP Alt mode is disabled
+ */
+bool dcn31_link_encoder_is_in_alt_mode(
+       struct link_encoder *enc);
+
+void dcn31_link_encoder_get_max_link_cap(struct link_encoder *enc,
+       struct dc_link_settings *link_settings);
+
 #endif /* __DC_LINK_ENCODER__DCN31_H__ */
index a7702d3..0006bba 100644 (file)
@@ -928,7 +928,7 @@ static const struct dc_debug_options debug_defaults_drv = {
        .disable_dcc = DCC_ENABLE,
        .vsr_support = true,
        .performance_trace = false,
-       .max_downscale_src_width = 7680,/*upto 8K*/
+       .max_downscale_src_width = 3840,/*upto 4K*/
        .disable_pplib_wm_range = false,
        .scl_reset_length10 = true,
        .sanity_checks = false,
@@ -1284,6 +1284,12 @@ static struct stream_encoder *dcn31_stream_encoder_create(
        if (!enc1 || !vpg || !afmt)
                return NULL;
 
+       if (ctx->asic_id.chip_family == FAMILY_YELLOW_CARP &&
+                       ctx->asic_id.hw_internal_rev == YELLOW_CARP_B0) {
+               if ((eng_id == ENGINE_ID_DIGC) || (eng_id == ENGINE_ID_DIGD))
+                       eng_id = eng_id + 3; // For B0 only. C->F, D->G.
+       }
+
        dcn30_dio_stream_encoder_construct(enc1, ctx, ctx->dc_bios,
                                        eng_id, vpg, afmt,
                                        &stream_enc_regs[eng_id],
index 381c17c..5adc471 100644 (file)
@@ -227,7 +227,7 @@ enum {
 #define FAMILY_YELLOW_CARP                     146
 
 #define YELLOW_CARP_A0 0x01
-#define YELLOW_CARP_B0 0x02            // TODO: DCN31 - update with correct B0 ID
+#define YELLOW_CARP_B0 0x1A
 #define YELLOW_CARP_UNKNOWN 0xFF
 
 #ifndef ASICREV_IS_YELLOW_CARP
index 92caf84..01a5655 100644 (file)
 #define ixDPCSSYS_CR4_RAWLANEX_DIG_PCS_XF_RX_OVRD_OUT_2                                                0xe0c7
 #define ixDPCSSYS_CR4_RAWLANEX_DIG_PCS_XF_TX_OVRD_IN_2                                                 0xe0c8
 
+//RDPCSPIPE0_RDPCSPIPE_PHY_CNTL6
+#define RDPCSPIPE0_RDPCSPIPE_PHY_CNTL6__RDPCS_PHY_DPALT_DP4__SHIFT                                            0x10
+#define RDPCSPIPE0_RDPCSPIPE_PHY_CNTL6__RDPCS_PHY_DPALT_DISABLE__SHIFT                                        0x11
+#define RDPCSPIPE0_RDPCSPIPE_PHY_CNTL6__RDPCS_PHY_DPALT_DISABLE_ACK__SHIFT                                    0x12
+#define RDPCSPIPE0_RDPCSPIPE_PHY_CNTL6__RDPCS_PHY_DPALT_DP4_MASK                                              0x00010000L
+#define RDPCSPIPE0_RDPCSPIPE_PHY_CNTL6__RDPCS_PHY_DPALT_DISABLE_MASK                                          0x00020000L
+#define RDPCSPIPE0_RDPCSPIPE_PHY_CNTL6__RDPCS_PHY_DPALT_DISABLE_ACK_MASK                                      0x00040000L
+
+//RDPCSPIPE1_RDPCSPIPE_PHY_CNTL6
+#define RDPCSPIPE1_RDPCSPIPE_PHY_CNTL6__RDPCS_PHY_DPALT_DP4__SHIFT                                            0x10
+#define RDPCSPIPE1_RDPCSPIPE_PHY_CNTL6__RDPCS_PHY_DPALT_DISABLE__SHIFT                                        0x11
+#define RDPCSPIPE1_RDPCSPIPE_PHY_CNTL6__RDPCS_PHY_DPALT_DISABLE_ACK__SHIFT                                    0x12
+#define RDPCSPIPE1_RDPCSPIPE_PHY_CNTL6__RDPCS_PHY_DPALT_DP4_MASK                                              0x00010000L
+#define RDPCSPIPE1_RDPCSPIPE_PHY_CNTL6__RDPCS_PHY_DPALT_DISABLE_MASK                                          0x00020000L
+#define RDPCSPIPE1_RDPCSPIPE_PHY_CNTL6__RDPCS_PHY_DPALT_DISABLE_ACK_MASK                                      0x00040000L
+
+//[Note] Hack. RDPCSPIPE only has 2 instances.
+#define regRDPCSPIPE0_RDPCSPIPE_PHY_CNTL6                                                              0x2d73
+#define regRDPCSPIPE0_RDPCSPIPE_PHY_CNTL6_BASE_IDX                                                     2
+#define regRDPCSPIPE1_RDPCSPIPE_PHY_CNTL6                                                              0x2e4b
+#define regRDPCSPIPE1_RDPCSPIPE_PHY_CNTL6_BASE_IDX                                                     2
+#define regRDPCSPIPE2_RDPCSPIPE_PHY_CNTL6                                                              0x2d73
+#define regRDPCSPIPE2_RDPCSPIPE_PHY_CNTL6_BASE_IDX                                                     2
+#define regRDPCSPIPE3_RDPCSPIPE_PHY_CNTL6                                                              0x2e4b
+#define regRDPCSPIPE3_RDPCSPIPE_PHY_CNTL6_BASE_IDX                                                     2
+#define regRDPCSPIPE4_RDPCSPIPE_PHY_CNTL6                                                              0x2d73
+#define regRDPCSPIPE4_RDPCSPIPE_PHY_CNTL6_BASE_IDX                                                     2
 
 #endif
index 6325877..ea9a79b 100644 (file)
@@ -1834,11 +1834,20 @@ static void connector_bad_edid(struct drm_connector *connector,
                               u8 *edid, int num_blocks)
 {
        int i;
-       u8 num_of_ext = edid[0x7e];
+       u8 last_block;
+
+       /*
+        * 0x7e in the EDID is the number of extension blocks. The EDID
+        * is 1 (base block) + num_ext_blocks big. That means we can think
+        * of 0x7e in the EDID of the _index_ of the last block in the
+        * combined chunk of memory.
+        */
+       last_block = edid[0x7e];
 
        /* Calculate real checksum for the last edid extension block data */
-       connector->real_edid_checksum =
-               drm_edid_block_checksum(edid + num_of_ext * EDID_LENGTH);
+       if (last_block < num_blocks)
+               connector->real_edid_checksum =
+                       drm_edid_block_checksum(edid + last_block * EDID_LENGTH);
 
        if (connector->bad_edid_counter++ && !drm_debug_enabled(DRM_UT_KMS))
                return;
index 3ab0783..8e7a124 100644 (file)
@@ -1506,6 +1506,7 @@ static int drm_fb_helper_single_fb_probe(struct drm_fb_helper *fb_helper,
 {
        struct drm_client_dev *client = &fb_helper->client;
        struct drm_device *dev = fb_helper->dev;
+       struct drm_mode_config *config = &dev->mode_config;
        int ret = 0;
        int crtc_count = 0;
        struct drm_connector_list_iter conn_iter;
@@ -1663,6 +1664,11 @@ static int drm_fb_helper_single_fb_probe(struct drm_fb_helper *fb_helper,
        /* Handle our overallocation */
        sizes.surface_height *= drm_fbdev_overalloc;
        sizes.surface_height /= 100;
+       if (sizes.surface_height > config->max_height) {
+               drm_dbg_kms(dev, "Fbdev over-allocation too large; clamping height to %d\n",
+                           config->max_height);
+               sizes.surface_height = config->max_height;
+       }
 
        /* push down into drivers */
        ret = (*fb_helper->funcs->fb_probe)(fb_helper, &sizes);
index 886add4..d2d8582 100644 (file)
@@ -46,6 +46,7 @@ int hyperv_mode_config_init(struct hyperv_drm_device *hv);
 int hyperv_update_vram_location(struct hv_device *hdev, phys_addr_t vram_pp);
 int hyperv_update_situation(struct hv_device *hdev, u8 active, u32 bpp,
                            u32 w, u32 h, u32 pitch);
+int hyperv_hide_hw_ptr(struct hv_device *hdev);
 int hyperv_update_dirt(struct hv_device *hdev, struct drm_rect *rect);
 int hyperv_connect_vsp(struct hv_device *hdev);
 
index 6dd4717..8c97a20 100644 (file)
@@ -101,6 +101,7 @@ static void hyperv_pipe_enable(struct drm_simple_display_pipe *pipe,
        struct hyperv_drm_device *hv = to_hv(pipe->crtc.dev);
        struct drm_shadow_plane_state *shadow_plane_state = to_drm_shadow_plane_state(plane_state);
 
+       hyperv_hide_hw_ptr(hv->hdev);
        hyperv_update_situation(hv->hdev, 1,  hv->screen_depth,
                                crtc_state->mode.hdisplay,
                                crtc_state->mode.vdisplay,
index 6d4bdcc..c0155c6 100644 (file)
@@ -299,6 +299,55 @@ int hyperv_update_situation(struct hv_device *hdev, u8 active, u32 bpp,
        return 0;
 }
 
+/*
+ * Hyper-V supports a hardware cursor feature. It's not used by Linux VM,
+ * but the Hyper-V host still draws a point as an extra mouse pointer,
+ * which is unwanted, especially when Xorg is running.
+ *
+ * The hyperv_fb driver uses synthvid_send_ptr() to hide the unwanted
+ * pointer, by setting msg.ptr_pos.is_visible = 1 and setting the
+ * msg.ptr_shape.data. Note: setting msg.ptr_pos.is_visible to 0 doesn't
+ * work in tests.
+ *
+ * Copy synthvid_send_ptr() to hyperv_drm and rename it to
+ * hyperv_hide_hw_ptr(). Note: hyperv_hide_hw_ptr() is also called in the
+ * handler of the SYNTHVID_FEATURE_CHANGE event, otherwise the host still
+ * draws an extra unwanted mouse pointer after the VM Connection window is
+ * closed and reopened.
+ */
+int hyperv_hide_hw_ptr(struct hv_device *hdev)
+{
+       struct synthvid_msg msg;
+
+       memset(&msg, 0, sizeof(struct synthvid_msg));
+       msg.vid_hdr.type = SYNTHVID_POINTER_POSITION;
+       msg.vid_hdr.size = sizeof(struct synthvid_msg_hdr) +
+               sizeof(struct synthvid_pointer_position);
+       msg.ptr_pos.is_visible = 1;
+       msg.ptr_pos.video_output = 0;
+       msg.ptr_pos.image_x = 0;
+       msg.ptr_pos.image_y = 0;
+       hyperv_sendpacket(hdev, &msg);
+
+       memset(&msg, 0, sizeof(struct synthvid_msg));
+       msg.vid_hdr.type = SYNTHVID_POINTER_SHAPE;
+       msg.vid_hdr.size = sizeof(struct synthvid_msg_hdr) +
+               sizeof(struct synthvid_pointer_shape);
+       msg.ptr_shape.part_idx = SYNTHVID_CURSOR_COMPLETE;
+       msg.ptr_shape.is_argb = 1;
+       msg.ptr_shape.width = 1;
+       msg.ptr_shape.height = 1;
+       msg.ptr_shape.hot_x = 0;
+       msg.ptr_shape.hot_y = 0;
+       msg.ptr_shape.data[0] = 0;
+       msg.ptr_shape.data[1] = 1;
+       msg.ptr_shape.data[2] = 1;
+       msg.ptr_shape.data[3] = 1;
+       hyperv_sendpacket(hdev, &msg);
+
+       return 0;
+}
+
 int hyperv_update_dirt(struct hv_device *hdev, struct drm_rect *rect)
 {
        struct hyperv_drm_device *hv = hv_get_drvdata(hdev);
@@ -392,8 +441,11 @@ static void hyperv_receive_sub(struct hv_device *hdev)
                return;
        }
 
-       if (msg->vid_hdr.type == SYNTHVID_FEATURE_CHANGE)
+       if (msg->vid_hdr.type == SYNTHVID_FEATURE_CHANGE) {
                hv->dirt_needed = msg->feature_chg.is_dirt_needed;
+               if (hv->dirt_needed)
+                       hyperv_hide_hw_ptr(hv->hdev);
+       }
 }
 
 static void hyperv_receive(void *ctx)
index 43ec7fc..a3eae3f 100644 (file)
@@ -1577,8 +1577,14 @@ static void gen11_dsi_sync_state(struct intel_encoder *encoder,
                                 const struct intel_crtc_state *crtc_state)
 {
        struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
-       struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state->uapi.crtc);
-       enum pipe pipe = intel_crtc->pipe;
+       struct intel_crtc *intel_crtc;
+       enum pipe pipe;
+
+       if (!crtc_state)
+               return;
+
+       intel_crtc = to_intel_crtc(crtc_state->uapi.crtc);
+       pipe = intel_crtc->pipe;
 
        /* wa verify 1409054076:icl,jsl,ehl */
        if (DISPLAY_VER(dev_priv) == 11 && pipe == PIPE_B &&
index 7cfe91f..68abeaf 100644 (file)
@@ -186,13 +186,16 @@ void intel_dsm_get_bios_data_funcs_supported(struct drm_i915_private *i915)
 {
        struct pci_dev *pdev = to_pci_dev(i915->drm.dev);
        acpi_handle dhandle;
+       union acpi_object *obj;
 
        dhandle = ACPI_HANDLE(&pdev->dev);
        if (!dhandle)
                return;
 
-       acpi_evaluate_dsm(dhandle, &intel_dsm_guid2, INTEL_DSM_REVISION_ID,
-                         INTEL_DSM_FN_GET_BIOS_DATA_FUNCS_SUPPORTED, NULL);
+       obj = acpi_evaluate_dsm(dhandle, &intel_dsm_guid2, INTEL_DSM_REVISION_ID,
+                               INTEL_DSM_FN_GET_BIOS_DATA_FUNCS_SUPPORTED, NULL);
+       if (obj)
+               ACPI_FREE(obj);
 }
 
 /*
index 5322375..4e0f96b 100644 (file)
@@ -1308,8 +1308,9 @@ static void i915_audio_component_init(struct drm_i915_private *dev_priv)
                else
                        aud_freq = aud_freq_init;
 
-               /* use BIOS provided value for TGL unless it is a known bad value */
-               if (IS_TIGERLAKE(dev_priv) && aud_freq_init != AUD_FREQ_TGL_BROKEN)
+               /* use BIOS provided value for TGL and RKL unless it is a known bad value */
+               if ((IS_TIGERLAKE(dev_priv) || IS_ROCKETLAKE(dev_priv)) &&
+                   aud_freq_init != AUD_FREQ_TGL_BROKEN)
                        aud_freq = aud_freq_init;
 
                drm_dbg_kms(&dev_priv->drm, "use AUD_FREQ_CNTRL of 0x%x (init value 0x%x)\n",
index e86e6ed..fd71346 100644 (file)
@@ -451,13 +451,23 @@ parse_lfp_backlight(struct drm_i915_private *i915,
        }
 
        i915->vbt.backlight.type = INTEL_BACKLIGHT_DISPLAY_DDI;
-       if (bdb->version >= 191 &&
-           get_blocksize(backlight_data) >= sizeof(*backlight_data)) {
-               const struct lfp_backlight_control_method *method;
+       if (bdb->version >= 191) {
+               size_t exp_size;
 
-               method = &backlight_data->backlight_control[panel_type];
-               i915->vbt.backlight.type = method->type;
-               i915->vbt.backlight.controller = method->controller;
+               if (bdb->version >= 236)
+                       exp_size = sizeof(struct bdb_lfp_backlight_data);
+               else if (bdb->version >= 234)
+                       exp_size = EXP_BDB_LFP_BL_DATA_SIZE_REV_234;
+               else
+                       exp_size = EXP_BDB_LFP_BL_DATA_SIZE_REV_191;
+
+               if (get_blocksize(backlight_data) >= exp_size) {
+                       const struct lfp_backlight_control_method *method;
+
+                       method = &backlight_data->backlight_control[panel_type];
+                       i915->vbt.backlight.type = method->type;
+                       i915->vbt.backlight.controller = method->controller;
+               }
        }
 
        i915->vbt.backlight.pwm_freq_hz = entry->pwm_freq_hz;
index 9903a78..bd18432 100644 (file)
@@ -3807,7 +3807,13 @@ void hsw_ddi_get_config(struct intel_encoder *encoder,
 static void intel_ddi_sync_state(struct intel_encoder *encoder,
                                 const struct intel_crtc_state *crtc_state)
 {
-       if (intel_crtc_has_dp_encoder(crtc_state))
+       struct drm_i915_private *i915 = to_i915(encoder->base.dev);
+       enum phy phy = intel_port_to_phy(i915, encoder->port);
+
+       if (intel_phy_is_tc(i915, phy))
+               intel_tc_port_sanitize(enc_to_dig_port(encoder));
+
+       if (crtc_state && intel_crtc_has_dp_encoder(crtc_state))
                intel_dp_sync_state(encoder, crtc_state);
 }
 
index 134a6ac..17f44ff 100644 (file)
@@ -13082,18 +13082,16 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
        readout_plane_state(dev_priv);
 
        for_each_intel_encoder(dev, encoder) {
+               struct intel_crtc_state *crtc_state = NULL;
+
                pipe = 0;
 
                if (encoder->get_hw_state(encoder, &pipe)) {
-                       struct intel_crtc_state *crtc_state;
-
                        crtc = intel_get_crtc_for_pipe(dev_priv, pipe);
                        crtc_state = to_intel_crtc_state(crtc->base.state);
 
                        encoder->base.crtc = &crtc->base;
                        intel_encoder_get_config(encoder, crtc_state);
-                       if (encoder->sync_state)
-                               encoder->sync_state(encoder, crtc_state);
 
                        /* read out to slave crtc as well for bigjoiner */
                        if (crtc_state->bigjoiner) {
@@ -13108,6 +13106,9 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
                        encoder->base.crtc = NULL;
                }
 
+               if (encoder->sync_state)
+                       encoder->sync_state(encoder, crtc_state);
+
                drm_dbg_kms(&dev_priv->drm,
                            "[ENCODER:%d:%s] hw state readout: %s, pipe %c\n",
                            encoder->base.base.id, encoder->base.name,
@@ -13390,17 +13391,6 @@ intel_modeset_setup_hw_state(struct drm_device *dev,
        intel_modeset_readout_hw_state(dev);
 
        /* HW state is read out, now we need to sanitize this mess. */
-
-       /* Sanitize the TypeC port mode upfront, encoders depend on this */
-       for_each_intel_encoder(dev, encoder) {
-               enum phy phy = intel_port_to_phy(dev_priv, encoder->port);
-
-               /* We need to sanitize only the MST primary port. */
-               if (encoder->type != INTEL_OUTPUT_DP_MST &&
-                   intel_phy_is_tc(dev_priv, phy))
-                       intel_tc_port_sanitize(enc_to_dig_port(encoder));
-       }
-
        get_encoder_power_domains(dev_priv);
 
        if (HAS_PCH_IBX(dev_priv))
index 330077c..a2108a8 100644 (file)
@@ -814,6 +814,11 @@ struct lfp_brightness_level {
        u16 reserved;
 } __packed;
 
+#define EXP_BDB_LFP_BL_DATA_SIZE_REV_191 \
+       offsetof(struct bdb_lfp_backlight_data, brightness_level)
+#define EXP_BDB_LFP_BL_DATA_SIZE_REV_234 \
+       offsetof(struct bdb_lfp_backlight_data, brightness_precision_bits)
+
 struct bdb_lfp_backlight_data {
        u8 entry_size;
        struct lfp_backlight_data_entry data[16];
index 9ccf4b2..166bb46 100644 (file)
@@ -937,6 +937,10 @@ static struct i915_gem_engines *user_engines(struct i915_gem_context *ctx,
        unsigned int n;
 
        e = alloc_engines(num_engines);
+       if (!e)
+               return ERR_PTR(-ENOMEM);
+       e->num_engines = num_engines;
+
        for (n = 0; n < num_engines; n++) {
                struct intel_context *ce;
                int ret;
@@ -970,7 +974,6 @@ static struct i915_gem_engines *user_engines(struct i915_gem_context *ctx,
                        goto free_engines;
                }
        }
-       e->num_engines = num_engines;
 
        return e;
 
index e382b7f..5ab136f 100644 (file)
@@ -118,7 +118,7 @@ i915_gem_shrink(struct i915_gem_ww_ctx *ww,
        intel_wakeref_t wakeref = 0;
        unsigned long count = 0;
        unsigned long scanned = 0;
-       int err;
+       int err = 0;
 
        /* CHV + VTD workaround use stop_machine(); need to trylock vm->mutex */
        bool trylock_vm = !ww && intel_vm_no_concurrent_access_wa(i915);
@@ -242,12 +242,15 @@ skip:
                list_splice_tail(&still_in_list, phase->list);
                spin_unlock_irqrestore(&i915->mm.obj_lock, flags);
                if (err)
-                       return err;
+                       break;
        }
 
        if (shrink & I915_SHRINK_BOUND)
                intel_runtime_pm_put(&i915->runtime_pm, wakeref);
 
+       if (err)
+               return err;
+
        if (nr_scanned)
                *nr_scanned += scanned;
        return count;
index e866105..17ca4dc 100644 (file)
@@ -421,6 +421,7 @@ void intel_context_fini(struct intel_context *ce)
 
        mutex_destroy(&ce->pin_mutex);
        i915_active_fini(&ce->active);
+       i915_sw_fence_fini(&ce->guc_blocked);
 }
 
 void i915_context_module_exit(void)
index 664970f..4037030 100644 (file)
@@ -8193,6 +8193,11 @@ enum {
 #define  HSW_SPR_STRETCH_MAX_X1                REG_FIELD_PREP(HSW_SPR_STRETCH_MAX_MASK, 3)
 #define  HSW_FBCQ_DIS                  (1 << 22)
 #define  BDW_DPRS_MASK_VBLANK_SRD      (1 << 0)
+#define  SKL_PLANE1_STRETCH_MAX_MASK   REG_GENMASK(1, 0)
+#define  SKL_PLANE1_STRETCH_MAX_X8     REG_FIELD_PREP(SKL_PLANE1_STRETCH_MAX_MASK, 0)
+#define  SKL_PLANE1_STRETCH_MAX_X4     REG_FIELD_PREP(SKL_PLANE1_STRETCH_MAX_MASK, 1)
+#define  SKL_PLANE1_STRETCH_MAX_X2     REG_FIELD_PREP(SKL_PLANE1_STRETCH_MAX_MASK, 2)
+#define  SKL_PLANE1_STRETCH_MAX_X1     REG_FIELD_PREP(SKL_PLANE1_STRETCH_MAX_MASK, 3)
 #define CHICKEN_PIPESL_1(pipe) _MMIO_PIPE(pipe, _CHICKEN_PIPESL_1_A, _CHICKEN_PIPESL_1_B)
 
 #define _CHICKEN_TRANS_A       0x420c0
index 65bc370..a725792 100644 (file)
@@ -76,6 +76,8 @@ struct intel_wm_config {
 
 static void gen9_init_clock_gating(struct drm_i915_private *dev_priv)
 {
+       enum pipe pipe;
+
        if (HAS_LLC(dev_priv)) {
                /*
                 * WaCompressedResourceDisplayNewHashMode:skl,kbl
@@ -89,6 +91,16 @@ static void gen9_init_clock_gating(struct drm_i915_private *dev_priv)
                           SKL_DE_COMPRESSED_HASH_MODE);
        }
 
+       for_each_pipe(dev_priv, pipe) {
+               /*
+                * "Plane N strech max must be programmed to 11b (x1)
+                *  when Async flips are enabled on that plane."
+                */
+               if (!IS_GEMINILAKE(dev_priv) && intel_vtd_active())
+                       intel_uncore_rmw(&dev_priv->uncore, CHICKEN_PIPESL_1(pipe),
+                                        SKL_PLANE1_STRETCH_MAX_MASK, SKL_PLANE1_STRETCH_MAX_X1);
+       }
+
        /* See Bspec note for PSR2_CTL bit 31, Wa#828:skl,bxt,kbl,cfl */
        intel_uncore_write(&dev_priv->uncore, CHICKEN_PAR1_1,
                   intel_uncore_read(&dev_priv->uncore, CHICKEN_PAR1_1) | SKL_EDP_PSR_FIX_RDWRAP);
index 1c2f479..12ce669 100644 (file)
@@ -172,10 +172,10 @@ static int kmb_setup_mode_config(struct drm_device *drm)
        ret = drmm_mode_config_init(drm);
        if (ret)
                return ret;
-       drm->mode_config.min_width = KMB_MIN_WIDTH;
-       drm->mode_config.min_height = KMB_MIN_HEIGHT;
-       drm->mode_config.max_width = KMB_MAX_WIDTH;
-       drm->mode_config.max_height = KMB_MAX_HEIGHT;
+       drm->mode_config.min_width = KMB_FB_MIN_WIDTH;
+       drm->mode_config.min_height = KMB_FB_MIN_HEIGHT;
+       drm->mode_config.max_width = KMB_FB_MAX_WIDTH;
+       drm->mode_config.max_height = KMB_FB_MAX_HEIGHT;
        drm->mode_config.funcs = &kmb_mode_config_funcs;
 
        ret = kmb_setup_crtc(drm);
index ebbaa5f..69a62e2 100644 (file)
 #define DRIVER_MAJOR                   1
 #define DRIVER_MINOR                   1
 
+#define KMB_FB_MAX_WIDTH               1920
+#define KMB_FB_MAX_HEIGHT              1080
+#define KMB_FB_MIN_WIDTH               1
+#define KMB_FB_MIN_HEIGHT              1
+
 #define KMB_LCD_DEFAULT_CLK            200000000
 #define KMB_SYS_CLK_MHZ                        500
 
index ecee678..06b0c42 100644 (file)
@@ -94,9 +94,10 @@ static int kmb_plane_atomic_check(struct drm_plane *plane,
        if (ret)
                return ret;
 
-       if (new_plane_state->crtc_w > KMB_MAX_WIDTH || new_plane_state->crtc_h > KMB_MAX_HEIGHT)
-               return -EINVAL;
-       if (new_plane_state->crtc_w < KMB_MIN_WIDTH || new_plane_state->crtc_h < KMB_MIN_HEIGHT)
+       if (new_plane_state->crtc_w > KMB_FB_MAX_WIDTH ||
+           new_plane_state->crtc_h > KMB_FB_MAX_HEIGHT ||
+           new_plane_state->crtc_w < KMB_FB_MIN_WIDTH ||
+           new_plane_state->crtc_h < KMB_FB_MIN_HEIGHT)
                return -EINVAL;
        can_position = (plane->type == DRM_PLANE_TYPE_OVERLAY);
        crtc_state =
@@ -277,6 +278,44 @@ static void config_csc(struct kmb_drm_private *kmb, int plane_id)
        kmb_write_lcd(kmb, LCD_LAYERn_CSC_OFF3(plane_id), csc_coef_lcd[11]);
 }
 
+static void kmb_plane_set_alpha(struct kmb_drm_private *kmb,
+                               const struct drm_plane_state *state,
+                               unsigned char plane_id,
+                               unsigned int *val)
+{
+       u16 plane_alpha = state->alpha;
+       u16 pixel_blend_mode = state->pixel_blend_mode;
+       int has_alpha = state->fb->format->has_alpha;
+
+       if (plane_alpha != DRM_BLEND_ALPHA_OPAQUE)
+               *val |= LCD_LAYER_ALPHA_STATIC;
+
+       if (has_alpha) {
+               switch (pixel_blend_mode) {
+               case DRM_MODE_BLEND_PIXEL_NONE:
+                       break;
+               case DRM_MODE_BLEND_PREMULTI:
+                       *val |= LCD_LAYER_ALPHA_EMBED | LCD_LAYER_ALPHA_PREMULT;
+                       break;
+               case DRM_MODE_BLEND_COVERAGE:
+                       *val |= LCD_LAYER_ALPHA_EMBED;
+                       break;
+               default:
+                       DRM_DEBUG("Missing pixel blend mode case (%s == %ld)\n",
+                                 __stringify(pixel_blend_mode),
+                                 (long)pixel_blend_mode);
+                       break;
+               }
+       }
+
+       if (plane_alpha == DRM_BLEND_ALPHA_OPAQUE && !has_alpha) {
+               *val &= LCD_LAYER_ALPHA_DISABLED;
+               return;
+       }
+
+       kmb_write_lcd(kmb, LCD_LAYERn_ALPHA(plane_id), plane_alpha);
+}
+
 static void kmb_plane_atomic_update(struct drm_plane *plane,
                                    struct drm_atomic_state *state)
 {
@@ -303,11 +342,12 @@ static void kmb_plane_atomic_update(struct drm_plane *plane,
        fb = new_plane_state->fb;
        if (!fb)
                return;
+
        num_planes = fb->format->num_planes;
        kmb_plane = to_kmb_plane(plane);
-       plane_id = kmb_plane->id;
 
        kmb = to_kmb(plane->dev);
+       plane_id = kmb_plane->id;
 
        spin_lock_irq(&kmb->irq_lock);
        if (kmb->kmb_under_flow || kmb->kmb_flush_done) {
@@ -400,20 +440,32 @@ static void kmb_plane_atomic_update(struct drm_plane *plane,
                config_csc(kmb, plane_id);
        }
 
+       kmb_plane_set_alpha(kmb, plane->state, plane_id, &val);
+
        kmb_write_lcd(kmb, LCD_LAYERn_CFG(plane_id), val);
 
+       /* Configure LCD_CONTROL */
+       ctrl = kmb_read_lcd(kmb, LCD_CONTROL);
+
+       /* Set layer blending config */
+       ctrl &= ~LCD_CTRL_ALPHA_ALL;
+       ctrl |= LCD_CTRL_ALPHA_BOTTOM_VL1 |
+               LCD_CTRL_ALPHA_BLEND_VL2;
+
+       ctrl &= ~LCD_CTRL_ALPHA_BLEND_BKGND_DISABLE;
+
        switch (plane_id) {
        case LAYER_0:
-               ctrl = LCD_CTRL_VL1_ENABLE;
+               ctrl |= LCD_CTRL_VL1_ENABLE;
                break;
        case LAYER_1:
-               ctrl = LCD_CTRL_VL2_ENABLE;
+               ctrl |= LCD_CTRL_VL2_ENABLE;
                break;
        case LAYER_2:
-               ctrl = LCD_CTRL_GL1_ENABLE;
+               ctrl |= LCD_CTRL_GL1_ENABLE;
                break;
        case LAYER_3:
-               ctrl = LCD_CTRL_GL2_ENABLE;
+               ctrl |= LCD_CTRL_GL2_ENABLE;
                break;
        }
 
@@ -425,7 +477,7 @@ static void kmb_plane_atomic_update(struct drm_plane *plane,
         */
        ctrl |= LCD_CTRL_VHSYNC_IDLE_LVL;
 
-       kmb_set_bitmask_lcd(kmb, LCD_CONTROL, ctrl);
+       kmb_write_lcd(kmb, LCD_CONTROL, ctrl);
 
        /* Enable pipeline AXI read transactions for the DMA
         * after setting graphics layers. This must be done
@@ -490,6 +542,9 @@ struct kmb_plane *kmb_plane_init(struct drm_device *drm)
        enum drm_plane_type plane_type;
        const u32 *plane_formats;
        int num_plane_formats;
+       unsigned int blend_caps = BIT(DRM_MODE_BLEND_PIXEL_NONE) |
+                                 BIT(DRM_MODE_BLEND_PREMULTI)   |
+                                 BIT(DRM_MODE_BLEND_COVERAGE);
 
        for (i = 0; i < KMB_MAX_PLANES; i++) {
                plane = drmm_kzalloc(drm, sizeof(*plane), GFP_KERNEL);
@@ -521,8 +576,16 @@ struct kmb_plane *kmb_plane_init(struct drm_device *drm)
                drm_dbg(drm, "%s : %d i=%d type=%d",
                        __func__, __LINE__,
                          i, plane_type);
+               drm_plane_create_alpha_property(&plane->base_plane);
+
+               drm_plane_create_blend_mode_property(&plane->base_plane,
+                                                    blend_caps);
+
+               drm_plane_create_zpos_immutable_property(&plane->base_plane, i);
+
                drm_plane_helper_add(&plane->base_plane,
                                     &kmb_plane_helper_funcs);
+
                if (plane_type == DRM_PLANE_TYPE_PRIMARY) {
                        primary = plane;
                        kmb->plane = plane;
index 486490f..6e8d22c 100644 (file)
@@ -35,6 +35,9 @@
 #define POSSIBLE_CRTCS 1
 #define to_kmb_plane(x) container_of(x, struct kmb_plane, base_plane)
 
+#define POSSIBLE_CRTCS         1
+#define KMB_MAX_PLANES         2
+
 enum layer_id {
        LAYER_0,
        LAYER_1,
@@ -43,8 +46,6 @@ enum layer_id {
        /* KMB_MAX_PLANES */
 };
 
-#define KMB_MAX_PLANES 1
-
 enum sub_plane_id {
        Y_PLANE,
        U_PLANE,
index 4815056..9756101 100644 (file)
 #define LCD_CTRL_OUTPUT_ENABLED                          BIT(19)
 #define LCD_CTRL_BPORCH_ENABLE                   BIT(21)
 #define LCD_CTRL_FPORCH_ENABLE                   BIT(22)
+#define LCD_CTRL_ALPHA_BLEND_BKGND_DISABLE       BIT(23)
 #define LCD_CTRL_PIPELINE_DMA                    BIT(28)
 #define LCD_CTRL_VHSYNC_IDLE_LVL                 BIT(31)
+#define LCD_CTRL_ALPHA_ALL                       (0xff << 6)
 
 /* interrupts */
 #define LCD_INT_STATUS                         (0x4 * 0x001)
 #define LCD_LAYER_ALPHA_EMBED                  BIT(5)
 #define LCD_LAYER_ALPHA_COMBI                  (LCD_LAYER_ALPHA_STATIC | \
                                                      LCD_LAYER_ALPHA_EMBED)
+#define LCD_LAYER_ALPHA_DISABLED               ~(LCD_LAYER_ALPHA_COMBI)
 /* RGB multiplied with alpha */
 #define LCD_LAYER_ALPHA_PREMULT                        BIT(6)
 #define LCD_LAYER_INVERT_COL                   BIT(7)
index 5f81489..a4e80e4 100644 (file)
@@ -4,8 +4,6 @@
  */
 
 #include <linux/clk.h>
-#include <linux/dma-mapping.h>
-#include <linux/mailbox_controller.h>
 #include <linux/pm_runtime.h>
 #include <linux/soc/mediatek/mtk-cmdq.h>
 #include <linux/soc/mediatek/mtk-mmsys.h>
@@ -52,11 +50,8 @@ struct mtk_drm_crtc {
        bool                            pending_async_planes;
 
 #if IS_REACHABLE(CONFIG_MTK_CMDQ)
-       struct mbox_client              cmdq_cl;
-       struct mbox_chan                *cmdq_chan;
-       struct cmdq_pkt                 cmdq_handle;
+       struct cmdq_client              *cmdq_client;
        u32                             cmdq_event;
-       u32                             cmdq_vblank_cnt;
 #endif
 
        struct device                   *mmsys_dev;
@@ -227,79 +222,9 @@ struct mtk_ddp_comp *mtk_drm_ddp_comp_for_plane(struct drm_crtc *crtc,
 }
 
 #if IS_REACHABLE(CONFIG_MTK_CMDQ)
-static int mtk_drm_cmdq_pkt_create(struct mbox_chan *chan, struct cmdq_pkt *pkt,
-                                   size_t size)
+static void ddp_cmdq_cb(struct cmdq_cb_data data)
 {
-       struct device *dev;
-       dma_addr_t dma_addr;
-
-       pkt->va_base = kzalloc(size, GFP_KERNEL);
-       if (!pkt->va_base) {
-               kfree(pkt);
-               return -ENOMEM;
-       }
-       pkt->buf_size = size;
-
-       dev = chan->mbox->dev;
-       dma_addr = dma_map_single(dev, pkt->va_base, pkt->buf_size,
-                                 DMA_TO_DEVICE);
-       if (dma_mapping_error(dev, dma_addr)) {
-               dev_err(dev, "dma map failed, size=%u\n", (u32)(u64)size);
-               kfree(pkt->va_base);
-               kfree(pkt);
-               return -ENOMEM;
-       }
-
-       pkt->pa_base = dma_addr;
-
-       return 0;
-}
-
-static void mtk_drm_cmdq_pkt_destroy(struct mbox_chan *chan, struct cmdq_pkt *pkt)
-{
-       dma_unmap_single(chan->mbox->dev, pkt->pa_base, pkt->buf_size,
-                        DMA_TO_DEVICE);
-       kfree(pkt->va_base);
-       kfree(pkt);
-}
-
-static void ddp_cmdq_cb(struct mbox_client *cl, void *mssg)
-{
-       struct mtk_drm_crtc *mtk_crtc = container_of(cl, struct mtk_drm_crtc, cmdq_cl);
-       struct cmdq_cb_data *data = mssg;
-       struct mtk_crtc_state *state;
-       unsigned int i;
-
-       state = to_mtk_crtc_state(mtk_crtc->base.state);
-
-       state->pending_config = false;
-
-       if (mtk_crtc->pending_planes) {
-               for (i = 0; i < mtk_crtc->layer_nr; i++) {
-                       struct drm_plane *plane = &mtk_crtc->planes[i];
-                       struct mtk_plane_state *plane_state;
-
-                       plane_state = to_mtk_plane_state(plane->state);
-
-                       plane_state->pending.config = false;
-               }
-               mtk_crtc->pending_planes = false;
-       }
-
-       if (mtk_crtc->pending_async_planes) {
-               for (i = 0; i < mtk_crtc->layer_nr; i++) {
-                       struct drm_plane *plane = &mtk_crtc->planes[i];
-                       struct mtk_plane_state *plane_state;
-
-                       plane_state = to_mtk_plane_state(plane->state);
-
-                       plane_state->pending.async_config = false;
-               }
-               mtk_crtc->pending_async_planes = false;
-       }
-
-       mtk_crtc->cmdq_vblank_cnt = 0;
-       mtk_drm_cmdq_pkt_destroy(mtk_crtc->cmdq_chan, data->pkt);
+       cmdq_pkt_destroy(data.data);
 }
 #endif
 
@@ -453,8 +378,7 @@ static void mtk_crtc_ddp_config(struct drm_crtc *crtc,
                                    state->pending_vrefresh, 0,
                                    cmdq_handle);
 
-               if (!cmdq_handle)
-                       state->pending_config = false;
+               state->pending_config = false;
        }
 
        if (mtk_crtc->pending_planes) {
@@ -474,12 +398,9 @@ static void mtk_crtc_ddp_config(struct drm_crtc *crtc,
                                mtk_ddp_comp_layer_config(comp, local_layer,
                                                          plane_state,
                                                          cmdq_handle);
-                       if (!cmdq_handle)
-                               plane_state->pending.config = false;
+                       plane_state->pending.config = false;
                }
-
-               if (!cmdq_handle)
-                       mtk_crtc->pending_planes = false;
+               mtk_crtc->pending_planes = false;
        }
 
        if (mtk_crtc->pending_async_planes) {
@@ -499,12 +420,9 @@ static void mtk_crtc_ddp_config(struct drm_crtc *crtc,
                                mtk_ddp_comp_layer_config(comp, local_layer,
                                                          plane_state,
                                                          cmdq_handle);
-                       if (!cmdq_handle)
-                               plane_state->pending.async_config = false;
+                       plane_state->pending.async_config = false;
                }
-
-               if (!cmdq_handle)
-                       mtk_crtc->pending_async_planes = false;
+               mtk_crtc->pending_async_planes = false;
        }
 }
 
@@ -512,7 +430,7 @@ static void mtk_drm_crtc_update_config(struct mtk_drm_crtc *mtk_crtc,
                                       bool needs_vblank)
 {
 #if IS_REACHABLE(CONFIG_MTK_CMDQ)
-       struct cmdq_pkt *cmdq_handle = &mtk_crtc->cmdq_handle;
+       struct cmdq_pkt *cmdq_handle;
 #endif
        struct drm_crtc *crtc = &mtk_crtc->base;
        struct mtk_drm_private *priv = crtc->dev->dev_private;
@@ -550,24 +468,14 @@ static void mtk_drm_crtc_update_config(struct mtk_drm_crtc *mtk_crtc,
                mtk_mutex_release(mtk_crtc->mutex);
        }
 #if IS_REACHABLE(CONFIG_MTK_CMDQ)
-       if (mtk_crtc->cmdq_chan) {
-               mbox_flush(mtk_crtc->cmdq_chan, 2000);
-               cmdq_handle->cmd_buf_size = 0;
+       if (mtk_crtc->cmdq_client) {
+               mbox_flush(mtk_crtc->cmdq_client->chan, 2000);
+               cmdq_handle = cmdq_pkt_create(mtk_crtc->cmdq_client, PAGE_SIZE);
                cmdq_pkt_clear_event(cmdq_handle, mtk_crtc->cmdq_event);
                cmdq_pkt_wfe(cmdq_handle, mtk_crtc->cmdq_event, false);
                mtk_crtc_ddp_config(crtc, cmdq_handle);
                cmdq_pkt_finalize(cmdq_handle);
-               dma_sync_single_for_device(mtk_crtc->cmdq_chan->mbox->dev,
-                                           cmdq_handle->pa_base,
-                                           cmdq_handle->cmd_buf_size,
-                                           DMA_TO_DEVICE);
-               /*
-                * CMDQ command should execute in next vblank,
-                * If it fail to execute in next 2 vblank, timeout happen.
-                */
-               mtk_crtc->cmdq_vblank_cnt = 2;
-               mbox_send_message(mtk_crtc->cmdq_chan, cmdq_handle);
-               mbox_client_txdone(mtk_crtc->cmdq_chan, 0);
+               cmdq_pkt_flush_async(cmdq_handle, ddp_cmdq_cb, cmdq_handle);
        }
 #endif
        mtk_crtc->config_updating = false;
@@ -581,15 +489,12 @@ static void mtk_crtc_ddp_irq(void *data)
        struct mtk_drm_private *priv = crtc->dev->dev_private;
 
 #if IS_REACHABLE(CONFIG_MTK_CMDQ)
-       if (!priv->data->shadow_register && !mtk_crtc->cmdq_chan)
-               mtk_crtc_ddp_config(crtc, NULL);
-       else if (mtk_crtc->cmdq_vblank_cnt > 0 && --mtk_crtc->cmdq_vblank_cnt == 0)
-               DRM_ERROR("mtk_crtc %d CMDQ execute command timeout!\n",
-                         drm_crtc_index(&mtk_crtc->base));
+       if (!priv->data->shadow_register && !mtk_crtc->cmdq_client)
 #else
        if (!priv->data->shadow_register)
-               mtk_crtc_ddp_config(crtc, NULL);
 #endif
+               mtk_crtc_ddp_config(crtc, NULL);
+
        mtk_drm_finish_page_flip(mtk_crtc);
 }
 
@@ -924,20 +829,16 @@ int mtk_drm_crtc_create(struct drm_device *drm_dev,
        mutex_init(&mtk_crtc->hw_lock);
 
 #if IS_REACHABLE(CONFIG_MTK_CMDQ)
-       mtk_crtc->cmdq_cl.dev = mtk_crtc->mmsys_dev;
-       mtk_crtc->cmdq_cl.tx_block = false;
-       mtk_crtc->cmdq_cl.knows_txdone = true;
-       mtk_crtc->cmdq_cl.rx_callback = ddp_cmdq_cb;
-       mtk_crtc->cmdq_chan =
-                       mbox_request_channel(&mtk_crtc->cmdq_cl,
-                                             drm_crtc_index(&mtk_crtc->base));
-       if (IS_ERR(mtk_crtc->cmdq_chan)) {
+       mtk_crtc->cmdq_client =
+                       cmdq_mbox_create(mtk_crtc->mmsys_dev,
+                                        drm_crtc_index(&mtk_crtc->base));
+       if (IS_ERR(mtk_crtc->cmdq_client)) {
                dev_dbg(dev, "mtk_crtc %d failed to create mailbox client, writing register by CPU now\n",
                        drm_crtc_index(&mtk_crtc->base));
-               mtk_crtc->cmdq_chan = NULL;
+               mtk_crtc->cmdq_client = NULL;
        }
 
-       if (mtk_crtc->cmdq_chan) {
+       if (mtk_crtc->cmdq_client) {
                ret = of_property_read_u32_index(priv->mutex_node,
                                                 "mediatek,gce-events",
                                                 drm_crtc_index(&mtk_crtc->base),
@@ -945,18 +846,8 @@ int mtk_drm_crtc_create(struct drm_device *drm_dev,
                if (ret) {
                        dev_dbg(dev, "mtk_crtc %d failed to get mediatek,gce-events property\n",
                                drm_crtc_index(&mtk_crtc->base));
-                       mbox_free_channel(mtk_crtc->cmdq_chan);
-                       mtk_crtc->cmdq_chan = NULL;
-               } else {
-                       ret = mtk_drm_cmdq_pkt_create(mtk_crtc->cmdq_chan,
-                                                      &mtk_crtc->cmdq_handle,
-                                                      PAGE_SIZE);
-                       if (ret) {
-                               dev_dbg(dev, "mtk_crtc %d failed to create cmdq packet\n",
-                                       drm_crtc_index(&mtk_crtc->base));
-                               mbox_free_channel(mtk_crtc->cmdq_chan);
-                               mtk_crtc->cmdq_chan = NULL;
-                       }
+                       cmdq_mbox_destroy(mtk_crtc->cmdq_client);
+                       mtk_crtc->cmdq_client = NULL;
                }
        }
 #endif
index e9c6af7..3ddf739 100644 (file)
@@ -17,7 +17,7 @@ config DRM_MSM
        select DRM_SCHED
        select SHMEM
        select TMPFS
-       select QCOM_SCM if ARCH_QCOM
+       select QCOM_SCM
        select WANT_DEV_COREDUMP
        select SND_SOC_HDMI_CODEC if SND_SOC
        select SYNC_FILE
@@ -55,7 +55,7 @@ config DRM_MSM_GPU_SUDO
 
 config DRM_MSM_HDMI_HDCP
        bool "Enable HDMI HDCP support in MSM DRM driver"
-       depends on DRM_MSM && QCOM_SCM
+       depends on DRM_MSM
        default y
        help
          Choose this option to enable HDCP state machine
index 4534633..8fb847c 100644 (file)
@@ -571,13 +571,14 @@ struct msm_gpu *a3xx_gpu_init(struct drm_device *dev)
        }
 
        icc_path = devm_of_icc_get(&pdev->dev, "gfx-mem");
-       ret = IS_ERR(icc_path);
-       if (ret)
+       if (IS_ERR(icc_path)) {
+               ret = PTR_ERR(icc_path);
                goto fail;
+       }
 
        ocmem_icc_path = devm_of_icc_get(&pdev->dev, "ocmem");
-       ret = IS_ERR(ocmem_icc_path);
-       if (ret) {
+       if (IS_ERR(ocmem_icc_path)) {
+               ret = PTR_ERR(ocmem_icc_path);
                /* allow -ENODATA, ocmem icc is optional */
                if (ret != -ENODATA)
                        goto fail;
index 82bebb4..a96ee79 100644 (file)
@@ -699,13 +699,14 @@ struct msm_gpu *a4xx_gpu_init(struct drm_device *dev)
        }
 
        icc_path = devm_of_icc_get(&pdev->dev, "gfx-mem");
-       ret = IS_ERR(icc_path);
-       if (ret)
+       if (IS_ERR(icc_path)) {
+               ret = PTR_ERR(icc_path);
                goto fail;
+       }
 
        ocmem_icc_path = devm_of_icc_get(&pdev->dev, "ocmem");
-       ret = IS_ERR(ocmem_icc_path);
-       if (ret) {
+       if (IS_ERR(ocmem_icc_path)) {
+               ret = PTR_ERR(ocmem_icc_path);
                /* allow -ENODATA, ocmem icc is optional */
                if (ret != -ENODATA)
                        goto fail;
index a7c5801..8b73f70 100644 (file)
@@ -296,6 +296,8 @@ int a6xx_gmu_set_oob(struct a6xx_gmu *gmu, enum a6xx_gmu_oob_state state)
        u32 val;
        int request, ack;
 
+       WARN_ON_ONCE(!mutex_is_locked(&gmu->lock));
+
        if (state >= ARRAY_SIZE(a6xx_gmu_oob_bits))
                return -EINVAL;
 
@@ -337,6 +339,8 @@ void a6xx_gmu_clear_oob(struct a6xx_gmu *gmu, enum a6xx_gmu_oob_state state)
 {
        int bit;
 
+       WARN_ON_ONCE(!mutex_is_locked(&gmu->lock));
+
        if (state >= ARRAY_SIZE(a6xx_gmu_oob_bits))
                return;
 
@@ -1482,6 +1486,8 @@ int a6xx_gmu_init(struct a6xx_gpu *a6xx_gpu, struct device_node *node)
        if (!pdev)
                return -ENODEV;
 
+       mutex_init(&gmu->lock);
+
        gmu->dev = &pdev->dev;
 
        of_dma_configure(gmu->dev, node, true);
index 3c74f64..84bd516 100644 (file)
@@ -44,6 +44,9 @@ struct a6xx_gmu_bo {
 struct a6xx_gmu {
        struct device *dev;
 
+       /* For serializing communication with the GMU: */
+       struct mutex lock;
+
        struct msm_gem_address_space *aspace;
 
        void * __iomem mmio;
index 40c9fef..33da25b 100644 (file)
@@ -106,7 +106,7 @@ static void a6xx_set_pagetable(struct a6xx_gpu *a6xx_gpu,
        u32 asid;
        u64 memptr = rbmemptr(ring, ttbr0);
 
-       if (ctx == a6xx_gpu->cur_ctx)
+       if (ctx->seqno == a6xx_gpu->cur_ctx_seqno)
                return;
 
        if (msm_iommu_pagetable_params(ctx->aspace->mmu, &ttbr, &asid))
@@ -139,7 +139,7 @@ static void a6xx_set_pagetable(struct a6xx_gpu *a6xx_gpu,
        OUT_PKT7(ring, CP_EVENT_WRITE, 1);
        OUT_RING(ring, 0x31);
 
-       a6xx_gpu->cur_ctx = ctx;
+       a6xx_gpu->cur_ctx_seqno = ctx->seqno;
 }
 
 static void a6xx_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit)
@@ -881,7 +881,7 @@ static int a6xx_zap_shader_init(struct msm_gpu *gpu)
          A6XX_RBBM_INT_0_MASK_UCHE_OOB_ACCESS | \
          A6XX_RBBM_INT_0_MASK_UCHE_TRAP_INTR)
 
-static int a6xx_hw_init(struct msm_gpu *gpu)
+static int hw_init(struct msm_gpu *gpu)
 {
        struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
        struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu);
@@ -1081,7 +1081,7 @@ static int a6xx_hw_init(struct msm_gpu *gpu)
        /* Always come up on rb 0 */
        a6xx_gpu->cur_ring = gpu->rb[0];
 
-       a6xx_gpu->cur_ctx = NULL;
+       a6xx_gpu->cur_ctx_seqno = 0;
 
        /* Enable the SQE_to start the CP engine */
        gpu_write(gpu, REG_A6XX_CP_SQE_CNTL, 1);
@@ -1135,6 +1135,19 @@ out:
        return ret;
 }
 
+static int a6xx_hw_init(struct msm_gpu *gpu)
+{
+       struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
+       struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu);
+       int ret;
+
+       mutex_lock(&a6xx_gpu->gmu.lock);
+       ret = hw_init(gpu);
+       mutex_unlock(&a6xx_gpu->gmu.lock);
+
+       return ret;
+}
+
 static void a6xx_dump(struct msm_gpu *gpu)
 {
        DRM_DEV_INFO(&gpu->pdev->dev, "status:   %08x\n",
@@ -1509,7 +1522,9 @@ static int a6xx_pm_resume(struct msm_gpu *gpu)
 
        trace_msm_gpu_resume(0);
 
+       mutex_lock(&a6xx_gpu->gmu.lock);
        ret = a6xx_gmu_resume(a6xx_gpu);
+       mutex_unlock(&a6xx_gpu->gmu.lock);
        if (ret)
                return ret;
 
@@ -1532,7 +1547,9 @@ static int a6xx_pm_suspend(struct msm_gpu *gpu)
 
        msm_devfreq_suspend(gpu);
 
+       mutex_lock(&a6xx_gpu->gmu.lock);
        ret = a6xx_gmu_stop(a6xx_gpu);
+       mutex_unlock(&a6xx_gpu->gmu.lock);
        if (ret)
                return ret;
 
@@ -1547,18 +1564,19 @@ static int a6xx_get_timestamp(struct msm_gpu *gpu, uint64_t *value)
 {
        struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
        struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu);
-       static DEFINE_MUTEX(perfcounter_oob);
 
-       mutex_lock(&perfcounter_oob);
+       mutex_lock(&a6xx_gpu->gmu.lock);
 
        /* Force the GPU power on so we can read this register */
        a6xx_gmu_set_oob(&a6xx_gpu->gmu, GMU_OOB_PERFCOUNTER_SET);
 
        *value = gpu_read64(gpu, REG_A6XX_CP_ALWAYS_ON_COUNTER_LO,
-               REG_A6XX_CP_ALWAYS_ON_COUNTER_HI);
+                           REG_A6XX_CP_ALWAYS_ON_COUNTER_HI);
 
        a6xx_gmu_clear_oob(&a6xx_gpu->gmu, GMU_OOB_PERFCOUNTER_SET);
-       mutex_unlock(&perfcounter_oob);
+
+       mutex_unlock(&a6xx_gpu->gmu.lock);
+
        return 0;
 }
 
@@ -1622,6 +1640,16 @@ static unsigned long a6xx_gpu_busy(struct msm_gpu *gpu)
        return (unsigned long)busy_time;
 }
 
+void a6xx_gpu_set_freq(struct msm_gpu *gpu, struct dev_pm_opp *opp)
+{
+       struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
+       struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu);
+
+       mutex_lock(&a6xx_gpu->gmu.lock);
+       a6xx_gmu_set_freq(gpu, opp);
+       mutex_unlock(&a6xx_gpu->gmu.lock);
+}
+
 static struct msm_gem_address_space *
 a6xx_create_address_space(struct msm_gpu *gpu, struct platform_device *pdev)
 {
@@ -1766,7 +1794,7 @@ static const struct adreno_gpu_funcs funcs = {
 #endif
                .gpu_busy = a6xx_gpu_busy,
                .gpu_get_freq = a6xx_gmu_get_freq,
-               .gpu_set_freq = a6xx_gmu_set_freq,
+               .gpu_set_freq = a6xx_gpu_set_freq,
 #if defined(CONFIG_DRM_MSM_GPU_STATE)
                .gpu_state_get = a6xx_gpu_state_get,
                .gpu_state_put = a6xx_gpu_state_put,
index 0bc2d06..8e5527c 100644 (file)
@@ -19,7 +19,16 @@ struct a6xx_gpu {
        uint64_t sqe_iova;
 
        struct msm_ringbuffer *cur_ring;
-       struct msm_file_private *cur_ctx;
+
+       /**
+        * cur_ctx_seqno:
+        *
+        * The ctx->seqno value of the context with current pgtables
+        * installed.  Tracked by seqno rather than pointer value to
+        * avoid dangling pointers, and cases where a ctx can be freed
+        * and a new one created with the same address.
+        */
+       int cur_ctx_seqno;
 
        struct a6xx_gmu gmu;
 
index b131fd3..700d65e 100644 (file)
@@ -794,7 +794,7 @@ static const struct dpu_pingpong_cfg sm8150_pp[] = {
                        DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 30),
                        -1),
        PP_BLK("pingpong_5", PINGPONG_5, 0x72800, MERGE_3D_2, sdm845_pp_sblk,
-                       DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 30),
+                       DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 31),
                        -1),
 };
 
index f482e09..bb7d066 100644 (file)
@@ -1125,6 +1125,20 @@ static void mdp5_crtc_reset(struct drm_crtc *crtc)
        __drm_atomic_helper_crtc_reset(crtc, &mdp5_cstate->base);
 }
 
+static const struct drm_crtc_funcs mdp5_crtc_no_lm_cursor_funcs = {
+       .set_config = drm_atomic_helper_set_config,
+       .destroy = mdp5_crtc_destroy,
+       .page_flip = drm_atomic_helper_page_flip,
+       .reset = mdp5_crtc_reset,
+       .atomic_duplicate_state = mdp5_crtc_duplicate_state,
+       .atomic_destroy_state = mdp5_crtc_destroy_state,
+       .atomic_print_state = mdp5_crtc_atomic_print_state,
+       .get_vblank_counter = mdp5_crtc_get_vblank_counter,
+       .enable_vblank  = msm_crtc_enable_vblank,
+       .disable_vblank = msm_crtc_disable_vblank,
+       .get_vblank_timestamp = drm_crtc_vblank_helper_get_vblank_timestamp,
+};
+
 static const struct drm_crtc_funcs mdp5_crtc_funcs = {
        .set_config = drm_atomic_helper_set_config,
        .destroy = mdp5_crtc_destroy,
@@ -1313,6 +1327,8 @@ struct drm_crtc *mdp5_crtc_init(struct drm_device *dev,
        mdp5_crtc->lm_cursor_enabled = cursor_plane ? false : true;
 
        drm_crtc_init_with_planes(dev, crtc, plane, cursor_plane,
+                                 cursor_plane ?
+                                 &mdp5_crtc_no_lm_cursor_funcs :
                                  &mdp5_crtc_funcs, NULL);
 
        drm_flip_work_init(&mdp5_crtc->unref_cursor_work,
index fbe4c2c..a0392e4 100644 (file)
@@ -1309,14 +1309,14 @@ static int dp_pm_resume(struct device *dev)
         * can not declared display is connected unless
         * HDMI cable is plugged in and sink_count of
         * dongle become 1
+        * also only signal audio when disconnected
         */
-       if (dp->link->sink_count)
+       if (dp->link->sink_count) {
                dp->dp_display.is_connected = true;
-       else
+       } else {
                dp->dp_display.is_connected = false;
-
-       dp_display_handle_plugged_change(g_dp_display,
-                               dp->dp_display.is_connected);
+               dp_display_handle_plugged_change(g_dp_display, false);
+       }
 
        DRM_DEBUG_DP("After, sink_count=%d is_connected=%d core_inited=%d power_on=%d\n",
                        dp->link->sink_count, dp->dp_display.is_connected,
index 614dc7f..75ae300 100644 (file)
@@ -215,8 +215,10 @@ int msm_dsi_modeset_init(struct msm_dsi *msm_dsi, struct drm_device *dev,
                goto fail;
        }
 
-       if (!msm_dsi_manager_validate_current_config(msm_dsi->id))
+       if (!msm_dsi_manager_validate_current_config(msm_dsi->id)) {
+               ret = -EINVAL;
                goto fail;
+       }
 
        msm_dsi->encoder = encoder;
 
index e269df2..c86b509 100644 (file)
@@ -451,7 +451,7 @@ static int dsi_bus_clk_enable(struct msm_dsi_host *msm_host)
 
        return 0;
 err:
-       for (; i > 0; i--)
+       while (--i >= 0)
                clk_disable_unprepare(msm_host->bus_clks[i]);
 
        return ret;
index d13552b..5b4e991 100644 (file)
@@ -110,14 +110,13 @@ static struct dsi_pll_14nm *pll_14nm_list[DSI_MAX];
 static bool pll_14nm_poll_for_ready(struct dsi_pll_14nm *pll_14nm,
                                    u32 nb_tries, u32 timeout_us)
 {
-       bool pll_locked = false;
+       bool pll_locked = false, pll_ready = false;
        void __iomem *base = pll_14nm->phy->pll_base;
        u32 tries, val;
 
        tries = nb_tries;
        while (tries--) {
-               val = dsi_phy_read(base +
-                              REG_DSI_14nm_PHY_PLL_RESET_SM_READY_STATUS);
+               val = dsi_phy_read(base + REG_DSI_14nm_PHY_PLL_RESET_SM_READY_STATUS);
                pll_locked = !!(val & BIT(5));
 
                if (pll_locked)
@@ -126,23 +125,24 @@ static bool pll_14nm_poll_for_ready(struct dsi_pll_14nm *pll_14nm,
                udelay(timeout_us);
        }
 
-       if (!pll_locked) {
-               tries = nb_tries;
-               while (tries--) {
-                       val = dsi_phy_read(base +
-                               REG_DSI_14nm_PHY_PLL_RESET_SM_READY_STATUS);
-                       pll_locked = !!(val & BIT(0));
+       if (!pll_locked)
+               goto out;
 
-                       if (pll_locked)
-                               break;
+       tries = nb_tries;
+       while (tries--) {
+               val = dsi_phy_read(base + REG_DSI_14nm_PHY_PLL_RESET_SM_READY_STATUS);
+               pll_ready = !!(val & BIT(0));
 
-                       udelay(timeout_us);
-               }
+               if (pll_ready)
+                       break;
+
+               udelay(timeout_us);
        }
 
-       DBG("DSI PLL is %slocked", pll_locked ? "" : "*not* ");
+out:
+       DBG("DSI PLL is %slocked, %sready", pll_locked ? "" : "*not* ", pll_ready ? "" : "*not* ");
 
-       return pll_locked;
+       return pll_locked && pll_ready;
 }
 
 static void dsi_pll_14nm_config_init(struct dsi_pll_config *pconf)
index aaa3745..71ed4aa 100644 (file)
@@ -428,7 +428,7 @@ static int pll_28nm_register(struct dsi_pll_28nm *pll_28nm, struct clk_hw **prov
        bytediv->reg = pll_28nm->phy->pll_base + REG_DSI_28nm_8960_PHY_PLL_CTRL_9;
 
        snprintf(parent_name, 32, "dsi%dvco_clk", pll_28nm->phy->id);
-       snprintf(clk_name, 32, "dsi%dpllbyte", pll_28nm->phy->id);
+       snprintf(clk_name, 32, "dsi%dpllbyte", pll_28nm->phy->id + 1);
 
        bytediv_init.name = clk_name;
        bytediv_init.ops = &clk_bytediv_ops;
@@ -442,7 +442,7 @@ static int pll_28nm_register(struct dsi_pll_28nm *pll_28nm, struct clk_hw **prov
                return ret;
        provided_clocks[DSI_BYTE_PLL_CLK] = &bytediv->hw;
 
-       snprintf(clk_name, 32, "dsi%dpll", pll_28nm->phy->id);
+       snprintf(clk_name, 32, "dsi%dpll", pll_28nm->phy->id + 1);
        /* DIV3 */
        hw = devm_clk_hw_register_divider(dev, clk_name,
                                parent_name, 0, pll_28nm->phy->pll_base +
index 4fb397e..fe1366b 100644 (file)
@@ -1116,7 +1116,7 @@ void msm_edp_ctrl_power(struct edp_ctrl *ctrl, bool on)
 int msm_edp_ctrl_init(struct msm_edp *edp)
 {
        struct edp_ctrl *ctrl = NULL;
-       struct device *dev = &edp->pdev->dev;
+       struct device *dev;
        int ret;
 
        if (!edp) {
@@ -1124,6 +1124,7 @@ int msm_edp_ctrl_init(struct msm_edp *edp)
                return -EINVAL;
        }
 
+       dev = &edp->pdev->dev;
        ctrl = devm_kzalloc(dev, sizeof(*ctrl), GFP_KERNEL);
        if (!ctrl)
                return -ENOMEM;
index 2e6fc18..d4e0970 100644 (file)
@@ -630,10 +630,11 @@ static int msm_drm_init(struct device *dev, const struct drm_driver *drv)
        if (ret)
                goto err_msm_uninit;
 
-       ret = msm_disp_snapshot_init(ddev);
-       if (ret)
-               DRM_DEV_ERROR(dev, "msm_disp_snapshot_init failed ret = %d\n", ret);
-
+       if (kms) {
+               ret = msm_disp_snapshot_init(ddev);
+               if (ret)
+                       DRM_DEV_ERROR(dev, "msm_disp_snapshot_init failed ret = %d\n", ret);
+       }
        drm_mode_config_reset(ddev);
 
 #ifdef CONFIG_DRM_FBDEV_EMULATION
@@ -682,6 +683,7 @@ static void load_gpu(struct drm_device *dev)
 
 static int context_init(struct drm_device *dev, struct drm_file *file)
 {
+       static atomic_t ident = ATOMIC_INIT(0);
        struct msm_drm_private *priv = dev->dev_private;
        struct msm_file_private *ctx;
 
@@ -689,12 +691,17 @@ static int context_init(struct drm_device *dev, struct drm_file *file)
        if (!ctx)
                return -ENOMEM;
 
+       INIT_LIST_HEAD(&ctx->submitqueues);
+       rwlock_init(&ctx->queuelock);
+
        kref_init(&ctx->ref);
        msm_submitqueue_init(dev, ctx);
 
        ctx->aspace = msm_gpu_create_private_address_space(priv->gpu, current);
        file->driver_priv = ctx;
 
+       ctx->seqno = atomic_inc_return(&ident);
+
        return 0;
 }
 
index 8b005d1..c552f0c 100644 (file)
@@ -53,14 +53,6 @@ struct msm_disp_state;
 
 #define FRAC_16_16(mult, div)    (((mult) << 16) / (div))
 
-struct msm_file_private {
-       rwlock_t queuelock;
-       struct list_head submitqueues;
-       int queueid;
-       struct msm_gem_address_space *aspace;
-       struct kref ref;
-};
-
 enum msm_mdp_plane_property {
        PLANE_PROP_ZPOS,
        PLANE_PROP_ALPHA,
@@ -488,41 +480,6 @@ void msm_writel(u32 data, void __iomem *addr);
 u32 msm_readl(const void __iomem *addr);
 void msm_rmw(void __iomem *addr, u32 mask, u32 or);
 
-struct msm_gpu_submitqueue;
-int msm_submitqueue_init(struct drm_device *drm, struct msm_file_private *ctx);
-struct msm_gpu_submitqueue *msm_submitqueue_get(struct msm_file_private *ctx,
-               u32 id);
-int msm_submitqueue_create(struct drm_device *drm,
-               struct msm_file_private *ctx,
-               u32 prio, u32 flags, u32 *id);
-int msm_submitqueue_query(struct drm_device *drm, struct msm_file_private *ctx,
-               struct drm_msm_submitqueue_query *args);
-int msm_submitqueue_remove(struct msm_file_private *ctx, u32 id);
-void msm_submitqueue_close(struct msm_file_private *ctx);
-
-void msm_submitqueue_destroy(struct kref *kref);
-
-static inline void __msm_file_private_destroy(struct kref *kref)
-{
-       struct msm_file_private *ctx = container_of(kref,
-               struct msm_file_private, ref);
-
-       msm_gem_address_space_put(ctx->aspace);
-       kfree(ctx);
-}
-
-static inline void msm_file_private_put(struct msm_file_private *ctx)
-{
-       kref_put(&ctx->ref, __msm_file_private_destroy);
-}
-
-static inline struct msm_file_private *msm_file_private_get(
-       struct msm_file_private *ctx)
-{
-       kref_get(&ctx->ref);
-       return ctx;
-}
-
 #define DBG(fmt, ...) DRM_DEBUG_DRIVER(fmt"\n", ##__VA_ARGS__)
 #define VERB(fmt, ...) if (0) DRM_DEBUG_DRIVER(fmt"\n", ##__VA_ARGS__)
 
@@ -547,7 +504,7 @@ static inline int align_pitch(int width, int bpp)
 static inline unsigned long timeout_to_jiffies(const ktime_t *timeout)
 {
        ktime_t now = ktime_get();
-       unsigned long remaining_jiffies;
+       s64 remaining_jiffies;
 
        if (ktime_compare(*timeout, now) < 0) {
                remaining_jiffies = 0;
@@ -556,7 +513,7 @@ static inline unsigned long timeout_to_jiffies(const ktime_t *timeout)
                remaining_jiffies = ktime_divns(rem, NSEC_PER_SEC / HZ);
        }
 
-       return remaining_jiffies;
+       return clamp(remaining_jiffies, 0LL, (s64)INT_MAX);
 }
 
 #endif /* __MSM_DRV_H__ */
index fdc5367..151d19e 100644 (file)
@@ -46,7 +46,7 @@ static struct msm_gem_submit *submit_create(struct drm_device *dev,
        if (!submit)
                return ERR_PTR(-ENOMEM);
 
-       ret = drm_sched_job_init(&submit->base, &queue->entity, queue);
+       ret = drm_sched_job_init(&submit->base, queue->entity, queue);
        if (ret) {
                kfree(submit);
                return ERR_PTR(ret);
@@ -171,7 +171,8 @@ out:
 static int submit_lookup_cmds(struct msm_gem_submit *submit,
                struct drm_msm_gem_submit *args, struct drm_file *file)
 {
-       unsigned i, sz;
+       unsigned i;
+       size_t sz;
        int ret = 0;
 
        for (i = 0; i < args->nr_cmds; i++) {
@@ -907,7 +908,7 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data,
        /* The scheduler owns a ref now: */
        msm_gem_submit_get(submit);
 
-       drm_sched_entity_push_job(&submit->base, &queue->entity);
+       drm_sched_entity_push_job(&submit->base, queue->entity);
 
        args->fence = submit->fence_id;
 
index 0e4b45b..030f82f 100644 (file)
@@ -258,6 +258,39 @@ struct msm_gpu_perfcntr {
 #define NR_SCHED_PRIORITIES (1 + DRM_SCHED_PRIORITY_HIGH - DRM_SCHED_PRIORITY_MIN)
 
 /**
+ * struct msm_file_private - per-drm_file context
+ *
+ * @queuelock:    synchronizes access to submitqueues list
+ * @submitqueues: list of &msm_gpu_submitqueue created by userspace
+ * @queueid:      counter incremented each time a submitqueue is created,
+ *                used to assign &msm_gpu_submitqueue.id
+ * @aspace:       the per-process GPU address-space
+ * @ref:          reference count
+ * @seqno:        unique per process seqno
+ */
+struct msm_file_private {
+       rwlock_t queuelock;
+       struct list_head submitqueues;
+       int queueid;
+       struct msm_gem_address_space *aspace;
+       struct kref ref;
+       int seqno;
+
+       /**
+        * entities:
+        *
+        * Table of per-priority-level sched entities used by submitqueues
+        * associated with this &drm_file.  Because some userspace apps
+        * make assumptions about rendering from multiple gl contexts
+        * (of the same priority) within the process happening in FIFO
+        * order without requiring any fencing beyond MakeCurrent(), we
+        * create at most one &drm_sched_entity per-process per-priority-
+        * level.
+        */
+       struct drm_sched_entity *entities[NR_SCHED_PRIORITIES * MSM_GPU_MAX_RINGS];
+};
+
+/**
  * msm_gpu_convert_priority - Map userspace priority to ring # and sched priority
  *
  * @gpu:        the gpu instance
@@ -304,6 +337,8 @@ static inline int msm_gpu_convert_priority(struct msm_gpu *gpu, int prio,
 }
 
 /**
+ * struct msm_gpu_submitqueues - Userspace created context.
+ *
  * A submitqueue is associated with a gl context or vk queue (or equiv)
  * in userspace.
  *
@@ -321,7 +356,7 @@ static inline int msm_gpu_convert_priority(struct msm_gpu *gpu, int prio,
  *             seqno, protected by submitqueue lock
  * @lock:      submitqueue lock
  * @ref:       reference count
- * @entity: the submit job-queue
+ * @entity:    the submit job-queue
  */
 struct msm_gpu_submitqueue {
        int id;
@@ -333,7 +368,7 @@ struct msm_gpu_submitqueue {
        struct idr fence_idr;
        struct mutex lock;
        struct kref ref;
-       struct drm_sched_entity entity;
+       struct drm_sched_entity *entity;
 };
 
 struct msm_gpu_state_bo {
@@ -421,6 +456,33 @@ static inline void gpu_write64(struct msm_gpu *gpu, u32 lo, u32 hi, u64 val)
 int msm_gpu_pm_suspend(struct msm_gpu *gpu);
 int msm_gpu_pm_resume(struct msm_gpu *gpu);
 
+int msm_submitqueue_init(struct drm_device *drm, struct msm_file_private *ctx);
+struct msm_gpu_submitqueue *msm_submitqueue_get(struct msm_file_private *ctx,
+               u32 id);
+int msm_submitqueue_create(struct drm_device *drm,
+               struct msm_file_private *ctx,
+               u32 prio, u32 flags, u32 *id);
+int msm_submitqueue_query(struct drm_device *drm, struct msm_file_private *ctx,
+               struct drm_msm_submitqueue_query *args);
+int msm_submitqueue_remove(struct msm_file_private *ctx, u32 id);
+void msm_submitqueue_close(struct msm_file_private *ctx);
+
+void msm_submitqueue_destroy(struct kref *kref);
+
+void __msm_file_private_destroy(struct kref *kref);
+
+static inline void msm_file_private_put(struct msm_file_private *ctx)
+{
+       kref_put(&ctx->ref, __msm_file_private_destroy);
+}
+
+static inline struct msm_file_private *msm_file_private_get(
+       struct msm_file_private *ctx)
+{
+       kref_get(&ctx->ref);
+       return ctx;
+}
+
 void msm_devfreq_init(struct msm_gpu *gpu);
 void msm_devfreq_cleanup(struct msm_gpu *gpu);
 void msm_devfreq_resume(struct msm_gpu *gpu);
index 0a1ee20..84e98c0 100644 (file)
@@ -151,6 +151,9 @@ void msm_devfreq_active(struct msm_gpu *gpu)
        unsigned int idle_time;
        unsigned long target_freq = df->idle_freq;
 
+       if (!df->devfreq)
+               return;
+
        /*
         * Hold devfreq lock to synchronize with get_dev_status()/
         * target() callbacks
@@ -186,6 +189,9 @@ void msm_devfreq_idle(struct msm_gpu *gpu)
        struct msm_gpu_devfreq *df = &gpu->devfreq;
        unsigned long idle_freq, target_freq = 0;
 
+       if (!df->devfreq)
+               return;
+
        /*
         * Hold devfreq lock to synchronize with get_dev_status()/
         * target() callbacks
index 32a55d8..b8621c6 100644 (file)
@@ -7,6 +7,24 @@
 
 #include "msm_gpu.h"
 
+void __msm_file_private_destroy(struct kref *kref)
+{
+       struct msm_file_private *ctx = container_of(kref,
+               struct msm_file_private, ref);
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(ctx->entities); i++) {
+               if (!ctx->entities[i])
+                       continue;
+
+               drm_sched_entity_destroy(ctx->entities[i]);
+               kfree(ctx->entities[i]);
+       }
+
+       msm_gem_address_space_put(ctx->aspace);
+       kfree(ctx);
+}
+
 void msm_submitqueue_destroy(struct kref *kref)
 {
        struct msm_gpu_submitqueue *queue = container_of(kref,
@@ -14,8 +32,6 @@ void msm_submitqueue_destroy(struct kref *kref)
 
        idr_destroy(&queue->fence_idr);
 
-       drm_sched_entity_destroy(&queue->entity);
-
        msm_file_private_put(queue->ctx);
 
        kfree(queue);
@@ -61,13 +77,47 @@ void msm_submitqueue_close(struct msm_file_private *ctx)
        }
 }
 
+static struct drm_sched_entity *
+get_sched_entity(struct msm_file_private *ctx, struct msm_ringbuffer *ring,
+                unsigned ring_nr, enum drm_sched_priority sched_prio)
+{
+       static DEFINE_MUTEX(entity_lock);
+       unsigned idx = (ring_nr * NR_SCHED_PRIORITIES) + sched_prio;
+
+       /* We should have already validated that the requested priority is
+        * valid by the time we get here.
+        */
+       if (WARN_ON(idx >= ARRAY_SIZE(ctx->entities)))
+               return ERR_PTR(-EINVAL);
+
+       mutex_lock(&entity_lock);
+
+       if (!ctx->entities[idx]) {
+               struct drm_sched_entity *entity;
+               struct drm_gpu_scheduler *sched = &ring->sched;
+               int ret;
+
+               entity = kzalloc(sizeof(*ctx->entities[idx]), GFP_KERNEL);
+
+               ret = drm_sched_entity_init(entity, sched_prio, &sched, 1, NULL);
+               if (ret) {
+                       kfree(entity);
+                       return ERR_PTR(ret);
+               }
+
+               ctx->entities[idx] = entity;
+       }
+
+       mutex_unlock(&entity_lock);
+
+       return ctx->entities[idx];
+}
+
 int msm_submitqueue_create(struct drm_device *drm, struct msm_file_private *ctx,
                u32 prio, u32 flags, u32 *id)
 {
        struct msm_drm_private *priv = drm->dev_private;
        struct msm_gpu_submitqueue *queue;
-       struct msm_ringbuffer *ring;
-       struct drm_gpu_scheduler *sched;
        enum drm_sched_priority sched_prio;
        unsigned ring_nr;
        int ret;
@@ -91,12 +141,10 @@ int msm_submitqueue_create(struct drm_device *drm, struct msm_file_private *ctx,
        queue->flags = flags;
        queue->ring_nr = ring_nr;
 
-       ring = priv->gpu->rb[ring_nr];
-       sched = &ring->sched;
-
-       ret = drm_sched_entity_init(&queue->entity,
-                       sched_prio, &sched, 1, NULL);
-       if (ret) {
+       queue->entity = get_sched_entity(ctx, priv->gpu->rb[ring_nr],
+                                        ring_nr, sched_prio);
+       if (IS_ERR(queue->entity)) {
+               ret = PTR_ERR(queue->entity);
                kfree(queue);
                return ret;
        }
@@ -140,10 +188,6 @@ int msm_submitqueue_init(struct drm_device *drm, struct msm_file_private *ctx)
         */
        default_prio = DIV_ROUND_UP(max_priority, 2);
 
-       INIT_LIST_HEAD(&ctx->submitqueues);
-
-       rwlock_init(&ctx->queuelock);
-
        return msm_submitqueue_create(drm, ctx, default_prio, 0, NULL);
 }
 
index b8c31b6..66f32d9 100644 (file)
@@ -704,6 +704,7 @@ static const struct file_operations nv50_crc_flip_threshold_fops = {
        .open = nv50_crc_debugfs_flip_threshold_open,
        .read = seq_read,
        .write = nv50_crc_debugfs_flip_threshold_set,
+       .release = single_release,
 };
 
 int nv50_head_crc_late_register(struct nv50_head *head)
index d66f972..72099d1 100644 (file)
@@ -52,6 +52,7 @@ nv50_head_flush_clr(struct nv50_head *head,
 void
 nv50_head_flush_set_wndw(struct nv50_head *head, struct nv50_head_atom *asyh)
 {
+       if (asyh->set.curs   ) head->func->curs_set(head, asyh);
        if (asyh->set.olut   ) {
                asyh->olut.offset = nv50_lut_load(&head->olut,
                                                  asyh->olut.buffer,
@@ -67,7 +68,6 @@ nv50_head_flush_set(struct nv50_head *head, struct nv50_head_atom *asyh)
        if (asyh->set.view   ) head->func->view    (head, asyh);
        if (asyh->set.mode   ) head->func->mode    (head, asyh);
        if (asyh->set.core   ) head->func->core_set(head, asyh);
-       if (asyh->set.curs   ) head->func->curs_set(head, asyh);
        if (asyh->set.base   ) head->func->base    (head, asyh);
        if (asyh->set.ovly   ) head->func->ovly    (head, asyh);
        if (asyh->set.dither ) head->func->dither  (head, asyh);
index c68cc95..a582c0c 100644 (file)
@@ -71,6 +71,7 @@
 #define PASCAL_CHANNEL_GPFIFO_A                       /* cla06f.h */ 0x0000c06f
 #define VOLTA_CHANNEL_GPFIFO_A                        /* clc36f.h */ 0x0000c36f
 #define TURING_CHANNEL_GPFIFO_A                       /* clc36f.h */ 0x0000c46f
+#define AMPERE_CHANNEL_GPFIFO_B                       /* clc36f.h */ 0x0000c76f
 
 #define NV50_DISP                                     /* cl5070.h */ 0x00005070
 #define G82_DISP                                      /* cl5070.h */ 0x00008270
 #define PASCAL_DMA_COPY_B                                            0x0000c1b5
 #define VOLTA_DMA_COPY_A                                             0x0000c3b5
 #define TURING_DMA_COPY_A                                            0x0000c5b5
+#define AMPERE_DMA_COPY_B                                            0x0000c7b5
 
 #define FERMI_DECOMPRESS                                             0x000090b8
 
index 54fab7c..64ee82c 100644 (file)
@@ -77,4 +77,5 @@ int gp100_fifo_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct
 int gp10b_fifo_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fifo **);
 int gv100_fifo_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fifo **);
 int tu102_fifo_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fifo **);
+int ga102_fifo_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fifo **);
 #endif
index 6d07e65..c58bcdb 100644 (file)
@@ -844,6 +844,7 @@ nouveau_bo_move_init(struct nouveau_drm *drm)
                            struct ttm_resource *, struct ttm_resource *);
                int (*init)(struct nouveau_channel *, u32 handle);
        } _methods[] = {
+               {  "COPY", 4, 0xc7b5, nve0_bo_move_copy, nve0_bo_move_init },
                {  "COPY", 4, 0xc5b5, nve0_bo_move_copy, nve0_bo_move_init },
                {  "GRCE", 0, 0xc5b5, nve0_bo_move_copy, nvc0_bo_move_init },
                {  "COPY", 4, 0xc3b5, nve0_bo_move_copy, nve0_bo_move_init },
index 80099ef..ea77691 100644 (file)
@@ -250,7 +250,8 @@ static int
 nouveau_channel_ind(struct nouveau_drm *drm, struct nvif_device *device,
                    u64 runlist, bool priv, struct nouveau_channel **pchan)
 {
-       static const u16 oclasses[] = { TURING_CHANNEL_GPFIFO_A,
+       static const u16 oclasses[] = { AMPERE_CHANNEL_GPFIFO_B,
+                                       TURING_CHANNEL_GPFIFO_A,
                                        VOLTA_CHANNEL_GPFIFO_A,
                                        PASCAL_CHANNEL_GPFIFO_A,
                                        MAXWELL_CHANNEL_GPFIFO_A,
@@ -386,7 +387,8 @@ nouveau_channel_init(struct nouveau_channel *chan, u32 vram, u32 gart)
 
        nvif_object_map(&chan->user, NULL, 0);
 
-       if (chan->user.oclass >= FERMI_CHANNEL_GPFIFO) {
+       if (chan->user.oclass >= FERMI_CHANNEL_GPFIFO &&
+           chan->user.oclass < AMPERE_CHANNEL_GPFIFO_B) {
                ret = nvif_notify_ctor(&chan->user, "abi16ChanKilled",
                                       nouveau_channel_killed,
                                       true, NV906F_V0_NTFY_KILLED,
index c2bc05e..1cbe010 100644 (file)
@@ -207,6 +207,7 @@ static const struct file_operations nouveau_pstate_fops = {
        .open = nouveau_debugfs_pstate_open,
        .read = seq_read,
        .write = nouveau_debugfs_pstate_set,
+       .release = single_release,
 };
 
 static struct drm_info_list nouveau_debugfs_list[] = {
index 1f828c9..6109cd9 100644 (file)
@@ -345,6 +345,9 @@ nouveau_accel_gr_init(struct nouveau_drm *drm)
        u32 arg0, arg1;
        int ret;
 
+       if (device->info.family >= NV_DEVICE_INFO_V0_AMPERE)
+               return;
+
        /* Allocate channel that has access to the graphics engine. */
        if (device->info.family >= NV_DEVICE_INFO_V0_KEPLER) {
                arg0 = nvif_fifo_runlist(device, NV_DEVICE_HOST_RUNLIST_ENGINES_GR);
@@ -469,6 +472,7 @@ nouveau_accel_init(struct nouveau_drm *drm)
                case PASCAL_CHANNEL_GPFIFO_A:
                case VOLTA_CHANNEL_GPFIFO_A:
                case TURING_CHANNEL_GPFIFO_A:
+               case AMPERE_CHANNEL_GPFIFO_B:
                        ret = nvc0_fence_create(drm);
                        break;
                default:
index 5b27845..8c2ecc2 100644 (file)
@@ -247,10 +247,8 @@ nouveau_gem_new(struct nouveau_cli *cli, u64 size, int align, uint32_t domain,
        }
 
        ret = nouveau_bo_init(nvbo, size, align, domain, NULL, NULL);
-       if (ret) {
-               nouveau_bo_ref(NULL, &nvbo);
+       if (ret)
                return ret;
-       }
 
        /* we restrict allowed domains on nv50+ to only the types
         * that were requested at creation time.  not possibly on
index 7c9c928..c3526a8 100644 (file)
@@ -204,7 +204,7 @@ nv84_fence_create(struct nouveau_drm *drm)
        priv->base.context_new = nv84_fence_context_new;
        priv->base.context_del = nv84_fence_context_del;
 
-       priv->base.uevent = true;
+       priv->base.uevent = drm->client.device.info.family < NV_DEVICE_INFO_V0_AMPERE;
 
        mutex_init(&priv->mutex);
 
index 93ddf63..ca75c5f 100644 (file)
@@ -2602,6 +2602,7 @@ nv172_chipset = {
        .top      = { 0x00000001, ga100_top_new },
        .disp     = { 0x00000001, ga102_disp_new },
        .dma      = { 0x00000001, gv100_dma_new },
+       .fifo     = { 0x00000001, ga102_fifo_new },
 };
 
 static const struct nvkm_device_chip
@@ -2622,6 +2623,7 @@ nv174_chipset = {
        .top      = { 0x00000001, ga100_top_new },
        .disp     = { 0x00000001, ga102_disp_new },
        .dma      = { 0x00000001, gv100_dma_new },
+       .fifo     = { 0x00000001, ga102_fifo_new },
 };
 
 static const struct nvkm_device_chip
@@ -2642,6 +2644,7 @@ nv177_chipset = {
        .top      = { 0x00000001, ga100_top_new },
        .disp     = { 0x00000001, ga102_disp_new },
        .dma      = { 0x00000001, gv100_dma_new },
+       .fifo     = { 0x00000001, ga102_fifo_new },
 };
 
 static int
index 3209eb7..5e831d3 100644 (file)
@@ -18,6 +18,7 @@ nvkm-y += nvkm/engine/fifo/gp100.o
 nvkm-y += nvkm/engine/fifo/gp10b.o
 nvkm-y += nvkm/engine/fifo/gv100.o
 nvkm-y += nvkm/engine/fifo/tu102.o
+nvkm-y += nvkm/engine/fifo/ga102.o
 
 nvkm-y += nvkm/engine/fifo/chan.o
 nvkm-y += nvkm/engine/fifo/channv50.o
index 353b77d..3492c56 100644 (file)
@@ -82,7 +82,7 @@ g84_fifo_chan_engine_fini(struct nvkm_fifo_chan *base,
        if (offset < 0)
                return 0;
 
-       engn = fifo->base.func->engine_id(&fifo->base, engine);
+       engn = fifo->base.func->engine_id(&fifo->base, engine) - 1;
        save = nvkm_mask(device, 0x002520, 0x0000003f, 1 << engn);
        nvkm_wr32(device, 0x0032fc, chan->base.inst->addr >> 12);
        done = nvkm_msec(device, 2000,
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/ga102.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/ga102.c
new file mode 100644 (file)
index 0000000..c630dbd
--- /dev/null
@@ -0,0 +1,311 @@
+/*
+ * Copyright 2021 Red Hat 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.
+ */
+#define ga102_fifo(p) container_of((p), struct ga102_fifo, base.engine)
+#define ga102_chan(p) container_of((p), struct ga102_chan, object)
+#include <engine/fifo.h>
+#include "user.h"
+
+#include <core/memory.h>
+#include <subdev/mmu.h>
+#include <subdev/timer.h>
+#include <subdev/top.h>
+
+#include <nvif/cl0080.h>
+#include <nvif/clc36f.h>
+#include <nvif/class.h>
+
+struct ga102_fifo {
+       struct nvkm_fifo base;
+};
+
+struct ga102_chan {
+       struct nvkm_object object;
+
+       struct {
+               u32 runl;
+               u32 chan;
+       } ctrl;
+
+       struct nvkm_memory *mthd;
+       struct nvkm_memory *inst;
+       struct nvkm_memory *user;
+       struct nvkm_memory *runl;
+
+       struct nvkm_vmm *vmm;
+};
+
+static int
+ga102_chan_sclass(struct nvkm_object *object, int index, struct nvkm_oclass *oclass)
+{
+       if (index == 0) {
+               oclass->ctor = nvkm_object_new;
+               oclass->base = (struct nvkm_sclass) { -1, -1, AMPERE_DMA_COPY_B };
+               return 0;
+       }
+
+       return -EINVAL;
+}
+
+static int
+ga102_chan_map(struct nvkm_object *object, void *argv, u32 argc,
+              enum nvkm_object_map *type, u64 *addr, u64 *size)
+{
+       struct ga102_chan *chan = ga102_chan(object);
+       struct nvkm_device *device = chan->object.engine->subdev.device;
+       u64 bar2 = nvkm_memory_bar2(chan->user);
+
+       if (bar2 == ~0ULL)
+               return -EFAULT;
+
+       *type = NVKM_OBJECT_MAP_IO;
+       *addr = device->func->resource_addr(device, 3) + bar2;
+       *size = 0x1000;
+       return 0;
+}
+
+static int
+ga102_chan_fini(struct nvkm_object *object, bool suspend)
+{
+       struct ga102_chan *chan = ga102_chan(object);
+       struct nvkm_device *device = chan->object.engine->subdev.device;
+
+       nvkm_wr32(device, chan->ctrl.chan, 0x00000003);
+
+       nvkm_wr32(device, chan->ctrl.runl + 0x098, 0x01000000);
+       nvkm_msec(device, 2000,
+               if (!(nvkm_rd32(device, chan->ctrl.runl + 0x098) & 0x00100000))
+                       break;
+       );
+
+       nvkm_wr32(device, chan->ctrl.runl + 0x088, 0);
+
+       nvkm_wr32(device, chan->ctrl.chan, 0xffffffff);
+       return 0;
+}
+
+static int
+ga102_chan_init(struct nvkm_object *object)
+{
+       struct ga102_chan *chan = ga102_chan(object);
+       struct nvkm_device *device = chan->object.engine->subdev.device;
+
+       nvkm_mask(device, chan->ctrl.runl + 0x300, 0x80000000, 0x80000000);
+
+       nvkm_wr32(device, chan->ctrl.runl + 0x080, lower_32_bits(nvkm_memory_addr(chan->runl)));
+       nvkm_wr32(device, chan->ctrl.runl + 0x084, upper_32_bits(nvkm_memory_addr(chan->runl)));
+       nvkm_wr32(device, chan->ctrl.runl + 0x088, 2);
+
+       nvkm_wr32(device, chan->ctrl.chan, 0x00000002);
+       nvkm_wr32(device, chan->ctrl.runl + 0x0090, 0);
+       return 0;
+}
+
+static void *
+ga102_chan_dtor(struct nvkm_object *object)
+{
+       struct ga102_chan *chan = ga102_chan(object);
+
+       if (chan->vmm) {
+               nvkm_vmm_part(chan->vmm, chan->inst);
+               nvkm_vmm_unref(&chan->vmm);
+       }
+
+       nvkm_memory_unref(&chan->runl);
+       nvkm_memory_unref(&chan->user);
+       nvkm_memory_unref(&chan->inst);
+       nvkm_memory_unref(&chan->mthd);
+       return chan;
+}
+
+static const struct nvkm_object_func
+ga102_chan = {
+       .dtor = ga102_chan_dtor,
+       .init = ga102_chan_init,
+       .fini = ga102_chan_fini,
+       .map = ga102_chan_map,
+       .sclass = ga102_chan_sclass,
+};
+
+static int
+ga102_chan_new(struct nvkm_device *device,
+              const struct nvkm_oclass *oclass, void *argv, u32 argc, struct nvkm_object **pobject)
+{
+       struct volta_channel_gpfifo_a_v0 *args = argv;
+       struct nvkm_top_device *tdev;
+       struct nvkm_vmm *vmm;
+       struct ga102_chan *chan;
+       int ret;
+
+       if (argc != sizeof(*args))
+               return -ENOSYS;
+
+       vmm = nvkm_uvmm_search(oclass->client, args->vmm);
+       if (IS_ERR(vmm))
+               return PTR_ERR(vmm);
+
+       if (!(chan = kzalloc(sizeof(*chan), GFP_KERNEL)))
+               return -ENOMEM;
+
+       nvkm_object_ctor(&ga102_chan, oclass, &chan->object);
+       *pobject = &chan->object;
+
+       list_for_each_entry(tdev, &device->top->device, head) {
+               if (tdev->type == NVKM_ENGINE_CE) {
+                       chan->ctrl.runl = tdev->runlist;
+                       break;
+               }
+       }
+
+       if (!chan->ctrl.runl)
+               return -ENODEV;
+
+       chan->ctrl.chan = nvkm_rd32(device, chan->ctrl.runl + 0x004) & 0xfffffff0;
+
+       args->chid = 0;
+       args->inst = 0;
+       args->token = nvkm_rd32(device, chan->ctrl.runl + 0x008) & 0xffff0000;
+
+       ret = nvkm_memory_new(device, NVKM_MEM_TARGET_INST, 0x1000, 0x1000, true, &chan->mthd);
+       if (ret)
+               return ret;
+
+       ret = nvkm_memory_new(device, NVKM_MEM_TARGET_INST, 0x1000, 0x1000, true, &chan->inst);
+       if (ret)
+               return ret;
+
+       nvkm_kmap(chan->inst);
+       nvkm_wo32(chan->inst, 0x010, 0x0000face);
+       nvkm_wo32(chan->inst, 0x030, 0x7ffff902);
+       nvkm_wo32(chan->inst, 0x048, lower_32_bits(args->ioffset));
+       nvkm_wo32(chan->inst, 0x04c, upper_32_bits(args->ioffset) |
+                                    (order_base_2(args->ilength / 8) << 16));
+       nvkm_wo32(chan->inst, 0x084, 0x20400000);
+       nvkm_wo32(chan->inst, 0x094, 0x30000001);
+       nvkm_wo32(chan->inst, 0x0ac, 0x00020000);
+       nvkm_wo32(chan->inst, 0x0e4, 0x00000000);
+       nvkm_wo32(chan->inst, 0x0e8, 0);
+       nvkm_wo32(chan->inst, 0x0f4, 0x00001000);
+       nvkm_wo32(chan->inst, 0x0f8, 0x10003080);
+       nvkm_mo32(chan->inst, 0x218, 0x00000000, 0x00000000);
+       nvkm_wo32(chan->inst, 0x220, lower_32_bits(nvkm_memory_bar2(chan->mthd)));
+       nvkm_wo32(chan->inst, 0x224, upper_32_bits(nvkm_memory_bar2(chan->mthd)));
+       nvkm_done(chan->inst);
+
+       ret = nvkm_memory_new(device, NVKM_MEM_TARGET_INST, 0x1000, 0x1000, true, &chan->user);
+       if (ret)
+               return ret;
+
+       ret = nvkm_memory_new(device, NVKM_MEM_TARGET_INST, 0x1000, 0x1000, true, &chan->runl);
+       if (ret)
+               return ret;
+
+       nvkm_kmap(chan->runl);
+       nvkm_wo32(chan->runl, 0x00, 0x80030001);
+       nvkm_wo32(chan->runl, 0x04, 1);
+       nvkm_wo32(chan->runl, 0x08, 0);
+       nvkm_wo32(chan->runl, 0x0c, 0x00000000);
+       nvkm_wo32(chan->runl, 0x10, lower_32_bits(nvkm_memory_addr(chan->user)));
+       nvkm_wo32(chan->runl, 0x14, upper_32_bits(nvkm_memory_addr(chan->user)));
+       nvkm_wo32(chan->runl, 0x18, lower_32_bits(nvkm_memory_addr(chan->inst)));
+       nvkm_wo32(chan->runl, 0x1c, upper_32_bits(nvkm_memory_addr(chan->inst)));
+       nvkm_done(chan->runl);
+
+       ret = nvkm_vmm_join(vmm, chan->inst);
+       if (ret)
+               return ret;
+
+       chan->vmm = nvkm_vmm_ref(vmm);
+       return 0;
+}
+
+static const struct nvkm_device_oclass
+ga102_chan_oclass = {
+       .ctor = ga102_chan_new,
+};
+
+static int
+ga102_user_new(struct nvkm_device *device,
+              const struct nvkm_oclass *oclass, void *argv, u32 argc, struct nvkm_object **pobject)
+{
+       return tu102_fifo_user_new(oclass, argv, argc, pobject);
+}
+
+static const struct nvkm_device_oclass
+ga102_user_oclass = {
+       .ctor = ga102_user_new,
+};
+
+static int
+ga102_fifo_sclass(struct nvkm_oclass *oclass, int index, const struct nvkm_device_oclass **class)
+{
+       if (index == 0) {
+               oclass->base = (struct nvkm_sclass) { -1, -1, VOLTA_USERMODE_A };
+               *class = &ga102_user_oclass;
+               return 0;
+       } else
+       if (index == 1) {
+               oclass->base = (struct nvkm_sclass) { 0, 0, AMPERE_CHANNEL_GPFIFO_B };
+               *class = &ga102_chan_oclass;
+               return 0;
+       }
+
+       return 2;
+}
+
+static int
+ga102_fifo_info(struct nvkm_engine *engine, u64 mthd, u64 *data)
+{
+       switch (mthd) {
+       case NV_DEVICE_HOST_CHANNELS: *data = 1; return 0;
+       default:
+               break;
+       }
+
+       return -ENOSYS;
+}
+
+static void *
+ga102_fifo_dtor(struct nvkm_engine *engine)
+{
+       return ga102_fifo(engine);
+}
+
+static const struct nvkm_engine_func
+ga102_fifo = {
+       .dtor = ga102_fifo_dtor,
+       .info = ga102_fifo_info,
+       .base.sclass = ga102_fifo_sclass,
+};
+
+int
+ga102_fifo_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst,
+              struct nvkm_fifo **pfifo)
+{
+       struct ga102_fifo *fifo;
+
+       if (!(fifo = kzalloc(sizeof(*fifo), GFP_KERNEL)))
+               return -ENOMEM;
+
+       nvkm_engine_ctor(&ga102_fifo, device, type, inst, true, &fifo->base.engine);
+       *pfifo = &fifo->base;
+       return 0;
+}
index 31933f3..c982d83 100644 (file)
@@ -54,7 +54,7 @@ ga100_top_oneinit(struct nvkm_top *top)
                        info->reset   = (data & 0x0000001f);
                        break;
                case 2:
-                       info->runlist = (data & 0x0000fc00) >> 10;
+                       info->runlist = (data & 0x00fffc00);
                        info->engine  = (data & 0x00000003);
                        break;
                default:
@@ -85,9 +85,10 @@ ga100_top_oneinit(struct nvkm_top *top)
                }
 
                nvkm_debug(subdev, "%02x.%d (%8s): addr %06x fault %2d "
-                                  "runlist %2d engine %2d reset %2d\n", type, inst,
+                                  "runlist %6x engine %2d reset %2d\n", type, inst,
                           info->type == NVKM_SUBDEV_NR ? "????????" : nvkm_subdev_type[info->type],
-                          info->addr, info->fault, info->runlist, info->engine, info->reset);
+                          info->addr, info->fault, info->runlist < 0 ? 0 : info->runlist,
+                          info->engine, info->reset);
                info = NULL;
        }
 
index beb581b..418638e 100644 (file)
@@ -295,6 +295,7 @@ config DRM_PANEL_OLIMEX_LCD_OLINUXINO
        depends on OF
        depends on I2C
        depends on BACKLIGHT_CLASS_DEVICE
+       select CRC32
        help
          The panel is used with different sizes LCDs, from 480x272 to
          1280x800, and 24 bit per pixel.
index 2d8794d..3d8a9ab 100644 (file)
@@ -146,8 +146,8 @@ static const struct reg_sequence y030xx067a_init_sequence[] = {
        { 0x09, REG09_SUB_BRIGHT_R(0x20) },
        { 0x0a, REG0A_SUB_BRIGHT_B(0x20) },
        { 0x0b, REG0B_HD_FREERUN | REG0B_VD_FREERUN },
-       { 0x0c, REG0C_CONTRAST_R(0x10) },
-       { 0x0d, REG0D_CONTRAST_G(0x10) },
+       { 0x0c, REG0C_CONTRAST_R(0x00) },
+       { 0x0d, REG0D_CONTRAST_G(0x00) },
        { 0x0e, REG0E_CONTRAST_B(0x10) },
        { 0x0f, 0 },
        { 0x10, REG10_BRIGHT(0x7f) },
index 0ecccf2..d2a0f53 100644 (file)
@@ -214,7 +214,7 @@ int drm_ati_pcigart_init(struct drm_device *dev, struct drm_ati_pcigart_info *ga
        }
        ret = 0;
 
-#if defined(__i386__) || defined(__x86_64__)
+#ifdef CONFIG_X86
        wbinvd();
 #else
        mb();
index 0daa8bb..4bf4e25 100644 (file)
@@ -86,12 +86,20 @@ int rcar_du_encoder_init(struct rcar_du_device *rcdu,
        }
 
        /*
-        * Create and initialize the encoder. On Gen3 skip the LVDS1 output if
+        * Create and initialize the encoder. On Gen3, skip the LVDS1 output if
         * the LVDS1 encoder is used as a companion for LVDS0 in dual-link
-        * mode.
+        * mode, or any LVDS output if it isn't connected. The latter may happen
+        * on D3 or E3 as the LVDS encoders are needed to provide the pixel
+        * clock to the DU, even when the LVDS outputs are not used.
         */
-       if (rcdu->info->gen >= 3 && output == RCAR_DU_OUTPUT_LVDS1) {
-               if (rcar_lvds_dual_link(bridge))
+       if (rcdu->info->gen >= 3) {
+               if (output == RCAR_DU_OUTPUT_LVDS1 &&
+                   rcar_lvds_dual_link(bridge))
+                       return -ENOLINK;
+
+               if ((output == RCAR_DU_OUTPUT_LVDS0 ||
+                    output == RCAR_DU_OUTPUT_LVDS1) &&
+                   !rcar_lvds_is_connected(bridge))
                        return -ENOLINK;
        }
 
index d061b8d..b672c5b 100644 (file)
@@ -576,6 +576,9 @@ static int rcar_lvds_attach(struct drm_bridge *bridge,
 {
        struct rcar_lvds *lvds = bridge_to_rcar_lvds(bridge);
 
+       if (!lvds->next_bridge)
+               return 0;
+
        return drm_bridge_attach(bridge->encoder, lvds->next_bridge, bridge,
                                 flags);
 }
@@ -598,6 +601,14 @@ bool rcar_lvds_dual_link(struct drm_bridge *bridge)
 }
 EXPORT_SYMBOL_GPL(rcar_lvds_dual_link);
 
+bool rcar_lvds_is_connected(struct drm_bridge *bridge)
+{
+       struct rcar_lvds *lvds = bridge_to_rcar_lvds(bridge);
+
+       return lvds->next_bridge != NULL;
+}
+EXPORT_SYMBOL_GPL(rcar_lvds_is_connected);
+
 /* -----------------------------------------------------------------------------
  * Probe & Remove
  */
index 222ec0e..eb7c6ef 100644 (file)
@@ -16,6 +16,7 @@ struct drm_bridge;
 int rcar_lvds_clk_enable(struct drm_bridge *bridge, unsigned long freq);
 void rcar_lvds_clk_disable(struct drm_bridge *bridge);
 bool rcar_lvds_dual_link(struct drm_bridge *bridge);
+bool rcar_lvds_is_connected(struct drm_bridge *bridge);
 #else
 static inline int rcar_lvds_clk_enable(struct drm_bridge *bridge,
                                       unsigned long freq)
@@ -27,6 +28,10 @@ static inline bool rcar_lvds_dual_link(struct drm_bridge *bridge)
 {
        return false;
 }
+static inline bool rcar_lvds_is_connected(struct drm_bridge *bridge)
+{
+       return false;
+}
 #endif /* CONFIG_DRM_RCAR_LVDS */
 
 #endif /* __RCAR_LVDS_H__ */
index ba9e14d..a25b98b 100644 (file)
@@ -1174,26 +1174,24 @@ static bool vop_crtc_mode_fixup(struct drm_crtc *crtc,
         *
         * Action plan:
         *
-        * 1. When DRM gives us a mode, we should add 999 Hz to it.  That way
-        *    if the clock we need is 60000001 Hz (~60 MHz) and DRM tells us to
-        *    make 60000 kHz then the clock framework will actually give us
-        *    the right clock.
+        * 1. Try to set the exact rate first, and confirm the clock framework
+        *    can provide it.
         *
-        *    NOTE: if the PLL (maybe through a divider) could actually make
-        *    a clock rate 999 Hz higher instead of the one we want then this
-        *    could be a problem.  Unfortunately there's not much we can do
-        *    since it's baked into DRM to use kHz.  It shouldn't matter in
-        *    practice since Rockchip PLLs are controlled by tables and
-        *    even if there is a divider in the middle I wouldn't expect PLL
-        *    rates in the table that are just a few kHz different.
+        * 2. If the clock framework cannot provide the exact rate, we should
+        *    add 999 Hz to the requested rate.  That way if the clock we need
+        *    is 60000001 Hz (~60 MHz) and DRM tells us to make 60000 kHz then
+        *    the clock framework will actually give us the right clock.
         *
-        * 2. Get the clock framework to round the rate for us to tell us
+        * 3. Get the clock framework to round the rate for us to tell us
         *    what it will actually make.
         *
-        * 3. Store the rounded up rate so that we don't need to worry about
+        * 4. Store the rounded up rate so that we don't need to worry about
         *    this in the actual clk_set_rate().
         */
-       rate = clk_round_rate(vop->dclk, adjusted_mode->clock * 1000 + 999);
+       rate = clk_round_rate(vop->dclk, adjusted_mode->clock * 1000);
+       if (rate / 1000 != adjusted_mode->clock)
+               rate = clk_round_rate(vop->dclk,
+                                     adjusted_mode->clock * 1000 + 999);
        adjusted_mode->clock = DIV_ROUND_UP(rate, 1000);
 
        return true;
index f75fb15..016b877 100644 (file)
@@ -216,11 +216,13 @@ static int sun8i_dw_hdmi_bind(struct device *dev, struct device *master,
                goto err_disable_clk_tmds;
        }
 
+       ret = sun8i_hdmi_phy_init(hdmi->phy);
+       if (ret)
+               goto err_disable_clk_tmds;
+
        drm_encoder_helper_add(encoder, &sun8i_dw_hdmi_encoder_helper_funcs);
        drm_simple_encoder_init(drm, encoder, DRM_MODE_ENCODER_TMDS);
 
-       sun8i_hdmi_phy_init(hdmi->phy);
-
        plat_data->mode_valid = hdmi->quirks->mode_valid;
        plat_data->use_drm_infoframe = hdmi->quirks->use_drm_infoframe;
        sun8i_hdmi_phy_set_ops(hdmi->phy, plat_data);
@@ -262,6 +264,7 @@ static void sun8i_dw_hdmi_unbind(struct device *dev, struct device *master,
        struct sun8i_dw_hdmi *hdmi = dev_get_drvdata(dev);
 
        dw_hdmi_unbind(hdmi->hdmi);
+       sun8i_hdmi_phy_deinit(hdmi->phy);
        clk_disable_unprepare(hdmi->clk_tmds);
        reset_control_assert(hdmi->rst_ctrl);
        gpiod_set_value(hdmi->ddc_en, 0);
index 74f6ed0..bffe1b9 100644 (file)
@@ -169,6 +169,7 @@ struct sun8i_hdmi_phy {
        struct clk                      *clk_phy;
        struct clk                      *clk_pll0;
        struct clk                      *clk_pll1;
+       struct device                   *dev;
        unsigned int                    rcal;
        struct regmap                   *regs;
        struct reset_control            *rst_phy;
@@ -205,7 +206,8 @@ encoder_to_sun8i_dw_hdmi(struct drm_encoder *encoder)
 
 int sun8i_hdmi_phy_get(struct sun8i_dw_hdmi *hdmi, struct device_node *node);
 
-void sun8i_hdmi_phy_init(struct sun8i_hdmi_phy *phy);
+int sun8i_hdmi_phy_init(struct sun8i_hdmi_phy *phy);
+void sun8i_hdmi_phy_deinit(struct sun8i_hdmi_phy *phy);
 void sun8i_hdmi_phy_set_ops(struct sun8i_hdmi_phy *phy,
                            struct dw_hdmi_plat_data *plat_data);
 
index c923970..b64d93d 100644 (file)
@@ -506,9 +506,60 @@ static void sun8i_hdmi_phy_init_h3(struct sun8i_hdmi_phy *phy)
        phy->rcal = (val & SUN8I_HDMI_PHY_ANA_STS_RCAL_MASK) >> 2;
 }
 
-void sun8i_hdmi_phy_init(struct sun8i_hdmi_phy *phy)
+int sun8i_hdmi_phy_init(struct sun8i_hdmi_phy *phy)
 {
+       int ret;
+
+       ret = reset_control_deassert(phy->rst_phy);
+       if (ret) {
+               dev_err(phy->dev, "Cannot deassert phy reset control: %d\n", ret);
+               return ret;
+       }
+
+       ret = clk_prepare_enable(phy->clk_bus);
+       if (ret) {
+               dev_err(phy->dev, "Cannot enable bus clock: %d\n", ret);
+               goto err_assert_rst_phy;
+       }
+
+       ret = clk_prepare_enable(phy->clk_mod);
+       if (ret) {
+               dev_err(phy->dev, "Cannot enable mod clock: %d\n", ret);
+               goto err_disable_clk_bus;
+       }
+
+       if (phy->variant->has_phy_clk) {
+               ret = sun8i_phy_clk_create(phy, phy->dev,
+                                          phy->variant->has_second_pll);
+               if (ret) {
+                       dev_err(phy->dev, "Couldn't create the PHY clock\n");
+                       goto err_disable_clk_mod;
+               }
+
+               clk_prepare_enable(phy->clk_phy);
+       }
+
        phy->variant->phy_init(phy);
+
+       return 0;
+
+err_disable_clk_mod:
+       clk_disable_unprepare(phy->clk_mod);
+err_disable_clk_bus:
+       clk_disable_unprepare(phy->clk_bus);
+err_assert_rst_phy:
+       reset_control_assert(phy->rst_phy);
+
+       return ret;
+}
+
+void sun8i_hdmi_phy_deinit(struct sun8i_hdmi_phy *phy)
+{
+       clk_disable_unprepare(phy->clk_mod);
+       clk_disable_unprepare(phy->clk_bus);
+       clk_disable_unprepare(phy->clk_phy);
+
+       reset_control_assert(phy->rst_phy);
 }
 
 void sun8i_hdmi_phy_set_ops(struct sun8i_hdmi_phy *phy,
@@ -638,6 +689,7 @@ static int sun8i_hdmi_phy_probe(struct platform_device *pdev)
                return -ENOMEM;
 
        phy->variant = (struct sun8i_hdmi_phy_variant *)match->data;
+       phy->dev = dev;
 
        ret = of_address_to_resource(node, 0, &res);
        if (ret) {
@@ -696,47 +748,10 @@ static int sun8i_hdmi_phy_probe(struct platform_device *pdev)
                goto err_put_clk_pll1;
        }
 
-       ret = reset_control_deassert(phy->rst_phy);
-       if (ret) {
-               dev_err(dev, "Cannot deassert phy reset control: %d\n", ret);
-               goto err_put_rst_phy;
-       }
-
-       ret = clk_prepare_enable(phy->clk_bus);
-       if (ret) {
-               dev_err(dev, "Cannot enable bus clock: %d\n", ret);
-               goto err_deassert_rst_phy;
-       }
-
-       ret = clk_prepare_enable(phy->clk_mod);
-       if (ret) {
-               dev_err(dev, "Cannot enable mod clock: %d\n", ret);
-               goto err_disable_clk_bus;
-       }
-
-       if (phy->variant->has_phy_clk) {
-               ret = sun8i_phy_clk_create(phy, dev,
-                                          phy->variant->has_second_pll);
-               if (ret) {
-                       dev_err(dev, "Couldn't create the PHY clock\n");
-                       goto err_disable_clk_mod;
-               }
-
-               clk_prepare_enable(phy->clk_phy);
-       }
-
        platform_set_drvdata(pdev, phy);
 
        return 0;
 
-err_disable_clk_mod:
-       clk_disable_unprepare(phy->clk_mod);
-err_disable_clk_bus:
-       clk_disable_unprepare(phy->clk_bus);
-err_deassert_rst_phy:
-       reset_control_assert(phy->rst_phy);
-err_put_rst_phy:
-       reset_control_put(phy->rst_phy);
 err_put_clk_pll1:
        clk_put(phy->clk_pll1);
 err_put_clk_pll0:
@@ -753,12 +768,6 @@ static int sun8i_hdmi_phy_remove(struct platform_device *pdev)
 {
        struct sun8i_hdmi_phy *phy = platform_get_drvdata(pdev);
 
-       clk_disable_unprepare(phy->clk_mod);
-       clk_disable_unprepare(phy->clk_bus);
-       clk_disable_unprepare(phy->clk_phy);
-
-       reset_control_assert(phy->rst_phy);
-
        reset_control_put(phy->rst_phy);
 
        clk_put(phy->clk_pll0);
index b4b4653..ed8a4b7 100644 (file)
@@ -1395,14 +1395,6 @@ static int vc4_hdmi_audio_prepare(struct device *dev, void *data,
        return 0;
 }
 
-static const struct snd_soc_dapm_widget vc4_hdmi_audio_widgets[] = {
-       SND_SOC_DAPM_OUTPUT("TX"),
-};
-
-static const struct snd_soc_dapm_route vc4_hdmi_audio_routes[] = {
-       { "TX", NULL, "Playback" },
-};
-
 static const struct snd_soc_component_driver vc4_hdmi_audio_cpu_dai_comp = {
        .name = "vc4-hdmi-cpu-dai-component",
 };
index 4e0b7c2..015e11c 100644 (file)
@@ -49,7 +49,7 @@
 #define MLXCPLD_LPCI2C_NACK_IND                2
 
 #define MLXCPLD_I2C_FREQ_1000KHZ_SET   0x04
-#define MLXCPLD_I2C_FREQ_400KHZ_SET    0x0f
+#define MLXCPLD_I2C_FREQ_400KHZ_SET    0x0c
 #define MLXCPLD_I2C_FREQ_100KHZ_SET    0x42
 
 enum mlxcpld_i2c_frequency {
@@ -495,7 +495,7 @@ mlxcpld_i2c_set_frequency(struct mlxcpld_i2c_priv *priv,
                return err;
 
        /* Set frequency only if it is not 100KHz, which is default. */
-       switch ((data->reg & data->mask) >> data->bit) {
+       switch ((regval & data->mask) >> data->bit) {
        case MLXCPLD_I2C_FREQ_1000KHZ:
                freq = MLXCPLD_I2C_FREQ_1000KHZ_SET;
                break;
index 477480d..7d4b3eb 100644 (file)
@@ -41,6 +41,8 @@
 #define I2C_HANDSHAKE_RST              0x0020
 #define I2C_FIFO_ADDR_CLR              0x0001
 #define I2C_DELAY_LEN                  0x0002
+#define I2C_ST_START_CON               0x8001
+#define I2C_FS_START_CON               0x1800
 #define I2C_TIME_CLR_VALUE             0x0000
 #define I2C_TIME_DEFAULT_VALUE         0x0003
 #define I2C_WRRD_TRANAC_VALUE          0x0002
@@ -480,6 +482,7 @@ static void mtk_i2c_init_hw(struct mtk_i2c *i2c)
 {
        u16 control_reg;
        u16 intr_stat_reg;
+       u16 ext_conf_val;
 
        mtk_i2c_writew(i2c, I2C_CHN_CLR_FLAG, OFFSET_START);
        intr_stat_reg = mtk_i2c_readw(i2c, OFFSET_INTR_STAT);
@@ -518,8 +521,13 @@ static void mtk_i2c_init_hw(struct mtk_i2c *i2c)
        if (i2c->dev_comp->ltiming_adjust)
                mtk_i2c_writew(i2c, i2c->ltiming_reg, OFFSET_LTIMING);
 
+       if (i2c->speed_hz <= I2C_MAX_STANDARD_MODE_FREQ)
+               ext_conf_val = I2C_ST_START_CON;
+       else
+               ext_conf_val = I2C_FS_START_CON;
+
        if (i2c->dev_comp->timing_adjust) {
-               mtk_i2c_writew(i2c, i2c->ac_timing.ext, OFFSET_EXT_CONF);
+               ext_conf_val = i2c->ac_timing.ext;
                mtk_i2c_writew(i2c, i2c->ac_timing.inter_clk_div,
                               OFFSET_CLOCK_DIV);
                mtk_i2c_writew(i2c, I2C_SCL_MIS_COMP_VALUE,
@@ -544,6 +552,7 @@ static void mtk_i2c_init_hw(struct mtk_i2c *i2c)
                                       OFFSET_HS_STA_STO_AC_TIMING);
                }
        }
+       mtk_i2c_writew(i2c, ext_conf_val, OFFSET_EXT_CONF);
 
        /* If use i2c pin from PMIC mt6397 side, need set PATH_DIR first */
        if (i2c->have_pmic)
index aaeeacc..546cc93 100644 (file)
@@ -454,6 +454,7 @@ static int i2c_acpi_notify(struct notifier_block *nb, unsigned long value,
                        break;
 
                i2c_acpi_register_device(adapter, adev, &info);
+               put_device(&adapter->dev);
                break;
        case ACPI_RECONFIG_DEVICE_REMOVE:
                if (!acpi_device_enumerated(adev))
index 0019f1e..f41db9e 100644 (file)
@@ -738,7 +738,7 @@ static irqreturn_t fxls8962af_interrupt(int irq, void *p)
 
        if (reg & FXLS8962AF_INT_STATUS_SRC_BUF) {
                ret = fxls8962af_fifo_flush(indio_dev);
-               if (ret)
+               if (ret < 0)
                        return IRQ_NONE;
 
                return IRQ_HANDLED;
index ee8ed94..2121a81 100644 (file)
@@ -293,6 +293,7 @@ static const struct ad_sigma_delta_info ad7192_sigma_delta_info = {
        .has_registers = true,
        .addr_shift = 3,
        .read_mask = BIT(6),
+       .irq_flags = IRQF_TRIGGER_FALLING,
 };
 
 static const struct ad_sd_calib_data ad7192_calib_arr[8] = {
index 42bb952..b6e8c8a 100644 (file)
@@ -203,7 +203,7 @@ static const struct ad_sigma_delta_info ad7780_sigma_delta_info = {
        .set_mode = ad7780_set_mode,
        .postprocess_sample = ad7780_postprocess_sample,
        .has_registers = false,
-       .irq_flags = IRQF_TRIGGER_LOW,
+       .irq_flags = IRQF_TRIGGER_FALLING,
 };
 
 #define _AD7780_CHANNEL(_bits, _wordsize, _mask_all)           \
index ef3e2d3..0e7ab3f 100644 (file)
@@ -206,7 +206,7 @@ static const struct ad_sigma_delta_info ad7793_sigma_delta_info = {
        .has_registers = true,
        .addr_shift = 3,
        .read_mask = BIT(6),
-       .irq_flags = IRQF_TRIGGER_LOW,
+       .irq_flags = IRQF_TRIGGER_FALLING,
 };
 
 static const struct ad_sd_calib_data ad7793_calib_arr[6] = {
index 19efaa4..34ec0c2 100644 (file)
@@ -183,6 +183,7 @@ static int aspeed_adc_probe(struct platform_device *pdev)
 
        data = iio_priv(indio_dev);
        data->dev = &pdev->dev;
+       platform_set_drvdata(pdev, indio_dev);
 
        data->base = devm_platform_ioremap_resource(pdev, 0);
        if (IS_ERR(data->base))
index 655ab02..b753658 100644 (file)
@@ -103,7 +103,7 @@ MODULE_DEVICE_TABLE(of, max1027_adc_dt_ids);
                        .sign = 'u',                                    \
                        .realbits = depth,                              \
                        .storagebits = 16,                              \
-                       .shift = 2,                                     \
+                       .shift = (depth == 10) ? 2 : 0,                 \
                        .endianness = IIO_BE,                           \
                },                                                      \
        }
@@ -142,7 +142,6 @@ MODULE_DEVICE_TABLE(of, max1027_adc_dt_ids);
        MAX1027_V_CHAN(11, depth)
 
 #define MAX1X31_CHANNELS(depth)                        \
-       MAX1X27_CHANNELS(depth),                \
        MAX1X29_CHANNELS(depth),                \
        MAX1027_V_CHAN(12, depth),              \
        MAX1027_V_CHAN(13, depth),              \
index 79c1dd6..d4fccd5 100644 (file)
@@ -82,6 +82,10 @@ static const struct iio_chan_spec mt6577_auxadc_iio_channels[] = {
        MT6577_AUXADC_CHANNEL(15),
 };
 
+/* For Voltage calculation */
+#define VOLTAGE_FULL_RANGE  1500       /* VA voltage */
+#define AUXADC_PRECISE      4096       /* 12 bits */
+
 static int mt_auxadc_get_cali_data(int rawdata, bool enable_cali)
 {
        return rawdata;
@@ -191,6 +195,10 @@ static int mt6577_auxadc_read_raw(struct iio_dev *indio_dev,
                }
                if (adc_dev->dev_comp->sample_data_cali)
                        *val = mt_auxadc_get_cali_data(*val, true);
+
+               /* Convert adc raw data to voltage: 0 - 1500 mV */
+               *val = *val * VOLTAGE_FULL_RANGE / AUXADC_PRECISE;
+
                return IIO_VAL_INT;
 
        default:
index 9996d5e..32fbf57 100644 (file)
@@ -401,7 +401,7 @@ static int rzg2l_adc_hw_init(struct rzg2l_adc *adc)
 exit_hw_init:
        clk_disable_unprepare(adc->pclk);
 
-       return 0;
+       return ret;
 }
 
 static void rzg2l_adc_pm_runtime_disable(void *data)
@@ -570,8 +570,10 @@ static int __maybe_unused rzg2l_adc_pm_runtime_resume(struct device *dev)
                return ret;
 
        ret = clk_prepare_enable(adc->adclk);
-       if (ret)
+       if (ret) {
+               clk_disable_unprepare(adc->pclk);
                return ret;
+       }
 
        rzg2l_adc_pwr(adc, true);
 
index 3143f35..83c1ae0 100644 (file)
@@ -171,7 +171,13 @@ static int adc128_probe(struct spi_device *spi)
        mutex_init(&adc->lock);
 
        ret = iio_device_register(indio_dev);
+       if (ret)
+               goto err_disable_regulator;
 
+       return 0;
+
+err_disable_regulator:
+       regulator_disable(adc->reg);
        return ret;
 }
 
index 4864c38..769bd92 100644 (file)
@@ -137,7 +137,7 @@ static int ssp_print_mcu_debug(char *data_frame, int *data_index,
        if (length > received_len - *data_index || length <= 0) {
                ssp_dbg("[SSP]: MSG From MCU-invalid debug length(%d/%d)\n",
                        length, received_len);
-               return length ? length : -EPROTO;
+               return -EPROTO;
        }
 
        ssp_dbg("[SSP]: MSG From MCU - %s\n", &data_frame[*data_index]);
@@ -273,6 +273,8 @@ static int ssp_parse_dataframe(struct ssp_data *data, char *dataframe, int len)
        for (idx = 0; idx < len;) {
                switch (dataframe[idx++]) {
                case SSP_MSG2AP_INST_BYPASS_DATA:
+                       if (idx >= len)
+                               return -EPROTO;
                        sd = dataframe[idx++];
                        if (sd < 0 || sd >= SSP_SENSOR_MAX) {
                                dev_err(SSP_DEV,
@@ -282,10 +284,13 @@ static int ssp_parse_dataframe(struct ssp_data *data, char *dataframe, int len)
 
                        if (indio_devs[sd]) {
                                spd = iio_priv(indio_devs[sd]);
-                               if (spd->process_data)
+                               if (spd->process_data) {
+                                       if (idx >= len)
+                                               return -EPROTO;
                                        spd->process_data(indio_devs[sd],
                                                          &dataframe[idx],
                                                          data->timestamp);
+                               }
                        } else {
                                dev_err(SSP_DEV, "no client for frame\n");
                        }
@@ -293,6 +298,8 @@ static int ssp_parse_dataframe(struct ssp_data *data, char *dataframe, int len)
                        idx += ssp_offset_map[sd];
                        break;
                case SSP_MSG2AP_INST_DEBUG_DATA:
+                       if (idx >= len)
+                               return -EPROTO;
                        sd = ssp_print_mcu_debug(dataframe, &idx, len);
                        if (sd) {
                                dev_err(SSP_DEV,
index 2a5ba1b..546a4cf 100644 (file)
@@ -350,6 +350,7 @@ static int dac5571_probe(struct i2c_client *client,
                data->dac5571_pwrdwn = dac5571_pwrdwn_quad;
                break;
        default:
+               ret = -EINVAL;
                goto err;
        }
 
index eb48102..287fff3 100644 (file)
@@ -353,10 +353,11 @@ static int adis16475_set_freq(struct adis16475 *st, const u32 freq)
        if (dec > st->info->max_dec)
                dec = st->info->max_dec;
 
-       ret = adis_write_reg_16(&st->adis, ADIS16475_REG_DEC_RATE, dec);
+       ret = __adis_write_reg_16(&st->adis, ADIS16475_REG_DEC_RATE, dec);
        if (ret)
                goto error;
 
+       adis_dev_unlock(&st->adis);
        /*
         * If decimation is used, then gyro and accel data will have meaningful
         * bits on the LSB registers. This info is used on the trigger handler.
index a869a6e..ed12932 100644 (file)
@@ -144,6 +144,7 @@ struct adis16480_chip_info {
        unsigned int max_dec_rate;
        const unsigned int *filter_freqs;
        bool has_pps_clk_mode;
+       bool has_sleep_cnt;
        const struct adis_data adis_data;
 };
 
@@ -939,6 +940,7 @@ static const struct adis16480_chip_info adis16480_chip_info[] = {
                .temp_scale = 5650, /* 5.65 milli degree Celsius */
                .int_clk = 2460000,
                .max_dec_rate = 2048,
+               .has_sleep_cnt = true,
                .filter_freqs = adis16480_def_filter_freqs,
                .adis_data = ADIS16480_DATA(16375, &adis16485_timeouts, 0),
        },
@@ -952,6 +954,7 @@ static const struct adis16480_chip_info adis16480_chip_info[] = {
                .temp_scale = 5650, /* 5.65 milli degree Celsius */
                .int_clk = 2460000,
                .max_dec_rate = 2048,
+               .has_sleep_cnt = true,
                .filter_freqs = adis16480_def_filter_freqs,
                .adis_data = ADIS16480_DATA(16480, &adis16480_timeouts, 0),
        },
@@ -965,6 +968,7 @@ static const struct adis16480_chip_info adis16480_chip_info[] = {
                .temp_scale = 5650, /* 5.65 milli degree Celsius */
                .int_clk = 2460000,
                .max_dec_rate = 2048,
+               .has_sleep_cnt = true,
                .filter_freqs = adis16480_def_filter_freqs,
                .adis_data = ADIS16480_DATA(16485, &adis16485_timeouts, 0),
        },
@@ -978,6 +982,7 @@ static const struct adis16480_chip_info adis16480_chip_info[] = {
                .temp_scale = 5650, /* 5.65 milli degree Celsius */
                .int_clk = 2460000,
                .max_dec_rate = 2048,
+               .has_sleep_cnt = true,
                .filter_freqs = adis16480_def_filter_freqs,
                .adis_data = ADIS16480_DATA(16488, &adis16485_timeouts, 0),
        },
@@ -1425,9 +1430,12 @@ static int adis16480_probe(struct spi_device *spi)
        if (ret)
                return ret;
 
-       ret = devm_add_action_or_reset(&spi->dev, adis16480_stop, indio_dev);
-       if (ret)
-               return ret;
+       if (st->chip_info->has_sleep_cnt) {
+               ret = devm_add_action_or_reset(&spi->dev, adis16480_stop,
+                                              indio_dev);
+               if (ret)
+                       return ret;
+       }
 
        ret = adis16480_config_irq_pin(spi->dev.of_node, st);
        if (ret)
index 52963da..1880bd5 100644 (file)
@@ -276,6 +276,8 @@ static int opt3001_get_lux(struct opt3001 *opt, int *val, int *val2)
                ret = wait_event_timeout(opt->result_ready_queue,
                                opt->result_ready,
                                msecs_to_jiffies(OPT3001_RESULT_READY_LONG));
+               if (ret == 0)
+                       return -ETIMEDOUT;
        } else {
                /* Sleep for result ready time */
                timeout = (opt->int_time == OPT3001_INT_TIME_SHORT) ?
@@ -312,9 +314,7 @@ err:
                /* Disallow IRQ to access the device while lock is active */
                opt->ok_to_ignore_lock = false;
 
-       if (ret == 0)
-               return -ETIMEDOUT;
-       else if (ret < 0)
+       if (ret < 0)
                return ret;
 
        if (opt->use_irq) {
index f1099b4..467519a 100644 (file)
@@ -5,3 +5,4 @@
 
 # Keep in alphabetical order
 obj-$(CONFIG_IIO_TEST_FORMAT) += iio-test-format.o
+CFLAGS_iio-test-format.o += $(DISABLE_STRUCTLEAK_PLUGIN)
index 29de841..4c914f7 100644 (file)
@@ -334,6 +334,7 @@ static const struct xpad_device {
        { 0x24c6, 0x5b03, "Thrustmaster Ferrari 458 Racing Wheel", 0, XTYPE_XBOX360 },
        { 0x24c6, 0x5d04, "Razer Sabertooth", 0, XTYPE_XBOX360 },
        { 0x24c6, 0xfafe, "Rock Candy Gamepad for Xbox 360", 0, XTYPE_XBOX360 },
+       { 0x3285, 0x0607, "Nacon GC-100", 0, XTYPE_XBOX360 },
        { 0x3767, 0x0101, "Fanatec Speedster 3 Forceshock Wheel", 0, XTYPE_XBOX },
        { 0xffff, 0xffff, "Chinese-made Xbox Controller", 0, XTYPE_XBOX },
        { 0x0000, 0x0000, "Generic X-Box pad", 0, XTYPE_UNKNOWN }
@@ -451,6 +452,7 @@ static const struct usb_device_id xpad_table[] = {
        XPAD_XBOXONE_VENDOR(0x24c6),            /* PowerA Controllers */
        XPAD_XBOXONE_VENDOR(0x2e24),            /* Hyperkin Duke X-Box One pad */
        XPAD_XBOX360_VENDOR(0x2f24),            /* GameSir Controllers */
+       XPAD_XBOX360_VENDOR(0x3285),            /* Nacon GC-100 */
        { }
 };
 
index 2f5e3ab..6528676 100644 (file)
@@ -3,6 +3,7 @@
 // Driver for the IMX SNVS ON/OFF Power Key
 // Copyright (C) 2015 Freescale Semiconductor, Inc. All Rights Reserved.
 
+#include <linux/clk.h>
 #include <linux/device.h>
 #include <linux/err.h>
 #include <linux/init.h>
@@ -99,6 +100,11 @@ static irqreturn_t imx_snvs_pwrkey_interrupt(int irq, void *dev_id)
        return IRQ_HANDLED;
 }
 
+static void imx_snvs_pwrkey_disable_clk(void *data)
+{
+       clk_disable_unprepare(data);
+}
+
 static void imx_snvs_pwrkey_act(void *pdata)
 {
        struct pwrkey_drv_data *pd = pdata;
@@ -111,6 +117,7 @@ static int imx_snvs_pwrkey_probe(struct platform_device *pdev)
        struct pwrkey_drv_data *pdata;
        struct input_dev *input;
        struct device_node *np;
+       struct clk *clk;
        int error;
        u32 vid;
 
@@ -134,6 +141,28 @@ static int imx_snvs_pwrkey_probe(struct platform_device *pdev)
                dev_warn(&pdev->dev, "KEY_POWER without setting in dts\n");
        }
 
+       clk = devm_clk_get_optional(&pdev->dev, NULL);
+       if (IS_ERR(clk)) {
+               dev_err(&pdev->dev, "Failed to get snvs clock (%pe)\n", clk);
+               return PTR_ERR(clk);
+       }
+
+       error = clk_prepare_enable(clk);
+       if (error) {
+               dev_err(&pdev->dev, "Failed to enable snvs clock (%pe)\n",
+                       ERR_PTR(error));
+               return error;
+       }
+
+       error = devm_add_action_or_reset(&pdev->dev,
+                                        imx_snvs_pwrkey_disable_clk, clk);
+       if (error) {
+               dev_err(&pdev->dev,
+                       "Failed to register clock cleanup handler (%pe)\n",
+                       ERR_PTR(error));
+               return error;
+       }
+
        pdata->wakeup = of_property_read_bool(np, "wakeup-source");
 
        pdata->irq = platform_get_irq(pdev, 0);
index dd18cb9..4620e20 100644 (file)
@@ -80,27 +80,27 @@ void touchscreen_parse_properties(struct input_dev *input, bool multitouch,
 
        data_present = touchscreen_get_prop_u32(dev, "touchscreen-min-x",
                                                input_abs_get_min(input, axis_x),
-                                               &minimum) |
-                      touchscreen_get_prop_u32(dev, "touchscreen-size-x",
-                                               input_abs_get_max(input,
-                                                                 axis_x) + 1,
-                                               &maximum) |
-                      touchscreen_get_prop_u32(dev, "touchscreen-fuzz-x",
-                                               input_abs_get_fuzz(input, axis_x),
-                                               &fuzz);
+                                               &minimum);
+       data_present |= touchscreen_get_prop_u32(dev, "touchscreen-size-x",
+                                                input_abs_get_max(input,
+                                                                  axis_x) + 1,
+                                                &maximum);
+       data_present |= touchscreen_get_prop_u32(dev, "touchscreen-fuzz-x",
+                                                input_abs_get_fuzz(input, axis_x),
+                                                &fuzz);
        if (data_present)
                touchscreen_set_params(input, axis_x, minimum, maximum - 1, fuzz);
 
        data_present = touchscreen_get_prop_u32(dev, "touchscreen-min-y",
                                                input_abs_get_min(input, axis_y),
-                                               &minimum) |
-                      touchscreen_get_prop_u32(dev, "touchscreen-size-y",
-                                               input_abs_get_max(input,
-                                                                 axis_y) + 1,
-                                               &maximum) |
-                      touchscreen_get_prop_u32(dev, "touchscreen-fuzz-y",
-                                               input_abs_get_fuzz(input, axis_y),
-                                               &fuzz);
+                                               &minimum);
+       data_present |= touchscreen_get_prop_u32(dev, "touchscreen-size-y",
+                                                input_abs_get_max(input,
+                                                                  axis_y) + 1,
+                                                &maximum);
+       data_present |= touchscreen_get_prop_u32(dev, "touchscreen-fuzz-y",
+                                                input_abs_get_fuzz(input, axis_y),
+                                                &fuzz);
        if (data_present)
                touchscreen_set_params(input, axis_y, minimum, maximum - 1, fuzz);
 
@@ -108,11 +108,11 @@ void touchscreen_parse_properties(struct input_dev *input, bool multitouch,
        data_present = touchscreen_get_prop_u32(dev,
                                                "touchscreen-max-pressure",
                                                input_abs_get_max(input, axis),
-                                               &maximum) |
-                      touchscreen_get_prop_u32(dev,
-                                               "touchscreen-fuzz-pressure",
-                                               input_abs_get_fuzz(input, axis),
-                                               &fuzz);
+                                               &maximum);
+       data_present |= touchscreen_get_prop_u32(dev,
+                                                "touchscreen-fuzz-pressure",
+                                                input_abs_get_fuzz(input, axis),
+                                                &fuzz);
        if (data_present)
                touchscreen_set_params(input, axis, 0, maximum, fuzz);
 
index 744544a..6f754a8 100644 (file)
@@ -71,19 +71,22 @@ static int grts_cb(const void *data, void *private)
                unsigned int z2 = touch_info[st->ch_map[GRTS_CH_Z2]];
                unsigned int Rt;
 
-               Rt = z2;
-               Rt -= z1;
-               Rt *= st->x_plate_ohms;
-               Rt = DIV_ROUND_CLOSEST(Rt, 16);
-               Rt *= x;
-               Rt /= z1;
-               Rt = DIV_ROUND_CLOSEST(Rt, 256);
-               /*
-                * On increased pressure the resistance (Rt) is decreasing
-                * so, convert values to make it looks as real pressure.
-                */
-               if (Rt < GRTS_DEFAULT_PRESSURE_MAX)
-                       press = GRTS_DEFAULT_PRESSURE_MAX - Rt;
+               if (likely(x && z1)) {
+                       Rt = z2;
+                       Rt -= z1;
+                       Rt *= st->x_plate_ohms;
+                       Rt = DIV_ROUND_CLOSEST(Rt, 16);
+                       Rt *= x;
+                       Rt /= z1;
+                       Rt = DIV_ROUND_CLOSEST(Rt, 256);
+                       /*
+                        * On increased pressure the resistance (Rt) is
+                        * decreasing so, convert values to make it looks as
+                        * real pressure.
+                        */
+                       if (Rt < GRTS_DEFAULT_PRESSURE_MAX)
+                               press = GRTS_DEFAULT_PRESSURE_MAX - Rt;
+               }
        }
 
        if ((!x && !y) || (st->pressure && (press < st->pressure_min))) {
index 124c41a..3eb68fa 100644 (file)
@@ -308,7 +308,6 @@ config APPLE_DART
 config ARM_SMMU
        tristate "ARM Ltd. System MMU (SMMU) Support"
        depends on ARM64 || ARM || (COMPILE_TEST && !GENERIC_ATOMIC64)
-       depends on QCOM_SCM || !QCOM_SCM #if QCOM_SCM=m this can't be =y
        select IOMMU_API
        select IOMMU_IO_PGTABLE_LPAE
        select ARM_DMA_USE_IOMMU if ARM
@@ -356,6 +355,14 @@ config ARM_SMMU_DISABLE_BYPASS_BY_DEFAULT
          'arm-smmu.disable_bypass' will continue to override this
          config.
 
+config ARM_SMMU_QCOM
+       def_tristate y
+       depends on ARM_SMMU && ARCH_QCOM
+       select QCOM_SCM
+       help
+         When running on a Qualcomm platform that has the custom variant
+         of the ARM SMMU, this needs to be built into the SMMU driver.
+
 config ARM_SMMU_V3
        tristate "ARM Ltd. System MMU Version 3 (SMMUv3) Support"
        depends on ARM64
@@ -438,7 +445,7 @@ config QCOM_IOMMU
        # Note: iommu drivers cannot (yet?) be built as modules
        bool "Qualcomm IOMMU Support"
        depends on ARCH_QCOM || (COMPILE_TEST && !GENERIC_ATOMIC64)
-       depends on QCOM_SCM=y
+       select QCOM_SCM
        select IOMMU_API
        select IOMMU_IO_PGTABLE_LPAE
        select ARM_DMA_USE_IOMMU
index e240a7b..b0cc01a 100644 (file)
@@ -1,4 +1,5 @@
 # SPDX-License-Identifier: GPL-2.0
 obj-$(CONFIG_QCOM_IOMMU) += qcom_iommu.o
 obj-$(CONFIG_ARM_SMMU) += arm_smmu.o
-arm_smmu-objs += arm-smmu.o arm-smmu-impl.o arm-smmu-nvidia.o arm-smmu-qcom.o
+arm_smmu-objs += arm-smmu.o arm-smmu-impl.o arm-smmu-nvidia.o
+arm_smmu-$(CONFIG_ARM_SMMU_QCOM) += arm-smmu-qcom.o
index 9f465e1..2c25cce 100644 (file)
@@ -215,7 +215,8 @@ struct arm_smmu_device *arm_smmu_impl_init(struct arm_smmu_device *smmu)
            of_device_is_compatible(np, "nvidia,tegra186-smmu"))
                return nvidia_smmu_impl_init(smmu);
 
-       smmu = qcom_smmu_impl_init(smmu);
+       if (IS_ENABLED(CONFIG_ARM_SMMU_QCOM))
+               smmu = qcom_smmu_impl_init(smmu);
 
        if (of_device_is_compatible(np, "marvell,ap806-smmu-500"))
                smmu->impl = &mrvl_mmu500_impl;
index cb0afe8..7313454 100644 (file)
@@ -480,6 +480,11 @@ int detach_capi_ctr(struct capi_ctr *ctr)
 
        ctr_down(ctr, CAPI_CTR_DETACHED);
 
+       if (ctr->cnr < 1 || ctr->cnr - 1 >= CAPI_MAXCONTR) {
+               err = -EINVAL;
+               goto unlock_out;
+       }
+
        if (capi_controller[ctr->cnr - 1] != ctr) {
                err = -EINVAL;
                goto unlock_out;
index 2a1ddd4..a52f275 100644 (file)
@@ -949,8 +949,8 @@ nj_release(struct tiger_hw *card)
                nj_disable_hwirq(card);
                mode_tiger(&card->bc[0], ISDN_P_NONE);
                mode_tiger(&card->bc[1], ISDN_P_NONE);
-               card->isac.release(&card->isac);
                spin_unlock_irqrestore(&card->lock, flags);
+               card->isac.release(&card->isac);
                release_region(card->base, card->base_s);
                card->base_s = 0;
        }
index 84dbe08..edd22e4 100644 (file)
@@ -161,7 +161,7 @@ static const char *clone_device_name(struct clone *clone)
 
 static void __set_clone_mode(struct clone *clone, enum clone_metadata_mode new_mode)
 {
-       const char *descs[] = {
+       static const char * const descs[] = {
                "read-write",
                "read-only",
                "fail"
index 5b95eea..a896dea 100644 (file)
@@ -490,6 +490,14 @@ static blk_status_t dm_mq_queue_rq(struct blk_mq_hw_ctx *hctx,
        struct mapped_device *md = tio->md;
        struct dm_target *ti = md->immutable_target;
 
+       /*
+        * blk-mq's unquiesce may come from outside events, such as
+        * elevator switch, updating nr_requests or others, and request may
+        * come during suspend, so simply ask for blk-mq to requeue it.
+        */
+       if (unlikely(test_bit(DMF_BLOCK_IO_FOR_SUSPEND, &md->flags)))
+               return BLK_STS_RESOURCE;
+
        if (unlikely(!ti)) {
                int srcu_idx;
                struct dm_table *map = dm_get_live_table(md, &srcu_idx);
index 22a5ac8..88288c8 100644 (file)
@@ -475,6 +475,7 @@ static int verity_verify_io(struct dm_verity_io *io)
        struct bvec_iter start;
        unsigned b;
        struct crypto_wait wait;
+       struct bio *bio = dm_bio_from_per_bio_data(io, v->ti->per_io_data_size);
 
        for (b = 0; b < io->n_blocks; b++) {
                int r;
@@ -529,9 +530,17 @@ static int verity_verify_io(struct dm_verity_io *io)
                else if (verity_fec_decode(v, io, DM_VERITY_BLOCK_TYPE_DATA,
                                           cur_block, NULL, &start) == 0)
                        continue;
-               else if (verity_handle_err(v, DM_VERITY_BLOCK_TYPE_DATA,
-                                          cur_block))
-                       return -EIO;
+               else {
+                       if (bio->bi_status) {
+                               /*
+                                * Error correction failed; Just return error
+                                */
+                               return -EIO;
+                       }
+                       if (verity_handle_err(v, DM_VERITY_BLOCK_TYPE_DATA,
+                                             cur_block))
+                               return -EIO;
+               }
        }
 
        return 0;
index a011d09..76d9da4 100644 (file)
@@ -496,18 +496,17 @@ static void start_io_acct(struct dm_io *io)
                                    false, 0, &io->stats_aux);
 }
 
-static void end_io_acct(struct dm_io *io)
+static void end_io_acct(struct mapped_device *md, struct bio *bio,
+                       unsigned long start_time, struct dm_stats_aux *stats_aux)
 {
-       struct mapped_device *md = io->md;
-       struct bio *bio = io->orig_bio;
-       unsigned long duration = jiffies - io->start_time;
+       unsigned long duration = jiffies - start_time;
 
-       bio_end_io_acct(bio, io->start_time);
+       bio_end_io_acct(bio, start_time);
 
        if (unlikely(dm_stats_used(&md->stats)))
                dm_stats_account_io(&md->stats, bio_data_dir(bio),
                                    bio->bi_iter.bi_sector, bio_sectors(bio),
-                                   true, duration, &io->stats_aux);
+                                   true, duration, stats_aux);
 
        /* nudge anyone waiting on suspend queue */
        if (unlikely(wq_has_sleeper(&md->wait)))
@@ -790,6 +789,8 @@ void dm_io_dec_pending(struct dm_io *io, blk_status_t error)
        blk_status_t io_error;
        struct bio *bio;
        struct mapped_device *md = io->md;
+       unsigned long start_time = 0;
+       struct dm_stats_aux stats_aux;
 
        /* Push-back supersedes any I/O errors */
        if (unlikely(error)) {
@@ -821,8 +822,10 @@ void dm_io_dec_pending(struct dm_io *io, blk_status_t error)
                }
 
                io_error = io->status;
-               end_io_acct(io);
+               start_time = io->start_time;
+               stats_aux = io->stats_aux;
                free_io(md, io);
+               end_io_acct(md, bio, start_time, &stats_aux);
 
                if (io_error == BLK_STS_DM_REQUEUE)
                        return;
index 157c924..80321e0 100644 (file)
@@ -565,7 +565,7 @@ config VIDEO_QCOM_VENUS
        depends on VIDEO_DEV && VIDEO_V4L2 && QCOM_SMEM
        depends on (ARCH_QCOM && IOMMU_DMA) || COMPILE_TEST
        select QCOM_MDT_LOADER if ARCH_QCOM
-       select QCOM_SCM if ARCH_QCOM
+       select QCOM_SCM
        select VIDEOBUF2_DMA_CONTIG
        select V4L2_MEM2MEM_DEV
        help
index 85ba901..0f5a49f 100644 (file)
@@ -224,6 +224,7 @@ config HI6421V600_IRQ
        tristate "HiSilicon Hi6421v600 IRQ and powerkey"
        depends on OF
        depends on SPMI
+       depends on HAS_IOMEM
        select MFD_CORE
        select REGMAP_SPMI
        help
index e5a4ed3..a798fad 100644 (file)
@@ -47,7 +47,7 @@ static inline bool needs_unaligned_copy(const void *ptr)
 #ifdef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
        return false;
 #else
-       return ((ptr - NULL) & 3) != 0;
+       return ((uintptr_t)ptr & 3) != 0;
 #endif
 }
 
index 4d09b67..6323254 100644 (file)
@@ -366,6 +366,13 @@ static const struct of_device_id at25_of_match[] = {
 };
 MODULE_DEVICE_TABLE(of, at25_of_match);
 
+static const struct spi_device_id at25_spi_ids[] = {
+       { .name = "at25",},
+       { .name = "fm25",},
+       { }
+};
+MODULE_DEVICE_TABLE(spi, at25_spi_ids);
+
 static int at25_probe(struct spi_device *spi)
 {
        struct at25_data        *at25 = NULL;
@@ -491,6 +498,7 @@ static struct spi_driver at25_driver = {
                .dev_groups     = sernum_groups,
        },
        .probe          = at25_probe,
+       .id_table       = at25_spi_ids,
 };
 
 module_spi_driver(at25_driver);
index 29d8971..1f15399 100644 (file)
@@ -406,6 +406,23 @@ static const struct of_device_id eeprom_93xx46_of_table[] = {
 };
 MODULE_DEVICE_TABLE(of, eeprom_93xx46_of_table);
 
+static const struct spi_device_id eeprom_93xx46_spi_ids[] = {
+       { .name = "eeprom-93xx46",
+         .driver_data = (kernel_ulong_t)&at93c46_data, },
+       { .name = "at93c46",
+         .driver_data = (kernel_ulong_t)&at93c46_data, },
+       { .name = "at93c46d",
+         .driver_data = (kernel_ulong_t)&atmel_at93c46d_data, },
+       { .name = "at93c56",
+         .driver_data = (kernel_ulong_t)&at93c56_data, },
+       { .name = "at93c66",
+         .driver_data = (kernel_ulong_t)&at93c66_data, },
+       { .name = "93lc46b",
+         .driver_data = (kernel_ulong_t)&microchip_93lc46b_data, },
+       {}
+};
+MODULE_DEVICE_TABLE(spi, eeprom_93xx46_spi_ids);
+
 static int eeprom_93xx46_probe_dt(struct spi_device *spi)
 {
        const struct of_device_id *of_id =
@@ -555,6 +572,7 @@ static struct spi_driver eeprom_93xx46_driver = {
        },
        .probe          = eeprom_93xx46_probe,
        .remove         = eeprom_93xx46_remove,
+       .id_table       = eeprom_93xx46_spi_ids,
 };
 
 module_spi_driver(eeprom_93xx46_driver);
index beda610..ad6ced4 100644 (file)
@@ -814,10 +814,12 @@ static int fastrpc_get_args(u32 kernel, struct fastrpc_invoke_ctx *ctx)
                        rpra[i].pv = (u64) ctx->args[i].ptr;
                        pages[i].addr = ctx->maps[i]->phys;
 
+                       mmap_read_lock(current->mm);
                        vma = find_vma(current->mm, ctx->args[i].ptr);
                        if (vma)
                                pages[i].addr += ctx->args[i].ptr -
                                                 vma->vm_start;
+                       mmap_read_unlock(current->mm);
 
                        pg_start = (ctx->args[i].ptr & PAGE_MASK) >> PAGE_SHIFT;
                        pg_end = ((ctx->args[i].ptr + len - 1) & PAGE_MASK) >>
index 02f33bc..4c9c539 100644 (file)
@@ -539,6 +539,7 @@ static int gehc_achc_probe(struct spi_device *spi)
 
 static const struct spi_device_id gehc_achc_id[] = {
        { "ge,achc", 0 },
+       { "achc", 0 },
        { }
 };
 MODULE_DEVICE_TABLE(spi, gehc_achc_id);
index 91b5754..6dafff3 100644 (file)
@@ -2649,11 +2649,18 @@ put_ctx:
 free_seq_arr:
        kfree(cs_seq_arr);
 
-       /* update output args */
-       memset(args, 0, sizeof(*args));
        if (rc)
                return rc;
 
+       if (mcs_data.wait_status == -ERESTARTSYS) {
+               dev_err_ratelimited(hdev->dev,
+                               "user process got signal while waiting for Multi-CS\n");
+               return -EINTR;
+       }
+
+       /* update output args */
+       memset(args, 0, sizeof(*args));
+
        if (mcs_data.completion_bitmap) {
                args->out.status = HL_WAIT_CS_STATUS_COMPLETED;
                args->out.cs_completion_map = mcs_data.completion_bitmap;
@@ -2667,8 +2674,6 @@ free_seq_arr:
                /* update if some CS was gone */
                if (mcs_data.timestamp)
                        args->out.flags |= HL_WAIT_CS_STATUS_FLAG_GONE;
-       } else if (mcs_data.wait_status == -ERESTARTSYS) {
-               args->out.status = HL_WAIT_CS_STATUS_INTERRUPTED;
        } else {
                args->out.status = HL_WAIT_CS_STATUS_BUSY;
        }
@@ -2688,16 +2693,17 @@ static int hl_cs_wait_ioctl(struct hl_fpriv *hpriv, void *data)
        rc = _hl_cs_wait_ioctl(hdev, hpriv->ctx, args->in.timeout_us, seq,
                                &status, &timestamp);
 
+       if (rc == -ERESTARTSYS) {
+               dev_err_ratelimited(hdev->dev,
+                       "user process got signal while waiting for CS handle %llu\n",
+                       seq);
+               return -EINTR;
+       }
+
        memset(args, 0, sizeof(*args));
 
        if (rc) {
-               if (rc == -ERESTARTSYS) {
-                       dev_err_ratelimited(hdev->dev,
-                               "user process got signal while waiting for CS handle %llu\n",
-                               seq);
-                       args->out.status = HL_WAIT_CS_STATUS_INTERRUPTED;
-                       rc = -EINTR;
-               } else if (rc == -ETIMEDOUT) {
+               if (rc == -ETIMEDOUT) {
                        dev_err_ratelimited(hdev->dev,
                                "CS %llu has timed-out while user process is waiting for it\n",
                                seq);
@@ -2823,7 +2829,6 @@ wait_again:
                dev_err_ratelimited(hdev->dev,
                        "user process got signal while waiting for interrupt ID %d\n",
                        interrupt->interrupt_id);
-               *status = HL_WAIT_CS_STATUS_INTERRUPTED;
                rc = -EINTR;
        } else {
                *status = CS_WAIT_STATUS_BUSY;
@@ -2878,8 +2883,6 @@ static int hl_interrupt_wait_ioctl(struct hl_fpriv *hpriv, void *data)
                                args->in.interrupt_timeout_us, args->in.addr,
                                args->in.target, interrupt_offset, &status);
 
-       memset(args, 0, sizeof(*args));
-
        if (rc) {
                if (rc != -EINTR)
                        dev_err_ratelimited(hdev->dev,
@@ -2888,6 +2891,8 @@ static int hl_interrupt_wait_ioctl(struct hl_fpriv *hpriv, void *data)
                return rc;
        }
 
+       memset(args, 0, sizeof(*args));
+
        switch (status) {
        case CS_WAIT_STATUS_COMPLETED:
                args->out.status = HL_WAIT_CS_STATUS_COMPLETED;
index 99b5c1e..be41843 100644 (file)
@@ -1298,7 +1298,8 @@ int mei_hbm_dispatch(struct mei_device *dev, struct mei_msg_hdr *hdr)
 
                if (dev->dev_state != MEI_DEV_INIT_CLIENTS ||
                    dev->hbm_state != MEI_HBM_STARTING) {
-                       if (dev->dev_state == MEI_DEV_POWER_DOWN) {
+                       if (dev->dev_state == MEI_DEV_POWER_DOWN ||
+                           dev->dev_state == MEI_DEV_POWERING_DOWN) {
                                dev_dbg(dev->dev, "hbm: start: on shutdown, ignoring\n");
                                return 0;
                        }
@@ -1381,7 +1382,8 @@ int mei_hbm_dispatch(struct mei_device *dev, struct mei_msg_hdr *hdr)
 
                if (dev->dev_state != MEI_DEV_INIT_CLIENTS ||
                    dev->hbm_state != MEI_HBM_DR_SETUP) {
-                       if (dev->dev_state == MEI_DEV_POWER_DOWN) {
+                       if (dev->dev_state == MEI_DEV_POWER_DOWN ||
+                           dev->dev_state == MEI_DEV_POWERING_DOWN) {
                                dev_dbg(dev->dev, "hbm: dma setup response: on shutdown, ignoring\n");
                                return 0;
                        }
@@ -1448,7 +1450,8 @@ int mei_hbm_dispatch(struct mei_device *dev, struct mei_msg_hdr *hdr)
 
                if (dev->dev_state != MEI_DEV_INIT_CLIENTS ||
                    dev->hbm_state != MEI_HBM_CLIENT_PROPERTIES) {
-                       if (dev->dev_state == MEI_DEV_POWER_DOWN) {
+                       if (dev->dev_state == MEI_DEV_POWER_DOWN ||
+                           dev->dev_state == MEI_DEV_POWERING_DOWN) {
                                dev_dbg(dev->dev, "hbm: properties response: on shutdown, ignoring\n");
                                return 0;
                        }
@@ -1490,7 +1493,8 @@ int mei_hbm_dispatch(struct mei_device *dev, struct mei_msg_hdr *hdr)
 
                if (dev->dev_state != MEI_DEV_INIT_CLIENTS ||
                    dev->hbm_state != MEI_HBM_ENUM_CLIENTS) {
-                       if (dev->dev_state == MEI_DEV_POWER_DOWN) {
+                       if (dev->dev_state == MEI_DEV_POWER_DOWN ||
+                           dev->dev_state == MEI_DEV_POWERING_DOWN) {
                                dev_dbg(dev->dev, "hbm: enumeration response: on shutdown, ignoring\n");
                                return 0;
                        }
index cb34925..67bb6a2 100644 (file)
@@ -92,6 +92,7 @@
 #define MEI_DEV_ID_CDF        0x18D3  /* Cedar Fork */
 
 #define MEI_DEV_ID_ICP_LP     0x34E0  /* Ice Lake Point LP */
+#define MEI_DEV_ID_ICP_N      0x38E0  /* Ice Lake Point N */
 
 #define MEI_DEV_ID_JSP_N      0x4DE0  /* Jasper Lake Point N */
 
index c3393b3..3a45aaf 100644 (file)
@@ -96,6 +96,7 @@ static const struct pci_device_id mei_me_pci_tbl[] = {
        {MEI_PCI_DEVICE(MEI_DEV_ID_CMP_H_3, MEI_ME_PCH8_ITOUCH_CFG)},
 
        {MEI_PCI_DEVICE(MEI_DEV_ID_ICP_LP, MEI_ME_PCH12_CFG)},
+       {MEI_PCI_DEVICE(MEI_DEV_ID_ICP_N, MEI_ME_PCH12_CFG)},
 
        {MEI_PCI_DEVICE(MEI_DEV_ID_TGP_LP, MEI_ME_PCH15_CFG)},
        {MEI_PCI_DEVICE(MEI_DEV_ID_TGP_H, MEI_ME_PCH15_SPS_CFG)},
index 7131396..95b3511 100644 (file)
@@ -547,7 +547,7 @@ config MMC_SDHCI_MSM
        depends on MMC_SDHCI_PLTFM
        select MMC_SDHCI_IO_ACCESSORS
        select MMC_CQHCI
-       select QCOM_SCM if MMC_CRYPTO && ARCH_QCOM
+       select QCOM_SCM if MMC_CRYPTO
        help
          This selects the Secure Digital Host Controller Interface (SDHCI)
          support present in Qualcomm SOCs. The controller supports
index 3f28eb4..8f36536 100644 (file)
@@ -746,7 +746,7 @@ static void meson_mmc_desc_chain_transfer(struct mmc_host *mmc, u32 cmd_cfg)
        writel(start, host->regs + SD_EMMC_START);
 }
 
-/* local sg copy to buffer version with _to/fromio usage for dram_access_quirk */
+/* local sg copy for dram_access_quirk */
 static void meson_mmc_copy_buffer(struct meson_host *host, struct mmc_data *data,
                                  size_t buflen, bool to_buffer)
 {
@@ -764,21 +764,27 @@ static void meson_mmc_copy_buffer(struct meson_host *host, struct mmc_data *data
        sg_miter_start(&miter, sgl, nents, sg_flags);
 
        while ((offset < buflen) && sg_miter_next(&miter)) {
-               unsigned int len;
+               unsigned int buf_offset = 0;
+               unsigned int len, left;
+               u32 *buf = miter.addr;
 
                len = min(miter.length, buflen - offset);
+               left = len;
 
-               /* When dram_access_quirk, the bounce buffer is a iomem mapping */
-               if (host->dram_access_quirk) {
-                       if (to_buffer)
-                               memcpy_toio(host->bounce_iomem_buf + offset, miter.addr, len);
-                       else
-                               memcpy_fromio(miter.addr, host->bounce_iomem_buf + offset, len);
+               if (to_buffer) {
+                       do {
+                               writel(*buf++, host->bounce_iomem_buf + offset + buf_offset);
+
+                               buf_offset += 4;
+                               left -= 4;
+                       } while (left);
                } else {
-                       if (to_buffer)
-                               memcpy(host->bounce_buf + offset, miter.addr, len);
-                       else
-                               memcpy(miter.addr, host->bounce_buf + offset, len);
+                       do {
+                               *buf++ = readl(host->bounce_iomem_buf + offset + buf_offset);
+
+                               buf_offset += 4;
+                               left -= 4;
+                       } while (left);
                }
 
                offset += len;
@@ -830,7 +836,11 @@ static void meson_mmc_start_cmd(struct mmc_host *mmc, struct mmc_command *cmd)
                if (data->flags & MMC_DATA_WRITE) {
                        cmd_cfg |= CMD_CFG_DATA_WR;
                        WARN_ON(xfer_bytes > host->bounce_buf_size);
-                       meson_mmc_copy_buffer(host, data, xfer_bytes, true);
+                       if (host->dram_access_quirk)
+                               meson_mmc_copy_buffer(host, data, xfer_bytes, true);
+                       else
+                               sg_copy_to_buffer(data->sg, data->sg_len,
+                                                 host->bounce_buf, xfer_bytes);
                        dma_wmb();
                }
 
@@ -849,12 +859,43 @@ static void meson_mmc_start_cmd(struct mmc_host *mmc, struct mmc_command *cmd)
        writel(cmd->arg, host->regs + SD_EMMC_CMD_ARG);
 }
 
+static int meson_mmc_validate_dram_access(struct mmc_host *mmc, struct mmc_data *data)
+{
+       struct scatterlist *sg;
+       int i;
+
+       /* Reject request if any element offset or size is not 32bit aligned */
+       for_each_sg(data->sg, sg, data->sg_len, i) {
+               if (!IS_ALIGNED(sg->offset, sizeof(u32)) ||
+                   !IS_ALIGNED(sg->length, sizeof(u32))) {
+                       dev_err(mmc_dev(mmc), "unaligned sg offset %u len %u\n",
+                               data->sg->offset, data->sg->length);
+                       return -EINVAL;
+               }
+       }
+
+       return 0;
+}
+
 static void meson_mmc_request(struct mmc_host *mmc, struct mmc_request *mrq)
 {
        struct meson_host *host = mmc_priv(mmc);
        bool needs_pre_post_req = mrq->data &&
                        !(mrq->data->host_cookie & SD_EMMC_PRE_REQ_DONE);
 
+       /*
+        * The memory at the end of the controller used as bounce buffer for
+        * the dram_access_quirk only accepts 32bit read/write access,
+        * check the aligment and length of the data before starting the request.
+        */
+       if (host->dram_access_quirk && mrq->data) {
+               mrq->cmd->error = meson_mmc_validate_dram_access(mmc, mrq->data);
+               if (mrq->cmd->error) {
+                       mmc_request_done(mmc, mrq);
+                       return;
+               }
+       }
+
        if (needs_pre_post_req) {
                meson_mmc_get_transfer_mode(mmc, mrq);
                if (!meson_mmc_desc_chain_mode(mrq->data))
@@ -999,7 +1040,11 @@ static irqreturn_t meson_mmc_irq_thread(int irq, void *dev_id)
        if (meson_mmc_bounce_buf_read(data)) {
                xfer_bytes = data->blksz * data->blocks;
                WARN_ON(xfer_bytes > host->bounce_buf_size);
-               meson_mmc_copy_buffer(host, data, xfer_bytes, false);
+               if (host->dram_access_quirk)
+                       meson_mmc_copy_buffer(host, data, xfer_bytes, false);
+               else
+                       sg_copy_from_buffer(data->sg, data->sg_len,
+                                           host->bounce_buf, xfer_bytes);
        }
 
        next_cmd = meson_mmc_get_next_command(cmd);
index 5564d7b..d1a1c54 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/delay.h>
 #include <linux/err.h>
 #include <linux/io.h>
+#include <linux/iopoll.h>
 #include <linux/kernel.h>
 #include <linux/mmc/host.h>
 #include <linux/mmc/slot-gpio.h>
@@ -61,7 +62,6 @@ static void sdhci_at91_set_force_card_detect(struct sdhci_host *host)
 static void sdhci_at91_set_clock(struct sdhci_host *host, unsigned int clock)
 {
        u16 clk;
-       unsigned long timeout;
 
        host->mmc->actual_clock = 0;
 
@@ -86,16 +86,11 @@ static void sdhci_at91_set_clock(struct sdhci_host *host, unsigned int clock)
        sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
 
        /* Wait max 20 ms */
-       timeout = 20;
-       while (!((clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL))
-               & SDHCI_CLOCK_INT_STABLE)) {
-               if (timeout == 0) {
-                       pr_err("%s: Internal clock never stabilised.\n",
-                              mmc_hostname(host->mmc));
-                       return;
-               }
-               timeout--;
-               mdelay(1);
+       if (read_poll_timeout(sdhci_readw, clk, (clk & SDHCI_CLOCK_INT_STABLE),
+                             1000, 20000, false, host, SDHCI_CLOCK_CONTROL)) {
+               pr_err("%s: Internal clock never stabilised.\n",
+                      mmc_hostname(host->mmc));
+               return;
        }
 
        clk |= SDHCI_CLOCK_CARD_EN;
@@ -114,6 +109,7 @@ static void sdhci_at91_reset(struct sdhci_host *host, u8 mask)
 {
        struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
        struct sdhci_at91_priv *priv = sdhci_pltfm_priv(pltfm_host);
+       unsigned int tmp;
 
        sdhci_reset(host, mask);
 
@@ -126,6 +122,10 @@ static void sdhci_at91_reset(struct sdhci_host *host, u8 mask)
 
                sdhci_writel(host, calcr | SDMMC_CALCR_ALWYSON | SDMMC_CALCR_EN,
                             SDMMC_CALCR);
+
+               if (read_poll_timeout(sdhci_readl, tmp, !(tmp & SDMMC_CALCR_EN),
+                                     10, 20000, false, host, SDMMC_CALCR))
+                       dev_err(mmc_dev(host->mmc), "Failed to calibrate\n");
        }
 }
 
index ef0bade..04e6f7b 100644 (file)
@@ -1676,13 +1676,17 @@ qcom_nandc_read_cw_raw(struct mtd_info *mtd, struct nand_chip *chip,
        struct nand_ecc_ctrl *ecc = &chip->ecc;
        int data_size1, data_size2, oob_size1, oob_size2;
        int ret, reg_off = FLASH_BUF_ACC, read_loc = 0;
+       int raw_cw = cw;
 
        nand_read_page_op(chip, page, 0, NULL, 0);
        host->use_ecc = false;
 
+       if (nandc->props->qpic_v2)
+               raw_cw = ecc->steps - 1;
+
        clear_bam_transaction(nandc);
        set_address(host, host->cw_size * cw, page);
-       update_rw_regs(host, 1, true, cw);
+       update_rw_regs(host, 1, true, raw_cw);
        config_nand_page_read(chip);
 
        data_size1 = mtd->writesize - host->cw_size * (ecc->steps - 1);
@@ -1711,7 +1715,7 @@ qcom_nandc_read_cw_raw(struct mtd_info *mtd, struct nand_chip *chip,
                nandc_set_read_loc(chip, cw, 3, read_loc, oob_size2, 1);
        }
 
-       config_nand_cw_read(chip, false, cw);
+       config_nand_cw_read(chip, false, raw_cw);
 
        read_data_dma(nandc, reg_off, data_buf, data_size1, 0);
        reg_off += data_size1;
index 1542bfb..7c2968a 100644 (file)
@@ -449,8 +449,10 @@ EXPORT_SYMBOL(ksz_switch_register);
 void ksz_switch_remove(struct ksz_device *dev)
 {
        /* timer started */
-       if (dev->mib_read_interval)
+       if (dev->mib_read_interval) {
+               dev->mib_read_interval = 0;
                cancel_delayed_work_sync(&dev->mib_read);
+       }
 
        dev->dev_ops->exit(dev);
        dsa_unregister_switch(dev->ds);
index 03744d1..8dadcae 100644 (file)
@@ -12,6 +12,7 @@
 
 #include <linux/bitfield.h>
 #include <linux/delay.h>
+#include <linux/dsa/mv88e6xxx.h>
 #include <linux/etherdevice.h>
 #include <linux/ethtool.h>
 #include <linux/if_bridge.h>
@@ -749,7 +750,11 @@ static void mv88e6xxx_mac_link_down(struct dsa_switch *ds, int port,
        ops = chip->info->ops;
 
        mv88e6xxx_reg_lock(chip);
-       if ((!mv88e6xxx_port_ppu_updates(chip, port) ||
+       /* Internal PHYs propagate their configuration directly to the MAC.
+        * External PHYs depend on whether the PPU is enabled for this port.
+        */
+       if (((!mv88e6xxx_phy_is_internal(ds, port) &&
+             !mv88e6xxx_port_ppu_updates(chip, port)) ||
             mode == MLO_AN_FIXED) && ops->port_sync_link)
                err = ops->port_sync_link(chip, port, mode, false);
        mv88e6xxx_reg_unlock(chip);
@@ -772,7 +777,12 @@ static void mv88e6xxx_mac_link_up(struct dsa_switch *ds, int port,
        ops = chip->info->ops;
 
        mv88e6xxx_reg_lock(chip);
-       if (!mv88e6xxx_port_ppu_updates(chip, port) || mode == MLO_AN_FIXED) {
+       /* Internal PHYs propagate their configuration directly to the MAC.
+        * External PHYs depend on whether the PPU is enabled for this port.
+        */
+       if ((!mv88e6xxx_phy_is_internal(ds, port) &&
+            !mv88e6xxx_port_ppu_updates(chip, port)) ||
+           mode == MLO_AN_FIXED) {
                /* FIXME: for an automedia port, should we force the link
                 * down here - what if the link comes up due to "other" media
                 * while we're bringing the port up, how is the exclusivity
@@ -1677,6 +1687,30 @@ static int mv88e6xxx_port_check_hw_vlan(struct dsa_switch *ds, int port,
        return 0;
 }
 
+static int mv88e6xxx_port_commit_pvid(struct mv88e6xxx_chip *chip, int port)
+{
+       struct dsa_port *dp = dsa_to_port(chip->ds, port);
+       struct mv88e6xxx_port *p = &chip->ports[port];
+       u16 pvid = MV88E6XXX_VID_STANDALONE;
+       bool drop_untagged = false;
+       int err;
+
+       if (dp->bridge_dev) {
+               if (br_vlan_enabled(dp->bridge_dev)) {
+                       pvid = p->bridge_pvid.vid;
+                       drop_untagged = !p->bridge_pvid.valid;
+               } else {
+                       pvid = MV88E6XXX_VID_BRIDGED;
+               }
+       }
+
+       err = mv88e6xxx_port_set_pvid(chip, port, pvid);
+       if (err)
+               return err;
+
+       return mv88e6xxx_port_drop_untagged(chip, port, drop_untagged);
+}
+
 static int mv88e6xxx_port_vlan_filtering(struct dsa_switch *ds, int port,
                                         bool vlan_filtering,
                                         struct netlink_ext_ack *extack)
@@ -1690,7 +1724,16 @@ static int mv88e6xxx_port_vlan_filtering(struct dsa_switch *ds, int port,
                return -EOPNOTSUPP;
 
        mv88e6xxx_reg_lock(chip);
+
        err = mv88e6xxx_port_set_8021q_mode(chip, port, mode);
+       if (err)
+               goto unlock;
+
+       err = mv88e6xxx_port_commit_pvid(chip, port);
+       if (err)
+               goto unlock;
+
+unlock:
        mv88e6xxx_reg_unlock(chip);
 
        return err;
@@ -1725,11 +1768,15 @@ static int mv88e6xxx_port_db_load_purge(struct mv88e6xxx_chip *chip, int port,
        u16 fid;
        int err;
 
-       /* Null VLAN ID corresponds to the port private database */
+       /* Ports have two private address databases: one for when the port is
+        * standalone and one for when the port is under a bridge and the
+        * 802.1Q mode is disabled. When the port is standalone, DSA wants its
+        * address database to remain 100% empty, so we never load an ATU entry
+        * into a standalone port's database. Therefore, translate the null
+        * VLAN ID into the port's database used for VLAN-unaware bridging.
+        */
        if (vid == 0) {
-               err = mv88e6xxx_port_get_fid(chip, port, &fid);
-               if (err)
-                       return err;
+               fid = MV88E6XXX_FID_BRIDGED;
        } else {
                err = mv88e6xxx_vtu_get(chip, vid, &vlan);
                if (err)
@@ -2123,6 +2170,7 @@ static int mv88e6xxx_port_vlan_add(struct dsa_switch *ds, int port,
        struct mv88e6xxx_chip *chip = ds->priv;
        bool untagged = vlan->flags & BRIDGE_VLAN_INFO_UNTAGGED;
        bool pvid = vlan->flags & BRIDGE_VLAN_INFO_PVID;
+       struct mv88e6xxx_port *p = &chip->ports[port];
        bool warn;
        u8 member;
        int err;
@@ -2156,13 +2204,21 @@ static int mv88e6xxx_port_vlan_add(struct dsa_switch *ds, int port,
        }
 
        if (pvid) {
-               err = mv88e6xxx_port_set_pvid(chip, port, vlan->vid);
-               if (err) {
-                       dev_err(ds->dev, "p%d: failed to set PVID %d\n",
-                               port, vlan->vid);
+               p->bridge_pvid.vid = vlan->vid;
+               p->bridge_pvid.valid = true;
+
+               err = mv88e6xxx_port_commit_pvid(chip, port);
+               if (err)
+                       goto out;
+       } else if (vlan->vid && p->bridge_pvid.vid == vlan->vid) {
+               /* The old pvid was reinstalled as a non-pvid VLAN */
+               p->bridge_pvid.valid = false;
+
+               err = mv88e6xxx_port_commit_pvid(chip, port);
+               if (err)
                        goto out;
-               }
        }
+
 out:
        mv88e6xxx_reg_unlock(chip);
 
@@ -2212,6 +2268,7 @@ static int mv88e6xxx_port_vlan_del(struct dsa_switch *ds, int port,
                                   const struct switchdev_obj_port_vlan *vlan)
 {
        struct mv88e6xxx_chip *chip = ds->priv;
+       struct mv88e6xxx_port *p = &chip->ports[port];
        int err = 0;
        u16 pvid;
 
@@ -2229,7 +2286,9 @@ static int mv88e6xxx_port_vlan_del(struct dsa_switch *ds, int port,
                goto unlock;
 
        if (vlan->vid == pvid) {
-               err = mv88e6xxx_port_set_pvid(chip, port, 0);
+               p->bridge_pvid.valid = false;
+
+               err = mv88e6xxx_port_commit_pvid(chip, port);
                if (err)
                        goto unlock;
        }
@@ -2393,7 +2452,16 @@ static int mv88e6xxx_port_bridge_join(struct dsa_switch *ds, int port,
        int err;
 
        mv88e6xxx_reg_lock(chip);
+
        err = mv88e6xxx_bridge_map(chip, br);
+       if (err)
+               goto unlock;
+
+       err = mv88e6xxx_port_commit_pvid(chip, port);
+       if (err)
+               goto unlock;
+
+unlock:
        mv88e6xxx_reg_unlock(chip);
 
        return err;
@@ -2403,11 +2471,20 @@ static void mv88e6xxx_port_bridge_leave(struct dsa_switch *ds, int port,
                                        struct net_device *br)
 {
        struct mv88e6xxx_chip *chip = ds->priv;
+       int err;
 
        mv88e6xxx_reg_lock(chip);
+
        if (mv88e6xxx_bridge_map(chip, br) ||
            mv88e6xxx_port_vlan_map(chip, port))
                dev_err(ds->dev, "failed to remap in-chip Port VLAN\n");
+
+       err = mv88e6xxx_port_commit_pvid(chip, port);
+       if (err)
+               dev_err(ds->dev,
+                       "port %d failed to restore standalone pvid: %pe\n",
+                       port, ERR_PTR(err));
+
        mv88e6xxx_reg_unlock(chip);
 }
 
@@ -2853,6 +2930,20 @@ static int mv88e6xxx_setup_port(struct mv88e6xxx_chip *chip, int port)
        if (err)
                return err;
 
+       /* Associate MV88E6XXX_VID_BRIDGED with MV88E6XXX_FID_BRIDGED in the
+        * ATU by virtue of the fact that mv88e6xxx_atu_new() will pick it as
+        * the first free FID after MV88E6XXX_FID_STANDALONE. This will be used
+        * as the private PVID on ports under a VLAN-unaware bridge.
+        * Shared (DSA and CPU) ports must also be members of it, to translate
+        * the VID from the DSA tag into MV88E6XXX_FID_BRIDGED, instead of
+        * relying on their port default FID.
+        */
+       err = mv88e6xxx_port_vlan_join(chip, port, MV88E6XXX_VID_BRIDGED,
+                                      MV88E6XXX_G1_VTU_DATA_MEMBER_TAG_UNTAGGED,
+                                      false);
+       if (err)
+               return err;
+
        if (chip->info->ops->port_set_jumbo_size) {
                err = chip->info->ops->port_set_jumbo_size(chip, port, 10218);
                if (err)
@@ -2925,7 +3016,7 @@ static int mv88e6xxx_setup_port(struct mv88e6xxx_chip *chip, int port)
         * database, and allow bidirectional communication between the
         * CPU and DSA port(s), and the other ports.
         */
-       err = mv88e6xxx_port_set_fid(chip, port, 0);
+       err = mv88e6xxx_port_set_fid(chip, port, MV88E6XXX_FID_STANDALONE);
        if (err)
                return err;
 
@@ -3115,6 +3206,10 @@ static int mv88e6xxx_setup(struct dsa_switch *ds)
                }
        }
 
+       err = mv88e6xxx_vtu_setup(chip);
+       if (err)
+               goto unlock;
+
        /* Setup Switch Port Registers */
        for (i = 0; i < mv88e6xxx_num_ports(chip); i++) {
                if (dsa_is_unused_port(ds, i))
@@ -3144,10 +3239,6 @@ static int mv88e6xxx_setup(struct dsa_switch *ds)
        if (err)
                goto unlock;
 
-       err = mv88e6xxx_vtu_setup(chip);
-       if (err)
-               goto unlock;
-
        err = mv88e6xxx_pvt_setup(chip);
        if (err)
                goto unlock;
index 59f316c..8271b8a 100644 (file)
@@ -21,6 +21,9 @@
 #define EDSA_HLEN              8
 #define MV88E6XXX_N_FID                4096
 
+#define MV88E6XXX_FID_STANDALONE       0
+#define MV88E6XXX_FID_BRIDGED          1
+
 /* PVT limits for 4-bit port and 5-bit switch */
 #define MV88E6XXX_MAX_PVT_SWITCHES     32
 #define MV88E6XXX_MAX_PVT_PORTS                16
@@ -246,9 +249,15 @@ struct mv88e6xxx_policy {
        u16 vid;
 };
 
+struct mv88e6xxx_vlan {
+       u16     vid;
+       bool    valid;
+};
+
 struct mv88e6xxx_port {
        struct mv88e6xxx_chip *chip;
        int port;
+       struct mv88e6xxx_vlan bridge_pvid;
        u64 serdes_stats[2];
        u64 atu_member_violation;
        u64 atu_miss_violation;
index 451028c..d9817b2 100644 (file)
@@ -1257,6 +1257,27 @@ int mv88e6xxx_port_set_8021q_mode(struct mv88e6xxx_chip *chip, int port,
        return 0;
 }
 
+int mv88e6xxx_port_drop_untagged(struct mv88e6xxx_chip *chip, int port,
+                                bool drop_untagged)
+{
+       u16 old, new;
+       int err;
+
+       err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL2, &old);
+       if (err)
+               return err;
+
+       if (drop_untagged)
+               new = old | MV88E6XXX_PORT_CTL2_DISCARD_UNTAGGED;
+       else
+               new = old & ~MV88E6XXX_PORT_CTL2_DISCARD_UNTAGGED;
+
+       if (new == old)
+               return 0;
+
+       return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL2, new);
+}
+
 int mv88e6xxx_port_set_map_da(struct mv88e6xxx_chip *chip, int port)
 {
        u16 reg;
index b10e5ae..03382b6 100644 (file)
@@ -423,6 +423,8 @@ int mv88e6393x_port_set_cmode(struct mv88e6xxx_chip *chip, int port,
                              phy_interface_t mode);
 int mv88e6185_port_get_cmode(struct mv88e6xxx_chip *chip, int port, u8 *cmode);
 int mv88e6352_port_get_cmode(struct mv88e6xxx_chip *chip, int port, u8 *cmode);
+int mv88e6xxx_port_drop_untagged(struct mv88e6xxx_chip *chip, int port,
+                                bool drop_untagged);
 int mv88e6xxx_port_set_map_da(struct mv88e6xxx_chip *chip, int port);
 int mv88e6095_port_set_upstream_port(struct mv88e6xxx_chip *chip, int port,
                                     int upstream_port);
index a3a9636..341236d 100644 (file)
@@ -266,12 +266,12 @@ static void felix_8021q_cpu_port_deinit(struct ocelot *ocelot, int port)
  */
 static int felix_setup_mmio_filtering(struct felix *felix)
 {
-       unsigned long user_ports = 0, cpu_ports = 0;
+       unsigned long user_ports = dsa_user_ports(felix->ds);
        struct ocelot_vcap_filter *redirect_rule;
        struct ocelot_vcap_filter *tagging_rule;
        struct ocelot *ocelot = &felix->ocelot;
        struct dsa_switch *ds = felix->ds;
-       int port, ret;
+       int cpu = -1, port, ret;
 
        tagging_rule = kzalloc(sizeof(struct ocelot_vcap_filter), GFP_KERNEL);
        if (!tagging_rule)
@@ -284,12 +284,15 @@ static int felix_setup_mmio_filtering(struct felix *felix)
        }
 
        for (port = 0; port < ocelot->num_phys_ports; port++) {
-               if (dsa_is_user_port(ds, port))
-                       user_ports |= BIT(port);
-               if (dsa_is_cpu_port(ds, port))
-                       cpu_ports |= BIT(port);
+               if (dsa_is_cpu_port(ds, port)) {
+                       cpu = port;
+                       break;
+               }
        }
 
+       if (cpu < 0)
+               return -EINVAL;
+
        tagging_rule->key_type = OCELOT_VCAP_KEY_ETYPE;
        *(__be16 *)tagging_rule->key.etype.etype.value = htons(ETH_P_1588);
        *(__be16 *)tagging_rule->key.etype.etype.mask = htons(0xffff);
@@ -325,7 +328,7 @@ static int felix_setup_mmio_filtering(struct felix *felix)
                 * the CPU port module
                 */
                redirect_rule->action.mask_mode = OCELOT_MASK_MODE_REDIRECT;
-               redirect_rule->action.port_mask = cpu_ports;
+               redirect_rule->action.port_mask = BIT(cpu);
        } else {
                /* Trap PTP packets only to the CPU port module (which is
                 * redirected to the NPI port)
@@ -1074,6 +1077,101 @@ static int felix_init_structs(struct felix *felix, int num_phys_ports)
        return 0;
 }
 
+static void ocelot_port_purge_txtstamp_skb(struct ocelot *ocelot, int port,
+                                          struct sk_buff *skb)
+{
+       struct ocelot_port *ocelot_port = ocelot->ports[port];
+       struct sk_buff *clone = OCELOT_SKB_CB(skb)->clone;
+       struct sk_buff *skb_match = NULL, *skb_tmp;
+       unsigned long flags;
+
+       if (!clone)
+               return;
+
+       spin_lock_irqsave(&ocelot_port->tx_skbs.lock, flags);
+
+       skb_queue_walk_safe(&ocelot_port->tx_skbs, skb, skb_tmp) {
+               if (skb != clone)
+                       continue;
+               __skb_unlink(skb, &ocelot_port->tx_skbs);
+               skb_match = skb;
+               break;
+       }
+
+       spin_unlock_irqrestore(&ocelot_port->tx_skbs.lock, flags);
+
+       WARN_ONCE(!skb_match,
+                 "Could not find skb clone in TX timestamping list\n");
+}
+
+#define work_to_xmit_work(w) \
+               container_of((w), struct felix_deferred_xmit_work, work)
+
+static void felix_port_deferred_xmit(struct kthread_work *work)
+{
+       struct felix_deferred_xmit_work *xmit_work = work_to_xmit_work(work);
+       struct dsa_switch *ds = xmit_work->dp->ds;
+       struct sk_buff *skb = xmit_work->skb;
+       u32 rew_op = ocelot_ptp_rew_op(skb);
+       struct ocelot *ocelot = ds->priv;
+       int port = xmit_work->dp->index;
+       int retries = 10;
+
+       do {
+               if (ocelot_can_inject(ocelot, 0))
+                       break;
+
+               cpu_relax();
+       } while (--retries);
+
+       if (!retries) {
+               dev_err(ocelot->dev, "port %d failed to inject skb\n",
+                       port);
+               ocelot_port_purge_txtstamp_skb(ocelot, port, skb);
+               kfree_skb(skb);
+               return;
+       }
+
+       ocelot_port_inject_frame(ocelot, port, 0, rew_op, skb);
+
+       consume_skb(skb);
+       kfree(xmit_work);
+}
+
+static int felix_port_setup_tagger_data(struct dsa_switch *ds, int port)
+{
+       struct dsa_port *dp = dsa_to_port(ds, port);
+       struct ocelot *ocelot = ds->priv;
+       struct felix *felix = ocelot_to_felix(ocelot);
+       struct felix_port *felix_port;
+
+       if (!dsa_port_is_user(dp))
+               return 0;
+
+       felix_port = kzalloc(sizeof(*felix_port), GFP_KERNEL);
+       if (!felix_port)
+               return -ENOMEM;
+
+       felix_port->xmit_worker = felix->xmit_worker;
+       felix_port->xmit_work_fn = felix_port_deferred_xmit;
+
+       dp->priv = felix_port;
+
+       return 0;
+}
+
+static void felix_port_teardown_tagger_data(struct dsa_switch *ds, int port)
+{
+       struct dsa_port *dp = dsa_to_port(ds, port);
+       struct felix_port *felix_port = dp->priv;
+
+       if (!felix_port)
+               return;
+
+       dp->priv = NULL;
+       kfree(felix_port);
+}
+
 /* Hardware initialization done here so that we can allocate structures with
  * devm without fear of dsa_register_switch returning -EPROBE_DEFER and causing
  * us to allocate structures twice (leak memory) and map PCI memory twice
@@ -1102,6 +1200,12 @@ static int felix_setup(struct dsa_switch *ds)
                }
        }
 
+       felix->xmit_worker = kthread_create_worker(0, "felix_xmit");
+       if (IS_ERR(felix->xmit_worker)) {
+               err = PTR_ERR(felix->xmit_worker);
+               goto out_deinit_timestamp;
+       }
+
        for (port = 0; port < ds->num_ports; port++) {
                if (dsa_is_unused_port(ds, port))
                        continue;
@@ -1112,6 +1216,14 @@ static int felix_setup(struct dsa_switch *ds)
                 * bits of vlan tag.
                 */
                felix_port_qos_map_init(ocelot, port);
+
+               err = felix_port_setup_tagger_data(ds, port);
+               if (err) {
+                       dev_err(ds->dev,
+                               "port %d failed to set up tagger data: %pe\n",
+                               port, ERR_PTR(err));
+                       goto out_deinit_ports;
+               }
        }
 
        err = ocelot_devlink_sb_register(ocelot);
@@ -1126,6 +1238,7 @@ static int felix_setup(struct dsa_switch *ds)
                 * there's no real point in checking for errors.
                 */
                felix_set_tag_protocol(ds, port, felix->tag_proto);
+               break;
        }
 
        ds->mtu_enforcement_ingress = true;
@@ -1138,9 +1251,13 @@ out_deinit_ports:
                if (dsa_is_unused_port(ds, port))
                        continue;
 
+               felix_port_teardown_tagger_data(ds, port);
                ocelot_deinit_port(ocelot, port);
        }
 
+       kthread_destroy_worker(felix->xmit_worker);
+
+out_deinit_timestamp:
        ocelot_deinit_timestamp(ocelot);
        ocelot_deinit(ocelot);
 
@@ -1162,19 +1279,23 @@ static void felix_teardown(struct dsa_switch *ds)
                        continue;
 
                felix_del_tag_protocol(ds, port, felix->tag_proto);
+               break;
        }
 
-       ocelot_devlink_sb_unregister(ocelot);
-       ocelot_deinit_timestamp(ocelot);
-       ocelot_deinit(ocelot);
-
        for (port = 0; port < ocelot->num_phys_ports; port++) {
                if (dsa_is_unused_port(ds, port))
                        continue;
 
+               felix_port_teardown_tagger_data(ds, port);
                ocelot_deinit_port(ocelot, port);
        }
 
+       kthread_destroy_worker(felix->xmit_worker);
+
+       ocelot_devlink_sb_unregister(ocelot);
+       ocelot_deinit_timestamp(ocelot);
+       ocelot_deinit(ocelot);
+
        if (felix->info->mdio_bus_free)
                felix->info->mdio_bus_free(ocelot);
 }
@@ -1291,8 +1412,12 @@ static void felix_txtstamp(struct dsa_switch *ds, int port,
        if (!ocelot->ptp)
                return;
 
-       if (ocelot_port_txtstamp_request(ocelot, port, skb, &clone))
+       if (ocelot_port_txtstamp_request(ocelot, port, skb, &clone)) {
+               dev_err_ratelimited(ds->dev,
+                                   "port %d delivering skb without TX timestamp\n",
+                                   port);
                return;
+       }
 
        if (clone)
                OCELOT_SKB_CB(skb)->clone = clone;
index 54024b6..be3e42e 100644 (file)
@@ -62,6 +62,7 @@ struct felix {
        resource_size_t                 switch_base;
        resource_size_t                 imdio_base;
        enum dsa_tag_protocol           tag_proto;
+       struct kthread_worker           *xmit_worker;
 };
 
 struct net_device *felix_port_to_netdev(struct ocelot *ocelot, int port);
index 7c0db80..924c3f1 100644 (file)
@@ -3117,7 +3117,7 @@ static void sja1105_teardown(struct dsa_switch *ds)
        sja1105_static_config_free(&priv->static_config);
 }
 
-const struct dsa_switch_ops sja1105_switch_ops = {
+static const struct dsa_switch_ops sja1105_switch_ops = {
        .get_tag_protocol       = sja1105_get_tag_protocol,
        .setup                  = sja1105_setup,
        .teardown               = sja1105_teardown,
@@ -3166,7 +3166,6 @@ const struct dsa_switch_ops sja1105_switch_ops = {
        .port_bridge_tx_fwd_offload = dsa_tag_8021q_bridge_tx_fwd_offload,
        .port_bridge_tx_fwd_unoffload = dsa_tag_8021q_bridge_tx_fwd_unoffload,
 };
-EXPORT_SYMBOL_GPL(sja1105_switch_ops);
 
 static const struct of_device_id sja1105_dt_ids[];
 
index 691f6dd..5439699 100644 (file)
@@ -64,6 +64,7 @@ enum sja1105_ptp_clk_mode {
 static int sja1105_change_rxtstamping(struct sja1105_private *priv,
                                      bool on)
 {
+       struct sja1105_tagger_data *tagger_data = &priv->tagger_data;
        struct sja1105_ptp_data *ptp_data = &priv->ptp_data;
        struct sja1105_general_params_entry *general_params;
        struct sja1105_table *table;
@@ -79,7 +80,7 @@ static int sja1105_change_rxtstamping(struct sja1105_private *priv,
                priv->tagger_data.stampable_skb = NULL;
        }
        ptp_cancel_worker_sync(ptp_data->clock);
-       skb_queue_purge(&ptp_data->skb_txtstamp_queue);
+       skb_queue_purge(&tagger_data->skb_txtstamp_queue);
        skb_queue_purge(&ptp_data->skb_rxtstamp_queue);
 
        return sja1105_static_config_reload(priv, SJA1105_RX_HWTSTAMPING);
@@ -452,40 +453,6 @@ bool sja1105_port_rxtstamp(struct dsa_switch *ds, int port,
        return priv->info->rxtstamp(ds, port, skb);
 }
 
-void sja1110_process_meta_tstamp(struct dsa_switch *ds, int port, u8 ts_id,
-                                enum sja1110_meta_tstamp dir, u64 tstamp)
-{
-       struct sja1105_private *priv = ds->priv;
-       struct sja1105_ptp_data *ptp_data = &priv->ptp_data;
-       struct sk_buff *skb, *skb_tmp, *skb_match = NULL;
-       struct skb_shared_hwtstamps shwt = {0};
-
-       /* We don't care about RX timestamps on the CPU port */
-       if (dir == SJA1110_META_TSTAMP_RX)
-               return;
-
-       spin_lock(&ptp_data->skb_txtstamp_queue.lock);
-
-       skb_queue_walk_safe(&ptp_data->skb_txtstamp_queue, skb, skb_tmp) {
-               if (SJA1105_SKB_CB(skb)->ts_id != ts_id)
-                       continue;
-
-               __skb_unlink(skb, &ptp_data->skb_txtstamp_queue);
-               skb_match = skb;
-
-               break;
-       }
-
-       spin_unlock(&ptp_data->skb_txtstamp_queue.lock);
-
-       if (WARN_ON(!skb_match))
-               return;
-
-       shwt.hwtstamp = ns_to_ktime(sja1105_ticks_to_ns(tstamp));
-       skb_complete_tx_timestamp(skb_match, &shwt);
-}
-EXPORT_SYMBOL_GPL(sja1110_process_meta_tstamp);
-
 /* In addition to cloning the skb which is done by the common
  * sja1105_port_txtstamp, we need to generate a timestamp ID and save the
  * packet to the TX timestamping queue.
@@ -494,7 +461,6 @@ void sja1110_txtstamp(struct dsa_switch *ds, int port, struct sk_buff *skb)
 {
        struct sk_buff *clone = SJA1105_SKB_CB(skb)->clone;
        struct sja1105_private *priv = ds->priv;
-       struct sja1105_ptp_data *ptp_data = &priv->ptp_data;
        struct sja1105_port *sp = &priv->ports[port];
        u8 ts_id;
 
@@ -510,7 +476,7 @@ void sja1110_txtstamp(struct dsa_switch *ds, int port, struct sk_buff *skb)
 
        spin_unlock(&sp->data->meta_lock);
 
-       skb_queue_tail(&ptp_data->skb_txtstamp_queue, clone);
+       skb_queue_tail(&sp->data->skb_txtstamp_queue, clone);
 }
 
 /* Called from dsa_skb_tx_timestamp. This callback is just to clone
@@ -953,7 +919,7 @@ int sja1105_ptp_clock_register(struct dsa_switch *ds)
        /* Only used on SJA1105 */
        skb_queue_head_init(&ptp_data->skb_rxtstamp_queue);
        /* Only used on SJA1110 */
-       skb_queue_head_init(&ptp_data->skb_txtstamp_queue);
+       skb_queue_head_init(&tagger_data->skb_txtstamp_queue);
        spin_lock_init(&tagger_data->meta_lock);
 
        ptp_data->clock = ptp_clock_register(&ptp_data->caps, ds->dev);
@@ -971,6 +937,7 @@ int sja1105_ptp_clock_register(struct dsa_switch *ds)
 void sja1105_ptp_clock_unregister(struct dsa_switch *ds)
 {
        struct sja1105_private *priv = ds->priv;
+       struct sja1105_tagger_data *tagger_data = &priv->tagger_data;
        struct sja1105_ptp_data *ptp_data = &priv->ptp_data;
 
        if (IS_ERR_OR_NULL(ptp_data->clock))
@@ -978,7 +945,7 @@ void sja1105_ptp_clock_unregister(struct dsa_switch *ds)
 
        del_timer_sync(&ptp_data->extts_timer);
        ptp_cancel_worker_sync(ptp_data->clock);
-       skb_queue_purge(&ptp_data->skb_txtstamp_queue);
+       skb_queue_purge(&tagger_data->skb_txtstamp_queue);
        skb_queue_purge(&ptp_data->skb_rxtstamp_queue);
        ptp_clock_unregister(ptp_data->clock);
        ptp_data->clock = NULL;
index 3c874bb..3ae6b9f 100644 (file)
@@ -8,21 +8,6 @@
 
 #if IS_ENABLED(CONFIG_NET_DSA_SJA1105_PTP)
 
-/* Timestamps are in units of 8 ns clock ticks (equivalent to
- * a fixed 125 MHz clock).
- */
-#define SJA1105_TICK_NS                        8
-
-static inline s64 ns_to_sja1105_ticks(s64 ns)
-{
-       return ns / SJA1105_TICK_NS;
-}
-
-static inline s64 sja1105_ticks_to_ns(s64 ticks)
-{
-       return ticks * SJA1105_TICK_NS;
-}
-
 /* Calculate the first base_time in the future that satisfies this
  * relationship:
  *
@@ -77,10 +62,6 @@ struct sja1105_ptp_data {
        struct timer_list extts_timer;
        /* Used only on SJA1105 to reconstruct partial timestamps */
        struct sk_buff_head skb_rxtstamp_queue;
-       /* Used on SJA1110 where meta frames are generated only for
-        * 2-step TX timestamps
-        */
-       struct sk_buff_head skb_txtstamp_queue;
        struct ptp_clock_info caps;
        struct ptp_clock *clock;
        struct sja1105_ptp_cmd cmd;
index d796684..412ae3e 100644 (file)
@@ -100,6 +100,7 @@ config JME
 config KORINA
        tristate "Korina (IDT RC32434) Ethernet support"
        depends on MIKROTIK_RB532 || COMPILE_TEST
+       select CRC32
        select MII
        help
          If you have a Mikrotik RouterBoard 500 or IDT RC32434
index 37a4177..92a79c4 100644 (file)
@@ -21,6 +21,7 @@ config ARC_EMAC_CORE
        depends on ARC || ARCH_ROCKCHIP || COMPILE_TEST
        select MII
        select PHYLIB
+       select CRC32
 
 config ARC_EMAC
        tristate "ARC EMAC support"
index 1d3188e..92dc18a 100644 (file)
@@ -780,7 +780,7 @@ struct gve_queue_page_list *gve_assign_rx_qpl(struct gve_priv *priv)
                                    gve_num_tx_qpls(priv));
 
        /* we are out of rx qpls */
-       if (id == priv->qpl_cfg.qpl_map_size)
+       if (id == gve_num_tx_qpls(priv) + gve_num_rx_qpls(priv))
                return NULL;
 
        set_bit(id, priv->qpl_cfg.qpl_id_map);
index 099a2bc..bf8a4a7 100644 (file)
@@ -41,6 +41,7 @@ static void gve_get_stats(struct net_device *dev, struct rtnl_link_stats64 *s)
 {
        struct gve_priv *priv = netdev_priv(dev);
        unsigned int start;
+       u64 packets, bytes;
        int ring;
 
        if (priv->rx) {
@@ -48,10 +49,12 @@ static void gve_get_stats(struct net_device *dev, struct rtnl_link_stats64 *s)
                        do {
                                start =
                                  u64_stats_fetch_begin(&priv->rx[ring].statss);
-                               s->rx_packets += priv->rx[ring].rpackets;
-                               s->rx_bytes += priv->rx[ring].rbytes;
+                               packets = priv->rx[ring].rpackets;
+                               bytes = priv->rx[ring].rbytes;
                        } while (u64_stats_fetch_retry(&priv->rx[ring].statss,
                                                       start));
+                       s->rx_packets += packets;
+                       s->rx_bytes += bytes;
                }
        }
        if (priv->tx) {
@@ -59,10 +62,12 @@ static void gve_get_stats(struct net_device *dev, struct rtnl_link_stats64 *s)
                        do {
                                start =
                                  u64_stats_fetch_begin(&priv->tx[ring].statss);
-                               s->tx_packets += priv->tx[ring].pkt_done;
-                               s->tx_bytes += priv->tx[ring].bytes_done;
+                               packets = priv->tx[ring].pkt_done;
+                               bytes = priv->tx[ring].bytes_done;
                        } while (u64_stats_fetch_retry(&priv->tx[ring].statss,
                                                       start));
+                       s->tx_packets += packets;
+                       s->tx_bytes += bytes;
                }
        }
 }
@@ -82,6 +87,9 @@ static int gve_alloc_counter_array(struct gve_priv *priv)
 
 static void gve_free_counter_array(struct gve_priv *priv)
 {
+       if (!priv->counter_array)
+               return;
+
        dma_free_coherent(&priv->pdev->dev,
                          priv->num_event_counters *
                          sizeof(*priv->counter_array),
@@ -142,6 +150,9 @@ static int gve_alloc_stats_report(struct gve_priv *priv)
 
 static void gve_free_stats_report(struct gve_priv *priv)
 {
+       if (!priv->stats_report)
+               return;
+
        del_timer_sync(&priv->stats_report_timer);
        dma_free_coherent(&priv->pdev->dev, priv->stats_report_len,
                          priv->stats_report, priv->stats_report_bus);
@@ -370,18 +381,19 @@ static void gve_free_notify_blocks(struct gve_priv *priv)
 {
        int i;
 
-       if (priv->msix_vectors) {
-               /* Free the irqs */
-               for (i = 0; i < priv->num_ntfy_blks; i++) {
-                       struct gve_notify_block *block = &priv->ntfy_blocks[i];
-                       int msix_idx = i;
+       if (!priv->msix_vectors)
+               return;
 
-                       irq_set_affinity_hint(priv->msix_vectors[msix_idx].vector,
-                                             NULL);
-                       free_irq(priv->msix_vectors[msix_idx].vector, block);
-               }
-               free_irq(priv->msix_vectors[priv->mgmt_msix_idx].vector, priv);
+       /* Free the irqs */
+       for (i = 0; i < priv->num_ntfy_blks; i++) {
+               struct gve_notify_block *block = &priv->ntfy_blocks[i];
+               int msix_idx = i;
+
+               irq_set_affinity_hint(priv->msix_vectors[msix_idx].vector,
+                                     NULL);
+               free_irq(priv->msix_vectors[msix_idx].vector, block);
        }
+       free_irq(priv->msix_vectors[priv->mgmt_msix_idx].vector, priv);
        dma_free_coherent(&priv->pdev->dev,
                          priv->num_ntfy_blks * sizeof(*priv->ntfy_blocks),
                          priv->ntfy_blocks, priv->ntfy_block_bus);
@@ -1185,9 +1197,10 @@ static void gve_handle_reset(struct gve_priv *priv)
 
 void gve_handle_report_stats(struct gve_priv *priv)
 {
-       int idx, stats_idx = 0, tx_bytes;
-       unsigned int start = 0;
        struct stats *stats = priv->stats_report->stats;
+       int idx, stats_idx = 0;
+       unsigned int start = 0;
+       u64 tx_bytes;
 
        if (!gve_get_report_stats(priv))
                return;
index bb82613..94941d4 100644 (file)
@@ -104,8 +104,14 @@ static int gve_prefill_rx_pages(struct gve_rx_ring *rx)
        if (!rx->data.page_info)
                return -ENOMEM;
 
-       if (!rx->data.raw_addressing)
+       if (!rx->data.raw_addressing) {
                rx->data.qpl = gve_assign_rx_qpl(priv);
+               if (!rx->data.qpl) {
+                       kvfree(rx->data.page_info);
+                       rx->data.page_info = NULL;
+                       return -ENOMEM;
+               }
+       }
        for (i = 0; i < slots; i++) {
                if (!rx->data.raw_addressing) {
                        struct page *page = rx->data.qpl->pages[i];
index 2f20980..e04b540 100644 (file)
@@ -4871,7 +4871,8 @@ static void i40e_clear_interrupt_scheme(struct i40e_pf *pf)
 {
        int i;
 
-       i40e_free_misc_vector(pf);
+       if (test_bit(__I40E_MISC_IRQ_REQUESTED, pf->state))
+               i40e_free_misc_vector(pf);
 
        i40e_put_lump(pf->irq_pile, pf->iwarp_base_vector,
                      I40E_IWARP_IRQ_PILE_ID);
@@ -10113,7 +10114,7 @@ static int i40e_get_capabilities(struct i40e_pf *pf,
                if (pf->hw.aq.asq_last_status == I40E_AQ_RC_ENOMEM) {
                        /* retry with a larger buffer */
                        buf_len = data_size;
-               } else if (pf->hw.aq.asq_last_status != I40E_AQ_RC_OK) {
+               } else if (pf->hw.aq.asq_last_status != I40E_AQ_RC_OK || err) {
                        dev_info(&pf->pdev->dev,
                                 "capability discovery failed, err %s aq_err %s\n",
                                 i40e_stat_str(&pf->hw, err),
index 23762a7..cada4e0 100644 (file)
@@ -1965,7 +1965,6 @@ static void iavf_watchdog_task(struct work_struct *work)
                }
                adapter->aq_required = 0;
                adapter->current_op = VIRTCHNL_OP_UNKNOWN;
-               mutex_unlock(&adapter->crit_lock);
                queue_delayed_work(iavf_wq,
                                   &adapter->watchdog_task,
                                   msecs_to_jiffies(10));
index 05cc587..80380ae 100644 (file)
@@ -1313,22 +1313,21 @@ ice_ptp_flush_tx_tracker(struct ice_pf *pf, struct ice_ptp_tx *tx)
 {
        u8 idx;
 
-       spin_lock(&tx->lock);
-
        for (idx = 0; idx < tx->len; idx++) {
                u8 phy_idx = idx + tx->quad_offset;
 
-               /* Clear any potential residual timestamp in the PHY block */
-               if (!pf->hw.reset_ongoing)
-                       ice_clear_phy_tstamp(&pf->hw, tx->quad, phy_idx);
-
+               spin_lock(&tx->lock);
                if (tx->tstamps[idx].skb) {
                        dev_kfree_skb_any(tx->tstamps[idx].skb);
                        tx->tstamps[idx].skb = NULL;
                }
-       }
+               clear_bit(idx, tx->in_use);
+               spin_unlock(&tx->lock);
 
-       spin_unlock(&tx->lock);
+               /* Clear any potential residual timestamp in the PHY block */
+               if (!pf->hw.reset_ongoing)
+                       ice_clear_phy_tstamp(&pf->hw, tx->quad, phy_idx);
+       }
 }
 
 /**
index cf97985..02e77ff 100644 (file)
@@ -155,6 +155,8 @@ int mlx5_core_destroy_cq(struct mlx5_core_dev *dev, struct mlx5_core_cq *cq)
        u32 in[MLX5_ST_SZ_DW(destroy_cq_in)] = {};
        int err;
 
+       mlx5_debug_cq_remove(dev, cq);
+
        mlx5_eq_del_cq(mlx5_get_async_eq(dev), cq);
        mlx5_eq_del_cq(&cq->eq->core, cq);
 
@@ -162,16 +164,13 @@ int mlx5_core_destroy_cq(struct mlx5_core_dev *dev, struct mlx5_core_cq *cq)
        MLX5_SET(destroy_cq_in, in, cqn, cq->cqn);
        MLX5_SET(destroy_cq_in, in, uid, cq->uid);
        err = mlx5_cmd_exec_in(dev, destroy_cq, in);
-       if (err)
-               return err;
 
        synchronize_irq(cq->irqn);
 
-       mlx5_debug_cq_remove(dev, cq);
        mlx5_cq_put(cq);
        wait_for_completion(&cq->free);
 
-       return 0;
+       return err;
 }
 EXPORT_SYMBOL(mlx5_core_destroy_cq);
 
index 7b8c818..03a7a4c 100644 (file)
@@ -252,6 +252,7 @@ struct mlx5e_params {
        struct {
                u16 mode;
                u8 num_tc;
+               struct netdev_tc_txq tc_to_txq[TC_MAX_QUEUE];
        } mqprio;
        bool rx_cqe_compress_def;
        bool tunneled_offload_en;
@@ -845,6 +846,7 @@ struct mlx5e_priv {
        struct mlx5e_channel_stats channel_stats[MLX5E_MAX_NUM_CHANNELS];
        struct mlx5e_channel_stats trap_stats;
        struct mlx5e_ptp_stats     ptp_stats;
+       u16                        stats_nch;
        u16                        max_nch;
        u8                         max_opened_tc;
        bool                       tx_ptp_opened;
@@ -1100,12 +1102,6 @@ int mlx5e_ethtool_set_pauseparam(struct mlx5e_priv *priv,
                                 struct ethtool_pauseparam *pauseparam);
 
 /* mlx5e generic netdev management API */
-static inline unsigned int
-mlx5e_calc_max_nch(struct mlx5e_priv *priv, const struct mlx5e_profile *profile)
-{
-       return priv->netdev->num_rx_queues / max_t(u8, profile->rq_groups, 1);
-}
-
 static inline bool
 mlx5e_tx_mpwqe_supported(struct mlx5_core_dev *mdev)
 {
@@ -1114,11 +1110,13 @@ mlx5e_tx_mpwqe_supported(struct mlx5_core_dev *mdev)
 }
 
 int mlx5e_priv_init(struct mlx5e_priv *priv,
+                   const struct mlx5e_profile *profile,
                    struct net_device *netdev,
                    struct mlx5_core_dev *mdev);
 void mlx5e_priv_cleanup(struct mlx5e_priv *priv);
 struct net_device *
-mlx5e_create_netdev(struct mlx5_core_dev *mdev, unsigned int txqs, unsigned int rxqs);
+mlx5e_create_netdev(struct mlx5_core_dev *mdev, const struct mlx5e_profile *profile,
+                   unsigned int txqs, unsigned int rxqs);
 int mlx5e_attach_netdev(struct mlx5e_priv *priv);
 void mlx5e_detach_netdev(struct mlx5e_priv *priv);
 void mlx5e_destroy_netdev(struct mlx5e_priv *priv);
index ac44bbe..d290d72 100644 (file)
@@ -35,7 +35,7 @@ static void mlx5e_hv_vhca_fill_stats(struct mlx5e_priv *priv, void *data,
 {
        int ch, i = 0;
 
-       for (ch = 0; ch < priv->max_nch; ch++) {
+       for (ch = 0; ch < priv->stats_nch; ch++) {
                void *buf = data + i;
 
                if (WARN_ON_ONCE(buf +
@@ -51,7 +51,7 @@ static void mlx5e_hv_vhca_fill_stats(struct mlx5e_priv *priv, void *data,
 static int mlx5e_hv_vhca_stats_buf_size(struct mlx5e_priv *priv)
 {
        return (sizeof(struct mlx5e_hv_vhca_per_ring_stats) *
-               priv->max_nch);
+               priv->stats_nch);
 }
 
 static void mlx5e_hv_vhca_stats_work(struct work_struct *work)
@@ -100,7 +100,7 @@ static void mlx5e_hv_vhca_stats_control(struct mlx5_hv_vhca_agent *agent,
        sagent = &priv->stats_agent;
 
        block->version = MLX5_HV_VHCA_STATS_VERSION;
-       block->rings   = priv->max_nch;
+       block->rings   = priv->stats_nch;
 
        if (!block->command) {
                cancel_delayed_work_sync(&priv->stats_agent.work);
index ee688de..3a86f66 100644 (file)
@@ -13,8 +13,6 @@ struct mlx5e_ptp_fs {
        bool valid;
 };
 
-#define MLX5E_PTP_CHANNEL_IX 0
-
 struct mlx5e_ptp_params {
        struct mlx5e_params params;
        struct mlx5e_sq_param txq_sq_param;
@@ -509,6 +507,7 @@ static int mlx5e_init_ptp_rq(struct mlx5e_ptp *c, struct mlx5e_params *params,
        rq->mdev         = mdev;
        rq->hw_mtu       = MLX5E_SW2HW_MTU(params, params->sw_mtu);
        rq->stats        = &c->priv->ptp_stats.rq;
+       rq->ix           = MLX5E_PTP_CHANNEL_IX;
        rq->ptp_cyc2time = mlx5_rq_ts_translator(mdev);
        err = mlx5e_rq_set_handlers(rq, params, false);
        if (err)
index c96668b..a71a32e 100644 (file)
@@ -8,6 +8,8 @@
 #include "en_stats.h"
 #include <linux/ptp_classify.h>
 
+#define MLX5E_PTP_CHANNEL_IX 0
+
 struct mlx5e_ptpsq {
        struct mlx5e_txqsq       txqsq;
        struct mlx5e_cq          ts_cq;
index b5ddaa8..c6d2f8c 100644 (file)
@@ -475,9 +475,6 @@ void mlx5e_rep_bridge_init(struct mlx5e_priv *priv)
                esw_warn(mdev, "Failed to allocate bridge offloads workqueue\n");
                goto err_alloc_wq;
        }
-       INIT_DELAYED_WORK(&br_offloads->update_work, mlx5_esw_bridge_update_work);
-       queue_delayed_work(br_offloads->wq, &br_offloads->update_work,
-                          msecs_to_jiffies(MLX5_ESW_BRIDGE_UPDATE_INTERVAL));
 
        br_offloads->nb.notifier_call = mlx5_esw_bridge_switchdev_event;
        err = register_switchdev_notifier(&br_offloads->nb);
@@ -500,6 +497,9 @@ void mlx5e_rep_bridge_init(struct mlx5e_priv *priv)
                         err);
                goto err_register_netdev;
        }
+       INIT_DELAYED_WORK(&br_offloads->update_work, mlx5_esw_bridge_update_work);
+       queue_delayed_work(br_offloads->wq, &br_offloads->update_work,
+                          msecs_to_jiffies(MLX5_ESW_BRIDGE_UPDATE_INTERVAL));
        return;
 
 err_register_netdev:
@@ -523,10 +523,10 @@ void mlx5e_rep_bridge_cleanup(struct mlx5e_priv *priv)
        if (!br_offloads)
                return;
 
+       cancel_delayed_work_sync(&br_offloads->update_work);
        unregister_netdevice_notifier(&br_offloads->netdev_nb);
        unregister_switchdev_blocking_notifier(&br_offloads->nb_blk);
        unregister_switchdev_notifier(&br_offloads->nb);
-       cancel_delayed_work(&br_offloads->update_work);
        destroy_workqueue(br_offloads->wq);
        rtnl_lock();
        mlx5_esw_bridge_cleanup(esw);
index 306fb5d..9d451b8 100644 (file)
@@ -2036,6 +2036,17 @@ static int set_pflag_tx_port_ts(struct net_device *netdev, bool enable)
        }
 
        new_params = priv->channels.params;
+       /* Don't allow enabling TX-port-TS if MQPRIO mode channel  offload is
+        * active, since it defines explicitly which TC accepts the packet.
+        * This conflicts with TX-port-TS hijacking the PTP traffic to a specific
+        * HW TX-queue.
+        */
+       if (enable && new_params.mqprio.mode == TC_MQPRIO_MODE_CHANNEL) {
+               netdev_err(priv->netdev,
+                          "%s: MQPRIO mode channel offload is active, cannot set the TX-port-TS\n",
+                          __func__);
+               return -EINVAL;
+       }
        MLX5E_SET_PFLAG(&new_params, MLX5E_PFLAG_TX_PORT_TS, enable);
        /* No need to verify SQ stop room as
         * ptpsq.txqsq.stop_room <= generic_sq->stop_room, and both
index 3fd515e..09c8b71 100644 (file)
@@ -2264,7 +2264,7 @@ void mlx5e_set_netdev_mtu_boundaries(struct mlx5e_priv *priv)
 }
 
 static int mlx5e_netdev_set_tcs(struct net_device *netdev, u16 nch, u8 ntc,
-                               struct tc_mqprio_qopt_offload *mqprio)
+                               struct netdev_tc_txq *tc_to_txq)
 {
        int tc, err;
 
@@ -2282,11 +2282,8 @@ static int mlx5e_netdev_set_tcs(struct net_device *netdev, u16 nch, u8 ntc,
        for (tc = 0; tc < ntc; tc++) {
                u16 count, offset;
 
-               /* For DCB mode, map netdev TCs to offset 0
-                * We have our own UP to TXQ mapping for QoS
-                */
-               count = mqprio ? mqprio->qopt.count[tc] : nch;
-               offset = mqprio ? mqprio->qopt.offset[tc] : 0;
+               count = tc_to_txq[tc].count;
+               offset = tc_to_txq[tc].offset;
                netdev_set_tc_queue(netdev, tc, count, offset);
        }
 
@@ -2315,19 +2312,24 @@ int mlx5e_update_tx_netdev_queues(struct mlx5e_priv *priv)
 
 static int mlx5e_update_netdev_queues(struct mlx5e_priv *priv)
 {
+       struct netdev_tc_txq old_tc_to_txq[TC_MAX_QUEUE], *tc_to_txq;
        struct net_device *netdev = priv->netdev;
        int old_num_txqs, old_ntc;
        int num_rxqs, nch, ntc;
        int err;
+       int i;
 
        old_num_txqs = netdev->real_num_tx_queues;
        old_ntc = netdev->num_tc ? : 1;
+       for (i = 0; i < ARRAY_SIZE(old_tc_to_txq); i++)
+               old_tc_to_txq[i] = netdev->tc_to_txq[i];
 
        nch = priv->channels.params.num_channels;
-       ntc = mlx5e_get_dcb_num_tc(&priv->channels.params);
+       ntc = priv->channels.params.mqprio.num_tc;
        num_rxqs = nch * priv->profile->rq_groups;
+       tc_to_txq = priv->channels.params.mqprio.tc_to_txq;
 
-       err = mlx5e_netdev_set_tcs(netdev, nch, ntc, NULL);
+       err = mlx5e_netdev_set_tcs(netdev, nch, ntc, tc_to_txq);
        if (err)
                goto err_out;
        err = mlx5e_update_tx_netdev_queues(priv);
@@ -2350,11 +2352,14 @@ err_txqs:
        WARN_ON_ONCE(netif_set_real_num_tx_queues(netdev, old_num_txqs));
 
 err_tcs:
-       mlx5e_netdev_set_tcs(netdev, old_num_txqs / old_ntc, old_ntc, NULL);
+       WARN_ON_ONCE(mlx5e_netdev_set_tcs(netdev, old_num_txqs / old_ntc, old_ntc,
+                                         old_tc_to_txq));
 err_out:
        return err;
 }
 
+static MLX5E_DEFINE_PREACTIVATE_WRAPPER_CTX(mlx5e_update_netdev_queues);
+
 static void mlx5e_set_default_xps_cpumasks(struct mlx5e_priv *priv,
                                           struct mlx5e_params *params)
 {
@@ -2861,6 +2866,58 @@ static int mlx5e_modify_channels_vsd(struct mlx5e_channels *chs, bool vsd)
        return 0;
 }
 
+static void mlx5e_mqprio_build_default_tc_to_txq(struct netdev_tc_txq *tc_to_txq,
+                                                int ntc, int nch)
+{
+       int tc;
+
+       memset(tc_to_txq, 0, sizeof(*tc_to_txq) * TC_MAX_QUEUE);
+
+       /* Map netdev TCs to offset 0.
+        * We have our own UP to TXQ mapping for DCB mode of QoS
+        */
+       for (tc = 0; tc < ntc; tc++) {
+               tc_to_txq[tc] = (struct netdev_tc_txq) {
+                       .count = nch,
+                       .offset = 0,
+               };
+       }
+}
+
+static void mlx5e_mqprio_build_tc_to_txq(struct netdev_tc_txq *tc_to_txq,
+                                        struct tc_mqprio_qopt *qopt)
+{
+       int tc;
+
+       for (tc = 0; tc < TC_MAX_QUEUE; tc++) {
+               tc_to_txq[tc] = (struct netdev_tc_txq) {
+                       .count = qopt->count[tc],
+                       .offset = qopt->offset[tc],
+               };
+       }
+}
+
+static void mlx5e_params_mqprio_dcb_set(struct mlx5e_params *params, u8 num_tc)
+{
+       params->mqprio.mode = TC_MQPRIO_MODE_DCB;
+       params->mqprio.num_tc = num_tc;
+       mlx5e_mqprio_build_default_tc_to_txq(params->mqprio.tc_to_txq, num_tc,
+                                            params->num_channels);
+}
+
+static void mlx5e_params_mqprio_channel_set(struct mlx5e_params *params,
+                                           struct tc_mqprio_qopt *qopt)
+{
+       params->mqprio.mode = TC_MQPRIO_MODE_CHANNEL;
+       params->mqprio.num_tc = qopt->num_tc;
+       mlx5e_mqprio_build_tc_to_txq(params->mqprio.tc_to_txq, qopt);
+}
+
+static void mlx5e_params_mqprio_reset(struct mlx5e_params *params)
+{
+       mlx5e_params_mqprio_dcb_set(params, 1);
+}
+
 static int mlx5e_setup_tc_mqprio_dcb(struct mlx5e_priv *priv,
                                     struct tc_mqprio_qopt *mqprio)
 {
@@ -2874,8 +2931,7 @@ static int mlx5e_setup_tc_mqprio_dcb(struct mlx5e_priv *priv,
                return -EINVAL;
 
        new_params = priv->channels.params;
-       new_params.mqprio.mode = TC_MQPRIO_MODE_DCB;
-       new_params.mqprio.num_tc = tc ? tc : 1;
+       mlx5e_params_mqprio_dcb_set(&new_params, tc ? tc : 1);
 
        err = mlx5e_safe_switch_params(priv, &new_params,
                                       mlx5e_num_channels_changed_ctx, NULL, true);
@@ -2889,9 +2945,17 @@ static int mlx5e_mqprio_channel_validate(struct mlx5e_priv *priv,
                                         struct tc_mqprio_qopt_offload *mqprio)
 {
        struct net_device *netdev = priv->netdev;
+       struct mlx5e_ptp *ptp_channel;
        int agg_count = 0;
        int i;
 
+       ptp_channel = priv->channels.ptp;
+       if (ptp_channel && test_bit(MLX5E_PTP_STATE_TX, ptp_channel->state)) {
+               netdev_err(netdev,
+                          "Cannot activate MQPRIO mode channel since it conflicts with TX port TS\n");
+               return -EINVAL;
+       }
+
        if (mqprio->qopt.offset[0] != 0 || mqprio->qopt.num_tc < 1 ||
            mqprio->qopt.num_tc > MLX5E_MAX_NUM_MQPRIO_CH_TC)
                return -EINVAL;
@@ -2917,8 +2981,8 @@ static int mlx5e_mqprio_channel_validate(struct mlx5e_priv *priv,
                agg_count += mqprio->qopt.count[i];
        }
 
-       if (priv->channels.params.num_channels < agg_count) {
-               netdev_err(netdev, "Num of queues (%d) exceeds available (%d)\n",
+       if (priv->channels.params.num_channels != agg_count) {
+               netdev_err(netdev, "Num of queues (%d) does not match available (%d)\n",
                           agg_count, priv->channels.params.num_channels);
                return -EINVAL;
        }
@@ -2926,25 +2990,12 @@ static int mlx5e_mqprio_channel_validate(struct mlx5e_priv *priv,
        return 0;
 }
 
-static int mlx5e_mqprio_channel_set_tcs_ctx(struct mlx5e_priv *priv, void *ctx)
-{
-       struct tc_mqprio_qopt_offload *mqprio = (struct tc_mqprio_qopt_offload *)ctx;
-       struct net_device *netdev = priv->netdev;
-       u8 num_tc;
-
-       if (priv->channels.params.mqprio.mode != TC_MQPRIO_MODE_CHANNEL)
-               return -EINVAL;
-
-       num_tc = priv->channels.params.mqprio.num_tc;
-       mlx5e_netdev_set_tcs(netdev, 0, num_tc, mqprio);
-
-       return 0;
-}
-
 static int mlx5e_setup_tc_mqprio_channel(struct mlx5e_priv *priv,
                                         struct tc_mqprio_qopt_offload *mqprio)
 {
+       mlx5e_fp_preactivate preactivate;
        struct mlx5e_params new_params;
+       bool nch_changed;
        int err;
 
        err = mlx5e_mqprio_channel_validate(priv, mqprio);
@@ -2952,12 +3003,12 @@ static int mlx5e_setup_tc_mqprio_channel(struct mlx5e_priv *priv,
                return err;
 
        new_params = priv->channels.params;
-       new_params.mqprio.mode = TC_MQPRIO_MODE_CHANNEL;
-       new_params.mqprio.num_tc = mqprio->qopt.num_tc;
-       err = mlx5e_safe_switch_params(priv, &new_params,
-                                      mlx5e_mqprio_channel_set_tcs_ctx, mqprio, true);
+       mlx5e_params_mqprio_channel_set(&new_params, &mqprio->qopt);
 
-       return err;
+       nch_changed = mlx5e_get_dcb_num_tc(&priv->channels.params) > 1;
+       preactivate = nch_changed ? mlx5e_num_channels_changed_ctx :
+               mlx5e_update_netdev_queues_ctx;
+       return mlx5e_safe_switch_params(priv, &new_params, preactivate, NULL, true);
 }
 
 static int mlx5e_setup_tc_mqprio(struct mlx5e_priv *priv,
@@ -3065,7 +3116,7 @@ void mlx5e_fold_sw_stats64(struct mlx5e_priv *priv, struct rtnl_link_stats64 *s)
 {
        int i;
 
-       for (i = 0; i < priv->max_nch; i++) {
+       for (i = 0; i < priv->stats_nch; i++) {
                struct mlx5e_channel_stats *channel_stats = &priv->channel_stats[i];
                struct mlx5e_rq_stats *xskrq_stats = &channel_stats->xskrq;
                struct mlx5e_rq_stats *rq_stats = &channel_stats->rq;
@@ -3274,20 +3325,67 @@ static int set_feature_rx_all(struct net_device *netdev, bool enable)
        return mlx5_set_port_fcs(mdev, !enable);
 }
 
+static int mlx5e_set_rx_port_ts(struct mlx5_core_dev *mdev, bool enable)
+{
+       u32 in[MLX5_ST_SZ_DW(pcmr_reg)] = {};
+       bool supported, curr_state;
+       int err;
+
+       if (!MLX5_CAP_GEN(mdev, ports_check))
+               return 0;
+
+       err = mlx5_query_ports_check(mdev, in, sizeof(in));
+       if (err)
+               return err;
+
+       supported = MLX5_GET(pcmr_reg, in, rx_ts_over_crc_cap);
+       curr_state = MLX5_GET(pcmr_reg, in, rx_ts_over_crc);
+
+       if (!supported || enable == curr_state)
+               return 0;
+
+       MLX5_SET(pcmr_reg, in, local_port, 1);
+       MLX5_SET(pcmr_reg, in, rx_ts_over_crc, enable);
+
+       return mlx5_set_ports_check(mdev, in, sizeof(in));
+}
+
 static int set_feature_rx_fcs(struct net_device *netdev, bool enable)
 {
        struct mlx5e_priv *priv = netdev_priv(netdev);
+       struct mlx5e_channels *chs = &priv->channels;
+       struct mlx5_core_dev *mdev = priv->mdev;
        int err;
 
        mutex_lock(&priv->state_lock);
 
-       priv->channels.params.scatter_fcs_en = enable;
-       err = mlx5e_modify_channels_scatter_fcs(&priv->channels, enable);
-       if (err)
-               priv->channels.params.scatter_fcs_en = !enable;
+       if (enable) {
+               err = mlx5e_set_rx_port_ts(mdev, false);
+               if (err)
+                       goto out;
 
-       mutex_unlock(&priv->state_lock);
+               chs->params.scatter_fcs_en = true;
+               err = mlx5e_modify_channels_scatter_fcs(chs, true);
+               if (err) {
+                       chs->params.scatter_fcs_en = false;
+                       mlx5e_set_rx_port_ts(mdev, true);
+               }
+       } else {
+               chs->params.scatter_fcs_en = false;
+               err = mlx5e_modify_channels_scatter_fcs(chs, false);
+               if (err) {
+                       chs->params.scatter_fcs_en = true;
+                       goto out;
+               }
+               err = mlx5e_set_rx_port_ts(mdev, true);
+               if (err) {
+                       mlx5_core_warn(mdev, "Failed to set RX port timestamp %d\n", err);
+                       err = 0;
+               }
+       }
 
+out:
+       mutex_unlock(&priv->state_lock);
        return err;
 }
 
@@ -4186,13 +4284,11 @@ void mlx5e_build_nic_params(struct mlx5e_priv *priv, struct mlx5e_xsk *xsk, u16
        struct mlx5_core_dev *mdev = priv->mdev;
        u8 rx_cq_period_mode;
 
-       priv->max_nch = mlx5e_calc_max_nch(priv, priv->profile);
-
        params->sw_mtu = mtu;
        params->hard_mtu = MLX5E_ETH_HARD_MTU;
        params->num_channels = min_t(unsigned int, MLX5E_MAX_NUM_CHANNELS / 2,
                                     priv->max_nch);
-       params->mqprio.num_tc = 1;
+       mlx5e_params_mqprio_reset(params);
 
        /* Set an initial non-zero value, so that mlx5e_select_queue won't
         * divide by zero if called before first activating channels.
@@ -4682,8 +4778,35 @@ static const struct mlx5e_profile mlx5e_nic_profile = {
        .rx_ptp_support    = true,
 };
 
+static unsigned int
+mlx5e_calc_max_nch(struct mlx5_core_dev *mdev, struct net_device *netdev,
+                  const struct mlx5e_profile *profile)
+
+{
+       unsigned int max_nch, tmp;
+
+       /* core resources */
+       max_nch = mlx5e_get_max_num_channels(mdev);
+
+       /* netdev rx queues */
+       tmp = netdev->num_rx_queues / max_t(u8, profile->rq_groups, 1);
+       max_nch = min_t(unsigned int, max_nch, tmp);
+
+       /* netdev tx queues */
+       tmp = netdev->num_tx_queues;
+       if (mlx5_qos_is_supported(mdev))
+               tmp -= mlx5e_qos_max_leaf_nodes(mdev);
+       if (MLX5_CAP_GEN(mdev, ts_cqe_to_dest_cqn))
+               tmp -= profile->max_tc;
+       tmp = tmp / profile->max_tc;
+       max_nch = min_t(unsigned int, max_nch, tmp);
+
+       return max_nch;
+}
+
 /* mlx5e generic netdev management API (move to en_common.c) */
 int mlx5e_priv_init(struct mlx5e_priv *priv,
+                   const struct mlx5e_profile *profile,
                    struct net_device *netdev,
                    struct mlx5_core_dev *mdev)
 {
@@ -4691,6 +4814,8 @@ int mlx5e_priv_init(struct mlx5e_priv *priv,
        priv->mdev        = mdev;
        priv->netdev      = netdev;
        priv->msglevel    = MLX5E_MSG_LEVEL;
+       priv->max_nch     = mlx5e_calc_max_nch(mdev, netdev, profile);
+       priv->stats_nch   = priv->max_nch;
        priv->max_opened_tc = 1;
 
        if (!alloc_cpumask_var(&priv->scratchpad.cpumask, GFP_KERNEL))
@@ -4734,7 +4859,8 @@ void mlx5e_priv_cleanup(struct mlx5e_priv *priv)
 }
 
 struct net_device *
-mlx5e_create_netdev(struct mlx5_core_dev *mdev, unsigned int txqs, unsigned int rxqs)
+mlx5e_create_netdev(struct mlx5_core_dev *mdev, const struct mlx5e_profile *profile,
+                   unsigned int txqs, unsigned int rxqs)
 {
        struct net_device *netdev;
        int err;
@@ -4745,7 +4871,7 @@ mlx5e_create_netdev(struct mlx5_core_dev *mdev, unsigned int txqs, unsigned int
                return NULL;
        }
 
-       err = mlx5e_priv_init(netdev_priv(netdev), netdev, mdev);
+       err = mlx5e_priv_init(netdev_priv(netdev), profile, netdev, mdev);
        if (err) {
                mlx5_core_err(mdev, "mlx5e_priv_init failed, err=%d\n", err);
                goto err_free_netdev;
@@ -4787,7 +4913,7 @@ int mlx5e_attach_netdev(struct mlx5e_priv *priv)
        clear_bit(MLX5E_STATE_DESTROYING, &priv->state);
 
        /* max number of channels may have changed */
-       max_nch = mlx5e_get_max_num_channels(priv->mdev);
+       max_nch = mlx5e_calc_max_nch(priv->mdev, priv->netdev, profile);
        if (priv->channels.params.num_channels > max_nch) {
                mlx5_core_warn(priv->mdev, "MLX5E: Reducing number of channels to %d\n", max_nch);
                /* Reducing the number of channels - RXFH has to be reset, and
@@ -4795,7 +4921,18 @@ int mlx5e_attach_netdev(struct mlx5e_priv *priv)
                 */
                priv->netdev->priv_flags &= ~IFF_RXFH_CONFIGURED;
                priv->channels.params.num_channels = max_nch;
+               if (priv->channels.params.mqprio.mode == TC_MQPRIO_MODE_CHANNEL) {
+                       mlx5_core_warn(priv->mdev, "MLX5E: Disabling MQPRIO channel mode\n");
+                       mlx5e_params_mqprio_reset(&priv->channels.params);
+               }
        }
+       if (max_nch != priv->max_nch) {
+               mlx5_core_warn(priv->mdev,
+                              "MLX5E: Updating max number of channels from %u to %u\n",
+                              priv->max_nch, max_nch);
+               priv->max_nch = max_nch;
+       }
+
        /* 1. Set the real number of queues in the kernel the first time.
         * 2. Set our default XPS cpumask.
         * 3. Build the RQT.
@@ -4860,7 +4997,7 @@ mlx5e_netdev_attach_profile(struct net_device *netdev, struct mlx5_core_dev *mde
        struct mlx5e_priv *priv = netdev_priv(netdev);
        int err;
 
-       err = mlx5e_priv_init(priv, netdev, mdev);
+       err = mlx5e_priv_init(priv, new_profile, netdev, mdev);
        if (err) {
                mlx5_core_err(mdev, "mlx5e_priv_init failed, err=%d\n", err);
                return err;
@@ -4886,20 +5023,12 @@ priv_cleanup:
 int mlx5e_netdev_change_profile(struct mlx5e_priv *priv,
                                const struct mlx5e_profile *new_profile, void *new_ppriv)
 {
-       unsigned int new_max_nch = mlx5e_calc_max_nch(priv, new_profile);
        const struct mlx5e_profile *orig_profile = priv->profile;
        struct net_device *netdev = priv->netdev;
        struct mlx5_core_dev *mdev = priv->mdev;
        void *orig_ppriv = priv->ppriv;
        int err, rollback_err;
 
-       /* sanity */
-       if (new_max_nch != priv->max_nch) {
-               netdev_warn(netdev, "%s: Replacing profile with different max channels\n",
-                           __func__);
-               return -EINVAL;
-       }
-
        /* cleanup old profile */
        mlx5e_detach_netdev(priv);
        priv->profile->cleanup(priv);
@@ -4995,7 +5124,7 @@ static int mlx5e_probe(struct auxiliary_device *adev,
        nch = mlx5e_get_max_num_channels(mdev);
        txqs = nch * profile->max_tc + ptp_txqs + qos_sqs;
        rxqs = nch * profile->rq_groups;
-       netdev = mlx5e_create_netdev(mdev, txqs, rxqs);
+       netdev = mlx5e_create_netdev(mdev, profile, txqs, rxqs);
        if (!netdev) {
                mlx5_core_err(mdev, "mlx5e_create_netdev failed\n");
                return -ENOMEM;
index ae71a17..0684ac6 100644 (file)
@@ -596,7 +596,6 @@ static void mlx5e_build_rep_params(struct net_device *netdev)
                                         MLX5_CQ_PERIOD_MODE_START_FROM_CQE :
                                         MLX5_CQ_PERIOD_MODE_START_FROM_EQE;
 
-       priv->max_nch = mlx5e_calc_max_nch(priv, priv->profile);
        params = &priv->channels.params;
 
        params->num_channels = MLX5E_REP_PARAMS_DEF_NUM_CHANNELS;
@@ -619,6 +618,11 @@ static void mlx5e_build_rep_params(struct net_device *netdev)
        params->mqprio.num_tc       = 1;
        params->tunneled_offload_en = false;
 
+       /* Set an initial non-zero value, so that mlx5e_select_queue won't
+        * divide by zero if called before first activating channels.
+        */
+       priv->num_tc_x_num_ch = params->num_channels * params->mqprio.num_tc;
+
        mlx5_query_min_inline(mdev, &params->tx_min_inline_mode);
 }
 
@@ -644,7 +648,6 @@ static void mlx5e_build_rep_netdev(struct net_device *netdev,
        netdev->hw_features    |= NETIF_F_RXCSUM;
 
        netdev->features |= netdev->hw_features;
-       netdev->features |= NETIF_F_VLAN_CHALLENGED;
        netdev->features |= NETIF_F_NETNS_LOCAL;
 }
 
@@ -1169,7 +1172,7 @@ mlx5e_vport_vf_rep_load(struct mlx5_core_dev *dev, struct mlx5_eswitch_rep *rep)
        nch = mlx5e_get_max_num_channels(dev);
        txqs = nch * profile->max_tc;
        rxqs = nch * profile->rq_groups;
-       netdev = mlx5e_create_netdev(dev, txqs, rxqs);
+       netdev = mlx5e_create_netdev(dev, profile, txqs, rxqs);
        if (!netdev) {
                mlx5_core_warn(dev,
                               "Failed to create representor netdev for vport %d\n",
index 3c65fd0..29a6586 100644 (file)
@@ -1001,14 +1001,9 @@ static inline void mlx5e_handle_csum(struct net_device *netdev,
                goto csum_unnecessary;
 
        if (likely(is_last_ethertype_ip(skb, &network_depth, &proto))) {
-               u8 ipproto = get_ip_proto(skb, network_depth, proto);
-
-               if (unlikely(ipproto == IPPROTO_SCTP))
+               if (unlikely(get_ip_proto(skb, network_depth, proto) == IPPROTO_SCTP))
                        goto csum_unnecessary;
 
-               if (unlikely(mlx5_ipsec_is_rx_flow(cqe)))
-                       goto csum_none;
-
                stats->csum_complete++;
                skb->ip_summed = CHECKSUM_COMPLETE;
                skb->csum = csum_unfold((__force __sum16)cqe->check_sum);
index e4f5b63..e1dd170 100644 (file)
@@ -34,6 +34,7 @@
 #include "en.h"
 #include "en_accel/tls.h"
 #include "en_accel/en_accel.h"
+#include "en/ptp.h"
 
 static unsigned int stats_grps_num(struct mlx5e_priv *priv)
 {
@@ -450,7 +451,7 @@ static MLX5E_DECLARE_STATS_GRP_OP_UPDATE_STATS(sw)
 
        memset(s, 0, sizeof(*s));
 
-       for (i = 0; i < priv->max_nch; i++) {
+       for (i = 0; i < priv->stats_nch; i++) {
                struct mlx5e_channel_stats *channel_stats =
                        &priv->channel_stats[i];
                int j;
@@ -2076,7 +2077,7 @@ static MLX5E_DECLARE_STATS_GRP_OP_FILL_STRS(ptp)
        if (priv->rx_ptp_opened) {
                for (i = 0; i < NUM_PTP_RQ_STATS; i++)
                        sprintf(data + (idx++) * ETH_GSTRING_LEN,
-                               ptp_rq_stats_desc[i].format);
+                               ptp_rq_stats_desc[i].format, MLX5E_PTP_CHANNEL_IX);
        }
        return idx;
 }
@@ -2119,7 +2120,7 @@ static MLX5E_DECLARE_STATS_GRP_OP_UPDATE_STATS(ptp) { return; }
 
 static MLX5E_DECLARE_STATS_GRP_OP_NUM_STATS(channels)
 {
-       int max_nch = priv->max_nch;
+       int max_nch = priv->stats_nch;
 
        return (NUM_RQ_STATS * max_nch) +
               (NUM_CH_STATS * max_nch) +
@@ -2133,7 +2134,7 @@ static MLX5E_DECLARE_STATS_GRP_OP_NUM_STATS(channels)
 static MLX5E_DECLARE_STATS_GRP_OP_FILL_STRS(channels)
 {
        bool is_xsk = priv->xsk.ever_used;
-       int max_nch = priv->max_nch;
+       int max_nch = priv->stats_nch;
        int i, j, tc;
 
        for (i = 0; i < max_nch; i++)
@@ -2175,7 +2176,7 @@ static MLX5E_DECLARE_STATS_GRP_OP_FILL_STRS(channels)
 static MLX5E_DECLARE_STATS_GRP_OP_FILL_STATS(channels)
 {
        bool is_xsk = priv->xsk.ever_used;
-       int max_nch = priv->max_nch;
+       int max_nch = priv->stats_nch;
        int i, j, tc;
 
        for (i = 0; i < max_nch; i++)
index 0399a39..60a7399 100644 (file)
@@ -79,12 +79,16 @@ int esw_acl_egress_lgcy_setup(struct mlx5_eswitch *esw,
        int dest_num = 0;
        int err = 0;
 
-       if (MLX5_CAP_ESW_EGRESS_ACL(esw->dev, flow_counter)) {
+       if (vport->egress.legacy.drop_counter) {
+               drop_counter = vport->egress.legacy.drop_counter;
+       } else if (MLX5_CAP_ESW_EGRESS_ACL(esw->dev, flow_counter)) {
                drop_counter = mlx5_fc_create(esw->dev, false);
-               if (IS_ERR(drop_counter))
+               if (IS_ERR(drop_counter)) {
                        esw_warn(esw->dev,
                                 "vport[%d] configure egress drop rule counter err(%ld)\n",
                                 vport->vport, PTR_ERR(drop_counter));
+                       drop_counter = NULL;
+               }
                vport->egress.legacy.drop_counter = drop_counter;
        }
 
@@ -123,7 +127,7 @@ int esw_acl_egress_lgcy_setup(struct mlx5_eswitch *esw,
        flow_act.action = MLX5_FLOW_CONTEXT_ACTION_DROP;
 
        /* Attach egress drop flow counter */
-       if (!IS_ERR_OR_NULL(drop_counter)) {
+       if (drop_counter) {
                flow_act.action |= MLX5_FLOW_CONTEXT_ACTION_COUNT;
                drop_ctr_dst.type = MLX5_FLOW_DESTINATION_TYPE_COUNTER;
                drop_ctr_dst.counter_id = mlx5_fc_id(drop_counter);
@@ -162,7 +166,7 @@ void esw_acl_egress_lgcy_cleanup(struct mlx5_eswitch *esw,
        esw_acl_egress_table_destroy(vport);
 
 clean_drop_counter:
-       if (!IS_ERR_OR_NULL(vport->egress.legacy.drop_counter)) {
+       if (vport->egress.legacy.drop_counter) {
                mlx5_fc_destroy(esw->dev, vport->egress.legacy.drop_counter);
                vport->egress.legacy.drop_counter = NULL;
        }
index f75b86a..b1a5199 100644 (file)
@@ -160,7 +160,9 @@ int esw_acl_ingress_lgcy_setup(struct mlx5_eswitch *esw,
 
        esw_acl_ingress_lgcy_rules_destroy(vport);
 
-       if (MLX5_CAP_ESW_INGRESS_ACL(esw->dev, flow_counter)) {
+       if (vport->ingress.legacy.drop_counter) {
+               counter = vport->ingress.legacy.drop_counter;
+       } else if (MLX5_CAP_ESW_INGRESS_ACL(esw->dev, flow_counter)) {
                counter = mlx5_fc_create(esw->dev, false);
                if (IS_ERR(counter)) {
                        esw_warn(esw->dev,
index 67571e5..269ebb5 100644 (file)
@@ -113,7 +113,7 @@ static void mlx5i_grp_sw_update_stats(struct mlx5e_priv *priv)
        struct mlx5e_sw_stats s = { 0 };
        int i, j;
 
-       for (i = 0; i < priv->max_nch; i++) {
+       for (i = 0; i < priv->stats_nch; i++) {
                struct mlx5e_channel_stats *channel_stats;
                struct mlx5e_rq_stats *rq_stats;
 
@@ -711,7 +711,7 @@ static int mlx5_rdma_setup_rn(struct ib_device *ibdev, u32 port_num,
                        goto destroy_ht;
        }
 
-       err = mlx5e_priv_init(epriv, netdev, mdev);
+       err = mlx5e_priv_init(epriv, prof, netdev, mdev);
        if (err)
                goto destroy_mdev_resources;
 
index ffac8a0..91e806c 100644 (file)
@@ -448,22 +448,20 @@ static u64 find_target_cycles(struct mlx5_core_dev *mdev, s64 target_ns)
        return cycles_now + cycles_delta;
 }
 
-static u64 perout_conf_internal_timer(struct mlx5_core_dev *mdev,
-                                     s64 sec, u32 nsec)
+static u64 perout_conf_internal_timer(struct mlx5_core_dev *mdev, s64 sec)
 {
-       struct timespec64 ts;
+       struct timespec64 ts = {};
        s64 target_ns;
 
        ts.tv_sec = sec;
-       ts.tv_nsec = nsec;
        target_ns = timespec64_to_ns(&ts);
 
        return find_target_cycles(mdev, target_ns);
 }
 
-static u64 perout_conf_real_time(s64 sec, u32 nsec)
+static u64 perout_conf_real_time(s64 sec)
 {
-       return (u64)nsec | (u64)sec << 32;
+       return (u64)sec << 32;
 }
 
 static int mlx5_perout_configure(struct ptp_clock_info *ptp,
@@ -474,6 +472,7 @@ static int mlx5_perout_configure(struct ptp_clock_info *ptp,
                        container_of(ptp, struct mlx5_clock, ptp_info);
        struct mlx5_core_dev *mdev =
                        container_of(clock, struct mlx5_core_dev, clock);
+       bool rt_mode = mlx5_real_time_mode(mdev);
        u32 in[MLX5_ST_SZ_DW(mtpps_reg)] = {0};
        struct timespec64 ts;
        u32 field_select = 0;
@@ -501,8 +500,10 @@ static int mlx5_perout_configure(struct ptp_clock_info *ptp,
 
        if (on) {
                bool rt_mode = mlx5_real_time_mode(mdev);
-               u32 nsec;
-               s64 sec;
+               s64 sec = rq->perout.start.sec;
+
+               if (rq->perout.start.nsec)
+                       return -EINVAL;
 
                pin_mode = MLX5_PIN_MODE_OUT;
                pattern = MLX5_OUT_PATTERN_PERIODIC;
@@ -513,14 +514,11 @@ static int mlx5_perout_configure(struct ptp_clock_info *ptp,
                if ((ns >> 1) != 500000000LL)
                        return -EINVAL;
 
-               nsec = rq->perout.start.nsec;
-               sec = rq->perout.start.sec;
-
                if (rt_mode && sec > U32_MAX)
                        return -EINVAL;
 
-               time_stamp = rt_mode ? perout_conf_real_time(sec, nsec) :
-                                      perout_conf_internal_timer(mdev, sec, nsec);
+               time_stamp = rt_mode ? perout_conf_real_time(sec) :
+                                      perout_conf_internal_timer(mdev, sec);
 
                field_select |= MLX5_MTPPS_FS_PIN_MODE |
                                MLX5_MTPPS_FS_PATTERN |
@@ -538,6 +536,9 @@ static int mlx5_perout_configure(struct ptp_clock_info *ptp,
        if (err)
                return err;
 
+       if (rt_mode)
+               return 0;
+
        return mlx5_set_mtppse(mdev, pin, 0,
                               MLX5_EVENT_MODE_REPETETIVE & on);
 }
@@ -705,20 +706,14 @@ static void ts_next_sec(struct timespec64 *ts)
 static u64 perout_conf_next_event_timer(struct mlx5_core_dev *mdev,
                                        struct mlx5_clock *clock)
 {
-       bool rt_mode = mlx5_real_time_mode(mdev);
        struct timespec64 ts;
        s64 target_ns;
 
-       if (rt_mode)
-               ts = mlx5_ptp_gettimex_real_time(mdev, NULL);
-       else
-               mlx5_ptp_gettimex(&clock->ptp_info, &ts, NULL);
-
+       mlx5_ptp_gettimex(&clock->ptp_info, &ts, NULL);
        ts_next_sec(&ts);
        target_ns = timespec64_to_ns(&ts);
 
-       return rt_mode ? perout_conf_real_time(ts.tv_sec, ts.tv_nsec) :
-                        find_target_cycles(mdev, target_ns);
+       return find_target_cycles(mdev, target_ns);
 }
 
 static int mlx5_pps_event(struct notifier_block *nb,
index c79a10b..763c83a 100644 (file)
@@ -13,8 +13,8 @@
 #endif
 
 #define MLX5_MAX_IRQ_NAME (32)
-/* max irq_index is 255. three chars */
-#define MLX5_MAX_IRQ_IDX_CHARS (3)
+/* max irq_index is 2047, so four chars */
+#define MLX5_MAX_IRQ_IDX_CHARS (4)
 
 #define MLX5_SFS_PER_CTRL_IRQ 64
 #define MLX5_IRQ_CTRL_SF_MAX 8
@@ -633,8 +633,9 @@ void mlx5_irq_table_destroy(struct mlx5_core_dev *dev)
 int mlx5_irq_table_get_sfs_vec(struct mlx5_irq_table *table)
 {
        if (table->sf_comp_pool)
-               return table->sf_comp_pool->xa_num_irqs.max -
-                       table->sf_comp_pool->xa_num_irqs.min + 1;
+               return min_t(int, num_online_cpus(),
+                            table->sf_comp_pool->xa_num_irqs.max -
+                            table->sf_comp_pool->xa_num_irqs.min + 1);
        else
                return mlx5_irq_table_get_num_comp(table);
 }
index 0998dcc..b298244 100644 (file)
 #define MLXSW_THERMAL_ZONE_MAX_NAME    16
 #define MLXSW_THERMAL_TEMP_SCORE_MAX   GENMASK(31, 0)
 #define MLXSW_THERMAL_MAX_STATE        10
+#define MLXSW_THERMAL_MIN_STATE        2
 #define MLXSW_THERMAL_MAX_DUTY 255
-/* Minimum and maximum fan allowed speed in percent: from 20% to 100%. Values
- * MLXSW_THERMAL_MAX_STATE + x, where x is between 2 and 10 are used for
- * setting fan speed dynamic minimum. For example, if value is set to 14 (40%)
- * cooling levels vector will be set to 4, 4, 4, 4, 4, 5, 6, 7, 8, 9, 10 to
- * introduce PWM speed in percent: 40, 40, 40, 40, 40, 50, 60. 70, 80, 90, 100.
- */
-#define MLXSW_THERMAL_SPEED_MIN                (MLXSW_THERMAL_MAX_STATE + 2)
-#define MLXSW_THERMAL_SPEED_MAX                (MLXSW_THERMAL_MAX_STATE * 2)
-#define MLXSW_THERMAL_SPEED_MIN_LEVEL  2               /* 20% */
 
 /* External cooling devices, allowed for binding to mlxsw thermal zones. */
 static char * const mlxsw_thermal_external_allowed_cdev[] = {
@@ -646,49 +638,16 @@ static int mlxsw_thermal_set_cur_state(struct thermal_cooling_device *cdev,
        struct mlxsw_thermal *thermal = cdev->devdata;
        struct device *dev = thermal->bus_info->dev;
        char mfsc_pl[MLXSW_REG_MFSC_LEN];
-       unsigned long cur_state, i;
        int idx;
-       u8 duty;
        int err;
 
+       if (state > MLXSW_THERMAL_MAX_STATE)
+               return -EINVAL;
+
        idx = mlxsw_get_cooling_device_idx(thermal, cdev);
        if (idx < 0)
                return idx;
 
-       /* Verify if this request is for changing allowed fan dynamical
-        * minimum. If it is - update cooling levels accordingly and update
-        * state, if current state is below the newly requested minimum state.
-        * For example, if current state is 5, and minimal state is to be
-        * changed from 4 to 6, thermal->cooling_levels[0 to 5] will be changed
-        * all from 4 to 6. And state 5 (thermal->cooling_levels[4]) should be
-        * overwritten.
-        */
-       if (state >= MLXSW_THERMAL_SPEED_MIN &&
-           state <= MLXSW_THERMAL_SPEED_MAX) {
-               state -= MLXSW_THERMAL_MAX_STATE;
-               for (i = 0; i <= MLXSW_THERMAL_MAX_STATE; i++)
-                       thermal->cooling_levels[i] = max(state, i);
-
-               mlxsw_reg_mfsc_pack(mfsc_pl, idx, 0);
-               err = mlxsw_reg_query(thermal->core, MLXSW_REG(mfsc), mfsc_pl);
-               if (err)
-                       return err;
-
-               duty = mlxsw_reg_mfsc_pwm_duty_cycle_get(mfsc_pl);
-               cur_state = mlxsw_duty_to_state(duty);
-
-               /* If current fan state is lower than requested dynamical
-                * minimum, increase fan speed up to dynamical minimum.
-                */
-               if (state < cur_state)
-                       return 0;
-
-               state = cur_state;
-       }
-
-       if (state > MLXSW_THERMAL_MAX_STATE)
-               return -EINVAL;
-
        /* Normalize the state to the valid speed range. */
        state = thermal->cooling_levels[state];
        mlxsw_reg_mfsc_pack(mfsc_pl, idx, mlxsw_state_to_duty(state));
@@ -998,8 +957,7 @@ int mlxsw_thermal_init(struct mlxsw_core *core,
 
        /* Initialize cooling levels per PWM state. */
        for (i = 0; i < MLXSW_THERMAL_MAX_STATE; i++)
-               thermal->cooling_levels[i] = max(MLXSW_THERMAL_SPEED_MIN_LEVEL,
-                                                i);
+               thermal->cooling_levels[i] = max(MLXSW_THERMAL_MIN_STATE, i);
 
        thermal->polling_delay = bus_info->low_frequency ?
                                 MLXSW_THERMAL_SLOW_POLL_INT :
index 796e46a..81a8ccc 100644 (file)
@@ -497,13 +497,19 @@ static struct regmap_bus phymap_encx24j600 = {
        .reg_read = regmap_encx24j600_phy_reg_read,
 };
 
-void devm_regmap_init_encx24j600(struct device *dev,
-                                struct encx24j600_context *ctx)
+int devm_regmap_init_encx24j600(struct device *dev,
+                               struct encx24j600_context *ctx)
 {
        mutex_init(&ctx->mutex);
        regcfg.lock_arg = ctx;
        ctx->regmap = devm_regmap_init(dev, &regmap_encx24j600, ctx, &regcfg);
+       if (IS_ERR(ctx->regmap))
+               return PTR_ERR(ctx->regmap);
        ctx->phymap = devm_regmap_init(dev, &phymap_encx24j600, ctx, &phycfg);
+       if (IS_ERR(ctx->phymap))
+               return PTR_ERR(ctx->phymap);
+
+       return 0;
 }
 EXPORT_SYMBOL_GPL(devm_regmap_init_encx24j600);
 
index ee921a9..0bc6b31 100644 (file)
@@ -1023,10 +1023,13 @@ static int encx24j600_spi_probe(struct spi_device *spi)
        priv->speed = SPEED_100;
 
        priv->ctx.spi = spi;
-       devm_regmap_init_encx24j600(&spi->dev, &priv->ctx);
        ndev->irq = spi->irq;
        ndev->netdev_ops = &encx24j600_netdev_ops;
 
+       ret = devm_regmap_init_encx24j600(&spi->dev, &priv->ctx);
+       if (ret)
+               goto out_free;
+
        mutex_init(&priv->lock);
 
        /* Reset device and check if it is connected */
index fac61a8..34c5a28 100644 (file)
@@ -15,8 +15,8 @@ struct encx24j600_context {
        int bank;
 };
 
-void devm_regmap_init_encx24j600(struct device *dev,
-                                struct encx24j600_context *ctx);
+int devm_regmap_init_encx24j600(struct device *dev,
+                               struct encx24j600_context *ctx);
 
 /* Single-byte instructions */
 #define BANK_SELECT(bank) (0xC0 | ((bank & (BANK_MASK >> BANK_SHIFT)) << 1))
index 1b21030..030ae89 100644 (file)
@@ -1477,8 +1477,10 @@ static struct mana_rxq *mana_create_rxq(struct mana_port_context *apc,
        if (err)
                goto out;
 
-       if (cq->gdma_id >= gc->max_num_cqs)
+       if (WARN_ON(cq->gdma_id >= gc->max_num_cqs)) {
+               err = -EINVAL;
                goto out;
+       }
 
        gc->cq_table[cq->gdma_id] = cq->gdma_cq;
 
index 559177e..a08e4f5 100644 (file)
@@ -472,9 +472,9 @@ void ocelot_phylink_mac_link_down(struct ocelot *ocelot, int port,
            !(quirks & OCELOT_QUIRK_QSGMII_PORTS_MUST_BE_UP))
                ocelot_port_rmwl(ocelot_port,
                                 DEV_CLOCK_CFG_MAC_TX_RST |
-                                DEV_CLOCK_CFG_MAC_TX_RST,
+                                DEV_CLOCK_CFG_MAC_RX_RST,
                                 DEV_CLOCK_CFG_MAC_TX_RST |
-                                DEV_CLOCK_CFG_MAC_TX_RST,
+                                DEV_CLOCK_CFG_MAC_RX_RST,
                                 DEV_CLOCK_CFG);
 }
 EXPORT_SYMBOL_GPL(ocelot_phylink_mac_link_down);
@@ -569,49 +569,44 @@ void ocelot_phylink_mac_link_up(struct ocelot *ocelot, int port,
 }
 EXPORT_SYMBOL_GPL(ocelot_phylink_mac_link_up);
 
-static void ocelot_port_add_txtstamp_skb(struct ocelot *ocelot, int port,
-                                        struct sk_buff *clone)
+static int ocelot_port_add_txtstamp_skb(struct ocelot *ocelot, int port,
+                                       struct sk_buff *clone)
 {
        struct ocelot_port *ocelot_port = ocelot->ports[port];
+       unsigned long flags;
+
+       spin_lock_irqsave(&ocelot->ts_id_lock, flags);
 
-       spin_lock(&ocelot_port->ts_id_lock);
+       if (ocelot_port->ptp_skbs_in_flight == OCELOT_MAX_PTP_ID ||
+           ocelot->ptp_skbs_in_flight == OCELOT_PTP_FIFO_SIZE) {
+               spin_unlock_irqrestore(&ocelot->ts_id_lock, flags);
+               return -EBUSY;
+       }
 
        skb_shinfo(clone)->tx_flags |= SKBTX_IN_PROGRESS;
        /* Store timestamp ID in OCELOT_SKB_CB(clone)->ts_id */
        OCELOT_SKB_CB(clone)->ts_id = ocelot_port->ts_id;
-       ocelot_port->ts_id = (ocelot_port->ts_id + 1) % 4;
-       skb_queue_tail(&ocelot_port->tx_skbs, clone);
 
-       spin_unlock(&ocelot_port->ts_id_lock);
-}
+       ocelot_port->ts_id++;
+       if (ocelot_port->ts_id == OCELOT_MAX_PTP_ID)
+               ocelot_port->ts_id = 0;
 
-u32 ocelot_ptp_rew_op(struct sk_buff *skb)
-{
-       struct sk_buff *clone = OCELOT_SKB_CB(skb)->clone;
-       u8 ptp_cmd = OCELOT_SKB_CB(skb)->ptp_cmd;
-       u32 rew_op = 0;
+       ocelot_port->ptp_skbs_in_flight++;
+       ocelot->ptp_skbs_in_flight++;
 
-       if (ptp_cmd == IFH_REW_OP_TWO_STEP_PTP && clone) {
-               rew_op = ptp_cmd;
-               rew_op |= OCELOT_SKB_CB(clone)->ts_id << 3;
-       } else if (ptp_cmd == IFH_REW_OP_ORIGIN_PTP) {
-               rew_op = ptp_cmd;
-       }
+       skb_queue_tail(&ocelot_port->tx_skbs, clone);
 
-       return rew_op;
+       spin_unlock_irqrestore(&ocelot->ts_id_lock, flags);
+
+       return 0;
 }
-EXPORT_SYMBOL(ocelot_ptp_rew_op);
 
-static bool ocelot_ptp_is_onestep_sync(struct sk_buff *skb)
+static bool ocelot_ptp_is_onestep_sync(struct sk_buff *skb,
+                                      unsigned int ptp_class)
 {
        struct ptp_header *hdr;
-       unsigned int ptp_class;
        u8 msgtype, twostep;
 
-       ptp_class = ptp_classify_raw(skb);
-       if (ptp_class == PTP_CLASS_NONE)
-               return false;
-
        hdr = ptp_parse_header(skb, ptp_class);
        if (!hdr)
                return false;
@@ -631,10 +626,20 @@ int ocelot_port_txtstamp_request(struct ocelot *ocelot, int port,
 {
        struct ocelot_port *ocelot_port = ocelot->ports[port];
        u8 ptp_cmd = ocelot_port->ptp_cmd;
+       unsigned int ptp_class;
+       int err;
+
+       /* Don't do anything if PTP timestamping not enabled */
+       if (!ptp_cmd)
+               return 0;
+
+       ptp_class = ptp_classify_raw(skb);
+       if (ptp_class == PTP_CLASS_NONE)
+               return -EINVAL;
 
        /* Store ptp_cmd in OCELOT_SKB_CB(skb)->ptp_cmd */
        if (ptp_cmd == IFH_REW_OP_ORIGIN_PTP) {
-               if (ocelot_ptp_is_onestep_sync(skb)) {
+               if (ocelot_ptp_is_onestep_sync(skb, ptp_class)) {
                        OCELOT_SKB_CB(skb)->ptp_cmd = ptp_cmd;
                        return 0;
                }
@@ -648,8 +653,12 @@ int ocelot_port_txtstamp_request(struct ocelot *ocelot, int port,
                if (!(*clone))
                        return -ENOMEM;
 
-               ocelot_port_add_txtstamp_skb(ocelot, port, *clone);
+               err = ocelot_port_add_txtstamp_skb(ocelot, port, *clone);
+               if (err)
+                       return err;
+
                OCELOT_SKB_CB(skb)->ptp_cmd = ptp_cmd;
+               OCELOT_SKB_CB(*clone)->ptp_class = ptp_class;
        }
 
        return 0;
@@ -683,6 +692,17 @@ static void ocelot_get_hwtimestamp(struct ocelot *ocelot,
        spin_unlock_irqrestore(&ocelot->ptp_clock_lock, flags);
 }
 
+static bool ocelot_validate_ptp_skb(struct sk_buff *clone, u16 seqid)
+{
+       struct ptp_header *hdr;
+
+       hdr = ptp_parse_header(clone, OCELOT_SKB_CB(clone)->ptp_class);
+       if (WARN_ON(!hdr))
+               return false;
+
+       return seqid == ntohs(hdr->sequence_id);
+}
+
 void ocelot_get_txtstamp(struct ocelot *ocelot)
 {
        int budget = OCELOT_PTP_QUEUE_SZ;
@@ -690,10 +710,10 @@ void ocelot_get_txtstamp(struct ocelot *ocelot)
        while (budget--) {
                struct sk_buff *skb, *skb_tmp, *skb_match = NULL;
                struct skb_shared_hwtstamps shhwtstamps;
+               u32 val, id, seqid, txport;
                struct ocelot_port *port;
                struct timespec64 ts;
                unsigned long flags;
-               u32 val, id, txport;
 
                val = ocelot_read(ocelot, SYS_PTP_STATUS);
 
@@ -706,10 +726,17 @@ void ocelot_get_txtstamp(struct ocelot *ocelot)
                /* Retrieve the ts ID and Tx port */
                id = SYS_PTP_STATUS_PTP_MESS_ID_X(val);
                txport = SYS_PTP_STATUS_PTP_MESS_TXPORT_X(val);
+               seqid = SYS_PTP_STATUS_PTP_MESS_SEQ_ID(val);
 
-               /* Retrieve its associated skb */
                port = ocelot->ports[txport];
 
+               spin_lock(&ocelot->ts_id_lock);
+               port->ptp_skbs_in_flight--;
+               ocelot->ptp_skbs_in_flight--;
+               spin_unlock(&ocelot->ts_id_lock);
+
+               /* Retrieve its associated skb */
+try_again:
                spin_lock_irqsave(&port->tx_skbs.lock, flags);
 
                skb_queue_walk_safe(&port->tx_skbs, skb, skb_tmp) {
@@ -722,12 +749,20 @@ void ocelot_get_txtstamp(struct ocelot *ocelot)
 
                spin_unlock_irqrestore(&port->tx_skbs.lock, flags);
 
+               if (WARN_ON(!skb_match))
+                       continue;
+
+               if (!ocelot_validate_ptp_skb(skb_match, seqid)) {
+                       dev_err_ratelimited(ocelot->dev,
+                                           "port %d received stale TX timestamp for seqid %d, discarding\n",
+                                           txport, seqid);
+                       dev_kfree_skb_any(skb);
+                       goto try_again;
+               }
+
                /* Get the h/w timestamp */
                ocelot_get_hwtimestamp(ocelot, &ts);
 
-               if (unlikely(!skb_match))
-                       continue;
-
                /* Set the timestamp into the skb */
                memset(&shhwtstamps, 0, sizeof(shhwtstamps));
                shhwtstamps.hwtstamp = ktime_set(ts.tv_sec, ts.tv_nsec);
@@ -1948,7 +1983,6 @@ void ocelot_init_port(struct ocelot *ocelot, int port)
        struct ocelot_port *ocelot_port = ocelot->ports[port];
 
        skb_queue_head_init(&ocelot_port->tx_skbs);
-       spin_lock_init(&ocelot_port->ts_id_lock);
 
        /* Basic L2 initialization */
 
@@ -2081,6 +2115,7 @@ int ocelot_init(struct ocelot *ocelot)
        mutex_init(&ocelot->stats_lock);
        mutex_init(&ocelot->ptp_lock);
        spin_lock_init(&ocelot->ptp_clock_lock);
+       spin_lock_init(&ocelot->ts_id_lock);
        snprintf(queue_name, sizeof(queue_name), "%s-stats",
                 dev_name(ocelot->dev));
        ocelot->stats_queue = create_singlethread_workqueue(queue_name);
index e54b9fb..2545727 100644 (file)
@@ -8,6 +8,7 @@
  * Copyright 2020-2021 NXP
  */
 
+#include <linux/dsa/ocelot.h>
 #include <linux/if_bridge.h>
 #include <linux/of_net.h>
 #include <linux/phy/phy.h>
@@ -1625,7 +1626,7 @@ static int ocelot_port_phylink_create(struct ocelot *ocelot, int port,
        if (phy_mode == PHY_INTERFACE_MODE_QSGMII)
                ocelot_port_rmwl(ocelot_port, 0,
                                 DEV_CLOCK_CFG_MAC_TX_RST |
-                                DEV_CLOCK_CFG_MAC_TX_RST,
+                                DEV_CLOCK_CFG_MAC_RX_RST,
                                 DEV_CLOCK_CFG);
 
        ocelot_port->phy_mode = phy_mode;
index 7945393..99d7376 100644 (file)
@@ -998,8 +998,8 @@ ocelot_vcap_block_find_filter_by_index(struct ocelot_vcap_block *block,
 }
 
 struct ocelot_vcap_filter *
-ocelot_vcap_block_find_filter_by_id(struct ocelot_vcap_block *block, int cookie,
-                                   bool tc_offload)
+ocelot_vcap_block_find_filter_by_id(struct ocelot_vcap_block *block,
+                                   unsigned long cookie, bool tc_offload)
 {
        struct ocelot_vcap_filter *filter;
 
index 09c0e83..3b6b2e6 100644 (file)
@@ -8566,7 +8566,7 @@ static void s2io_io_resume(struct pci_dev *pdev)
                        return;
                }
 
-               if (s2io_set_mac_addr(netdev, netdev->dev_addr) == FAILURE) {
+               if (do_s2io_prog_unicast(netdev, netdev->dev_addr) == FAILURE) {
                        s2io_card_down(sp);
                        pr_err("Can't restore mac addr after reset.\n");
                        return;
index c029950..ac1dcfa 100644 (file)
@@ -830,10 +830,6 @@ static int nfp_flower_init(struct nfp_app *app)
        if (err)
                goto err_cleanup;
 
-       err = flow_indr_dev_register(nfp_flower_indr_setup_tc_cb, app);
-       if (err)
-               goto err_cleanup;
-
        if (app_priv->flower_ext_feats & NFP_FL_FEATS_VF_RLIM)
                nfp_flower_qos_init(app);
 
@@ -942,7 +938,20 @@ static int nfp_flower_start(struct nfp_app *app)
                        return err;
        }
 
-       return nfp_tunnel_config_start(app);
+       err = flow_indr_dev_register(nfp_flower_indr_setup_tc_cb, app);
+       if (err)
+               return err;
+
+       err = nfp_tunnel_config_start(app);
+       if (err)
+               goto err_tunnel_config;
+
+       return 0;
+
+err_tunnel_config:
+       flow_indr_dev_unregister(nfp_flower_indr_setup_tc_cb, app,
+                                nfp_flower_setup_indr_tc_release);
+       return err;
 }
 
 static void nfp_flower_stop(struct nfp_app *app)
index 381966e..7f3322c 100644 (file)
@@ -1292,8 +1292,10 @@ int ionic_lif_addr_add(struct ionic_lif *lif, const u8 *addr)
        if (err && err != -EEXIST) {
                /* set the state back to NEW so we can try again later */
                f = ionic_rx_filter_by_addr(lif, addr);
-               if (f && f->state == IONIC_FILTER_STATE_SYNCED)
+               if (f && f->state == IONIC_FILTER_STATE_SYNCED) {
                        f->state = IONIC_FILTER_STATE_NEW;
+                       set_bit(IONIC_LIF_F_FILTER_SYNC_NEEDED, lif->state);
+               }
 
                spin_unlock_bh(&lif->rx_filters.lock);
 
@@ -1377,6 +1379,10 @@ static int ionic_addr_add(struct net_device *netdev, const u8 *addr)
 
 static int ionic_addr_del(struct net_device *netdev, const u8 *addr)
 {
+       /* Don't delete our own address from the uc list */
+       if (ether_addr_equal(addr, netdev->dev_addr))
+               return 0;
+
        return ionic_lif_list_addr(netdev_priv(netdev), addr, DEL_ADDR);
 }
 
index 25ecfcf..69728f9 100644 (file)
@@ -349,9 +349,6 @@ loop_out:
        list_for_each_entry_safe(sync_item, spos, &sync_add_list, list) {
                (void)ionic_lif_addr_add(lif, sync_item->f.cmd.mac.addr);
 
-               if (sync_item->f.state != IONIC_FILTER_STATE_SYNCED)
-                       set_bit(IONIC_LIF_F_FILTER_SYNC_NEEDED, lif->state);
-
                list_del(&sync_item->list);
                devm_kfree(dev, sync_item);
        }
index 15ef59a..d10e1cd 100644 (file)
@@ -1299,6 +1299,7 @@ static int qed_slowpath_start(struct qed_dev *cdev,
                        } else {
                                DP_NOTICE(cdev,
                                          "Failed to acquire PTT for aRFS\n");
+                               rc = -EINVAL;
                                goto err;
                        }
                }
index fbfda55..5e731a7 100644 (file)
@@ -71,6 +71,7 @@ err_remove_config_dt:
 
 static const struct of_device_id dwmac_generic_match[] = {
        { .compatible = "st,spear600-gmac"},
+       { .compatible = "snps,dwmac-3.40a"},
        { .compatible = "snps,dwmac-3.50a"},
        { .compatible = "snps,dwmac-3.610"},
        { .compatible = "snps,dwmac-3.70a"},
index ed81701..6924a6a 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/delay.h>
 #include <linux/mfd/syscon.h>
 #include <linux/regmap.h>
+#include <linux/pm_runtime.h>
 
 #include "stmmac_platform.h"
 
@@ -1528,6 +1529,8 @@ static int rk_gmac_powerup(struct rk_priv_data *bsp_priv)
                return ret;
        }
 
+       pm_runtime_get_sync(dev);
+
        if (bsp_priv->integrated_phy)
                rk_gmac_integrated_phy_powerup(bsp_priv);
 
@@ -1539,6 +1542,8 @@ static void rk_gmac_powerdown(struct rk_priv_data *gmac)
        if (gmac->integrated_phy)
                rk_gmac_integrated_phy_powerdown(gmac);
 
+       pm_runtime_put_sync(&gmac->pdev->dev);
+
        phy_power_on(gmac, false);
        gmac_clk_enable(gmac, false);
 }
index 90383ab..f5581db 100644 (file)
@@ -218,11 +218,18 @@ static void dwmac1000_dump_dma_regs(void __iomem *ioaddr, u32 *reg_space)
                                readl(ioaddr + DMA_BUS_MODE + i * 4);
 }
 
-static void dwmac1000_get_hw_feature(void __iomem *ioaddr,
-                                    struct dma_features *dma_cap)
+static int dwmac1000_get_hw_feature(void __iomem *ioaddr,
+                                   struct dma_features *dma_cap)
 {
        u32 hw_cap = readl(ioaddr + DMA_HW_FEATURE);
 
+       if (!hw_cap) {
+               /* 0x00000000 is the value read on old hardware that does not
+                * implement this register
+                */
+               return -EOPNOTSUPP;
+       }
+
        dma_cap->mbps_10_100 = (hw_cap & DMA_HW_FEAT_MIISEL);
        dma_cap->mbps_1000 = (hw_cap & DMA_HW_FEAT_GMIISEL) >> 1;
        dma_cap->half_duplex = (hw_cap & DMA_HW_FEAT_HDSEL) >> 2;
@@ -252,6 +259,8 @@ static void dwmac1000_get_hw_feature(void __iomem *ioaddr,
        dma_cap->number_tx_channel = (hw_cap & DMA_HW_FEAT_TXCHCNT) >> 22;
        /* Alternate (enhanced) DESC mode */
        dma_cap->enh_desc = (hw_cap & DMA_HW_FEAT_ENHDESSEL) >> 24;
+
+       return 0;
 }
 
 static void dwmac1000_rx_watchdog(void __iomem *ioaddr, u32 riwt,
index 5be8e6a..d99fa02 100644 (file)
@@ -347,8 +347,8 @@ static void dwmac4_dma_tx_chan_op_mode(void __iomem *ioaddr, int mode,
        writel(mtl_tx_op, ioaddr +  MTL_CHAN_TX_OP_MODE(channel));
 }
 
-static void dwmac4_get_hw_feature(void __iomem *ioaddr,
-                                 struct dma_features *dma_cap)
+static int dwmac4_get_hw_feature(void __iomem *ioaddr,
+                                struct dma_features *dma_cap)
 {
        u32 hw_cap = readl(ioaddr + GMAC_HW_FEATURE0);
 
@@ -437,6 +437,8 @@ static void dwmac4_get_hw_feature(void __iomem *ioaddr,
        dma_cap->frpbs = (hw_cap & GMAC_HW_FEAT_FRPBS) >> 11;
        dma_cap->frpsel = (hw_cap & GMAC_HW_FEAT_FRPSEL) >> 10;
        dma_cap->dvlan = (hw_cap & GMAC_HW_FEAT_DVLAN) >> 5;
+
+       return 0;
 }
 
 /* Enable/disable TSO feature and set MSS */
index 906e985..5e98355 100644 (file)
@@ -371,8 +371,8 @@ static int dwxgmac2_dma_interrupt(void __iomem *ioaddr,
        return ret;
 }
 
-static void dwxgmac2_get_hw_feature(void __iomem *ioaddr,
-                                   struct dma_features *dma_cap)
+static int dwxgmac2_get_hw_feature(void __iomem *ioaddr,
+                                  struct dma_features *dma_cap)
 {
        u32 hw_cap;
 
@@ -445,6 +445,8 @@ static void dwxgmac2_get_hw_feature(void __iomem *ioaddr,
        dma_cap->frpes = (hw_cap & XGMAC_HWFEAT_FRPES) >> 11;
        dma_cap->frpbs = (hw_cap & XGMAC_HWFEAT_FRPPB) >> 9;
        dma_cap->frpsel = (hw_cap & XGMAC_HWFEAT_FRPSEL) >> 3;
+
+       return 0;
 }
 
 static void dwxgmac2_rx_watchdog(void __iomem *ioaddr, u32 riwt, u32 queue)
index 6dc1c98..fe2660d 100644 (file)
@@ -203,8 +203,8 @@ struct stmmac_dma_ops {
        int (*dma_interrupt) (void __iomem *ioaddr,
                              struct stmmac_extra_stats *x, u32 chan, u32 dir);
        /* If supported then get the optional core features */
-       void (*get_hw_feature)(void __iomem *ioaddr,
-                              struct dma_features *dma_cap);
+       int (*get_hw_feature)(void __iomem *ioaddr,
+                             struct dma_features *dma_cap);
        /* Program the HW RX Watchdog */
        void (*rx_watchdog)(void __iomem *ioaddr, u32 riwt, u32 queue);
        void (*set_tx_ring_len)(void __iomem *ioaddr, u32 len, u32 chan);
@@ -255,7 +255,7 @@ struct stmmac_dma_ops {
 #define stmmac_dma_interrupt_status(__priv, __args...) \
        stmmac_do_callback(__priv, dma, dma_interrupt, __args)
 #define stmmac_get_hw_feature(__priv, __args...) \
-       stmmac_do_void_callback(__priv, dma, get_hw_feature, __args)
+       stmmac_do_callback(__priv, dma, get_hw_feature, __args)
 #define stmmac_rx_watchdog(__priv, __args...) \
        stmmac_do_void_callback(__priv, dma, rx_watchdog, __args)
 #define stmmac_set_tx_ring_len(__priv, __args...) \
index 981ccf4..eb3b7bf 100644 (file)
@@ -477,6 +477,10 @@ bool stmmac_eee_init(struct stmmac_priv *priv)
                        stmmac_lpi_entry_timer_config(priv, 0);
                        del_timer_sync(&priv->eee_ctrl_timer);
                        stmmac_set_eee_timer(priv, priv->hw, 0, eee_tw_timer);
+                       if (priv->hw->xpcs)
+                               xpcs_config_eee(priv->hw->xpcs,
+                                               priv->plat->mult_fact_100ns,
+                                               false);
                }
                mutex_unlock(&priv->lock);
                return false;
@@ -1038,7 +1042,7 @@ static void stmmac_mac_link_down(struct phylink_config *config,
        stmmac_mac_set(priv, priv->ioaddr, false);
        priv->eee_active = false;
        priv->tx_lpi_enabled = false;
-       stmmac_eee_init(priv);
+       priv->eee_enabled = stmmac_eee_init(priv);
        stmmac_set_eee_pls(priv, priv->hw, false);
 
        if (priv->dma_cap.fpesel)
index 62cec9b..232ac98 100644 (file)
@@ -508,6 +508,14 @@ stmmac_probe_config_dt(struct platform_device *pdev, u8 *mac)
                plat->pmt = 1;
        }
 
+       if (of_device_is_compatible(np, "snps,dwmac-3.40a")) {
+               plat->has_gmac = 1;
+               plat->enh_desc = 1;
+               plat->tx_coe = 1;
+               plat->bugged_jumbo = 1;
+               plat->pmt = 1;
+       }
+
        if (of_device_is_compatible(np, "snps,dwmac-4.00") ||
            of_device_is_compatible(np, "snps,dwmac-4.10a") ||
            of_device_is_compatible(np, "snps,dwmac-4.20a") ||
index 8f99cfa..d037682 100644 (file)
@@ -4,6 +4,7 @@ config QCOM_IPA
        depends on ARCH_QCOM || COMPILE_TEST
        depends on QCOM_RPROC_COMMON || (QCOM_RPROC_COMMON=n && COMPILE_TEST)
        select QCOM_MDT_LOADER if ARCH_QCOM
+       select QCOM_SCM
        select QCOM_QMI_HELPERS
        help
          Choose Y or M here to include support for the Qualcomm
index fb0a83d..7de631f 100644 (file)
@@ -666,6 +666,10 @@ int xpcs_config_eee(struct dw_xpcs *xpcs, int mult_fact_100ns, int enable)
 {
        int ret;
 
+       ret = xpcs_read(xpcs, MDIO_MMD_VEND2, DW_VR_MII_EEE_MCTRL0);
+       if (ret < 0)
+               return ret;
+
        if (enable) {
        /* Enable EEE */
                ret = DW_VR_MII_EEE_LTX_EN | DW_VR_MII_EEE_LRX_EN |
@@ -673,9 +677,6 @@ int xpcs_config_eee(struct dw_xpcs *xpcs, int mult_fact_100ns, int enable)
                      DW_VR_MII_EEE_TX_EN_CTRL | DW_VR_MII_EEE_RX_EN_CTRL |
                      mult_fact_100ns << DW_VR_MII_EEE_MULT_FACT_100NS_SHIFT;
        } else {
-               ret = xpcs_read(xpcs, MDIO_MMD_VEND2, DW_VR_MII_EEE_MCTRL0);
-               if (ret < 0)
-                       return ret;
                ret &= ~(DW_VR_MII_EEE_LTX_EN | DW_VR_MII_EEE_LRX_EN |
                       DW_VR_MII_EEE_TX_QUIET_EN | DW_VR_MII_EEE_RX_QUIET_EN |
                       DW_VR_MII_EEE_TX_EN_CTRL | DW_VR_MII_EEE_RX_EN_CTRL |
@@ -690,21 +691,28 @@ int xpcs_config_eee(struct dw_xpcs *xpcs, int mult_fact_100ns, int enable)
        if (ret < 0)
                return ret;
 
-       ret |= DW_VR_MII_EEE_TRN_LPI;
+       if (enable)
+               ret |= DW_VR_MII_EEE_TRN_LPI;
+       else
+               ret &= ~DW_VR_MII_EEE_TRN_LPI;
+
        return xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_EEE_MCTRL1, ret);
 }
 EXPORT_SYMBOL_GPL(xpcs_config_eee);
 
 static int xpcs_config_aneg_c37_sgmii(struct dw_xpcs *xpcs, unsigned int mode)
 {
-       int ret;
+       int ret, mdio_ctrl;
 
        /* For AN for C37 SGMII mode, the settings are :-
-        * 1) VR_MII_AN_CTRL Bit(2:1)[PCS_MODE] = 10b (SGMII AN)
-        * 2) VR_MII_AN_CTRL Bit(3) [TX_CONFIG] = 0b (MAC side SGMII)
+        * 1) VR_MII_MMD_CTRL Bit(12) [AN_ENABLE] = 0b (Disable SGMII AN in case
+             it is already enabled)
+        * 2) VR_MII_AN_CTRL Bit(2:1)[PCS_MODE] = 10b (SGMII AN)
+        * 3) VR_MII_AN_CTRL Bit(3) [TX_CONFIG] = 0b (MAC side SGMII)
         *    DW xPCS used with DW EQoS MAC is always MAC side SGMII.
-        * 3) VR_MII_DIG_CTRL1 Bit(9) [MAC_AUTO_SW] = 1b (Automatic
+        * 4) VR_MII_DIG_CTRL1 Bit(9) [MAC_AUTO_SW] = 1b (Automatic
         *    speed/duplex mode change by HW after SGMII AN complete)
+        * 5) VR_MII_MMD_CTRL Bit(12) [AN_ENABLE] = 1b (Enable SGMII AN)
         *
         * Note: Since it is MAC side SGMII, there is no need to set
         *       SR_MII_AN_ADV. MAC side SGMII receives AN Tx Config from
@@ -712,6 +720,17 @@ static int xpcs_config_aneg_c37_sgmii(struct dw_xpcs *xpcs, unsigned int mode)
         *       between PHY and Link Partner. There is also no need to
         *       trigger AN restart for MAC-side SGMII.
         */
+       mdio_ctrl = xpcs_read(xpcs, MDIO_MMD_VEND2, DW_VR_MII_MMD_CTRL);
+       if (mdio_ctrl < 0)
+               return mdio_ctrl;
+
+       if (mdio_ctrl & AN_CL37_EN) {
+               ret = xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_MMD_CTRL,
+                                mdio_ctrl & ~AN_CL37_EN);
+               if (ret < 0)
+                       return ret;
+       }
+
        ret = xpcs_read(xpcs, MDIO_MMD_VEND2, DW_VR_MII_AN_CTRL);
        if (ret < 0)
                return ret;
@@ -736,7 +755,15 @@ static int xpcs_config_aneg_c37_sgmii(struct dw_xpcs *xpcs, unsigned int mode)
        else
                ret &= ~DW_VR_MII_DIG_CTRL1_MAC_AUTO_SW;
 
-       return xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_DIG_CTRL1, ret);
+       ret = xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_DIG_CTRL1, ret);
+       if (ret < 0)
+               return ret;
+
+       if (phylink_autoneg_inband(mode))
+               ret = xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_MMD_CTRL,
+                                mdio_ctrl | AN_CL37_EN);
+
+       return ret;
 }
 
 static int xpcs_config_2500basex(struct dw_xpcs *xpcs)
index e37edf7..6865d93 100644 (file)
@@ -538,10 +538,16 @@ int __mdiobus_register(struct mii_bus *bus, struct module *owner)
        bus->dev.groups = NULL;
        dev_set_name(&bus->dev, "%s", bus->id);
 
+       /* We need to set state to MDIOBUS_UNREGISTERED to correctly release
+        * the device in mdiobus_free()
+        *
+        * State will be updated later in this function in case of success
+        */
+       bus->state = MDIOBUS_UNREGISTERED;
+
        err = device_register(&bus->dev);
        if (err) {
                pr_err("mii_bus %s failed to register\n", bus->id);
-               put_device(&bus->dev);
                return -EINVAL;
        }
 
index ba5ad86..4f9990b 100644 (file)
@@ -3125,6 +3125,9 @@ static void phy_shutdown(struct device *dev)
 {
        struct phy_device *phydev = to_phy_device(dev);
 
+       if (phydev->state == PHY_READY || !phydev->attached_dev)
+               return;
+
        phy_disable_interrupts(phydev);
 }
 
index 34e9021..ab77a9f 100644 (file)
@@ -134,7 +134,7 @@ static const char * const sm_state_strings[] = {
        [SFP_S_LINK_UP] = "link_up",
        [SFP_S_TX_FAULT] = "tx_fault",
        [SFP_S_REINIT] = "reinit",
-       [SFP_S_TX_DISABLE] = "rx_disable",
+       [SFP_S_TX_DISABLE] = "tx_disable",
 };
 
 static const char *sm_state_to_str(unsigned short sm_state)
index 4c5d697..f87f175 100644 (file)
@@ -99,6 +99,10 @@ config USB_RTL8150
 config USB_RTL8152
        tristate "Realtek RTL8152/RTL8153 Based USB Ethernet Adapters"
        select MII
+       select CRC32
+       select CRYPTO
+       select CRYPTO_HASH
+       select CRYPTO_SHA256
        help
          This option adds support for Realtek RTL8152 based USB 2.0
          10/100 Ethernet adapters and RTL8153 based USB 3.0 10/100/1000
index 60ba9b7..f329e39 100644 (file)
@@ -767,6 +767,7 @@ enum rtl8152_flags {
        PHY_RESET,
        SCHEDULE_TASKLET,
        GREEN_ETHERNET,
+       RX_EPROTO,
 };
 
 #define DEVICE_ID_THINKPAD_THUNDERBOLT3_DOCK_GEN2      0x3082
@@ -1770,6 +1771,14 @@ static void read_bulk_callback(struct urb *urb)
                rtl_set_unplug(tp);
                netif_device_detach(tp->netdev);
                return;
+       case -EPROTO:
+               urb->actual_length = 0;
+               spin_lock_irqsave(&tp->rx_lock, flags);
+               list_add_tail(&agg->list, &tp->rx_done);
+               spin_unlock_irqrestore(&tp->rx_lock, flags);
+               set_bit(RX_EPROTO, &tp->flags);
+               schedule_delayed_work(&tp->schedule, 1);
+               return;
        case -ENOENT:
                return; /* the urb is in unlink state */
        case -ETIME:
@@ -2425,6 +2434,7 @@ static int rx_bottom(struct r8152 *tp, int budget)
        if (list_empty(&tp->rx_done))
                goto out1;
 
+       clear_bit(RX_EPROTO, &tp->flags);
        INIT_LIST_HEAD(&rx_queue);
        spin_lock_irqsave(&tp->rx_lock, flags);
        list_splice_init(&tp->rx_done, &rx_queue);
@@ -2441,7 +2451,7 @@ static int rx_bottom(struct r8152 *tp, int budget)
 
                agg = list_entry(cursor, struct rx_agg, list);
                urb = agg->urb;
-               if (urb->actual_length < ETH_ZLEN)
+               if (urb->status != 0 || urb->actual_length < ETH_ZLEN)
                        goto submit;
 
                agg_free = rtl_get_free_rx(tp, GFP_ATOMIC);
@@ -6643,6 +6653,10 @@ static void rtl_work_func_t(struct work_struct *work)
            netif_carrier_ok(tp->netdev))
                tasklet_schedule(&tp->tx_tl);
 
+       if (test_and_clear_bit(RX_EPROTO, &tp->flags) &&
+           !list_empty(&tp->rx_done))
+               napi_schedule(&tp->napi);
+
        mutex_unlock(&tp->control);
 
 out1:
index 79bd258..4ad25a8 100644 (file)
@@ -406,7 +406,7 @@ static struct sk_buff *page_to_skb(struct virtnet_info *vi,
         * add_recvbuf_mergeable() + get_mergeable_buf_len()
         */
        truesize = headroom ? PAGE_SIZE : truesize;
-       tailroom = truesize - len - headroom;
+       tailroom = truesize - len - headroom - (hdr_padded_len - hdr_len);
        buf = p - headroom;
 
        len -= hdr_len;
index 741289e..ca007b8 100644 (file)
@@ -44,7 +44,7 @@ config ATH10K_SNOC
        tristate "Qualcomm ath10k SNOC support"
        depends on ATH10K
        depends on ARCH_QCOM || COMPILE_TEST
-       depends on QCOM_SCM || !QCOM_SCM #if QCOM_SCM=m this can't be =y
+       select QCOM_SCM
        select QCOM_QMI_HELPERS
        help
          This module adds support for integrated WCN3990 chip connected
index f35cd8d..6914b37 100644 (file)
@@ -3,9 +3,7 @@ config ATH5K
        tristate "Atheros 5xxx wireless cards support"
        depends on (PCI || ATH25) && MAC80211
        select ATH_COMMON
-       select MAC80211_LEDS
-       select LEDS_CLASS
-       select NEW_LEDS
+       select MAC80211_LEDS if LEDS_CLASS=y || LEDS_CLASS=MAC80211
        select ATH5K_AHB if ATH25
        select ATH5K_PCI if !ATH25
        help
index 6a2a168..33e9928 100644 (file)
@@ -89,7 +89,8 @@ static const struct pci_device_id ath5k_led_devices[] = {
 
 void ath5k_led_enable(struct ath5k_hw *ah)
 {
-       if (test_bit(ATH_STAT_LEDSOFT, ah->status)) {
+       if (IS_ENABLED(CONFIG_MAC80211_LEDS) &&
+           test_bit(ATH_STAT_LEDSOFT, ah->status)) {
                ath5k_hw_set_gpio_output(ah, ah->led_pin);
                ath5k_led_off(ah);
        }
@@ -104,7 +105,8 @@ static void ath5k_led_on(struct ath5k_hw *ah)
 
 void ath5k_led_off(struct ath5k_hw *ah)
 {
-       if (!test_bit(ATH_STAT_LEDSOFT, ah->status))
+       if (!IS_ENABLED(CONFIG_MAC80211_LEDS) ||
+           !test_bit(ATH_STAT_LEDSOFT, ah->status))
                return;
        ath5k_hw_set_gpio(ah, ah->led_pin, !ah->led_on);
 }
@@ -146,7 +148,7 @@ ath5k_register_led(struct ath5k_hw *ah, struct ath5k_led *led,
 static void
 ath5k_unregister_led(struct ath5k_led *led)
 {
-       if (!led->ah)
+       if (!IS_ENABLED(CONFIG_MAC80211_LEDS) || !led->ah)
                return;
        led_classdev_unregister(&led->led_dev);
        ath5k_led_off(led->ah);
@@ -169,7 +171,7 @@ int ath5k_init_leds(struct ath5k_hw *ah)
        char name[ATH5K_LED_MAX_NAME_LEN + 1];
        const struct pci_device_id *match;
 
-       if (!ah->pdev)
+       if (!IS_ENABLED(CONFIG_MAC80211_LEDS) || !ah->pdev)
                return 0;
 
 #ifdef CONFIG_ATH5K_AHB
index f7b96cd..9db12ff 100644 (file)
@@ -7463,23 +7463,18 @@ static s32 brcmf_translate_country_code(struct brcmf_pub *drvr, char alpha2[2],
        s32 found_index;
        int i;
 
+       country_codes = drvr->settings->country_codes;
+       if (!country_codes) {
+               brcmf_dbg(TRACE, "No country codes configured for device\n");
+               return -EINVAL;
+       }
+
        if ((alpha2[0] == ccreq->country_abbrev[0]) &&
            (alpha2[1] == ccreq->country_abbrev[1])) {
                brcmf_dbg(TRACE, "Country code already set\n");
                return -EAGAIN;
        }
 
-       country_codes = drvr->settings->country_codes;
-       if (!country_codes) {
-               brcmf_dbg(TRACE, "No country codes configured for device, using ISO3166 code and 0 rev\n");
-               memset(ccreq, 0, sizeof(*ccreq));
-               ccreq->country_abbrev[0] = alpha2[0];
-               ccreq->country_abbrev[1] = alpha2[1];
-               ccreq->ccode[0] = alpha2[0];
-               ccreq->ccode[1] = alpha2[1];
-               return 0;
-       }
-
        found_index = -1;
        for (i = 0; i < country_codes->table_size; i++) {
                cc = &country_codes->table[i];
index 0e97d5e..9f706ff 100644 (file)
@@ -160,6 +160,7 @@ static void iwl_mvm_wowlan_program_keys(struct ieee80211_hw *hw,
                mvm->ptk_icvlen = key->icv_len;
                mvm->gtk_ivlen = key->iv_len;
                mvm->gtk_icvlen = key->icv_len;
+               mutex_unlock(&mvm->mutex);
 
                /* don't upload key again */
                return;
@@ -360,11 +361,11 @@ static void iwl_mvm_wowlan_get_rsc_v5_data(struct ieee80211_hw *hw,
        if (sta) {
                rsc = data->rsc->ucast_rsc;
        } else {
-               if (WARN_ON(data->gtks > ARRAY_SIZE(data->gtk_ids)))
+               if (WARN_ON(data->gtks >= ARRAY_SIZE(data->gtk_ids)))
                        return;
                data->gtk_ids[data->gtks] = key->keyidx;
                rsc = data->rsc->mcast_rsc[data->gtks % 2];
-               if (WARN_ON(key->keyidx >
+               if (WARN_ON(key->keyidx >=
                                ARRAY_SIZE(data->rsc->mcast_key_id_map)))
                        return;
                data->rsc->mcast_key_id_map[key->keyidx] = data->gtks % 2;
index 25af88a..e91f8e8 100644 (file)
@@ -662,12 +662,13 @@ static bool __iwl_mvm_remove_time_event(struct iwl_mvm *mvm,
                                        u32 *uid)
 {
        u32 id;
-       struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(te_data->vif);
+       struct iwl_mvm_vif *mvmvif;
        enum nl80211_iftype iftype;
 
        if (!te_data->vif)
                return false;
 
+       mvmvif = iwl_mvm_vif_from_mac80211(te_data->vif);
        iftype = te_data->vif->type;
 
        /*
index 61b2797..e3996ff 100644 (file)
@@ -547,6 +547,8 @@ static const struct iwl_dev_info iwl_dev_info_table[] = {
        IWL_DEV_INFO(0x43F0, 0x0074, iwl_ax201_cfg_qu_hr, NULL),
        IWL_DEV_INFO(0x43F0, 0x0078, iwl_ax201_cfg_qu_hr, NULL),
        IWL_DEV_INFO(0x43F0, 0x007C, iwl_ax201_cfg_qu_hr, NULL),
+       IWL_DEV_INFO(0x43F0, 0x1651, killer1650s_2ax_cfg_qu_b0_hr_b0, iwl_ax201_killer_1650s_name),
+       IWL_DEV_INFO(0x43F0, 0x1652, killer1650i_2ax_cfg_qu_b0_hr_b0, iwl_ax201_killer_1650i_name),
        IWL_DEV_INFO(0x43F0, 0x2074, iwl_ax201_cfg_qu_hr, NULL),
        IWL_DEV_INFO(0x43F0, 0x4070, iwl_ax201_cfg_qu_hr, NULL),
        IWL_DEV_INFO(0xA0F0, 0x0070, iwl_ax201_cfg_qu_hr, NULL),
index 2413053..a9b5eb9 100644 (file)
@@ -62,8 +62,8 @@ void *mwifiex_process_sta_txpd(struct mwifiex_private *priv,
 
        pkt_type = mwifiex_is_skb_mgmt_frame(skb) ? PKT_TYPE_MGMT : 0;
 
-       pad = ((void *)skb->data - (sizeof(*local_tx_pd) + hroom)-
-                        NULL) & (MWIFIEX_DMA_ALIGN_SZ - 1);
+       pad = ((uintptr_t)skb->data - (sizeof(*local_tx_pd) + hroom)) &
+              (MWIFIEX_DMA_ALIGN_SZ - 1);
        skb_push(skb, sizeof(*local_tx_pd) + pad);
 
        local_tx_pd = (struct txpd *) skb->data;
index 9bbdb8d..245ff64 100644 (file)
@@ -475,8 +475,8 @@ void *mwifiex_process_uap_txpd(struct mwifiex_private *priv,
 
        pkt_type = mwifiex_is_skb_mgmt_frame(skb) ? PKT_TYPE_MGMT : 0;
 
-       pad = ((void *)skb->data - (sizeof(*txpd) + hroom) - NULL) &
-                       (MWIFIEX_DMA_ALIGN_SZ - 1);
+       pad = ((uintptr_t)skb->data - (sizeof(*txpd) + hroom)) &
+              (MWIFIEX_DMA_ALIGN_SZ - 1);
 
        skb_push(skb, sizeof(*txpd) + pad);
 
index 3d87fad..8976da3 100644 (file)
@@ -1383,7 +1383,8 @@ static void nvmem_shift_read_buffer_in_place(struct nvmem_cell *cell, void *buf)
                *p-- = 0;
 
        /* clear msb bits if any leftover in the last byte */
-       *p &= GENMASK((cell->nbits%BITS_PER_BYTE) - 1, 0);
+       if (cell->nbits % BITS_PER_BYTE)
+               *p &= GENMASK((cell->nbits % BITS_PER_BYTE) - 1, 0);
 }
 
 static int __nvmem_cell_read(struct nvmem_device *nvmem,
index f720c0d..0ac1725 100644 (file)
@@ -36,6 +36,7 @@ LIST_HEAD(aliases_lookup);
 struct device_node *of_root;
 EXPORT_SYMBOL(of_root);
 struct device_node *of_chosen;
+EXPORT_SYMBOL(of_chosen);
 struct device_node *of_aliases;
 struct device_node *of_stdout;
 static const char *of_stdout_options;
index eaec915..67c46e5 100644 (file)
@@ -3301,9 +3301,17 @@ static int hv_pci_bus_exit(struct hv_device *hdev, bool keep_devs)
                return 0;
 
        if (!keep_devs) {
-               /* Delete any children which might still exist. */
+               struct list_head removed;
+
+               /* Move all present children to the list on stack */
+               INIT_LIST_HEAD(&removed);
                spin_lock_irqsave(&hbus->device_list_lock, flags);
-               list_for_each_entry_safe(hpdev, tmp, &hbus->children, list_entry) {
+               list_for_each_entry_safe(hpdev, tmp, &hbus->children, list_entry)
+                       list_move_tail(&hpdev->list_entry, &removed);
+               spin_unlock_irqrestore(&hbus->device_list_lock, flags);
+
+               /* Remove all children in the list */
+               list_for_each_entry_safe(hpdev, tmp, &removed, list_entry) {
                        list_del(&hpdev->list_entry);
                        if (hpdev->pci_slot)
                                pci_destroy_slot(hpdev->pci_slot);
@@ -3311,7 +3319,6 @@ static int hv_pci_bus_exit(struct hv_device *hdev, bool keep_devs)
                        put_pcichild(hpdev);
                        put_pcichild(hpdev);
                }
-               spin_unlock_irqrestore(&hbus->device_list_lock, flags);
        }
 
        ret = hv_send_resources_released(hdev);
index 0148687..dcefdb4 100644 (file)
@@ -62,14 +62,7 @@ static int get_power_status(struct hotplug_slot *hotplug_slot, u8 *value)
        struct zpci_dev *zdev = container_of(hotplug_slot, struct zpci_dev,
                                             hotplug_slot);
 
-       switch (zdev->state) {
-       case ZPCI_FN_STATE_STANDBY:
-               *value = 0;
-               break;
-       default:
-               *value = 1;
-               break;
-       }
+       *value = zpci_is_device_configured(zdev) ? 1 : 0;
        return 0;
 }
 
index 0099a00..4b47929 100644 (file)
@@ -535,6 +535,7 @@ static int msi_verify_entries(struct pci_dev *dev)
 static int msi_capability_init(struct pci_dev *dev, int nvec,
                               struct irq_affinity *affd)
 {
+       const struct attribute_group **groups;
        struct msi_desc *entry;
        int ret;
 
@@ -558,12 +559,14 @@ static int msi_capability_init(struct pci_dev *dev, int nvec,
        if (ret)
                goto err;
 
-       dev->msi_irq_groups = msi_populate_sysfs(&dev->dev);
-       if (IS_ERR(dev->msi_irq_groups)) {
-               ret = PTR_ERR(dev->msi_irq_groups);
+       groups = msi_populate_sysfs(&dev->dev);
+       if (IS_ERR(groups)) {
+               ret = PTR_ERR(groups);
                goto err;
        }
 
+       dev->msi_irq_groups = groups;
+
        /* Set MSI enabled bits */
        pci_intx_for_msi(dev, 0);
        pci_msi_set_enable(dev, 1);
@@ -691,6 +694,7 @@ static void msix_mask_all(void __iomem *base, int tsize)
 static int msix_capability_init(struct pci_dev *dev, struct msix_entry *entries,
                                int nvec, struct irq_affinity *affd)
 {
+       const struct attribute_group **groups;
        void __iomem *base;
        int ret, tsize;
        u16 control;
@@ -730,12 +734,14 @@ static int msix_capability_init(struct pci_dev *dev, struct msix_entry *entries,
 
        msix_update_entries(dev, entries);
 
-       dev->msi_irq_groups = msi_populate_sysfs(&dev->dev);
-       if (IS_ERR(dev->msi_irq_groups)) {
-               ret = PTR_ERR(dev->msi_irq_groups);
+       groups = msi_populate_sysfs(&dev->dev);
+       if (IS_ERR(groups)) {
+               ret = PTR_ERR(groups);
                goto out_free;
        }
 
+       dev->msi_irq_groups = groups;
+
        /* Set MSI-X enabled bits and unmask the function */
        pci_intx_for_msi(dev, 0);
        dev->msix_enabled = 1;
index 0f40943..260a06f 100644 (file)
@@ -1249,6 +1249,9 @@ static struct acpi_device *acpi_pci_find_companion(struct device *dev)
        bool check_children;
        u64 addr;
 
+       if (!dev->parent)
+               return NULL;
+
        down_read(&pci_acpi_companion_lookup_sem);
 
        adev = pci_acpi_find_companion_hook ?
index 32ea2a8..5ff4207 100644 (file)
@@ -3,7 +3,8 @@ if (ARCH_QCOM || COMPILE_TEST)
 
 config PINCTRL_MSM
        tristate "Qualcomm core pin controller driver"
-       depends on GPIOLIB && (QCOM_SCM || !QCOM_SCM) #if QCOM_SCM=m this can't be =y
+       depends on GPIOLIB
+       select QCOM_SCM
        select PINMUX
        select PINCONF
        select GENERIC_PINCONF
index 7646708..a916cd8 100644 (file)
@@ -98,7 +98,7 @@ mlxreg_io_get_reg(void *regmap, struct mlxreg_core_data *data, u32 in_val,
                        if (ret)
                                goto access_error;
 
-                       *regval |= rol32(val, regsize * i);
+                       *regval |= rol32(val, regsize * i * 8);
                }
        }
 
@@ -141,7 +141,7 @@ mlxreg_io_attr_store(struct device *dev, struct device_attribute *attr,
                return -EINVAL;
 
        /* Convert buffer to input value. */
-       ret = kstrtou32(buf, len, &input_val);
+       ret = kstrtou32(buf, 0, &input_val);
        if (ret)
                return ret;
 
index d6a7c89..fc95620 100644 (file)
@@ -476,6 +476,7 @@ static const struct acpi_device_id amd_pmc_acpi_ids[] = {
        {"AMDI0006", 0},
        {"AMDI0007", 0},
        {"AMD0004", 0},
+       {"AMD0005", 0},
        { }
 };
 MODULE_DEVICE_TABLE(acpi, amd_pmc_acpi_ids);
index 42513ea..2fffa57 100644 (file)
@@ -167,6 +167,7 @@ config DELL_WMI
 config DELL_WMI_PRIVACY
        bool "Dell WMI Hardware Privacy Support"
        depends on LEDS_TRIGGER_AUDIO = y || DELL_WMI = LEDS_TRIGGER_AUDIO
+       depends on DELL_WMI
        help
          This option adds integration with the "Dell Hardware Privacy"
          feature of Dell laptops to the dell-wmi driver.
index d53634c..658bab4 100644 (file)
@@ -141,6 +141,7 @@ static u8 gigabyte_wmi_detect_sensor_usability(struct wmi_device *wdev)
 
 static const struct dmi_system_id gigabyte_wmi_known_working_platforms[] = {
        DMI_EXACT_MATCH_GIGABYTE_BOARD_NAME("B450M S2H V2"),
+       DMI_EXACT_MATCH_GIGABYTE_BOARD_NAME("B550 AORUS ELITE AX V2"),
        DMI_EXACT_MATCH_GIGABYTE_BOARD_NAME("B550 AORUS ELITE"),
        DMI_EXACT_MATCH_GIGABYTE_BOARD_NAME("B550 AORUS ELITE V2"),
        DMI_EXACT_MATCH_GIGABYTE_BOARD_NAME("B550 GAMING X V2"),
index 379560f..e03943e 100644 (file)
@@ -42,12 +42,20 @@ static void update_sar_data(struct wwan_sar_context *context)
 
        if (config->device_mode_info &&
            context->sar_data.device_mode < config->total_dev_mode) {
-               struct wwan_device_mode_info *dev_mode =
-                       &config->device_mode_info[context->sar_data.device_mode];
-
-               context->sar_data.antennatable_index = dev_mode->antennatable_index;
-               context->sar_data.bandtable_index = dev_mode->bandtable_index;
-               context->sar_data.sartable_index = dev_mode->sartable_index;
+               int itr = 0;
+
+               for (itr = 0; itr < config->total_dev_mode; itr++) {
+                       if (context->sar_data.device_mode ==
+                               config->device_mode_info[itr].device_mode) {
+                               struct wwan_device_mode_info *dev_mode =
+                               &config->device_mode_info[itr];
+
+                               context->sar_data.antennatable_index = dev_mode->antennatable_index;
+                               context->sar_data.bandtable_index = dev_mode->bandtable_index;
+                               context->sar_data.sartable_index = dev_mode->sartable_index;
+                               break;
+                       }
+               }
        }
 }
 
@@ -305,7 +313,6 @@ static struct platform_driver sar_driver = {
        .remove = sar_remove,
        .driver = {
                .name = DRVNAME,
-               .owner = THIS_MODULE,
                .acpi_match_table = ACPI_PTR(sar_device_ids)
        }
 };
@@ -313,4 +320,4 @@ module_platform_driver(sar_driver);
 
 MODULE_LICENSE("GPL v2");
 MODULE_DESCRIPTION("Platform device driver for INTEL MODEM BIOS SAR");
-MODULE_AUTHOR("Shravan S <s.shravan@intel.com>");
+MODULE_AUTHOR("Shravan Sudhakar <s.shravan@intel.com>");
index 9fe0a25..e59d79c 100644 (file)
@@ -401,7 +401,7 @@ int skl_int3472_discrete_remove(struct platform_device *pdev)
 
        gpiod_remove_lookup_table(&int3472->gpios);
 
-       if (int3472->clock.ena_gpio)
+       if (int3472->clock.cl)
                skl_int3472_unregister_clock(int3472);
 
        gpiod_put(int3472->clock.ena_gpio);
index bfa0cc2..7cc9089 100644 (file)
@@ -75,7 +75,7 @@ struct intel_scu_ipc_dev {
 #define IPC_READ_BUFFER                0x90
 
 /* Timeout in jiffies */
-#define IPC_TIMEOUT            (5 * HZ)
+#define IPC_TIMEOUT            (10 * HZ)
 
 static struct intel_scu_ipc_dev *ipcdev; /* Only one for now */
 static DEFINE_MUTEX(ipclock); /* lock used to prevent multiple call to SCU */
@@ -232,7 +232,7 @@ static inline u32 ipc_data_readl(struct intel_scu_ipc_dev *scu, u32 offset)
 /* Wait till scu status is busy */
 static inline int busy_loop(struct intel_scu_ipc_dev *scu)
 {
-       unsigned long end = jiffies + msecs_to_jiffies(IPC_TIMEOUT);
+       unsigned long end = jiffies + IPC_TIMEOUT;
 
        do {
                u32 status;
@@ -247,7 +247,7 @@ static inline int busy_loop(struct intel_scu_ipc_dev *scu)
        return -ETIMEDOUT;
 }
 
-/* Wait till ipc ioc interrupt is received or timeout in 3 HZ */
+/* Wait till ipc ioc interrupt is received or timeout in 10 HZ */
 static inline int ipc_wait_for_interrupt(struct intel_scu_ipc_dev *scu)
 {
        int status;
index a17e8cc..8070f3f 100644 (file)
@@ -644,6 +644,7 @@ static const struct pci_device_id pch_ieee1588_pcidev_id[] = {
         },
        {0}
 };
+MODULE_DEVICE_TABLE(pci, pch_ieee1588_pcidev_id);
 
 static SIMPLE_DEV_PM_OPS(pch_pm_ops, pch_suspend, pch_resume);
 
index b4cb5fb..0cc62c1 100644 (file)
@@ -1776,7 +1776,7 @@ int acornscsi_reconnect_finish(AS_Host *host)
        host->scsi.disconnectable = 0;
        if (host->SCpnt->device->id  == host->scsi.reconnected.target &&
            host->SCpnt->device->lun == host->scsi.reconnected.lun &&
-           scsi_cmd_to_tag(host->SCpnt) == host->scsi.reconnected.tag) {
+           scsi_cmd_to_rq(host->SCpnt)->tag == host->scsi.reconnected.tag) {
 #if (DEBUG & (DEBUG_QUEUES|DEBUG_DISCON))
            DBG(host->SCpnt, printk("scsi%d.%c: reconnected",
                    host->host->host_no, acornscsi_target(host)));
index 40fb3a7..cf2e41d 100644 (file)
@@ -32,7 +32,7 @@ efct_scsi_io_alloc(struct efct_node *node)
        struct efct *efct;
        struct efct_xport *xport;
        struct efct_io *io;
-       unsigned long flags = 0;
+       unsigned long flags;
 
        efct = node->efct;
 
@@ -44,7 +44,6 @@ efct_scsi_io_alloc(struct efct_node *node)
        if (!io) {
                efc_log_err(efct, "IO alloc Failed\n");
                atomic_add_return(1, &xport->io_alloc_failed_count);
-               spin_unlock_irqrestore(&node->active_ios_lock, flags);
                return NULL;
        }
 
index 4683c18..5bc91d3 100644 (file)
@@ -2281,11 +2281,6 @@ int iscsi_eh_abort(struct scsi_cmnd *sc)
                return FAILED;
        }
 
-       conn = session->leadconn;
-       iscsi_get_conn(conn->cls_conn);
-       conn->eh_abort_cnt++;
-       age = session->age;
-
        spin_lock(&session->back_lock);
        task = (struct iscsi_task *)sc->SCp.ptr;
        if (!task || !task->sc) {
@@ -2293,8 +2288,16 @@ int iscsi_eh_abort(struct scsi_cmnd *sc)
                ISCSI_DBG_EH(session, "sc completed while abort in progress\n");
 
                spin_unlock(&session->back_lock);
-               goto success;
+               spin_unlock_bh(&session->frwd_lock);
+               mutex_unlock(&session->eh_mutex);
+               return SUCCESS;
        }
+
+       conn = session->leadconn;
+       iscsi_get_conn(conn->cls_conn);
+       conn->eh_abort_cnt++;
+       age = session->age;
+
        ISCSI_DBG_EH(session, "aborting [sc %p itt 0x%x]\n", sc, task->itt);
        __iscsi_get_task(task);
        spin_unlock(&session->back_lock);
index 78ce38d..026a119 100644 (file)
@@ -12292,12 +12292,12 @@ void
 lpfc_ignore_els_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
                     struct lpfc_iocbq *rspiocb)
 {
-       struct lpfc_nodelist *ndlp = (struct lpfc_nodelist *) cmdiocb->context1;
+       struct lpfc_nodelist *ndlp = NULL;
        IOCB_t *irsp = &rspiocb->iocb;
 
        /* ELS cmd tag <ulpIoTag> completes */
        lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
-                       "0139 Ignoring ELS cmd tag x%x completion Data: "
+                       "0139 Ignoring ELS cmd code x%x completion Data: "
                        "x%x x%x x%x\n",
                        irsp->ulpIoTag, irsp->ulpStatus,
                        irsp->un.ulpWord[4], irsp->ulpTimeout);
@@ -12305,10 +12305,13 @@ lpfc_ignore_els_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
         * Deref the ndlp after free_iocb. sli_release_iocb will access the ndlp
         * if exchange is busy.
         */
-       if (cmdiocb->iocb.ulpCommand == CMD_GEN_REQUEST64_CR)
+       if (cmdiocb->iocb.ulpCommand == CMD_GEN_REQUEST64_CR) {
+               ndlp = cmdiocb->context_un.ndlp;
                lpfc_ct_free_iocb(phba, cmdiocb);
-       else
+       } else {
+               ndlp = (struct lpfc_nodelist *) cmdiocb->context1;
                lpfc_els_free_iocb(phba, cmdiocb);
+       }
 
        lpfc_nlp_put(ndlp);
 }
index 188de6f..95be7ec 100644 (file)
@@ -6377,27 +6377,6 @@ static irqreturn_t ufshcd_check_errors(struct ufs_hba *hba, u32 intr_status)
        return retval;
 }
 
-struct ctm_info {
-       struct ufs_hba  *hba;
-       unsigned long   pending;
-       unsigned int    ncpl;
-};
-
-static bool ufshcd_compl_tm(struct request *req, void *priv, bool reserved)
-{
-       struct ctm_info *const ci = priv;
-       struct completion *c;
-
-       WARN_ON_ONCE(reserved);
-       if (test_bit(req->tag, &ci->pending))
-               return true;
-       ci->ncpl++;
-       c = req->end_io_data;
-       if (c)
-               complete(c);
-       return true;
-}
-
 /**
  * ufshcd_tmc_handler - handle task management function completion
  * @hba: per adapter instance
@@ -6408,18 +6387,24 @@ static bool ufshcd_compl_tm(struct request *req, void *priv, bool reserved)
  */
 static irqreturn_t ufshcd_tmc_handler(struct ufs_hba *hba)
 {
-       unsigned long flags;
-       struct request_queue *q = hba->tmf_queue;
-       struct ctm_info ci = {
-               .hba     = hba,
-       };
+       unsigned long flags, pending, issued;
+       irqreturn_t ret = IRQ_NONE;
+       int tag;
+
+       pending = ufshcd_readl(hba, REG_UTP_TASK_REQ_DOOR_BELL);
 
        spin_lock_irqsave(hba->host->host_lock, flags);
-       ci.pending = ufshcd_readl(hba, REG_UTP_TASK_REQ_DOOR_BELL);
-       blk_mq_tagset_busy_iter(q->tag_set, ufshcd_compl_tm, &ci);
+       issued = hba->outstanding_tasks & ~pending;
+       for_each_set_bit(tag, &issued, hba->nutmrs) {
+               struct request *req = hba->tmf_rqs[tag];
+               struct completion *c = req->end_io_data;
+
+               complete(c);
+               ret = IRQ_HANDLED;
+       }
        spin_unlock_irqrestore(hba->host->host_lock, flags);
 
-       return ci.ncpl ? IRQ_HANDLED : IRQ_NONE;
+       return ret;
 }
 
 /**
@@ -6542,9 +6527,9 @@ static int __ufshcd_issue_tm_cmd(struct ufs_hba *hba,
        ufshcd_hold(hba, false);
 
        spin_lock_irqsave(host->host_lock, flags);
-       blk_mq_start_request(req);
 
        task_tag = req->tag;
+       hba->tmf_rqs[req->tag] = req;
        treq->upiu_req.req_header.dword_0 |= cpu_to_be32(task_tag);
 
        memcpy(hba->utmrdl_base_addr + task_tag, treq, sizeof(*treq));
@@ -6585,6 +6570,7 @@ static int __ufshcd_issue_tm_cmd(struct ufs_hba *hba,
        }
 
        spin_lock_irqsave(hba->host->host_lock, flags);
+       hba->tmf_rqs[req->tag] = NULL;
        __clear_bit(task_tag, &hba->outstanding_tasks);
        spin_unlock_irqrestore(hba->host->host_lock, flags);
 
@@ -9635,6 +9621,12 @@ int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq)
                err = PTR_ERR(hba->tmf_queue);
                goto free_tmf_tag_set;
        }
+       hba->tmf_rqs = devm_kcalloc(hba->dev, hba->nutmrs,
+                                   sizeof(*hba->tmf_rqs), GFP_KERNEL);
+       if (!hba->tmf_rqs) {
+               err = -ENOMEM;
+               goto free_tmf_queue;
+       }
 
        /* Reset the attached device */
        ufshcd_device_reset(hba);
index f0da5d3..41f6e06 100644 (file)
@@ -828,6 +828,7 @@ struct ufs_hba {
 
        struct blk_mq_tag_set tmf_tag_set;
        struct request_queue *tmf_queue;
+       struct request **tmf_rqs;
 
        struct uic_command *active_uic_cmd;
        struct mutex uic_cmd_mutex;
index 8179b69..853096b 100644 (file)
@@ -5,7 +5,6 @@ config SOC_K210_SYSCTL
        depends on RISCV && SOC_CANAAN && OF
        default SOC_CANAAN
         select PM
-        select SIMPLE_PM_BUS
         select SYSCON
         select MFD_SYSCON
        help
index bda170d..72fc2b5 100644 (file)
@@ -98,7 +98,7 @@ void *qcom_mdt_read_metadata(const struct firmware *fw, size_t *data_len)
        if (ehdr->e_phnum < 2)
                return ERR_PTR(-EINVAL);
 
-       if (phdrs[0].p_type == PT_LOAD || phdrs[1].p_type == PT_LOAD)
+       if (phdrs[0].p_type == PT_LOAD)
                return ERR_PTR(-EINVAL);
 
        if ((phdrs[1].p_flags & QCOM_MDT_TYPE_MASK) != QCOM_MDT_TYPE_HASH)
index 9faf483..52e5811 100644 (file)
@@ -628,7 +628,7 @@ static int qcom_socinfo_probe(struct platform_device *pdev)
        /* Feed the soc specific unique data into entropy pool */
        add_device_randomness(info, item_size);
 
-       platform_set_drvdata(pdev, qs->soc_dev);
+       platform_set_drvdata(pdev, qs);
 
        return 0;
 }
index ea64e18..f32e1cb 100644 (file)
@@ -825,25 +825,28 @@ static int omap_reset_deassert(struct reset_controller_dev *rcdev,
        writel_relaxed(v, reset->prm->base + reset->prm->data->rstctrl);
        spin_unlock_irqrestore(&reset->lock, flags);
 
-       if (!has_rstst)
-               goto exit;
+       /* wait for the reset bit to clear */
+       ret = readl_relaxed_poll_timeout_atomic(reset->prm->base +
+                                               reset->prm->data->rstctrl,
+                                               v, !(v & BIT(id)), 1,
+                                               OMAP_RESET_MAX_WAIT);
+       if (ret)
+               pr_err("%s: timedout waiting for %s:%lu\n", __func__,
+                      reset->prm->data->name, id);
 
        /* wait for the status to be set */
-       ret = readl_relaxed_poll_timeout_atomic(reset->prm->base +
+       if (has_rstst) {
+               ret = readl_relaxed_poll_timeout_atomic(reset->prm->base +
                                                 reset->prm->data->rstst,
                                                 v, v & BIT(st_bit), 1,
                                                 OMAP_RESET_MAX_WAIT);
-       if (ret)
-               pr_err("%s: timedout waiting for %s:%lu\n", __func__,
-                      reset->prm->data->name, id);
+               if (ret)
+                       pr_err("%s: timedout waiting for %s:%lu\n", __func__,
+                              reset->prm->data->name, id);
+       }
 
-exit:
-       if (reset->clkdm) {
-               /* At least dra7 iva needs a delay before clkdm idle */
-               if (has_rstst)
-                       udelay(1);
+       if (reset->clkdm)
                pdata->clkdm_allow_idle(reset->clkdm);
-       }
 
        return ret;
 }
index 788dcdf..f872cf1 100644 (file)
@@ -1301,7 +1301,7 @@ static int atmel_spi_one_transfer(struct spi_master *master,
         * DMA map early, for performance (empties dcache ASAP) and
         * better fault reporting.
         */
-       if ((!master->cur_msg_mapped)
+       if ((!master->cur_msg->is_dma_mapped)
                && as->use_pdc) {
                if (atmel_spi_dma_map_xfer(as, xfer) < 0)
                        return -ENOMEM;
@@ -1381,7 +1381,7 @@ static int atmel_spi_one_transfer(struct spi_master *master,
                }
        }
 
-       if (!master->cur_msg_mapped
+       if (!master->cur_msg->is_dma_mapped
                && as->use_pdc)
                atmel_spi_dma_unmap_xfer(master, xfer);
 
index a78e56f..3043677 100644 (file)
@@ -1250,10 +1250,14 @@ static void bcm_qspi_hw_init(struct bcm_qspi *qspi)
 
 static void bcm_qspi_hw_uninit(struct bcm_qspi *qspi)
 {
+       u32 status = bcm_qspi_read(qspi, MSPI, MSPI_MSPI_STATUS);
+
        bcm_qspi_write(qspi, MSPI, MSPI_SPCR2, 0);
        if (has_bspi(qspi))
                bcm_qspi_write(qspi, MSPI, MSPI_WRITE_LOCK, 0);
 
+       /* clear interrupt */
+       bcm_qspi_write(qspi, MSPI, MSPI_MSPI_STATUS, status & ~1);
 }
 
 static const struct spi_controller_mem_ops bcm_qspi_mem_ops = {
@@ -1397,6 +1401,47 @@ int bcm_qspi_probe(struct platform_device *pdev,
        if (!qspi->dev_ids)
                return -ENOMEM;
 
+       /*
+        * Some SoCs integrate spi controller (e.g., its interrupt bits)
+        * in specific ways
+        */
+       if (soc_intc) {
+               qspi->soc_intc = soc_intc;
+               soc_intc->bcm_qspi_int_set(soc_intc, MSPI_DONE, true);
+       } else {
+               qspi->soc_intc = NULL;
+       }
+
+       if (qspi->clk) {
+               ret = clk_prepare_enable(qspi->clk);
+               if (ret) {
+                       dev_err(dev, "failed to prepare clock\n");
+                       goto qspi_probe_err;
+               }
+               qspi->base_clk = clk_get_rate(qspi->clk);
+       } else {
+               qspi->base_clk = MSPI_BASE_FREQ;
+       }
+
+       if (data->has_mspi_rev) {
+               rev = bcm_qspi_read(qspi, MSPI, MSPI_REV);
+               /* some older revs do not have a MSPI_REV register */
+               if ((rev & 0xff) == 0xff)
+                       rev = 0;
+       }
+
+       qspi->mspi_maj_rev = (rev >> 4) & 0xf;
+       qspi->mspi_min_rev = rev & 0xf;
+       qspi->mspi_spcr3_sysclk = data->has_spcr3_sysclk;
+
+       qspi->max_speed_hz = qspi->base_clk / (bcm_qspi_spbr_min(qspi) * 2);
+
+       /*
+        * On SW resets it is possible to have the mask still enabled
+        * Need to disable the mask and clear the status while we init
+        */
+       bcm_qspi_hw_uninit(qspi);
+
        for (val = 0; val < num_irqs; val++) {
                irq = -1;
                name = qspi_irq_tab[val].irq_name;
@@ -1433,38 +1478,6 @@ int bcm_qspi_probe(struct platform_device *pdev,
                goto qspi_probe_err;
        }
 
-       /*
-        * Some SoCs integrate spi controller (e.g., its interrupt bits)
-        * in specific ways
-        */
-       if (soc_intc) {
-               qspi->soc_intc = soc_intc;
-               soc_intc->bcm_qspi_int_set(soc_intc, MSPI_DONE, true);
-       } else {
-               qspi->soc_intc = NULL;
-       }
-
-       ret = clk_prepare_enable(qspi->clk);
-       if (ret) {
-               dev_err(dev, "failed to prepare clock\n");
-               goto qspi_probe_err;
-       }
-
-       qspi->base_clk = clk_get_rate(qspi->clk);
-
-       if (data->has_mspi_rev) {
-               rev = bcm_qspi_read(qspi, MSPI, MSPI_REV);
-               /* some older revs do not have a MSPI_REV register */
-               if ((rev & 0xff) == 0xff)
-                       rev = 0;
-       }
-
-       qspi->mspi_maj_rev = (rev >> 4) & 0xf;
-       qspi->mspi_min_rev = rev & 0xf;
-       qspi->mspi_spcr3_sysclk = data->has_spcr3_sysclk;
-
-       qspi->max_speed_hz = qspi->base_clk / (bcm_qspi_spbr_min(qspi) * 2);
-
        bcm_qspi_hw_init(qspi);
        init_completion(&qspi->mspi_done);
        init_completion(&qspi->bspi_done);
index 386e8c8..a15de10 100644 (file)
@@ -233,36 +233,44 @@ static int mtk_spi_set_hw_cs_timing(struct spi_device *spi)
                return delay;
        inactive = (delay * DIV_ROUND_UP(mdata->spi_clk_hz, 1000000)) / 1000;
 
-       setup    = setup ? setup : 1;
-       hold     = hold ? hold : 1;
-       inactive = inactive ? inactive : 1;
-
-       reg_val = readl(mdata->base + SPI_CFG0_REG);
-       if (mdata->dev_comp->enhance_timing) {
-               hold = min_t(u32, hold, 0x10000);
-               setup = min_t(u32, setup, 0x10000);
-               reg_val &= ~(0xffff << SPI_ADJUST_CFG0_CS_HOLD_OFFSET);
-               reg_val |= (((hold - 1) & 0xffff)
-                          << SPI_ADJUST_CFG0_CS_HOLD_OFFSET);
-               reg_val &= ~(0xffff << SPI_ADJUST_CFG0_CS_SETUP_OFFSET);
-               reg_val |= (((setup - 1) & 0xffff)
-                          << SPI_ADJUST_CFG0_CS_SETUP_OFFSET);
-       } else {
-               hold = min_t(u32, hold, 0x100);
-               setup = min_t(u32, setup, 0x100);
-               reg_val &= ~(0xff << SPI_CFG0_CS_HOLD_OFFSET);
-               reg_val |= (((hold - 1) & 0xff) << SPI_CFG0_CS_HOLD_OFFSET);
-               reg_val &= ~(0xff << SPI_CFG0_CS_SETUP_OFFSET);
-               reg_val |= (((setup - 1) & 0xff)
-                           << SPI_CFG0_CS_SETUP_OFFSET);
+       if (hold || setup) {
+               reg_val = readl(mdata->base + SPI_CFG0_REG);
+               if (mdata->dev_comp->enhance_timing) {
+                       if (hold) {
+                               hold = min_t(u32, hold, 0x10000);
+                               reg_val &= ~(0xffff << SPI_ADJUST_CFG0_CS_HOLD_OFFSET);
+                               reg_val |= (((hold - 1) & 0xffff)
+                                       << SPI_ADJUST_CFG0_CS_HOLD_OFFSET);
+                       }
+                       if (setup) {
+                               setup = min_t(u32, setup, 0x10000);
+                               reg_val &= ~(0xffff << SPI_ADJUST_CFG0_CS_SETUP_OFFSET);
+                               reg_val |= (((setup - 1) & 0xffff)
+                                       << SPI_ADJUST_CFG0_CS_SETUP_OFFSET);
+                       }
+               } else {
+                       if (hold) {
+                               hold = min_t(u32, hold, 0x100);
+                               reg_val &= ~(0xff << SPI_CFG0_CS_HOLD_OFFSET);
+                               reg_val |= (((hold - 1) & 0xff) << SPI_CFG0_CS_HOLD_OFFSET);
+                       }
+                       if (setup) {
+                               setup = min_t(u32, setup, 0x100);
+                               reg_val &= ~(0xff << SPI_CFG0_CS_SETUP_OFFSET);
+                               reg_val |= (((setup - 1) & 0xff)
+                                       << SPI_CFG0_CS_SETUP_OFFSET);
+                       }
+               }
+               writel(reg_val, mdata->base + SPI_CFG0_REG);
        }
-       writel(reg_val, mdata->base + SPI_CFG0_REG);
 
-       inactive = min_t(u32, inactive, 0x100);
-       reg_val = readl(mdata->base + SPI_CFG1_REG);
-       reg_val &= ~SPI_CFG1_CS_IDLE_MASK;
-       reg_val |= (((inactive - 1) & 0xff) << SPI_CFG1_CS_IDLE_OFFSET);
-       writel(reg_val, mdata->base + SPI_CFG1_REG);
+       if (inactive) {
+               inactive = min_t(u32, inactive, 0x100);
+               reg_val = readl(mdata->base + SPI_CFG1_REG);
+               reg_val &= ~SPI_CFG1_CS_IDLE_MASK;
+               reg_val |= (((inactive - 1) & 0xff) << SPI_CFG1_CS_IDLE_OFFSET);
+               writel(reg_val, mdata->base + SPI_CFG1_REG);
+       }
 
        return 0;
 }
index 9708b78..f5d32ec 100644 (file)
@@ -137,6 +137,13 @@ static int spi_mux_probe(struct spi_device *spi)
        priv = spi_controller_get_devdata(ctlr);
        priv->spi = spi;
 
+       /*
+        * Increase lockdep class as these lock are taken while the parent bus
+        * already holds their instance's lock.
+        */
+       lockdep_set_subclass(&ctlr->io_mutex, 1);
+       lockdep_set_subclass(&ctlr->add_lock, 1);
+
        priv->mux = devm_mux_control_get(&spi->dev, NULL);
        if (IS_ERR(priv->mux)) {
                ret = dev_err_probe(&spi->dev, PTR_ERR(priv->mux),
index a66fa97..2b0301f 100644 (file)
@@ -33,6 +33,7 @@
 
 #include <linux/acpi.h>
 #include <linux/bitops.h>
+#include <linux/bitfield.h>
 #include <linux/clk.h>
 #include <linux/completion.h>
 #include <linux/delay.h>
 #define NXP_FSPI_MIN_IOMAP     SZ_4M
 
 #define DCFG_RCWSR1            0x100
+#define SYS_PLL_RAT            GENMASK(6, 2)
 
 /* Access flash memory using IP bus only */
 #define FSPI_QUIRK_USE_IP_ONLY BIT(0)
@@ -926,9 +928,8 @@ static void erratum_err050568(struct nxp_fspi *f)
                { .family = "QorIQ LS1028A" },
                { /* sentinel */ }
        };
-       struct device_node *np;
        struct regmap *map;
-       u32 val = 0, sysclk = 0;
+       u32 val, sys_pll_ratio;
        int ret;
 
        /* Check for LS1028A family */
@@ -937,7 +938,6 @@ static void erratum_err050568(struct nxp_fspi *f)
                return;
        }
 
-       /* Compute system clock frequency multiplier ratio */
        map = syscon_regmap_lookup_by_compatible("fsl,ls1028a-dcfg");
        if (IS_ERR(map)) {
                dev_err(f->dev, "No syscon regmap\n");
@@ -948,23 +948,11 @@ static void erratum_err050568(struct nxp_fspi *f)
        if (ret < 0)
                goto err;
 
-       /* Strap bits 6:2 define SYS_PLL_RAT i.e frequency multiplier ratio */
-       val = (val >> 2) & 0x1F;
-       WARN(val == 0, "Strapping is zero: Cannot determine ratio");
+       sys_pll_ratio = FIELD_GET(SYS_PLL_RAT, val);
+       dev_dbg(f->dev, "val: 0x%08x, sys_pll_ratio: %d\n", val, sys_pll_ratio);
 
-       /* Compute system clock frequency */
-       np = of_find_node_by_name(NULL, "clock-sysclk");
-       if (!np)
-               goto err;
-
-       if (of_property_read_u32(np, "clock-frequency", &sysclk))
-               goto err;
-
-       sysclk = (sysclk * val) / 1000000; /* Convert sysclk to Mhz */
-       dev_dbg(f->dev, "val: 0x%08x, sysclk: %dMhz\n", val, sysclk);
-
-       /* Use IP bus only if PLL is 300MHz */
-       if (sysclk == 300)
+       /* Use IP bus only if platform clock is 300MHz */
+       if (sys_pll_ratio == 3)
                f->devtype_data->quirks |= FSPI_QUIRK_USE_IP_ONLY;
 
        return;
index 8ce840c..713292b 100644 (file)
@@ -1182,8 +1182,7 @@ static int tegra_slink_resume(struct device *dev)
 }
 #endif
 
-#ifdef CONFIG_PM
-static int tegra_slink_runtime_suspend(struct device *dev)
+static int __maybe_unused tegra_slink_runtime_suspend(struct device *dev)
 {
        struct spi_master *master = dev_get_drvdata(dev);
        struct tegra_slink_data *tspi = spi_master_get_devdata(master);
@@ -1208,7 +1207,6 @@ static int tegra_slink_runtime_resume(struct device *dev)
        }
        return 0;
 }
-#endif /* CONFIG_PM */
 
 static const struct dev_pm_ops slink_pm_ops = {
        SET_RUNTIME_PM_OPS(tegra_slink_runtime_suspend,
index aea037c..926b68a 100644 (file)
@@ -478,12 +478,6 @@ static LIST_HEAD(spi_controller_list);
  */
 static DEFINE_MUTEX(board_lock);
 
-/*
- * Prevents addition of devices with same chip select and
- * addition of devices below an unregistering controller.
- */
-static DEFINE_MUTEX(spi_add_lock);
-
 /**
  * spi_alloc_device - Allocate a new SPI device
  * @ctlr: Controller to which device is connected
@@ -636,9 +630,9 @@ int spi_add_device(struct spi_device *spi)
         * chipselect **BEFORE** we call setup(), else we'll trash
         * its configuration.  Lock against concurrent add() calls.
         */
-       mutex_lock(&spi_add_lock);
+       mutex_lock(&ctlr->add_lock);
        status = __spi_add_device(spi);
-       mutex_unlock(&spi_add_lock);
+       mutex_unlock(&ctlr->add_lock);
        return status;
 }
 EXPORT_SYMBOL_GPL(spi_add_device);
@@ -658,7 +652,7 @@ static int spi_add_device_locked(struct spi_device *spi)
        /* Set the bus ID string */
        spi_dev_set_name(spi);
 
-       WARN_ON(!mutex_is_locked(&spi_add_lock));
+       WARN_ON(!mutex_is_locked(&ctlr->add_lock));
        return __spi_add_device(spi);
 }
 
@@ -2553,6 +2547,12 @@ struct spi_controller *__spi_alloc_controller(struct device *dev,
                return NULL;
 
        device_initialize(&ctlr->dev);
+       INIT_LIST_HEAD(&ctlr->queue);
+       spin_lock_init(&ctlr->queue_lock);
+       spin_lock_init(&ctlr->bus_lock_spinlock);
+       mutex_init(&ctlr->bus_lock_mutex);
+       mutex_init(&ctlr->io_mutex);
+       mutex_init(&ctlr->add_lock);
        ctlr->bus_num = -1;
        ctlr->num_chipselect = 1;
        ctlr->slave = slave;
@@ -2825,11 +2825,6 @@ int spi_register_controller(struct spi_controller *ctlr)
                        return id;
                ctlr->bus_num = id;
        }
-       INIT_LIST_HEAD(&ctlr->queue);
-       spin_lock_init(&ctlr->queue_lock);
-       spin_lock_init(&ctlr->bus_lock_spinlock);
-       mutex_init(&ctlr->bus_lock_mutex);
-       mutex_init(&ctlr->io_mutex);
        ctlr->bus_lock_flag = 0;
        init_completion(&ctlr->xfer_completion);
        if (!ctlr->max_dma_len)
@@ -2966,7 +2961,7 @@ void spi_unregister_controller(struct spi_controller *ctlr)
 
        /* Prevent addition of new devices, unregister existing ones */
        if (IS_ENABLED(CONFIG_SPI_DYNAMIC))
-               mutex_lock(&spi_add_lock);
+               mutex_lock(&ctlr->add_lock);
 
        device_for_each_child(&ctlr->dev, NULL, __unregister);
 
@@ -2997,7 +2992,7 @@ void spi_unregister_controller(struct spi_controller *ctlr)
        mutex_unlock(&board_lock);
 
        if (IS_ENABLED(CONFIG_SPI_DYNAMIC))
-               mutex_unlock(&spi_add_lock);
+               mutex_unlock(&ctlr->add_lock);
 }
 EXPORT_SYMBOL_GPL(spi_unregister_controller);
 
index 6dc29ce..1bd73e3 100644 (file)
@@ -673,6 +673,19 @@ static const struct file_operations spidev_fops = {
 
 static struct class *spidev_class;
 
+static const struct spi_device_id spidev_spi_ids[] = {
+       { .name = "dh2228fv" },
+       { .name = "ltc2488" },
+       { .name = "sx1301" },
+       { .name = "bk4" },
+       { .name = "dhcom-board" },
+       { .name = "m53cpld" },
+       { .name = "spi-petra" },
+       { .name = "spi-authenta" },
+       {},
+};
+MODULE_DEVICE_TABLE(spi, spidev_spi_ids);
+
 #ifdef CONFIG_OF
 static const struct of_device_id spidev_dt_ids[] = {
        { .compatible = "rohm,dh2228fv" },
@@ -818,6 +831,7 @@ static struct spi_driver spidev_spi_driver = {
        },
        .probe =        spidev_probe,
        .remove =       spidev_remove,
+       .id_table =     spidev_spi_ids,
 
        /* NOTE:  suspend/resume methods are not necessary here.
         * We don't do anything except pass the requests to/from
index 8e085dd..712e01c 100644 (file)
@@ -1646,6 +1646,8 @@ static input_system_err_t input_system_configure_channel_sensor(
        default:
                return INPUT_SYSTEM_ERR_PARAMETER_NOT_SUPPORTED;
        }
+
+       return INPUT_SYSTEM_ERR_NO_ERROR;
 }
 
 // Test flags and set structure.
index a6d589e..f27eba7 100644 (file)
@@ -248,7 +248,7 @@ void rtw_hal_update_ra_mask(struct adapter *adapt, u32 mac_id, u8 rssi_level)
 #ifdef CONFIG_88EU_AP_MODE
                struct sta_info *psta = NULL;
                struct sta_priv *pstapriv = &adapt->stapriv;
-               if ((mac_id - 1) > 0)
+               if (mac_id >= 2)
                        psta = pstapriv->sta_aid[(mac_id - 1) - 1];
                if (psta)
                        add_RATid(adapt, psta, 0);/* todo: based on rssi_level*/
index b25369a..967f10b 100644 (file)
@@ -182,7 +182,7 @@ create_pagelist(char *buf, char __user *ubuf,
                offset = (uintptr_t)ubuf & (PAGE_SIZE - 1);
        num_pages = DIV_ROUND_UP(count + offset, PAGE_SIZE);
 
-       if (num_pages > (SIZE_MAX - sizeof(struct pagelist) -
+       if ((size_t)num_pages > (SIZE_MAX - sizeof(struct pagelist) -
                         sizeof(struct vchiq_pagelist_info)) /
                        (sizeof(u32) + sizeof(pages[0]) +
                         sizeof(struct scatterlist)))
index 5ce13b0..5363ebe 100644 (file)
@@ -585,6 +585,9 @@ static int optee_remove(struct platform_device *pdev)
 {
        struct optee *optee = platform_get_drvdata(pdev);
 
+       /* Unregister OP-TEE specific client devices on TEE bus */
+       optee_unregister_devices();
+
        /*
         * Ask OP-TEE to free all cached shared memory objects to decrease
         * reference counters and also avoid wild pointers in secure world
index ec1d246..128a2d2 100644 (file)
@@ -53,6 +53,13 @@ static int get_devices(struct tee_context *ctx, u32 session,
        return 0;
 }
 
+static void optee_release_device(struct device *dev)
+{
+       struct tee_client_device *optee_device = to_tee_client_device(dev);
+
+       kfree(optee_device);
+}
+
 static int optee_register_device(const uuid_t *device_uuid)
 {
        struct tee_client_device *optee_device = NULL;
@@ -63,6 +70,7 @@ static int optee_register_device(const uuid_t *device_uuid)
                return -ENOMEM;
 
        optee_device->dev.bus = &tee_bus_type;
+       optee_device->dev.release = optee_release_device;
        if (dev_set_name(&optee_device->dev, "optee-ta-%pUb", device_uuid)) {
                kfree(optee_device);
                return -ENOMEM;
@@ -154,3 +162,17 @@ int optee_enumerate_devices(u32 func)
 {
        return  __optee_enumerate_devices(func);
 }
+
+static int __optee_unregister_device(struct device *dev, void *data)
+{
+       if (!strncmp(dev_name(dev), "optee-ta", strlen("optee-ta")))
+               device_unregister(dev);
+
+       return 0;
+}
+
+void optee_unregister_devices(void)
+{
+       bus_for_each_dev(&tee_bus_type, NULL, NULL,
+                        __optee_unregister_device);
+}
index dbdd367..f6bb4a7 100644 (file)
@@ -184,6 +184,7 @@ void optee_fill_pages_list(u64 *dst, struct page **pages, int num_pages,
 #define PTA_CMD_GET_DEVICES            0x0
 #define PTA_CMD_GET_DEVICES_SUPP       0x1
 int optee_enumerate_devices(u32 func);
+void optee_unregister_devices(void);
 
 /*
  * Small helpers
index c41a9a5..d167039 100644 (file)
@@ -35,7 +35,7 @@ static int pool_op_alloc(struct tee_shm_pool_mgr *poolm,
                unsigned int nr_pages = 1 << order, i;
                struct page **pages;
 
-               pages = kcalloc(nr_pages, sizeof(pages), GFP_KERNEL);
+               pages = kcalloc(nr_pages, sizeof(*pages), GFP_KERNEL);
                if (!pages) {
                        rc = -ENOMEM;
                        goto err;
index da19d79..78fd365 100644 (file)
@@ -7,6 +7,7 @@ thunderbolt-objs += usb4_port.o nvm.o retimer.o quirks.o
 thunderbolt-${CONFIG_ACPI} += acpi.o
 thunderbolt-$(CONFIG_DEBUG_FS) += debugfs.o
 thunderbolt-${CONFIG_USB4_KUNIT_TEST} += test.o
+CFLAGS_test.o += $(DISABLE_STRUCTLEAK_PLUGIN)
 
 thunderbolt_dma_test-${CONFIG_USB4_DMA_TEST} += dma_test.o
 obj-$(CONFIG_USB4_DMA_TEST) += thunderbolt_dma_test.o
index 8f143c0..f0bf01e 100644 (file)
@@ -618,10 +618,8 @@ static int __init xenboot_console_setup(struct console *console, char *string)
 {
        static struct xencons_info xenboot;
 
-       if (xen_initial_domain())
+       if (xen_initial_domain() || !xen_pv_domain())
                return 0;
-       if (!xen_pv_domain())
-               return -ENODEV;
 
        return xencons_info_pv_init(&xenboot, 0);
 }
@@ -632,17 +630,16 @@ static void xenboot_write_console(struct console *console, const char *string,
        unsigned int linelen, off = 0;
        const char *pos;
 
+       if (dom0_write_console(0, string, len) >= 0)
+               return;
+
        if (!xen_pv_domain()) {
                xen_hvm_early_write(0, string, len);
                return;
        }
 
-       dom0_write_console(0, string, len);
-
-       if (xen_initial_domain())
+       if (domU_write_console(0, "(early) ", 8) < 0)
                return;
-
-       domU_write_console(0, "(early) ", 8);
        while (off < len && NULL != (pos = strchr(string+off, '\n'))) {
                linelen = pos-string+off;
                if (off + linelen > len)
index 71ae16d..39fc96d 100644 (file)
@@ -361,9 +361,13 @@ config SERIAL_8250_BCM2835AUX
          If unsure, say N.
 
 config SERIAL_8250_FSL
-       bool
+       bool "Freescale 16550 UART support" if COMPILE_TEST && !(PPC || ARM || ARM64)
        depends on SERIAL_8250_CONSOLE
-       default PPC || ARM || ARM64 || COMPILE_TEST
+       default PPC || ARM || ARM64
+       help
+         Selecting this option enables a workaround for a break-detection
+         erratum for Freescale 16550 UARTs in the 8250 driver. It also
+         enables support for ACPI enumeration.
 
 config SERIAL_8250_DW
        tristate "Support for Synopsys DesignWare 8250 quirks"
index 8b7bc10..f1d1006 100644 (file)
@@ -420,11 +420,16 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev)
        data->phy = devm_usb_get_phy_by_phandle(dev, "fsl,usbphy", 0);
        if (IS_ERR(data->phy)) {
                ret = PTR_ERR(data->phy);
-               /* Return -EINVAL if no usbphy is available */
-               if (ret == -ENODEV)
-                       data->phy = NULL;
-               else
-                       goto err_clk;
+               if (ret == -ENODEV) {
+                       data->phy = devm_usb_get_phy_by_phandle(dev, "phys", 0);
+                       if (IS_ERR(data->phy)) {
+                               ret = PTR_ERR(data->phy);
+                               if (ret == -ENODEV)
+                                       data->phy = NULL;
+                               else
+                                       goto err_clk;
+                       }
+               }
        }
 
        pdata.usb_phy = data->phy;
index 4e2f155..7b2e242 100644 (file)
@@ -340,6 +340,9 @@ static void acm_process_notification(struct acm *acm, unsigned char *buf)
                        acm->iocount.overrun++;
                spin_unlock_irqrestore(&acm->read_lock, flags);
 
+               if (newctrl & ACM_CTRL_BRK)
+                       tty_flip_buffer_push(&acm->port);
+
                if (difference)
                        wake_up_all(&acm->wioctl);
 
@@ -475,11 +478,16 @@ static int acm_submit_read_urbs(struct acm *acm, gfp_t mem_flags)
 
 static void acm_process_read_urb(struct acm *acm, struct urb *urb)
 {
+       unsigned long flags;
+
        if (!urb->actual_length)
                return;
 
+       spin_lock_irqsave(&acm->read_lock, flags);
        tty_insert_flip_string(&acm->port, urb->transfer_buffer,
                        urb->actual_length);
+       spin_unlock_irqrestore(&acm->read_lock, flags);
+
        tty_flip_buffer_push(&acm->port);
 }
 
index 35d5908..fdf79bc 100644 (file)
@@ -824,7 +824,7 @@ static struct usb_class_driver wdm_class = {
 };
 
 /* --- WWAN framework integration --- */
-#ifdef CONFIG_WWAN_CORE
+#ifdef CONFIG_WWAN
 static int wdm_wwan_port_start(struct wwan_port *port)
 {
        struct wdm_device *desc = wwan_port_get_drvdata(port);
@@ -963,11 +963,11 @@ static void wdm_wwan_rx(struct wdm_device *desc, int length)
        /* inbuf has been copied, it is safe to check for outstanding data */
        schedule_work(&desc->service_outs_intr);
 }
-#else /* CONFIG_WWAN_CORE */
+#else /* CONFIG_WWAN */
 static void wdm_wwan_init(struct wdm_device *desc) {}
 static void wdm_wwan_deinit(struct wdm_device *desc) {}
 static void wdm_wwan_rx(struct wdm_device *desc, int length) {}
-#endif /* CONFIG_WWAN_CORE */
+#endif /* CONFIG_WWAN */
 
 /* --- error handling --- */
 static void wdm_rxwork(struct work_struct *work)
index 5e8a04e..b856622 100644 (file)
@@ -6,8 +6,7 @@ config USB_COMMON
 
 config USB_LED_TRIG
        bool "USB LED Triggers"
-       depends on LEDS_CLASS && LEDS_TRIGGERS
-       select USB_COMMON
+       depends on LEDS_CLASS && USB_COMMON && LEDS_TRIGGERS
        help
          This option adds LED triggers for USB host and/or gadget activity.
 
index 804b505..4519d06 100644 (file)
@@ -4243,7 +4243,7 @@ int dwc3_gadget_init(struct dwc3 *dwc)
        }
 
 
-       usb_initialize_gadget(dwc->sysdev, dwc->gadget, dwc_gadget_release);
+       usb_initialize_gadget(dwc->dev, dwc->gadget, dwc_gadget_release);
        dev                             = &dwc->gadget->dev;
        dev->platform_data              = dwc;
        dwc->gadget->ops                = &dwc3_gadget_ops;
index be86456..ef55b8b 100644 (file)
@@ -674,11 +674,17 @@ static int set_ep_max_packet_size(const struct f_uac2_opts *uac2_opts,
                ssize = uac2_opts->c_ssize;
        }
 
-       if (!is_playback && (uac2_opts->c_sync == USB_ENDPOINT_SYNC_ASYNC))
+       if (!is_playback && (uac2_opts->c_sync == USB_ENDPOINT_SYNC_ASYNC)) {
+         // Win10 requires max packet size + 1 frame
                srate = srate * (1000 + uac2_opts->fb_max) / 1000;
-
-       max_size_bw = num_channels(chmask) * ssize *
-               DIV_ROUND_UP(srate, factor / (1 << (ep_desc->bInterval - 1)));
+               // updated srate is always bigger, therefore DIV_ROUND_UP always yields +1
+               max_size_bw = num_channels(chmask) * ssize *
+                       (DIV_ROUND_UP(srate, factor / (1 << (ep_desc->bInterval - 1))));
+       } else {
+               // adding 1 frame provision for Win10
+               max_size_bw = num_channels(chmask) * ssize *
+                       (DIV_ROUND_UP(srate, factor / (1 << (ep_desc->bInterval - 1))) + 1);
+       }
        ep_desc->wMaxPacketSize = cpu_to_le16(min_t(u16, max_size_bw,
                                                    max_size_ep));
 
index 0b37227..ded9738 100644 (file)
 #include <mach/usb.h>
 
 
-/* OMAP-1510 OHCI has its own MMU for DMA */
-#define OMAP1510_LB_MEMSIZE    32      /* Should be same as SDRAM size */
-#define OMAP1510_LB_CLOCK_DIV  0xfffec10c
-#define OMAP1510_LB_MMU_CTL    0xfffec208
-#define OMAP1510_LB_MMU_LCK    0xfffec224
-#define OMAP1510_LB_MMU_LD_TLB 0xfffec228
-#define OMAP1510_LB_MMU_CAM_H  0xfffec22c
-#define OMAP1510_LB_MMU_CAM_L  0xfffec230
-#define OMAP1510_LB_MMU_RAM_H  0xfffec234
-#define OMAP1510_LB_MMU_RAM_L  0xfffec238
-
 #define DRIVER_DESC "OHCI OMAP driver"
 
 struct ohci_omap_priv {
@@ -104,61 +93,6 @@ static int omap_ohci_transceiver_power(struct ohci_omap_priv *priv, int on)
        return 0;
 }
 
-#ifdef CONFIG_ARCH_OMAP15XX
-/*
- * OMAP-1510 specific Local Bus clock on/off
- */
-static int omap_1510_local_bus_power(int on)
-{
-       if (on) {
-               omap_writel((1 << 1) | (1 << 0), OMAP1510_LB_MMU_CTL);
-               udelay(200);
-       } else {
-               omap_writel(0, OMAP1510_LB_MMU_CTL);
-       }
-
-       return 0;
-}
-
-/*
- * OMAP-1510 specific Local Bus initialization
- * NOTE: This assumes 32MB memory size in OMAP1510LB_MEMSIZE.
- *       See also arch/mach-omap/memory.h for __virt_to_dma() and
- *       __dma_to_virt() which need to match with the physical
- *       Local Bus address below.
- */
-static int omap_1510_local_bus_init(void)
-{
-       unsigned int tlb;
-       unsigned long lbaddr, physaddr;
-
-       omap_writel((omap_readl(OMAP1510_LB_CLOCK_DIV) & 0xfffffff8) | 0x4,
-              OMAP1510_LB_CLOCK_DIV);
-
-       /* Configure the Local Bus MMU table */
-       for (tlb = 0; tlb < OMAP1510_LB_MEMSIZE; tlb++) {
-               lbaddr = tlb * 0x00100000 + OMAP1510_LB_OFFSET;
-               physaddr = tlb * 0x00100000 + PHYS_OFFSET;
-               omap_writel((lbaddr & 0x0fffffff) >> 22, OMAP1510_LB_MMU_CAM_H);
-               omap_writel(((lbaddr & 0x003ffc00) >> 6) | 0xc,
-                      OMAP1510_LB_MMU_CAM_L);
-               omap_writel(physaddr >> 16, OMAP1510_LB_MMU_RAM_H);
-               omap_writel((physaddr & 0x0000fc00) | 0x300, OMAP1510_LB_MMU_RAM_L);
-               omap_writel(tlb << 4, OMAP1510_LB_MMU_LCK);
-               omap_writel(0x1, OMAP1510_LB_MMU_LD_TLB);
-       }
-
-       /* Enable the walking table */
-       omap_writel(omap_readl(OMAP1510_LB_MMU_CTL) | (1 << 3), OMAP1510_LB_MMU_CTL);
-       udelay(200);
-
-       return 0;
-}
-#else
-#define omap_1510_local_bus_power(x)   {}
-#define omap_1510_local_bus_init()     {}
-#endif
-
 #ifdef CONFIG_USB_OTG
 
 static void start_hnp(struct ohci_hcd *ohci)
@@ -229,10 +163,8 @@ static int ohci_omap_reset(struct usb_hcd *hcd)
 
        omap_ohci_clock_power(priv, 1);
 
-       if (cpu_is_omap15xx()) {
-               omap_1510_local_bus_power(1);
-               omap_1510_local_bus_init();
-       }
+       if (config->lb_reset)
+               config->lb_reset();
 
        ret = ohci_setup(hcd);
        if (ret < 0)
index 6e784f2..eb46e64 100644 (file)
@@ -408,40 +408,38 @@ static int xhci_dbc_tty_register_device(struct xhci_dbc *dbc)
                return -EBUSY;
 
        xhci_dbc_tty_init_port(dbc, port);
-       tty_dev = tty_port_register_device(&port->port,
-                                          dbc_tty_driver, 0, NULL);
-       if (IS_ERR(tty_dev)) {
-               ret = PTR_ERR(tty_dev);
-               goto register_fail;
-       }
 
        ret = kfifo_alloc(&port->write_fifo, DBC_WRITE_BUF_SIZE, GFP_KERNEL);
        if (ret)
-               goto buf_alloc_fail;
+               goto err_exit_port;
 
        ret = xhci_dbc_alloc_requests(dbc, BULK_IN, &port->read_pool,
                                      dbc_read_complete);
        if (ret)
-               goto request_fail;
+               goto err_free_fifo;
 
        ret = xhci_dbc_alloc_requests(dbc, BULK_OUT, &port->write_pool,
                                      dbc_write_complete);
        if (ret)
-               goto request_fail;
+               goto err_free_requests;
+
+       tty_dev = tty_port_register_device(&port->port,
+                                          dbc_tty_driver, 0, NULL);
+       if (IS_ERR(tty_dev)) {
+               ret = PTR_ERR(tty_dev);
+               goto err_free_requests;
+       }
 
        port->registered = true;
 
        return 0;
 
-request_fail:
+err_free_requests:
        xhci_dbc_free_requests(&port->read_pool);
        xhci_dbc_free_requests(&port->write_pool);
+err_free_fifo:
        kfifo_free(&port->write_fifo);
-
-buf_alloc_fail:
-       tty_unregister_device(dbc_tty_driver, 0);
-
-register_fail:
+err_exit_port:
        xhci_dbc_tty_exit_port(port);
 
        dev_err(dbc->dev, "can't register tty port, err %d\n", ret);
index 2c9f25c..2484a9d 100644 (file)
@@ -30,6 +30,7 @@
 #define PCI_VENDOR_ID_FRESCO_LOGIC     0x1b73
 #define PCI_DEVICE_ID_FRESCO_LOGIC_PDK 0x1000
 #define PCI_DEVICE_ID_FRESCO_LOGIC_FL1009      0x1009
+#define PCI_DEVICE_ID_FRESCO_LOGIC_FL1100      0x1100
 #define PCI_DEVICE_ID_FRESCO_LOGIC_FL1400      0x1400
 
 #define PCI_VENDOR_ID_ETRON            0x1b6f
@@ -113,6 +114,7 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci)
        /* Look for vendor-specific quirks */
        if (pdev->vendor == PCI_VENDOR_ID_FRESCO_LOGIC &&
                        (pdev->device == PCI_DEVICE_ID_FRESCO_LOGIC_PDK ||
+                        pdev->device == PCI_DEVICE_ID_FRESCO_LOGIC_FL1100 ||
                         pdev->device == PCI_DEVICE_ID_FRESCO_LOGIC_FL1400)) {
                if (pdev->device == PCI_DEVICE_ID_FRESCO_LOGIC_PDK &&
                                pdev->revision == 0x0) {
@@ -279,8 +281,10 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci)
                        pdev->device == 0x3432)
                xhci->quirks |= XHCI_BROKEN_STREAMS;
 
-       if (pdev->vendor == PCI_VENDOR_ID_VIA && pdev->device == 0x3483)
+       if (pdev->vendor == PCI_VENDOR_ID_VIA && pdev->device == 0x3483) {
                xhci->quirks |= XHCI_LPM_SUPPORT;
+               xhci->quirks |= XHCI_EP_CTX_BROKEN_DCS;
+       }
 
        if (pdev->vendor == PCI_VENDOR_ID_ASMEDIA &&
                pdev->device == PCI_DEVICE_ID_ASMEDIA_1042_XHCI)
index e676749..311597b 100644 (file)
@@ -366,16 +366,22 @@ static void xhci_handle_stopped_cmd_ring(struct xhci_hcd *xhci,
 /* Must be called with xhci->lock held, releases and aquires lock back */
 static int xhci_abort_cmd_ring(struct xhci_hcd *xhci, unsigned long flags)
 {
-       u64 temp_64;
+       u32 temp_32;
        int ret;
 
        xhci_dbg(xhci, "Abort command ring\n");
 
        reinit_completion(&xhci->cmd_ring_stop_completion);
 
-       temp_64 = xhci_read_64(xhci, &xhci->op_regs->cmd_ring);
-       xhci_write_64(xhci, temp_64 | CMD_RING_ABORT,
-                       &xhci->op_regs->cmd_ring);
+       /*
+        * The control bits like command stop, abort are located in lower
+        * dword of the command ring control register. Limit the write
+        * to the lower dword to avoid corrupting the command ring pointer
+        * in case if the command ring is stopped by the time upper dword
+        * is written.
+        */
+       temp_32 = readl(&xhci->op_regs->cmd_ring);
+       writel(temp_32 | CMD_RING_ABORT, &xhci->op_regs->cmd_ring);
 
        /* Section 4.6.1.2 of xHCI 1.0 spec says software should also time the
         * completion of the Command Abort operation. If CRR is not negated in 5
@@ -559,8 +565,11 @@ static int xhci_move_dequeue_past_td(struct xhci_hcd *xhci,
        struct xhci_ring *ep_ring;
        struct xhci_command *cmd;
        struct xhci_segment *new_seg;
+       struct xhci_segment *halted_seg = NULL;
        union xhci_trb *new_deq;
        int new_cycle;
+       union xhci_trb *halted_trb;
+       int index = 0;
        dma_addr_t addr;
        u64 hw_dequeue;
        bool cycle_found = false;
@@ -598,7 +607,27 @@ static int xhci_move_dequeue_past_td(struct xhci_hcd *xhci,
        hw_dequeue = xhci_get_hw_deq(xhci, dev, ep_index, stream_id);
        new_seg = ep_ring->deq_seg;
        new_deq = ep_ring->dequeue;
-       new_cycle = hw_dequeue & 0x1;
+
+       /*
+        * Quirk: xHC write-back of the DCS field in the hardware dequeue
+        * pointer is wrong - use the cycle state of the TRB pointed to by
+        * the dequeue pointer.
+        */
+       if (xhci->quirks & XHCI_EP_CTX_BROKEN_DCS &&
+           !(ep->ep_state & EP_HAS_STREAMS))
+               halted_seg = trb_in_td(xhci, td->start_seg,
+                                      td->first_trb, td->last_trb,
+                                      hw_dequeue & ~0xf, false);
+       if (halted_seg) {
+               index = ((dma_addr_t)(hw_dequeue & ~0xf) - halted_seg->dma) /
+                        sizeof(*halted_trb);
+               halted_trb = &halted_seg->trbs[index];
+               new_cycle = halted_trb->generic.field[3] & 0x1;
+               xhci_dbg(xhci, "Endpoint DCS = %d TRB index = %d cycle = %d\n",
+                        (u8)(hw_dequeue & 0x1), index, new_cycle);
+       } else {
+               new_cycle = hw_dequeue & 0x1;
+       }
 
        /*
         * We want to find the pointer, segment and cycle state of the new trb
index 575fa89..1bf494b 100644 (file)
@@ -1787,7 +1787,6 @@ static int tegra_xusb_remove(struct platform_device *pdev)
        return 0;
 }
 
-#if IS_ENABLED(CONFIG_PM) || IS_ENABLED(CONFIG_PM_SLEEP)
 static bool xhci_hub_ports_suspended(struct xhci_hub *hub)
 {
        struct device *dev = hub->hcd->self.controller;
@@ -2102,7 +2101,7 @@ out:
        return err;
 }
 
-static int tegra_xusb_suspend(struct device *dev)
+static __maybe_unused int tegra_xusb_suspend(struct device *dev)
 {
        struct tegra_xusb *tegra = dev_get_drvdata(dev);
        int err;
@@ -2144,7 +2143,7 @@ out:
        return err;
 }
 
-static int tegra_xusb_resume(struct device *dev)
+static __maybe_unused int tegra_xusb_resume(struct device *dev)
 {
        struct tegra_xusb *tegra = dev_get_drvdata(dev);
        int err;
@@ -2174,10 +2173,8 @@ static int tegra_xusb_resume(struct device *dev)
 
        return 0;
 }
-#endif
 
-#ifdef CONFIG_PM
-static int tegra_xusb_runtime_suspend(struct device *dev)
+static __maybe_unused int tegra_xusb_runtime_suspend(struct device *dev)
 {
        struct tegra_xusb *tegra = dev_get_drvdata(dev);
        int ret;
@@ -2190,7 +2187,7 @@ static int tegra_xusb_runtime_suspend(struct device *dev)
        return ret;
 }
 
-static int tegra_xusb_runtime_resume(struct device *dev)
+static __maybe_unused int tegra_xusb_runtime_resume(struct device *dev)
 {
        struct tegra_xusb *tegra = dev_get_drvdata(dev);
        int err;
@@ -2201,7 +2198,6 @@ static int tegra_xusb_runtime_resume(struct device *dev)
 
        return err;
 }
-#endif
 
 static const struct dev_pm_ops tegra_xusb_pm_ops = {
        SET_RUNTIME_PM_OPS(tegra_xusb_runtime_suspend,
index 93c38b5..541fe4d 100644 (file)
@@ -3214,10 +3214,13 @@ static void xhci_endpoint_reset(struct usb_hcd *hcd,
                return;
 
        /* Bail out if toggle is already being cleared by a endpoint reset */
+       spin_lock_irqsave(&xhci->lock, flags);
        if (ep->ep_state & EP_HARD_CLEAR_TOGGLE) {
                ep->ep_state &= ~EP_HARD_CLEAR_TOGGLE;
+               spin_unlock_irqrestore(&xhci->lock, flags);
                return;
        }
+       spin_unlock_irqrestore(&xhci->lock, flags);
        /* Only interrupt and bulk ep's use data toggle, USB2 spec 5.5.4-> */
        if (usb_endpoint_xfer_control(&host_ep->desc) ||
            usb_endpoint_xfer_isoc(&host_ep->desc))
@@ -3303,8 +3306,10 @@ static void xhci_endpoint_reset(struct usb_hcd *hcd,
        xhci_free_command(xhci, cfg_cmd);
 cleanup:
        xhci_free_command(xhci, stop_cmd);
+       spin_lock_irqsave(&xhci->lock, flags);
        if (ep->ep_state & EP_SOFT_CLEAR_TOGGLE)
                ep->ep_state &= ~EP_SOFT_CLEAR_TOGGLE;
+       spin_unlock_irqrestore(&xhci->lock, flags);
 }
 
 static int xhci_check_streams_endpoint(struct xhci_hcd *xhci,
index dca6181..5a75fe5 100644 (file)
@@ -1899,6 +1899,7 @@ struct xhci_hcd {
 #define XHCI_SG_TRB_CACHE_SIZE_QUIRK   BIT_ULL(39)
 #define XHCI_NO_SOFT_RETRY     BIT_ULL(40)
 #define XHCI_BROKEN_D3COLD     BIT_ULL(41)
+#define XHCI_EP_CTX_BROKEN_DCS BIT_ULL(42)
 
        unsigned int            num_active_eps;
        unsigned int            limit_active_eps;
index ce9fc46..b593583 100644 (file)
@@ -899,11 +899,13 @@ static int dsps_probe(struct platform_device *pdev)
        if (usb_get_dr_mode(&pdev->dev) == USB_DR_MODE_PERIPHERAL) {
                ret = dsps_setup_optional_vbus_irq(pdev, glue);
                if (ret)
-                       goto err;
+                       goto unregister_pdev;
        }
 
        return 0;
 
+unregister_pdev:
+       platform_device_unregister(glue->musb);
 err:
        pm_runtime_disable(&pdev->dev);
        iounmap(glue->usbss_base);
index 6cfb5d3..a484ff5 100644 (file)
@@ -246,11 +246,13 @@ static void option_instat_callback(struct urb *urb);
 /* These Quectel products use Quectel's vendor ID */
 #define QUECTEL_PRODUCT_EC21                   0x0121
 #define QUECTEL_PRODUCT_EC25                   0x0125
+#define QUECTEL_PRODUCT_EG91                   0x0191
 #define QUECTEL_PRODUCT_EG95                   0x0195
 #define QUECTEL_PRODUCT_BG96                   0x0296
 #define QUECTEL_PRODUCT_EP06                   0x0306
 #define QUECTEL_PRODUCT_EM12                   0x0512
 #define QUECTEL_PRODUCT_RM500Q                 0x0800
+#define QUECTEL_PRODUCT_EC200S_CN              0x6002
 #define QUECTEL_PRODUCT_EC200T                 0x6026
 
 #define CMOTECH_VENDOR_ID                      0x16d8
@@ -1111,6 +1113,9 @@ static const struct usb_device_id option_ids[] = {
        { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EC25, 0xff, 0xff, 0xff),
          .driver_info = NUMEP2 },
        { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EC25, 0xff, 0, 0) },
+       { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EG91, 0xff, 0xff, 0xff),
+         .driver_info = NUMEP2 },
+       { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EG91, 0xff, 0, 0) },
        { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EG95, 0xff, 0xff, 0xff),
          .driver_info = NUMEP2 },
        { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EG95, 0xff, 0, 0) },
@@ -1128,6 +1133,7 @@ static const struct usb_device_id option_ids[] = {
        { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RM500Q, 0xff, 0, 0) },
        { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RM500Q, 0xff, 0xff, 0x10),
          .driver_info = ZLP },
+       { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EC200S_CN, 0xff, 0, 0) },
        { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EC200T, 0xff, 0, 0) },
 
        { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6001) },
@@ -1227,6 +1233,8 @@ static const struct usb_device_id option_ids[] = {
          .driver_info = NCTRL(0) | RSVD(1) | RSVD(2) },
        { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1203, 0xff),    /* Telit LE910Cx (RNDIS) */
          .driver_info = NCTRL(2) | RSVD(3) },
+       { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1204, 0xff),    /* Telit LE910Cx (MBIM) */
+         .driver_info = NCTRL(0) | RSVD(1) },
        { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE910_USBCFG4),
          .driver_info = NCTRL(0) | RSVD(1) | RSVD(2) | RSVD(3) },
        { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE920),
index 83da823..c18bf81 100644 (file)
@@ -165,6 +165,7 @@ static const struct usb_device_id id_table[] = {
        {DEVICE_SWI(0x1199, 0x907b)},   /* Sierra Wireless EM74xx */
        {DEVICE_SWI(0x1199, 0x9090)},   /* Sierra Wireless EM7565 QDL */
        {DEVICE_SWI(0x1199, 0x9091)},   /* Sierra Wireless EM7565 */
+       {DEVICE_SWI(0x1199, 0x90d2)},   /* Sierra Wireless EM9191 QDL */
        {DEVICE_SWI(0x413c, 0x81a2)},   /* Dell Wireless 5806 Gobi(TM) 4G LTE Mobile Broadband Card */
        {DEVICE_SWI(0x413c, 0x81a3)},   /* Dell Wireless 5570 HSPA+ (42Mbps) Mobile Broadband Card */
        {DEVICE_SWI(0x413c, 0x81a4)},   /* Dell Wireless 5570e HSPA+ (42Mbps) Mobile Broadband Card */
index 9858716..c15eec9 100644 (file)
@@ -696,7 +696,7 @@ irqreturn_t tcpci_irq(struct tcpci *tcpci)
                tcpm_pd_receive(tcpci->port, &msg);
        }
 
-       if (status & TCPC_ALERT_EXTENDED_STATUS) {
+       if (tcpci->data->vbus_vsafe0v && (status & TCPC_ALERT_EXTENDED_STATUS)) {
                ret = regmap_read(tcpci->regmap, TCPC_EXTENDED_STATUS, &raw);
                if (!ret && (raw & TCPC_EXTENDED_STATUS_VSAFE0V))
                        tcpm_vbus_change(tcpci->port);
index a4d3720..7f2f3ff 100644 (file)
@@ -4876,6 +4876,7 @@ static void _tcpm_cc_change(struct tcpm_port *port, enum typec_cc_status cc1,
                        tcpm_set_state(port, SRC_ATTACH_WAIT, 0);
                break;
        case SRC_ATTACHED:
+       case SRC_STARTUP:
        case SRC_SEND_CAPABILITIES:
        case SRC_READY:
                if (tcpm_port_is_disconnected(port) ||
index 21b3ae2..ea4cc0a 100644 (file)
@@ -625,10 +625,6 @@ static int tps6598x_probe(struct i2c_client *client)
        if (ret < 0)
                return ret;
 
-       fwnode = device_get_named_child_node(&client->dev, "connector");
-       if (!fwnode)
-               return -ENODEV;
-
        /*
         * This fwnode has a "compatible" property, but is never populated as a
         * struct device. Instead we simply parse it to read the properties.
@@ -636,7 +632,9 @@ static int tps6598x_probe(struct i2c_client *client)
         * with existing DT files, we work around this by deleting any
         * fwnode_links to/from this fwnode.
         */
-       fw_devlink_purge_absent_suppliers(fwnode);
+       fwnode = device_get_named_child_node(&client->dev, "connector");
+       if (fwnode)
+               fw_devlink_purge_absent_suppliers(fwnode);
 
        tps->role_sw = fwnode_usb_role_switch_get(fwnode);
        if (IS_ERR(tps->role_sw)) {
index b26b79d..6ed5e60 100644 (file)
@@ -2193,8 +2193,9 @@ config FB_HYPERV
          This framebuffer driver supports Microsoft Hyper-V Synthetic Video.
 
 config FB_SIMPLE
-       bool "Simple framebuffer support"
-       depends on (FB = y) && !DRM_SIMPLEDRM
+       tristate "Simple framebuffer support"
+       depends on FB
+       depends on !DRM_SIMPLEDRM
        select FB_CFB_FILLRECT
        select FB_CFB_COPYAREA
        select FB_CFB_IMAGEBLIT
index c5b99a4..6b4d5a7 100644 (file)
@@ -1267,7 +1267,7 @@ static struct platform_device *gbefb_device;
 static int __init gbefb_init(void)
 {
        int ret = platform_driver_register(&gbefb_driver);
-       if (!ret) {
+       if (IS_ENABLED(CONFIG_SGI_IP32) && !ret) {
                gbefb_device = platform_device_alloc("gbefb", 0);
                if (gbefb_device) {
                        ret = platform_device_add(gbefb_device);
index 22f5aff..1b2c3ac 100644 (file)
@@ -241,7 +241,7 @@ config XEN_PRIVCMD
 
 config XEN_ACPI_PROCESSOR
        tristate "Xen ACPI processor"
-       depends on XEN && XEN_DOM0 && X86 && ACPI_PROCESSOR && CPU_FREQ
+       depends on XEN && XEN_PV_DOM0 && X86 && ACPI_PROCESSOR && CPU_FREQ
        default m
        help
          This ACPI processor uploads Power Management information to the Xen
@@ -259,7 +259,7 @@ config XEN_ACPI_PROCESSOR
 
 config XEN_MCE_LOG
        bool "Xen platform mcelog"
-       depends on XEN_DOM0 && X86_MCE
+       depends on XEN_PV_DOM0 && X86_MCE
        help
          Allow kernel fetching MCE error from Xen platform and
          converting it into Linux mcelog format for mcelog tools
index 43ebfe3..3a50f09 100644 (file)
@@ -491,12 +491,12 @@ static enum bp_state decrease_reservation(unsigned long nr_pages, gfp_t gfp)
 }
 
 /*
- * Stop waiting if either state is not BP_EAGAIN and ballooning action is
- * needed, or if the credit has changed while state is BP_EAGAIN.
+ * Stop waiting if either state is BP_DONE and ballooning action is
+ * needed, or if the credit has changed while state is not BP_DONE.
  */
 static bool balloon_thread_cond(enum bp_state state, long credit)
 {
-       if (state != BP_EAGAIN)
+       if (state == BP_DONE)
                credit = 0;
 
        return current_credit() != credit || kthread_should_stop();
@@ -516,10 +516,19 @@ static int balloon_thread(void *unused)
 
        set_freezable();
        for (;;) {
-               if (state == BP_EAGAIN)
-                       timeout = balloon_stats.schedule_delay * HZ;
-               else
+               switch (state) {
+               case BP_DONE:
+               case BP_ECANCELED:
                        timeout = 3600 * HZ;
+                       break;
+               case BP_EAGAIN:
+                       timeout = balloon_stats.schedule_delay * HZ;
+                       break;
+               case BP_WAIT:
+                       timeout = HZ;
+                       break;
+               }
+
                credit = current_credit();
 
                wait_event_freezable_timeout(balloon_thread_wq,
index 720a7b7..3369734 100644 (file)
@@ -257,7 +257,7 @@ static long privcmd_ioctl_mmap(struct file *file, void __user *udata)
        LIST_HEAD(pagelist);
        struct mmap_gfn_state state;
 
-       /* We only support privcmd_ioctl_mmap_batch for auto translated. */
+       /* We only support privcmd_ioctl_mmap_batch for non-auto-translated. */
        if (xen_feature(XENFEAT_auto_translated_physmap))
                return -ENOSYS;
 
@@ -420,7 +420,7 @@ static int alloc_empty_pages(struct vm_area_struct *vma, int numpgs)
        int rc;
        struct page **pages;
 
-       pages = kcalloc(numpgs, sizeof(pages[0]), GFP_KERNEL);
+       pages = kvcalloc(numpgs, sizeof(pages[0]), GFP_KERNEL);
        if (pages == NULL)
                return -ENOMEM;
 
@@ -428,7 +428,7 @@ static int alloc_empty_pages(struct vm_area_struct *vma, int numpgs)
        if (rc != 0) {
                pr_warn("%s Could not alloc %d pfns rc:%d\n", __func__,
                        numpgs, rc);
-               kfree(pages);
+               kvfree(pages);
                return -ENOMEM;
        }
        BUG_ON(vma->vm_private_data != NULL);
@@ -803,21 +803,21 @@ static long privcmd_ioctl_mmap_resource(struct file *file,
                unsigned int domid =
                        (xdata.flags & XENMEM_rsrc_acq_caller_owned) ?
                        DOMID_SELF : kdata.dom;
-               int num;
+               int num, *errs = (int *)pfns;
 
+               BUILD_BUG_ON(sizeof(*errs) > sizeof(*pfns));
                num = xen_remap_domain_mfn_array(vma,
                                                 kdata.addr & PAGE_MASK,
-                                                pfns, kdata.num, (int *)pfns,
+                                                pfns, kdata.num, errs,
                                                 vma->vm_page_prot,
-                                                domid,
-                                                vma->vm_private_data);
+                                                domid);
                if (num < 0)
                        rc = num;
                else if (num != kdata.num) {
                        unsigned int i;
 
                        for (i = 0; i < num; i++) {
-                               rc = pfns[i];
+                               rc = errs[i];
                                if (rc < 0)
                                        break;
                        }
@@ -912,7 +912,7 @@ static void privcmd_close(struct vm_area_struct *vma)
        else
                pr_crit("unable to unmap MFN range: leaking %d pages. rc=%d\n",
                        numpgs, rc);
-       kfree(pages);
+       kvfree(pages);
 }
 
 static vm_fault_t privcmd_fault(struct vm_fault *vmf)
index eb2151f..1769a44 100644 (file)
@@ -23,7 +23,7 @@ struct fscache_netfs v9fs_cache_netfs = {
        .version        = 0,
 };
 
-/**
+/*
  * v9fs_random_cachetag - Generate a random tag to be associated
  *                       with a new cache session.
  *
@@ -233,7 +233,7 @@ static void v9fs_vfs_readpage_complete(struct page *page, void *data,
        unlock_page(page);
 }
 
-/**
+/*
  * __v9fs_readpage_from_fscache - read a page from cache
  *
  * Returns 0 if the pages are in cache and a BIO is submitted,
@@ -268,7 +268,7 @@ int __v9fs_readpage_from_fscache(struct inode *inode, struct page *page)
        }
 }
 
-/**
+/*
  * __v9fs_readpages_from_fscache - read multiple pages from cache
  *
  * Returns 0 if the pages are in cache and a BIO is submitted,
@@ -308,7 +308,7 @@ int __v9fs_readpages_from_fscache(struct inode *inode,
        }
 }
 
-/**
+/*
  * __v9fs_readpage_to_fscache - write a page to the cache
  *
  */
index 9d9de62..b8863dd 100644 (file)
 #include "v9fs_vfs.h"
 #include "fid.h"
 
+static inline void __add_fid(struct dentry *dentry, struct p9_fid *fid)
+{
+       hlist_add_head(&fid->dlist, (struct hlist_head *)&dentry->d_fsdata);
+}
+
+
 /**
  * v9fs_fid_add - add a fid to a dentry
  * @dentry: dentry that the fid is being added to
  * @fid: fid to add
  *
  */
-
-static inline void __add_fid(struct dentry *dentry, struct p9_fid *fid)
-{
-       hlist_add_head(&fid->dlist, (struct hlist_head *)&dentry->d_fsdata);
-}
-
 void v9fs_fid_add(struct dentry *dentry, struct p9_fid *fid)
 {
        spin_lock(&dentry->d_lock);
@@ -67,7 +67,7 @@ static struct p9_fid *v9fs_fid_find_inode(struct inode *inode, kuid_t uid)
 
 /**
  * v9fs_open_fid_add - add an open fid to an inode
- * @dentry: inode that the fid is being added to
+ * @inode: inode that the fid is being added to
  * @fid: fid to add
  *
  */
index cdb9950..2e0fa7c 100644 (file)
@@ -155,6 +155,7 @@ int v9fs_show_options(struct seq_file *m, struct dentry *root)
 /**
  * v9fs_parse_options - parse mount options into session structure
  * @v9ses: existing v9fs session information
+ * @opts: The mount option string
  *
  * Return 0 upon success, -ERRNO upon failure.
  */
@@ -542,12 +543,9 @@ extern int v9fs_error_init(void);
 static struct kobject *v9fs_kobj;
 
 #ifdef CONFIG_9P_FSCACHE
-/**
- * caches_show - list caches associated with a session
- *
- * Returns the size of buffer written.
+/*
+ * List caches associated with a session
  */
-
 static ssize_t caches_show(struct kobject *kobj,
                           struct kobj_attribute *attr,
                           char *buf)
index cce9ace..1c4f1b3 100644 (file)
@@ -30,8 +30,7 @@
 
 /**
  * v9fs_fid_readpage - read an entire page in from 9P
- *
- * @fid: fid being read
+ * @data: Opaque pointer to the fid being read
  * @page: structure to page
  *
  */
@@ -116,6 +115,8 @@ static int v9fs_vfs_readpages(struct file *filp, struct address_space *mapping,
 
 /**
  * v9fs_release_page - release the private state associated with a page
+ * @page: The page to be released
+ * @gfp: The caller's allocation restrictions
  *
  * Returns 1 if the page can be released, false otherwise.
  */
@@ -129,9 +130,9 @@ static int v9fs_release_page(struct page *page, gfp_t gfp)
 
 /**
  * v9fs_invalidate_page - Invalidate a page completely or partially
- *
- * @page: structure to page
- * @offset: offset in the page
+ * @page: The page to be invalidated
+ * @offset: offset of the invalidated region
+ * @length: length of the invalidated region
  */
 
 static void v9fs_invalidate_page(struct page *page, unsigned int offset,
@@ -199,6 +200,8 @@ static int v9fs_vfs_writepage(struct page *page, struct writeback_control *wbc)
 
 /**
  * v9fs_launder_page - Writeback a dirty page
+ * @page: The page to be cleaned up
+ *
  * Returns 0 on success.
  */
 
@@ -219,6 +222,7 @@ static int v9fs_launder_page(struct page *page)
 /**
  * v9fs_direct_IO - 9P address space operation for direct I/O
  * @iocb: target I/O control block
+ * @iter: The data/buffer to use
  *
  * The presence of v9fs_direct_IO() in the address space ops vector
  * allowes open() O_DIRECT flags which would have failed otherwise.
index aab5e65..246235e 100644 (file)
@@ -359,14 +359,11 @@ out_err:
 }
 
 /**
- * v9fs_file_read - read from a file
- * @filp: file pointer to read
- * @udata: user data buffer to read data into
- * @count: size of buffer
- * @offset: offset at which to read data
+ * v9fs_file_read_iter - read from a file
+ * @iocb: The operation parameters
+ * @to: The buffer to read into
  *
  */
-
 static ssize_t
 v9fs_file_read_iter(struct kiocb *iocb, struct iov_iter *to)
 {
@@ -388,11 +385,9 @@ v9fs_file_read_iter(struct kiocb *iocb, struct iov_iter *to)
 }
 
 /**
- * v9fs_file_write - write to a file
- * @filp: file pointer to write
- * @data: data buffer to write data from
- * @count: size of buffer
- * @offset: offset at which to write data
+ * v9fs_file_write_iter - write to a file
+ * @iocb: The operation parameters
+ * @from: The data to write
  *
  */
 static ssize_t
@@ -561,11 +556,9 @@ out_unlock:
 }
 
 /**
- * v9fs_mmap_file_read - read from a file
- * @filp: file pointer to read
- * @data: user data buffer to read data into
- * @count: size of buffer
- * @offset: offset at which to read data
+ * v9fs_mmap_file_read_iter - read from a file
+ * @iocb: The operation parameters
+ * @to: The buffer to read into
  *
  */
 static ssize_t
@@ -576,11 +569,9 @@ v9fs_mmap_file_read_iter(struct kiocb *iocb, struct iov_iter *to)
 }
 
 /**
- * v9fs_mmap_file_write - write to a file
- * @filp: file pointer to write
- * @data: data buffer to write data from
- * @count: size of buffer
- * @offset: offset at which to write data
+ * v9fs_mmap_file_write_iter - write to a file
+ * @iocb: The operation parameters
+ * @from: The data to write
  *
  */
 static ssize_t
index 7957065..08f48b7 100644 (file)
@@ -218,7 +218,7 @@ v9fs_blank_wstat(struct p9_wstat *wstat)
 
 /**
  * v9fs_alloc_inode - helper function to allocate an inode
- *
+ * @sb: The superblock to allocate the inode from
  */
 struct inode *v9fs_alloc_inode(struct super_block *sb)
 {
@@ -238,7 +238,7 @@ struct inode *v9fs_alloc_inode(struct super_block *sb)
 
 /**
  * v9fs_free_inode - destroy an inode
- *
+ * @inode: The inode to be freed
  */
 
 void v9fs_free_inode(struct inode *inode)
@@ -343,7 +343,7 @@ error:
  * v9fs_get_inode - helper function to setup an inode
  * @sb: superblock
  * @mode: mode to setup inode with
- *
+ * @rdev: The device numbers to set
  */
 
 struct inode *v9fs_get_inode(struct super_block *sb, umode_t mode, dev_t rdev)
@@ -369,7 +369,7 @@ struct inode *v9fs_get_inode(struct super_block *sb, umode_t mode, dev_t rdev)
 }
 
 /**
- * v9fs_clear_inode - release an inode
+ * v9fs_evict_inode - Remove an inode from the inode cache
  * @inode: inode to release
  *
  */
@@ -665,14 +665,15 @@ error:
 
 /**
  * v9fs_vfs_create - VFS hook to create a regular file
+ * @mnt_userns: The user namespace of the mount
+ * @dir: The parent directory
+ * @dentry: The name of file to be created
+ * @mode: The UNIX file mode to set
+ * @excl: True if the file must not yet exist
  *
  * open(.., O_CREAT) is handled in v9fs_vfs_atomic_open().  This is only called
  * for mknod(2).
  *
- * @dir: directory inode that is being created
- * @dentry:  dentry that is being deleted
- * @mode: create permissions
- *
  */
 
 static int
@@ -696,6 +697,7 @@ v9fs_vfs_create(struct user_namespace *mnt_userns, struct inode *dir,
 
 /**
  * v9fs_vfs_mkdir - VFS mkdir hook to create a directory
+ * @mnt_userns: The user namespace of the mount
  * @dir:  inode that is being unlinked
  * @dentry: dentry that is being unlinked
  * @mode: mode for new directory
@@ -900,10 +902,12 @@ int v9fs_vfs_rmdir(struct inode *i, struct dentry *d)
 
 /**
  * v9fs_vfs_rename - VFS hook to rename an inode
+ * @mnt_userns: The user namespace of the mount
  * @old_dir:  old dir inode
  * @old_dentry: old dentry
  * @new_dir: new dir inode
  * @new_dentry: new dentry
+ * @flags: RENAME_* flags
  *
  */
 
@@ -1009,6 +1013,7 @@ done:
 
 /**
  * v9fs_vfs_getattr - retrieve file metadata
+ * @mnt_userns: The user namespace of the mount
  * @path: Object to query
  * @stat: metadata structure to populate
  * @request_mask: Mask of STATX_xxx flags indicating the caller's interests
@@ -1050,6 +1055,7 @@ v9fs_vfs_getattr(struct user_namespace *mnt_userns, const struct path *path,
 
 /**
  * v9fs_vfs_setattr - set file metadata
+ * @mnt_userns: The user namespace of the mount
  * @dentry: file whose metadata to set
  * @iattr: metadata assignment structure
  *
@@ -1285,6 +1291,7 @@ static int v9fs_vfs_mkspecial(struct inode *dir, struct dentry *dentry,
 
 /**
  * v9fs_vfs_symlink - helper function to create symlinks
+ * @mnt_userns: The user namespace of the mount
  * @dir: directory inode containing symlink
  * @dentry: dentry for symlink
  * @symname: symlink data
@@ -1340,6 +1347,7 @@ v9fs_vfs_link(struct dentry *old_dentry, struct inode *dir,
 
 /**
  * v9fs_vfs_mknod - create a special file
+ * @mnt_userns: The user namespace of the mount
  * @dir: inode destination for new link
  * @dentry: dentry for file
  * @mode: mode for creation
index e1c0240..01b9e12 100644 (file)
@@ -37,7 +37,10 @@ v9fs_vfs_mknod_dotl(struct user_namespace *mnt_userns, struct inode *dir,
                    struct dentry *dentry, umode_t omode, dev_t rdev);
 
 /**
- * v9fs_get_fsgid_for_create - Helper function to get the gid for creating a
+ * v9fs_get_fsgid_for_create - Helper function to get the gid for a new object
+ * @dir_inode: The directory inode
+ *
+ * Helper function to get the gid for creating a
  * new file system object. This checks the S_ISGID to determine the owning
  * group of the new file system object.
  */
@@ -211,12 +214,13 @@ int v9fs_open_to_dotl_flags(int flags)
 
 /**
  * v9fs_vfs_create_dotl - VFS hook to create files for 9P2000.L protocol.
+ * @mnt_userns: The user namespace of the mount
  * @dir: directory inode that is being created
  * @dentry:  dentry that is being deleted
  * @omode: create permissions
+ * @excl: True if the file must not yet exist
  *
  */
-
 static int
 v9fs_vfs_create_dotl(struct user_namespace *mnt_userns, struct inode *dir,
                     struct dentry *dentry, umode_t omode, bool excl)
@@ -361,6 +365,7 @@ err_clunk_old_fid:
 
 /**
  * v9fs_vfs_mkdir_dotl - VFS mkdir hook to create a directory
+ * @mnt_userns: The user namespace of the mount
  * @dir:  inode that is being unlinked
  * @dentry: dentry that is being unlinked
  * @omode: mode for new directory
@@ -537,6 +542,7 @@ static int v9fs_mapped_iattr_valid(int iattr_valid)
 
 /**
  * v9fs_vfs_setattr_dotl - set file metadata
+ * @mnt_userns: The user namespace of the mount
  * @dentry: file whose metadata to set
  * @iattr: metadata assignment structure
  *
@@ -816,6 +822,7 @@ v9fs_vfs_link_dotl(struct dentry *old_dentry, struct inode *dir,
 
 /**
  * v9fs_vfs_mknod_dotl - create a special file
+ * @mnt_userns: The user namespace of the mount
  * @dir: inode destination for new link
  * @dentry: dentry for file
  * @omode: mode for creation
index dae9a57..45cfd50 100644 (file)
@@ -86,8 +86,8 @@ static int afs_do_silly_rename(struct afs_vnode *dvnode, struct afs_vnode *vnode
        return afs_do_sync_operation(op);
 }
 
-/**
- * afs_sillyrename - Perform a silly-rename of a dentry
+/*
+ * Perform silly-rename of a dentry.
  *
  * AFS is stateless and the server doesn't know when the client is holding a
  * file open.  To prevent application problems when a file is unlinked while
index 2dfe3b3..f24370f 100644 (file)
@@ -974,8 +974,7 @@ int afs_launder_page(struct page *page)
                iov_iter_bvec(&iter, WRITE, bv, 1, bv[0].bv_len);
 
                trace_afs_page_dirty(vnode, tracepoint_string("launder"), page);
-               ret = afs_store_data(vnode, &iter, (loff_t)page->index * PAGE_SIZE,
-                                    true);
+               ret = afs_store_data(vnode, &iter, page_offset(page) + f, true);
        }
 
        trace_afs_page_dirty(vnode, tracepoint_string("laundered"), page);
index dff2c8a..c0cebcf 100644 (file)
@@ -3030,7 +3030,7 @@ struct btrfs_dir_item *
 btrfs_lookup_dir_index_item(struct btrfs_trans_handle *trans,
                            struct btrfs_root *root,
                            struct btrfs_path *path, u64 dir,
-                           u64 objectid, const char *name, int name_len,
+                           u64 index, const char *name, int name_len,
                            int mod);
 struct btrfs_dir_item *
 btrfs_search_dir_index_item(struct btrfs_root *root,
index f1274d5..7721ce0 100644 (file)
@@ -190,9 +190,20 @@ static struct btrfs_dir_item *btrfs_lookup_match_dir(
 }
 
 /*
- * lookup a directory item based on name.  'dir' is the objectid
- * we're searching in, and 'mod' tells us if you plan on deleting the
- * item (use mod < 0) or changing the options (use mod > 0)
+ * Lookup for a directory item by name.
+ *
+ * @trans:     The transaction handle to use. Can be NULL if @mod is 0.
+ * @root:      The root of the target tree.
+ * @path:      Path to use for the search.
+ * @dir:       The inode number (objectid) of the directory.
+ * @name:      The name associated to the directory entry we are looking for.
+ * @name_len:  The length of the name.
+ * @mod:       Used to indicate if the tree search is meant for a read only
+ *             lookup, for a modification lookup or for a deletion lookup, so
+ *             its value should be 0, 1 or -1, respectively.
+ *
+ * Returns: NULL if the dir item does not exists, an error pointer if an error
+ * happened, or a pointer to a dir item if a dir item exists for the given name.
  */
 struct btrfs_dir_item *btrfs_lookup_dir_item(struct btrfs_trans_handle *trans,
                                             struct btrfs_root *root,
@@ -273,27 +284,42 @@ out:
 }
 
 /*
- * lookup a directory item based on index.  'dir' is the objectid
- * we're searching in, and 'mod' tells us if you plan on deleting the
- * item (use mod < 0) or changing the options (use mod > 0)
+ * Lookup for a directory index item by name and index number.
  *
- * The name is used to make sure the index really points to the name you were
- * looking for.
+ * @trans:     The transaction handle to use. Can be NULL if @mod is 0.
+ * @root:      The root of the target tree.
+ * @path:      Path to use for the search.
+ * @dir:       The inode number (objectid) of the directory.
+ * @index:     The index number.
+ * @name:      The name associated to the directory entry we are looking for.
+ * @name_len:  The length of the name.
+ * @mod:       Used to indicate if the tree search is meant for a read only
+ *             lookup, for a modification lookup or for a deletion lookup, so
+ *             its value should be 0, 1 or -1, respectively.
+ *
+ * Returns: NULL if the dir index item does not exists, an error pointer if an
+ * error happened, or a pointer to a dir item if the dir index item exists and
+ * matches the criteria (name and index number).
  */
 struct btrfs_dir_item *
 btrfs_lookup_dir_index_item(struct btrfs_trans_handle *trans,
                            struct btrfs_root *root,
                            struct btrfs_path *path, u64 dir,
-                           u64 objectid, const char *name, int name_len,
+                           u64 index, const char *name, int name_len,
                            int mod)
 {
+       struct btrfs_dir_item *di;
        struct btrfs_key key;
 
        key.objectid = dir;
        key.type = BTRFS_DIR_INDEX_KEY;
-       key.offset = objectid;
+       key.offset = index;
 
-       return btrfs_lookup_match_dir(trans, root, path, &key, name, name_len, mod);
+       di = btrfs_lookup_match_dir(trans, root, path, &key, name, name_len, mod);
+       if (di == ERR_PTR(-ENOENT))
+               return NULL;
+
+       return di;
 }
 
 struct btrfs_dir_item *
index fc3da75..0ab456c 100644 (file)
@@ -4859,6 +4859,7 @@ struct extent_buffer *btrfs_alloc_tree_block(struct btrfs_trans_handle *trans,
 out_free_delayed:
        btrfs_free_delayed_extent_op(extent_op);
 out_free_buf:
+       btrfs_tree_unlock(buf);
        free_extent_buffer(buf);
 out_free_reserved:
        btrfs_free_reserved_extent(fs_info, ins.objectid, ins.offset, 0);
index 7ff5770..a176236 100644 (file)
@@ -734,8 +734,7 @@ int btrfs_drop_extents(struct btrfs_trans_handle *trans,
        if (args->start >= inode->disk_i_size && !args->replace_extent)
                modify_tree = 0;
 
-       update_refs = (test_bit(BTRFS_ROOT_SHAREABLE, &root->state) ||
-                      root == fs_info->tree_root);
+       update_refs = (root->root_key.objectid != BTRFS_TREE_LOG_OBJECTID);
        while (1) {
                recow = 0;
                ret = btrfs_lookup_file_extent(trans, root, path, ino,
@@ -2704,14 +2703,16 @@ int btrfs_replace_file_extents(struct btrfs_inode *inode,
                                                 drop_args.bytes_found);
                if (ret != -ENOSPC) {
                        /*
-                        * When cloning we want to avoid transaction aborts when
-                        * nothing was done and we are attempting to clone parts
-                        * of inline extents, in such cases -EOPNOTSUPP is
-                        * returned by __btrfs_drop_extents() without having
-                        * changed anything in the file.
+                        * The only time we don't want to abort is if we are
+                        * attempting to clone a partial inline extent, in which
+                        * case we'll get EOPNOTSUPP.  However if we aren't
+                        * clone we need to abort no matter what, because if we
+                        * got EOPNOTSUPP via prealloc then we messed up and
+                        * need to abort.
                         */
-                       if (extent_info && !extent_info->is_new_extent &&
-                           ret && ret != -EOPNOTSUPP)
+                       if (ret &&
+                           (ret != -EOPNOTSUPP ||
+                            (extent_info && extent_info->is_new_extent)))
                                btrfs_abort_transaction(trans, ret);
                        break;
                }
index f7efc26..b415c5e 100644 (file)
@@ -939,9 +939,11 @@ out:
 }
 
 /*
- * helper function to see if a given name and sequence number found
- * in an inode back reference are already in a directory and correctly
- * point to this inode
+ * See if a given name and sequence number found in an inode back reference are
+ * already in a directory and correctly point to this inode.
+ *
+ * Returns: < 0 on error, 0 if the directory entry does not exists and 1 if it
+ * exists.
  */
 static noinline int inode_in_dir(struct btrfs_root *root,
                                 struct btrfs_path *path,
@@ -950,29 +952,34 @@ static noinline int inode_in_dir(struct btrfs_root *root,
 {
        struct btrfs_dir_item *di;
        struct btrfs_key location;
-       int match = 0;
+       int ret = 0;
 
        di = btrfs_lookup_dir_index_item(NULL, root, path, dirid,
                                         index, name, name_len, 0);
-       if (di && !IS_ERR(di)) {
+       if (IS_ERR(di)) {
+               ret = PTR_ERR(di);
+               goto out;
+       } else if (di) {
                btrfs_dir_item_key_to_cpu(path->nodes[0], di, &location);
                if (location.objectid != objectid)
                        goto out;
-       } else
+       } else {
                goto out;
-       btrfs_release_path(path);
+       }
 
+       btrfs_release_path(path);
        di = btrfs_lookup_dir_item(NULL, root, path, dirid, name, name_len, 0);
-       if (di && !IS_ERR(di)) {
-               btrfs_dir_item_key_to_cpu(path->nodes[0], di, &location);
-               if (location.objectid != objectid)
-                       goto out;
-       } else
+       if (IS_ERR(di)) {
+               ret = PTR_ERR(di);
                goto out;
-       match = 1;
+       } else if (di) {
+               btrfs_dir_item_key_to_cpu(path->nodes[0], di, &location);
+               if (location.objectid == objectid)
+                       ret = 1;
+       }
 out:
        btrfs_release_path(path);
-       return match;
+       return ret;
 }
 
 /*
@@ -1182,7 +1189,9 @@ next:
        /* look for a conflicting sequence number */
        di = btrfs_lookup_dir_index_item(trans, root, path, btrfs_ino(dir),
                                         ref_index, name, namelen, 0);
-       if (di && !IS_ERR(di)) {
+       if (IS_ERR(di)) {
+               return PTR_ERR(di);
+       } else if (di) {
                ret = drop_one_dir_item(trans, root, path, dir, di);
                if (ret)
                        return ret;
@@ -1192,7 +1201,9 @@ next:
        /* look for a conflicting name */
        di = btrfs_lookup_dir_item(trans, root, path, btrfs_ino(dir),
                                   name, namelen, 0);
-       if (di && !IS_ERR(di)) {
+       if (IS_ERR(di)) {
+               return PTR_ERR(di);
+       } else if (di) {
                ret = drop_one_dir_item(trans, root, path, dir, di);
                if (ret)
                        return ret;
@@ -1517,10 +1528,12 @@ static noinline int add_inode_ref(struct btrfs_trans_handle *trans,
                if (ret)
                        goto out;
 
-               /* if we already have a perfect match, we're done */
-               if (!inode_in_dir(root, path, btrfs_ino(BTRFS_I(dir)),
-                                       btrfs_ino(BTRFS_I(inode)), ref_index,
-                                       name, namelen)) {
+               ret = inode_in_dir(root, path, btrfs_ino(BTRFS_I(dir)),
+                                  btrfs_ino(BTRFS_I(inode)), ref_index,
+                                  name, namelen);
+               if (ret < 0) {
+                       goto out;
+               } else if (ret == 0) {
                        /*
                         * look for a conflicting back reference in the
                         * metadata. if we find one we have to unlink that name
@@ -1580,6 +1593,7 @@ static noinline int add_inode_ref(struct btrfs_trans_handle *trans,
                        if (ret)
                                goto out;
                }
+               /* Else, ret == 1, we already have a perfect match, we're done. */
 
                ref_ptr = (unsigned long)(ref_ptr + ref_struct_size) + namelen;
                kfree(name);
@@ -1936,8 +1950,8 @@ static noinline int replay_one_name(struct btrfs_trans_handle *trans,
        struct btrfs_key log_key;
        struct inode *dir;
        u8 log_type;
-       int exists;
-       int ret = 0;
+       bool exists;
+       int ret;
        bool update_size = (key->type == BTRFS_DIR_INDEX_KEY);
        bool name_added = false;
 
@@ -1957,12 +1971,12 @@ static noinline int replay_one_name(struct btrfs_trans_handle *trans,
                   name_len);
 
        btrfs_dir_item_key_to_cpu(eb, di, &log_key);
-       exists = btrfs_lookup_inode(trans, root, path, &log_key, 0);
-       if (exists == 0)
-               exists = 1;
-       else
-               exists = 0;
+       ret = btrfs_lookup_inode(trans, root, path, &log_key, 0);
        btrfs_release_path(path);
+       if (ret < 0)
+               goto out;
+       exists = (ret == 0);
+       ret = 0;
 
        if (key->type == BTRFS_DIR_ITEM_KEY) {
                dst_di = btrfs_lookup_dir_item(trans, root, path, key->objectid,
@@ -1977,7 +1991,11 @@ static noinline int replay_one_name(struct btrfs_trans_handle *trans,
                ret = -EINVAL;
                goto out;
        }
-       if (IS_ERR_OR_NULL(dst_di)) {
+
+       if (IS_ERR(dst_di)) {
+               ret = PTR_ERR(dst_di);
+               goto out;
+       } else if (!dst_di) {
                /* we need a sequence number to insert, so we only
                 * do inserts for the BTRFS_DIR_INDEX_KEY types
                 */
@@ -2281,7 +2299,7 @@ again:
                                                     dir_key->offset,
                                                     name, name_len, 0);
                }
-               if (!log_di || log_di == ERR_PTR(-ENOENT)) {
+               if (!log_di) {
                        btrfs_dir_item_key_to_cpu(eb, di, &location);
                        btrfs_release_path(path);
                        btrfs_release_path(log_path);
@@ -3540,8 +3558,7 @@ out_unlock:
        if (err == -ENOSPC) {
                btrfs_set_log_full_commit(trans);
                err = 0;
-       } else if (err < 0 && err != -ENOENT) {
-               /* ENOENT can be returned if the entry hasn't been fsynced yet */
+       } else if (err < 0) {
                btrfs_abort_transaction(trans, err);
        }
 
index f346a78..6a67565 100644 (file)
@@ -77,7 +77,6 @@ static WORK_STATE(INIT_OBJECT,                "INIT", fscache_initialise_object);
 static WORK_STATE(PARENT_READY,                "PRDY", fscache_parent_ready);
 static WORK_STATE(ABORT_INIT,          "ABRT", fscache_abort_initialisation);
 static WORK_STATE(LOOK_UP_OBJECT,      "LOOK", fscache_look_up_object);
-static WORK_STATE(CREATE_OBJECT,       "CRTO", fscache_look_up_object);
 static WORK_STATE(OBJECT_AVAILABLE,    "AVBL", fscache_object_available);
 static WORK_STATE(JUMPSTART_DEPS,      "JUMP", fscache_jumpstart_dependents);
 
@@ -907,6 +906,7 @@ static void fscache_dequeue_object(struct fscache_object *object)
  * @object: The object to ask about
  * @data: The auxiliary data for the object
  * @datalen: The size of the auxiliary data
+ * @object_size: The size of the object according to the server.
  *
  * This function consults the netfs about the coherency state of an object.
  * The caller must be holding a ref on cookie->n_active (held by
index 4338771..e002cdf 100644 (file)
@@ -22,7 +22,10 @@ static void fscache_operation_dummy_cancel(struct fscache_operation *op)
 
 /**
  * fscache_operation_init - Do basic initialisation of an operation
+ * @cookie: The cookie to operate on
  * @op: The operation to initialise
+ * @processor: The function to perform the operation
+ * @cancel: A function to handle operation cancellation
  * @release: The release function to assign
  *
  * Do basic initialisation of an operation.  The caller must still set flags,
index cfc3ce8..8e0a137 100644 (file)
@@ -1111,7 +1111,14 @@ static struct dentry *kernfs_iop_lookup(struct inode *dir,
 
        kn = kernfs_find_ns(parent, dentry->d_name.name, ns);
        /* attach dentry and inode */
-       if (kn && kernfs_active(kn)) {
+       if (kn) {
+               /* Inactive nodes are invisible to the VFS so don't
+                * create a negative.
+                */
+               if (!kernfs_active(kn)) {
+                       up_read(&kernfs_rwsem);
+                       return NULL;
+               }
                inode = kernfs_get_inode(dir->i_sb, kn);
                if (!inode)
                        inode = ERR_PTR(-ENOMEM);
index af086d3..48b18b4 100644 (file)
@@ -296,10 +296,12 @@ int ksmbd_conn_handler_loop(void *p)
                pdu_size = get_rfc1002_len(hdr_buf);
                ksmbd_debug(CONN, "RFC1002 header %u bytes\n", pdu_size);
 
-               /* make sure we have enough to get to SMB header end */
-               if (!ksmbd_pdu_size_has_room(pdu_size)) {
-                       ksmbd_debug(CONN, "SMB request too short (%u bytes)\n",
-                                   pdu_size);
+               /*
+                * Check if pdu size is valid (min : smb header size,
+                * max : 0x00FFFFFF).
+                */
+               if (pdu_size < __SMB2_HEADER_STRUCTURE_SIZE ||
+                   pdu_size > MAX_STREAM_PROT_LEN) {
                        continue;
                }
 
index 49a5a3a..5b8f3e0 100644 (file)
@@ -12,7 +12,7 @@
 #include "unicode.h"
 #include "vfs_cache.h"
 
-#define KSMBD_VERSION  "3.1.9"
+#define KSMBD_VERSION  "3.4.2"
 
 extern int ksmbd_debug_types;
 
index 9aa46bb..9edd9c1 100644 (file)
@@ -80,18 +80,21 @@ static const bool has_smb2_data_area[NUMBER_OF_SMB2_COMMANDS] = {
 };
 
 /*
- * Returns the pointer to the beginning of the data area. Length of the data
- * area and the offset to it (from the beginning of the smb are also returned.
+ * Set length of the data area and the offset to arguments.
+ * if they are invalid, return error.
  */
-static char *smb2_get_data_area_len(int *off, int *len, struct smb2_hdr *hdr)
+static int smb2_get_data_area_len(unsigned int *off, unsigned int *len,
+                                 struct smb2_hdr *hdr)
 {
+       int ret = 0;
+
        *off = 0;
        *len = 0;
 
        /* error reqeusts do not have data area */
        if (hdr->Status && hdr->Status != STATUS_MORE_PROCESSING_REQUIRED &&
            (((struct smb2_err_rsp *)hdr)->StructureSize) == SMB2_ERROR_STRUCTURE_SIZE2_LE)
-               return NULL;
+               return ret;
 
        /*
         * Following commands have data areas so we have to get the location
@@ -165,69 +168,60 @@ static char *smb2_get_data_area_len(int *off, int *len, struct smb2_hdr *hdr)
        case SMB2_IOCTL:
                *off = le32_to_cpu(((struct smb2_ioctl_req *)hdr)->InputOffset);
                *len = le32_to_cpu(((struct smb2_ioctl_req *)hdr)->InputCount);
-
                break;
        default:
                ksmbd_debug(SMB, "no length check for command\n");
                break;
        }
 
-       /*
-        * Invalid length or offset probably means data area is invalid, but
-        * we have little choice but to ignore the data area in this case.
-        */
        if (*off > 4096) {
-               ksmbd_debug(SMB, "offset %d too large, data area ignored\n",
-                           *off);
-               *len = 0;
-               *off = 0;
-       } else if (*off < 0) {
-               ksmbd_debug(SMB,
-                           "negative offset %d to data invalid ignore data area\n",
-                           *off);
-               *off = 0;
-               *len = 0;
-       } else if (*len < 0) {
-               ksmbd_debug(SMB,
-                           "negative data length %d invalid, data area ignored\n",
-                           *len);
-               *len = 0;
-       } else if (*len > 128 * 1024) {
-               ksmbd_debug(SMB, "data area larger than 128K: %d\n", *len);
-               *len = 0;
+               ksmbd_debug(SMB, "offset %d too large\n", *off);
+               ret = -EINVAL;
+       } else if ((u64)*off + *len > MAX_STREAM_PROT_LEN) {
+               ksmbd_debug(SMB, "Request is larger than maximum stream protocol length(%u): %llu\n",
+                           MAX_STREAM_PROT_LEN, (u64)*off + *len);
+               ret = -EINVAL;
        }
 
-       /* return pointer to beginning of data area, ie offset from SMB start */
-       if ((*off != 0) && (*len != 0))
-               return (char *)hdr + *off;
-       else
-               return NULL;
+       return ret;
 }
 
 /*
  * Calculate the size of the SMB message based on the fixed header
  * portion, the number of word parameters and the data portion of the message.
  */
-static unsigned int smb2_calc_size(void *buf)
+static int smb2_calc_size(void *buf, unsigned int *len)
 {
        struct smb2_pdu *pdu = (struct smb2_pdu *)buf;
        struct smb2_hdr *hdr = &pdu->hdr;
-       int offset; /* the offset from the beginning of SMB to data area */
-       int data_length; /* the length of the variable length data area */
+       unsigned int offset; /* the offset from the beginning of SMB to data area */
+       unsigned int data_length; /* the length of the variable length data area */
+       int ret;
+
        /* Structure Size has already been checked to make sure it is 64 */
-       int len = le16_to_cpu(hdr->StructureSize);
+       *len = le16_to_cpu(hdr->StructureSize);
 
        /*
         * StructureSize2, ie length of fixed parameter area has already
         * been checked to make sure it is the correct length.
         */
-       len += le16_to_cpu(pdu->StructureSize2);
+       *len += le16_to_cpu(pdu->StructureSize2);
+       /*
+        * StructureSize2 of smb2_lock pdu is set to 48, indicating
+        * the size of smb2 lock request with single smb2_lock_element
+        * regardless of number of locks. Subtract single
+        * smb2_lock_element for correct buffer size check.
+        */
+       if (hdr->Command == SMB2_LOCK)
+               *len -= sizeof(struct smb2_lock_element);
 
        if (has_smb2_data_area[le16_to_cpu(hdr->Command)] == false)
                goto calc_size_exit;
 
-       smb2_get_data_area_len(&offset, &data_length, hdr);
-       ksmbd_debug(SMB, "SMB2 data length %d offset %d\n", data_length,
+       ret = smb2_get_data_area_len(&offset, &data_length, hdr);
+       if (ret)
+               return ret;
+       ksmbd_debug(SMB, "SMB2 data length %u offset %u\n", data_length,
                    offset);
 
        if (data_length > 0) {
@@ -237,16 +231,19 @@ static unsigned int smb2_calc_size(void *buf)
                 * for some commands, typically those with odd StructureSize,
                 * so we must add one to the calculation.
                 */
-               if (offset + 1 < len)
+               if (offset + 1 < *len) {
                        ksmbd_debug(SMB,
-                                   "data area offset %d overlaps SMB2 header %d\n",
-                                   offset + 1, len);
-               else
-                       len = offset + data_length;
+                                   "data area offset %d overlaps SMB2 header %u\n",
+                                   offset + 1, *len);
+                       return -EINVAL;
+               }
+
+               *len = offset + data_length;
        }
+
 calc_size_exit:
-       ksmbd_debug(SMB, "SMB2 len %d\n", len);
-       return len;
+       ksmbd_debug(SMB, "SMB2 len %u\n", *len);
+       return 0;
 }
 
 static inline int smb2_query_info_req_len(struct smb2_query_info_req *h)
@@ -391,9 +388,11 @@ int ksmbd_smb2_check_message(struct ksmbd_work *work)
                return 1;
        }
 
-       clc_len = smb2_calc_size(hdr);
+       if (smb2_calc_size(hdr, &clc_len))
+               return 1;
+
        if (len != clc_len) {
-               /* server can return one byte more due to implied bcc[0] */
+               /* client can return one byte more due to implied bcc[0] */
                if (clc_len == len + 1)
                        return 0;
 
@@ -418,9 +417,6 @@ int ksmbd_smb2_check_message(struct ksmbd_work *work)
                        return 0;
                }
 
-               if (command == SMB2_LOCK_HE && len == 88)
-                       return 0;
-
                ksmbd_debug(SMB,
                            "cli req too short, len %d not %d. cmd:%d mid:%llu\n",
                            len, clc_len, command,
index 1974738..b06456e 100644 (file)
@@ -187,11 +187,6 @@ static struct smb_version_cmds smb2_0_server_cmds[NUMBER_OF_SMB2_COMMANDS] = {
        [SMB2_CHANGE_NOTIFY_HE] =       { .proc = smb2_notify},
 };
 
-int init_smb2_0_server(struct ksmbd_conn *conn)
-{
-       return -EOPNOTSUPP;
-}
-
 /**
  * init_smb2_1_server() - initialize a smb server connection with smb2.1
  *                     command dispatcher
index dcf9077..005aa93 100644 (file)
@@ -236,9 +236,6 @@ int init_smb2_neg_rsp(struct ksmbd_work *work)
 
        if (conn->need_neg == false)
                return -EINVAL;
-       if (!(conn->dialect >= SMB20_PROT_ID &&
-             conn->dialect <= SMB311_PROT_ID))
-               return -EINVAL;
 
        rsp_hdr = work->response_buf;
 
@@ -1166,13 +1163,6 @@ int smb2_handle_negotiate(struct ksmbd_work *work)
        case SMB21_PROT_ID:
                init_smb2_1_server(conn);
                break;
-       case SMB20_PROT_ID:
-               rc = init_smb2_0_server(conn);
-               if (rc) {
-                       rsp->hdr.Status = STATUS_NOT_SUPPORTED;
-                       goto err_out;
-               }
-               break;
        case SMB2X_PROT_ID:
        case BAD_PROT_ID:
        default:
@@ -1191,11 +1181,9 @@ int smb2_handle_negotiate(struct ksmbd_work *work)
        rsp->MaxReadSize = cpu_to_le32(conn->vals->max_read_size);
        rsp->MaxWriteSize = cpu_to_le32(conn->vals->max_write_size);
 
-       if (conn->dialect > SMB20_PROT_ID) {
-               memcpy(conn->ClientGUID, req->ClientGUID,
-                      SMB2_CLIENT_GUID_SIZE);
-               conn->cli_sec_mode = le16_to_cpu(req->SecurityMode);
-       }
+       memcpy(conn->ClientGUID, req->ClientGUID,
+                       SMB2_CLIENT_GUID_SIZE);
+       conn->cli_sec_mode = le16_to_cpu(req->SecurityMode);
 
        rsp->StructureSize = cpu_to_le16(65);
        rsp->DialectRevision = cpu_to_le16(conn->dialect);
@@ -1537,11 +1525,9 @@ binding_session:
                }
        }
 
-       if (conn->dialect > SMB20_PROT_ID) {
-               if (!ksmbd_conn_lookup_dialect(conn)) {
-                       pr_err("fail to verify the dialect\n");
-                       return -ENOENT;
-               }
+       if (!ksmbd_conn_lookup_dialect(conn)) {
+               pr_err("fail to verify the dialect\n");
+               return -ENOENT;
        }
        return 0;
 }
@@ -1623,11 +1609,9 @@ static int krb5_authenticate(struct ksmbd_work *work)
                }
        }
 
-       if (conn->dialect > SMB20_PROT_ID) {
-               if (!ksmbd_conn_lookup_dialect(conn)) {
-                       pr_err("fail to verify the dialect\n");
-                       return -ENOENT;
-               }
+       if (!ksmbd_conn_lookup_dialect(conn)) {
+               pr_err("fail to verify the dialect\n");
+               return -ENOENT;
        }
        return 0;
 }
@@ -5499,7 +5483,6 @@ static int set_file_basic_info(struct ksmbd_file *fp,
                               struct ksmbd_share_config *share)
 {
        struct iattr attrs;
-       struct timespec64 ctime;
        struct file *filp;
        struct inode *inode;
        struct user_namespace *user_ns;
@@ -5521,13 +5504,11 @@ static int set_file_basic_info(struct ksmbd_file *fp,
                attrs.ia_valid |= (ATTR_ATIME | ATTR_ATIME_SET);
        }
 
-       if (file_info->ChangeTime) {
+       attrs.ia_valid |= ATTR_CTIME;
+       if (file_info->ChangeTime)
                attrs.ia_ctime = ksmbd_NTtimeToUnix(file_info->ChangeTime);
-               ctime = attrs.ia_ctime;
-               attrs.ia_valid |= ATTR_CTIME;
-       } else {
-               ctime = inode->i_ctime;
-       }
+       else
+               attrs.ia_ctime = inode->i_ctime;
 
        if (file_info->LastWriteTime) {
                attrs.ia_mtime = ksmbd_NTtimeToUnix(file_info->LastWriteTime);
@@ -5573,11 +5554,9 @@ static int set_file_basic_info(struct ksmbd_file *fp,
                        return -EACCES;
 
                inode_lock(inode);
+               inode->i_ctime = attrs.ia_ctime;
+               attrs.ia_valid &= ~ATTR_CTIME;
                rc = notify_change(user_ns, dentry, &attrs, NULL);
-               if (!rc) {
-                       inode->i_ctime = ctime;
-                       mark_inode_dirty(inode);
-               }
                inode_unlock(inode);
        }
        return rc;
@@ -8411,20 +8390,18 @@ int smb3_decrypt_req(struct ksmbd_work *work)
        struct smb2_hdr *hdr;
        unsigned int pdu_length = get_rfc1002_len(buf);
        struct kvec iov[2];
-       unsigned int buf_data_size = pdu_length + 4 -
+       int buf_data_size = pdu_length + 4 -
                sizeof(struct smb2_transform_hdr);
        struct smb2_transform_hdr *tr_hdr = (struct smb2_transform_hdr *)buf;
        int rc = 0;
 
-       if (pdu_length + 4 <
-           sizeof(struct smb2_transform_hdr) + sizeof(struct smb2_hdr)) {
+       if (buf_data_size < sizeof(struct smb2_hdr)) {
                pr_err("Transform message is too small (%u)\n",
                       pdu_length);
                return -ECONNABORTED;
        }
 
-       if (pdu_length + 4 <
-           le32_to_cpu(tr_hdr->OriginalMessageSize) + sizeof(struct smb2_transform_hdr)) {
+       if (buf_data_size < le32_to_cpu(tr_hdr->OriginalMessageSize)) {
                pr_err("Transform message is broken\n");
                return -ECONNABORTED;
        }
index 261825d..a6dec5e 100644 (file)
@@ -1637,7 +1637,6 @@ struct smb2_posix_info {
 } __packed;
 
 /* functions */
-int init_smb2_0_server(struct ksmbd_conn *conn);
 void init_smb2_1_server(struct ksmbd_conn *conn);
 void init_smb3_0_server(struct ksmbd_conn *conn);
 void init_smb3_02_server(struct ksmbd_conn *conn);
index db8042a..707490a 100644 (file)
@@ -21,7 +21,6 @@ static const char basechars[43] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_-!@#$%";
 #define MAGIC_CHAR '~'
 #define PERIOD '.'
 #define mangle(V) ((char)(basechars[(V) % MANGLE_BASE]))
-#define KSMBD_MIN_SUPPORTED_HEADER_SIZE        (sizeof(struct smb2_hdr))
 
 struct smb_protocol {
        int             index;
@@ -89,7 +88,7 @@ unsigned int ksmbd_server_side_copy_max_total_size(void)
 
 inline int ksmbd_min_protocol(void)
 {
-       return SMB2_PROT;
+       return SMB21_PROT;
 }
 
 inline int ksmbd_max_protocol(void)
@@ -294,11 +293,6 @@ int ksmbd_init_smb_server(struct ksmbd_work *work)
        return 0;
 }
 
-bool ksmbd_pdu_size_has_room(unsigned int pdu)
-{
-       return (pdu >= KSMBD_MIN_SUPPORTED_HEADER_SIZE - 4);
-}
-
 int ksmbd_populate_dot_dotdot_entries(struct ksmbd_work *work, int info_level,
                                      struct ksmbd_file *dir,
                                      struct ksmbd_dir_info *d_info,
@@ -433,7 +427,7 @@ int ksmbd_extract_shortname(struct ksmbd_conn *conn, const char *longname,
 
 static int __smb2_negotiate(struct ksmbd_conn *conn)
 {
-       return (conn->dialect >= SMB20_PROT_ID &&
+       return (conn->dialect >= SMB21_PROT_ID &&
                conn->dialect <= SMB311_PROT_ID);
 }
 
@@ -463,7 +457,7 @@ int ksmbd_smb_negotiate_common(struct ksmbd_work *work, unsigned int command)
                }
        }
 
-       if (command == SMB2_NEGOTIATE_HE) {
+       if (command == SMB2_NEGOTIATE_HE && __smb2_negotiate(conn)) {
                ret = smb2_handle_negotiate(work);
                init_smb2_neg_rsp(work);
                return ret;
index 994abed..6e79e75 100644 (file)
@@ -48,6 +48,8 @@
 #define CIFS_DEFAULT_IOSIZE    (64 * 1024)
 #define MAX_CIFS_SMALL_BUFFER_SIZE 448 /* big enough for most */
 
+#define MAX_STREAM_PROT_LEN    0x00FFFFFF
+
 /* Responses when opening a file. */
 #define F_SUPERSEDED   0
 #define F_OPENED       1
@@ -493,8 +495,6 @@ int ksmbd_lookup_dialect_by_id(__le16 *cli_dialects, __le16 dialects_count);
 
 int ksmbd_init_smb_server(struct ksmbd_work *work);
 
-bool ksmbd_pdu_size_has_room(unsigned int pdu);
-
 struct ksmbd_kstat;
 int ksmbd_populate_dot_dotdot_entries(struct ksmbd_work *work,
                                      int info_level,
index 0b6cd3b..994ec22 100644 (file)
@@ -150,7 +150,7 @@ static void netfs_clear_unread(struct netfs_read_subrequest *subreq)
 {
        struct iov_iter iter;
 
-       iov_iter_xarray(&iter, WRITE, &subreq->rreq->mapping->i_pages,
+       iov_iter_xarray(&iter, READ, &subreq->rreq->mapping->i_pages,
                        subreq->start + subreq->transferred,
                        subreq->len   - subreq->transferred);
        iov_iter_zero(iov_iter_count(&iter), &iter);
index edec458..0a9b726 100644 (file)
@@ -42,7 +42,6 @@ EXPORT_SYMBOL_GPL(locks_start_grace);
 
 /**
  * locks_end_grace
- * @net: net namespace that this lock manager belongs to
  * @lm: who this grace period is for
  *
  * Call this function to state that the given lock manager is ready to
index 7629248..be3c1aa 100644 (file)
@@ -542,7 +542,7 @@ nfsd_file_close_inode_sync(struct inode *inode)
 }
 
 /**
- * nfsd_file_close_inode_sync - attempt to forcibly close a nfsd_file
+ * nfsd_file_close_inode - attempt a delayed close of a nfsd_file
  * @inode: inode of the file to attempt to remove
  *
  * Walk the whole hash bucket, looking for any files that correspond to "inode".
index 7abeccb..cf030eb 100644 (file)
@@ -3544,15 +3544,18 @@ nfsd4_encode_dirent(void *ccdv, const char *name, int namlen,
                goto fail;
        cd->rd_maxcount -= entry_bytes;
        /*
-        * RFC 3530 14.2.24 describes rd_dircount as only a "hint", so
-        * let's always let through the first entry, at least:
+        * RFC 3530 14.2.24 describes rd_dircount as only a "hint", and
+        * notes that it could be zero. If it is zero, then the server
+        * should enforce only the rd_maxcount value.
         */
-       if (!cd->rd_dircount)
-               goto fail;
-       name_and_cookie = 4 + 4 * XDR_QUADLEN(namlen) + 8;
-       if (name_and_cookie > cd->rd_dircount && cd->cookie_offset)
-               goto fail;
-       cd->rd_dircount -= min(cd->rd_dircount, name_and_cookie);
+       if (cd->rd_dircount) {
+               name_and_cookie = 4 + 4 * XDR_QUADLEN(namlen) + 8;
+               if (name_and_cookie > cd->rd_dircount && cd->cookie_offset)
+                       goto fail;
+               cd->rd_dircount -= min(cd->rd_dircount, name_and_cookie);
+               if (!cd->rd_dircount)
+                       cd->rd_maxcount = 0;
+       }
 
        cd->cookie_offset = cookie_offset;
 skip_entry:
index c2c3d90..070e5dd 100644 (file)
@@ -793,7 +793,10 @@ out_close:
                svc_xprt_put(xprt);
        }
 out_err:
-       nfsd_destroy(net);
+       if (!list_empty(&nn->nfsd_serv->sv_permsocks))
+               nn->nfsd_serv->sv_nrthreads--;
+        else
+               nfsd_destroy(net);
        return err;
 }
 
@@ -1545,7 +1548,7 @@ static int __init init_nfsd(void)
                goto out_free_all;
        return 0;
 out_free_all:
-       unregister_pernet_subsys(&nfsd_net_ops);
+       unregister_filesystem(&nfsd_fs_type);
 out_free_exports:
        remove_proc_entry("fs/nfs/exports", NULL);
        remove_proc_entry("fs/nfs", NULL);
index 34c4cbf..e8c00dd 100644 (file)
@@ -6,13 +6,9 @@
  * TODO: Merge attr_set_size/attr_data_get_block/attr_allocate_frame?
  */
 
-#include <linux/blkdev.h>
-#include <linux/buffer_head.h>
 #include <linux/fs.h>
-#include <linux/hash.h>
-#include <linux/nls.h>
-#include <linux/ratelimit.h>
 #include <linux/slab.h>
+#include <linux/kernel.h>
 
 #include "debug.h"
 #include "ntfs.h"
@@ -291,7 +287,7 @@ int attr_make_nonresident(struct ntfs_inode *ni, struct ATTRIB *attr,
                if (!rsize) {
                        /* Empty resident -> Non empty nonresident. */
                } else if (!is_data) {
-                       err = ntfs_sb_write_run(sbi, run, 0, data, rsize);
+                       err = ntfs_sb_write_run(sbi, run, 0, data, rsize, 0);
                        if (err)
                                goto out2;
                } else if (!page) {
@@ -451,11 +447,8 @@ again:
 again_1:
        align = sbi->cluster_size;
 
-       if (is_ext) {
+       if (is_ext)
                align <<= attr_b->nres.c_unit;
-               if (is_attr_sparsed(attr_b))
-                       keep_prealloc = false;
-       }
 
        old_valid = le64_to_cpu(attr_b->nres.valid_size);
        old_size = le64_to_cpu(attr_b->nres.data_size);
@@ -465,9 +458,6 @@ again_1:
        new_alloc = (new_size + align - 1) & ~(u64)(align - 1);
        new_alen = new_alloc >> cluster_bits;
 
-       if (keep_prealloc && is_ext)
-               keep_prealloc = false;
-
        if (keep_prealloc && new_size < old_size) {
                attr_b->nres.data_size = cpu_to_le64(new_size);
                mi_b->dirty = true;
@@ -529,7 +519,7 @@ add_alloc_in_same_attr_seg:
                } else if (pre_alloc == -1) {
                        pre_alloc = 0;
                        if (type == ATTR_DATA && !name_len &&
-                           sbi->options.prealloc) {
+                           sbi->options->prealloc) {
                                CLST new_alen2 = bytes_to_cluster(
                                        sbi, get_pre_allocated(new_size));
                                pre_alloc = new_alen2 - new_alen;
@@ -1966,7 +1956,7 @@ int attr_punch_hole(struct ntfs_inode *ni, u64 vbo, u64 bytes, u32 *frame_size)
                        return 0;
 
                from = vbo;
-               to = (vbo + bytes) < data_size ? (vbo + bytes) : data_size;
+               to = min_t(u64, vbo + bytes, data_size);
                memset(Add2Ptr(resident_data(attr_b), from), 0, to - from);
                return 0;
        }
index fa32399..bad6d8a 100644 (file)
@@ -5,10 +5,7 @@
  *
  */
 
-#include <linux/blkdev.h>
-#include <linux/buffer_head.h>
 #include <linux/fs.h>
-#include <linux/nls.h>
 
 #include "debug.h"
 #include "ntfs.h"
@@ -336,7 +333,7 @@ int al_add_le(struct ntfs_inode *ni, enum ATTR_TYPE type, const __le16 *name,
 
        if (attr && attr->non_res) {
                err = ntfs_sb_write_run(ni->mi.sbi, &al->run, 0, al->le,
-                                       al->size);
+                                       al->size, 0);
                if (err)
                        return err;
                al->dirty = false;
@@ -423,7 +420,7 @@ next:
        return true;
 }
 
-int al_update(struct ntfs_inode *ni)
+int al_update(struct ntfs_inode *ni, int sync)
 {
        int err;
        struct ATTRIB *attr;
@@ -445,7 +442,7 @@ int al_update(struct ntfs_inode *ni)
                memcpy(resident_data(attr), al->le, al->size);
        } else {
                err = ntfs_sb_write_run(ni->mi.sbi, &al->run, 0, al->le,
-                                       al->size);
+                                       al->size, sync);
                if (err)
                        goto out;
 
index ce304d4..50d8380 100644 (file)
@@ -5,13 +5,8 @@
  *
  */
 
-#include <linux/blkdev.h>
-#include <linux/buffer_head.h>
-#include <linux/fs.h>
-#include <linux/nls.h>
+#include <linux/types.h>
 
-#include "debug.h"
-#include "ntfs.h"
 #include "ntfs_fs.h"
 
 #define BITS_IN_SIZE_T (sizeof(size_t) * 8)
@@ -124,8 +119,7 @@ bool are_bits_set(const ulong *lmap, size_t bit, size_t nbits)
 
        pos = nbits & 7;
        if (pos) {
-               u8 mask = fill_mask[pos];
-
+               mask = fill_mask[pos];
                if ((*map & mask) != mask)
                        return false;
        }
index 8315015..aa18440 100644 (file)
  *
  */
 
-#include <linux/blkdev.h>
 #include <linux/buffer_head.h>
 #include <linux/fs.h>
-#include <linux/nls.h>
+#include <linux/kernel.h>
 
-#include "debug.h"
 #include "ntfs.h"
 #include "ntfs_fs.h"
 
@@ -435,7 +433,7 @@ static void wnd_remove_free_ext(struct wnd_bitmap *wnd, size_t bit, size_t len)
                ;
        } else {
                n3 = rb_next(&e->count.node);
-               max_new_len = len > new_len ? len : new_len;
+               max_new_len = max(len, new_len);
                if (!n3) {
                        wnd->extent_max = max_new_len;
                } else {
@@ -731,7 +729,7 @@ int wnd_set_free(struct wnd_bitmap *wnd, size_t bit, size_t bits)
                        wbits = wnd->bits_last;
 
                tail = wbits - wbit;
-               op = tail < bits ? tail : bits;
+               op = min_t(u32, tail, bits);
 
                bh = wnd_map(wnd, iw);
                if (IS_ERR(bh)) {
@@ -784,7 +782,7 @@ int wnd_set_used(struct wnd_bitmap *wnd, size_t bit, size_t bits)
                        wbits = wnd->bits_last;
 
                tail = wbits - wbit;
-               op = tail < bits ? tail : bits;
+               op = min_t(u32, tail, bits);
 
                bh = wnd_map(wnd, iw);
                if (IS_ERR(bh)) {
@@ -834,7 +832,7 @@ static bool wnd_is_free_hlp(struct wnd_bitmap *wnd, size_t bit, size_t bits)
                        wbits = wnd->bits_last;
 
                tail = wbits - wbit;
-               op = tail < bits ? tail : bits;
+               op = min_t(u32, tail, bits);
 
                if (wbits != wnd->free_bits[iw]) {
                        bool ret;
@@ -926,7 +924,7 @@ use_wnd:
                        wbits = wnd->bits_last;
 
                tail = wbits - wbit;
-               op = tail < bits ? tail : bits;
+               op = min_t(u32, tail, bits);
 
                if (wnd->free_bits[iw]) {
                        bool ret;
index 3112056..53ef748 100644 (file)
@@ -11,6 +11,9 @@
 #ifndef _LINUX_NTFS3_DEBUG_H
 #define _LINUX_NTFS3_DEBUG_H
 
+struct super_block;
+struct inode;
+
 #ifndef Add2Ptr
 #define Add2Ptr(P, I)          ((void *)((u8 *)(P) + (I)))
 #define PtrOffset(B, O)                ((size_t)((size_t)(O) - (size_t)(B)))
index 93f6d48..fb438d6 100644 (file)
@@ -7,10 +7,7 @@
  *
  */
 
-#include <linux/blkdev.h>
-#include <linux/buffer_head.h>
 #include <linux/fs.h>
-#include <linux/iversion.h>
 #include <linux/nls.h>
 
 #include "debug.h"
 #include "ntfs_fs.h"
 
 /* Convert little endian UTF-16 to NLS string. */
-int ntfs_utf16_to_nls(struct ntfs_sb_info *sbi, const struct le_str *uni,
+int ntfs_utf16_to_nls(struct ntfs_sb_info *sbi, const __le16 *name, u32 len,
                      u8 *buf, int buf_len)
 {
-       int ret, uni_len, warn;
-       const __le16 *ip;
+       int ret, warn;
        u8 *op;
-       struct nls_table *nls = sbi->options.nls;
+       struct nls_table *nls = sbi->options->nls;
 
        static_assert(sizeof(wchar_t) == sizeof(__le16));
 
        if (!nls) {
                /* UTF-16 -> UTF-8 */
-               ret = utf16s_to_utf8s((wchar_t *)uni->name, uni->len,
-                                     UTF16_LITTLE_ENDIAN, buf, buf_len);
+               ret = utf16s_to_utf8s(name, len, UTF16_LITTLE_ENDIAN, buf,
+                                     buf_len);
                buf[ret] = '\0';
                return ret;
        }
 
-       ip = uni->name;
        op = buf;
-       uni_len = uni->len;
        warn = 0;
 
-       while (uni_len--) {
+       while (len--) {
                u16 ec;
                int charlen;
                char dump[5];
@@ -52,7 +46,7 @@ int ntfs_utf16_to_nls(struct ntfs_sb_info *sbi, const struct le_str *uni,
                        break;
                }
 
-               ec = le16_to_cpu(*ip++);
+               ec = le16_to_cpu(*name++);
                charlen = nls->uni2char(ec, op, buf_len);
 
                if (charlen > 0) {
@@ -186,7 +180,7 @@ int ntfs_nls_to_utf16(struct ntfs_sb_info *sbi, const u8 *name, u32 name_len,
 {
        int ret, slen;
        const u8 *end;
-       struct nls_table *nls = sbi->options.nls;
+       struct nls_table *nls = sbi->options->nls;
        u16 *uname = uni->name;
 
        static_assert(sizeof(wchar_t) == sizeof(u16));
@@ -301,14 +295,14 @@ static inline int ntfs_filldir(struct ntfs_sb_info *sbi, struct ntfs_inode *ni,
                return 0;
 
        /* Skip meta files. Unless option to show metafiles is set. */
-       if (!sbi->options.showmeta && ntfs_is_meta_file(sbi, ino))
+       if (!sbi->options->showmeta && ntfs_is_meta_file(sbi, ino))
                return 0;
 
-       if (sbi->options.nohidden && (fname->dup.fa & FILE_ATTRIBUTE_HIDDEN))
+       if (sbi->options->nohidden && (fname->dup.fa & FILE_ATTRIBUTE_HIDDEN))
                return 0;
 
-       name_len = ntfs_utf16_to_nls(sbi, (struct le_str *)&fname->name_len,
-                                    name, PATH_MAX);
+       name_len = ntfs_utf16_to_nls(sbi, fname->name, fname->name_len, name,
+                                    PATH_MAX);
        if (name_len <= 0) {
                ntfs_warn(sbi->sb, "failed to convert name for inode %lx.",
                          ino);
index 424450e..43b1451 100644 (file)
@@ -12,7 +12,6 @@
 #include <linux/compat.h>
 #include <linux/falloc.h>
 #include <linux/fiemap.h>
-#include <linux/nls.h>
 
 #include "debug.h"
 #include "ntfs.h"
@@ -588,8 +587,11 @@ static long ntfs_fallocate(struct file *file, int mode, loff_t vbo, loff_t len)
                truncate_pagecache(inode, vbo_down);
 
                if (!is_sparsed(ni) && !is_compressed(ni)) {
-                       /* Normal file. */
-                       err = ntfs_zero_range(inode, vbo, end);
+                       /*
+                        * Normal file, can't make hole.
+                        * TODO: Try to find way to save info about hole.
+                        */
+                       err = -EOPNOTSUPP;
                        goto out;
                }
 
@@ -737,7 +739,7 @@ int ntfs3_setattr(struct user_namespace *mnt_userns, struct dentry *dentry,
        umode_t mode = inode->i_mode;
        int err;
 
-       if (sbi->options.no_acs_rules) {
+       if (sbi->options->noacsrules) {
                /* "No access rules" - Force any changes of time etc. */
                attr->ia_valid |= ATTR_FORCE;
                /* and disable for editing some attributes. */
@@ -1185,7 +1187,7 @@ static int ntfs_file_release(struct inode *inode, struct file *file)
        int err = 0;
 
        /* If we are last writer on the inode, drop the block reservation. */
-       if (sbi->options.prealloc && ((file->f_mode & FMODE_WRITE) &&
+       if (sbi->options->prealloc && ((file->f_mode & FMODE_WRITE) &&
                                      atomic_read(&inode->i_writecount) == 1)) {
                ni_lock(ni);
                down_write(&ni->file.run_lock);
index 938b12d..6f47a9c 100644 (file)
@@ -5,11 +5,8 @@
  *
  */
 
-#include <linux/blkdev.h>
-#include <linux/buffer_head.h>
 #include <linux/fiemap.h>
 #include <linux/fs.h>
-#include <linux/nls.h>
 #include <linux/vmalloc.h>
 
 #include "debug.h"
@@ -708,18 +705,35 @@ static int ni_try_remove_attr_list(struct ntfs_inode *ni)
                        continue;
 
                mi = ni_find_mi(ni, ino_get(&le->ref));
+               if (!mi) {
+                       /* Should never happened, 'cause already checked. */
+                       goto bad;
+               }
 
                attr = mi_find_attr(mi, NULL, le->type, le_name(le),
                                    le->name_len, &le->id);
+               if (!attr) {
+                       /* Should never happened, 'cause already checked. */
+                       goto bad;
+               }
                asize = le32_to_cpu(attr->size);
 
                /* Insert into primary record. */
                attr_ins = mi_insert_attr(&ni->mi, le->type, le_name(le),
                                          le->name_len, asize,
                                          le16_to_cpu(attr->name_off));
-               id = attr_ins->id;
+               if (!attr_ins) {
+                       /*
+                        * Internal error.
+                        * Either no space in primary record (already checked).
+                        * Either tried to insert another
+                        * non indexed attribute (logic error).
+                        */
+                       goto bad;
+               }
 
                /* Copy all except id. */
+               id = attr_ins->id;
                memcpy(attr_ins, attr, asize);
                attr_ins->id = id;
 
@@ -735,6 +749,10 @@ static int ni_try_remove_attr_list(struct ntfs_inode *ni)
        ni->attr_list.dirty = false;
 
        return 0;
+bad:
+       ntfs_inode_err(&ni->vfs_inode, "Internal error");
+       make_bad_inode(&ni->vfs_inode);
+       return -EINVAL;
 }
 
 /*
@@ -956,6 +974,13 @@ static int ni_ins_attr_ext(struct ntfs_inode *ni, struct ATTR_LIST_ENTRY *le,
                        continue;
                }
 
+               /*
+                * Do not try to insert this attribute
+                * if there is no room in record.
+                */
+               if (le32_to_cpu(mi->mrec->used) + asize > sbi->record_size)
+                       continue;
+
                /* Try to insert attribute into this subrecord. */
                attr = ni_ins_new_attr(ni, mi, le, type, name, name_len, asize,
                                       name_off, svcn, ins_le);
@@ -1451,7 +1476,7 @@ int ni_insert_resident(struct ntfs_inode *ni, u32 data_size,
                attr->res.flags = RESIDENT_FLAG_INDEXED;
 
                /* is_attr_indexed(attr)) == true */
-               le16_add_cpu(&ni->mi.mrec->hard_links, +1);
+               le16_add_cpu(&ni->mi.mrec->hard_links, 1);
                ni->mi.dirty = true;
        }
        attr->res.res = 0;
@@ -1606,7 +1631,7 @@ struct ATTR_FILE_NAME *ni_fname_type(struct ntfs_inode *ni, u8 name_type,
 
        *le = NULL;
 
-       if (FILE_NAME_POSIX == name_type)
+       if (name_type == FILE_NAME_POSIX)
                return NULL;
 
        /* Enumerate all names. */
@@ -1706,18 +1731,16 @@ out:
 /*
  * ni_parse_reparse
  *
- * Buffer is at least 24 bytes.
+ * buffer - memory for reparse buffer header
  */
 enum REPARSE_SIGN ni_parse_reparse(struct ntfs_inode *ni, struct ATTRIB *attr,
-                                  void *buffer)
+                                  struct REPARSE_DATA_BUFFER *buffer)
 {
        const struct REPARSE_DATA_BUFFER *rp = NULL;
        u8 bits;
        u16 len;
        typeof(rp->CompressReparseBuffer) *cmpr;
 
-       static_assert(sizeof(struct REPARSE_DATA_BUFFER) <= 24);
-
        /* Try to estimate reparse point. */
        if (!attr->non_res) {
                rp = resident_data_ex(attr, sizeof(struct REPARSE_DATA_BUFFER));
@@ -1803,6 +1826,9 @@ enum REPARSE_SIGN ni_parse_reparse(struct ntfs_inode *ni, struct ATTRIB *attr,
                return REPARSE_NONE;
        }
 
+       if (buffer != rp)
+               memcpy(buffer, rp, sizeof(struct REPARSE_DATA_BUFFER));
+
        /* Looks like normal symlink. */
        return REPARSE_LINK;
 }
@@ -2906,9 +2932,8 @@ bool ni_remove_name_undo(struct ntfs_inode *dir_ni, struct ntfs_inode *ni,
                memcpy(Add2Ptr(attr, SIZEOF_RESIDENT), de + 1, de_key_size);
                mi_get_ref(&ni->mi, &de->ref);
 
-               if (indx_insert_entry(&dir_ni->dir, dir_ni, de, sbi, NULL, 1)) {
+               if (indx_insert_entry(&dir_ni->dir, dir_ni, de, sbi, NULL, 1))
                        return false;
-               }
        }
 
        return true;
@@ -3077,7 +3102,9 @@ static bool ni_update_parent(struct ntfs_inode *ni, struct NTFS_DUP_INFO *dup,
                        const struct EA_INFO *info;
 
                        info = resident_data_ex(attr, sizeof(struct EA_INFO));
-                       dup->ea_size = info->size_pack;
+                       /* If ATTR_EA_INFO exists 'info' can't be NULL. */
+                       if (info)
+                               dup->ea_size = info->size_pack;
                }
        }
 
@@ -3205,7 +3232,7 @@ int ni_write_inode(struct inode *inode, int sync, const char *hint)
                                        goto out;
                        }
 
-                       err = al_update(ni);
+                       err = al_update(ni, sync);
                        if (err)
                                goto out;
                }
index b5853ae..06492f0 100644 (file)
@@ -6,12 +6,8 @@
  */
 
 #include <linux/blkdev.h>
-#include <linux/buffer_head.h>
 #include <linux/fs.h>
-#include <linux/hash.h>
-#include <linux/nls.h>
 #include <linux/random.h>
-#include <linux/ratelimit.h>
 #include <linux/slab.h>
 
 #include "debug.h"
@@ -2219,7 +2215,7 @@ file_is_valid:
 
                        err = ntfs_sb_write_run(log->ni->mi.sbi,
                                                &log->ni->file.run, off, page,
-                                               log->page_size);
+                                               log->page_size, 0);
 
                        if (err)
                                goto out;
@@ -3710,7 +3706,7 @@ move_data:
 
        if (a_dirty) {
                attr = oa->attr;
-               err = ntfs_sb_write_run(sbi, oa->run1, vbo, buffer_le, bytes);
+               err = ntfs_sb_write_run(sbi, oa->run1, vbo, buffer_le, bytes, 0);
                if (err)
                        goto out;
        }
@@ -5152,10 +5148,10 @@ end_reply:
 
        ntfs_fix_pre_write(&rh->rhdr, log->page_size);
 
-       err = ntfs_sb_write_run(sbi, &ni->file.run, 0, rh, log->page_size);
+       err = ntfs_sb_write_run(sbi, &ni->file.run, 0, rh, log->page_size, 0);
        if (!err)
                err = ntfs_sb_write_run(sbi, &log->ni->file.run, log->page_size,
-                                       rh, log->page_size);
+                                       rh, log->page_size, 0);
 
        kfree(rh);
        if (err)
index 91e3743..4de9acb 100644 (file)
@@ -8,7 +8,7 @@
 #include <linux/blkdev.h>
 #include <linux/buffer_head.h>
 #include <linux/fs.h>
-#include <linux/nls.h>
+#include <linux/kernel.h>
 
 #include "debug.h"
 #include "ntfs.h"
@@ -358,7 +358,7 @@ int ntfs_look_for_free_space(struct ntfs_sb_info *sbi, CLST lcn, CLST len,
                             enum ALLOCATE_OPT opt)
 {
        int err;
-       CLST alen = 0;
+       CLST alen;
        struct super_block *sb = sbi->sb;
        size_t alcn, zlen, zeroes, zlcn, zlen2, ztrim, new_zlen;
        struct wnd_bitmap *wnd = &sbi->used.bitmap;
@@ -370,27 +370,28 @@ int ntfs_look_for_free_space(struct ntfs_sb_info *sbi, CLST lcn, CLST len,
                if (!zlen) {
                        err = ntfs_refresh_zone(sbi);
                        if (err)
-                               goto out;
+                               goto up_write;
+
                        zlen = wnd_zone_len(wnd);
                }
 
                if (!zlen) {
                        ntfs_err(sbi->sb, "no free space to extend mft");
-                       goto out;
+                       err = -ENOSPC;
+                       goto up_write;
                }
 
                lcn = wnd_zone_bit(wnd);
-               alen = zlen > len ? len : zlen;
+               alen = min_t(CLST, len, zlen);
 
                wnd_zone_set(wnd, lcn + alen, zlen - alen);
 
                err = wnd_set_used(wnd, lcn, alen);
-               if (err) {
-                       up_write(&wnd->rw_lock);
-                       return err;
-               }
+               if (err)
+                       goto up_write;
+
                alcn = lcn;
-               goto out;
+               goto space_found;
        }
        /*
         * 'Cause cluster 0 is always used this value means that we should use
@@ -404,49 +405,45 @@ int ntfs_look_for_free_space(struct ntfs_sb_info *sbi, CLST lcn, CLST len,
 
        alen = wnd_find(wnd, len, lcn, BITMAP_FIND_MARK_AS_USED, &alcn);
        if (alen)
-               goto out;
+               goto space_found;
 
        /* Try to use clusters from MftZone. */
        zlen = wnd_zone_len(wnd);
        zeroes = wnd_zeroes(wnd);
 
        /* Check too big request */
-       if (len > zeroes + zlen || zlen <= NTFS_MIN_MFT_ZONE)
-               goto out;
+       if (len > zeroes + zlen || zlen <= NTFS_MIN_MFT_ZONE) {
+               err = -ENOSPC;
+               goto up_write;
+       }
 
        /* How many clusters to cat from zone. */
        zlcn = wnd_zone_bit(wnd);
        zlen2 = zlen >> 1;
-       ztrim = len > zlen ? zlen : (len > zlen2 ? len : zlen2);
-       new_zlen = zlen - ztrim;
-
-       if (new_zlen < NTFS_MIN_MFT_ZONE) {
-               new_zlen = NTFS_MIN_MFT_ZONE;
-               if (new_zlen > zlen)
-                       new_zlen = zlen;
-       }
+       ztrim = clamp_val(len, zlen2, zlen);
+       new_zlen = max_t(size_t, zlen - ztrim, NTFS_MIN_MFT_ZONE);
 
        wnd_zone_set(wnd, zlcn, new_zlen);
 
        /* Allocate continues clusters. */
        alen = wnd_find(wnd, len, 0,
                        BITMAP_FIND_MARK_AS_USED | BITMAP_FIND_FULL, &alcn);
-
-out:
-       if (alen) {
-               err = 0;
-               *new_len = alen;
-               *new_lcn = alcn;
-
-               ntfs_unmap_meta(sb, alcn, alen);
-
-               /* Set hint for next requests. */
-               if (!(opt & ALLOCATE_MFT))
-                       sbi->used.next_free_lcn = alcn + alen;
-       } else {
+       if (!alen) {
                err = -ENOSPC;
+               goto up_write;
        }
 
+space_found:
+       err = 0;
+       *new_len = alen;
+       *new_lcn = alcn;
+
+       ntfs_unmap_meta(sb, alcn, alen);
+
+       /* Set hint for next requests. */
+       if (!(opt & ALLOCATE_MFT))
+               sbi->used.next_free_lcn = alcn + alen;
+up_write:
        up_write(&wnd->rw_lock);
        return err;
 }
@@ -1080,7 +1077,7 @@ int ntfs_sb_write(struct super_block *sb, u64 lbo, size_t bytes,
 }
 
 int ntfs_sb_write_run(struct ntfs_sb_info *sbi, const struct runs_tree *run,
-                     u64 vbo, const void *buf, size_t bytes)
+                     u64 vbo, const void *buf, size_t bytes, int sync)
 {
        struct super_block *sb = sbi->sb;
        u8 cluster_bits = sbi->cluster_bits;
@@ -1099,8 +1096,8 @@ int ntfs_sb_write_run(struct ntfs_sb_info *sbi, const struct runs_tree *run,
        len = ((u64)clen << cluster_bits) - off;
 
        for (;;) {
-               u32 op = len < bytes ? len : bytes;
-               int err = ntfs_sb_write(sb, lbo, op, buf, 0);
+               u32 op = min_t(u64, len, bytes);
+               int err = ntfs_sb_write(sb, lbo, op, buf, sync);
 
                if (err)
                        return err;
@@ -1300,7 +1297,7 @@ int ntfs_get_bh(struct ntfs_sb_info *sbi, const struct runs_tree *run, u64 vbo,
        nb->off = off = lbo & (blocksize - 1);
 
        for (;;) {
-               u32 len32 = len < bytes ? len : bytes;
+               u32 len32 = min_t(u64, len, bytes);
                sector_t block = lbo >> sb->s_blocksize_bits;
 
                do {
@@ -2175,7 +2172,7 @@ int ntfs_insert_security(struct ntfs_sb_info *sbi,
 
        /* Write main SDS bucket. */
        err = ntfs_sb_write_run(sbi, &ni->file.run, sbi->security.next_off,
-                               d_security, aligned_sec_size);
+                               d_security, aligned_sec_size, 0);
 
        if (err)
                goto out;
@@ -2193,7 +2190,7 @@ int ntfs_insert_security(struct ntfs_sb_info *sbi,
 
        /* Write copy SDS bucket. */
        err = ntfs_sb_write_run(sbi, &ni->file.run, mirr_off, d_security,
-                               aligned_sec_size);
+                               aligned_sec_size, 0);
        if (err)
                goto out;
 
index 0daca9a..6f81e3a 100644 (file)
@@ -8,7 +8,7 @@
 #include <linux/blkdev.h>
 #include <linux/buffer_head.h>
 #include <linux/fs.h>
-#include <linux/nls.h>
+#include <linux/kernel.h>
 
 #include "debug.h"
 #include "ntfs.h"
@@ -671,138 +671,74 @@ static struct NTFS_DE *hdr_find_e(const struct ntfs_index *indx,
                                  const struct INDEX_HDR *hdr, const void *key,
                                  size_t key_len, const void *ctx, int *diff)
 {
-       struct NTFS_DE *e;
+       struct NTFS_DE *e, *found = NULL;
        NTFS_CMP_FUNC cmp = indx->cmp;
+       int min_idx = 0, mid_idx, max_idx = 0;
+       int diff2;
+       int table_size = 8;
        u32 e_size, e_key_len;
        u32 end = le32_to_cpu(hdr->used);
        u32 off = le32_to_cpu(hdr->de_off);
+       u16 offs[128];
 
-#ifdef NTFS3_INDEX_BINARY_SEARCH
-       int max_idx = 0, fnd, min_idx;
-       int nslots = 64;
-       u16 *offs;
-
-       if (end > 0x10000)
-               goto next;
-
-       offs = kmalloc(sizeof(u16) * nslots, GFP_NOFS);
-       if (!offs)
-               goto next;
+fill_table:
+       if (off + sizeof(struct NTFS_DE) > end)
+               return NULL;
 
-       /* Use binary search algorithm. */
-next1:
-       if (off + sizeof(struct NTFS_DE) > end) {
-               e = NULL;
-               goto out1;
-       }
        e = Add2Ptr(hdr, off);
        e_size = le16_to_cpu(e->size);
 
-       if (e_size < sizeof(struct NTFS_DE) || off + e_size > end) {
-               e = NULL;
-               goto out1;
-       }
-
-       if (max_idx >= nslots) {
-               u16 *ptr;
-               int new_slots = ALIGN(2 * nslots, 8);
-
-               ptr = kmalloc(sizeof(u16) * new_slots, GFP_NOFS);
-               if (ptr)
-                       memcpy(ptr, offs, sizeof(u16) * max_idx);
-               kfree(offs);
-               offs = ptr;
-               nslots = new_slots;
-               if (!ptr)
-                       goto next;
-       }
-
-       /* Store entry table. */
-       offs[max_idx] = off;
+       if (e_size < sizeof(struct NTFS_DE) || off + e_size > end)
+               return NULL;
 
        if (!de_is_last(e)) {
+               offs[max_idx] = off;
                off += e_size;
-               max_idx += 1;
-               goto next1;
-       }
 
-       /*
-        * Table of pointers is created.
-        * Use binary search to find entry that is <= to the search value.
-        */
-       fnd = -1;
-       min_idx = 0;
+               max_idx++;
+               if (max_idx < table_size)
+                       goto fill_table;
 
-       while (min_idx <= max_idx) {
-               int mid_idx = min_idx + ((max_idx - min_idx) >> 1);
-               int diff2;
-
-               e = Add2Ptr(hdr, offs[mid_idx]);
+               max_idx--;
+       }
 
-               e_key_len = le16_to_cpu(e->key_size);
+binary_search:
+       e_key_len = le16_to_cpu(e->key_size);
 
-               diff2 = (*cmp)(key, key_len, e + 1, e_key_len, ctx);
+       diff2 = (*cmp)(key, key_len, e + 1, e_key_len, ctx);
+       if (diff2 > 0) {
+               if (found) {
+                       min_idx = mid_idx + 1;
+               } else {
+                       if (de_is_last(e))
+                               return NULL;
 
-               if (!diff2) {
-                       *diff = 0;
-                       goto out1;
+                       max_idx = 0;
+                       table_size = min(table_size * 2,
+                                        (int)ARRAY_SIZE(offs));
+                       goto fill_table;
                }
-
-               if (diff2 < 0) {
+       } else if (diff2 < 0) {
+               if (found)
                        max_idx = mid_idx - 1;
-                       fnd = mid_idx;
-                       if (!fnd)
-                               break;
-               } else {
-                       min_idx = mid_idx + 1;
-               }
-       }
+               else
+                       max_idx--;
 
-       if (fnd == -1) {
-               e = NULL;
-               goto out1;
+               found = e;
+       } else {
+               *diff = 0;
+               return e;
        }
 
-       *diff = -1;
-       e = Add2Ptr(hdr, offs[fnd]);
-
-out1:
-       kfree(offs);
-
-       return e;
-#endif
-
-next:
-       /*
-        * Entries index are sorted.
-        * Enumerate all entries until we find entry
-        * that is <= to the search value.
-        */
-       if (off + sizeof(struct NTFS_DE) > end)
-               return NULL;
-
-       e = Add2Ptr(hdr, off);
-       e_size = le16_to_cpu(e->size);
-
-       if (e_size < sizeof(struct NTFS_DE) || off + e_size > end)
-               return NULL;
-
-       off += e_size;
-
-       e_key_len = le16_to_cpu(e->key_size);
-
-       *diff = (*cmp)(key, key_len, e + 1, e_key_len, ctx);
-       if (!*diff)
-               return e;
+       if (min_idx > max_idx) {
+               *diff = -1;
+               return found;
+       }
 
-       if (*diff <= 0)
-               return e;
+       mid_idx = (min_idx + max_idx) >> 1;
+       e = Add2Ptr(hdr, offs[mid_idx]);
 
-       if (de_is_last(e)) {
-               *diff = 1;
-               return e;
-       }
-       goto next;
+       goto binary_search;
 }
 
 /*
@@ -1136,9 +1072,7 @@ int indx_find(struct ntfs_index *indx, struct ntfs_inode *ni,
        if (!e)
                return -EINVAL;
 
-       if (fnd)
-               fnd->root_de = e;
-
+       fnd->root_de = e;
        err = 0;
 
        for (;;) {
@@ -1401,7 +1335,7 @@ ok:
 static int indx_create_allocate(struct ntfs_index *indx, struct ntfs_inode *ni,
                                CLST *vbn)
 {
-       int err = -ENOMEM;
+       int err;
        struct ntfs_sb_info *sbi = ni->mi.sbi;
        struct ATTRIB *bitmap;
        struct ATTRIB *alloc;
index db2a5a4..859951d 100644 (file)
@@ -5,10 +5,8 @@
  *
  */
 
-#include <linux/blkdev.h>
 #include <linux/buffer_head.h>
 #include <linux/fs.h>
-#include <linux/iversion.h>
 #include <linux/mpage.h>
 #include <linux/namei.h>
 #include <linux/nls.h>
@@ -49,8 +47,8 @@ static struct inode *ntfs_read_mft(struct inode *inode,
 
        inode->i_op = NULL;
        /* Setup 'uid' and 'gid' */
-       inode->i_uid = sbi->options.fs_uid;
-       inode->i_gid = sbi->options.fs_gid;
+       inode->i_uid = sbi->options->fs_uid;
+       inode->i_gid = sbi->options->fs_gid;
 
        err = mi_init(&ni->mi, sbi, ino);
        if (err)
@@ -224,12 +222,9 @@ next_attr:
                if (!attr->non_res) {
                        ni->i_valid = inode->i_size = rsize;
                        inode_set_bytes(inode, rsize);
-                       t32 = asize;
-               } else {
-                       t32 = le16_to_cpu(attr->nres.run_off);
                }
 
-               mode = S_IFREG | (0777 & sbi->options.fs_fmask_inv);
+               mode = S_IFREG | (0777 & sbi->options->fs_fmask_inv);
 
                if (!attr->non_res) {
                        ni->ni_flags |= NI_FLAG_RESIDENT;
@@ -272,7 +267,7 @@ next_attr:
                        goto out;
 
                mode = sb->s_root
-                              ? (S_IFDIR | (0777 & sbi->options.fs_dmask_inv))
+                              ? (S_IFDIR | (0777 & sbi->options->fs_dmask_inv))
                               : (S_IFDIR | 0777);
                goto next_attr;
 
@@ -315,17 +310,14 @@ next_attr:
                rp_fa = ni_parse_reparse(ni, attr, &rp);
                switch (rp_fa) {
                case REPARSE_LINK:
-                       if (!attr->non_res) {
-                               inode->i_size = rsize;
-                               inode_set_bytes(inode, rsize);
-                               t32 = asize;
-                       } else {
-                               inode->i_size =
-                                       le64_to_cpu(attr->nres.data_size);
-                               t32 = le16_to_cpu(attr->nres.run_off);
-                       }
+                       /*
+                        * Normal symlink.
+                        * Assume one unicode symbol == one utf8.
+                        */
+                       inode->i_size = le16_to_cpu(rp.SymbolicLinkReparseBuffer
+                                                           .PrintNameLength) /
+                                       sizeof(u16);
 
-                       /* Looks like normal symlink. */
                        ni->i_valid = inode->i_size;
 
                        /* Clear directory bit. */
@@ -422,7 +414,7 @@ end_enum:
                ni->std_fa &= ~FILE_ATTRIBUTE_DIRECTORY;
                inode->i_op = &ntfs_link_inode_operations;
                inode->i_fop = NULL;
-               inode_nohighmem(inode); // ??
+               inode_nohighmem(inode);
        } else if (S_ISREG(mode)) {
                ni->std_fa &= ~FILE_ATTRIBUTE_DIRECTORY;
                inode->i_op = &ntfs_file_inode_operations;
@@ -443,7 +435,7 @@ end_enum:
                goto out;
        }
 
-       if ((sbi->options.sys_immutable &&
+       if ((sbi->options->sys_immutable &&
             (std5->fa & FILE_ATTRIBUTE_SYSTEM)) &&
            !S_ISFIFO(mode) && !S_ISSOCK(mode) && !S_ISLNK(mode)) {
                inode->i_flags |= S_IMMUTABLE;
@@ -1200,9 +1192,13 @@ struct inode *ntfs_create_inode(struct user_namespace *mnt_userns,
        struct REPARSE_DATA_BUFFER *rp = NULL;
        bool rp_inserted = false;
 
+       ni_lock_dir(dir_ni);
+
        dir_root = indx_get_root(&dir_ni->dir, dir_ni, NULL, NULL);
-       if (!dir_root)
-               return ERR_PTR(-EINVAL);
+       if (!dir_root) {
+               err = -EINVAL;
+               goto out1;
+       }
 
        if (S_ISDIR(mode)) {
                /* Use parent's directory attributes. */
@@ -1244,7 +1240,7 @@ struct inode *ntfs_create_inode(struct user_namespace *mnt_userns,
                 *      }
                 */
        } else if (S_ISREG(mode)) {
-               if (sbi->options.sparse) {
+               if (sbi->options->sparse) {
                        /* Sparsed regular file, cause option 'sparse'. */
                        fa = FILE_ATTRIBUTE_SPARSE_FILE |
                             FILE_ATTRIBUTE_ARCHIVE;
@@ -1486,7 +1482,10 @@ struct inode *ntfs_create_inode(struct user_namespace *mnt_userns,
                asize = ALIGN(SIZEOF_RESIDENT + nsize, 8);
                t16 = PtrOffset(rec, attr);
 
-               /* 0x78 - the size of EA + EAINFO to store WSL */
+               /*
+                * Below function 'ntfs_save_wsl_perm' requires 0x78 bytes.
+                * It is good idea to keep extened attributes resident.
+                */
                if (asize + t16 + 0x78 + 8 > sbi->record_size) {
                        CLST alen;
                        CLST clst = bytes_to_cluster(sbi, nsize);
@@ -1521,14 +1520,14 @@ struct inode *ntfs_create_inode(struct user_namespace *mnt_userns,
                        }
 
                        asize = SIZEOF_NONRESIDENT + ALIGN(err, 8);
-                       inode->i_size = nsize;
                } else {
                        attr->res.data_off = SIZEOF_RESIDENT_LE;
                        attr->res.data_size = cpu_to_le32(nsize);
                        memcpy(Add2Ptr(attr, SIZEOF_RESIDENT), rp, nsize);
-                       inode->i_size = nsize;
                        nsize = 0;
                }
+               /* Size of symlink equals the length of input string. */
+               inode->i_size = size;
 
                attr->size = cpu_to_le32(asize);
 
@@ -1551,6 +1550,9 @@ struct inode *ntfs_create_inode(struct user_namespace *mnt_userns,
        if (err)
                goto out6;
 
+       /* Unlock parent directory before ntfs_init_acl. */
+       ni_unlock(dir_ni);
+
        inode->i_generation = le16_to_cpu(rec->seq);
 
        dir->i_mtime = dir->i_ctime = inode->i_atime;
@@ -1562,6 +1564,8 @@ struct inode *ntfs_create_inode(struct user_namespace *mnt_userns,
                inode->i_op = &ntfs_link_inode_operations;
                inode->i_fop = NULL;
                inode->i_mapping->a_ops = &ntfs_aops;
+               inode->i_size = size;
+               inode_nohighmem(inode);
        } else if (S_ISREG(mode)) {
                inode->i_op = &ntfs_file_inode_operations;
                inode->i_fop = &ntfs_file_operations;
@@ -1577,7 +1581,7 @@ struct inode *ntfs_create_inode(struct user_namespace *mnt_userns,
        if (!S_ISLNK(mode) && (sb->s_flags & SB_POSIXACL)) {
                err = ntfs_init_acl(mnt_userns, inode, dir);
                if (err)
-                       goto out6;
+                       goto out7;
        } else
 #endif
        {
@@ -1586,7 +1590,7 @@ struct inode *ntfs_create_inode(struct user_namespace *mnt_userns,
 
        /* Write non resident data. */
        if (nsize) {
-               err = ntfs_sb_write_run(sbi, &ni->file.run, 0, rp, nsize);
+               err = ntfs_sb_write_run(sbi, &ni->file.run, 0, rp, nsize, 0);
                if (err)
                        goto out7;
        }
@@ -1607,8 +1611,10 @@ struct inode *ntfs_create_inode(struct user_namespace *mnt_userns,
 out7:
 
        /* Undo 'indx_insert_entry'. */
+       ni_lock_dir(dir_ni);
        indx_delete_entry(&dir_ni->dir, dir_ni, new_de + 1,
                          le16_to_cpu(new_de->key_size), sbi);
+       /* ni_unlock(dir_ni); will be called later. */
 out6:
        if (rp_inserted)
                ntfs_remove_reparse(sbi, IO_REPARSE_TAG_SYMLINK, &new_de->ref);
@@ -1632,8 +1638,10 @@ out2:
        kfree(rp);
 
 out1:
-       if (err)
+       if (err) {
+               ni_unlock(dir_ni);
                return ERR_PTR(err);
+       }
 
        unlock_new_inode(inode);
 
@@ -1754,15 +1762,15 @@ void ntfs_evict_inode(struct inode *inode)
 static noinline int ntfs_readlink_hlp(struct inode *inode, char *buffer,
                                      int buflen)
 {
-       int i, err = 0;
+       int i, err = -EINVAL;
        struct ntfs_inode *ni = ntfs_i(inode);
        struct super_block *sb = inode->i_sb;
        struct ntfs_sb_info *sbi = sb->s_fs_info;
-       u64 i_size = inode->i_size;
-       u16 nlen = 0;
+       u64 size;
+       u16 ulen = 0;
        void *to_free = NULL;
        struct REPARSE_DATA_BUFFER *rp;
-       struct le_str *uni;
+       const __le16 *uname;
        struct ATTRIB *attr;
 
        /* Reparse data present. Try to parse it. */
@@ -1771,68 +1779,64 @@ static noinline int ntfs_readlink_hlp(struct inode *inode, char *buffer,
 
        *buffer = 0;
 
-       /* Read into temporal buffer. */
-       if (i_size > sbi->reparse.max_size || i_size <= sizeof(u32)) {
-               err = -EINVAL;
-               goto out;
-       }
-
        attr = ni_find_attr(ni, NULL, NULL, ATTR_REPARSE, NULL, 0, NULL, NULL);
-       if (!attr) {
-               err = -EINVAL;
+       if (!attr)
                goto out;
-       }
 
        if (!attr->non_res) {
-               rp = resident_data_ex(attr, i_size);
-               if (!rp) {
-                       err = -EINVAL;
+               rp = resident_data_ex(attr, sizeof(struct REPARSE_DATA_BUFFER));
+               if (!rp)
                        goto out;
-               }
+               size = le32_to_cpu(attr->res.data_size);
        } else {
-               rp = kmalloc(i_size, GFP_NOFS);
+               size = le64_to_cpu(attr->nres.data_size);
+               rp = NULL;
+       }
+
+       if (size > sbi->reparse.max_size || size <= sizeof(u32))
+               goto out;
+
+       if (!rp) {
+               rp = kmalloc(size, GFP_NOFS);
                if (!rp) {
                        err = -ENOMEM;
                        goto out;
                }
                to_free = rp;
-               err = ntfs_read_run_nb(sbi, &ni->file.run, 0, rp, i_size, NULL);
+               /* Read into temporal buffer. */
+               err = ntfs_read_run_nb(sbi, &ni->file.run, 0, rp, size, NULL);
                if (err)
                        goto out;
        }
 
-       err = -EINVAL;
-
        /* Microsoft Tag. */
        switch (rp->ReparseTag) {
        case IO_REPARSE_TAG_MOUNT_POINT:
                /* Mount points and junctions. */
                /* Can we use 'Rp->MountPointReparseBuffer.PrintNameLength'? */
-               if (i_size <= offsetof(struct REPARSE_DATA_BUFFER,
-                                      MountPointReparseBuffer.PathBuffer))
+               if (size <= offsetof(struct REPARSE_DATA_BUFFER,
+                                    MountPointReparseBuffer.PathBuffer))
                        goto out;
-               uni = Add2Ptr(rp,
-                             offsetof(struct REPARSE_DATA_BUFFER,
-                                      MountPointReparseBuffer.PathBuffer) +
-                                     le16_to_cpu(rp->MountPointReparseBuffer
-                                                         .PrintNameOffset) -
-                                     2);
-               nlen = le16_to_cpu(rp->MountPointReparseBuffer.PrintNameLength);
+               uname = Add2Ptr(rp,
+                               offsetof(struct REPARSE_DATA_BUFFER,
+                                        MountPointReparseBuffer.PathBuffer) +
+                                       le16_to_cpu(rp->MountPointReparseBuffer
+                                                           .PrintNameOffset));
+               ulen = le16_to_cpu(rp->MountPointReparseBuffer.PrintNameLength);
                break;
 
        case IO_REPARSE_TAG_SYMLINK:
                /* FolderSymbolicLink */
                /* Can we use 'Rp->SymbolicLinkReparseBuffer.PrintNameLength'? */
-               if (i_size <= offsetof(struct REPARSE_DATA_BUFFER,
-                                      SymbolicLinkReparseBuffer.PathBuffer))
+               if (size <= offsetof(struct REPARSE_DATA_BUFFER,
+                                    SymbolicLinkReparseBuffer.PathBuffer))
                        goto out;
-               uni = Add2Ptr(rp,
-                             offsetof(struct REPARSE_DATA_BUFFER,
-                                      SymbolicLinkReparseBuffer.PathBuffer) +
-                                     le16_to_cpu(rp->SymbolicLinkReparseBuffer
-                                                         .PrintNameOffset) -
-                                     2);
-               nlen = le16_to_cpu(
+               uname = Add2Ptr(
+                       rp, offsetof(struct REPARSE_DATA_BUFFER,
+                                    SymbolicLinkReparseBuffer.PathBuffer) +
+                                   le16_to_cpu(rp->SymbolicLinkReparseBuffer
+                                                       .PrintNameOffset));
+               ulen = le16_to_cpu(
                        rp->SymbolicLinkReparseBuffer.PrintNameLength);
                break;
 
@@ -1864,29 +1868,28 @@ static noinline int ntfs_readlink_hlp(struct inode *inode, char *buffer,
                        goto out;
                }
                if (!IsReparseTagNameSurrogate(rp->ReparseTag) ||
-                   i_size <= sizeof(struct REPARSE_POINT)) {
+                   size <= sizeof(struct REPARSE_POINT)) {
                        goto out;
                }
 
                /* Users tag. */
-               uni = Add2Ptr(rp, sizeof(struct REPARSE_POINT) - 2);
-               nlen = le16_to_cpu(rp->ReparseDataLength) -
+               uname = Add2Ptr(rp, sizeof(struct REPARSE_POINT));
+               ulen = le16_to_cpu(rp->ReparseDataLength) -
                       sizeof(struct REPARSE_POINT);
        }
 
        /* Convert nlen from bytes to UNICODE chars. */
-       nlen >>= 1;
+       ulen >>= 1;
 
        /* Check that name is available. */
-       if (!nlen || &uni->name[nlen] > (__le16 *)Add2Ptr(rp, i_size))
+       if (!ulen || uname + ulen > (__le16 *)Add2Ptr(rp, size))
                goto out;
 
        /* If name is already zero terminated then truncate it now. */
-       if (!uni->name[nlen - 1])
-               nlen -= 1;
-       uni->len = nlen;
+       if (!uname[ulen - 1])
+               ulen -= 1;
 
-       err = ntfs_utf16_to_nls(sbi, uni, buffer, buflen);
+       err = ntfs_utf16_to_nls(sbi, uname, ulen, buffer, buflen);
 
        if (err < 0)
                goto out;
index 2d70ae4..dd7ced0 100644 (file)
@@ -5,6 +5,9 @@
  * Copyright (C) 2015 Eric Biggers
  */
 
+#ifndef _LINUX_NTFS3_LIB_DECOMPRESS_COMMON_H
+#define _LINUX_NTFS3_LIB_DECOMPRESS_COMMON_H
+
 #include <linux/string.h>
 #include <linux/compiler.h>
 #include <linux/types.h>
@@ -336,3 +339,5 @@ static forceinline u8 *lz_copy(u8 *dst, u32 length, u32 offset, const u8 *bufend
 
        return dst;
 }
+
+#endif /* _LINUX_NTFS3_LIB_DECOMPRESS_COMMON_H */
index f508fba..90309a5 100644 (file)
@@ -7,6 +7,10 @@
  * - linux kernel code style
  */
 
+#ifndef _LINUX_NTFS3_LIB_LIB_H
+#define _LINUX_NTFS3_LIB_LIB_H
+
+#include <linux/types.h>
 
 /* globals from xpress_decompress.c */
 struct xpress_decompressor *xpress_allocate_decompressor(void);
@@ -24,3 +28,5 @@ int lzx_decompress(struct lzx_decompressor *__restrict d,
                   const void *__restrict compressed_data,
                   size_t compressed_size, void *__restrict uncompressed_data,
                   size_t uncompressed_size);
+
+#endif /* _LINUX_NTFS3_LIB_LIB_H */
index f1f691a..28f6545 100644 (file)
@@ -5,13 +5,13 @@
  *
  */
 
-#include <linux/blkdev.h>
-#include <linux/buffer_head.h>
-#include <linux/fs.h>
-#include <linux/nls.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/stddef.h>
+#include <linux/string.h>
+#include <linux/types.h>
 
 #include "debug.h"
-#include "ntfs.h"
 #include "ntfs_fs.h"
 
 // clang-format off
@@ -292,7 +292,7 @@ next:
 /*
  * get_lznt_ctx
  * @level: 0 - Standard compression.
- *        !0 - Best compression, requires a lot of cpu.
+ *        !0 - Best compression, requires a lot of cpu.
  */
 struct lznt *get_lznt_ctx(int level)
 {
index e58415d..bc74121 100644 (file)
@@ -5,11 +5,7 @@
  *
  */
 
-#include <linux/blkdev.h>
-#include <linux/buffer_head.h>
 #include <linux/fs.h>
-#include <linux/iversion.h>
-#include <linux/namei.h>
 #include <linux/nls.h>
 
 #include "debug.h"
@@ -99,16 +95,11 @@ static struct dentry *ntfs_lookup(struct inode *dir, struct dentry *dentry,
 static int ntfs_create(struct user_namespace *mnt_userns, struct inode *dir,
                       struct dentry *dentry, umode_t mode, bool excl)
 {
-       struct ntfs_inode *ni = ntfs_i(dir);
        struct inode *inode;
 
-       ni_lock_dir(ni);
-
        inode = ntfs_create_inode(mnt_userns, dir, dentry, NULL, S_IFREG | mode,
                                  0, NULL, 0, NULL);
 
-       ni_unlock(ni);
-
        return IS_ERR(inode) ? PTR_ERR(inode) : 0;
 }
 
@@ -120,16 +111,11 @@ static int ntfs_create(struct user_namespace *mnt_userns, struct inode *dir,
 static int ntfs_mknod(struct user_namespace *mnt_userns, struct inode *dir,
                      struct dentry *dentry, umode_t mode, dev_t rdev)
 {
-       struct ntfs_inode *ni = ntfs_i(dir);
        struct inode *inode;
 
-       ni_lock_dir(ni);
-
        inode = ntfs_create_inode(mnt_userns, dir, dentry, NULL, mode, rdev,
                                  NULL, 0, NULL);
 
-       ni_unlock(ni);
-
        return IS_ERR(inode) ? PTR_ERR(inode) : 0;
 }
 
@@ -200,15 +186,10 @@ static int ntfs_symlink(struct user_namespace *mnt_userns, struct inode *dir,
 {
        u32 size = strlen(symname);
        struct inode *inode;
-       struct ntfs_inode *ni = ntfs_i(dir);
-
-       ni_lock_dir(ni);
 
        inode = ntfs_create_inode(mnt_userns, dir, dentry, NULL, S_IFLNK | 0777,
                                  0, symname, size, NULL);
 
-       ni_unlock(ni);
-
        return IS_ERR(inode) ? PTR_ERR(inode) : 0;
 }
 
@@ -219,15 +200,10 @@ static int ntfs_mkdir(struct user_namespace *mnt_userns, struct inode *dir,
                      struct dentry *dentry, umode_t mode)
 {
        struct inode *inode;
-       struct ntfs_inode *ni = ntfs_i(dir);
-
-       ni_lock_dir(ni);
 
        inode = ntfs_create_inode(mnt_userns, dir, dentry, NULL, S_IFDIR | mode,
                                  0, NULL, 0, NULL);
 
-       ni_unlock(ni);
-
        return IS_ERR(inode) ? PTR_ERR(inode) : 0;
 }
 
index 6bb3e59..9cc396b 100644 (file)
 #ifndef _LINUX_NTFS3_NTFS_H
 #define _LINUX_NTFS3_NTFS_H
 
-/* TODO: Check 4K MFT record and 512 bytes cluster. */
+#include <linux/blkdev.h>
+#include <linux/build_bug.h>
+#include <linux/kernel.h>
+#include <linux/stddef.h>
+#include <linux/string.h>
+#include <linux/types.h>
+
+#include "debug.h"
 
-/* Activate this define to use binary search in indexes. */
-#define NTFS3_INDEX_BINARY_SEARCH
+/* TODO: Check 4K MFT record and 512 bytes cluster. */
 
 /* Check each run for marked clusters. */
 #define NTFS3_CHECK_FREE_CLST
 
 #define NTFS_NAME_LEN 255
 
-/* ntfs.sys used 500 maximum links on-disk struct allows up to 0xffff. */
-#define NTFS_LINK_MAX 0x400
-//#define NTFS_LINK_MAX 0xffff
+/*
+ * ntfs.sys used 500 maximum links on-disk struct allows up to 0xffff.
+ * xfstest generic/041 creates 3003 hardlinks.
+ */
+#define NTFS_LINK_MAX 4000
 
 /*
  * Activate to use 64 bit clusters instead of 32 bits in ntfs.sys.
index dc71c59..8aaec7e 100644 (file)
@@ -9,6 +9,37 @@
 #ifndef _LINUX_NTFS3_NTFS_FS_H
 #define _LINUX_NTFS3_NTFS_FS_H
 
+#include <linux/blkdev.h>
+#include <linux/buffer_head.h>
+#include <linux/cleancache.h>
+#include <linux/fs.h>
+#include <linux/highmem.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/mutex.h>
+#include <linux/page-flags.h>
+#include <linux/pagemap.h>
+#include <linux/rbtree.h>
+#include <linux/rwsem.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/time64.h>
+#include <linux/types.h>
+#include <linux/uidgid.h>
+#include <asm/div64.h>
+#include <asm/page.h>
+
+#include "debug.h"
+#include "ntfs.h"
+
+struct dentry;
+struct fiemap_extent_info;
+struct user_namespace;
+struct page;
+struct writeback_control;
+enum utf16_endian;
+
+
 #define MINUS_ONE_T                    ((size_t)(-1))
 /* Biggest MFT / smallest cluster */
 #define MAXIMUM_BYTES_PER_MFT          4096
@@ -52,6 +83,7 @@
 // clang-format on
 
 struct ntfs_mount_options {
+       char *nls_name;
        struct nls_table *nls;
 
        kuid_t fs_uid;
@@ -59,19 +91,16 @@ struct ntfs_mount_options {
        u16 fs_fmask_inv;
        u16 fs_dmask_inv;
 
-       unsigned uid : 1, /* uid was set. */
-               gid : 1, /* gid was set. */
-               fmask : 1, /* fmask was set. */
-               dmask : 1, /* dmask was set. */
-               sys_immutable : 1, /* Immutable system files. */
-               discard : 1, /* Issue discard requests on deletions. */
-               sparse : 1, /* Create sparse files. */
-               showmeta : 1, /* Show meta files. */
-               nohidden : 1, /* Do not show hidden files. */
-               force : 1, /* Rw mount dirty volume. */
-               no_acs_rules : 1, /*Exclude acs rules. */
-               prealloc : 1 /* Preallocate space when file is growing. */
-               ;
+       unsigned fmask : 1; /* fmask was set. */
+       unsigned dmask : 1; /*dmask was set. */
+       unsigned sys_immutable : 1; /* Immutable system files. */
+       unsigned discard : 1; /* Issue discard requests on deletions. */
+       unsigned sparse : 1; /* Create sparse files. */
+       unsigned showmeta : 1; /* Show meta files. */
+       unsigned nohidden : 1; /* Do not show hidden files. */
+       unsigned force : 1; /* RW mount dirty volume. */
+       unsigned noacsrules : 1; /* Exclude acs rules. */
+       unsigned prealloc : 1; /* Preallocate space when file is growing. */
 };
 
 /* Special value to unpack and deallocate. */
@@ -182,10 +211,8 @@ struct ntfs_sb_info {
        u32 blocks_per_cluster; // cluster_size / sb->s_blocksize
 
        u32 record_size;
-       u32 sector_size;
        u32 index_size;
 
-       u8 sector_bits;
        u8 cluster_bits;
        u8 record_bits;
 
@@ -279,7 +306,7 @@ struct ntfs_sb_info {
 #endif
        } compress;
 
-       struct ntfs_mount_options options;
+       struct ntfs_mount_options *options;
        struct ratelimit_state msg_ratelimit;
 };
 
@@ -436,7 +463,7 @@ bool al_remove_le(struct ntfs_inode *ni, struct ATTR_LIST_ENTRY *le);
 bool al_delete_le(struct ntfs_inode *ni, enum ATTR_TYPE type, CLST vcn,
                  const __le16 *name, size_t name_len,
                  const struct MFT_REF *ref);
-int al_update(struct ntfs_inode *ni);
+int al_update(struct ntfs_inode *ni, int sync);
 static inline size_t al_aligned(size_t size)
 {
        return (size + 1023) & ~(size_t)1023;
@@ -448,7 +475,7 @@ bool are_bits_set(const ulong *map, size_t bit, size_t nbits);
 size_t get_set_bits_ex(const ulong *map, size_t bit, size_t nbits);
 
 /* Globals from dir.c */
-int ntfs_utf16_to_nls(struct ntfs_sb_info *sbi, const struct le_str *uni,
+int ntfs_utf16_to_nls(struct ntfs_sb_info *sbi, const __le16 *name, u32 len,
                      u8 *buf, int buf_len);
 int ntfs_nls_to_utf16(struct ntfs_sb_info *sbi, const u8 *name, u32 name_len,
                      struct cpu_str *uni, u32 max_ulen,
@@ -520,7 +547,7 @@ struct ATTR_FILE_NAME *ni_fname_type(struct ntfs_inode *ni, u8 name_type,
                                     struct ATTR_LIST_ENTRY **entry);
 int ni_new_attr_flags(struct ntfs_inode *ni, enum FILE_ATTRIBUTE new_fa);
 enum REPARSE_SIGN ni_parse_reparse(struct ntfs_inode *ni, struct ATTRIB *attr,
-                                  void *buffer);
+                                  struct REPARSE_DATA_BUFFER *buffer);
 int ni_write_inode(struct inode *inode, int sync, const char *hint);
 #define _ni_write_inode(i, w) ni_write_inode(i, w, __func__)
 int ni_fiemap(struct ntfs_inode *ni, struct fiemap_extent_info *fieinfo,
@@ -577,7 +604,7 @@ int ntfs_sb_read(struct super_block *sb, u64 lbo, size_t bytes, void *buffer);
 int ntfs_sb_write(struct super_block *sb, u64 lbo, size_t bytes,
                  const void *buffer, int wait);
 int ntfs_sb_write_run(struct ntfs_sb_info *sbi, const struct runs_tree *run,
-                     u64 vbo, const void *buf, size_t bytes);
+                     u64 vbo, const void *buf, size_t bytes, int sync);
 struct buffer_head *ntfs_bread_run(struct ntfs_sb_info *sbi,
                                   const struct runs_tree *run, u64 vbo);
 int ntfs_read_run_nb(struct ntfs_sb_info *sbi, const struct runs_tree *run,
index 103705c..861e357 100644 (file)
@@ -5,10 +5,7 @@
  *
  */
 
-#include <linux/blkdev.h>
-#include <linux/buffer_head.h>
 #include <linux/fs.h>
-#include <linux/nls.h>
 
 #include "debug.h"
 #include "ntfs.h"
index 26ed2b6..a8fec65 100644 (file)
@@ -7,10 +7,8 @@
  */
 
 #include <linux/blkdev.h>
-#include <linux/buffer_head.h>
 #include <linux/fs.h>
 #include <linux/log2.h>
-#include <linux/nls.h>
 
 #include "debug.h"
 #include "ntfs.h"
index 55bbc92..d41d769 100644 (file)
  *
  */
 
-#include <linux/backing-dev.h>
 #include <linux/blkdev.h>
 #include <linux/buffer_head.h>
 #include <linux/exportfs.h>
 #include <linux/fs.h>
-#include <linux/iversion.h>
+#include <linux/fs_context.h>
+#include <linux/fs_parser.h>
 #include <linux/log2.h>
 #include <linux/module.h>
 #include <linux/nls.h>
-#include <linux/parser.h>
 #include <linux/seq_file.h>
 #include <linux/statfs.h>
 
@@ -205,9 +204,11 @@ void *ntfs_put_shared(void *ptr)
        return ret;
 }
 
-static inline void clear_mount_options(struct ntfs_mount_options *options)
+static inline void put_mount_options(struct ntfs_mount_options *options)
 {
+       kfree(options->nls_name);
        unload_nls(options->nls);
+       kfree(options);
 }
 
 enum Opt {
@@ -223,218 +224,175 @@ enum Opt {
        Opt_nohidden,
        Opt_showmeta,
        Opt_acl,
-       Opt_noatime,
-       Opt_nls,
+       Opt_iocharset,
        Opt_prealloc,
-       Opt_no_acs_rules,
+       Opt_noacsrules,
        Opt_err,
 };
 
-static const match_table_t ntfs_tokens = {
-       { Opt_uid, "uid=%u" },
-       { Opt_gid, "gid=%u" },
-       { Opt_umask, "umask=%o" },
-       { Opt_dmask, "dmask=%o" },
-       { Opt_fmask, "fmask=%o" },
-       { Opt_immutable, "sys_immutable" },
-       { Opt_discard, "discard" },
-       { Opt_force, "force" },
-       { Opt_sparse, "sparse" },
-       { Opt_nohidden, "nohidden" },
-       { Opt_acl, "acl" },
-       { Opt_noatime, "noatime" },
-       { Opt_showmeta, "showmeta" },
-       { Opt_nls, "nls=%s" },
-       { Opt_prealloc, "prealloc" },
-       { Opt_no_acs_rules, "no_acs_rules" },
-       { Opt_err, NULL },
+static const struct fs_parameter_spec ntfs_fs_parameters[] = {
+       fsparam_u32("uid",                      Opt_uid),
+       fsparam_u32("gid",                      Opt_gid),
+       fsparam_u32oct("umask",                 Opt_umask),
+       fsparam_u32oct("dmask",                 Opt_dmask),
+       fsparam_u32oct("fmask",                 Opt_fmask),
+       fsparam_flag_no("sys_immutable",        Opt_immutable),
+       fsparam_flag_no("discard",              Opt_discard),
+       fsparam_flag_no("force",                Opt_force),
+       fsparam_flag_no("sparse",               Opt_sparse),
+       fsparam_flag_no("hidden",               Opt_nohidden),
+       fsparam_flag_no("acl",                  Opt_acl),
+       fsparam_flag_no("showmeta",             Opt_showmeta),
+       fsparam_flag_no("prealloc",             Opt_prealloc),
+       fsparam_flag_no("acsrules",             Opt_noacsrules),
+       fsparam_string("iocharset",             Opt_iocharset),
+       {}
 };
 
-static noinline int ntfs_parse_options(struct super_block *sb, char *options,
-                                      int silent,
-                                      struct ntfs_mount_options *opts)
+/*
+ * Load nls table or if @nls is utf8 then return NULL.
+ */
+static struct nls_table *ntfs_load_nls(char *nls)
 {
-       char *p;
-       substring_t args[MAX_OPT_ARGS];
-       int option;
-       char nls_name[30];
-       struct nls_table *nls;
+       struct nls_table *ret;
 
-       opts->fs_uid = current_uid();
-       opts->fs_gid = current_gid();
-       opts->fs_fmask_inv = opts->fs_dmask_inv = ~current_umask();
-       nls_name[0] = 0;
+       if (!nls)
+               nls = CONFIG_NLS_DEFAULT;
 
-       if (!options)
-               goto out;
+       if (strcmp(nls, "utf8") == 0)
+               return NULL;
 
-       while ((p = strsep(&options, ","))) {
-               int token;
+       if (strcmp(nls, CONFIG_NLS_DEFAULT) == 0)
+               return load_nls_default();
 
-               if (!*p)
-                       continue;
+       ret = load_nls(nls);
+       if (ret)
+               return ret;
 
-               token = match_token(p, ntfs_tokens, args);
-               switch (token) {
-               case Opt_immutable:
-                       opts->sys_immutable = 1;
-                       break;
-               case Opt_uid:
-                       if (match_int(&args[0], &option))
-                               return -EINVAL;
-                       opts->fs_uid = make_kuid(current_user_ns(), option);
-                       if (!uid_valid(opts->fs_uid))
-                               return -EINVAL;
-                       opts->uid = 1;
-                       break;
-               case Opt_gid:
-                       if (match_int(&args[0], &option))
-                               return -EINVAL;
-                       opts->fs_gid = make_kgid(current_user_ns(), option);
-                       if (!gid_valid(opts->fs_gid))
-                               return -EINVAL;
-                       opts->gid = 1;
-                       break;
-               case Opt_umask:
-                       if (match_octal(&args[0], &option))
-                               return -EINVAL;
-                       opts->fs_fmask_inv = opts->fs_dmask_inv = ~option;
-                       opts->fmask = opts->dmask = 1;
-                       break;
-               case Opt_dmask:
-                       if (match_octal(&args[0], &option))
-                               return -EINVAL;
-                       opts->fs_dmask_inv = ~option;
-                       opts->dmask = 1;
-                       break;
-               case Opt_fmask:
-                       if (match_octal(&args[0], &option))
-                               return -EINVAL;
-                       opts->fs_fmask_inv = ~option;
-                       opts->fmask = 1;
-                       break;
-               case Opt_discard:
-                       opts->discard = 1;
-                       break;
-               case Opt_force:
-                       opts->force = 1;
-                       break;
-               case Opt_sparse:
-                       opts->sparse = 1;
-                       break;
-               case Opt_nohidden:
-                       opts->nohidden = 1;
-                       break;
-               case Opt_acl:
+       return ERR_PTR(-EINVAL);
+}
+
+static int ntfs_fs_parse_param(struct fs_context *fc,
+                              struct fs_parameter *param)
+{
+       struct ntfs_mount_options *opts = fc->fs_private;
+       struct fs_parse_result result;
+       int opt;
+
+       opt = fs_parse(fc, ntfs_fs_parameters, param, &result);
+       if (opt < 0)
+               return opt;
+
+       switch (opt) {
+       case Opt_uid:
+               opts->fs_uid = make_kuid(current_user_ns(), result.uint_32);
+               if (!uid_valid(opts->fs_uid))
+                       return invalf(fc, "ntfs3: Invalid value for uid.");
+               break;
+       case Opt_gid:
+               opts->fs_gid = make_kgid(current_user_ns(), result.uint_32);
+               if (!gid_valid(opts->fs_gid))
+                       return invalf(fc, "ntfs3: Invalid value for gid.");
+               break;
+       case Opt_umask:
+               if (result.uint_32 & ~07777)
+                       return invalf(fc, "ntfs3: Invalid value for umask.");
+               opts->fs_fmask_inv = ~result.uint_32;
+               opts->fs_dmask_inv = ~result.uint_32;
+               opts->fmask = 1;
+               opts->dmask = 1;
+               break;
+       case Opt_dmask:
+               if (result.uint_32 & ~07777)
+                       return invalf(fc, "ntfs3: Invalid value for dmask.");
+               opts->fs_dmask_inv = ~result.uint_32;
+               opts->dmask = 1;
+               break;
+       case Opt_fmask:
+               if (result.uint_32 & ~07777)
+                       return invalf(fc, "ntfs3: Invalid value for fmask.");
+               opts->fs_fmask_inv = ~result.uint_32;
+               opts->fmask = 1;
+               break;
+       case Opt_immutable:
+               opts->sys_immutable = result.negated ? 0 : 1;
+               break;
+       case Opt_discard:
+               opts->discard = result.negated ? 0 : 1;
+               break;
+       case Opt_force:
+               opts->force = result.negated ? 0 : 1;
+               break;
+       case Opt_sparse:
+               opts->sparse = result.negated ? 0 : 1;
+               break;
+       case Opt_nohidden:
+               opts->nohidden = result.negated ? 1 : 0;
+               break;
+       case Opt_acl:
+               if (!result.negated)
 #ifdef CONFIG_NTFS3_FS_POSIX_ACL
-                       sb->s_flags |= SB_POSIXACL;
-                       break;
+                       fc->sb_flags |= SB_POSIXACL;
 #else
-                       ntfs_err(sb, "support for ACL not compiled in!");
-                       return -EINVAL;
+                       return invalf(fc, "ntfs3: Support for ACL not compiled in!");
 #endif
-               case Opt_noatime:
-                       sb->s_flags |= SB_NOATIME;
-                       break;
-               case Opt_showmeta:
-                       opts->showmeta = 1;
-                       break;
-               case Opt_nls:
-                       match_strlcpy(nls_name, &args[0], sizeof(nls_name));
-                       break;
-               case Opt_prealloc:
-                       opts->prealloc = 1;
-                       break;
-               case Opt_no_acs_rules:
-                       opts->no_acs_rules = 1;
-                       break;
-               default:
-                       if (!silent)
-                               ntfs_err(
-                                       sb,
-                                       "Unrecognized mount option \"%s\" or missing value",
-                                       p);
-                       //return -EINVAL;
-               }
-       }
-
-out:
-       if (!strcmp(nls_name[0] ? nls_name : CONFIG_NLS_DEFAULT, "utf8")) {
-               /*
-                * For UTF-8 use utf16s_to_utf8s()/utf8s_to_utf16s()
-                * instead of NLS.
-                */
-               nls = NULL;
-       } else if (nls_name[0]) {
-               nls = load_nls(nls_name);
-               if (!nls) {
-                       ntfs_err(sb, "failed to load \"%s\"", nls_name);
-                       return -EINVAL;
-               }
-       } else {
-               nls = load_nls_default();
-               if (!nls) {
-                       ntfs_err(sb, "failed to load default nls");
-                       return -EINVAL;
-               }
+               else
+                       fc->sb_flags &= ~SB_POSIXACL;
+               break;
+       case Opt_showmeta:
+               opts->showmeta = result.negated ? 0 : 1;
+               break;
+       case Opt_iocharset:
+               kfree(opts->nls_name);
+               opts->nls_name = param->string;
+               param->string = NULL;
+               break;
+       case Opt_prealloc:
+               opts->prealloc = result.negated ? 0 : 1;
+               break;
+       case Opt_noacsrules:
+               opts->noacsrules = result.negated ? 1 : 0;
+               break;
+       default:
+               /* Should not be here unless we forget add case. */
+               return -EINVAL;
        }
-       opts->nls = nls;
-
        return 0;
 }
 
-static int ntfs_remount(struct super_block *sb, int *flags, char *data)
+static int ntfs_fs_reconfigure(struct fs_context *fc)
 {
-       int err, ro_rw;
+       struct super_block *sb = fc->root->d_sb;
        struct ntfs_sb_info *sbi = sb->s_fs_info;
-       struct ntfs_mount_options old_opts;
-       char *orig_data = kstrdup(data, GFP_KERNEL);
-
-       if (data && !orig_data)
-               return -ENOMEM;
+       struct ntfs_mount_options *new_opts = fc->fs_private;
+       int ro_rw;
 
-       /* Store  original options. */
-       memcpy(&old_opts, &sbi->options, sizeof(old_opts));
-       clear_mount_options(&sbi->options);
-       memset(&sbi->options, 0, sizeof(sbi->options));
-
-       err = ntfs_parse_options(sb, data, 0, &sbi->options);
-       if (err)
-               goto restore_opts;
-
-       ro_rw = sb_rdonly(sb) && !(*flags & SB_RDONLY);
+       ro_rw = sb_rdonly(sb) && !(fc->sb_flags & SB_RDONLY);
        if (ro_rw && (sbi->flags & NTFS_FLAGS_NEED_REPLAY)) {
-               ntfs_warn(
-                       sb,
-                       "Couldn't remount rw because journal is not replayed. Please umount/remount instead\n");
-               err = -EINVAL;
-               goto restore_opts;
+               errorf(fc, "ntfs3: Couldn't remount rw because journal is not replayed. Please umount/remount instead\n");
+               return -EINVAL;
        }
 
+       new_opts->nls = ntfs_load_nls(new_opts->nls_name);
+       if (IS_ERR(new_opts->nls)) {
+               new_opts->nls = NULL;
+               errorf(fc, "ntfs3: Cannot load iocharset %s", new_opts->nls_name);
+               return -EINVAL;
+       }
+       if (new_opts->nls != sbi->options->nls)
+               return invalf(fc, "ntfs3: Cannot use different iocharset when remounting!");
+
        sync_filesystem(sb);
 
        if (ro_rw && (sbi->volume.flags & VOLUME_FLAG_DIRTY) &&
-           !sbi->options.force) {
-               ntfs_warn(sb, "volume is dirty and \"force\" flag is not set!");
-               err = -EINVAL;
-               goto restore_opts;
+           !new_opts->force) {
+               errorf(fc, "ntfs3: Volume is dirty and \"force\" flag is not set!");
+               return -EINVAL;
        }
 
-       clear_mount_options(&old_opts);
-
-       *flags = (*flags & ~SB_LAZYTIME) | (sb->s_flags & SB_LAZYTIME) |
-                SB_NODIRATIME | SB_NOATIME;
-       ntfs_info(sb, "re-mounted. Opts: %s", orig_data);
-       err = 0;
-       goto out;
+       memcpy(sbi->options, new_opts, sizeof(*new_opts));
 
-restore_opts:
-       clear_mount_options(&sbi->options);
-       memcpy(&sbi->options, &old_opts, sizeof(old_opts));
-
-out:
-       kfree(orig_data);
-       return err;
+       return 0;
 }
 
 static struct kmem_cache *ntfs_inode_cachep;
@@ -513,8 +471,6 @@ static noinline void put_ntfs(struct ntfs_sb_info *sbi)
        xpress_free_decompressor(sbi->compress.xpress);
        lzx_free_decompressor(sbi->compress.lzx);
 #endif
-       clear_mount_options(&sbi->options);
-
        kfree(sbi);
 }
 
@@ -525,7 +481,9 @@ static void ntfs_put_super(struct super_block *sb)
        /* Mark rw ntfs as clear, if possible. */
        ntfs_set_state(sbi, NTFS_DIRTY_CLEAR);
 
+       put_mount_options(sbi->options);
        put_ntfs(sbi);
+       sb->s_fs_info = NULL;
 
        sync_blockdev(sb->s_bdev);
 }
@@ -552,23 +510,21 @@ static int ntfs_show_options(struct seq_file *m, struct dentry *root)
 {
        struct super_block *sb = root->d_sb;
        struct ntfs_sb_info *sbi = sb->s_fs_info;
-       struct ntfs_mount_options *opts = &sbi->options;
+       struct ntfs_mount_options *opts = sbi->options;
        struct user_namespace *user_ns = seq_user_ns(m);
 
-       if (opts->uid)
-               seq_printf(m, ",uid=%u",
-                          from_kuid_munged(user_ns, opts->fs_uid));
-       if (opts->gid)
-               seq_printf(m, ",gid=%u",
-                          from_kgid_munged(user_ns, opts->fs_gid));
+       seq_printf(m, ",uid=%u",
+                 from_kuid_munged(user_ns, opts->fs_uid));
+       seq_printf(m, ",gid=%u",
+                 from_kgid_munged(user_ns, opts->fs_gid));
        if (opts->fmask)
                seq_printf(m, ",fmask=%04o", ~opts->fs_fmask_inv);
        if (opts->dmask)
                seq_printf(m, ",dmask=%04o", ~opts->fs_dmask_inv);
        if (opts->nls)
-               seq_printf(m, ",nls=%s", opts->nls->charset);
+               seq_printf(m, ",iocharset=%s", opts->nls->charset);
        else
-               seq_puts(m, ",nls=utf8");
+               seq_puts(m, ",iocharset=utf8");
        if (opts->sys_immutable)
                seq_puts(m, ",sys_immutable");
        if (opts->discard)
@@ -581,14 +537,12 @@ static int ntfs_show_options(struct seq_file *m, struct dentry *root)
                seq_puts(m, ",nohidden");
        if (opts->force)
                seq_puts(m, ",force");
-       if (opts->no_acs_rules)
-               seq_puts(m, ",no_acs_rules");
+       if (opts->noacsrules)
+               seq_puts(m, ",noacsrules");
        if (opts->prealloc)
                seq_puts(m, ",prealloc");
        if (sb->s_flags & SB_POSIXACL)
                seq_puts(m, ",acl");
-       if (sb->s_flags & SB_NOATIME)
-               seq_puts(m, ",noatime");
 
        return 0;
 }
@@ -643,7 +597,6 @@ static const struct super_operations ntfs_sops = {
        .statfs = ntfs_statfs,
        .show_options = ntfs_show_options,
        .sync_fs = ntfs_sync_fs,
-       .remount_fs = ntfs_remount,
        .write_inode = ntfs3_write_inode,
 };
 
@@ -729,7 +682,7 @@ static int ntfs_init_from_boot(struct super_block *sb, u32 sector_size,
        struct ntfs_sb_info *sbi = sb->s_fs_info;
        int err;
        u32 mb, gb, boot_sector_size, sct_per_clst, record_size;
-       u64 sectors, clusters, fs_size, mlcn, mlcn2;
+       u64 sectors, clusters, mlcn, mlcn2;
        struct NTFS_BOOT *boot;
        struct buffer_head *bh;
        struct MFT_REC *rec;
@@ -787,20 +740,20 @@ static int ntfs_init_from_boot(struct super_block *sb, u32 sector_size,
                goto out;
        }
 
-       sbi->sector_size = boot_sector_size;
-       sbi->sector_bits = blksize_bits(boot_sector_size);
-       fs_size = (sectors + 1) << sbi->sector_bits;
+       sbi->volume.size = sectors * boot_sector_size;
 
-       gb = format_size_gb(fs_size, &mb);
+       gb = format_size_gb(sbi->volume.size + boot_sector_size, &mb);
 
        /*
         * - Volume formatted and mounted with the same sector size.
         * - Volume formatted 4K and mounted as 512.
         * - Volume formatted 512 and mounted as 4K.
         */
-       if (sbi->sector_size != sector_size) {
-               ntfs_warn(sb,
-                         "Different NTFS' sector size and media sector size");
+       if (boot_sector_size != sector_size) {
+               ntfs_warn(
+                       sb,
+                       "Different NTFS' sector size (%u) and media sector size (%u)",
+                       boot_sector_size, sector_size);
                dev_size += sector_size - 1;
        }
 
@@ -810,8 +763,19 @@ static int ntfs_init_from_boot(struct super_block *sb, u32 sector_size,
        sbi->mft.lbo = mlcn << sbi->cluster_bits;
        sbi->mft.lbo2 = mlcn2 << sbi->cluster_bits;
 
-       if (sbi->cluster_size < sbi->sector_size)
+       /* Compare boot's cluster and sector. */
+       if (sbi->cluster_size < boot_sector_size)
+               goto out;
+
+       /* Compare boot's cluster and media sector. */
+       if (sbi->cluster_size < sector_size) {
+               /* No way to use ntfs_get_block in this case. */
+               ntfs_err(
+                       sb,
+                       "Failed to mount 'cause NTFS's cluster size (%u) is less than media sector size (%u)",
+                       sbi->cluster_size, sector_size);
                goto out;
+       }
 
        sbi->cluster_mask = sbi->cluster_size - 1;
        sbi->cluster_mask_inv = ~(u64)sbi->cluster_mask;
@@ -836,10 +800,9 @@ static int ntfs_init_from_boot(struct super_block *sb, u32 sector_size,
                                  : (u32)boot->index_size << sbi->cluster_bits;
 
        sbi->volume.ser_num = le64_to_cpu(boot->serial_num);
-       sbi->volume.size = sectors << sbi->sector_bits;
 
        /* Warning if RAW volume. */
-       if (dev_size < fs_size) {
+       if (dev_size < sbi->volume.size + boot_sector_size) {
                u32 mb0, gb0;
 
                gb0 = format_size_gb(dev_size, &mb0);
@@ -883,8 +846,7 @@ static int ntfs_init_from_boot(struct super_block *sb, u32 sector_size,
        rec->total = cpu_to_le32(sbi->record_size);
        ((struct ATTRIB *)Add2Ptr(rec, ao))->type = ATTR_END;
 
-       if (sbi->cluster_size < PAGE_SIZE)
-               sb_set_blocksize(sb, sbi->cluster_size);
+       sb_set_blocksize(sb, min_t(u32, sbi->cluster_size, PAGE_SIZE));
 
        sbi->block_mask = sb->s_blocksize - 1;
        sbi->blocks_per_cluster = sbi->cluster_size >> sb->s_blocksize_bits;
@@ -897,9 +859,11 @@ static int ntfs_init_from_boot(struct super_block *sb, u32 sector_size,
        if (clusters >= (1ull << (64 - sbi->cluster_bits)))
                sbi->maxbytes = -1;
        sbi->maxbytes_sparse = -1;
+       sb->s_maxbytes = MAX_LFS_FILESIZE;
 #else
        /* Maximum size for sparse file. */
        sbi->maxbytes_sparse = (1ull << (sbi->cluster_bits + 32)) - 1;
+       sb->s_maxbytes = 0xFFFFFFFFull << sbi->cluster_bits;
 #endif
 
        err = 0;
@@ -913,14 +877,13 @@ out:
 /*
  * ntfs_fill_super - Try to mount.
  */
-static int ntfs_fill_super(struct super_block *sb, void *data, int silent)
+static int ntfs_fill_super(struct super_block *sb, struct fs_context *fc)
 {
        int err;
-       struct ntfs_sb_info *sbi;
+       struct ntfs_sb_info *sbi = sb->s_fs_info;
        struct block_device *bdev = sb->s_bdev;
-       struct inode *bd_inode = bdev->bd_inode;
-       struct request_queue *rq = bdev_get_queue(bdev);
-       struct inode *inode = NULL;
+       struct request_queue *rq;
+       struct inode *inode;
        struct ntfs_inode *ni;
        size_t i, tt;
        CLST vcn, lcn, len;
@@ -928,18 +891,11 @@ static int ntfs_fill_super(struct super_block *sb, void *data, int silent)
        const struct VOLUME_INFO *info;
        u32 idx, done, bytes;
        struct ATTR_DEF_ENTRY *t;
-       u16 *upcase = NULL;
        u16 *shared;
-       bool is_ro;
        struct MFT_REF ref;
 
        ref.high = 0;
 
-       sbi = kzalloc(sizeof(struct ntfs_sb_info), GFP_NOFS);
-       if (!sbi)
-               return -ENOMEM;
-
-       sb->s_fs_info = sbi;
        sbi->sb = sb;
        sb->s_flags |= SB_NODIRATIME;
        sb->s_magic = 0x7366746e; // "ntfs"
@@ -948,41 +904,27 @@ static int ntfs_fill_super(struct super_block *sb, void *data, int silent)
        sb->s_time_gran = NTFS_TIME_GRAN; // 100 nsec
        sb->s_xattr = ntfs_xattr_handlers;
 
-       ratelimit_state_init(&sbi->msg_ratelimit, DEFAULT_RATELIMIT_INTERVAL,
-                            DEFAULT_RATELIMIT_BURST);
-
-       err = ntfs_parse_options(sb, data, silent, &sbi->options);
-       if (err)
+       sbi->options->nls = ntfs_load_nls(sbi->options->nls_name);
+       if (IS_ERR(sbi->options->nls)) {
+               sbi->options->nls = NULL;
+               errorf(fc, "Cannot load nls %s", sbi->options->nls_name);
+               err = -EINVAL;
                goto out;
+       }
 
-       if (!rq || !blk_queue_discard(rq) || !rq->limits.discard_granularity) {
-               ;
-       } else {
+       rq = bdev_get_queue(bdev);
+       if (blk_queue_discard(rq) && rq->limits.discard_granularity) {
                sbi->discard_granularity = rq->limits.discard_granularity;
                sbi->discard_granularity_mask_inv =
                        ~(u64)(sbi->discard_granularity - 1);
        }
 
-       sb_set_blocksize(sb, PAGE_SIZE);
-
        /* Parse boot. */
        err = ntfs_init_from_boot(sb, rq ? queue_logical_block_size(rq) : 512,
-                                 bd_inode->i_size);
+                                 bdev->bd_inode->i_size);
        if (err)
                goto out;
 
-#ifdef CONFIG_NTFS3_64BIT_CLUSTER
-       sb->s_maxbytes = MAX_LFS_FILESIZE;
-#else
-       sb->s_maxbytes = 0xFFFFFFFFull << sbi->cluster_bits;
-#endif
-
-       mutex_init(&sbi->compress.mtx_lznt);
-#ifdef CONFIG_NTFS3_LZX_XPRESS
-       mutex_init(&sbi->compress.mtx_xpress);
-       mutex_init(&sbi->compress.mtx_lzx);
-#endif
-
        /*
         * Load $Volume. This should be done before $LogFile
         * 'cause 'sbi->volume.ni' is used 'ntfs_set_state'.
@@ -991,9 +933,8 @@ static int ntfs_fill_super(struct super_block *sb, void *data, int silent)
        ref.seq = cpu_to_le16(MFT_REC_VOL);
        inode = ntfs_iget5(sb, &ref, &NAME_VOLUME);
        if (IS_ERR(inode)) {
-               err = PTR_ERR(inode);
                ntfs_err(sb, "Failed to load $Volume.");
-               inode = NULL;
+               err = PTR_ERR(inode);
                goto out;
        }
 
@@ -1015,36 +956,33 @@ static int ntfs_fill_super(struct super_block *sb, void *data, int silent)
        } else {
                /* Should we break mounting here? */
                //err = -EINVAL;
-               //goto out;
+               //goto put_inode_out;
        }
 
        attr = ni_find_attr(ni, attr, NULL, ATTR_VOL_INFO, NULL, 0, NULL, NULL);
        if (!attr || is_attr_ext(attr)) {
                err = -EINVAL;
-               goto out;
+               goto put_inode_out;
        }
 
        info = resident_data_ex(attr, SIZEOF_ATTRIBUTE_VOLUME_INFO);
        if (!info) {
                err = -EINVAL;
-               goto out;
+               goto put_inode_out;
        }
 
        sbi->volume.major_ver = info->major_ver;
        sbi->volume.minor_ver = info->minor_ver;
        sbi->volume.flags = info->flags;
-
        sbi->volume.ni = ni;
-       inode = NULL;
 
        /* Load $MFTMirr to estimate recs_mirr. */
        ref.low = cpu_to_le32(MFT_REC_MIRR);
        ref.seq = cpu_to_le16(MFT_REC_MIRR);
        inode = ntfs_iget5(sb, &ref, &NAME_MIRROR);
        if (IS_ERR(inode)) {
-               err = PTR_ERR(inode);
                ntfs_err(sb, "Failed to load $MFTMirr.");
-               inode = NULL;
+               err = PTR_ERR(inode);
                goto out;
        }
 
@@ -1058,9 +996,8 @@ static int ntfs_fill_super(struct super_block *sb, void *data, int silent)
        ref.seq = cpu_to_le16(MFT_REC_LOG);
        inode = ntfs_iget5(sb, &ref, &NAME_LOGFILE);
        if (IS_ERR(inode)) {
-               err = PTR_ERR(inode);
                ntfs_err(sb, "Failed to load \x24LogFile.");
-               inode = NULL;
+               err = PTR_ERR(inode);
                goto out;
        }
 
@@ -1068,22 +1005,19 @@ static int ntfs_fill_super(struct super_block *sb, void *data, int silent)
 
        err = ntfs_loadlog_and_replay(ni, sbi);
        if (err)
-               goto out;
+               goto put_inode_out;
 
        iput(inode);
-       inode = NULL;
-
-       is_ro = sb_rdonly(sbi->sb);
 
        if (sbi->flags & NTFS_FLAGS_NEED_REPLAY) {
-               if (!is_ro) {
+               if (!sb_rdonly(sb)) {
                        ntfs_warn(sb,
                                  "failed to replay log file. Can't mount rw!");
                        err = -EINVAL;
                        goto out;
                }
        } else if (sbi->volume.flags & VOLUME_FLAG_DIRTY) {
-               if (!is_ro && !sbi->options.force) {
+               if (!sb_rdonly(sb) && !sbi->options->force) {
                        ntfs_warn(
                                sb,
                                "volume is dirty and \"force\" flag is not set!");
@@ -1098,9 +1032,8 @@ static int ntfs_fill_super(struct super_block *sb, void *data, int silent)
 
        inode = ntfs_iget5(sb, &ref, &NAME_MFT);
        if (IS_ERR(inode)) {
-               err = PTR_ERR(inode);
                ntfs_err(sb, "Failed to load $MFT.");
-               inode = NULL;
+               err = PTR_ERR(inode);
                goto out;
        }
 
@@ -1112,11 +1045,11 @@ static int ntfs_fill_super(struct super_block *sb, void *data, int silent)
 
        err = wnd_init(&sbi->mft.bitmap, sb, tt);
        if (err)
-               goto out;
+               goto put_inode_out;
 
        err = ni_load_all_mi(ni);
        if (err)
-               goto out;
+               goto put_inode_out;
 
        sbi->mft.ni = ni;
 
@@ -1125,9 +1058,8 @@ static int ntfs_fill_super(struct super_block *sb, void *data, int silent)
        ref.seq = cpu_to_le16(MFT_REC_BADCLUST);
        inode = ntfs_iget5(sb, &ref, &NAME_BADCLUS);
        if (IS_ERR(inode)) {
-               err = PTR_ERR(inode);
                ntfs_err(sb, "Failed to load $BadClus.");
-               inode = NULL;
+               err = PTR_ERR(inode);
                goto out;
        }
 
@@ -1150,18 +1082,15 @@ static int ntfs_fill_super(struct super_block *sb, void *data, int silent)
        ref.seq = cpu_to_le16(MFT_REC_BITMAP);
        inode = ntfs_iget5(sb, &ref, &NAME_BITMAP);
        if (IS_ERR(inode)) {
-               err = PTR_ERR(inode);
                ntfs_err(sb, "Failed to load $Bitmap.");
-               inode = NULL;
+               err = PTR_ERR(inode);
                goto out;
        }
 
-       ni = ntfs_i(inode);
-
 #ifndef CONFIG_NTFS3_64BIT_CLUSTER
        if (inode->i_size >> 32) {
                err = -EINVAL;
-               goto out;
+               goto put_inode_out;
        }
 #endif
 
@@ -1169,14 +1098,14 @@ static int ntfs_fill_super(struct super_block *sb, void *data, int silent)
        tt = sbi->used.bitmap.nbits;
        if (inode->i_size < bitmap_size(tt)) {
                err = -EINVAL;
-               goto out;
+               goto put_inode_out;
        }
 
        /* Not necessary. */
        sbi->used.bitmap.set_tail = true;
-       err = wnd_init(&sbi->used.bitmap, sbi->sb, tt);
+       err = wnd_init(&sbi->used.bitmap, sb, tt);
        if (err)
-               goto out;
+               goto put_inode_out;
 
        iput(inode);
 
@@ -1188,23 +1117,22 @@ static int ntfs_fill_super(struct super_block *sb, void *data, int silent)
        /* Load $AttrDef. */
        ref.low = cpu_to_le32(MFT_REC_ATTR);
        ref.seq = cpu_to_le16(MFT_REC_ATTR);
-       inode = ntfs_iget5(sbi->sb, &ref, &NAME_ATTRDEF);
+       inode = ntfs_iget5(sb, &ref, &NAME_ATTRDEF);
        if (IS_ERR(inode)) {
-               err = PTR_ERR(inode);
                ntfs_err(sb, "Failed to load $AttrDef -> %d", err);
-               inode = NULL;
+               err = PTR_ERR(inode);
                goto out;
        }
 
        if (inode->i_size < sizeof(struct ATTR_DEF_ENTRY)) {
                err = -EINVAL;
-               goto out;
+               goto put_inode_out;
        }
        bytes = inode->i_size;
        sbi->def_table = t = kmalloc(bytes, GFP_NOFS);
        if (!t) {
                err = -ENOMEM;
-               goto out;
+               goto put_inode_out;
        }
 
        for (done = idx = 0; done < bytes; done += PAGE_SIZE, idx++) {
@@ -1213,7 +1141,7 @@ static int ntfs_fill_super(struct super_block *sb, void *data, int silent)
 
                if (IS_ERR(page)) {
                        err = PTR_ERR(page);
-                       goto out;
+                       goto put_inode_out;
                }
                memcpy(Add2Ptr(t, done), page_address(page),
                       min(PAGE_SIZE, tail));
@@ -1221,7 +1149,7 @@ static int ntfs_fill_super(struct super_block *sb, void *data, int silent)
 
                if (!idx && ATTR_STD != t->type) {
                        err = -EINVAL;
-                       goto out;
+                       goto put_inode_out;
                }
        }
 
@@ -1254,33 +1182,24 @@ static int ntfs_fill_super(struct super_block *sb, void *data, int silent)
        ref.seq = cpu_to_le16(MFT_REC_UPCASE);
        inode = ntfs_iget5(sb, &ref, &NAME_UPCASE);
        if (IS_ERR(inode)) {
+               ntfs_err(sb, "Failed to load $UpCase.");
                err = PTR_ERR(inode);
-               ntfs_err(sb, "Failed to load \x24LogFile.");
-               inode = NULL;
                goto out;
        }
 
-       ni = ntfs_i(inode);
-
        if (inode->i_size != 0x10000 * sizeof(short)) {
                err = -EINVAL;
-               goto out;
-       }
-
-       sbi->upcase = upcase = kvmalloc(0x10000 * sizeof(short), GFP_KERNEL);
-       if (!upcase) {
-               err = -ENOMEM;
-               goto out;
+               goto put_inode_out;
        }
 
        for (idx = 0; idx < (0x10000 * sizeof(short) >> PAGE_SHIFT); idx++) {
                const __le16 *src;
-               u16 *dst = Add2Ptr(upcase, idx << PAGE_SHIFT);
+               u16 *dst = Add2Ptr(sbi->upcase, idx << PAGE_SHIFT);
                struct page *page = ntfs_map_page(inode->i_mapping, idx);
 
                if (IS_ERR(page)) {
                        err = PTR_ERR(page);
-                       goto out;
+                       goto put_inode_out;
                }
 
                src = page_address(page);
@@ -1294,14 +1213,13 @@ static int ntfs_fill_super(struct super_block *sb, void *data, int silent)
                ntfs_unmap_page(page);
        }
 
-       shared = ntfs_set_shared(upcase, 0x10000 * sizeof(short));
-       if (shared && upcase != shared) {
+       shared = ntfs_set_shared(sbi->upcase, 0x10000 * sizeof(short));
+       if (shared && sbi->upcase != shared) {
+               kvfree(sbi->upcase);
                sbi->upcase = shared;
-               kvfree(upcase);
        }
 
        iput(inode);
-       inode = NULL;
 
        if (is_ntfs3(sbi)) {
                /* Load $Secure. */
@@ -1331,34 +1249,31 @@ load_root:
        ref.seq = cpu_to_le16(MFT_REC_ROOT);
        inode = ntfs_iget5(sb, &ref, &NAME_ROOT);
        if (IS_ERR(inode)) {
-               err = PTR_ERR(inode);
                ntfs_err(sb, "Failed to load root.");
-               inode = NULL;
+               err = PTR_ERR(inode);
                goto out;
        }
 
-       ni = ntfs_i(inode);
-
        sb->s_root = d_make_root(inode);
-
        if (!sb->s_root) {
-               err = -EINVAL;
-               goto out;
+               err = -ENOMEM;
+               goto put_inode_out;
        }
 
+       fc->fs_private = NULL;
+
        return 0;
 
-out:
+put_inode_out:
        iput(inode);
-
-       if (sb->s_root) {
-               d_drop(sb->s_root);
-               sb->s_root = NULL;
-       }
-
+out:
+       /*
+        * Free resources here.
+        * ntfs_fs_free will be called with fc->s_fs_info = NULL
+        */
        put_ntfs(sbi);
-
        sb->s_fs_info = NULL;
+
        return err;
 }
 
@@ -1403,7 +1318,7 @@ int ntfs_discard(struct ntfs_sb_info *sbi, CLST lcn, CLST len)
        if (sbi->flags & NTFS_FLAGS_NODISCARD)
                return -EOPNOTSUPP;
 
-       if (!sbi->options.discard)
+       if (!sbi->options->discard)
                return -EOPNOTSUPP;
 
        lbo = (u64)lcn << sbi->cluster_bits;
@@ -1428,19 +1343,99 @@ int ntfs_discard(struct ntfs_sb_info *sbi, CLST lcn, CLST len)
        return err;
 }
 
-static struct dentry *ntfs_mount(struct file_system_type *fs_type, int flags,
-                                const char *dev_name, void *data)
+static int ntfs_fs_get_tree(struct fs_context *fc)
+{
+       return get_tree_bdev(fc, ntfs_fill_super);
+}
+
+/*
+ * ntfs_fs_free - Free fs_context.
+ *
+ * Note that this will be called after fill_super and reconfigure
+ * even when they pass. So they have to take pointers if they pass.
+ */
+static void ntfs_fs_free(struct fs_context *fc)
 {
-       return mount_bdev(fs_type, flags, dev_name, data, ntfs_fill_super);
+       struct ntfs_mount_options *opts = fc->fs_private;
+       struct ntfs_sb_info *sbi = fc->s_fs_info;
+
+       if (sbi)
+               put_ntfs(sbi);
+
+       if (opts)
+               put_mount_options(opts);
+}
+
+static const struct fs_context_operations ntfs_context_ops = {
+       .parse_param    = ntfs_fs_parse_param,
+       .get_tree       = ntfs_fs_get_tree,
+       .reconfigure    = ntfs_fs_reconfigure,
+       .free           = ntfs_fs_free,
+};
+
+/*
+ * ntfs_init_fs_context - Initialize spi and opts
+ *
+ * This will called when mount/remount. We will first initiliaze
+ * options so that if remount we can use just that.
+ */
+static int ntfs_init_fs_context(struct fs_context *fc)
+{
+       struct ntfs_mount_options *opts;
+       struct ntfs_sb_info *sbi;
+
+       opts = kzalloc(sizeof(struct ntfs_mount_options), GFP_NOFS);
+       if (!opts)
+               return -ENOMEM;
+
+       /* Default options. */
+       opts->fs_uid = current_uid();
+       opts->fs_gid = current_gid();
+       opts->fs_fmask_inv = ~current_umask();
+       opts->fs_dmask_inv = ~current_umask();
+
+       if (fc->purpose == FS_CONTEXT_FOR_RECONFIGURE)
+               goto ok;
+
+       sbi = kzalloc(sizeof(struct ntfs_sb_info), GFP_NOFS);
+       if (!sbi)
+               goto free_opts;
+
+       sbi->upcase = kvmalloc(0x10000 * sizeof(short), GFP_KERNEL);
+       if (!sbi->upcase)
+               goto free_sbi;
+
+       ratelimit_state_init(&sbi->msg_ratelimit, DEFAULT_RATELIMIT_INTERVAL,
+                            DEFAULT_RATELIMIT_BURST);
+
+       mutex_init(&sbi->compress.mtx_lznt);
+#ifdef CONFIG_NTFS3_LZX_XPRESS
+       mutex_init(&sbi->compress.mtx_xpress);
+       mutex_init(&sbi->compress.mtx_lzx);
+#endif
+
+       sbi->options = opts;
+       fc->s_fs_info = sbi;
+ok:
+       fc->fs_private = opts;
+       fc->ops = &ntfs_context_ops;
+
+       return 0;
+free_sbi:
+       kfree(sbi);
+free_opts:
+       kfree(opts);
+       return -ENOMEM;
 }
 
 // clang-format off
 static struct file_system_type ntfs_fs_type = {
-       .owner          = THIS_MODULE,
-       .name           = "ntfs3",
-       .mount          = ntfs_mount,
-       .kill_sb        = kill_block_super,
-       .fs_flags       = FS_REQUIRES_DEV | FS_ALLOW_IDMAP,
+       .owner                  = THIS_MODULE,
+       .name                   = "ntfs3",
+       .init_fs_context        = ntfs_init_fs_context,
+       .parameters             = ntfs_fs_parameters,
+       .kill_sb                = kill_block_super,
+       .fs_flags               = FS_REQUIRES_DEV | FS_ALLOW_IDMAP,
 };
 // clang-format on
 
index bbeba77..b5e8256 100644 (file)
@@ -5,13 +5,9 @@
  *
  */
 
-#include <linux/blkdev.h>
-#include <linux/buffer_head.h>
-#include <linux/module.h>
-#include <linux/nls.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
 
-#include "debug.h"
-#include "ntfs.h"
 #include "ntfs_fs.h"
 
 static inline u16 upcase_unicode_char(const u16 *upcase, u16 chr)
index 7282d85..afd0dda 100644 (file)
@@ -5,10 +5,7 @@
  *
  */
 
-#include <linux/blkdev.h>
-#include <linux/buffer_head.h>
 #include <linux/fs.h>
-#include <linux/nls.h>
 #include <linux/posix_acl.h>
 #include <linux/posix_acl_xattr.h>
 #include <linux/xattr.h>
@@ -78,6 +75,7 @@ static int ntfs_read_ea(struct ntfs_inode *ni, struct EA_FULL **ea,
                        size_t add_bytes, const struct EA_INFO **info)
 {
        int err;
+       struct ntfs_sb_info *sbi = ni->mi.sbi;
        struct ATTR_LIST_ENTRY *le = NULL;
        struct ATTRIB *attr_info, *attr_ea;
        void *ea_p;
@@ -102,10 +100,10 @@ static int ntfs_read_ea(struct ntfs_inode *ni, struct EA_FULL **ea,
 
        /* Check Ea limit. */
        size = le32_to_cpu((*info)->size);
-       if (size > ni->mi.sbi->ea_max_size)
+       if (size > sbi->ea_max_size)
                return -EFBIG;
 
-       if (attr_size(attr_ea) > ni->mi.sbi->ea_max_size)
+       if (attr_size(attr_ea) > sbi->ea_max_size)
                return -EFBIG;
 
        /* Allocate memory for packed Ea. */
@@ -113,15 +111,16 @@ static int ntfs_read_ea(struct ntfs_inode *ni, struct EA_FULL **ea,
        if (!ea_p)
                return -ENOMEM;
 
-       if (attr_ea->non_res) {
+       if (!size) {
+               ;
+       } else if (attr_ea->non_res) {
                struct runs_tree run;
 
                run_init(&run);
 
                err = attr_load_runs(attr_ea, ni, &run, NULL);
                if (!err)
-                       err = ntfs_read_run_nb(ni->mi.sbi, &run, 0, ea_p, size,
-                                              NULL);
+                       err = ntfs_read_run_nb(sbi, &run, 0, ea_p, size, NULL);
                run_close(&run);
 
                if (err)
@@ -260,7 +259,7 @@ out:
 
 static noinline int ntfs_set_ea(struct inode *inode, const char *name,
                                size_t name_len, const void *value,
-                               size_t val_size, int flags, int locked)
+                               size_t val_size, int flags)
 {
        struct ntfs_inode *ni = ntfs_i(inode);
        struct ntfs_sb_info *sbi = ni->mi.sbi;
@@ -279,8 +278,7 @@ static noinline int ntfs_set_ea(struct inode *inode, const char *name,
        u64 new_sz;
        void *p;
 
-       if (!locked)
-               ni_lock(ni);
+       ni_lock(ni);
 
        run_init(&ea_run);
 
@@ -370,21 +368,22 @@ static noinline int ntfs_set_ea(struct inode *inode, const char *name,
        new_ea->name[name_len] = 0;
        memcpy(new_ea->name + name_len + 1, value, val_size);
        new_pack = le16_to_cpu(ea_info.size_pack) + packed_ea_size(new_ea);
-
-       /* Should fit into 16 bits. */
-       if (new_pack > 0xffff) {
-               err = -EFBIG; // -EINVAL?
-               goto out;
-       }
        ea_info.size_pack = cpu_to_le16(new_pack);
-
        /* New size of ATTR_EA. */
        size += add;
-       if (size > sbi->ea_max_size) {
+       ea_info.size = cpu_to_le32(size);
+
+       /*
+        * 1. Check ea_info.size_pack for overflow.
+        * 2. New attibute size must fit value from $AttrDef
+        */
+       if (new_pack > 0xffff || size > sbi->ea_max_size) {
+               ntfs_inode_warn(
+                       inode,
+                       "The size of extended attributes must not exceed 64KiB");
                err = -EFBIG; // -EINVAL?
                goto out;
        }
-       ea_info.size = cpu_to_le32(size);
 
 update_ea:
 
@@ -444,7 +443,7 @@ update_ea:
                /* Delete xattr, ATTR_EA */
                ni_remove_attr_le(ni, attr, mi, le);
        } else if (attr->non_res) {
-               err = ntfs_sb_write_run(sbi, &ea_run, 0, ea_all, size);
+               err = ntfs_sb_write_run(sbi, &ea_run, 0, ea_all, size, 0);
                if (err)
                        goto out;
        } else {
@@ -468,8 +467,7 @@ update_ea:
        mark_inode_dirty(&ni->vfs_inode);
 
 out:
-       if (!locked)
-               ni_unlock(ni);
+       ni_unlock(ni);
 
        run_close(&ea_run);
        kfree(ea_all);
@@ -478,12 +476,6 @@ out:
 }
 
 #ifdef CONFIG_NTFS3_FS_POSIX_ACL
-static inline void ntfs_posix_acl_release(struct posix_acl *acl)
-{
-       if (acl && refcount_dec_and_test(&acl->a_refcount))
-               kfree(acl);
-}
-
 static struct posix_acl *ntfs_get_acl_ex(struct user_namespace *mnt_userns,
                                         struct inode *inode, int type,
                                         int locked)
@@ -521,12 +513,15 @@ static struct posix_acl *ntfs_get_acl_ex(struct user_namespace *mnt_userns,
        /* Translate extended attribute to acl. */
        if (err >= 0) {
                acl = posix_acl_from_xattr(mnt_userns, buf, err);
-               if (!IS_ERR(acl))
-                       set_cached_acl(inode, type, acl);
+       } else if (err == -ENODATA) {
+               acl = NULL;
        } else {
-               acl = err == -ENODATA ? NULL : ERR_PTR(err);
+               acl = ERR_PTR(err);
        }
 
+       if (!IS_ERR(acl))
+               set_cached_acl(inode, type, acl);
+
        __putname(buf);
 
        return acl;
@@ -546,12 +541,13 @@ struct posix_acl *ntfs_get_acl(struct inode *inode, int type, bool rcu)
 
 static noinline int ntfs_set_acl_ex(struct user_namespace *mnt_userns,
                                    struct inode *inode, struct posix_acl *acl,
-                                   int type, int locked)
+                                   int type)
 {
        const char *name;
        size_t size, name_len;
        void *value = NULL;
        int err = 0;
+       int flags;
 
        if (S_ISLNK(inode->i_mode))
                return -EOPNOTSUPP;
@@ -561,22 +557,15 @@ static noinline int ntfs_set_acl_ex(struct user_namespace *mnt_userns,
                if (acl) {
                        umode_t mode = inode->i_mode;
 
-                       err = posix_acl_equiv_mode(acl, &mode);
-                       if (err < 0)
-                               return err;
+                       err = posix_acl_update_mode(mnt_userns, inode, &mode,
+                                                   &acl);
+                       if (err)
+                               goto out;
 
                        if (inode->i_mode != mode) {
                                inode->i_mode = mode;
                                mark_inode_dirty(inode);
                        }
-
-                       if (!err) {
-                               /*
-                                * ACL can be exactly represented in the
-                                * traditional file mode permission bits.
-                                */
-                               acl = NULL;
-                       }
                }
                name = XATTR_NAME_POSIX_ACL_ACCESS;
                name_len = sizeof(XATTR_NAME_POSIX_ACL_ACCESS) - 1;
@@ -594,20 +583,24 @@ static noinline int ntfs_set_acl_ex(struct user_namespace *mnt_userns,
        }
 
        if (!acl) {
+               /* Remove xattr if it can be presented via mode. */
                size = 0;
                value = NULL;
+               flags = XATTR_REPLACE;
        } else {
                size = posix_acl_xattr_size(acl->a_count);
                value = kmalloc(size, GFP_NOFS);
                if (!value)
                        return -ENOMEM;
-
                err = posix_acl_to_xattr(mnt_userns, acl, value, size);
                if (err < 0)
                        goto out;
+               flags = 0;
        }
 
-       err = ntfs_set_ea(inode, name, name_len, value, size, 0, locked);
+       err = ntfs_set_ea(inode, name, name_len, value, size, flags);
+       if (err == -ENODATA && !size)
+               err = 0; /* Removing non existed xattr. */
        if (!err)
                set_cached_acl(inode, type, acl);
 
@@ -623,68 +616,7 @@ out:
 int ntfs_set_acl(struct user_namespace *mnt_userns, struct inode *inode,
                 struct posix_acl *acl, int type)
 {
-       return ntfs_set_acl_ex(mnt_userns, inode, acl, type, 0);
-}
-
-static int ntfs_xattr_get_acl(struct user_namespace *mnt_userns,
-                             struct inode *inode, int type, void *buffer,
-                             size_t size)
-{
-       struct posix_acl *acl;
-       int err;
-
-       if (!(inode->i_sb->s_flags & SB_POSIXACL)) {
-               ntfs_inode_warn(inode, "add mount option \"acl\" to use acl");
-               return -EOPNOTSUPP;
-       }
-
-       acl = ntfs_get_acl(inode, type, false);
-       if (IS_ERR(acl))
-               return PTR_ERR(acl);
-
-       if (!acl)
-               return -ENODATA;
-
-       err = posix_acl_to_xattr(mnt_userns, acl, buffer, size);
-       ntfs_posix_acl_release(acl);
-
-       return err;
-}
-
-static int ntfs_xattr_set_acl(struct user_namespace *mnt_userns,
-                             struct inode *inode, int type, const void *value,
-                             size_t size)
-{
-       struct posix_acl *acl;
-       int err;
-
-       if (!(inode->i_sb->s_flags & SB_POSIXACL)) {
-               ntfs_inode_warn(inode, "add mount option \"acl\" to use acl");
-               return -EOPNOTSUPP;
-       }
-
-       if (!inode_owner_or_capable(mnt_userns, inode))
-               return -EPERM;
-
-       if (!value) {
-               acl = NULL;
-       } else {
-               acl = posix_acl_from_xattr(mnt_userns, value, size);
-               if (IS_ERR(acl))
-                       return PTR_ERR(acl);
-
-               if (acl) {
-                       err = posix_acl_valid(mnt_userns, acl);
-                       if (err)
-                               goto release_and_out;
-               }
-       }
-
-       err = ntfs_set_acl(mnt_userns, inode, acl, type);
-
-release_and_out:
-       ntfs_posix_acl_release(acl);
-       return err;
+       return ntfs_set_acl_ex(mnt_userns, inode, acl, type);
 }
 
 /*
@@ -698,54 +630,27 @@ int ntfs_init_acl(struct user_namespace *mnt_userns, struct inode *inode,
        struct posix_acl *default_acl, *acl;
        int err;
 
-       /*
-        * TODO: Refactoring lock.
-        * ni_lock(dir) ... -> posix_acl_create(dir,...) -> ntfs_get_acl -> ni_lock(dir)
-        */
-       inode->i_default_acl = NULL;
-
-       default_acl = ntfs_get_acl_ex(mnt_userns, dir, ACL_TYPE_DEFAULT, 1);
-
-       if (!default_acl || default_acl == ERR_PTR(-EOPNOTSUPP)) {
-               inode->i_mode &= ~current_umask();
-               err = 0;
-               goto out;
-       }
-
-       if (IS_ERR(default_acl)) {
-               err = PTR_ERR(default_acl);
-               goto out;
-       }
-
-       acl = default_acl;
-       err = __posix_acl_create(&acl, GFP_NOFS, &inode->i_mode);
-       if (err < 0)
-               goto out1;
-       if (!err) {
-               posix_acl_release(acl);
-               acl = NULL;
-       }
+       err = posix_acl_create(dir, &inode->i_mode, &default_acl, &acl);
+       if (err)
+               return err;
 
-       if (!S_ISDIR(inode->i_mode)) {
+       if (default_acl) {
+               err = ntfs_set_acl_ex(mnt_userns, inode, default_acl,
+                                     ACL_TYPE_DEFAULT);
                posix_acl_release(default_acl);
-               default_acl = NULL;
+       } else {
+               inode->i_default_acl = NULL;
        }
 
-       if (default_acl)
-               err = ntfs_set_acl_ex(mnt_userns, inode, default_acl,
-                                     ACL_TYPE_DEFAULT, 1);
-
        if (!acl)
                inode->i_acl = NULL;
-       else if (!err)
-               err = ntfs_set_acl_ex(mnt_userns, inode, acl, ACL_TYPE_ACCESS,
-                                     1);
-
-       posix_acl_release(acl);
-out1:
-       posix_acl_release(default_acl);
+       else {
+               if (!err)
+                       err = ntfs_set_acl_ex(mnt_userns, inode, acl,
+                                             ACL_TYPE_ACCESS);
+               posix_acl_release(acl);
+       }
 
-out:
        return err;
 }
 #endif
@@ -772,7 +677,7 @@ int ntfs_acl_chmod(struct user_namespace *mnt_userns, struct inode *inode)
 int ntfs_permission(struct user_namespace *mnt_userns, struct inode *inode,
                    int mask)
 {
-       if (ntfs_sb(inode->i_sb)->options.no_acs_rules) {
+       if (ntfs_sb(inode->i_sb)->options->noacsrules) {
                /* "No access rules" mode - Allow all changes. */
                return 0;
        }
@@ -880,23 +785,6 @@ static int ntfs_getxattr(const struct xattr_handler *handler, struct dentry *de,
                goto out;
        }
 
-#ifdef CONFIG_NTFS3_FS_POSIX_ACL
-       if ((name_len == sizeof(XATTR_NAME_POSIX_ACL_ACCESS) - 1 &&
-            !memcmp(name, XATTR_NAME_POSIX_ACL_ACCESS,
-                    sizeof(XATTR_NAME_POSIX_ACL_ACCESS))) ||
-           (name_len == sizeof(XATTR_NAME_POSIX_ACL_DEFAULT) - 1 &&
-            !memcmp(name, XATTR_NAME_POSIX_ACL_DEFAULT,
-                    sizeof(XATTR_NAME_POSIX_ACL_DEFAULT)))) {
-               /* TODO: init_user_ns? */
-               err = ntfs_xattr_get_acl(
-                       &init_user_ns, inode,
-                       name_len == sizeof(XATTR_NAME_POSIX_ACL_ACCESS) - 1
-                               ? ACL_TYPE_ACCESS
-                               : ACL_TYPE_DEFAULT,
-                       buffer, size);
-               goto out;
-       }
-#endif
        /* Deal with NTFS extended attribute. */
        err = ntfs_get_ea(inode, name, name_len, buffer, size, NULL);
 
@@ -1009,24 +897,8 @@ set_new_fa:
                goto out;
        }
 
-#ifdef CONFIG_NTFS3_FS_POSIX_ACL
-       if ((name_len == sizeof(XATTR_NAME_POSIX_ACL_ACCESS) - 1 &&
-            !memcmp(name, XATTR_NAME_POSIX_ACL_ACCESS,
-                    sizeof(XATTR_NAME_POSIX_ACL_ACCESS))) ||
-           (name_len == sizeof(XATTR_NAME_POSIX_ACL_DEFAULT) - 1 &&
-            !memcmp(name, XATTR_NAME_POSIX_ACL_DEFAULT,
-                    sizeof(XATTR_NAME_POSIX_ACL_DEFAULT)))) {
-               err = ntfs_xattr_set_acl(
-                       mnt_userns, inode,
-                       name_len == sizeof(XATTR_NAME_POSIX_ACL_ACCESS) - 1
-                               ? ACL_TYPE_ACCESS
-                               : ACL_TYPE_DEFAULT,
-                       value, size);
-               goto out;
-       }
-#endif
        /* Deal with NTFS extended attribute. */
-       err = ntfs_set_ea(inode, name, name_len, value, size, flags, 0);
+       err = ntfs_set_ea(inode, name, name_len, value, size, flags);
 
 out:
        return err;
@@ -1042,28 +914,29 @@ int ntfs_save_wsl_perm(struct inode *inode)
        int err;
        __le32 value;
 
+       /* TODO: refactor this, so we don't lock 4 times in ntfs_set_ea */
        value = cpu_to_le32(i_uid_read(inode));
        err = ntfs_set_ea(inode, "$LXUID", sizeof("$LXUID") - 1, &value,
-                         sizeof(value), 0, 0);
+                         sizeof(value), 0);
        if (err)
                goto out;
 
        value = cpu_to_le32(i_gid_read(inode));
        err = ntfs_set_ea(inode, "$LXGID", sizeof("$LXGID") - 1, &value,
-                         sizeof(value), 0, 0);
+                         sizeof(value), 0);
        if (err)
                goto out;
 
        value = cpu_to_le32(inode->i_mode);
        err = ntfs_set_ea(inode, "$LXMOD", sizeof("$LXMOD") - 1, &value,
-                         sizeof(value), 0, 0);
+                         sizeof(value), 0);
        if (err)
                goto out;
 
        if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) {
                value = cpu_to_le32(inode->i_rdev);
                err = ntfs_set_ea(inode, "$LXDEV", sizeof("$LXDEV") - 1, &value,
-                                 sizeof(value), 0, 0);
+                                 sizeof(value), 0);
                if (err)
                        goto out;
        }
index 1fefb2b..93c7c26 100644 (file)
@@ -1219,9 +1219,13 @@ static int ovl_rename(struct user_namespace *mnt_userns, struct inode *olddir,
                                goto out_dput;
                }
        } else {
-               if (!d_is_negative(newdentry) &&
-                   (!new_opaque || !ovl_is_whiteout(newdentry)))
-                       goto out_dput;
+               if (!d_is_negative(newdentry)) {
+                       if (!new_opaque || !ovl_is_whiteout(newdentry))
+                               goto out_dput;
+               } else {
+                       if (flags & RENAME_EXCHANGE)
+                               goto out_dput;
+               }
        }
 
        if (olddentry == trap)
index d081faa..c88ac57 100644 (file)
@@ -296,6 +296,12 @@ static ssize_t ovl_read_iter(struct kiocb *iocb, struct iov_iter *iter)
        if (ret)
                return ret;
 
+       ret = -EINVAL;
+       if (iocb->ki_flags & IOCB_DIRECT &&
+           (!real.file->f_mapping->a_ops ||
+            !real.file->f_mapping->a_ops->direct_IO))
+               goto out_fdput;
+
        old_cred = ovl_override_creds(file_inode(file)->i_sb);
        if (is_sync_kiocb(iocb)) {
                ret = vfs_iter_read(real.file, iter, &iocb->ki_pos,
@@ -320,7 +326,7 @@ static ssize_t ovl_read_iter(struct kiocb *iocb, struct iov_iter *iter)
 out:
        revert_creds(old_cred);
        ovl_file_accessed(file);
-
+out_fdput:
        fdput(real);
 
        return ret;
@@ -349,6 +355,12 @@ static ssize_t ovl_write_iter(struct kiocb *iocb, struct iov_iter *iter)
        if (ret)
                goto out_unlock;
 
+       ret = -EINVAL;
+       if (iocb->ki_flags & IOCB_DIRECT &&
+           (!real.file->f_mapping->a_ops ||
+            !real.file->f_mapping->a_ops->direct_IO))
+               goto out_fdput;
+
        if (!ovl_should_sync(OVL_FS(inode->i_sb)))
                ifl &= ~(IOCB_DSYNC | IOCB_SYNC);
 
@@ -384,6 +396,7 @@ static ssize_t ovl_write_iter(struct kiocb *iocb, struct iov_iter *iter)
        }
 out:
        revert_creds(old_cred);
+out_fdput:
        fdput(real);
 
 out_unlock:
index cc7338f..7ce93aa 100644 (file)
@@ -957,7 +957,7 @@ static inline void __iomem *ioremap(phys_addr_t offset, size_t size)
 
 #ifndef iounmap
 #define iounmap iounmap
-static inline void iounmap(void __iomem *addr)
+static inline void iounmap(volatile void __iomem *addr)
 {
 }
 #endif
index 24b40e5..018e776 100644 (file)
@@ -613,7 +613,7 @@ void kunit_remove_resource(struct kunit *test, struct kunit_resource *res);
  * and is automatically cleaned up after the test case concludes. See &struct
  * kunit_resource for more information.
  */
-void *kunit_kmalloc_array(struct kunit *test, size_t n, size_t size, gfp_t flags);
+void *kunit_kmalloc_array(struct kunit *test, size_t n, size_t size, gfp_t gfp);
 
 /**
  * kunit_kmalloc() - Like kmalloc() except the allocation is *test managed*.
@@ -657,9 +657,9 @@ static inline void *kunit_kzalloc(struct kunit *test, size_t size, gfp_t gfp)
  *
  * See kcalloc() and kunit_kmalloc_array() for more information.
  */
-static inline void *kunit_kcalloc(struct kunit *test, size_t n, size_t size, gfp_t flags)
+static inline void *kunit_kcalloc(struct kunit *test, size_t n, size_t size, gfp_t gfp)
 {
-       return kunit_kmalloc_array(test, n, size, flags | __GFP_ZERO);
+       return kunit_kmalloc_array(test, n, size, gfp | __GFP_ZERO);
 }
 
 void kunit_cleanup(struct kunit *test);
index 7d1cabe..63ccb52 100644 (file)
@@ -321,10 +321,20 @@ asmlinkage unsigned long __arm_smccc_sve_check(unsigned long x0);
  * from register 0 to 3 on return from the SMC instruction.  An optional
  * quirk structure provides vendor specific behavior.
  */
+#ifdef CONFIG_HAVE_ARM_SMCCC
 asmlinkage void __arm_smccc_smc(unsigned long a0, unsigned long a1,
                        unsigned long a2, unsigned long a3, unsigned long a4,
                        unsigned long a5, unsigned long a6, unsigned long a7,
                        struct arm_smccc_res *res, struct arm_smccc_quirk *quirk);
+#else
+static inline void __arm_smccc_smc(unsigned long a0, unsigned long a1,
+                       unsigned long a2, unsigned long a3, unsigned long a4,
+                       unsigned long a5, unsigned long a6, unsigned long a7,
+                       struct arm_smccc_res *res, struct arm_smccc_quirk *quirk)
+{
+       *res = (struct arm_smccc_res){};
+}
+#endif
 
 /**
  * __arm_smccc_hvc() - make HVC calls
diff --git a/include/linux/dsa/mv88e6xxx.h b/include/linux/dsa/mv88e6xxx.h
new file mode 100644 (file)
index 0000000..8c3d45e
--- /dev/null
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: GPL-2.0
+ * Copyright 2021 NXP
+ */
+
+#ifndef _NET_DSA_TAG_MV88E6XXX_H
+#define _NET_DSA_TAG_MV88E6XXX_H
+
+#include <linux/if_vlan.h>
+
+#define MV88E6XXX_VID_STANDALONE       0
+#define MV88E6XXX_VID_BRIDGED          (VLAN_N_VID - 1)
+
+#endif
index 435777a..8ae999f 100644 (file)
@@ -5,7 +5,28 @@
 #ifndef _NET_DSA_TAG_OCELOT_H
 #define _NET_DSA_TAG_OCELOT_H
 
+#include <linux/kthread.h>
 #include <linux/packing.h>
+#include <linux/skbuff.h>
+
+struct ocelot_skb_cb {
+       struct sk_buff *clone;
+       unsigned int ptp_class; /* valid only for clones */
+       u8 ptp_cmd;
+       u8 ts_id;
+};
+
+#define OCELOT_SKB_CB(skb) \
+       ((struct ocelot_skb_cb *)((skb)->cb))
+
+#define IFH_TAG_TYPE_C                 0
+#define IFH_TAG_TYPE_S                 1
+
+#define IFH_REW_OP_NOOP                        0x0
+#define IFH_REW_OP_DSCP                        0x1
+#define IFH_REW_OP_ONE_STEP_PTP                0x2
+#define IFH_REW_OP_TWO_STEP_PTP                0x3
+#define IFH_REW_OP_ORIGIN_PTP          0x5
 
 #define OCELOT_TAG_LEN                 16
 #define OCELOT_SHORT_PREFIX_LEN                4
  *         +------+------+------+------+------+------+------+------+
  */
 
+struct felix_deferred_xmit_work {
+       struct dsa_port *dp;
+       struct sk_buff *skb;
+       struct kthread_work work;
+};
+
+struct felix_port {
+       void (*xmit_work_fn)(struct kthread_work *work);
+       struct kthread_worker *xmit_worker;
+};
+
 static inline void ocelot_xfh_get_rew_val(void *extraction, u64 *rew_val)
 {
        packing(extraction, rew_val, 116, 85, OCELOT_TAG_LEN, UNPACK, 0);
@@ -215,4 +247,21 @@ static inline void ocelot_ifh_set_vid(void *injection, u64 vid)
        packing(injection, &vid, 11, 0, OCELOT_TAG_LEN, PACK, 0);
 }
 
+/* Determine the PTP REW_OP to use for injecting the given skb */
+static inline u32 ocelot_ptp_rew_op(struct sk_buff *skb)
+{
+       struct sk_buff *clone = OCELOT_SKB_CB(skb)->clone;
+       u8 ptp_cmd = OCELOT_SKB_CB(skb)->ptp_cmd;
+       u32 rew_op = 0;
+
+       if (ptp_cmd == IFH_REW_OP_TWO_STEP_PTP && clone) {
+               rew_op = ptp_cmd;
+               rew_op |= OCELOT_SKB_CB(clone)->ts_id << 3;
+       } else if (ptp_cmd == IFH_REW_OP_ORIGIN_PTP) {
+               rew_op = ptp_cmd;
+       }
+
+       return rew_op;
+}
+
 #endif
index 1711062..9e07079 100644 (file)
@@ -48,6 +48,10 @@ struct sja1105_tagger_data {
        spinlock_t meta_lock;
        unsigned long state;
        u8 ts_id;
+       /* Used on SJA1110 where meta frames are generated only for
+        * 2-step TX timestamps
+        */
+       struct sk_buff_head skb_txtstamp_queue;
 };
 
 struct sja1105_skb_cb {
@@ -69,42 +73,24 @@ struct sja1105_port {
        bool hwts_tx_en;
 };
 
-enum sja1110_meta_tstamp {
-       SJA1110_META_TSTAMP_TX = 0,
-       SJA1110_META_TSTAMP_RX = 1,
-};
-
-#if IS_ENABLED(CONFIG_NET_DSA_SJA1105_PTP)
-
-void sja1110_process_meta_tstamp(struct dsa_switch *ds, int port, u8 ts_id,
-                                enum sja1110_meta_tstamp dir, u64 tstamp);
-
-#else
+/* Timestamps are in units of 8 ns clock ticks (equivalent to
+ * a fixed 125 MHz clock).
+ */
+#define SJA1105_TICK_NS                        8
 
-static inline void sja1110_process_meta_tstamp(struct dsa_switch *ds, int port,
-                                              u8 ts_id, enum sja1110_meta_tstamp dir,
-                                              u64 tstamp)
+static inline s64 ns_to_sja1105_ticks(s64 ns)
 {
+       return ns / SJA1105_TICK_NS;
 }
 
-#endif /* IS_ENABLED(CONFIG_NET_DSA_SJA1105_PTP) */
-
-#if IS_ENABLED(CONFIG_NET_DSA_SJA1105)
-
-extern const struct dsa_switch_ops sja1105_switch_ops;
-
-static inline bool dsa_port_is_sja1105(struct dsa_port *dp)
+static inline s64 sja1105_ticks_to_ns(s64 ticks)
 {
-       return dp->ds->ops == &sja1105_switch_ops;
+       return ticks * SJA1105_TICK_NS;
 }
 
-#else
-
 static inline bool dsa_port_is_sja1105(struct dsa_port *dp)
 {
-       return false;
+       return true;
 }
 
-#endif
-
 #endif /* _NET_DSA_SJA1105_H */
index 928c411..c58d504 100644 (file)
@@ -308,7 +308,7 @@ static inline void ether_addr_copy(u8 *dst, const u8 *src)
  */
 static inline void eth_hw_addr_set(struct net_device *dev, const u8 *addr)
 {
-       ether_addr_copy(dev->dev_addr, addr);
+       __dev_addr_set(dev, addr, ETH_ALEN);
 }
 
 /**
index f3638d0..993204a 100644 (file)
@@ -9475,16 +9475,22 @@ struct mlx5_ifc_pcmr_reg_bits {
        u8         reserved_at_0[0x8];
        u8         local_port[0x8];
        u8         reserved_at_10[0x10];
+
        u8         entropy_force_cap[0x1];
        u8         entropy_calc_cap[0x1];
        u8         entropy_gre_calc_cap[0x1];
-       u8         reserved_at_23[0x1b];
+       u8         reserved_at_23[0xf];
+       u8         rx_ts_over_crc_cap[0x1];
+       u8         reserved_at_33[0xb];
        u8         fcs_cap[0x1];
        u8         reserved_at_3f[0x1];
+
        u8         entropy_force[0x1];
        u8         entropy_calc[0x1];
        u8         entropy_gre_calc[0x1];
-       u8         reserved_at_43[0x1b];
+       u8         reserved_at_43[0xf];
+       u8         rx_ts_over_crc[0x1];
+       u8         reserved_at_53[0xb];
        u8         fcs_chk[0x1];
        u8         reserved_at_5f[0x1];
 };
index 43b5ce1..878e572 100644 (file)
@@ -48,6 +48,8 @@ struct omap_usb_config {
        u32 (*usb2_init)(unsigned nwires, unsigned alt_pingroup);
 
        int (*ocpi_enable)(void);
+
+       void (*lb_reset)(void);
 };
 
 #endif /* __LINUX_USB_OMAP1_H */
index c0475d1..81cad9e 100644 (file)
@@ -61,7 +61,6 @@ enum qcom_scm_ice_cipher {
 #define QCOM_SCM_PERM_RW (QCOM_SCM_PERM_READ | QCOM_SCM_PERM_WRITE)
 #define QCOM_SCM_PERM_RWX (QCOM_SCM_PERM_RW | QCOM_SCM_PERM_EXEC)
 
-#if IS_ENABLED(CONFIG_QCOM_SCM)
 extern bool qcom_scm_is_available(void);
 
 extern int qcom_scm_set_cold_boot_addr(void *entry, const cpumask_t *cpus);
@@ -115,74 +114,4 @@ extern int qcom_scm_lmh_dcvsh(u32 payload_fn, u32 payload_reg, u32 payload_val,
 extern int qcom_scm_lmh_profile_change(u32 profile_id);
 extern bool qcom_scm_lmh_dcvsh_available(void);
 
-#else
-
-#include <linux/errno.h>
-
-static inline bool qcom_scm_is_available(void) { return false; }
-
-static inline int qcom_scm_set_cold_boot_addr(void *entry,
-               const cpumask_t *cpus) { return -ENODEV; }
-static inline int qcom_scm_set_warm_boot_addr(void *entry,
-               const cpumask_t *cpus) { return -ENODEV; }
-static inline void qcom_scm_cpu_power_down(u32 flags) {}
-static inline u32 qcom_scm_set_remote_state(u32 state,u32 id)
-               { return -ENODEV; }
-
-static inline int qcom_scm_pas_init_image(u32 peripheral, const void *metadata,
-               size_t size) { return -ENODEV; }
-static inline int qcom_scm_pas_mem_setup(u32 peripheral, phys_addr_t addr,
-               phys_addr_t size) { return -ENODEV; }
-static inline int qcom_scm_pas_auth_and_reset(u32 peripheral)
-               { return -ENODEV; }
-static inline int qcom_scm_pas_shutdown(u32 peripheral) { return -ENODEV; }
-static inline bool qcom_scm_pas_supported(u32 peripheral) { return false; }
-
-static inline int qcom_scm_io_readl(phys_addr_t addr, unsigned int *val)
-               { return -ENODEV; }
-static inline int qcom_scm_io_writel(phys_addr_t addr, unsigned int val)
-               { return -ENODEV; }
-
-static inline bool qcom_scm_restore_sec_cfg_available(void) { return false; }
-static inline int qcom_scm_restore_sec_cfg(u32 device_id, u32 spare)
-               { return -ENODEV; }
-static inline int qcom_scm_iommu_secure_ptbl_size(u32 spare, size_t *size)
-               { return -ENODEV; }
-static inline int qcom_scm_iommu_secure_ptbl_init(u64 addr, u32 size, u32 spare)
-               { return -ENODEV; }
-extern inline int qcom_scm_mem_protect_video_var(u32 cp_start, u32 cp_size,
-                                                u32 cp_nonpixel_start,
-                                                u32 cp_nonpixel_size)
-               { return -ENODEV; }
-static inline int qcom_scm_assign_mem(phys_addr_t mem_addr, size_t mem_sz,
-               unsigned int *src, const struct qcom_scm_vmperm *newvm,
-               unsigned int dest_cnt) { return -ENODEV; }
-
-static inline bool qcom_scm_ocmem_lock_available(void) { return false; }
-static inline int qcom_scm_ocmem_lock(enum qcom_scm_ocmem_client id, u32 offset,
-               u32 size, u32 mode) { return -ENODEV; }
-static inline int qcom_scm_ocmem_unlock(enum qcom_scm_ocmem_client id,
-               u32 offset, u32 size) { return -ENODEV; }
-
-static inline bool qcom_scm_ice_available(void) { return false; }
-static inline int qcom_scm_ice_invalidate_key(u32 index) { return -ENODEV; }
-static inline int qcom_scm_ice_set_key(u32 index, const u8 *key, u32 key_size,
-                                      enum qcom_scm_ice_cipher cipher,
-                                      u32 data_unit_size) { return -ENODEV; }
-
-static inline bool qcom_scm_hdcp_available(void) { return false; }
-static inline int qcom_scm_hdcp_req(struct qcom_scm_hdcp_req *req, u32 req_cnt,
-               u32 *resp) { return -ENODEV; }
-
-static inline int qcom_scm_qsmmu500_wait_safe_toggle(bool en)
-               { return -ENODEV; }
-
-static inline int qcom_scm_lmh_dcvsh(u32 payload_fn, u32 payload_reg, u32 payload_val,
-                                    u64 limit_node, u32 node_id, u64 version)
-               { return -ENODEV; }
-
-static inline int qcom_scm_lmh_profile_change(u32 profile_id) { return -ENODEV; }
-
-static inline bool qcom_scm_lmh_dcvsh_available(void) { return -ENODEV; }
-#endif
 #endif
index 8371bca..6b0b686 100644 (file)
@@ -531,6 +531,9 @@ struct spi_controller {
        /* I/O mutex */
        struct mutex            io_mutex;
 
+       /* Used to avoid adding the same CS twice */
+       struct mutex            add_lock;
+
        /* lock and mutex for SPI bus locking */
        spinlock_t              bus_lock_spinlock;
        struct mutex            bus_lock_mutex;
index 2ebef6b..74d3c1e 100644 (file)
@@ -399,9 +399,8 @@ extern struct workqueue_struct *system_freezable_power_efficient_wq;
  * RETURNS:
  * Pointer to the allocated workqueue on success, %NULL on failure.
  */
-struct workqueue_struct *alloc_workqueue(const char *fmt,
-                                        unsigned int flags,
-                                        int max_active, ...);
+__printf(1, 4) struct workqueue_struct *
+alloc_workqueue(const char *fmt, unsigned int flags, int max_active, ...);
 
 /**
  * alloc_ordered_workqueue - allocate an ordered workqueue
index 0fd8a41..ceadf8b 100644 (file)
@@ -17,7 +17,6 @@ struct inet_frags_ctl;
 struct nft_ct_frag6_pernet {
        struct ctl_table_header *nf_frag_frags_hdr;
        struct fqdir    *fqdir;
-       unsigned int users;
 };
 
 #endif /* _NF_DEFRAG_IPV6_H */
index 148f5d8..a16171c 100644 (file)
@@ -1202,7 +1202,7 @@ struct nft_object *nft_obj_lookup(const struct net *net,
 
 void nft_obj_notify(struct net *net, const struct nft_table *table,
                    struct nft_object *obj, u32 portid, u32 seq,
-                   int event, int family, int report, gfp_t gfp);
+                   int event, u16 flags, int family, int report, gfp_t gfp);
 
 /**
  *     struct nft_object_type - stateful object type
index 986a2a9..b593f95 100644 (file)
@@ -27,5 +27,11 @@ struct netns_nf {
 #if IS_ENABLED(CONFIG_DECNET)
        struct nf_hook_entries __rcu *hooks_decnet[NF_DN_NUMHOOKS];
 #endif
+#if IS_ENABLED(CONFIG_NF_DEFRAG_IPV4)
+       unsigned int defrag_ipv4_users;
+#endif
+#if IS_ENABLED(CONFIG_NF_DEFRAG_IPV6)
+       unsigned int defrag_ipv6_users;
+#endif
 };
 #endif
index ae929e2..ea6fbc8 100644 (file)
@@ -307,6 +307,7 @@ struct bpf_local_storage;
   *    @sk_priority: %SO_PRIORITY setting
   *    @sk_type: socket type (%SOCK_STREAM, etc)
   *    @sk_protocol: which protocol this socket belongs in this network family
+  *    @sk_peer_lock: lock protecting @sk_peer_pid and @sk_peer_cred
   *    @sk_peer_pid: &struct pid for this socket's peer
   *    @sk_peer_cred: %SO_PEERCRED setting
   *    @sk_rcvlowat: %SO_RCVLOWAT setting
index 06706a9..d7055b4 100644 (file)
 /* Source PGIDs, one per physical port */
 #define PGID_SRC                       80
 
-#define IFH_TAG_TYPE_C                 0
-#define IFH_TAG_TYPE_S                 1
-
-#define IFH_REW_OP_NOOP                        0x0
-#define IFH_REW_OP_DSCP                        0x1
-#define IFH_REW_OP_ONE_STEP_PTP                0x2
-#define IFH_REW_OP_TWO_STEP_PTP                0x3
-#define IFH_REW_OP_ORIGIN_PTP          0x5
-
 #define OCELOT_NUM_TC                  8
 
 #define OCELOT_SPEED_2500              0
@@ -603,10 +594,10 @@ struct ocelot_port {
        /* The VLAN ID that will be transmitted as untagged, on egress */
        struct ocelot_vlan              native_vlan;
 
+       unsigned int                    ptp_skbs_in_flight;
        u8                              ptp_cmd;
        struct sk_buff_head             tx_skbs;
        u8                              ts_id;
-       spinlock_t                      ts_id_lock;
 
        phy_interface_t                 phy_mode;
 
@@ -680,6 +671,9 @@ struct ocelot {
        struct ptp_clock                *ptp_clock;
        struct ptp_clock_info           ptp_info;
        struct hwtstamp_config          hwtstamp_config;
+       unsigned int                    ptp_skbs_in_flight;
+       /* Protects the 2-step TX timestamp ID logic */
+       spinlock_t                      ts_id_lock;
        /* Protects the PTP interface state */
        struct mutex                    ptp_lock;
        /* Protects the PTP clock */
@@ -692,15 +686,6 @@ struct ocelot_policer {
        u32 burst; /* bytes */
 };
 
-struct ocelot_skb_cb {
-       struct sk_buff *clone;
-       u8 ptp_cmd;
-       u8 ts_id;
-};
-
-#define OCELOT_SKB_CB(skb) \
-       ((struct ocelot_skb_cb *)((skb)->cb))
-
 #define ocelot_read_ix(ocelot, reg, gi, ri) __ocelot_read_ix(ocelot, reg, reg##_GSZ * (gi) + reg##_RSZ * (ri))
 #define ocelot_read_gix(ocelot, reg, gi) __ocelot_read_ix(ocelot, reg, reg##_GSZ * (gi))
 #define ocelot_read_rix(ocelot, reg, ri) __ocelot_read_ix(ocelot, reg, reg##_RSZ * (ri))
@@ -752,8 +737,6 @@ u32 __ocelot_target_read_ix(struct ocelot *ocelot, enum ocelot_target target,
 void __ocelot_target_write_ix(struct ocelot *ocelot, enum ocelot_target target,
                              u32 val, u32 reg, u32 offset);
 
-#if IS_ENABLED(CONFIG_MSCC_OCELOT_SWITCH_LIB)
-
 /* Packet I/O */
 bool ocelot_can_inject(struct ocelot *ocelot, int grp);
 void ocelot_port_inject_frame(struct ocelot *ocelot, int port, int grp,
@@ -761,36 +744,6 @@ void ocelot_port_inject_frame(struct ocelot *ocelot, int port, int grp,
 int ocelot_xtr_poll_frame(struct ocelot *ocelot, int grp, struct sk_buff **skb);
 void ocelot_drain_cpu_queue(struct ocelot *ocelot, int grp);
 
-u32 ocelot_ptp_rew_op(struct sk_buff *skb);
-#else
-
-static inline bool ocelot_can_inject(struct ocelot *ocelot, int grp)
-{
-       return false;
-}
-
-static inline void ocelot_port_inject_frame(struct ocelot *ocelot, int port,
-                                           int grp, u32 rew_op,
-                                           struct sk_buff *skb)
-{
-}
-
-static inline int ocelot_xtr_poll_frame(struct ocelot *ocelot, int grp,
-                                       struct sk_buff **skb)
-{
-       return -EIO;
-}
-
-static inline void ocelot_drain_cpu_queue(struct ocelot *ocelot, int grp)
-{
-}
-
-static inline u32 ocelot_ptp_rew_op(struct sk_buff *skb)
-{
-       return 0;
-}
-#endif
-
 /* Hardware initialization */
 int ocelot_regfields_init(struct ocelot *ocelot,
                          const struct reg_field *const regfields);
index ded497d..f085884 100644 (file)
@@ -13,6 +13,9 @@
 #include <linux/ptp_clock_kernel.h>
 #include <soc/mscc/ocelot.h>
 
+#define OCELOT_MAX_PTP_ID              63
+#define OCELOT_PTP_FIFO_SIZE           128
+
 #define PTP_PIN_CFG_RSZ                        0x20
 #define PTP_PIN_TOD_SEC_MSB_RSZ                PTP_PIN_CFG_RSZ
 #define PTP_PIN_TOD_SEC_LSB_RSZ                PTP_PIN_CFG_RSZ
index 25fd525..4869ebb 100644 (file)
@@ -694,7 +694,7 @@ int ocelot_vcap_filter_add(struct ocelot *ocelot,
 int ocelot_vcap_filter_del(struct ocelot *ocelot,
                           struct ocelot_vcap_filter *rule);
 struct ocelot_vcap_filter *
-ocelot_vcap_block_find_filter_by_id(struct ocelot_vcap_block *block, int id,
-                                   bool tc_offload);
+ocelot_vcap_block_find_filter_by_id(struct ocelot_vcap_block *block,
+                                   unsigned long cookie, bool tc_offload);
 
 #endif /* _OCELOT_VCAP_H_ */
index 01570db..0e45963 100644 (file)
@@ -224,6 +224,7 @@ struct hda_codec {
 #endif
 
        /* misc flags */
+       unsigned int configured:1; /* codec was configured */
        unsigned int in_freeing:1; /* being released */
        unsigned int registered:1; /* codec was registered */
        unsigned int display_power_control:1; /* needs display power */
index 695bfdb..920b6a3 100644 (file)
@@ -178,7 +178,7 @@ TRACE_EVENT(cachefiles_unlink,
                             ),
 
            TP_fast_assign(
-                   __entry->obj        = obj->fscache.debug_id;
+                   __entry->obj        = obj ? obj->fscache.debug_id : UINT_MAX;
                    __entry->de         = de;
                    __entry->why        = why;
                           ),
@@ -205,7 +205,7 @@ TRACE_EVENT(cachefiles_rename,
                             ),
 
            TP_fast_assign(
-                   __entry->obj        = obj->fscache.debug_id;
+                   __entry->obj        = obj ? obj->fscache.debug_id : UINT_MAX;
                    __entry->de         = de;
                    __entry->to         = to;
                    __entry->why        = why;
index 6135d92..daf82a2 100644 (file)
@@ -26,7 +26,7 @@
 #ifndef _UAPI_HYPERV_H
 #define _UAPI_HYPERV_H
 
-#include <linux/uuid.h>
+#include <linux/types.h>
 
 /*
  * Framework version for util services.
index b96c1ea..eda0426 100644 (file)
@@ -213,13 +213,13 @@ enum {
        XFRM_MSG_GETSPDINFO,
 #define XFRM_MSG_GETSPDINFO XFRM_MSG_GETSPDINFO
 
+       XFRM_MSG_MAPPING,
+#define XFRM_MSG_MAPPING XFRM_MSG_MAPPING
+
        XFRM_MSG_SETDEFAULT,
 #define XFRM_MSG_SETDEFAULT XFRM_MSG_SETDEFAULT
        XFRM_MSG_GETDEFAULT,
 #define XFRM_MSG_GETDEFAULT XFRM_MSG_GETDEFAULT
-
-       XFRM_MSG_MAPPING,
-#define XFRM_MSG_MAPPING XFRM_MSG_MAPPING
        __XFRM_MSG_MAX
 };
 #define XFRM_MSG_MAX (__XFRM_MSG_MAX - 1)
@@ -514,9 +514,12 @@ struct xfrm_user_offload {
 #define XFRM_OFFLOAD_INBOUND   2
 
 struct xfrm_userpolicy_default {
-#define XFRM_USERPOLICY_DIRMASK_MAX    (sizeof(__u8) * 8)
-       __u8                            dirmask;
-       __u8                            action;
+#define XFRM_USERPOLICY_UNSPEC 0
+#define XFRM_USERPOLICY_BLOCK  1
+#define XFRM_USERPOLICY_ACCEPT 2
+       __u8                            in;
+       __u8                            fwd;
+       __u8                            out;
 };
 
 #ifndef __KERNEL__
index 7cc2a0f..d13bb8c 100644 (file)
@@ -917,7 +917,6 @@ struct hl_wait_cs_in {
 #define HL_WAIT_CS_STATUS_BUSY         1
 #define HL_WAIT_CS_STATUS_TIMEDOUT     2
 #define HL_WAIT_CS_STATUS_ABORTED      3
-#define HL_WAIT_CS_STATUS_INTERRUPTED  4
 
 #define HL_WAIT_CS_STATUS_FLAG_GONE            0x1
 #define HL_WAIT_CS_STATUS_FLAG_TIMESTAMP_VLD   0x2
@@ -1286,7 +1285,8 @@ struct hl_debug_args {
  * EIO       - The CS was aborted (usually because the device was reset)
  * ENODEV    - The device wants to do hard-reset (so user need to close FD)
  *
- * The driver also returns a custom define inside the IOCTL which can be:
+ * The driver also returns a custom define in case the IOCTL call returned 0.
+ * The define can be one of the following:
  *
  * HL_WAIT_CS_STATUS_COMPLETED   - The CS has been completed successfully (0)
  * HL_WAIT_CS_STATUS_BUSY        - The CS is still executing (0)
@@ -1294,8 +1294,6 @@ struct hl_debug_args {
  *                                 (ETIMEDOUT)
  * HL_WAIT_CS_STATUS_ABORTED     - The CS was aborted, usually because the
  *                                 device was reset (EIO)
- * HL_WAIT_CS_STATUS_INTERRUPTED - Waiting for the CS was interrupted (EINTR)
- *
  */
 
 #define HL_IOCTL_WAIT_CS                       \
index db28e79..a3584a3 100644 (file)
@@ -52,12 +52,12 @@ void xen_destroy_contiguous_region(phys_addr_t pstart, unsigned int order);
 #if defined(CONFIG_XEN_PV)
 int xen_remap_pfn(struct vm_area_struct *vma, unsigned long addr,
                  xen_pfn_t *pfn, int nr, int *err_ptr, pgprot_t prot,
-                 unsigned int domid, bool no_translate, struct page **pages);
+                 unsigned int domid, bool no_translate);
 #else
 static inline int xen_remap_pfn(struct vm_area_struct *vma, unsigned long addr,
                                xen_pfn_t *pfn, int nr, int *err_ptr,
                                pgprot_t prot,  unsigned int domid,
-                               bool no_translate, struct page **pages)
+                               bool no_translate)
 {
        BUG();
        return 0;
@@ -134,7 +134,7 @@ static inline int xen_remap_domain_gfn_array(struct vm_area_struct *vma,
         */
        BUG_ON(err_ptr == NULL);
        return xen_remap_pfn(vma, addr, gfn, nr, err_ptr, prot, domid,
-                            false, pages);
+                            false);
 }
 
 /*
@@ -146,7 +146,6 @@ static inline int xen_remap_domain_gfn_array(struct vm_area_struct *vma,
  * @err_ptr: Returns per-MFN error status.
  * @prot:    page protection mask
  * @domid:   Domain owning the pages
- * @pages:   Array of pages if this domain has an auto-translated physmap
  *
  * @mfn and @err_ptr may point to the same buffer, the MFNs will be
  * overwritten by the error codes after they are mapped.
@@ -157,14 +156,13 @@ static inline int xen_remap_domain_gfn_array(struct vm_area_struct *vma,
 static inline int xen_remap_domain_mfn_array(struct vm_area_struct *vma,
                                             unsigned long addr, xen_pfn_t *mfn,
                                             int nr, int *err_ptr,
-                                            pgprot_t prot, unsigned int domid,
-                                            struct page **pages)
+                                            pgprot_t prot, unsigned int domid)
 {
        if (xen_feature(XENFEAT_auto_translated_physmap))
                return -EOPNOTSUPP;
 
        return xen_remap_pfn(vma, addr, mfn, nr, err_ptr, prot, domid,
-                            true, pages);
+                            true);
 }
 
 /* xen_remap_domain_gfn_range() - map a range of foreign frames
@@ -188,8 +186,7 @@ static inline int xen_remap_domain_gfn_range(struct vm_area_struct *vma,
        if (xen_feature(XENFEAT_auto_translated_physmap))
                return -EOPNOTSUPP;
 
-       return xen_remap_pfn(vma, addr, &gfn, nr, NULL, prot, domid, false,
-                            pages);
+       return xen_remap_pfn(vma, addr, &gfn, nr, NULL, prot, domid, false);
 }
 
 int xen_unmap_domain_gfn_range(struct vm_area_struct *vma,
index 81a79a7..3c4054a 100644 (file)
@@ -382,6 +382,7 @@ static char * __init xbc_make_cmdline(const char *key)
        ret = xbc_snprint_cmdline(new_cmdline, len + 1, root);
        if (ret < 0 || ret > len) {
                pr_err("Failed to print extra kernel cmdline.\n");
+               memblock_free_ptr(new_cmdline, len + 1);
                return NULL;
        }
 
index 09a3fd9..6e75bbe 100644 (file)
@@ -63,7 +63,8 @@ static inline int stack_map_data_size(struct bpf_map *map)
 
 static int prealloc_elems_and_freelist(struct bpf_stack_map *smap)
 {
-       u32 elem_size = sizeof(struct stack_map_bucket) + smap->map.value_size;
+       u64 elem_size = sizeof(struct stack_map_bucket) +
+                       (u64)smap->map.value_size;
        int err;
 
        smap->elems = bpf_map_area_alloc(elem_size * smap->map.max_entries,
index df1ccf4..2a9695c 100644 (file)
@@ -311,17 +311,19 @@ static struct cpuset top_cpuset = {
                if (is_cpuset_online(((des_cs) = css_cs((pos_css)))))
 
 /*
- * There are two global locks guarding cpuset structures - cpuset_mutex and
+ * There are two global locks guarding cpuset structures - cpuset_rwsem and
  * callback_lock. We also require taking task_lock() when dereferencing a
  * task's cpuset pointer. See "The task_lock() exception", at the end of this
- * comment.
+ * comment.  The cpuset code uses only cpuset_rwsem write lock.  Other
+ * kernel subsystems can use cpuset_read_lock()/cpuset_read_unlock() to
+ * prevent change to cpuset structures.
  *
  * A task must hold both locks to modify cpusets.  If a task holds
- * cpuset_mutex, then it blocks others wanting that mutex, ensuring that it
+ * cpuset_rwsem, it blocks others wanting that rwsem, ensuring that it
  * is the only task able to also acquire callback_lock and be able to
  * modify cpusets.  It can perform various checks on the cpuset structure
  * first, knowing nothing will change.  It can also allocate memory while
- * just holding cpuset_mutex.  While it is performing these checks, various
+ * just holding cpuset_rwsem.  While it is performing these checks, various
  * callback routines can briefly acquire callback_lock to query cpusets.
  * Once it is ready to make the changes, it takes callback_lock, blocking
  * everyone else.
@@ -393,7 +395,7 @@ static inline bool is_in_v2_mode(void)
  * One way or another, we guarantee to return some non-empty subset
  * of cpu_online_mask.
  *
- * Call with callback_lock or cpuset_mutex held.
+ * Call with callback_lock or cpuset_rwsem held.
  */
 static void guarantee_online_cpus(struct task_struct *tsk,
                                  struct cpumask *pmask)
@@ -435,7 +437,7 @@ out_unlock:
  * One way or another, we guarantee to return some non-empty subset
  * of node_states[N_MEMORY].
  *
- * Call with callback_lock or cpuset_mutex held.
+ * Call with callback_lock or cpuset_rwsem held.
  */
 static void guarantee_online_mems(struct cpuset *cs, nodemask_t *pmask)
 {
@@ -447,7 +449,7 @@ static void guarantee_online_mems(struct cpuset *cs, nodemask_t *pmask)
 /*
  * update task's spread flag if cpuset's page/slab spread flag is set
  *
- * Call with callback_lock or cpuset_mutex held.
+ * Call with callback_lock or cpuset_rwsem held.
  */
 static void cpuset_update_task_spread_flag(struct cpuset *cs,
                                        struct task_struct *tsk)
@@ -468,7 +470,7 @@ static void cpuset_update_task_spread_flag(struct cpuset *cs,
  *
  * One cpuset is a subset of another if all its allowed CPUs and
  * Memory Nodes are a subset of the other, and its exclusive flags
- * are only set if the other's are set.  Call holding cpuset_mutex.
+ * are only set if the other's are set.  Call holding cpuset_rwsem.
  */
 
 static int is_cpuset_subset(const struct cpuset *p, const struct cpuset *q)
@@ -577,7 +579,7 @@ static inline void free_cpuset(struct cpuset *cs)
  * If we replaced the flag and mask values of the current cpuset
  * (cur) with those values in the trial cpuset (trial), would
  * our various subset and exclusive rules still be valid?  Presumes
- * cpuset_mutex held.
+ * cpuset_rwsem held.
  *
  * 'cur' is the address of an actual, in-use cpuset.  Operations
  * such as list traversal that depend on the actual address of the
@@ -700,7 +702,7 @@ static void update_domain_attr_tree(struct sched_domain_attr *dattr,
        rcu_read_unlock();
 }
 
-/* Must be called with cpuset_mutex held.  */
+/* Must be called with cpuset_rwsem held.  */
 static inline int nr_cpusets(void)
 {
        /* jump label reference count + the top-level cpuset */
@@ -726,7 +728,7 @@ static inline int nr_cpusets(void)
  * domains when operating in the severe memory shortage situations
  * that could cause allocation failures below.
  *
- * Must be called with cpuset_mutex held.
+ * Must be called with cpuset_rwsem held.
  *
  * The three key local variables below are:
  *    cp - cpuset pointer, used (together with pos_css) to perform a
@@ -1005,7 +1007,7 @@ partition_and_rebuild_sched_domains(int ndoms_new, cpumask_var_t doms_new[],
  * 'cpus' is removed, then call this routine to rebuild the
  * scheduler's dynamic sched domains.
  *
- * Call with cpuset_mutex held.  Takes cpus_read_lock().
+ * Call with cpuset_rwsem held.  Takes cpus_read_lock().
  */
 static void rebuild_sched_domains_locked(void)
 {
@@ -1078,7 +1080,7 @@ void rebuild_sched_domains(void)
  * @cs: the cpuset in which each task's cpus_allowed mask needs to be changed
  *
  * Iterate through each task of @cs updating its cpus_allowed to the
- * effective cpuset's.  As this function is called with cpuset_mutex held,
+ * effective cpuset's.  As this function is called with cpuset_rwsem held,
  * cpuset membership stays stable.
  */
 static void update_tasks_cpumask(struct cpuset *cs)
@@ -1347,7 +1349,7 @@ static int update_parent_subparts_cpumask(struct cpuset *cpuset, int cmd,
  *
  * On legacy hierarchy, effective_cpus will be the same with cpu_allowed.
  *
- * Called with cpuset_mutex held
+ * Called with cpuset_rwsem held
  */
 static void update_cpumasks_hier(struct cpuset *cs, struct tmpmasks *tmp)
 {
@@ -1704,12 +1706,12 @@ static void *cpuset_being_rebound;
  * @cs: the cpuset in which each task's mems_allowed mask needs to be changed
  *
  * Iterate through each task of @cs updating its mems_allowed to the
- * effective cpuset's.  As this function is called with cpuset_mutex held,
+ * effective cpuset's.  As this function is called with cpuset_rwsem held,
  * cpuset membership stays stable.
  */
 static void update_tasks_nodemask(struct cpuset *cs)
 {
-       static nodemask_t newmems;      /* protected by cpuset_mutex */
+       static nodemask_t newmems;      /* protected by cpuset_rwsem */
        struct css_task_iter it;
        struct task_struct *task;
 
@@ -1722,7 +1724,7 @@ static void update_tasks_nodemask(struct cpuset *cs)
         * take while holding tasklist_lock.  Forks can happen - the
         * mpol_dup() cpuset_being_rebound check will catch such forks,
         * and rebind their vma mempolicies too.  Because we still hold
-        * the global cpuset_mutex, we know that no other rebind effort
+        * the global cpuset_rwsem, we know that no other rebind effort
         * will be contending for the global variable cpuset_being_rebound.
         * It's ok if we rebind the same mm twice; mpol_rebind_mm()
         * is idempotent.  Also migrate pages in each mm to new nodes.
@@ -1768,7 +1770,7 @@ static void update_tasks_nodemask(struct cpuset *cs)
  *
  * On legacy hierarchy, effective_mems will be the same with mems_allowed.
  *
- * Called with cpuset_mutex held
+ * Called with cpuset_rwsem held
  */
 static void update_nodemasks_hier(struct cpuset *cs, nodemask_t *new_mems)
 {
@@ -1821,7 +1823,7 @@ static void update_nodemasks_hier(struct cpuset *cs, nodemask_t *new_mems)
  * mempolicies and if the cpuset is marked 'memory_migrate',
  * migrate the tasks pages to the new memory.
  *
- * Call with cpuset_mutex held. May take callback_lock during call.
+ * Call with cpuset_rwsem held. May take callback_lock during call.
  * Will take tasklist_lock, scan tasklist for tasks in cpuset cs,
  * lock each such tasks mm->mmap_lock, scan its vma's and rebind
  * their mempolicies to the cpusets new mems_allowed.
@@ -1911,7 +1913,7 @@ static int update_relax_domain_level(struct cpuset *cs, s64 val)
  * @cs: the cpuset in which each task's spread flags needs to be changed
  *
  * Iterate through each task of @cs updating its spread flags.  As this
- * function is called with cpuset_mutex held, cpuset membership stays
+ * function is called with cpuset_rwsem held, cpuset membership stays
  * stable.
  */
 static void update_tasks_flags(struct cpuset *cs)
@@ -1931,7 +1933,7 @@ static void update_tasks_flags(struct cpuset *cs)
  * cs:         the cpuset to update
  * turning_on:         whether the flag is being set or cleared
  *
- * Call with cpuset_mutex held.
+ * Call with cpuset_rwsem held.
  */
 
 static int update_flag(cpuset_flagbits_t bit, struct cpuset *cs,
@@ -1980,7 +1982,7 @@ out:
  * cs: the cpuset to update
  * new_prs: new partition root state
  *
- * Call with cpuset_mutex held.
+ * Call with cpuset_rwsem held.
  */
 static int update_prstate(struct cpuset *cs, int new_prs)
 {
@@ -2167,7 +2169,7 @@ static int fmeter_getrate(struct fmeter *fmp)
 
 static struct cpuset *cpuset_attach_old_cs;
 
-/* Called by cgroups to determine if a cpuset is usable; cpuset_mutex held */
+/* Called by cgroups to determine if a cpuset is usable; cpuset_rwsem held */
 static int cpuset_can_attach(struct cgroup_taskset *tset)
 {
        struct cgroup_subsys_state *css;
@@ -2219,7 +2221,7 @@ static void cpuset_cancel_attach(struct cgroup_taskset *tset)
 }
 
 /*
- * Protected by cpuset_mutex.  cpus_attach is used only by cpuset_attach()
+ * Protected by cpuset_rwsem.  cpus_attach is used only by cpuset_attach()
  * but we can't allocate it dynamically there.  Define it global and
  * allocate from cpuset_init().
  */
@@ -2227,7 +2229,7 @@ static cpumask_var_t cpus_attach;
 
 static void cpuset_attach(struct cgroup_taskset *tset)
 {
-       /* static buf protected by cpuset_mutex */
+       /* static buf protected by cpuset_rwsem */
        static nodemask_t cpuset_attach_nodemask_to;
        struct task_struct *task;
        struct task_struct *leader;
@@ -2417,7 +2419,7 @@ static ssize_t cpuset_write_resmask(struct kernfs_open_file *of,
         * operation like this one can lead to a deadlock through kernfs
         * active_ref protection.  Let's break the protection.  Losing the
         * protection is okay as we check whether @cs is online after
-        * grabbing cpuset_mutex anyway.  This only happens on the legacy
+        * grabbing cpuset_rwsem anyway.  This only happens on the legacy
         * hierarchies.
         */
        css_get(&cs->css);
@@ -3672,7 +3674,7 @@ void __cpuset_memory_pressure_bump(void)
  *  - Used for /proc/<pid>/cpuset.
  *  - No need to task_lock(tsk) on this tsk->cpuset reference, as it
  *    doesn't really matter if tsk->cpuset changes after we read it,
- *    and we take cpuset_mutex, keeping cpuset_attach() from changing it
+ *    and we take cpuset_rwsem, keeping cpuset_attach() from changing it
  *    anyway.
  */
 int proc_cpuset_show(struct seq_file *m, struct pid_namespace *ns,
index 40ec9a0..5c26a76 100644 (file)
@@ -4489,8 +4489,10 @@ static void cfi_init(struct module *mod)
        /* Fix init/exit functions to point to the CFI jump table */
        if (init)
                mod->init = *init;
+#ifdef CONFIG_MODULE_UNLOAD
        if (exit)
                mod->exit = *exit;
+#endif
 
        cfi_module_add(mod, module_addr_min);
 #endif
index 7896d30..bc677cd 100644 (file)
@@ -1744,16 +1744,15 @@ void latency_fsnotify(struct trace_array *tr)
        irq_work_queue(&tr->fsnotify_irqwork);
 }
 
-/*
- * (defined(CONFIG_TRACER_MAX_TRACE) || defined(CONFIG_HWLAT_TRACER)) && \
- *  defined(CONFIG_FSNOTIFY)
- */
-#else
+#elif defined(CONFIG_TRACER_MAX_TRACE) || defined(CONFIG_HWLAT_TRACER) \
+       || defined(CONFIG_OSNOISE_TRACER)
 
 #define trace_create_maxlat_file(tr, d_tracer)                         \
        trace_create_file("tracing_max_latency", 0644, d_tracer,        \
                          &tr->max_latency, &tracing_max_lat_fops)
 
+#else
+#define trace_create_maxlat_file(tr, d_tracer)  do { } while (0)
 #endif
 
 #ifdef CONFIG_TRACER_MAX_TRACE
@@ -9473,9 +9472,7 @@ init_tracer_tracefs(struct trace_array *tr, struct dentry *d_tracer)
 
        create_trace_options_dir(tr);
 
-#if defined(CONFIG_TRACER_MAX_TRACE) || defined(CONFIG_HWLAT_TRACER)
        trace_create_maxlat_file(tr, d_tracer);
-#endif
 
        if (ftrace_create_function_files(tr, d_tracer))
                MEM_FAIL(1, "Could not allocate function filter files");
index 3044b76..c4a15ae 100644 (file)
@@ -119,10 +119,58 @@ static bool eprobe_dyn_event_match(const char *system, const char *event,
                        int argc, const char **argv, struct dyn_event *ev)
 {
        struct trace_eprobe *ep = to_trace_eprobe(ev);
+       const char *slash;
 
-       return strcmp(trace_probe_name(&ep->tp), event) == 0 &&
-           (!system || strcmp(trace_probe_group_name(&ep->tp), system) == 0) &&
-           trace_probe_match_command_args(&ep->tp, argc, argv);
+       /*
+        * We match the following:
+        *  event only                  - match all eprobes with event name
+        *  system and event only       - match all system/event probes
+        *
+        * The below has the above satisfied with more arguments:
+        *
+        *  attached system/event       - If the arg has the system and event
+        *                                the probe is attached to, match
+        *                                probes with the attachment.
+        *
+        *  If any more args are given, then it requires a full match.
+        */
+
+       /*
+        * If system exists, but this probe is not part of that system
+        * do not match.
+        */
+       if (system && strcmp(trace_probe_group_name(&ep->tp), system) != 0)
+               return false;
+
+       /* Must match the event name */
+       if (strcmp(trace_probe_name(&ep->tp), event) != 0)
+               return false;
+
+       /* No arguments match all */
+       if (argc < 1)
+               return true;
+
+       /* First argument is the system/event the probe is attached to */
+
+       slash = strchr(argv[0], '/');
+       if (!slash)
+               slash = strchr(argv[0], '.');
+       if (!slash)
+               return false;
+
+       if (strncmp(ep->event_system, argv[0], slash - argv[0]))
+               return false;
+       if (strcmp(ep->event_name, slash + 1))
+               return false;
+
+       argc--;
+       argv++;
+
+       /* If there are no other args, then match */
+       if (argc < 1)
+               return true;
+
+       return trace_probe_match_command_args(&ep->tp, argc, argv);
 }
 
 static struct dyn_event_operations eprobe_dyn_event_ops = {
@@ -632,6 +680,13 @@ static int disable_eprobe(struct trace_eprobe *ep,
 
        trace_event_trigger_enable_disable(file, 0);
        update_cond_flag(file);
+
+       /* Make sure nothing is using the edata or trigger */
+       tracepoint_synchronize_unregister();
+
+       kfree(edata);
+       kfree(trigger);
+
        return 0;
 }
 
index a6061a6..f01e442 100644 (file)
@@ -2506,7 +2506,7 @@ find_synthetic_field_var(struct hist_trigger_data *target_hist_data,
  * events.  However, for convenience, users are allowed to directly
  * specify an event field in an action, which will be automatically
  * converted into a variable on their behalf.
-
+ *
  * If a user specifies a field on an event that isn't the event the
  * histogram currently being defined (the target event histogram), the
  * only way that can be accomplished is if a new hist trigger is
index 33a6b4a..1b3eb1e 100644 (file)
@@ -4830,8 +4830,16 @@ void show_workqueue_state(void)
 
                for_each_pwq(pwq, wq) {
                        raw_spin_lock_irqsave(&pwq->pool->lock, flags);
-                       if (pwq->nr_active || !list_empty(&pwq->inactive_works))
+                       if (pwq->nr_active || !list_empty(&pwq->inactive_works)) {
+                               /*
+                                * Defer printing to avoid deadlocks in console
+                                * drivers that queue work while holding locks
+                                * also taken in their write paths.
+                                */
+                               printk_deferred_enter();
                                show_pwq(pwq);
+                               printk_deferred_exit();
+                       }
                        raw_spin_unlock_irqrestore(&pwq->pool->lock, flags);
                        /*
                         * We could be printing a lot from atomic context, e.g.
@@ -4849,7 +4857,12 @@ void show_workqueue_state(void)
                raw_spin_lock_irqsave(&pool->lock, flags);
                if (pool->nr_workers == pool->nr_idle)
                        goto next_pool;
-
+               /*
+                * Defer printing to avoid deadlocks in console drivers that
+                * queue work while holding locks also taken in their write
+                * paths.
+                */
+               printk_deferred_enter();
                pr_info("pool %d:", pool->id);
                pr_cont_pool_info(pool);
                pr_cont(" hung=%us workers=%d",
@@ -4864,6 +4877,7 @@ void show_workqueue_state(void)
                        first = false;
                }
                pr_cont("\n");
+               printk_deferred_exit();
        next_pool:
                raw_spin_unlock_irqrestore(&pool->lock, flags);
                /*
index 5efd1b4..a841be5 100644 (file)
@@ -351,7 +351,7 @@ obj-$(CONFIG_OBJAGG) += objagg.o
 obj-$(CONFIG_PLDMFW) += pldmfw/
 
 # KUnit tests
-CFLAGS_bitfield_kunit.o := $(call cc-option,-Wframe-larger-than=10240)
+CFLAGS_bitfield_kunit.o := $(DISABLE_STRUCTLEAK_PLUGIN)
 obj-$(CONFIG_BITFIELD_KUNIT) += bitfield_kunit.o
 obj-$(CONFIG_LIST_KUNIT_TEST) += list-test.o
 obj-$(CONFIG_LINEAR_RANGES_TEST) += test_linear_ranges.o
index cdbe54b..e14a18a 100644 (file)
@@ -116,8 +116,8 @@ static void kfree_at_end(struct kunit *test, const void *to_free)
        /* kfree() handles NULL already, but avoid allocating a no-op cleanup. */
        if (IS_ERR_OR_NULL(to_free))
                return;
-       kunit_alloc_and_get_resource(test, NULL, kfree_res_free, GFP_KERNEL,
-                                    (void *)to_free);
+       kunit_alloc_resource(test, NULL, kfree_res_free, GFP_KERNEL,
+                            (void *)to_free);
 }
 
 static struct kunit_suite *alloc_fake_suite(struct kunit *test,
index 184dcd2..5c3503c 100644 (file)
@@ -936,7 +936,12 @@ int __init_memblock memblock_mark_mirror(phys_addr_t base, phys_addr_t size)
  */
 int __init_memblock memblock_mark_nomap(phys_addr_t base, phys_addr_t size)
 {
-       return memblock_setclr_flag(base, size, 1, MEMBLOCK_NOMAP);
+       int ret = memblock_setclr_flag(base, size, 1, MEMBLOCK_NOMAP);
+
+       if (!ret)
+               kmemleak_free_part_phys(base, size);
+
+       return ret;
 }
 
 /**
index 6c58fc1..5c6c430 100644 (file)
@@ -1666,7 +1666,8 @@ static size_t br_get_linkxstats_size(const struct net_device *dev, int attr)
        }
 
        return numvls * nla_total_size(sizeof(struct bridge_vlan_xstats)) +
-              nla_total_size(sizeof(struct br_mcast_stats)) +
+              nla_total_size_64bit(sizeof(struct br_mcast_stats)) +
+              (p ? nla_total_size_64bit(sizeof(p->stp_xstats)) : 0) +
               nla_total_size(0);
 }
 
index eab5fc8..d8b9dba 100644 (file)
@@ -77,8 +77,8 @@ static void dev_seq_printf_stats(struct seq_file *seq, struct net_device *dev)
        struct rtnl_link_stats64 temp;
        const struct rtnl_link_stats64 *stats = dev_get_stats(dev, &temp);
 
-       seq_printf(seq, "%9s: %16llu %12llu %4llu %6llu %4llu %5llu %10llu %9llu "
-                  "%16llu %12llu %4llu %6llu %4llu %5llu %7llu %10llu\n",
+       seq_printf(seq, "%6s: %7llu %7llu %4llu %4llu %4llu %5llu %10llu %9llu "
+                  "%8llu %7llu %4llu %4llu %4llu %5llu %7llu %10llu\n",
                   dev->name, stats->rx_bytes, stats->rx_packets,
                   stats->rx_errors,
                   stats->rx_dropped + stats->rx_missed_errors,
@@ -103,11 +103,11 @@ static void dev_seq_printf_stats(struct seq_file *seq, struct net_device *dev)
 static int dev_seq_show(struct seq_file *seq, void *v)
 {
        if (v == SEQ_START_TOKEN)
-               seq_puts(seq, "Interface|                            Receive                   "
-                             "                    |                                 Transmit\n"
-                             "         |            bytes      packets errs   drop fifo frame "
-                             "compressed multicast|            bytes      packets errs "
-                             "  drop fifo colls carrier compressed\n");
+               seq_puts(seq, "Inter-|   Receive                            "
+                             "                    |  Transmit\n"
+                             " face |bytes    packets errs drop fifo frame "
+                             "compressed multicast|bytes    packets errs "
+                             "drop fifo colls carrier compressed\n");
        else
                dev_seq_printf_stats(seq, v);
        return 0;
@@ -259,14 +259,14 @@ static int ptype_seq_show(struct seq_file *seq, void *v)
        struct packet_type *pt = v;
 
        if (v == SEQ_START_TOKEN)
-               seq_puts(seq, "Type      Device      Function\n");
+               seq_puts(seq, "Type Device      Function\n");
        else if (pt->dev == NULL || dev_net(pt->dev) == seq_file_net(seq)) {
                if (pt->type == htons(ETH_P_ALL))
                        seq_puts(seq, "ALL ");
                else
                        seq_printf(seq, "%04x", ntohs(pt->type));
 
-               seq_printf(seq, "      %-9s   %ps\n",
+               seq_printf(seq, " %-8s %ps\n",
                           pt->dev ? pt->dev->name : "", pt->func);
        }
 
@@ -327,14 +327,12 @@ static int dev_mc_seq_show(struct seq_file *seq, void *v)
        struct netdev_hw_addr *ha;
        struct net_device *dev = v;
 
-       if (v == SEQ_START_TOKEN) {
-               seq_puts(seq, "Ifindex Interface Refcount Global_use Address\n");
+       if (v == SEQ_START_TOKEN)
                return 0;
-       }
 
        netif_addr_lock_bh(dev);
        netdev_for_each_mc_addr(ha, dev) {
-               seq_printf(seq, "%-7d %-9s %-8d %-10d %*phN\n",
+               seq_printf(seq, "%-4d %-15s %-5d %-5d %*phN\n",
                           dev->ifindex, dev->name,
                           ha->refcount, ha->global_use,
                           (int)dev->addr_len, ha->addr);
index 972c8cb..8ccce85 100644 (file)
@@ -5262,7 +5262,7 @@ nla_put_failure:
 static size_t if_nlmsg_stats_size(const struct net_device *dev,
                                  u32 filter_mask)
 {
-       size_t size = 0;
+       size_t size = NLMSG_ALIGN(sizeof(struct if_stats_msg));
 
        if (stats_attr_valid(filter_mask, IFLA_STATS_LINK_64, 0))
                size += nla_total_size_64bit(sizeof(struct rtnl_link_stats64));
index 5482855..d8ee15f 100644 (file)
@@ -101,8 +101,6 @@ config NET_DSA_TAG_RTL4_A
 
 config NET_DSA_TAG_OCELOT
        tristate "Tag driver for Ocelot family of switches, using NPI port"
-       depends on MSCC_OCELOT_SWITCH_LIB || \
-                  (MSCC_OCELOT_SWITCH_LIB=n && COMPILE_TEST)
        select PACKING
        help
          Say Y or M if you want to enable NPI tagging for the Ocelot switches
@@ -114,8 +112,6 @@ config NET_DSA_TAG_OCELOT
 
 config NET_DSA_TAG_OCELOT_8021Q
        tristate "Tag driver for Ocelot family of switches, using VLAN"
-       depends on MSCC_OCELOT_SWITCH_LIB || \
-                 (MSCC_OCELOT_SWITCH_LIB=n && COMPILE_TEST)
        help
          Say Y or M if you want to enable support for tagging frames with a
          custom VLAN-based header. Frames that require timestamping, such as
@@ -138,7 +134,6 @@ config NET_DSA_TAG_LAN9303
 
 config NET_DSA_TAG_SJA1105
        tristate "Tag driver for NXP SJA1105 switches"
-       depends on NET_DSA_SJA1105 || !NET_DSA_SJA1105
        select PACKING
        help
          Say Y or M if you want to enable support for tagging frames with the
index b29262e..da18094 100644 (file)
@@ -170,7 +170,7 @@ void dsa_bridge_num_put(const struct net_device *bridge_dev, int bridge_num)
        /* Check if the bridge is still in use, otherwise it is time
         * to clean it up so we can reuse this bridge_num later.
         */
-       if (!dsa_bridge_num_find(bridge_dev))
+       if (dsa_bridge_num_find(bridge_dev) < 0)
                clear_bit(bridge_num, &dsa_fwd_offloading_bridges);
 }
 
@@ -811,7 +811,9 @@ static int dsa_switch_setup_tag_protocol(struct dsa_switch *ds)
                if (!dsa_is_cpu_port(ds, port))
                        continue;
 
+               rtnl_lock();
                err = ds->ops->change_tag_protocol(ds, port, tag_ops->proto);
+               rtnl_unlock();
                if (err) {
                        dev_err(ds->dev, "Unable to use tag protocol \"%s\": %pe\n",
                                tag_ops->name, ERR_PTR(err));
index 1c797ec..6466d05 100644 (file)
@@ -168,7 +168,7 @@ static int dsa_switch_bridge_leave(struct dsa_switch *ds,
                if (extack._msg)
                        dev_err(ds->dev, "port %d: %s\n", info->port,
                                extack._msg);
-               if (err && err != EOPNOTSUPP)
+               if (err && err != -EOPNOTSUPP)
                        return err;
        }
 
index 77d0ce8..b3da4b2 100644 (file)
@@ -45,6 +45,7 @@
  *   6    6       2        2      4    2       N
  */
 
+#include <linux/dsa/mv88e6xxx.h>
 #include <linux/etherdevice.h>
 #include <linux/list.h>
 #include <linux/slab.h>
@@ -129,12 +130,9 @@ static struct sk_buff *dsa_xmit_ll(struct sk_buff *skb, struct net_device *dev,
        u8 tag_dev, tag_port;
        enum dsa_cmd cmd;
        u8 *dsa_header;
-       u16 pvid = 0;
-       int err;
 
        if (skb->offload_fwd_mark) {
                struct dsa_switch_tree *dst = dp->ds->dst;
-               struct net_device *br = dp->bridge_dev;
 
                cmd = DSA_CMD_FORWARD;
 
@@ -144,19 +142,6 @@ static struct sk_buff *dsa_xmit_ll(struct sk_buff *skb, struct net_device *dev,
                 */
                tag_dev = dst->last_switch + 1 + dp->bridge_num;
                tag_port = 0;
-
-               /* If we are offloading forwarding for a VLAN-unaware bridge,
-                * inject packets to hardware using the bridge's pvid, since
-                * that's where the packets ingressed from.
-                */
-               if (!br_vlan_enabled(br)) {
-                       /* Safe because __dev_queue_xmit() runs under
-                        * rcu_read_lock_bh()
-                        */
-                       err = br_vlan_get_pvid_rcu(br, &pvid);
-                       if (err)
-                               return NULL;
-               }
        } else {
                cmd = DSA_CMD_FROM_CPU;
                tag_dev = dp->ds->index;
@@ -180,16 +165,21 @@ static struct sk_buff *dsa_xmit_ll(struct sk_buff *skb, struct net_device *dev,
                        dsa_header[2] &= ~0x10;
                }
        } else {
+               struct net_device *br = dp->bridge_dev;
+               u16 vid;
+
+               vid = br ? MV88E6XXX_VID_BRIDGED : MV88E6XXX_VID_STANDALONE;
+
                skb_push(skb, DSA_HLEN + extra);
                dsa_alloc_etype_header(skb, DSA_HLEN + extra);
 
-               /* Construct untagged DSA tag. */
+               /* Construct DSA header from untagged frame. */
                dsa_header = dsa_etype_header_pos_tx(skb) + extra;
 
                dsa_header[0] = (cmd << 6) | tag_dev;
                dsa_header[1] = tag_port << 3;
-               dsa_header[2] = pvid >> 8;
-               dsa_header[3] = pvid & 0xff;
+               dsa_header[2] = vid >> 8;
+               dsa_header[3] = vid & 0xff;
        }
 
        return skb;
@@ -210,7 +200,7 @@ static struct sk_buff *dsa_rcv_ll(struct sk_buff *skb, struct net_device *dev,
        cmd = dsa_header[0] >> 6;
        switch (cmd) {
        case DSA_CMD_FORWARD:
-               trunk = !!(dsa_header[1] & 7);
+               trunk = !!(dsa_header[1] & 4);
                break;
 
        case DSA_CMD_TO_CPU:
index 8025ed7..605b51c 100644 (file)
@@ -2,7 +2,6 @@
 /* Copyright 2019 NXP
  */
 #include <linux/dsa/ocelot.h>
-#include <soc/mscc/ocelot.h>
 #include "dsa_priv.h"
 
 static void ocelot_xmit_common(struct sk_buff *skb, struct net_device *netdev,
index 5907293..3412051 100644 (file)
@@ -9,10 +9,32 @@
  *   that on egress
  */
 #include <linux/dsa/8021q.h>
-#include <soc/mscc/ocelot.h>
-#include <soc/mscc/ocelot_ptp.h>
+#include <linux/dsa/ocelot.h>
 #include "dsa_priv.h"
 
+static struct sk_buff *ocelot_defer_xmit(struct dsa_port *dp,
+                                        struct sk_buff *skb)
+{
+       struct felix_deferred_xmit_work *xmit_work;
+       struct felix_port *felix_port = dp->priv;
+
+       xmit_work = kzalloc(sizeof(*xmit_work), GFP_ATOMIC);
+       if (!xmit_work)
+               return NULL;
+
+       /* Calls felix_port_deferred_xmit in felix.c */
+       kthread_init_work(&xmit_work->work, felix_port->xmit_work_fn);
+       /* Increase refcount so the kfree_skb in dsa_slave_xmit
+        * won't really free the packet.
+        */
+       xmit_work->dp = dp;
+       xmit_work->skb = skb_get(skb);
+
+       kthread_queue_work(felix_port->xmit_worker, &xmit_work->work);
+
+       return NULL;
+}
+
 static struct sk_buff *ocelot_xmit(struct sk_buff *skb,
                                   struct net_device *netdev)
 {
@@ -20,18 +42,10 @@ static struct sk_buff *ocelot_xmit(struct sk_buff *skb,
        u16 tx_vid = dsa_8021q_tx_vid(dp->ds, dp->index);
        u16 queue_mapping = skb_get_queue_mapping(skb);
        u8 pcp = netdev_txq_to_tc(netdev, queue_mapping);
-       struct ocelot *ocelot = dp->ds->priv;
-       int port = dp->index;
-       u32 rew_op = 0;
+       struct ethhdr *hdr = eth_hdr(skb);
 
-       rew_op = ocelot_ptp_rew_op(skb);
-       if (rew_op) {
-               if (!ocelot_can_inject(ocelot, 0))
-                       return NULL;
-
-               ocelot_port_inject_frame(ocelot, port, 0, rew_op, skb);
-               return NULL;
-       }
+       if (ocelot_ptp_rew_op(skb) || is_link_local_ether_addr(hdr->h_dest))
+               return ocelot_defer_xmit(dp, skb);
 
        return dsa_8021q_xmit(skb, netdev, ETH_P_8021Q,
                              ((pcp << VLAN_PRIO_SHIFT) | tx_vid));
index c054f48..2edede9 100644 (file)
@@ -4,6 +4,7 @@
 #include <linux/if_vlan.h>
 #include <linux/dsa/sja1105.h>
 #include <linux/dsa/8021q.h>
+#include <linux/skbuff.h>
 #include <linux/packing.h>
 #include "dsa_priv.h"
 
 #define SJA1110_TX_TRAILER_LEN                 4
 #define SJA1110_MAX_PADDING_LEN                        15
 
+enum sja1110_meta_tstamp {
+       SJA1110_META_TSTAMP_TX = 0,
+       SJA1110_META_TSTAMP_RX = 1,
+};
+
 /* Similar to is_link_local_ether_addr(hdr->h_dest) but also covers PTP */
 static inline bool sja1105_is_link_local(const struct sk_buff *skb)
 {
@@ -520,6 +526,43 @@ static struct sk_buff *sja1105_rcv(struct sk_buff *skb,
                                              is_meta);
 }
 
+static void sja1110_process_meta_tstamp(struct dsa_switch *ds, int port,
+                                       u8 ts_id, enum sja1110_meta_tstamp dir,
+                                       u64 tstamp)
+{
+       struct sk_buff *skb, *skb_tmp, *skb_match = NULL;
+       struct dsa_port *dp = dsa_to_port(ds, port);
+       struct skb_shared_hwtstamps shwt = {0};
+       struct sja1105_port *sp = dp->priv;
+
+       if (!dsa_port_is_sja1105(dp))
+               return;
+
+       /* We don't care about RX timestamps on the CPU port */
+       if (dir == SJA1110_META_TSTAMP_RX)
+               return;
+
+       spin_lock(&sp->data->skb_txtstamp_queue.lock);
+
+       skb_queue_walk_safe(&sp->data->skb_txtstamp_queue, skb, skb_tmp) {
+               if (SJA1105_SKB_CB(skb)->ts_id != ts_id)
+                       continue;
+
+               __skb_unlink(skb, &sp->data->skb_txtstamp_queue);
+               skb_match = skb;
+
+               break;
+       }
+
+       spin_unlock(&sp->data->skb_txtstamp_queue.lock);
+
+       if (WARN_ON(!skb_match))
+               return;
+
+       shwt.hwtstamp = ns_to_ktime(sja1105_ticks_to_ns(tstamp));
+       skb_complete_tx_timestamp(skb_match, &shwt);
+}
+
 static struct sk_buff *sja1110_rcv_meta(struct sk_buff *skb, u16 rx_header)
 {
        u8 *buf = dsa_etype_header_pos_rx(skb) + SJA1110_HEADER_LEN;
index 8b30cad..b7e277d 100644 (file)
@@ -1054,14 +1054,19 @@ bool icmp_build_probe(struct sk_buff *skb, struct icmphdr *icmphdr)
        iio = skb_header_pointer(skb, sizeof(_ext_hdr), sizeof(iio->extobj_hdr), &_iio);
        if (!ext_hdr || !iio)
                goto send_mal_query;
-       if (ntohs(iio->extobj_hdr.length) <= sizeof(iio->extobj_hdr))
+       if (ntohs(iio->extobj_hdr.length) <= sizeof(iio->extobj_hdr) ||
+           ntohs(iio->extobj_hdr.length) > sizeof(_iio))
                goto send_mal_query;
        ident_len = ntohs(iio->extobj_hdr.length) - sizeof(iio->extobj_hdr);
+       iio = skb_header_pointer(skb, sizeof(_ext_hdr),
+                                sizeof(iio->extobj_hdr) + ident_len, &_iio);
+       if (!iio)
+               goto send_mal_query;
+
        status = 0;
        dev = NULL;
        switch (iio->extobj_hdr.class_type) {
        case ICMP_EXT_ECHO_CTYPE_NAME:
-               iio = skb_header_pointer(skb, sizeof(_ext_hdr), sizeof(_iio), &_iio);
                if (ident_len >= IFNAMSIZ)
                        goto send_mal_query;
                memset(buff, 0, sizeof(buff));
@@ -1069,30 +1074,24 @@ bool icmp_build_probe(struct sk_buff *skb, struct icmphdr *icmphdr)
                dev = dev_get_by_name(net, buff);
                break;
        case ICMP_EXT_ECHO_CTYPE_INDEX:
-               iio = skb_header_pointer(skb, sizeof(_ext_hdr), sizeof(iio->extobj_hdr) +
-                                        sizeof(iio->ident.ifindex), &_iio);
                if (ident_len != sizeof(iio->ident.ifindex))
                        goto send_mal_query;
                dev = dev_get_by_index(net, ntohl(iio->ident.ifindex));
                break;
        case ICMP_EXT_ECHO_CTYPE_ADDR:
-               if (ident_len != sizeof(iio->ident.addr.ctype3_hdr) +
+               if (ident_len < sizeof(iio->ident.addr.ctype3_hdr) ||
+                   ident_len != sizeof(iio->ident.addr.ctype3_hdr) +
                                 iio->ident.addr.ctype3_hdr.addrlen)
                        goto send_mal_query;
                switch (ntohs(iio->ident.addr.ctype3_hdr.afi)) {
                case ICMP_AFI_IP:
-                       iio = skb_header_pointer(skb, sizeof(_ext_hdr), sizeof(iio->extobj_hdr) +
-                                                sizeof(struct in_addr), &_iio);
-                       if (ident_len != sizeof(iio->ident.addr.ctype3_hdr) +
-                                        sizeof(struct in_addr))
+                       if (iio->ident.addr.ctype3_hdr.addrlen != sizeof(struct in_addr))
                                goto send_mal_query;
                        dev = ip_dev_find(net, iio->ident.addr.ip_addr.ipv4_addr);
                        break;
 #if IS_ENABLED(CONFIG_IPV6)
                case ICMP_AFI_IP6:
-                       iio = skb_header_pointer(skb, sizeof(_ext_hdr), sizeof(_iio), &_iio);
-                       if (ident_len != sizeof(iio->ident.addr.ctype3_hdr) +
-                                        sizeof(struct in6_addr))
+                       if (iio->ident.addr.ctype3_hdr.addrlen != sizeof(struct in6_addr))
                                goto send_mal_query;
                        dev = ipv6_stub->ipv6_dev_find(net, &iio->ident.addr.ip_addr.ipv6_addr, dev);
                        dev_hold(dev);
index 80aeaf9..bfb522e 100644 (file)
@@ -242,8 +242,10 @@ static inline int compute_score(struct sock *sk, struct net *net,
 
                if (!inet_sk_bound_dev_eq(net, sk->sk_bound_dev_if, dif, sdif))
                        return -1;
+               score =  sk->sk_bound_dev_if ? 2 : 1;
 
-               score = sk->sk_family == PF_INET ? 2 : 1;
+               if (sk->sk_family == PF_INET)
+                       score++;
                if (READ_ONCE(sk->sk_incoming_cpu) == raw_smp_processor_id())
                        score++;
        }
index 613432a..e61ea42 100644 (file)
 #endif
 #include <net/netfilter/nf_conntrack_zones.h>
 
-static unsigned int defrag4_pernet_id __read_mostly;
 static DEFINE_MUTEX(defrag4_mutex);
 
-struct defrag4_pernet {
-       unsigned int users;
-};
-
 static int nf_ct_ipv4_gather_frags(struct net *net, struct sk_buff *skb,
                                   u_int32_t user)
 {
@@ -111,19 +106,15 @@ static const struct nf_hook_ops ipv4_defrag_ops[] = {
 
 static void __net_exit defrag4_net_exit(struct net *net)
 {
-       struct defrag4_pernet *nf_defrag = net_generic(net, defrag4_pernet_id);
-
-       if (nf_defrag->users) {
+       if (net->nf.defrag_ipv4_users) {
                nf_unregister_net_hooks(net, ipv4_defrag_ops,
                                        ARRAY_SIZE(ipv4_defrag_ops));
-               nf_defrag->users = 0;
+               net->nf.defrag_ipv4_users = 0;
        }
 }
 
 static struct pernet_operations defrag4_net_ops = {
        .exit = defrag4_net_exit,
-       .id   = &defrag4_pernet_id,
-       .size = sizeof(struct defrag4_pernet),
 };
 
 static int __init nf_defrag_init(void)
@@ -138,24 +129,23 @@ static void __exit nf_defrag_fini(void)
 
 int nf_defrag_ipv4_enable(struct net *net)
 {
-       struct defrag4_pernet *nf_defrag = net_generic(net, defrag4_pernet_id);
        int err = 0;
 
        mutex_lock(&defrag4_mutex);
-       if (nf_defrag->users == UINT_MAX) {
+       if (net->nf.defrag_ipv4_users == UINT_MAX) {
                err = -EOVERFLOW;
                goto out_unlock;
        }
 
-       if (nf_defrag->users) {
-               nf_defrag->users++;
+       if (net->nf.defrag_ipv4_users) {
+               net->nf.defrag_ipv4_users++;
                goto out_unlock;
        }
 
        err = nf_register_net_hooks(net, ipv4_defrag_ops,
                                    ARRAY_SIZE(ipv4_defrag_ops));
        if (err == 0)
-               nf_defrag->users = 1;
+               net->nf.defrag_ipv4_users = 1;
 
  out_unlock:
        mutex_unlock(&defrag4_mutex);
@@ -165,12 +155,10 @@ EXPORT_SYMBOL_GPL(nf_defrag_ipv4_enable);
 
 void nf_defrag_ipv4_disable(struct net *net)
 {
-       struct defrag4_pernet *nf_defrag = net_generic(net, defrag4_pernet_id);
-
        mutex_lock(&defrag4_mutex);
-       if (nf_defrag->users) {
-               nf_defrag->users--;
-               if (nf_defrag->users == 0)
+       if (net->nf.defrag_ipv4_users) {
+               net->nf.defrag_ipv4_users--;
+               if (net->nf.defrag_ipv4_users == 0)
                        nf_unregister_net_hooks(net, ipv4_defrag_ops,
                                                ARRAY_SIZE(ipv4_defrag_ops));
        }
index 2a7825a..8536b2a 100644 (file)
@@ -390,7 +390,8 @@ static int compute_score(struct sock *sk, struct net *net,
                                        dif, sdif);
        if (!dev_match)
                return -1;
-       score += 4;
+       if (sk->sk_bound_dev_if)
+               score += 4;
 
        if (READ_ONCE(sk->sk_incoming_cpu) == raw_smp_processor_id())
                score++;
index 55c290d..67c9114 100644 (file)
@@ -106,7 +106,7 @@ static inline int compute_score(struct sock *sk, struct net *net,
                if (!inet_sk_bound_dev_eq(net, sk->sk_bound_dev_if, dif, sdif))
                        return -1;
 
-               score = 1;
+               score =  sk->sk_bound_dev_if ? 2 : 1;
                if (READ_ONCE(sk->sk_incoming_cpu) == raw_smp_processor_id())
                        score++;
        }
index 5e89610..d128172 100644 (file)
@@ -770,6 +770,66 @@ static void __ioam6_fill_trace_data(struct sk_buff *skb,
                data += sizeof(__be32);
        }
 
+       /* bit12 undefined: filled with empty value */
+       if (trace->type.bit12) {
+               *(__be32 *)data = cpu_to_be32(IOAM6_U32_UNAVAILABLE);
+               data += sizeof(__be32);
+       }
+
+       /* bit13 undefined: filled with empty value */
+       if (trace->type.bit13) {
+               *(__be32 *)data = cpu_to_be32(IOAM6_U32_UNAVAILABLE);
+               data += sizeof(__be32);
+       }
+
+       /* bit14 undefined: filled with empty value */
+       if (trace->type.bit14) {
+               *(__be32 *)data = cpu_to_be32(IOAM6_U32_UNAVAILABLE);
+               data += sizeof(__be32);
+       }
+
+       /* bit15 undefined: filled with empty value */
+       if (trace->type.bit15) {
+               *(__be32 *)data = cpu_to_be32(IOAM6_U32_UNAVAILABLE);
+               data += sizeof(__be32);
+       }
+
+       /* bit16 undefined: filled with empty value */
+       if (trace->type.bit16) {
+               *(__be32 *)data = cpu_to_be32(IOAM6_U32_UNAVAILABLE);
+               data += sizeof(__be32);
+       }
+
+       /* bit17 undefined: filled with empty value */
+       if (trace->type.bit17) {
+               *(__be32 *)data = cpu_to_be32(IOAM6_U32_UNAVAILABLE);
+               data += sizeof(__be32);
+       }
+
+       /* bit18 undefined: filled with empty value */
+       if (trace->type.bit18) {
+               *(__be32 *)data = cpu_to_be32(IOAM6_U32_UNAVAILABLE);
+               data += sizeof(__be32);
+       }
+
+       /* bit19 undefined: filled with empty value */
+       if (trace->type.bit19) {
+               *(__be32 *)data = cpu_to_be32(IOAM6_U32_UNAVAILABLE);
+               data += sizeof(__be32);
+       }
+
+       /* bit20 undefined: filled with empty value */
+       if (trace->type.bit20) {
+               *(__be32 *)data = cpu_to_be32(IOAM6_U32_UNAVAILABLE);
+               data += sizeof(__be32);
+       }
+
+       /* bit21 undefined: filled with empty value */
+       if (trace->type.bit21) {
+               *(__be32 *)data = cpu_to_be32(IOAM6_U32_UNAVAILABLE);
+               data += sizeof(__be32);
+       }
+
        /* opaque state snapshot */
        if (trace->type.bit22) {
                if (!sc) {
@@ -791,16 +851,10 @@ void ioam6_fill_trace_data(struct sk_buff *skb,
        struct ioam6_schema *sc;
        u8 sclen = 0;
 
-       /* Skip if Overflow flag is set OR
-        * if an unknown type (bit 12-21) is set
+       /* Skip if Overflow flag is set
         */
-       if (trace->overflow ||
-           trace->type.bit12 | trace->type.bit13 | trace->type.bit14 |
-           trace->type.bit15 | trace->type.bit16 | trace->type.bit17 |
-           trace->type.bit18 | trace->type.bit19 | trace->type.bit20 |
-           trace->type.bit21) {
+       if (trace->overflow)
                return;
-       }
 
        /* NodeLen does not include Opaque State Snapshot length. We need to
         * take it into account if the corresponding bit is set (bit 22) and
index f9ee045..9b7b726 100644 (file)
@@ -75,7 +75,11 @@ static bool ioam6_validate_trace_hdr(struct ioam6_trace_hdr *trace)
        u32 fields;
 
        if (!trace->type_be32 || !trace->remlen ||
-           trace->remlen > IOAM6_TRACE_DATA_SIZE_MAX / 4)
+           trace->remlen > IOAM6_TRACE_DATA_SIZE_MAX / 4 ||
+           trace->type.bit12 | trace->type.bit13 | trace->type.bit14 |
+           trace->type.bit15 | trace->type.bit16 | trace->type.bit17 |
+           trace->type.bit18 | trace->type.bit19 | trace->type.bit20 |
+           trace->type.bit21)
                return false;
 
        trace->nodelen = 0;
index a010841..5c47be2 100644 (file)
@@ -33,7 +33,7 @@
 
 static const char nf_frags_cache_name[] = "nf-frags";
 
-unsigned int nf_frag_pernet_id __read_mostly;
+static unsigned int nf_frag_pernet_id __read_mostly;
 static struct inet_frags nf_frags;
 
 static struct nft_ct_frag6_pernet *nf_frag_pernet(struct net *net)
index e8a59d8..cb4eb1d 100644 (file)
@@ -25,8 +25,6 @@
 #include <net/netfilter/nf_conntrack_zones.h>
 #include <net/netfilter/ipv6/nf_defrag_ipv6.h>
 
-extern unsigned int nf_frag_pernet_id;
-
 static DEFINE_MUTEX(defrag6_mutex);
 
 static enum ip6_defrag_users nf_ct6_defrag_user(unsigned int hooknum,
@@ -91,12 +89,10 @@ static const struct nf_hook_ops ipv6_defrag_ops[] = {
 
 static void __net_exit defrag6_net_exit(struct net *net)
 {
-       struct nft_ct_frag6_pernet *nf_frag = net_generic(net, nf_frag_pernet_id);
-
-       if (nf_frag->users) {
+       if (net->nf.defrag_ipv6_users) {
                nf_unregister_net_hooks(net, ipv6_defrag_ops,
                                        ARRAY_SIZE(ipv6_defrag_ops));
-               nf_frag->users = 0;
+               net->nf.defrag_ipv6_users = 0;
        }
 }
 
@@ -134,24 +130,23 @@ static void __exit nf_defrag_fini(void)
 
 int nf_defrag_ipv6_enable(struct net *net)
 {
-       struct nft_ct_frag6_pernet *nf_frag = net_generic(net, nf_frag_pernet_id);
        int err = 0;
 
        mutex_lock(&defrag6_mutex);
-       if (nf_frag->users == UINT_MAX) {
+       if (net->nf.defrag_ipv6_users == UINT_MAX) {
                err = -EOVERFLOW;
                goto out_unlock;
        }
 
-       if (nf_frag->users) {
-               nf_frag->users++;
+       if (net->nf.defrag_ipv6_users) {
+               net->nf.defrag_ipv6_users++;
                goto out_unlock;
        }
 
        err = nf_register_net_hooks(net, ipv6_defrag_ops,
                                    ARRAY_SIZE(ipv6_defrag_ops));
        if (err == 0)
-               nf_frag->users = 1;
+               net->nf.defrag_ipv6_users = 1;
 
  out_unlock:
        mutex_unlock(&defrag6_mutex);
@@ -161,12 +156,10 @@ EXPORT_SYMBOL_GPL(nf_defrag_ipv6_enable);
 
 void nf_defrag_ipv6_disable(struct net *net)
 {
-       struct nft_ct_frag6_pernet *nf_frag = net_generic(net, nf_frag_pernet_id);
-
        mutex_lock(&defrag6_mutex);
-       if (nf_frag->users) {
-               nf_frag->users--;
-               if (nf_frag->users == 0)
+       if (net->nf.defrag_ipv6_users) {
+               net->nf.defrag_ipv6_users--;
+               if (net->nf.defrag_ipv6_users == 0)
                        nf_unregister_net_hooks(net, ipv6_defrag_ops,
                                                ARRAY_SIZE(ipv6_defrag_ops));
        }
index e505bb0..8d78523 100644 (file)
@@ -133,7 +133,8 @@ static int compute_score(struct sock *sk, struct net *net,
        dev_match = udp_sk_bound_dev_eq(net, sk->sk_bound_dev_if, dif, sdif);
        if (!dev_match)
                return -1;
-       score++;
+       if (sk->sk_bound_dev_if)
+               score++;
 
        if (READ_ONCE(sk->sk_incoming_cpu) == raw_smp_processor_id())
                score++;
index e5df0b5..d073b21 100644 (file)
@@ -528,7 +528,6 @@ static bool mptcp_check_data_fin(struct sock *sk)
 
                sk->sk_shutdown |= RCV_SHUTDOWN;
                smp_mb__before_atomic(); /* SHUTDOWN must be visible first */
-               set_bit(MPTCP_DATA_READY, &msk->flags);
 
                switch (sk->sk_state) {
                case TCP_ESTABLISHED:
@@ -742,10 +741,9 @@ void mptcp_data_ready(struct sock *sk, struct sock *ssk)
 
        /* Wake-up the reader only for in-sequence data */
        mptcp_data_lock(sk);
-       if (move_skbs_to_msk(msk, ssk)) {
-               set_bit(MPTCP_DATA_READY, &msk->flags);
+       if (move_skbs_to_msk(msk, ssk))
                sk->sk_data_ready(sk);
-       }
+
        mptcp_data_unlock(sk);
 }
 
@@ -847,7 +845,6 @@ static void mptcp_check_for_eof(struct mptcp_sock *msk)
                sk->sk_shutdown |= RCV_SHUTDOWN;
 
                smp_mb__before_atomic(); /* SHUTDOWN must be visible first */
-               set_bit(MPTCP_DATA_READY, &msk->flags);
                sk->sk_data_ready(sk);
        }
 
@@ -1759,21 +1756,6 @@ out:
        return copied ? : ret;
 }
 
-static void mptcp_wait_data(struct sock *sk, long *timeo)
-{
-       DEFINE_WAIT_FUNC(wait, woken_wake_function);
-       struct mptcp_sock *msk = mptcp_sk(sk);
-
-       add_wait_queue(sk_sleep(sk), &wait);
-       sk_set_bit(SOCKWQ_ASYNC_WAITDATA, sk);
-
-       sk_wait_event(sk, timeo,
-                     test_bit(MPTCP_DATA_READY, &msk->flags), &wait);
-
-       sk_clear_bit(SOCKWQ_ASYNC_WAITDATA, sk);
-       remove_wait_queue(sk_sleep(sk), &wait);
-}
-
 static int __mptcp_recvmsg_mskq(struct mptcp_sock *msk,
                                struct msghdr *msg,
                                size_t len, int flags,
@@ -2077,19 +2059,7 @@ static int mptcp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
                }
 
                pr_debug("block timeout %ld", timeo);
-               mptcp_wait_data(sk, &timeo);
-       }
-
-       if (skb_queue_empty_lockless(&sk->sk_receive_queue) &&
-           skb_queue_empty(&msk->receive_queue)) {
-               /* entire backlog drained, clear DATA_READY. */
-               clear_bit(MPTCP_DATA_READY, &msk->flags);
-
-               /* .. race-breaker: ssk might have gotten new data
-                * after last __mptcp_move_skbs() returned false.
-                */
-               if (unlikely(__mptcp_move_skbs(msk)))
-                       set_bit(MPTCP_DATA_READY, &msk->flags);
+               sk_wait_data(sk, &timeo, NULL);
        }
 
 out_err:
@@ -2098,9 +2068,9 @@ out_err:
                        tcp_recv_timestamp(msg, sk, &tss);
        }
 
-       pr_debug("msk=%p data_ready=%d rx queue empty=%d copied=%d",
-                msk, test_bit(MPTCP_DATA_READY, &msk->flags),
-                skb_queue_empty_lockless(&sk->sk_receive_queue), copied);
+       pr_debug("msk=%p rx queue empty=%d:%d copied=%d",
+                msk, skb_queue_empty_lockless(&sk->sk_receive_queue),
+                skb_queue_empty(&msk->receive_queue), copied);
        if (!(flags & MSG_PEEK))
                mptcp_rcv_space_adjust(msk, copied);
 
@@ -2368,7 +2338,6 @@ static void mptcp_check_fastclose(struct mptcp_sock *msk)
        inet_sk_state_store(sk, TCP_CLOSE);
        sk->sk_shutdown = SHUTDOWN_MASK;
        smp_mb__before_atomic(); /* SHUTDOWN must be visible first */
-       set_bit(MPTCP_DATA_READY, &msk->flags);
        set_bit(MPTCP_WORK_CLOSE_SUBFLOW, &msk->flags);
 
        mptcp_close_wake_up(sk);
@@ -3385,8 +3354,14 @@ unlock_fail:
 
 static __poll_t mptcp_check_readable(struct mptcp_sock *msk)
 {
-       return test_bit(MPTCP_DATA_READY, &msk->flags) ? EPOLLIN | EPOLLRDNORM :
-              0;
+       /* Concurrent splices from sk_receive_queue into receive_queue will
+        * always show at least one non-empty queue when checked in this order.
+        */
+       if (skb_queue_empty_lockless(&((struct sock *)msk)->sk_receive_queue) &&
+           skb_queue_empty_lockless(&msk->receive_queue))
+               return 0;
+
+       return EPOLLIN | EPOLLRDNORM;
 }
 
 static __poll_t mptcp_check_writeable(struct mptcp_sock *msk)
@@ -3421,7 +3396,7 @@ static __poll_t mptcp_poll(struct file *file, struct socket *sock,
        state = inet_sk_state_load(sk);
        pr_debug("msk=%p state=%d flags=%lx", msk, state, msk->flags);
        if (state == TCP_LISTEN)
-               return mptcp_check_readable(msk);
+               return test_bit(MPTCP_DATA_READY, &msk->flags) ? EPOLLIN | EPOLLRDNORM : 0;
 
        if (state != TCP_SYN_SENT && state != TCP_SYN_RECV) {
                mask |= mptcp_check_readable(msk);
index b9546de..c0851fe 100644 (file)
@@ -780,6 +780,7 @@ static void nf_tables_table_notify(const struct nft_ctx *ctx, int event)
 {
        struct nftables_pernet *nft_net;
        struct sk_buff *skb;
+       u16 flags = 0;
        int err;
 
        if (!ctx->report &&
@@ -790,8 +791,11 @@ static void nf_tables_table_notify(const struct nft_ctx *ctx, int event)
        if (skb == NULL)
                goto err;
 
+       if (ctx->flags & (NLM_F_CREATE | NLM_F_EXCL))
+               flags |= ctx->flags & (NLM_F_CREATE | NLM_F_EXCL);
+
        err = nf_tables_fill_table_info(skb, ctx->net, ctx->portid, ctx->seq,
-                                       event, 0, ctx->family, ctx->table);
+                                       event, flags, ctx->family, ctx->table);
        if (err < 0) {
                kfree_skb(skb);
                goto err;
@@ -1563,6 +1567,7 @@ static void nf_tables_chain_notify(const struct nft_ctx *ctx, int event)
 {
        struct nftables_pernet *nft_net;
        struct sk_buff *skb;
+       u16 flags = 0;
        int err;
 
        if (!ctx->report &&
@@ -1573,8 +1578,11 @@ static void nf_tables_chain_notify(const struct nft_ctx *ctx, int event)
        if (skb == NULL)
                goto err;
 
+       if (ctx->flags & (NLM_F_CREATE | NLM_F_EXCL))
+               flags |= ctx->flags & (NLM_F_CREATE | NLM_F_EXCL);
+
        err = nf_tables_fill_chain_info(skb, ctx->net, ctx->portid, ctx->seq,
-                                       event, 0, ctx->family, ctx->table,
+                                       event, flags, ctx->family, ctx->table,
                                        ctx->chain);
        if (err < 0) {
                kfree_skb(skb);
@@ -2866,8 +2874,7 @@ static int nf_tables_fill_rule_info(struct sk_buff *skb, struct net *net,
                                    u32 flags, int family,
                                    const struct nft_table *table,
                                    const struct nft_chain *chain,
-                                   const struct nft_rule *rule,
-                                   const struct nft_rule *prule)
+                                   const struct nft_rule *rule, u64 handle)
 {
        struct nlmsghdr *nlh;
        const struct nft_expr *expr, *next;
@@ -2887,9 +2894,8 @@ static int nf_tables_fill_rule_info(struct sk_buff *skb, struct net *net,
                         NFTA_RULE_PAD))
                goto nla_put_failure;
 
-       if (event != NFT_MSG_DELRULE && prule) {
-               if (nla_put_be64(skb, NFTA_RULE_POSITION,
-                                cpu_to_be64(prule->handle),
+       if (event != NFT_MSG_DELRULE && handle) {
+               if (nla_put_be64(skb, NFTA_RULE_POSITION, cpu_to_be64(handle),
                                 NFTA_RULE_PAD))
                        goto nla_put_failure;
        }
@@ -2925,7 +2931,10 @@ static void nf_tables_rule_notify(const struct nft_ctx *ctx,
                                  const struct nft_rule *rule, int event)
 {
        struct nftables_pernet *nft_net = nft_pernet(ctx->net);
+       const struct nft_rule *prule;
        struct sk_buff *skb;
+       u64 handle = 0;
+       u16 flags = 0;
        int err;
 
        if (!ctx->report &&
@@ -2936,9 +2945,20 @@ static void nf_tables_rule_notify(const struct nft_ctx *ctx,
        if (skb == NULL)
                goto err;
 
+       if (event == NFT_MSG_NEWRULE &&
+           !list_is_first(&rule->list, &ctx->chain->rules) &&
+           !list_is_last(&rule->list, &ctx->chain->rules)) {
+               prule = list_prev_entry(rule, list);
+               handle = prule->handle;
+       }
+       if (ctx->flags & (NLM_F_APPEND | NLM_F_REPLACE))
+               flags |= NLM_F_APPEND;
+       if (ctx->flags & (NLM_F_CREATE | NLM_F_EXCL))
+               flags |= ctx->flags & (NLM_F_CREATE | NLM_F_EXCL);
+
        err = nf_tables_fill_rule_info(skb, ctx->net, ctx->portid, ctx->seq,
-                                      event, 0, ctx->family, ctx->table,
-                                      ctx->chain, rule, NULL);
+                                      event, flags, ctx->family, ctx->table,
+                                      ctx->chain, rule, handle);
        if (err < 0) {
                kfree_skb(skb);
                goto err;
@@ -2964,6 +2984,7 @@ static int __nf_tables_dump_rules(struct sk_buff *skb,
        struct net *net = sock_net(skb->sk);
        const struct nft_rule *rule, *prule;
        unsigned int s_idx = cb->args[0];
+       u64 handle;
 
        prule = NULL;
        list_for_each_entry_rcu(rule, &chain->rules, list) {
@@ -2975,12 +2996,17 @@ static int __nf_tables_dump_rules(struct sk_buff *skb,
                        memset(&cb->args[1], 0,
                                        sizeof(cb->args) - sizeof(cb->args[0]));
                }
+               if (prule)
+                       handle = prule->handle;
+               else
+                       handle = 0;
+
                if (nf_tables_fill_rule_info(skb, net, NETLINK_CB(cb->skb).portid,
                                        cb->nlh->nlmsg_seq,
                                        NFT_MSG_NEWRULE,
                                        NLM_F_MULTI | NLM_F_APPEND,
                                        table->family,
-                                       table, chain, rule, prule) < 0)
+                                       table, chain, rule, handle) < 0)
                        return 1;
 
                nl_dump_check_consistent(cb, nlmsg_hdr(skb));
@@ -3143,7 +3169,7 @@ static int nf_tables_getrule(struct sk_buff *skb, const struct nfnl_info *info,
 
        err = nf_tables_fill_rule_info(skb2, net, NETLINK_CB(skb).portid,
                                       info->nlh->nlmsg_seq, NFT_MSG_NEWRULE, 0,
-                                      family, table, chain, rule, NULL);
+                                      family, table, chain, rule, 0);
        if (err < 0)
                goto err_fill_rule_info;
 
@@ -3403,17 +3429,15 @@ static int nf_tables_newrule(struct sk_buff *skb, const struct nfnl_info *info,
        }
 
        if (info->nlh->nlmsg_flags & NLM_F_REPLACE) {
+               err = nft_delrule(&ctx, old_rule);
+               if (err < 0)
+                       goto err_destroy_flow_rule;
+
                trans = nft_trans_rule_add(&ctx, NFT_MSG_NEWRULE, rule);
                if (trans == NULL) {
                        err = -ENOMEM;
                        goto err_destroy_flow_rule;
                }
-               err = nft_delrule(&ctx, old_rule);
-               if (err < 0) {
-                       nft_trans_destroy(trans);
-                       goto err_destroy_flow_rule;
-               }
-
                list_add_tail_rcu(&rule->list, &old_rule->list);
        } else {
                trans = nft_trans_rule_add(&ctx, NFT_MSG_NEWRULE, rule);
@@ -3943,8 +3967,9 @@ static void nf_tables_set_notify(const struct nft_ctx *ctx,
                                 gfp_t gfp_flags)
 {
        struct nftables_pernet *nft_net = nft_pernet(ctx->net);
-       struct sk_buff *skb;
        u32 portid = ctx->portid;
+       struct sk_buff *skb;
+       u16 flags = 0;
        int err;
 
        if (!ctx->report &&
@@ -3955,7 +3980,10 @@ static void nf_tables_set_notify(const struct nft_ctx *ctx,
        if (skb == NULL)
                goto err;
 
-       err = nf_tables_fill_set(skb, ctx, set, event, 0);
+       if (ctx->flags & (NLM_F_CREATE | NLM_F_EXCL))
+               flags |= ctx->flags & (NLM_F_CREATE | NLM_F_EXCL);
+
+       err = nf_tables_fill_set(skb, ctx, set, event, flags);
        if (err < 0) {
                kfree_skb(skb);
                goto err;
@@ -5231,12 +5259,13 @@ static int nf_tables_getsetelem(struct sk_buff *skb,
 static void nf_tables_setelem_notify(const struct nft_ctx *ctx,
                                     const struct nft_set *set,
                                     const struct nft_set_elem *elem,
-                                    int event, u16 flags)
+                                    int event)
 {
        struct nftables_pernet *nft_net;
        struct net *net = ctx->net;
        u32 portid = ctx->portid;
        struct sk_buff *skb;
+       u16 flags = 0;
        int err;
 
        if (!ctx->report && !nfnetlink_has_listeners(net, NFNLGRP_NFTABLES))
@@ -5246,6 +5275,9 @@ static void nf_tables_setelem_notify(const struct nft_ctx *ctx,
        if (skb == NULL)
                goto err;
 
+       if (ctx->flags & (NLM_F_CREATE | NLM_F_EXCL))
+               flags |= ctx->flags & (NLM_F_CREATE | NLM_F_EXCL);
+
        err = nf_tables_fill_setelem_info(skb, ctx, 0, portid, event, flags,
                                          set, elem);
        if (err < 0) {
@@ -6921,7 +6953,7 @@ static int nf_tables_delobj(struct sk_buff *skb, const struct nfnl_info *info,
 
 void nft_obj_notify(struct net *net, const struct nft_table *table,
                    struct nft_object *obj, u32 portid, u32 seq, int event,
-                   int family, int report, gfp_t gfp)
+                   u16 flags, int family, int report, gfp_t gfp)
 {
        struct nftables_pernet *nft_net = nft_pernet(net);
        struct sk_buff *skb;
@@ -6946,8 +6978,9 @@ void nft_obj_notify(struct net *net, const struct nft_table *table,
        if (skb == NULL)
                goto err;
 
-       err = nf_tables_fill_obj_info(skb, net, portid, seq, event, 0, family,
-                                     table, obj, false);
+       err = nf_tables_fill_obj_info(skb, net, portid, seq, event,
+                                     flags & (NLM_F_CREATE | NLM_F_EXCL),
+                                     family, table, obj, false);
        if (err < 0) {
                kfree_skb(skb);
                goto err;
@@ -6964,7 +6997,7 @@ static void nf_tables_obj_notify(const struct nft_ctx *ctx,
                                 struct nft_object *obj, int event)
 {
        nft_obj_notify(ctx->net, ctx->table, obj, ctx->portid, ctx->seq, event,
-                      ctx->family, ctx->report, GFP_KERNEL);
+                      ctx->flags, ctx->family, ctx->report, GFP_KERNEL);
 }
 
 /*
@@ -7745,6 +7778,7 @@ static void nf_tables_flowtable_notify(struct nft_ctx *ctx,
 {
        struct nftables_pernet *nft_net = nft_pernet(ctx->net);
        struct sk_buff *skb;
+       u16 flags = 0;
        int err;
 
        if (!ctx->report &&
@@ -7755,8 +7789,11 @@ static void nf_tables_flowtable_notify(struct nft_ctx *ctx,
        if (skb == NULL)
                goto err;
 
+       if (ctx->flags & (NLM_F_CREATE | NLM_F_EXCL))
+               flags |= ctx->flags & (NLM_F_CREATE | NLM_F_EXCL);
+
        err = nf_tables_fill_flowtable_info(skb, ctx->net, ctx->portid,
-                                           ctx->seq, event, 0,
+                                           ctx->seq, event, flags,
                                            ctx->family, flowtable, hook_list);
        if (err < 0) {
                kfree_skb(skb);
@@ -8634,7 +8671,7 @@ static int nf_tables_commit(struct net *net, struct sk_buff *skb)
                        nft_setelem_activate(net, te->set, &te->elem);
                        nf_tables_setelem_notify(&trans->ctx, te->set,
                                                 &te->elem,
-                                                NFT_MSG_NEWSETELEM, 0);
+                                                NFT_MSG_NEWSETELEM);
                        nft_trans_destroy(trans);
                        break;
                case NFT_MSG_DELSETELEM:
@@ -8642,7 +8679,7 @@ static int nf_tables_commit(struct net *net, struct sk_buff *skb)
 
                        nf_tables_setelem_notify(&trans->ctx, te->set,
                                                 &te->elem,
-                                                NFT_MSG_DELSETELEM, 0);
+                                                NFT_MSG_DELSETELEM);
                        nft_setelem_remove(net, te->set, &te->elem);
                        if (!nft_setelem_is_catchall(te->set, &te->elem)) {
                                atomic_dec(&te->set->nelems);
index 0363f53..c4d1389 100644 (file)
@@ -60,7 +60,7 @@ static void nft_quota_obj_eval(struct nft_object *obj,
        if (overquota &&
            !test_and_set_bit(NFT_QUOTA_DEPLETED_BIT, &priv->flags))
                nft_obj_notify(nft_net(pkt), obj->key.table, obj, 0, 0,
-                              NFT_MSG_NEWOBJ, nft_pf(pkt), 0, GFP_ATOMIC);
+                              NFT_MSG_NEWOBJ, 0, nft_pf(pkt), 0, GFP_ATOMIC);
 }
 
 static int nft_quota_do_init(const struct nlattr * const tb[],
index 24b7cf4..ada47e5 100644 (file)
@@ -594,7 +594,10 @@ static int netlink_insert(struct sock *sk, u32 portid)
 
        /* We need to ensure that the socket is hashed and visible. */
        smp_wmb();
-       nlk_sk(sk)->bound = portid;
+       /* Paired with lockless reads from netlink_bind(),
+        * netlink_connect() and netlink_sendmsg().
+        */
+       WRITE_ONCE(nlk_sk(sk)->bound, portid);
 
 err:
        release_sock(sk);
@@ -1012,7 +1015,8 @@ static int netlink_bind(struct socket *sock, struct sockaddr *addr,
        if (nlk->ngroups < BITS_PER_LONG)
                groups &= (1UL << nlk->ngroups) - 1;
 
-       bound = nlk->bound;
+       /* Paired with WRITE_ONCE() in netlink_insert() */
+       bound = READ_ONCE(nlk->bound);
        if (bound) {
                /* Ensure nlk->portid is up-to-date. */
                smp_rmb();
@@ -1098,8 +1102,9 @@ static int netlink_connect(struct socket *sock, struct sockaddr *addr,
 
        /* No need for barriers here as we return to user-space without
         * using any of the bound attributes.
+        * Paired with WRITE_ONCE() in netlink_insert().
         */
-       if (!nlk->bound)
+       if (!READ_ONCE(nlk->bound))
                err = netlink_autobind(sock);
 
        if (err == 0) {
@@ -1888,7 +1893,8 @@ static int netlink_sendmsg(struct socket *sock, struct msghdr *msg, size_t len)
                dst_group = nlk->dst_group;
        }
 
-       if (!nlk->bound) {
+       /* Paired with WRITE_ONCE() in netlink_insert() */
+       if (!READ_ONCE(nlk->bound)) {
                err = netlink_autobind(sock);
                if (err)
                        goto out;
index 6024fad..dda323e 100644 (file)
@@ -60,6 +60,9 @@ int nfc_proto_register(const struct nfc_protocol *nfc_proto)
                proto_tab[nfc_proto->id] = nfc_proto;
        write_unlock(&proto_tab_lock);
 
+       if (rc)
+               proto_unregister(nfc_proto->proto);
+
        return rc;
 }
 EXPORT_SYMBOL(nfc_proto_register);
index fefc036..d63d2e5 100644 (file)
@@ -277,6 +277,7 @@ int digital_tg_configure_hw(struct nfc_digital_dev *ddev, int type, int param)
 static int digital_tg_listen_mdaa(struct nfc_digital_dev *ddev, u8 rf_tech)
 {
        struct digital_tg_mdaa_params *params;
+       int rc;
 
        params = kzalloc(sizeof(*params), GFP_KERNEL);
        if (!params)
@@ -291,8 +292,12 @@ static int digital_tg_listen_mdaa(struct nfc_digital_dev *ddev, u8 rf_tech)
        get_random_bytes(params->nfcid2 + 2, NFC_NFCID2_MAXSIZE - 2);
        params->sc = DIGITAL_SENSF_FELICA_SC;
 
-       return digital_send_cmd(ddev, DIGITAL_CMD_TG_LISTEN_MDAA, NULL, params,
-                               500, digital_tg_recv_atr_req, NULL);
+       rc = digital_send_cmd(ddev, DIGITAL_CMD_TG_LISTEN_MDAA, NULL, params,
+                             500, digital_tg_recv_atr_req, NULL);
+       if (rc)
+               kfree(params);
+
+       return rc;
 }
 
 static int digital_tg_listen_md(struct nfc_digital_dev *ddev, u8 rf_tech)
index 84d2345..3adf458 100644 (file)
@@ -465,8 +465,12 @@ static int digital_in_send_sdd_req(struct nfc_digital_dev *ddev,
        skb_put_u8(skb, sel_cmd);
        skb_put_u8(skb, DIGITAL_SDD_REQ_SEL_PAR);
 
-       return digital_in_send_cmd(ddev, skb, 30, digital_in_recv_sdd_res,
-                                  target);
+       rc = digital_in_send_cmd(ddev, skb, 30, digital_in_recv_sdd_res,
+                                target);
+       if (rc)
+               kfree_skb(skb);
+
+       return rc;
 }
 
 static void digital_in_recv_sens_res(struct nfc_digital_dev *ddev, void *arg,
index a2e72c0..b911ab7 100644 (file)
@@ -334,6 +334,8 @@ static void nci_core_conn_close_rsp_packet(struct nci_dev *ndev,
                                                         ndev->cur_conn_id);
                if (conn_info) {
                        list_del(&conn_info->list);
+                       if (conn_info == ndev->rf_conn_info)
+                               ndev->rf_conn_info = NULL;
                        devm_kfree(&ndev->nfc_dev->dev, conn_info);
                }
        }
index a579a41..e104042 100644 (file)
@@ -233,6 +233,9 @@ int fifo_set_limit(struct Qdisc *q, unsigned int limit)
        if (strncmp(q->ops->id + 1, "fifo", 4) != 0)
                return 0;
 
+       if (!q->ops->change)
+               return 0;
+
        nla = kmalloc(nla_attr_size(sizeof(struct tc_fifo_qopt)), GFP_KERNEL);
        if (nla) {
                nla->nla_type = RTM_NEWQDISC;
index 8766ab5..5eb3b1b 100644 (file)
@@ -529,22 +529,28 @@ static int mqprio_dump_class_stats(struct Qdisc *sch, unsigned long cl,
                for (i = tc.offset; i < tc.offset + tc.count; i++) {
                        struct netdev_queue *q = netdev_get_tx_queue(dev, i);
                        struct Qdisc *qdisc = rtnl_dereference(q->qdisc);
-                       struct gnet_stats_basic_cpu __percpu *cpu_bstats = NULL;
-                       struct gnet_stats_queue __percpu *cpu_qstats = NULL;
 
                        spin_lock_bh(qdisc_lock(qdisc));
+
                        if (qdisc_is_percpu_stats(qdisc)) {
-                               cpu_bstats = qdisc->cpu_bstats;
-                               cpu_qstats = qdisc->cpu_qstats;
+                               qlen = qdisc_qlen_sum(qdisc);
+
+                               __gnet_stats_copy_basic(NULL, &bstats,
+                                                       qdisc->cpu_bstats,
+                                                       &qdisc->bstats);
+                               __gnet_stats_copy_queue(&qstats,
+                                                       qdisc->cpu_qstats,
+                                                       &qdisc->qstats,
+                                                       qlen);
+                       } else {
+                               qlen            += qdisc->q.qlen;
+                               bstats.bytes    += qdisc->bstats.bytes;
+                               bstats.packets  += qdisc->bstats.packets;
+                               qstats.backlog  += qdisc->qstats.backlog;
+                               qstats.drops    += qdisc->qstats.drops;
+                               qstats.requeues += qdisc->qstats.requeues;
+                               qstats.overlimits += qdisc->qstats.overlimits;
                        }
-
-                       qlen = qdisc_qlen_sum(qdisc);
-                       __gnet_stats_copy_basic(NULL, &sch->bstats,
-                                               cpu_bstats, &qdisc->bstats);
-                       __gnet_stats_copy_queue(&sch->qstats,
-                                               cpu_qstats,
-                                               &qdisc->qstats,
-                                               qlen);
                        spin_unlock_bh(qdisc_lock(qdisc));
                }
 
index 1ab2fc9..b9fd18d 100644 (file)
@@ -1641,6 +1641,10 @@ static void taprio_destroy(struct Qdisc *sch)
        list_del(&q->taprio_list);
        spin_unlock(&taprio_list_lock);
 
+       /* Note that taprio_reset() might not be called if an error
+        * happens in qdisc_create(), after taprio_init() has been called.
+        */
+       hrtimer_cancel(&q->advance_timer);
 
        taprio_disable_offload(dev, q, NULL);
 
index b8fa8f1..c7503fd 100644 (file)
@@ -3697,7 +3697,7 @@ struct sctp_chunk *sctp_make_strreset_req(
        outlen = (sizeof(outreq) + stream_len) * out;
        inlen = (sizeof(inreq) + stream_len) * in;
 
-       retval = sctp_make_reconf(asoc, outlen + inlen);
+       retval = sctp_make_reconf(asoc, SCTP_PAD4(outlen) + SCTP_PAD4(inlen));
        if (!retval)
                return NULL;
 
index f23f558..99acd33 100644 (file)
@@ -150,9 +150,11 @@ static int smcr_cdc_get_slot_and_msg_send(struct smc_connection *conn)
 
 again:
        link = conn->lnk;
+       if (!smc_wr_tx_link_hold(link))
+               return -ENOLINK;
        rc = smc_cdc_get_free_slot(conn, link, &wr_buf, NULL, &pend);
        if (rc)
-               return rc;
+               goto put_out;
 
        spin_lock_bh(&conn->send_lock);
        if (link != conn->lnk) {
@@ -160,6 +162,7 @@ again:
                spin_unlock_bh(&conn->send_lock);
                smc_wr_tx_put_slot(link,
                                   (struct smc_wr_tx_pend_priv *)pend);
+               smc_wr_tx_link_put(link);
                if (again)
                        return -ENOLINK;
                again = true;
@@ -167,6 +170,8 @@ again:
        }
        rc = smc_cdc_msg_send(conn, wr_buf, pend);
        spin_unlock_bh(&conn->send_lock);
+put_out:
+       smc_wr_tx_link_put(link);
        return rc;
 }
 
index 8280c93..d220674 100644 (file)
@@ -949,7 +949,7 @@ struct smc_link *smc_switch_conns(struct smc_link_group *lgr,
                to_lnk = &lgr->lnk[i];
                break;
        }
-       if (!to_lnk) {
+       if (!to_lnk || !smc_wr_tx_link_hold(to_lnk)) {
                smc_lgr_terminate_sched(lgr);
                return NULL;
        }
@@ -981,24 +981,26 @@ again:
                read_unlock_bh(&lgr->conns_lock);
                /* pre-fetch buffer outside of send_lock, might sleep */
                rc = smc_cdc_get_free_slot(conn, to_lnk, &wr_buf, NULL, &pend);
-               if (rc) {
-                       smcr_link_down_cond_sched(to_lnk);
-                       return NULL;
-               }
+               if (rc)
+                       goto err_out;
                /* avoid race with smcr_tx_sndbuf_nonempty() */
                spin_lock_bh(&conn->send_lock);
                smc_switch_link_and_count(conn, to_lnk);
                rc = smc_switch_cursor(smc, pend, wr_buf);
                spin_unlock_bh(&conn->send_lock);
                sock_put(&smc->sk);
-               if (rc) {
-                       smcr_link_down_cond_sched(to_lnk);
-                       return NULL;
-               }
+               if (rc)
+                       goto err_out;
                goto again;
        }
        read_unlock_bh(&lgr->conns_lock);
+       smc_wr_tx_link_put(to_lnk);
        return to_lnk;
+
+err_out:
+       smcr_link_down_cond_sched(to_lnk);
+       smc_wr_tx_link_put(to_lnk);
+       return NULL;
 }
 
 static void smcr_buf_unuse(struct smc_buf_desc *rmb_desc,
index 2e7560e..72f4b72 100644 (file)
@@ -383,9 +383,11 @@ int smc_llc_send_confirm_link(struct smc_link *link,
        struct smc_wr_buf *wr_buf;
        int rc;
 
+       if (!smc_wr_tx_link_hold(link))
+               return -ENOLINK;
        rc = smc_llc_add_pending_send(link, &wr_buf, &pend);
        if (rc)
-               return rc;
+               goto put_out;
        confllc = (struct smc_llc_msg_confirm_link *)wr_buf;
        memset(confllc, 0, sizeof(*confllc));
        confllc->hd.common.type = SMC_LLC_CONFIRM_LINK;
@@ -402,6 +404,8 @@ int smc_llc_send_confirm_link(struct smc_link *link,
        confllc->max_links = SMC_LLC_ADD_LNK_MAX_LINKS;
        /* send llc message */
        rc = smc_wr_tx_send(link, pend);
+put_out:
+       smc_wr_tx_link_put(link);
        return rc;
 }
 
@@ -415,9 +419,11 @@ static int smc_llc_send_confirm_rkey(struct smc_link *send_link,
        struct smc_link *link;
        int i, rc, rtok_ix;
 
+       if (!smc_wr_tx_link_hold(send_link))
+               return -ENOLINK;
        rc = smc_llc_add_pending_send(send_link, &wr_buf, &pend);
        if (rc)
-               return rc;
+               goto put_out;
        rkeyllc = (struct smc_llc_msg_confirm_rkey *)wr_buf;
        memset(rkeyllc, 0, sizeof(*rkeyllc));
        rkeyllc->hd.common.type = SMC_LLC_CONFIRM_RKEY;
@@ -444,6 +450,8 @@ static int smc_llc_send_confirm_rkey(struct smc_link *send_link,
                (u64)sg_dma_address(rmb_desc->sgt[send_link->link_idx].sgl));
        /* send llc message */
        rc = smc_wr_tx_send(send_link, pend);
+put_out:
+       smc_wr_tx_link_put(send_link);
        return rc;
 }
 
@@ -456,9 +464,11 @@ static int smc_llc_send_delete_rkey(struct smc_link *link,
        struct smc_wr_buf *wr_buf;
        int rc;
 
+       if (!smc_wr_tx_link_hold(link))
+               return -ENOLINK;
        rc = smc_llc_add_pending_send(link, &wr_buf, &pend);
        if (rc)
-               return rc;
+               goto put_out;
        rkeyllc = (struct smc_llc_msg_delete_rkey *)wr_buf;
        memset(rkeyllc, 0, sizeof(*rkeyllc));
        rkeyllc->hd.common.type = SMC_LLC_DELETE_RKEY;
@@ -467,6 +477,8 @@ static int smc_llc_send_delete_rkey(struct smc_link *link,
        rkeyllc->rkey[0] = htonl(rmb_desc->mr_rx[link->link_idx]->rkey);
        /* send llc message */
        rc = smc_wr_tx_send(link, pend);
+put_out:
+       smc_wr_tx_link_put(link);
        return rc;
 }
 
@@ -480,9 +492,11 @@ int smc_llc_send_add_link(struct smc_link *link, u8 mac[], u8 gid[],
        struct smc_wr_buf *wr_buf;
        int rc;
 
+       if (!smc_wr_tx_link_hold(link))
+               return -ENOLINK;
        rc = smc_llc_add_pending_send(link, &wr_buf, &pend);
        if (rc)
-               return rc;
+               goto put_out;
        addllc = (struct smc_llc_msg_add_link *)wr_buf;
 
        memset(addllc, 0, sizeof(*addllc));
@@ -504,6 +518,8 @@ int smc_llc_send_add_link(struct smc_link *link, u8 mac[], u8 gid[],
        }
        /* send llc message */
        rc = smc_wr_tx_send(link, pend);
+put_out:
+       smc_wr_tx_link_put(link);
        return rc;
 }
 
@@ -517,9 +533,11 @@ int smc_llc_send_delete_link(struct smc_link *link, u8 link_del_id,
        struct smc_wr_buf *wr_buf;
        int rc;
 
+       if (!smc_wr_tx_link_hold(link))
+               return -ENOLINK;
        rc = smc_llc_add_pending_send(link, &wr_buf, &pend);
        if (rc)
-               return rc;
+               goto put_out;
        delllc = (struct smc_llc_msg_del_link *)wr_buf;
 
        memset(delllc, 0, sizeof(*delllc));
@@ -536,6 +554,8 @@ int smc_llc_send_delete_link(struct smc_link *link, u8 link_del_id,
        delllc->reason = htonl(reason);
        /* send llc message */
        rc = smc_wr_tx_send(link, pend);
+put_out:
+       smc_wr_tx_link_put(link);
        return rc;
 }
 
@@ -547,9 +567,11 @@ static int smc_llc_send_test_link(struct smc_link *link, u8 user_data[16])
        struct smc_wr_buf *wr_buf;
        int rc;
 
+       if (!smc_wr_tx_link_hold(link))
+               return -ENOLINK;
        rc = smc_llc_add_pending_send(link, &wr_buf, &pend);
        if (rc)
-               return rc;
+               goto put_out;
        testllc = (struct smc_llc_msg_test_link *)wr_buf;
        memset(testllc, 0, sizeof(*testllc));
        testllc->hd.common.type = SMC_LLC_TEST_LINK;
@@ -557,6 +579,8 @@ static int smc_llc_send_test_link(struct smc_link *link, u8 user_data[16])
        memcpy(testllc->user_data, user_data, sizeof(testllc->user_data));
        /* send llc message */
        rc = smc_wr_tx_send(link, pend);
+put_out:
+       smc_wr_tx_link_put(link);
        return rc;
 }
 
@@ -567,13 +591,16 @@ static int smc_llc_send_message(struct smc_link *link, void *llcbuf)
        struct smc_wr_buf *wr_buf;
        int rc;
 
-       if (!smc_link_usable(link))
+       if (!smc_wr_tx_link_hold(link))
                return -ENOLINK;
        rc = smc_llc_add_pending_send(link, &wr_buf, &pend);
        if (rc)
-               return rc;
+               goto put_out;
        memcpy(wr_buf, llcbuf, sizeof(union smc_llc_msg));
-       return smc_wr_tx_send(link, pend);
+       rc = smc_wr_tx_send(link, pend);
+put_out:
+       smc_wr_tx_link_put(link);
+       return rc;
 }
 
 /* schedule an llc send on link, may wait for buffers,
@@ -586,13 +613,16 @@ static int smc_llc_send_message_wait(struct smc_link *link, void *llcbuf)
        struct smc_wr_buf *wr_buf;
        int rc;
 
-       if (!smc_link_usable(link))
+       if (!smc_wr_tx_link_hold(link))
                return -ENOLINK;
        rc = smc_llc_add_pending_send(link, &wr_buf, &pend);
        if (rc)
-               return rc;
+               goto put_out;
        memcpy(wr_buf, llcbuf, sizeof(union smc_llc_msg));
-       return smc_wr_tx_send_wait(link, pend, SMC_LLC_WAIT_TIME);
+       rc = smc_wr_tx_send_wait(link, pend, SMC_LLC_WAIT_TIME);
+put_out:
+       smc_wr_tx_link_put(link);
+       return rc;
 }
 
 /********************************* receive ***********************************/
@@ -672,9 +702,11 @@ static int smc_llc_add_link_cont(struct smc_link *link,
        struct smc_buf_desc *rmb;
        u8 n;
 
+       if (!smc_wr_tx_link_hold(link))
+               return -ENOLINK;
        rc = smc_llc_add_pending_send(link, &wr_buf, &pend);
        if (rc)
-               return rc;
+               goto put_out;
        addc_llc = (struct smc_llc_msg_add_link_cont *)wr_buf;
        memset(addc_llc, 0, sizeof(*addc_llc));
 
@@ -706,7 +738,10 @@ static int smc_llc_add_link_cont(struct smc_link *link,
        addc_llc->hd.length = sizeof(struct smc_llc_msg_add_link_cont);
        if (lgr->role == SMC_CLNT)
                addc_llc->hd.flags |= SMC_LLC_FLAG_RESP;
-       return smc_wr_tx_send(link, pend);
+       rc = smc_wr_tx_send(link, pend);
+put_out:
+       smc_wr_tx_link_put(link);
+       return rc;
 }
 
 static int smc_llc_cli_rkey_exchange(struct smc_link *link,
index c79361d..738a4a9 100644 (file)
@@ -496,7 +496,7 @@ static int smc_tx_rdma_writes(struct smc_connection *conn,
 /* Wakeup sndbuf consumers from any context (IRQ or process)
  * since there is more data to transmit; usable snd_wnd as max transmit
  */
-static int _smcr_tx_sndbuf_nonempty(struct smc_connection *conn)
+static int smcr_tx_sndbuf_nonempty(struct smc_connection *conn)
 {
        struct smc_cdc_producer_flags *pflags = &conn->local_tx_ctrl.prod_flags;
        struct smc_link *link = conn->lnk;
@@ -505,8 +505,11 @@ static int _smcr_tx_sndbuf_nonempty(struct smc_connection *conn)
        struct smc_wr_buf *wr_buf;
        int rc;
 
+       if (!link || !smc_wr_tx_link_hold(link))
+               return -ENOLINK;
        rc = smc_cdc_get_free_slot(conn, link, &wr_buf, &wr_rdma_buf, &pend);
        if (rc < 0) {
+               smc_wr_tx_link_put(link);
                if (rc == -EBUSY) {
                        struct smc_sock *smc =
                                container_of(conn, struct smc_sock, conn);
@@ -547,22 +550,7 @@ static int _smcr_tx_sndbuf_nonempty(struct smc_connection *conn)
 
 out_unlock:
        spin_unlock_bh(&conn->send_lock);
-       return rc;
-}
-
-static int smcr_tx_sndbuf_nonempty(struct smc_connection *conn)
-{
-       struct smc_link *link = conn->lnk;
-       int rc = -ENOLINK;
-
-       if (!link)
-               return rc;
-
-       atomic_inc(&link->wr_tx_refcnt);
-       if (smc_link_usable(link))
-               rc = _smcr_tx_sndbuf_nonempty(conn);
-       if (atomic_dec_and_test(&link->wr_tx_refcnt))
-               wake_up_all(&link->wr_tx_wait);
+       smc_wr_tx_link_put(link);
        return rc;
 }
 
index 423b870..2bc626f 100644 (file)
@@ -60,6 +60,20 @@ static inline void smc_wr_tx_set_wr_id(atomic_long_t *wr_tx_id, long val)
        atomic_long_set(wr_tx_id, val);
 }
 
+static inline bool smc_wr_tx_link_hold(struct smc_link *link)
+{
+       if (!smc_link_usable(link))
+               return false;
+       atomic_inc(&link->wr_tx_refcnt);
+       return true;
+}
+
+static inline void smc_wr_tx_link_put(struct smc_link *link)
+{
+       if (atomic_dec_and_test(&link->wr_tx_refcnt))
+               wake_up_all(&link->wr_tx_wait);
+}
+
 static inline void smc_wr_wakeup_tx_wait(struct smc_link *lnk)
 {
        wake_up_all(&lnk->wr_tx_wait);
index 3e776e3..1f28171 100644 (file)
@@ -645,7 +645,7 @@ static bool gss_check_seq_num(const struct svc_rqst *rqstp, struct rsc *rsci,
                }
                __set_bit(seq_num % GSS_SEQ_WIN, sd->sd_win);
                goto ok;
-       } else if (seq_num <= sd->sd_max - GSS_SEQ_WIN) {
+       } else if (seq_num + GSS_SEQ_WIN <= sd->sd_max) {
                goto toolow;
        }
        if (__test_and_set_bit(seq_num % GSS_SEQ_WIN, sd->sd_win))
index efac598..89f9e85 100644 (file)
@@ -828,7 +828,7 @@ static void unix_unhash(struct sock *sk)
 }
 
 struct proto unix_dgram_proto = {
-       .name                   = "UNIX-DGRAM",
+       .name                   = "UNIX",
        .owner                  = THIS_MODULE,
        .obj_size               = sizeof(struct unix_sock),
        .close                  = unix_close,
@@ -2882,6 +2882,9 @@ static int unix_shutdown(struct socket *sock, int mode)
 
        unix_state_lock(sk);
        sk->sk_shutdown |= mode;
+       if ((sk->sk_type == SOCK_STREAM || sk->sk_type == SOCK_SEQPACKET) &&
+           mode == SHUTDOWN_MASK)
+               sk->sk_state = TCP_CLOSE;
        other = unix_peer(sk);
        if (other)
                sock_hold(other);
@@ -2904,12 +2907,10 @@ static int unix_shutdown(struct socket *sock, int mode)
                other->sk_shutdown |= peer_mode;
                unix_state_unlock(other);
                other->sk_state_change(other);
-               if (peer_mode == SHUTDOWN_MASK) {
+               if (peer_mode == SHUTDOWN_MASK)
                        sk_wake_async(other, SOCK_WAKE_WAITD, POLL_HUP);
-                       other->sk_state = TCP_CLOSE;
-               } else if (peer_mode & RCV_SHUTDOWN) {
+               else if (peer_mode & RCV_SHUTDOWN)
                        sk_wake_async(other, SOCK_WAKE_WAITD, POLL_IN);
-               }
        }
        if (other)
                sock_put(other);
index 03b66d1..3a3cb09 100644 (file)
@@ -1961,24 +1961,65 @@ static struct sk_buff *xfrm_policy_netlink(struct sk_buff *in_skb,
        return skb;
 }
 
+static int xfrm_notify_userpolicy(struct net *net)
+{
+       struct xfrm_userpolicy_default *up;
+       int len = NLMSG_ALIGN(sizeof(*up));
+       struct nlmsghdr *nlh;
+       struct sk_buff *skb;
+       int err;
+
+       skb = nlmsg_new(len, GFP_ATOMIC);
+       if (skb == NULL)
+               return -ENOMEM;
+
+       nlh = nlmsg_put(skb, 0, 0, XFRM_MSG_GETDEFAULT, sizeof(*up), 0);
+       if (nlh == NULL) {
+               kfree_skb(skb);
+               return -EMSGSIZE;
+       }
+
+       up = nlmsg_data(nlh);
+       up->in = net->xfrm.policy_default & XFRM_POL_DEFAULT_IN ?
+                       XFRM_USERPOLICY_BLOCK : XFRM_USERPOLICY_ACCEPT;
+       up->fwd = net->xfrm.policy_default & XFRM_POL_DEFAULT_FWD ?
+                       XFRM_USERPOLICY_BLOCK : XFRM_USERPOLICY_ACCEPT;
+       up->out = net->xfrm.policy_default & XFRM_POL_DEFAULT_OUT ?
+                       XFRM_USERPOLICY_BLOCK : XFRM_USERPOLICY_ACCEPT;
+
+       nlmsg_end(skb, nlh);
+
+       rcu_read_lock();
+       err = xfrm_nlmsg_multicast(net, skb, 0, XFRMNLGRP_POLICY);
+       rcu_read_unlock();
+
+       return err;
+}
+
 static int xfrm_set_default(struct sk_buff *skb, struct nlmsghdr *nlh,
                            struct nlattr **attrs)
 {
        struct net *net = sock_net(skb->sk);
        struct xfrm_userpolicy_default *up = nlmsg_data(nlh);
-       u8 dirmask;
-       u8 old_default = net->xfrm.policy_default;
 
-       if (up->dirmask >= XFRM_USERPOLICY_DIRMASK_MAX)
-               return -EINVAL;
+       if (up->in == XFRM_USERPOLICY_BLOCK)
+               net->xfrm.policy_default |= XFRM_POL_DEFAULT_IN;
+       else if (up->in == XFRM_USERPOLICY_ACCEPT)
+               net->xfrm.policy_default &= ~XFRM_POL_DEFAULT_IN;
 
-       dirmask = (1 << up->dirmask) & XFRM_POL_DEFAULT_MASK;
+       if (up->fwd == XFRM_USERPOLICY_BLOCK)
+               net->xfrm.policy_default |= XFRM_POL_DEFAULT_FWD;
+       else if (up->fwd == XFRM_USERPOLICY_ACCEPT)
+               net->xfrm.policy_default &= ~XFRM_POL_DEFAULT_FWD;
 
-       net->xfrm.policy_default = (old_default & (0xff ^ dirmask))
-                                   | (up->action << up->dirmask);
+       if (up->out == XFRM_USERPOLICY_BLOCK)
+               net->xfrm.policy_default |= XFRM_POL_DEFAULT_OUT;
+       else if (up->out == XFRM_USERPOLICY_ACCEPT)
+               net->xfrm.policy_default &= ~XFRM_POL_DEFAULT_OUT;
 
        rt_genid_bump_all(net);
 
+       xfrm_notify_userpolicy(net);
        return 0;
 }
 
@@ -1988,13 +2029,11 @@ static int xfrm_get_default(struct sk_buff *skb, struct nlmsghdr *nlh,
        struct sk_buff *r_skb;
        struct nlmsghdr *r_nlh;
        struct net *net = sock_net(skb->sk);
-       struct xfrm_userpolicy_default *r_up, *up;
+       struct xfrm_userpolicy_default *r_up;
        int len = NLMSG_ALIGN(sizeof(struct xfrm_userpolicy_default));
        u32 portid = NETLINK_CB(skb).portid;
        u32 seq = nlh->nlmsg_seq;
 
-       up = nlmsg_data(nlh);
-
        r_skb = nlmsg_new(len, GFP_ATOMIC);
        if (!r_skb)
                return -ENOMEM;
@@ -2007,8 +2046,12 @@ static int xfrm_get_default(struct sk_buff *skb, struct nlmsghdr *nlh,
 
        r_up = nlmsg_data(r_nlh);
 
-       r_up->action = ((net->xfrm.policy_default & (1 << up->dirmask)) >> up->dirmask);
-       r_up->dirmask = up->dirmask;
+       r_up->in = net->xfrm.policy_default & XFRM_POL_DEFAULT_IN ?
+                       XFRM_USERPOLICY_BLOCK : XFRM_USERPOLICY_ACCEPT;
+       r_up->fwd = net->xfrm.policy_default & XFRM_POL_DEFAULT_FWD ?
+                       XFRM_USERPOLICY_BLOCK : XFRM_USERPOLICY_ACCEPT;
+       r_up->out = net->xfrm.policy_default & XFRM_POL_DEFAULT_OUT ?
+                       XFRM_USERPOLICY_BLOCK : XFRM_USERPOLICY_ACCEPT;
        nlmsg_end(r_skb, r_nlh);
 
        return nlmsg_unicast(net->xfrm.nlsk, r_skb, portid);
index 4dc20be..5fd48a8 100644 (file)
@@ -322,17 +322,11 @@ $(obj)/hbm_edt_kern.o: $(src)/hbm.h $(src)/hbm_kern.h
 
 -include $(BPF_SAMPLES_PATH)/Makefile.target
 
-VMLINUX_BTF_PATHS ?= $(if $(O),$(O)/vmlinux)                           \
-                    $(if $(KBUILD_OUTPUT),$(KBUILD_OUTPUT)/vmlinux)    \
-                    ../../../../vmlinux                                \
-                    /sys/kernel/btf/vmlinux                            \
-                    /boot/vmlinux-$(shell uname -r)
+VMLINUX_BTF_PATHS ?= $(abspath $(if $(O),$(O)/vmlinux))                                \
+                    $(abspath $(if $(KBUILD_OUTPUT),$(KBUILD_OUTPUT)/vmlinux)) \
+                    $(abspath ./vmlinux)
 VMLINUX_BTF ?= $(abspath $(firstword $(wildcard $(VMLINUX_BTF_PATHS))))
 
-ifeq ($(VMLINUX_BTF),)
-$(error Cannot find a vmlinux for VMLINUX_BTF at any of "$(VMLINUX_BTF_PATHS)")
-endif
-
 $(obj)/vmlinux.h: $(VMLINUX_BTF) $(BPFTOOL)
 ifeq ($(VMLINUX_H),)
        $(Q)$(BPFTOOL) btf dump file $(VMLINUX_BTF) format c > $@
@@ -340,6 +334,11 @@ else
        $(Q)cp "$(VMLINUX_H)" $@
 endif
 
+ifeq ($(VMLINUX_BTF),)
+       $(error Cannot find a vmlinux for VMLINUX_BTF at any of "$(VMLINUX_BTF_PATHS)",\
+               build the kernel or set VMLINUX_BTF variable)
+endif
+
 clean-files += vmlinux.h
 
 # Get Clang's default includes on this system, as opposed to those seen by
index aee0453..29c3bb6 100644 (file)
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: GPL-2.0 */
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
 /* eBPF instruction mini library */
 #ifndef __BPF_INSN_H
 #define __BPF_INSN_H
index 8f59d43..bb0a5a3 100644 (file)
@@ -5,11 +5,6 @@
 #include "xdp_sample.bpf.h"
 #include "xdp_sample_shared.h"
 
-enum {
-       BPF_F_BROADCAST         = (1ULL << 3),
-       BPF_F_EXCLUDE_INGRESS   = (1ULL << 4),
-};
-
 struct {
        __uint(type, BPF_MAP_TYPE_DEVMAP_HASH);
        __uint(key_size, sizeof(int));
index 952e468..4aad284 100644 (file)
@@ -19,6 +19,10 @@ gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_STRUCTLEAK_BYREF)              \
                += -fplugin-arg-structleak_plugin-byref
 gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_STRUCTLEAK_BYREF_ALL)    \
                += -fplugin-arg-structleak_plugin-byref-all
+ifdef CONFIG_GCC_PLUGIN_STRUCTLEAK
+    DISABLE_STRUCTLEAK_PLUGIN += -fplugin-arg-structleak_plugin-disable
+endif
+export DISABLE_STRUCTLEAK_PLUGIN
 gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_STRUCTLEAK)              \
                += -DSTRUCTLEAK_PLUGIN
 
index fd9777f..9dbab13 100755 (executable)
@@ -82,10 +82,8 @@ cat << EOF
 #define __IGNORE_truncate64
 #define __IGNORE_stat64
 #define __IGNORE_lstat64
-#define __IGNORE_fstat64
 #define __IGNORE_fcntl64
 #define __IGNORE_fadvise64_64
-#define __IGNORE_fstatat64
 #define __IGNORE_fstatfs64
 #define __IGNORE_statfs64
 #define __IGNORE_llseek
@@ -253,6 +251,10 @@ cat << EOF
 #define __IGNORE_getpmsg
 #define __IGNORE_putpmsg
 #define __IGNORE_vserver
+
+/* 64-bit ports never needed these, and new 32-bit ports can use statx */
+#define __IGNORE_fstat64
+#define __IGNORE_fstatat64
 EOF
 }
 
index 8f6b13a..7d631aa 100755 (executable)
@@ -189,7 +189,7 @@ if ($arch =~ /(x86(_64)?)|(i386)/) {
 $local_regex = "^[0-9a-fA-F]+\\s+t\\s+(\\S+)";
 $weak_regex = "^[0-9a-fA-F]+\\s+([wW])\\s+(\\S+)";
 $section_regex = "Disassembly of section\\s+(\\S+):";
-$function_regex = "^([0-9a-fA-F]+)\\s+<(.*?)>:";
+$function_regex = "^([0-9a-fA-F]+)\\s+<([^^]*?)>:";
 $mcount_regex = "^\\s*([0-9a-fA-F]+):.*\\s(mcount|__fentry__)\$";
 $section_type = '@progbits';
 $mcount_adjust = 0;
index d59276f..94ea2a8 100644 (file)
@@ -126,6 +126,8 @@ static const struct nlmsg_perm nlmsg_xfrm_perms[] =
        { XFRM_MSG_NEWSPDINFO,  NETLINK_XFRM_SOCKET__NLMSG_WRITE },
        { XFRM_MSG_GETSPDINFO,  NETLINK_XFRM_SOCKET__NLMSG_READ  },
        { XFRM_MSG_MAPPING,     NETLINK_XFRM_SOCKET__NLMSG_READ  },
+       { XFRM_MSG_SETDEFAULT,  NETLINK_XFRM_SOCKET__NLMSG_WRITE },
+       { XFRM_MSG_GETDEFAULT,  NETLINK_XFRM_SOCKET__NLMSG_READ  },
 };
 
 static const struct nlmsg_perm nlmsg_audit_perms[] =
@@ -189,7 +191,7 @@ int selinux_nlmsg_lookup(u16 sclass, u16 nlmsg_type, u32 *perm)
                 * structures at the top of this file with the new mappings
                 * before updating the BUILD_BUG_ON() macro!
                 */
-               BUILD_BUG_ON(XFRM_MSG_MAX != XFRM_MSG_MAPPING);
+               BUILD_BUG_ON(XFRM_MSG_MAX != XFRM_MSG_GETDEFAULT);
                err = nlmsg_perm(nlmsg_type, perm, nlmsg_xfrm_perms,
                                 sizeof(nlmsg_xfrm_perms));
                break;
index a59de24..dfe5a64 100644 (file)
@@ -468,6 +468,76 @@ static int snd_pcm_ioctl_sync_ptr_x32(struct snd_pcm_substream *substream,
 }
 #endif /* CONFIG_X86_X32 */
 
+#ifdef __BIG_ENDIAN
+typedef char __pad_before_u32[4];
+typedef char __pad_after_u32[0];
+#else
+typedef char __pad_before_u32[0];
+typedef char __pad_after_u32[4];
+#endif
+
+/* PCM 2.0.15 API definition had a bug in mmap control; it puts the avail_min
+ * at the wrong offset due to a typo in padding type.
+ * The bug hits only 32bit.
+ * A workaround for incorrect read/write is needed only in 32bit compat mode.
+ */
+struct __snd_pcm_mmap_control64_buggy {
+       __pad_before_u32 __pad1;
+       __u32 appl_ptr;
+       __pad_before_u32 __pad2;        /* SiC! here is the bug */
+       __pad_before_u32 __pad3;
+       __u32 avail_min;
+       __pad_after_uframe __pad4;
+};
+
+static int snd_pcm_ioctl_sync_ptr_buggy(struct snd_pcm_substream *substream,
+                                       struct snd_pcm_sync_ptr __user *_sync_ptr)
+{
+       struct snd_pcm_runtime *runtime = substream->runtime;
+       struct snd_pcm_sync_ptr sync_ptr;
+       struct __snd_pcm_mmap_control64_buggy *sync_cp;
+       volatile struct snd_pcm_mmap_status *status;
+       volatile struct snd_pcm_mmap_control *control;
+       int err;
+
+       memset(&sync_ptr, 0, sizeof(sync_ptr));
+       sync_cp = (struct __snd_pcm_mmap_control64_buggy *)&sync_ptr.c.control;
+       if (get_user(sync_ptr.flags, (unsigned __user *)&(_sync_ptr->flags)))
+               return -EFAULT;
+       if (copy_from_user(sync_cp, &(_sync_ptr->c.control), sizeof(*sync_cp)))
+               return -EFAULT;
+       status = runtime->status;
+       control = runtime->control;
+       if (sync_ptr.flags & SNDRV_PCM_SYNC_PTR_HWSYNC) {
+               err = snd_pcm_hwsync(substream);
+               if (err < 0)
+                       return err;
+       }
+       snd_pcm_stream_lock_irq(substream);
+       if (!(sync_ptr.flags & SNDRV_PCM_SYNC_PTR_APPL)) {
+               err = pcm_lib_apply_appl_ptr(substream, sync_cp->appl_ptr);
+               if (err < 0) {
+                       snd_pcm_stream_unlock_irq(substream);
+                       return err;
+               }
+       } else {
+               sync_cp->appl_ptr = control->appl_ptr;
+       }
+       if (!(sync_ptr.flags & SNDRV_PCM_SYNC_PTR_AVAIL_MIN))
+               control->avail_min = sync_cp->avail_min;
+       else
+               sync_cp->avail_min = control->avail_min;
+       sync_ptr.s.status.state = status->state;
+       sync_ptr.s.status.hw_ptr = status->hw_ptr;
+       sync_ptr.s.status.tstamp = status->tstamp;
+       sync_ptr.s.status.suspended_state = status->suspended_state;
+       sync_ptr.s.status.audio_tstamp = status->audio_tstamp;
+       snd_pcm_stream_unlock_irq(substream);
+       if (copy_to_user(_sync_ptr, &sync_ptr, sizeof(sync_ptr)))
+               return -EFAULT;
+       return 0;
+}
+
 /*
  */
 enum {
@@ -537,7 +607,7 @@ static long snd_pcm_ioctl_compat(struct file *file, unsigned int cmd, unsigned l
                if (in_x32_syscall())
                        return snd_pcm_ioctl_sync_ptr_x32(substream, argp);
 #endif /* CONFIG_X86_X32 */
-               return snd_pcm_common_ioctl(file, substream, cmd, argp);
+               return snd_pcm_ioctl_sync_ptr_buggy(substream, argp);
        case SNDRV_PCM_IOCTL_HW_REFINE32:
                return snd_pcm_ioctl_hw_params_compat(substream, 1, argp);
        case SNDRV_PCM_IOCTL_HW_PARAMS32:
index 382275c..7f3fd8e 100644 (file)
@@ -156,6 +156,8 @@ static int snd_seq_device_dev_free(struct snd_device *device)
        struct snd_seq_device *dev = device->device_data;
 
        cancel_autoload_drivers();
+       if (dev->private_free)
+               dev->private_free(dev);
        put_device(&dev->dev);
        return 0;
 }
@@ -183,11 +185,7 @@ static int snd_seq_device_dev_disconnect(struct snd_device *device)
 
 static void snd_seq_dev_release(struct device *dev)
 {
-       struct snd_seq_device *sdev = to_seq_dev(dev);
-
-       if (sdev->private_free)
-               sdev->private_free(sdev);
-       kfree(sdev);
+       kfree(to_seq_dev(dev));
 }
 
 /*
index 062da7a..f7bd6e2 100644 (file)
@@ -421,8 +421,9 @@ int snd_hdac_bus_reset_link(struct hdac_bus *bus, bool full_reset)
        if (!full_reset)
                goto skip_reset;
 
-       /* clear STATESTS */
-       snd_hdac_chip_writew(bus, STATESTS, STATESTS_INT_MASK);
+       /* clear STATESTS if not in reset */
+       if (snd_hdac_chip_readb(bus, GCTL) & AZX_GCTL_RESET)
+               snd_hdac_chip_writew(bus, STATESTS, STATESTS_INT_MASK);
 
        /* reset controller */
        snd_hdac_bus_enter_link_reset(bus);
index 2523b23..1c8bffc 100644 (file)
@@ -298,29 +298,31 @@ int snd_hda_codec_configure(struct hda_codec *codec)
 {
        int err;
 
+       if (codec->configured)
+               return 0;
+
        if (is_generic_config(codec))
                codec->probe_id = HDA_CODEC_ID_GENERIC;
        else
                codec->probe_id = 0;
 
-       err = snd_hdac_device_register(&codec->core);
-       if (err < 0)
-               return err;
+       if (!device_is_registered(&codec->core.dev)) {
+               err = snd_hdac_device_register(&codec->core);
+               if (err < 0)
+                       return err;
+       }
 
        if (!codec->preset)
                codec_bind_module(codec);
        if (!codec->preset) {
                err = codec_bind_generic(codec);
                if (err < 0) {
-                       codec_err(codec, "Unable to bind the codec\n");
-                       goto error;
+                       codec_dbg(codec, "Unable to bind the codec\n");
+                       return err;
                }
        }
 
+       codec->configured = 1;
        return 0;
-
- error:
-       snd_hdac_device_unregister(&codec->core);
-       return err;
 }
 EXPORT_SYMBOL_GPL(snd_hda_codec_configure);
index a9ebefd..0c4a337 100644 (file)
@@ -791,6 +791,7 @@ void snd_hda_codec_cleanup_for_unbind(struct hda_codec *codec)
        snd_array_free(&codec->nids);
        remove_conn_list(codec);
        snd_hdac_regmap_exit(&codec->core);
+       codec->configured = 0;
 }
 EXPORT_SYMBOL_GPL(snd_hda_codec_cleanup_for_unbind);
 
index 7cd4528..930ae40 100644 (file)
@@ -25,6 +25,7 @@
 #include <sound/core.h>
 #include <sound/initval.h>
 #include "hda_controller.h"
+#include "hda_local.h"
 
 #define CREATE_TRACE_POINTS
 #include "hda_controller_trace.h"
@@ -1248,17 +1249,24 @@ EXPORT_SYMBOL_GPL(azx_probe_codecs);
 int azx_codec_configure(struct azx *chip)
 {
        struct hda_codec *codec, *next;
+       int success = 0;
 
-       /* use _safe version here since snd_hda_codec_configure() deregisters
-        * the device upon error and deletes itself from the bus list.
-        */
-       list_for_each_codec_safe(codec, next, &chip->bus) {
-               snd_hda_codec_configure(codec);
+       list_for_each_codec(codec, &chip->bus) {
+               if (!snd_hda_codec_configure(codec))
+                       success++;
        }
 
-       if (!azx_bus(chip)->num_codecs)
-               return -ENODEV;
-       return 0;
+       if (success) {
+               /* unregister failed codecs if any codec has been probed */
+               list_for_each_codec_safe(codec, next, &chip->bus) {
+                       if (!codec->configured) {
+                               codec_err(codec, "Unable to configure, disabling\n");
+                               snd_hdac_device_unregister(&codec->core);
+                       }
+               }
+       }
+
+       return success ? 0 : -ENODEV;
 }
 EXPORT_SYMBOL_GPL(azx_codec_configure);
 
index 3062f87..f5bf295 100644 (file)
@@ -41,7 +41,7 @@
 /* 24 unused */
 #define AZX_DCAPS_COUNT_LPIB_DELAY  (1 << 25)  /* Take LPIB as delay */
 #define AZX_DCAPS_PM_RUNTIME   (1 << 26)       /* runtime PM support */
-/* 27 unused */
+#define AZX_DCAPS_RETRY_PROBE  (1 << 27)       /* retry probe if no codec is configured */
 #define AZX_DCAPS_CORBRP_SELF_CLEAR (1 << 28)  /* CORBRP clears itself after reset */
 #define AZX_DCAPS_NO_MSI64      (1 << 29)      /* Stick to 32-bit MSIs */
 #define AZX_DCAPS_SEPARATE_STREAM_TAG  (1 << 30) /* capture and playback use separate stream tag */
index 4777743..4d22e7a 100644 (file)
@@ -307,7 +307,8 @@ enum {
 /* quirks for AMD SB */
 #define AZX_DCAPS_PRESET_AMD_SB \
        (AZX_DCAPS_NO_TCSEL | AZX_DCAPS_AMD_WORKAROUND |\
-        AZX_DCAPS_SNOOP_TYPE(ATI) | AZX_DCAPS_PM_RUNTIME)
+        AZX_DCAPS_SNOOP_TYPE(ATI) | AZX_DCAPS_PM_RUNTIME |\
+        AZX_DCAPS_RETRY_PROBE)
 
 /* quirks for Nvidia */
 #define AZX_DCAPS_PRESET_NVIDIA \
@@ -1723,7 +1724,7 @@ static void azx_check_snoop_available(struct azx *chip)
 
 static void azx_probe_work(struct work_struct *work)
 {
-       struct hda_intel *hda = container_of(work, struct hda_intel, probe_work);
+       struct hda_intel *hda = container_of(work, struct hda_intel, probe_work.work);
        azx_probe_continue(&hda->chip);
 }
 
@@ -1828,7 +1829,7 @@ static int azx_create(struct snd_card *card, struct pci_dev *pci,
        }
 
        /* continue probing in work context as may trigger request module */
-       INIT_WORK(&hda->probe_work, azx_probe_work);
+       INIT_DELAYED_WORK(&hda->probe_work, azx_probe_work);
 
        *rchip = chip;
 
@@ -2142,7 +2143,7 @@ static int azx_probe(struct pci_dev *pci,
 #endif
 
        if (schedule_probe)
-               schedule_work(&hda->probe_work);
+               schedule_delayed_work(&hda->probe_work, 0);
 
        dev++;
        if (chip->disabled)
@@ -2228,6 +2229,11 @@ static int azx_probe_continue(struct azx *chip)
        int dev = chip->dev_index;
        int err;
 
+       if (chip->disabled || hda->init_failed)
+               return -EIO;
+       if (hda->probe_retry)
+               goto probe_retry;
+
        to_hda_bus(bus)->bus_probing = 1;
        hda->probe_continued = 1;
 
@@ -2289,10 +2295,20 @@ static int azx_probe_continue(struct azx *chip)
 #endif
        }
 #endif
+
+ probe_retry:
        if (bus->codec_mask && !(probe_only[dev] & 1)) {
                err = azx_codec_configure(chip);
-               if (err < 0)
+               if (err) {
+                       if ((chip->driver_caps & AZX_DCAPS_RETRY_PROBE) &&
+                           ++hda->probe_retry < 60) {
+                               schedule_delayed_work(&hda->probe_work,
+                                                     msecs_to_jiffies(1000));
+                               return 0; /* keep things up */
+                       }
+                       dev_err(chip->card->dev, "Cannot probe codecs, giving up\n");
                        goto out_free;
+               }
        }
 
        err = snd_card_register(chip->card);
@@ -2322,6 +2338,7 @@ out_free:
                display_power(chip, false);
        complete_all(&hda->probe_wait);
        to_hda_bus(bus)->bus_probing = 0;
+       hda->probe_retry = 0;
        return 0;
 }
 
@@ -2347,7 +2364,7 @@ static void azx_remove(struct pci_dev *pci)
                 * device during cancel_work_sync() call.
                 */
                device_unlock(&pci->dev);
-               cancel_work_sync(&hda->probe_work);
+               cancel_delayed_work_sync(&hda->probe_work);
                device_lock(&pci->dev);
 
                snd_card_free(card);
index 3fb119f..0f39418 100644 (file)
@@ -14,7 +14,7 @@ struct hda_intel {
 
        /* sync probing */
        struct completion probe_wait;
-       struct work_struct probe_work;
+       struct delayed_work probe_work;
 
        /* card list (for power_save trigger) */
        struct list_head list;
@@ -30,6 +30,8 @@ struct hda_intel {
        unsigned int freed:1; /* resources already released */
 
        bool need_i915_power:1; /* the hda controller needs i915 power */
+
+       int probe_retry;        /* being probe-retry */
 };
 
 #endif
index 4407f7d..22d27b1 100644 (file)
@@ -526,6 +526,8 @@ static void alc_shutup_pins(struct hda_codec *codec)
        struct alc_spec *spec = codec->spec;
 
        switch (codec->core.vendor_id) {
+       case 0x10ec0236:
+       case 0x10ec0256:
        case 0x10ec0283:
        case 0x10ec0286:
        case 0x10ec0288:
@@ -2537,7 +2539,8 @@ static const struct snd_pci_quirk alc882_fixup_tbl[] = {
        SND_PCI_QUIRK(0x1558, 0x67e1, "Clevo PB71[DE][CDF]", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
        SND_PCI_QUIRK(0x1558, 0x67e5, "Clevo PC70D[PRS](?:-D|-G)?", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
        SND_PCI_QUIRK(0x1558, 0x70d1, "Clevo PC70[ER][CDF]", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
-       SND_PCI_QUIRK(0x1558, 0x7714, "Clevo X170", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
+       SND_PCI_QUIRK(0x1558, 0x7714, "Clevo X170SM", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
+       SND_PCI_QUIRK(0x1558, 0x7715, "Clevo X170KM-G", ALC1220_FIXUP_CLEVO_PB51ED),
        SND_PCI_QUIRK(0x1558, 0x9501, "Clevo P950HR", ALC1220_FIXUP_CLEVO_P950),
        SND_PCI_QUIRK(0x1558, 0x9506, "Clevo P955HQ", ALC1220_FIXUP_CLEVO_P950),
        SND_PCI_QUIRK(0x1558, 0x950a, "Clevo P955H[PR]", ALC1220_FIXUP_CLEVO_P950),
@@ -3528,7 +3531,8 @@ static void alc256_shutup(struct hda_codec *codec)
        /* If disable 3k pulldown control for alc257, the Mic detection will not work correctly
         * when booting with headset plugged. So skip setting it for the codec alc257
         */
-       if (codec->core.vendor_id != 0x10ec0257)
+       if (spec->codec_variant != ALC269_TYPE_ALC257 &&
+           spec->codec_variant != ALC269_TYPE_ALC256)
                alc_update_coef_idx(codec, 0x46, 0, 3 << 12);
 
        if (!spec->no_shutup_pins)
@@ -6449,6 +6453,24 @@ static void alc287_fixup_legion_15imhg05_speakers(struct hda_codec *codec,
 /* for alc285_fixup_ideapad_s740_coef() */
 #include "ideapad_s740_helper.c"
 
+static void alc256_fixup_tongfang_reset_persistent_settings(struct hda_codec *codec,
+                                                           const struct hda_fixup *fix,
+                                                           int action)
+{
+       /*
+       * A certain other OS sets these coeffs to different values. On at least one TongFang
+       * barebone these settings might survive even a cold reboot. So to restore a clean slate the
+       * values are explicitly reset to default here. Without this, the external microphone is
+       * always in a plugged-in state, while the internal microphone is always in an unplugged
+       * state, breaking the ability to use the internal microphone.
+       */
+       alc_write_coef_idx(codec, 0x24, 0x0000);
+       alc_write_coef_idx(codec, 0x26, 0x0000);
+       alc_write_coef_idx(codec, 0x29, 0x3000);
+       alc_write_coef_idx(codec, 0x37, 0xfe05);
+       alc_write_coef_idx(codec, 0x45, 0x5089);
+}
+
 enum {
        ALC269_FIXUP_GPIO2,
        ALC269_FIXUP_SONY_VAIO,
@@ -6663,7 +6685,8 @@ enum {
        ALC287_FIXUP_LEGION_15IMHG05_SPEAKERS,
        ALC287_FIXUP_LEGION_15IMHG05_AUTOMUTE,
        ALC287_FIXUP_YOGA7_14ITL_SPEAKERS,
-       ALC287_FIXUP_13S_GEN2_SPEAKERS
+       ALC287_FIXUP_13S_GEN2_SPEAKERS,
+       ALC256_FIXUP_TONGFANG_RESET_PERSISTENT_SETTINGS,
 };
 
 static const struct hda_fixup alc269_fixups[] = {
@@ -8344,7 +8367,7 @@ static const struct hda_fixup alc269_fixups[] = {
                .v.verbs = (const struct hda_verb[]) {
                        { 0x20, AC_VERB_SET_COEF_INDEX, 0x24 },
                        { 0x20, AC_VERB_SET_PROC_COEF, 0x41 },
-                       { 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
+                       { 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
                        { 0x20, AC_VERB_SET_PROC_COEF, 0x2 },
                        { 0x20, AC_VERB_SET_PROC_COEF, 0x0 },
                        { 0x20, AC_VERB_SET_PROC_COEF, 0x0 },
@@ -8361,6 +8384,10 @@ static const struct hda_fixup alc269_fixups[] = {
                .chained = true,
                .chain_id = ALC269_FIXUP_HEADSET_MODE,
        },
+       [ALC256_FIXUP_TONGFANG_RESET_PERSISTENT_SETTINGS] = {
+               .type = HDA_FIXUP_FUNC,
+               .v.func = alc256_fixup_tongfang_reset_persistent_settings,
+       },
 };
 
 static const struct snd_pci_quirk alc269_fixup_tbl[] = {
@@ -8452,6 +8479,9 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
        SND_PCI_QUIRK(0x1028, 0x0a30, "Dell", ALC236_FIXUP_DELL_AIO_HEADSET_MIC),
        SND_PCI_QUIRK(0x1028, 0x0a58, "Dell", ALC255_FIXUP_DELL_HEADSET_MIC),
        SND_PCI_QUIRK(0x1028, 0x0a61, "Dell XPS 15 9510", ALC289_FIXUP_DUAL_SPK),
+       SND_PCI_QUIRK(0x1028, 0x0a62, "Dell Precision 5560", ALC289_FIXUP_DUAL_SPK),
+       SND_PCI_QUIRK(0x1028, 0x0a9d, "Dell Latitude 5430", ALC269_FIXUP_DELL4_MIC_NO_PRESENCE),
+       SND_PCI_QUIRK(0x1028, 0x0a9e, "Dell Latitude 5430", ALC269_FIXUP_DELL4_MIC_NO_PRESENCE),
        SND_PCI_QUIRK(0x1028, 0x164a, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
        SND_PCI_QUIRK(0x1028, 0x164b, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
        SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC2),
@@ -8789,6 +8819,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
        SND_PCI_QUIRK(0x1b7d, 0xa831, "Ordissimo EVE2 ", ALC269VB_FIXUP_ORDISSIMO_EVE2), /* Also known as Malata PC-B1303 */
        SND_PCI_QUIRK(0x1c06, 0x2013, "Lemote A1802", ALC269_FIXUP_LEMOTE_A1802),
        SND_PCI_QUIRK(0x1c06, 0x2015, "Lemote A190X", ALC269_FIXUP_LEMOTE_A190X),
+       SND_PCI_QUIRK(0x1d05, 0x1132, "TongFang PHxTxX1", ALC256_FIXUP_TONGFANG_RESET_PERSISTENT_SETTINGS),
        SND_PCI_QUIRK(0x1d72, 0x1602, "RedmiBook", ALC255_FIXUP_XIAOMI_HEADSET_MIC),
        SND_PCI_QUIRK(0x1d72, 0x1701, "XiaomiNotebook Pro", ALC298_FIXUP_DELL1_MIC_NO_PRESENCE),
        SND_PCI_QUIRK(0x1d72, 0x1901, "RedmiBook 14", ALC256_FIXUP_ASUS_HEADSET_MIC),
@@ -10166,6 +10197,9 @@ enum {
        ALC671_FIXUP_HP_HEADSET_MIC2,
        ALC662_FIXUP_ACER_X2660G_HEADSET_MODE,
        ALC662_FIXUP_ACER_NITRO_HEADSET_MODE,
+       ALC668_FIXUP_ASUS_NO_HEADSET_MIC,
+       ALC668_FIXUP_HEADSET_MIC,
+       ALC668_FIXUP_MIC_DET_COEF,
 };
 
 static const struct hda_fixup alc662_fixups[] = {
@@ -10549,6 +10583,29 @@ static const struct hda_fixup alc662_fixups[] = {
                .chained = true,
                .chain_id = ALC662_FIXUP_USI_FUNC
        },
+       [ALC668_FIXUP_ASUS_NO_HEADSET_MIC] = {
+               .type = HDA_FIXUP_PINS,
+               .v.pins = (const struct hda_pintbl[]) {
+                       { 0x1b, 0x04a1112c },
+                       { }
+               },
+               .chained = true,
+               .chain_id = ALC668_FIXUP_HEADSET_MIC
+       },
+       [ALC668_FIXUP_HEADSET_MIC] = {
+               .type = HDA_FIXUP_FUNC,
+               .v.func = alc269_fixup_headset_mic,
+               .chained = true,
+               .chain_id = ALC668_FIXUP_MIC_DET_COEF
+       },
+       [ALC668_FIXUP_MIC_DET_COEF] = {
+               .type = HDA_FIXUP_VERBS,
+               .v.verbs = (const struct hda_verb[]) {
+                       { 0x20, AC_VERB_SET_COEF_INDEX, 0x15 },
+                       { 0x20, AC_VERB_SET_PROC_COEF, 0x0d60 },
+                       {}
+               },
+       },
 };
 
 static const struct snd_pci_quirk alc662_fixup_tbl[] = {
@@ -10584,6 +10641,7 @@ static const struct snd_pci_quirk alc662_fixup_tbl[] = {
        SND_PCI_QUIRK(0x1043, 0x15a7, "ASUS UX51VZH", ALC662_FIXUP_BASS_16),
        SND_PCI_QUIRK(0x1043, 0x177d, "ASUS N551", ALC668_FIXUP_ASUS_Nx51),
        SND_PCI_QUIRK(0x1043, 0x17bd, "ASUS N751", ALC668_FIXUP_ASUS_Nx51),
+       SND_PCI_QUIRK(0x1043, 0x185d, "ASUS G551JW", ALC668_FIXUP_ASUS_NO_HEADSET_MIC),
        SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71SL", ALC662_FIXUP_ASUS_MODE8),
        SND_PCI_QUIRK(0x1043, 0x1b73, "ASUS N55SF", ALC662_FIXUP_BASS_16),
        SND_PCI_QUIRK(0x1043, 0x1bf3, "ASUS N76VZ", ALC662_FIXUP_BASS_MODE4_CHMAP),
index 3d5848d..53ebabf 100644 (file)
@@ -2450,6 +2450,8 @@ static int scarlett2_update_monitor_other(struct usb_mixer_interface *mixer)
                err = scarlett2_usb_get_config(mixer,
                                               SCARLETT2_CONFIG_TALKBACK_MAP,
                                               1, &bitmap);
+               if (err < 0)
+                       return err;
                for (i = 0; i < num_mixes; i++, bitmap >>= 1)
                        private->talkback_map[i] = bitmap & 1;
        }
index e03043f..de18fff 100644 (file)
 { USB_DEVICE_VENDOR_SPEC(0x041e, 0x3f19) },
 
 /*
+ * Creative Technology, Ltd Live! Cam Sync HD [VF0770]
+ * The device advertises 8 formats, but only a rate of 48kHz is honored by the
+ * hardware and 24 bits give chopped audio, so only report the one working
+ * combination.
+ */
+{
+       USB_DEVICE(0x041e, 0x4095),
+       .driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {
+               .ifnum = QUIRK_ANY_INTERFACE,
+               .type = QUIRK_COMPOSITE,
+               .data = &(const struct snd_usb_audio_quirk[]) {
+                       {
+                               .ifnum = 2,
+                               .type = QUIRK_AUDIO_STANDARD_MIXER,
+                       },
+                       {
+                               .ifnum = 3,
+                               .type = QUIRK_AUDIO_FIXED_ENDPOINT,
+                               .data = &(const struct audioformat) {
+                                       .formats = SNDRV_PCM_FMTBIT_S16_LE,
+                                       .channels = 2,
+                                       .fmt_bits = 16,
+                                       .iface = 3,
+                                       .altsetting = 4,
+                                       .altset_idx = 4,
+                                       .endpoint = 0x82,
+                                       .ep_attr = 0x05,
+                                       .rates = SNDRV_PCM_RATE_48000,
+                                       .rate_min = 48000,
+                                       .rate_max = 48000,
+                                       .nr_rates = 1,
+                                       .rate_table = (unsigned int[]) { 48000 },
+                               },
+                       },
+                       {
+                               .ifnum = -1
+                       },
+               },
+       },
+},
+
+/*
  * HP Wireless Audio
  * When not ignored, causes instability issues for some users, forcing them to
  * skip the entire module.
index 6ee6d24..889c855 100644 (file)
@@ -1900,6 +1900,8 @@ static const struct usb_audio_quirk_flags_table quirk_flags_table[] = {
                   QUIRK_FLAG_CTL_MSG_DELAY | QUIRK_FLAG_IFACE_DELAY),
        VENDOR_FLG(0x07fd, /* MOTU */
                   QUIRK_FLAG_VALIDATE_RATES),
+       VENDOR_FLG(0x1235, /* Focusrite Novation */
+                  QUIRK_FLAG_VALIDATE_RATES),
        VENDOR_FLG(0x152a, /* Thesycon devices */
                   QUIRK_FLAG_DSD_RAW),
        VENDOR_FLG(0x1de7, /* Phoenix Audio */
index 1d84ec9..5859ca0 100644 (file)
@@ -784,6 +784,7 @@ struct snd_rawmidi_status {
 
 #define SNDRV_RAWMIDI_IOCTL_PVERSION   _IOR('W', 0x00, int)
 #define SNDRV_RAWMIDI_IOCTL_INFO       _IOR('W', 0x01, struct snd_rawmidi_info)
+#define SNDRV_RAWMIDI_IOCTL_USER_PVERSION _IOW('W', 0x02, int)
 #define SNDRV_RAWMIDI_IOCTL_PARAMS     _IOWR('W', 0x10, struct snd_rawmidi_params)
 #define SNDRV_RAWMIDI_IOCTL_STATUS     _IOWR('W', 0x20, struct snd_rawmidi_status)
 #define SNDRV_RAWMIDI_IOCTL_DROP       _IOW('W', 0x30, int)
index 88d8825..e4f83c3 100644 (file)
@@ -6894,7 +6894,8 @@ int bpf_object__load_xattr(struct bpf_object_load_attr *attr)
 
        if (obj->gen_loader) {
                /* reset FDs */
-               btf__set_fd(obj->btf, -1);
+               if (obj->btf)
+                       btf__set_fd(obj->btf, -1);
                for (i = 0; i < obj->nr_maps; i++)
                        obj->maps[i].fd = -1;
                if (!err)
index 1fb8b49..ea65531 100644 (file)
@@ -88,6 +88,7 @@ void strset__free(struct strset *set)
 
        hashmap__free(set->strs_hash);
        free(set->strs_data);
+       free(set);
 }
 
 size_t strset__data_size(const struct strset *set)
index c67c833..ce91a58 100644 (file)
@@ -40,7 +40,7 @@ static int test_stat_cpu(void)
                .type   = PERF_TYPE_SOFTWARE,
                .config = PERF_COUNT_SW_TASK_CLOCK,
        };
-       int err, cpu, tmp;
+       int err, idx;
 
        cpus = perf_cpu_map__new(NULL);
        __T("failed to create cpus", cpus);
@@ -70,10 +70,10 @@ static int test_stat_cpu(void)
        perf_evlist__for_each_evsel(evlist, evsel) {
                cpus = perf_evsel__cpus(evsel);
 
-               perf_cpu_map__for_each_cpu(cpu, tmp, cpus) {
+               for (idx = 0; idx < perf_cpu_map__nr(cpus); idx++) {
                        struct perf_counts_values counts = { .val = 0 };
 
-                       perf_evsel__read(evsel, cpu, 0, &counts);
+                       perf_evsel__read(evsel, idx, 0, &counts);
                        __T("failed to read value for evsel", counts.val != 0);
                }
        }
index a184e48..33ae933 100644 (file)
@@ -22,7 +22,7 @@ static int test_stat_cpu(void)
                .type   = PERF_TYPE_SOFTWARE,
                .config = PERF_COUNT_SW_CPU_CLOCK,
        };
-       int err, cpu, tmp;
+       int err, idx;
 
        cpus = perf_cpu_map__new(NULL);
        __T("failed to create cpus", cpus);
@@ -33,10 +33,10 @@ static int test_stat_cpu(void)
        err = perf_evsel__open(evsel, cpus, NULL);
        __T("failed to open evsel", err == 0);
 
-       perf_cpu_map__for_each_cpu(cpu, tmp, cpus) {
+       for (idx = 0; idx < perf_cpu_map__nr(cpus); idx++) {
                struct perf_counts_values counts = { .val = 0 };
 
-               perf_evsel__read(evsel, cpu, 0, &counts);
+               perf_evsel__read(evsel, idx, 0, &counts);
                __T("failed to read value for evsel", counts.val != 0);
        }
 
@@ -148,6 +148,7 @@ static int test_stat_user_read(int event)
        __T("failed to mmap evsel", err == 0);
 
        pc = perf_evsel__mmap_base(evsel, 0, 0);
+       __T("failed to get mmapped address", pc);
 
 #if defined(__i386__) || defined(__x86_64__)
        __T("userspace counter access not supported", pc->cap_user_rdpmc);
index 4461804..14e3e8d 100644 (file)
@@ -143,7 +143,7 @@ FEATURE_CHECK_LDFLAGS-libcrypto = -lcrypto
 ifdef CSINCLUDES
   LIBOPENCSD_CFLAGS := -I$(CSINCLUDES)
 endif
-OPENCSDLIBS := -lopencsd_c_api -lopencsd
+OPENCSDLIBS := -lopencsd_c_api -lopencsd -lstdc++
 ifdef CSLIBS
   LIBOPENCSD_LDFLAGS := -L$(CSLIBS)
 endif
index e04313c..5cd7020 100644 (file)
@@ -802,7 +802,7 @@ endif
 
 $(patsubst perf-%,%.o,$(PROGRAMS)): $(wildcard */*.h)
 
-LIBTRACEEVENT_FLAGS += plugin_dir=$(plugindir_SQ) 'EXTRA_CFLAGS=$(EXTRA_CFLAGS)' 'LDFLAGS=$(LDFLAGS)'
+LIBTRACEEVENT_FLAGS += plugin_dir=$(plugindir_SQ) 'EXTRA_CFLAGS=$(EXTRA_CFLAGS)' 'LDFLAGS=$(filter-out -static,$(LDFLAGS))'
 
 $(LIBTRACEEVENT): FORCE
        $(Q)$(MAKE) -C $(TRACE_EVENT_DIR) $(LIBTRACEEVENT_FLAGS) O=$(OUTPUT) $(OUTPUT)libtraceevent.a
index 6731b3c..7c887d3 100644 (file)
@@ -1285,6 +1285,7 @@ int main(int argc, char *argv[])
        }
 
        free_arch_std_events();
+       free_sys_event_tables();
        free(mapfile);
        return 0;
 
@@ -1306,6 +1307,7 @@ err_close_eventsfp:
                create_empty_mapping(output_file);
 err_out:
        free_arch_std_events();
+       free_sys_event_tables();
        free(mapfile);
        return ret;
 }
index d9e99b3..d8ea6a8 100644 (file)
@@ -68,3 +68,100 @@ fd=10
 type=0
 config=5
 optional=1
+
+# PERF_TYPE_RAW / slots (0x400)
+[event11:base-stat]
+fd=11
+group_fd=-1
+type=4
+config=1024
+read_format=15
+optional=1
+
+# PERF_TYPE_RAW / topdown-retiring (0x8000)
+[event12:base-stat]
+fd=12
+group_fd=11
+type=4
+config=32768
+disabled=0
+enable_on_exec=0
+read_format=15
+optional=1
+
+# PERF_TYPE_RAW / topdown-bad-spec (0x8100)
+[event13:base-stat]
+fd=13
+group_fd=11
+type=4
+config=33024
+disabled=0
+enable_on_exec=0
+read_format=15
+optional=1
+
+# PERF_TYPE_RAW / topdown-fe-bound (0x8200)
+[event14:base-stat]
+fd=14
+group_fd=11
+type=4
+config=33280
+disabled=0
+enable_on_exec=0
+read_format=15
+optional=1
+
+# PERF_TYPE_RAW / topdown-be-bound (0x8300)
+[event15:base-stat]
+fd=15
+group_fd=11
+type=4
+config=33536
+disabled=0
+enable_on_exec=0
+read_format=15
+optional=1
+
+# PERF_TYPE_RAW / topdown-heavy-ops (0x8400)
+[event16:base-stat]
+fd=16
+group_fd=11
+type=4
+config=33792
+disabled=0
+enable_on_exec=0
+read_format=15
+optional=1
+
+# PERF_TYPE_RAW / topdown-br-mispredict (0x8500)
+[event17:base-stat]
+fd=17
+group_fd=11
+type=4
+config=34048
+disabled=0
+enable_on_exec=0
+read_format=15
+optional=1
+
+# PERF_TYPE_RAW / topdown-fetch-lat (0x8600)
+[event18:base-stat]
+fd=18
+group_fd=11
+type=4
+config=34304
+disabled=0
+enable_on_exec=0
+read_format=15
+optional=1
+
+# PERF_TYPE_RAW / topdown-mem-bound (0x8700)
+[event19:base-stat]
+fd=19
+group_fd=11
+type=4
+config=34560
+disabled=0
+enable_on_exec=0
+read_format=15
+optional=1
index 8b04a05..b656ab9 100644 (file)
@@ -70,12 +70,109 @@ type=0
 config=5
 optional=1
 
+# PERF_TYPE_RAW / slots (0x400)
+[event11:base-stat]
+fd=11
+group_fd=-1
+type=4
+config=1024
+read_format=15
+optional=1
+
+# PERF_TYPE_RAW / topdown-retiring (0x8000)
+[event12:base-stat]
+fd=12
+group_fd=11
+type=4
+config=32768
+disabled=0
+enable_on_exec=0
+read_format=15
+optional=1
+
+# PERF_TYPE_RAW / topdown-bad-spec (0x8100)
+[event13:base-stat]
+fd=13
+group_fd=11
+type=4
+config=33024
+disabled=0
+enable_on_exec=0
+read_format=15
+optional=1
+
+# PERF_TYPE_RAW / topdown-fe-bound (0x8200)
+[event14:base-stat]
+fd=14
+group_fd=11
+type=4
+config=33280
+disabled=0
+enable_on_exec=0
+read_format=15
+optional=1
+
+# PERF_TYPE_RAW / topdown-be-bound (0x8300)
+[event15:base-stat]
+fd=15
+group_fd=11
+type=4
+config=33536
+disabled=0
+enable_on_exec=0
+read_format=15
+optional=1
+
+# PERF_TYPE_RAW / topdown-heavy-ops (0x8400)
+[event16:base-stat]
+fd=16
+group_fd=11
+type=4
+config=33792
+disabled=0
+enable_on_exec=0
+read_format=15
+optional=1
+
+# PERF_TYPE_RAW / topdown-br-mispredict (0x8500)
+[event17:base-stat]
+fd=17
+group_fd=11
+type=4
+config=34048
+disabled=0
+enable_on_exec=0
+read_format=15
+optional=1
+
+# PERF_TYPE_RAW / topdown-fetch-lat (0x8600)
+[event18:base-stat]
+fd=18
+group_fd=11
+type=4
+config=34304
+disabled=0
+enable_on_exec=0
+read_format=15
+optional=1
+
+# PERF_TYPE_RAW / topdown-mem-bound (0x8700)
+[event19:base-stat]
+fd=19
+group_fd=11
+type=4
+config=34560
+disabled=0
+enable_on_exec=0
+read_format=15
+optional=1
+
 # PERF_TYPE_HW_CACHE /
 #  PERF_COUNT_HW_CACHE_L1D                <<  0  |
 # (PERF_COUNT_HW_CACHE_OP_READ            <<  8) |
 # (PERF_COUNT_HW_CACHE_RESULT_ACCESS      << 16)
-[event11:base-stat]
-fd=11
+[event20:base-stat]
+fd=20
 type=3
 config=0
 optional=1
@@ -84,8 +181,8 @@ optional=1
 #  PERF_COUNT_HW_CACHE_L1D                <<  0  |
 # (PERF_COUNT_HW_CACHE_OP_READ            <<  8) |
 # (PERF_COUNT_HW_CACHE_RESULT_MISS        << 16)
-[event12:base-stat]
-fd=12
+[event21:base-stat]
+fd=21
 type=3
 config=65536
 optional=1
@@ -94,8 +191,8 @@ optional=1
 #  PERF_COUNT_HW_CACHE_LL                 <<  0  |
 # (PERF_COUNT_HW_CACHE_OP_READ            <<  8) |
 # (PERF_COUNT_HW_CACHE_RESULT_ACCESS      << 16)
-[event13:base-stat]
-fd=13
+[event22:base-stat]
+fd=22
 type=3
 config=2
 optional=1
@@ -104,8 +201,8 @@ optional=1
 #  PERF_COUNT_HW_CACHE_LL                 <<  0  |
 # (PERF_COUNT_HW_CACHE_OP_READ            <<  8) |
 # (PERF_COUNT_HW_CACHE_RESULT_MISS        << 16)
-[event14:base-stat]
-fd=14
+[event23:base-stat]
+fd=23
 type=3
 config=65538
 optional=1
index 4fca9f1..9762509 100644 (file)
@@ -70,12 +70,109 @@ type=0
 config=5
 optional=1
 
+# PERF_TYPE_RAW / slots (0x400)
+[event11:base-stat]
+fd=11
+group_fd=-1
+type=4
+config=1024
+read_format=15
+optional=1
+
+# PERF_TYPE_RAW / topdown-retiring (0x8000)
+[event12:base-stat]
+fd=12
+group_fd=11
+type=4
+config=32768
+disabled=0
+enable_on_exec=0
+read_format=15
+optional=1
+
+# PERF_TYPE_RAW / topdown-bad-spec (0x8100)
+[event13:base-stat]
+fd=13
+group_fd=11
+type=4
+config=33024
+disabled=0
+enable_on_exec=0
+read_format=15
+optional=1
+
+# PERF_TYPE_RAW / topdown-fe-bound (0x8200)
+[event14:base-stat]
+fd=14
+group_fd=11
+type=4
+config=33280
+disabled=0
+enable_on_exec=0
+read_format=15
+optional=1
+
+# PERF_TYPE_RAW / topdown-be-bound (0x8300)
+[event15:base-stat]
+fd=15
+group_fd=11
+type=4
+config=33536
+disabled=0
+enable_on_exec=0
+read_format=15
+optional=1
+
+# PERF_TYPE_RAW / topdown-heavy-ops (0x8400)
+[event16:base-stat]
+fd=16
+group_fd=11
+type=4
+config=33792
+disabled=0
+enable_on_exec=0
+read_format=15
+optional=1
+
+# PERF_TYPE_RAW / topdown-br-mispredict (0x8500)
+[event17:base-stat]
+fd=17
+group_fd=11
+type=4
+config=34048
+disabled=0
+enable_on_exec=0
+read_format=15
+optional=1
+
+# PERF_TYPE_RAW / topdown-fetch-lat (0x8600)
+[event18:base-stat]
+fd=18
+group_fd=11
+type=4
+config=34304
+disabled=0
+enable_on_exec=0
+read_format=15
+optional=1
+
+# PERF_TYPE_RAW / topdown-mem-bound (0x8700)
+[event19:base-stat]
+fd=19
+group_fd=11
+type=4
+config=34560
+disabled=0
+enable_on_exec=0
+read_format=15
+optional=1
+
 # PERF_TYPE_HW_CACHE /
 #  PERF_COUNT_HW_CACHE_L1D                <<  0  |
 # (PERF_COUNT_HW_CACHE_OP_READ            <<  8) |
 # (PERF_COUNT_HW_CACHE_RESULT_ACCESS      << 16)
-[event11:base-stat]
-fd=11
+[event20:base-stat]
+fd=20
 type=3
 config=0
 optional=1
@@ -84,8 +181,8 @@ optional=1
 #  PERF_COUNT_HW_CACHE_L1D                <<  0  |
 # (PERF_COUNT_HW_CACHE_OP_READ            <<  8) |
 # (PERF_COUNT_HW_CACHE_RESULT_MISS        << 16)
-[event12:base-stat]
-fd=12
+[event21:base-stat]
+fd=21
 type=3
 config=65536
 optional=1
@@ -94,8 +191,8 @@ optional=1
 #  PERF_COUNT_HW_CACHE_LL                 <<  0  |
 # (PERF_COUNT_HW_CACHE_OP_READ            <<  8) |
 # (PERF_COUNT_HW_CACHE_RESULT_ACCESS      << 16)
-[event13:base-stat]
-fd=13
+[event22:base-stat]
+fd=22
 type=3
 config=2
 optional=1
@@ -104,8 +201,8 @@ optional=1
 #  PERF_COUNT_HW_CACHE_LL                 <<  0  |
 # (PERF_COUNT_HW_CACHE_OP_READ            <<  8) |
 # (PERF_COUNT_HW_CACHE_RESULT_MISS        << 16)
-[event14:base-stat]
-fd=14
+[event23:base-stat]
+fd=23
 type=3
 config=65538
 optional=1
@@ -114,8 +211,8 @@ optional=1
 #  PERF_COUNT_HW_CACHE_L1I                <<  0  |
 # (PERF_COUNT_HW_CACHE_OP_READ            <<  8) |
 # (PERF_COUNT_HW_CACHE_RESULT_ACCESS      << 16)
-[event15:base-stat]
-fd=15
+[event24:base-stat]
+fd=24
 type=3
 config=1
 optional=1
@@ -124,8 +221,8 @@ optional=1
 #  PERF_COUNT_HW_CACHE_L1I                <<  0  |
 # (PERF_COUNT_HW_CACHE_OP_READ            <<  8) |
 # (PERF_COUNT_HW_CACHE_RESULT_MISS        << 16)
-[event16:base-stat]
-fd=16
+[event25:base-stat]
+fd=25
 type=3
 config=65537
 optional=1
@@ -134,8 +231,8 @@ optional=1
 #  PERF_COUNT_HW_CACHE_DTLB               <<  0  |
 # (PERF_COUNT_HW_CACHE_OP_READ            <<  8) |
 # (PERF_COUNT_HW_CACHE_RESULT_ACCESS      << 16)
-[event17:base-stat]
-fd=17
+[event26:base-stat]
+fd=26
 type=3
 config=3
 optional=1
@@ -144,8 +241,8 @@ optional=1
 #  PERF_COUNT_HW_CACHE_DTLB               <<  0  |
 # (PERF_COUNT_HW_CACHE_OP_READ            <<  8) |
 # (PERF_COUNT_HW_CACHE_RESULT_MISS        << 16)
-[event18:base-stat]
-fd=18
+[event27:base-stat]
+fd=27
 type=3
 config=65539
 optional=1
@@ -154,8 +251,8 @@ optional=1
 #  PERF_COUNT_HW_CACHE_ITLB               <<  0  |
 # (PERF_COUNT_HW_CACHE_OP_READ            <<  8) |
 # (PERF_COUNT_HW_CACHE_RESULT_ACCESS      << 16)
-[event19:base-stat]
-fd=19
+[event28:base-stat]
+fd=28
 type=3
 config=4
 optional=1
@@ -164,8 +261,8 @@ optional=1
 #  PERF_COUNT_HW_CACHE_ITLB               <<  0  |
 # (PERF_COUNT_HW_CACHE_OP_READ            <<  8) |
 # (PERF_COUNT_HW_CACHE_RESULT_MISS        << 16)
-[event20:base-stat]
-fd=20
+[event29:base-stat]
+fd=29
 type=3
 config=65540
 optional=1
index 4bb58e1..d555042 100644 (file)
@@ -70,12 +70,109 @@ type=0
 config=5
 optional=1
 
+# PERF_TYPE_RAW / slots (0x400)
+[event11:base-stat]
+fd=11
+group_fd=-1
+type=4
+config=1024
+read_format=15
+optional=1
+
+# PERF_TYPE_RAW / topdown-retiring (0x8000)
+[event12:base-stat]
+fd=12
+group_fd=11
+type=4
+config=32768
+disabled=0
+enable_on_exec=0
+read_format=15
+optional=1
+
+# PERF_TYPE_RAW / topdown-bad-spec (0x8100)
+[event13:base-stat]
+fd=13
+group_fd=11
+type=4
+config=33024
+disabled=0
+enable_on_exec=0
+read_format=15
+optional=1
+
+# PERF_TYPE_RAW / topdown-fe-bound (0x8200)
+[event14:base-stat]
+fd=14
+group_fd=11
+type=4
+config=33280
+disabled=0
+enable_on_exec=0
+read_format=15
+optional=1
+
+# PERF_TYPE_RAW / topdown-be-bound (0x8300)
+[event15:base-stat]
+fd=15
+group_fd=11
+type=4
+config=33536
+disabled=0
+enable_on_exec=0
+read_format=15
+optional=1
+
+# PERF_TYPE_RAW / topdown-heavy-ops (0x8400)
+[event16:base-stat]
+fd=16
+group_fd=11
+type=4
+config=33792
+disabled=0
+enable_on_exec=0
+read_format=15
+optional=1
+
+# PERF_TYPE_RAW / topdown-br-mispredict (0x8500)
+[event17:base-stat]
+fd=17
+group_fd=11
+type=4
+config=34048
+disabled=0
+enable_on_exec=0
+read_format=15
+optional=1
+
+# PERF_TYPE_RAW / topdown-fetch-lat (0x8600)
+[event18:base-stat]
+fd=18
+group_fd=11
+type=4
+config=34304
+disabled=0
+enable_on_exec=0
+read_format=15
+optional=1
+
+# PERF_TYPE_RAW / topdown-mem-bound (0x8700)
+[event19:base-stat]
+fd=19
+group_fd=11
+type=4
+config=34560
+disabled=0
+enable_on_exec=0
+read_format=15
+optional=1
+
 # PERF_TYPE_HW_CACHE /
 #  PERF_COUNT_HW_CACHE_L1D                <<  0  |
 # (PERF_COUNT_HW_CACHE_OP_READ            <<  8) |
 # (PERF_COUNT_HW_CACHE_RESULT_ACCESS      << 16)
-[event11:base-stat]
-fd=11
+[event20:base-stat]
+fd=20
 type=3
 config=0
 optional=1
@@ -84,8 +181,8 @@ optional=1
 #  PERF_COUNT_HW_CACHE_L1D                <<  0  |
 # (PERF_COUNT_HW_CACHE_OP_READ            <<  8) |
 # (PERF_COUNT_HW_CACHE_RESULT_MISS        << 16)
-[event12:base-stat]
-fd=12
+[event21:base-stat]
+fd=21
 type=3
 config=65536
 optional=1
@@ -94,8 +191,8 @@ optional=1
 #  PERF_COUNT_HW_CACHE_LL                 <<  0  |
 # (PERF_COUNT_HW_CACHE_OP_READ            <<  8) |
 # (PERF_COUNT_HW_CACHE_RESULT_ACCESS      << 16)
-[event13:base-stat]
-fd=13
+[event22:base-stat]
+fd=22
 type=3
 config=2
 optional=1
@@ -104,8 +201,8 @@ optional=1
 #  PERF_COUNT_HW_CACHE_LL                 <<  0  |
 # (PERF_COUNT_HW_CACHE_OP_READ            <<  8) |
 # (PERF_COUNT_HW_CACHE_RESULT_MISS        << 16)
-[event14:base-stat]
-fd=14
+[event23:base-stat]
+fd=23
 type=3
 config=65538
 optional=1
@@ -114,8 +211,8 @@ optional=1
 #  PERF_COUNT_HW_CACHE_L1I                <<  0  |
 # (PERF_COUNT_HW_CACHE_OP_READ            <<  8) |
 # (PERF_COUNT_HW_CACHE_RESULT_ACCESS      << 16)
-[event15:base-stat]
-fd=15
+[event24:base-stat]
+fd=24
 type=3
 config=1
 optional=1
@@ -124,8 +221,8 @@ optional=1
 #  PERF_COUNT_HW_CACHE_L1I                <<  0  |
 # (PERF_COUNT_HW_CACHE_OP_READ            <<  8) |
 # (PERF_COUNT_HW_CACHE_RESULT_MISS        << 16)
-[event16:base-stat]
-fd=16
+[event25:base-stat]
+fd=25
 type=3
 config=65537
 optional=1
@@ -134,8 +231,8 @@ optional=1
 #  PERF_COUNT_HW_CACHE_DTLB               <<  0  |
 # (PERF_COUNT_HW_CACHE_OP_READ            <<  8) |
 # (PERF_COUNT_HW_CACHE_RESULT_ACCESS      << 16)
-[event17:base-stat]
-fd=17
+[event26:base-stat]
+fd=26
 type=3
 config=3
 optional=1
@@ -144,8 +241,8 @@ optional=1
 #  PERF_COUNT_HW_CACHE_DTLB               <<  0  |
 # (PERF_COUNT_HW_CACHE_OP_READ            <<  8) |
 # (PERF_COUNT_HW_CACHE_RESULT_MISS        << 16)
-[event18:base-stat]
-fd=18
+[event27:base-stat]
+fd=27
 type=3
 config=65539
 optional=1
@@ -154,8 +251,8 @@ optional=1
 #  PERF_COUNT_HW_CACHE_ITLB               <<  0  |
 # (PERF_COUNT_HW_CACHE_OP_READ            <<  8) |
 # (PERF_COUNT_HW_CACHE_RESULT_ACCESS      << 16)
-[event19:base-stat]
-fd=19
+[event28:base-stat]
+fd=28
 type=3
 config=4
 optional=1
@@ -164,8 +261,8 @@ optional=1
 #  PERF_COUNT_HW_CACHE_ITLB               <<  0  |
 # (PERF_COUNT_HW_CACHE_OP_READ            <<  8) |
 # (PERF_COUNT_HW_CACHE_RESULT_MISS        << 16)
-[event20:base-stat]
-fd=20
+[event29:base-stat]
+fd=29
 type=3
 config=65540
 optional=1
@@ -174,8 +271,8 @@ optional=1
 #  PERF_COUNT_HW_CACHE_L1D                <<  0  |
 # (PERF_COUNT_HW_CACHE_OP_PREFETCH        <<  8) |
 # (PERF_COUNT_HW_CACHE_RESULT_ACCESS      << 16)
-[event21:base-stat]
-fd=21
+[event30:base-stat]
+fd=30
 type=3
 config=512
 optional=1
@@ -184,8 +281,8 @@ optional=1
 #  PERF_COUNT_HW_CACHE_L1D                <<  0  |
 # (PERF_COUNT_HW_CACHE_OP_PREFETCH        <<  8) |
 # (PERF_COUNT_HW_CACHE_RESULT_MISS        << 16)
-[event22:base-stat]
-fd=22
+[event31:base-stat]
+fd=31
 type=3
 config=66048
 optional=1
index 069c2cf..352f160 100644 (file)
@@ -2116,7 +2116,7 @@ fetch_decomp_event(u64 head, size_t mmap_size, char *buf, bool needs_swap)
 static int __perf_session__process_decomp_events(struct perf_session *session)
 {
        s64 skip;
-       u64 size, file_pos = 0;
+       u64 size;
        struct decomp *decomp = session->decomp_last;
 
        if (!decomp)
@@ -2132,7 +2132,7 @@ static int __perf_session__process_decomp_events(struct perf_session *session)
                size = event->header.size;
 
                if (size < sizeof(struct perf_event_header) ||
-                   (skip = perf_session__process_event(session, event, file_pos)) < 0) {
+                   (skip = perf_session__process_event(session, event, decomp->file_pos)) < 0) {
                        pr_err("%#" PRIx64 " [%#x]: failed to process type: %d\n",
                                decomp->file_pos + decomp->head, event->header.size, event->header.type);
                        return -EINVAL;
index 5a93145..ac35c61 100755 (executable)
@@ -16,7 +16,7 @@ assert sys.version_info >= (3, 7), "Python version is too old"
 
 from collections import namedtuple
 from enum import Enum, auto
-from typing import Iterable
+from typing import Iterable, Sequence
 
 import kunit_config
 import kunit_json
@@ -186,6 +186,26 @@ def run_tests(linux: kunit_kernel.LinuxSourceTree,
                                exec_result.elapsed_time))
        return parse_result
 
+# Problem:
+# $ kunit.py run --json
+# works as one would expect and prints the parsed test results as JSON.
+# $ kunit.py run --json suite_name
+# would *not* pass suite_name as the filter_glob and print as json.
+# argparse will consider it to be another way of writing
+# $ kunit.py run --json=suite_name
+# i.e. it would run all tests, and dump the json to a `suite_name` file.
+# So we hackily automatically rewrite --json => --json=stdout
+pseudo_bool_flag_defaults = {
+               '--json': 'stdout',
+               '--raw_output': 'kunit',
+}
+def massage_argv(argv: Sequence[str]) -> Sequence[str]:
+       def massage_arg(arg: str) -> str:
+               if arg not in pseudo_bool_flag_defaults:
+                       return arg
+               return  f'{arg}={pseudo_bool_flag_defaults[arg]}'
+       return list(map(massage_arg, argv))
+
 def add_common_opts(parser) -> None:
        parser.add_argument('--build_dir',
                            help='As in the make command, it specifies the build '
@@ -303,7 +323,7 @@ def main(argv, linux=None):
                                  help='Specifies the file to read results from.',
                                  type=str, nargs='?', metavar='input_file')
 
-       cli_args = parser.parse_args(argv)
+       cli_args = parser.parse_args(massage_argv(argv))
 
        if get_kernel_root_path():
                os.chdir(get_kernel_root_path())
index 619c455..1edcc83 100755 (executable)
@@ -408,6 +408,14 @@ class KUnitMainTest(unittest.TestCase):
                        self.assertNotEqual(call, mock.call(StrContains('Testing complete.')))
                        self.assertNotEqual(call, mock.call(StrContains(' 0 tests run')))
 
+       def test_run_raw_output_does_not_take_positional_args(self):
+               # --raw_output is a string flag, but we don't want it to consume
+               # any positional arguments, only ones after an '='
+               self.linux_source_mock.run_kernel = mock.Mock(return_value=[])
+               kunit.main(['run', '--raw_output', 'filter_glob'], self.linux_source_mock)
+               self.linux_source_mock.run_kernel.assert_called_once_with(
+                       args=None, build_dir='.kunit', filter_glob='filter_glob', timeout=300)
+
        def test_exec_timeout(self):
                timeout = 3453
                kunit.main(['exec', '--timeout', str(timeout)], self.linux_source_mock)
index 4de902e..de1c4e6 100644 (file)
@@ -1,10 +1,13 @@
 // SPDX-License-Identifier: GPL-2.0
+#define _GNU_SOURCE
+#define __EXPORTED_HEADERS__
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>
 #include <string.h>
 #include <errno.h>
-#include <linux/fcntl.h>
+#include <fcntl.h>
 #include <malloc.h>
 
 #include <sys/ioctl.h>
index 5f5b2ba..60c02b4 100644 (file)
@@ -11,8 +11,8 @@ SYSTEM="syscalls"
 EVENT="sys_enter_openat"
 FIELD="filename"
 EPROBE="eprobe_open"
-
-echo "e:$EPROBE $SYSTEM/$EVENT file=+0(\$filename):ustring" >> dynamic_events
+OPTIONS="file=+0(\$filename):ustring"
+echo "e:$EPROBE $SYSTEM/$EVENT $OPTIONS" >> dynamic_events
 
 grep -q "$EPROBE" dynamic_events
 test -d events/eprobes/$EPROBE
@@ -37,4 +37,54 @@ echo "-:$EPROBE" >> dynamic_events
 ! grep -q "$EPROBE" dynamic_events
 ! test -d events/eprobes/$EPROBE
 
+# test various ways to remove the probe (already tested with just event name)
+
+# With group name
+echo "e:$EPROBE $SYSTEM/$EVENT $OPTIONS" >> dynamic_events
+grep -q "$EPROBE" dynamic_events
+test -d events/eprobes/$EPROBE
+echo "-:eprobes/$EPROBE" >> dynamic_events
+! grep -q "$EPROBE" dynamic_events
+! test -d events/eprobes/$EPROBE
+
+# With group name and system/event
+echo "e:$EPROBE $SYSTEM/$EVENT $OPTIONS" >> dynamic_events
+grep -q "$EPROBE" dynamic_events
+test -d events/eprobes/$EPROBE
+echo "-:eprobes/$EPROBE $SYSTEM/$EVENT" >> dynamic_events
+! grep -q "$EPROBE" dynamic_events
+! test -d events/eprobes/$EPROBE
+
+# With just event name and system/event
+echo "e:$EPROBE $SYSTEM/$EVENT $OPTIONS" >> dynamic_events
+grep -q "$EPROBE" dynamic_events
+test -d events/eprobes/$EPROBE
+echo "-:$EPROBE $SYSTEM/$EVENT" >> dynamic_events
+! grep -q "$EPROBE" dynamic_events
+! test -d events/eprobes/$EPROBE
+
+# With just event name and system/event and options
+echo "e:$EPROBE $SYSTEM/$EVENT $OPTIONS" >> dynamic_events
+grep -q "$EPROBE" dynamic_events
+test -d events/eprobes/$EPROBE
+echo "-:$EPROBE $SYSTEM/$EVENT $OPTIONS" >> dynamic_events
+! grep -q "$EPROBE" dynamic_events
+! test -d events/eprobes/$EPROBE
+
+# With group name and system/event and options
+echo "e:$EPROBE $SYSTEM/$EVENT $OPTIONS" >> dynamic_events
+grep -q "$EPROBE" dynamic_events
+test -d events/eprobes/$EPROBE
+echo "-:eprobes/$EPROBE $SYSTEM/$EVENT $OPTIONS" >> dynamic_events
+! grep -q "$EPROBE" dynamic_events
+! test -d events/eprobes/$EPROBE
+
+# Finally make sure what is in the dynamic_events file clears it too
+echo "e:$EPROBE $SYSTEM/$EVENT $OPTIONS" >> dynamic_events
+LINE=`sed -e '/$EPROBE/s/^e/-/' < dynamic_events`
+test -d events/eprobes/$EPROBE
+echo "-:eprobes/$EPROBE $SYSTEM/$EVENT $OPTIONS" >> dynamic_events
+! grep -q "$EPROBE" dynamic_events
+! test -d events/eprobes/$EPROBE
+
 clear_trace
index 3caf72b..a2489ec 100755 (executable)
@@ -468,10 +468,26 @@ out_bits()
   for i in {0..22}
   do
     ip -netns ioam-node-alpha route change db01::/64 encap ioam6 trace \
-           prealloc type ${bit2type[$i]} ns 123 size ${bit2size[$i]} dev veth0
-
-    run_test "out_bit$i" "${desc/<n>/$i}" ioam-node-alpha ioam-node-beta \
-           db01::2 db01::1 veth0 ${bit2type[$i]} 123
+           prealloc type ${bit2type[$i]} ns 123 size ${bit2size[$i]} \
+           dev veth0 &>/dev/null
+
+    local cmd_res=$?
+    local descr="${desc/<n>/$i}"
+
+    if [[ $i -ge 12 && $i -le 21 ]]
+    then
+      if [ $cmd_res != 0 ]
+      then
+        npassed=$((npassed+1))
+        log_test_passed "$descr"
+      else
+        nfailed=$((nfailed+1))
+        log_test_failed "$descr"
+      fi
+    else
+      run_test "out_bit$i" "$descr" ioam-node-alpha ioam-node-beta \
+             db01::2 db01::1 veth0 ${bit2type[$i]} 123
+    fi
   done
 
   bit2size[22]=$tmp
@@ -544,7 +560,7 @@ in_bits()
   local tmp=${bit2size[22]}
   bit2size[22]=$(( $tmp + ${#BETA[9]} + ((4 - (${#BETA[9]} % 4)) % 4) ))
 
-  for i in {0..22}
+  for i in {0..11} {22..22}
   do
     ip -netns ioam-node-alpha route change db01::/64 encap ioam6 trace \
            prealloc type ${bit2type[$i]} ns 123 size ${bit2size[$i]} dev veth0
index d376cb2..8f6997d 100644 (file)
@@ -94,16 +94,6 @@ enum {
        TEST_OUT_BIT9,
        TEST_OUT_BIT10,
        TEST_OUT_BIT11,
-       TEST_OUT_BIT12,
-       TEST_OUT_BIT13,
-       TEST_OUT_BIT14,
-       TEST_OUT_BIT15,
-       TEST_OUT_BIT16,
-       TEST_OUT_BIT17,
-       TEST_OUT_BIT18,
-       TEST_OUT_BIT19,
-       TEST_OUT_BIT20,
-       TEST_OUT_BIT21,
        TEST_OUT_BIT22,
        TEST_OUT_FULL_SUPP_TRACE,
 
@@ -125,16 +115,6 @@ enum {
        TEST_IN_BIT9,
        TEST_IN_BIT10,
        TEST_IN_BIT11,
-       TEST_IN_BIT12,
-       TEST_IN_BIT13,
-       TEST_IN_BIT14,
-       TEST_IN_BIT15,
-       TEST_IN_BIT16,
-       TEST_IN_BIT17,
-       TEST_IN_BIT18,
-       TEST_IN_BIT19,
-       TEST_IN_BIT20,
-       TEST_IN_BIT21,
        TEST_IN_BIT22,
        TEST_IN_FULL_SUPP_TRACE,
 
@@ -199,30 +179,6 @@ static int check_ioam_header(int tid, struct ioam6_trace_hdr *ioam6h,
                       ioam6h->nodelen != 2 ||
                       ioam6h->remlen;
 
-       case TEST_OUT_BIT12:
-       case TEST_IN_BIT12:
-       case TEST_OUT_BIT13:
-       case TEST_IN_BIT13:
-       case TEST_OUT_BIT14:
-       case TEST_IN_BIT14:
-       case TEST_OUT_BIT15:
-       case TEST_IN_BIT15:
-       case TEST_OUT_BIT16:
-       case TEST_IN_BIT16:
-       case TEST_OUT_BIT17:
-       case TEST_IN_BIT17:
-       case TEST_OUT_BIT18:
-       case TEST_IN_BIT18:
-       case TEST_OUT_BIT19:
-       case TEST_IN_BIT19:
-       case TEST_OUT_BIT20:
-       case TEST_IN_BIT20:
-       case TEST_OUT_BIT21:
-       case TEST_IN_BIT21:
-               return ioam6h->overflow ||
-                      ioam6h->nodelen ||
-                      ioam6h->remlen != 1;
-
        case TEST_OUT_BIT22:
        case TEST_IN_BIT22:
                return ioam6h->overflow ||
@@ -326,6 +282,66 @@ static int check_ioam6_data(__u8 **p, struct ioam6_trace_hdr *ioam6h,
                *p += sizeof(__u32);
        }
 
+       if (ioam6h->type.bit12) {
+               if (__be32_to_cpu(*((__u32 *)*p)) != 0xffffffff)
+                       return 1;
+               *p += sizeof(__u32);
+       }
+
+       if (ioam6h->type.bit13) {
+               if (__be32_to_cpu(*((__u32 *)*p)) != 0xffffffff)
+                       return 1;
+               *p += sizeof(__u32);
+       }
+
+       if (ioam6h->type.bit14) {
+               if (__be32_to_cpu(*((__u32 *)*p)) != 0xffffffff)
+                       return 1;
+               *p += sizeof(__u32);
+       }
+
+       if (ioam6h->type.bit15) {
+               if (__be32_to_cpu(*((__u32 *)*p)) != 0xffffffff)
+                       return 1;
+               *p += sizeof(__u32);
+       }
+
+       if (ioam6h->type.bit16) {
+               if (__be32_to_cpu(*((__u32 *)*p)) != 0xffffffff)
+                       return 1;
+               *p += sizeof(__u32);
+       }
+
+       if (ioam6h->type.bit17) {
+               if (__be32_to_cpu(*((__u32 *)*p)) != 0xffffffff)
+                       return 1;
+               *p += sizeof(__u32);
+       }
+
+       if (ioam6h->type.bit18) {
+               if (__be32_to_cpu(*((__u32 *)*p)) != 0xffffffff)
+                       return 1;
+               *p += sizeof(__u32);
+       }
+
+       if (ioam6h->type.bit19) {
+               if (__be32_to_cpu(*((__u32 *)*p)) != 0xffffffff)
+                       return 1;
+               *p += sizeof(__u32);
+       }
+
+       if (ioam6h->type.bit20) {
+               if (__be32_to_cpu(*((__u32 *)*p)) != 0xffffffff)
+                       return 1;
+               *p += sizeof(__u32);
+       }
+
+       if (ioam6h->type.bit21) {
+               if (__be32_to_cpu(*((__u32 *)*p)) != 0xffffffff)
+                       return 1;
+               *p += sizeof(__u32);
+       }
+
        if (ioam6h->type.bit22) {
                len = cnf.sc_data ? strlen(cnf.sc_data) : 0;
                aligned = cnf.sc_data ? __ALIGN_KERNEL(len, 4) : 0;
@@ -455,26 +471,6 @@ static int str2id(const char *tname)
                return TEST_OUT_BIT10;
        if (!strcmp("out_bit11", tname))
                return TEST_OUT_BIT11;
-       if (!strcmp("out_bit12", tname))
-               return TEST_OUT_BIT12;
-       if (!strcmp("out_bit13", tname))
-               return TEST_OUT_BIT13;
-       if (!strcmp("out_bit14", tname))
-               return TEST_OUT_BIT14;
-       if (!strcmp("out_bit15", tname))
-               return TEST_OUT_BIT15;
-       if (!strcmp("out_bit16", tname))
-               return TEST_OUT_BIT16;
-       if (!strcmp("out_bit17", tname))
-               return TEST_OUT_BIT17;
-       if (!strcmp("out_bit18", tname))
-               return TEST_OUT_BIT18;
-       if (!strcmp("out_bit19", tname))
-               return TEST_OUT_BIT19;
-       if (!strcmp("out_bit20", tname))
-               return TEST_OUT_BIT20;
-       if (!strcmp("out_bit21", tname))
-               return TEST_OUT_BIT21;
        if (!strcmp("out_bit22", tname))
                return TEST_OUT_BIT22;
        if (!strcmp("out_full_supp_trace", tname))
@@ -509,26 +505,6 @@ static int str2id(const char *tname)
                return TEST_IN_BIT10;
        if (!strcmp("in_bit11", tname))
                return TEST_IN_BIT11;
-       if (!strcmp("in_bit12", tname))
-               return TEST_IN_BIT12;
-       if (!strcmp("in_bit13", tname))
-               return TEST_IN_BIT13;
-       if (!strcmp("in_bit14", tname))
-               return TEST_IN_BIT14;
-       if (!strcmp("in_bit15", tname))
-               return TEST_IN_BIT15;
-       if (!strcmp("in_bit16", tname))
-               return TEST_IN_BIT16;
-       if (!strcmp("in_bit17", tname))
-               return TEST_IN_BIT17;
-       if (!strcmp("in_bit18", tname))
-               return TEST_IN_BIT18;
-       if (!strcmp("in_bit19", tname))
-               return TEST_IN_BIT19;
-       if (!strcmp("in_bit20", tname))
-               return TEST_IN_BIT20;
-       if (!strcmp("in_bit21", tname))
-               return TEST_IN_BIT21;
        if (!strcmp("in_bit22", tname))
                return TEST_IN_BIT22;
        if (!strcmp("in_full_supp_trace", tname))
@@ -606,16 +582,6 @@ static int (*func[__TEST_MAX])(int, struct ioam6_trace_hdr *, __u32, __u16) = {
        [TEST_OUT_BIT9]         = check_ioam_header_and_data,
        [TEST_OUT_BIT10]                = check_ioam_header_and_data,
        [TEST_OUT_BIT11]                = check_ioam_header_and_data,
-       [TEST_OUT_BIT12]                = check_ioam_header,
-       [TEST_OUT_BIT13]                = check_ioam_header,
-       [TEST_OUT_BIT14]                = check_ioam_header,
-       [TEST_OUT_BIT15]                = check_ioam_header,
-       [TEST_OUT_BIT16]                = check_ioam_header,
-       [TEST_OUT_BIT17]                = check_ioam_header,
-       [TEST_OUT_BIT18]                = check_ioam_header,
-       [TEST_OUT_BIT19]                = check_ioam_header,
-       [TEST_OUT_BIT20]                = check_ioam_header,
-       [TEST_OUT_BIT21]                = check_ioam_header,
        [TEST_OUT_BIT22]                = check_ioam_header_and_data,
        [TEST_OUT_FULL_SUPP_TRACE]      = check_ioam_header_and_data,
        [TEST_IN_UNDEF_NS]              = check_ioam_header,
@@ -633,16 +599,6 @@ static int (*func[__TEST_MAX])(int, struct ioam6_trace_hdr *, __u32, __u16) = {
        [TEST_IN_BIT9]                  = check_ioam_header_and_data,
        [TEST_IN_BIT10]         = check_ioam_header_and_data,
        [TEST_IN_BIT11]         = check_ioam_header_and_data,
-       [TEST_IN_BIT12]         = check_ioam_header,
-       [TEST_IN_BIT13]         = check_ioam_header,
-       [TEST_IN_BIT14]         = check_ioam_header,
-       [TEST_IN_BIT15]         = check_ioam_header,
-       [TEST_IN_BIT16]         = check_ioam_header,
-       [TEST_IN_BIT17]         = check_ioam_header,
-       [TEST_IN_BIT18]         = check_ioam_header,
-       [TEST_IN_BIT19]         = check_ioam_header,
-       [TEST_IN_BIT20]         = check_ioam_header,
-       [TEST_IN_BIT21]         = check_ioam_header,
        [TEST_IN_BIT22]         = check_ioam_header_and_data,
        [TEST_IN_FULL_SUPP_TRACE]       = check_ioam_header_and_data,
        [TEST_FWD_FULL_SUPP_TRACE]      = check_ioam_header_and_data,