Merge tag 's390-6.1-3' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux
authorLinus Torvalds <torvalds@linux-foundation.org>
Sat, 29 Oct 2022 00:11:26 +0000 (17:11 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sat, 29 Oct 2022 00:11:26 +0000 (17:11 -0700)
Pull s390 fixes from Vasily Gorbik:

 - Remove outdated linux390 link from MAINTAINERS

 - Add few missing EX_TABLE entries to inline assemblies

 - Fix raw data collection for pai_ext PMU

 - Add kernel image secure boot trailer for future firmware versions

 - Fix out-of-bounds access on cio_ignore free

 - Fix memory allocation of mdev_types array in vfio-ap

* tag 's390-6.1-3' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux:
  s390/vfio-ap: Fix memory allocation for mdev_types array
  s390/cio: fix out-of-bounds access on cio_ignore free
  s390/pai: fix raw data collection for PMU pai_ext
  s390/boot: add secure boot trailer
  s390/pci: add missing EX_TABLE entries to __pcistg_mio_inuser()/__pcilg_mio_inuser()
  s390/futex: add missing EX_TABLE entry to __futex_atomic_op()
  s390/uaccess: add missing EX_TABLE entries to __clear_user()
  MAINTAINERS: remove outdated linux390 link

315 files changed:
Documentation/admin-guide/media/vivid.rst
Documentation/core-api/kernel-api.rst
Documentation/devicetree/bindings/pinctrl/xlnx,zynqmp-pinctrl.yaml
Documentation/driver-api/basics.rst
Documentation/process/maintainer-netdev.rst
MAINTAINERS
arch/arc/boot/dts/axc003.dtsi
arch/arc/boot/dts/axc003_idu.dtsi
arch/arc/boot/dts/axs10x_mb.dtsi
arch/arc/boot/dts/hsdk.dts
arch/arc/boot/dts/vdk_axs10x_mb.dtsi
arch/arc/configs/axs101_defconfig
arch/arc/configs/axs103_defconfig
arch/arc/configs/axs103_smp_defconfig
arch/arc/configs/haps_hs_defconfig
arch/arc/configs/haps_hs_smp_defconfig
arch/arc/configs/hsdk_defconfig
arch/arc/configs/nsim_700_defconfig
arch/arc/configs/nsimosci_defconfig
arch/arc/configs/nsimosci_hs_defconfig
arch/arc/configs/nsimosci_hs_smp_defconfig
arch/arc/configs/tb10x_defconfig
arch/arc/configs/vdk_hs38_defconfig
arch/arc/configs/vdk_hs38_smp_defconfig
arch/arc/include/asm/bitops.h
arch/arc/include/asm/entry-compact.h
arch/arc/include/asm/io.h
arch/arc/include/asm/pgtable-levels.h
arch/arc/kernel/smp.c
arch/arc/mm/cache.c
arch/arc/mm/ioremap.c
arch/riscv/Kconfig
arch/riscv/Makefile
arch/riscv/include/asm/jump_label.h
arch/riscv/include/asm/vdso/processor.h
arch/riscv/kernel/cpu.c
arch/riscv/mm/kasan_init.c
arch/x86/crypto/polyval-clmulni_glue.c
arch/x86/mm/pat/set_memory.c
arch/x86/net/bpf_jit_comp.c
drivers/acpi/acpi_pcc.c
drivers/acpi/resource.c
drivers/acpi/scan.c
drivers/acpi/video_detect.c
drivers/base/power/domain.c
drivers/base/property.c
drivers/cpufreq/intel_pstate.c
drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c
drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c
drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c
drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h
drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
drivers/gpu/drm/amd/amdgpu/mes_v11_0.c
drivers/gpu/drm/amd/amdgpu/mmhub_v2_0.c
drivers/gpu/drm/amd/amdkfd/kfd_crat.c
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource_helpers.c
drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu13_driver_if_v13_0_0.h
drivers/gpu/drm/amd/pm/swsmu/inc/smu_v13_0.h
drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c
drivers/gpu/drm/bridge/parade-ps8640.c
drivers/gpu/drm/i915/display/intel_dp.c
drivers/gpu/drm/i915/gt/intel_workarounds.c
drivers/gpu/drm/i915/intel_runtime_pm.c
drivers/gpu/drm/msm/Kconfig
drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c
drivers/gpu/drm/msm/adreno/adreno_device.c
drivers/gpu/drm/msm/adreno/adreno_gpu.c
drivers/gpu/drm/msm/disp/mdp4/mdp4_lvds_connector.c
drivers/gpu/drm/msm/dp/dp_ctrl.c
drivers/gpu/drm/msm/dp/dp_display.c
drivers/gpu/drm/msm/dp/dp_drm.c
drivers/gpu/drm/msm/dp/dp_parser.c
drivers/gpu/drm/msm/dp/dp_parser.h
drivers/gpu/drm/msm/dsi/dsi.c
drivers/gpu/drm/msm/hdmi/hdmi.c
drivers/gpu/drm/msm/msm_drv.c
drivers/gpu/drm/msm/msm_gem_submit.c
drivers/gpu/drm/msm/msm_gpu.c
drivers/gpu/drm/msm/msm_gpu.h
drivers/gpu/drm/msm/msm_ringbuffer.c
drivers/gpu/drm/scheduler/sched_entity.c
drivers/leds/simple/simatic-ipc-leds-gpio.c
drivers/media/test-drivers/vivid/vivid-core.c
drivers/media/test-drivers/vivid/vivid-core.h
drivers/media/test-drivers/vivid/vivid-osd.c
drivers/media/test-drivers/vivid/vivid-vid-cap.c
drivers/media/v4l2-core/v4l2-dv-timings.c
drivers/mmc/core/block.c
drivers/mmc/core/queue.c
drivers/mmc/core/sdio_bus.c
drivers/mmc/host/Kconfig
drivers/mmc/host/sdhci-esdhc-imx.c
drivers/mmc/host/sdhci-pci-core.c
drivers/mtd/mtdcore.c
drivers/mtd/nand/raw/intel-nand-controller.c
drivers/mtd/nand/raw/marvell_nand.c
drivers/mtd/nand/raw/tegra_nand.c
drivers/mtd/parsers/bcm47xxpart.c
drivers/mtd/spi-nor/core.c
drivers/net/can/mscan/mpc5xxx_can.c
drivers/net/can/rcar/rcar_canfd.c
drivers/net/can/spi/mcp251x.c
drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c
drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c
drivers/net/ethernet/amd/xgbe/xgbe-pci.c
drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c
drivers/net/ethernet/amd/xgbe/xgbe.h
drivers/net/ethernet/aquantia/atlantic/aq_macsec.c
drivers/net/ethernet/aquantia/atlantic/aq_nic.h
drivers/net/ethernet/broadcom/bcm4908_enet.c
drivers/net/ethernet/broadcom/bcmsysport.c
drivers/net/ethernet/cadence/macb_main.c
drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
drivers/net/ethernet/freescale/dpaa/dpaa_eth_sysfs.c
drivers/net/ethernet/freescale/enetc/enetc.c
drivers/net/ethernet/freescale/fec_main.c
drivers/net/ethernet/freescale/fman/mac.c
drivers/net/ethernet/freescale/fman/mac.h
drivers/net/ethernet/huawei/hinic/hinic_debugfs.c
drivers/net/ethernet/huawei/hinic/hinic_hw_cmdq.c
drivers/net/ethernet/huawei/hinic/hinic_hw_dev.c
drivers/net/ethernet/huawei/hinic/hinic_sriov.c
drivers/net/ethernet/ibm/ehea/ehea_main.c
drivers/net/ethernet/intel/i40e/i40e_ethtool.c
drivers/net/ethernet/intel/i40e/i40e_type.h
drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.h
drivers/net/ethernet/lantiq_etop.c
drivers/net/ethernet/mellanox/mlx5/core/cmd.c
drivers/net/ethernet/mellanox/mlx5/core/en/ptp.h
drivers/net/ethernet/mellanox/mlx5/core/en/tc_priv.h
drivers/net/ethernet/mellanox/mlx5/core/en/txrx.h
drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c
drivers/net/ethernet/mellanox/mlx5/core/en_accel/macsec.c
drivers/net/ethernet/mellanox/mlx5/core/en_accel/macsec_fs.c
drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
drivers/net/ethernet/mellanox/mlx5/core/en_tx.c
drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c
drivers/net/ethernet/mellanox/mlx5/core/lib/aso.c
drivers/net/ethernet/mellanox/mlx5/core/lib/mpfs.c
drivers/net/ethernet/mellanox/mlx5/core/main.c
drivers/net/ethernet/mellanox/mlx5/core/steering/dr_rule.c
drivers/net/ethernet/micrel/ksz884x.c
drivers/net/ethernet/microchip/lan966x/lan966x_ethtool.c
drivers/net/ethernet/microchip/lan966x/lan966x_fdma.c
drivers/net/ethernet/netronome/nfp/nfp_main.c
drivers/net/ethernet/socionext/netsec.c
drivers/net/ethernet/socionext/sni_ave.c
drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
drivers/net/ipa/data/ipa_data-v3.5.1.c
drivers/net/ipa/ipa_main.c
drivers/net/ipa/reg/ipa_reg-v3.1.c
drivers/net/netdevsim/bus.c
drivers/net/netdevsim/dev.c
drivers/nfc/virtual_ncidev.c
drivers/pinctrl/pinctrl-ingenic.c
drivers/pinctrl/pinctrl-ocelot.c
drivers/pinctrl/pinctrl-zynqmp.c
drivers/pinctrl/qcom/pinctrl-msm.c
drivers/platform/x86/amd/pmc.c
drivers/platform/x86/asus-nb-wmi.c
drivers/platform/x86/intel/pmc/core.c
drivers/platform/x86/thinkpad_acpi.c
drivers/rtc/rtc-cmos.c
drivers/scsi/mpt3sas/mpt3sas_base.c
drivers/spi/spi-aspeed-smc.c
drivers/spi/spi-gxp.c
drivers/spi/spi-intel.c
drivers/spi/spi-mpc52xx.c
drivers/spi/spi-qup.c
drivers/spi/spi-tegra210-quad.c
drivers/video/aperture.c
fs/binfmt_elf.c
fs/crypto/keyring.c
fs/exec.c
fs/super.c
include/linux/bpf.h
include/linux/fscrypt.h
include/linux/mlx5/driver.h
include/linux/overflow.h
include/linux/spi/spi-mem.h
include/net/genetlink.h
include/net/sock.h
include/sound/control.h
include/sound/simple_card_utils.h
include/uapi/drm/amdgpu_drm.h
include/uapi/linux/videodev2.h
kernel/bpf/btf.c
kernel/bpf/dispatcher.c
kernel/bpf/memalloc.c
kernel/bpf/verifier.c
kernel/power/hibernate.c
kernel/rcu/tree.c
lib/kunit/string-stream.c
lib/kunit/test.c
lib/overflow_kunit.c
lib/test_rhashtable.c
net/can/j1939/transport.c
net/core/net_namespace.c
net/core/skbuff.c
net/ethtool/eeprom.c
net/ethtool/pse-pd.c
net/ieee802154/socket.c
net/ipv4/fib_frontend.c
net/ipv4/fib_semantics.c
net/ipv4/nexthop.c
net/ipv4/tcp_input.c
net/ipv4/tcp_ipv4.c
net/ipv6/ip6_gre.c
net/ipv6/ip6_tunnel.c
net/ipv6/sit.c
net/kcm/kcmsock.c
net/mac802154/rx.c
net/mptcp/protocol.c
net/mptcp/protocol.h
net/mptcp/subflow.c
net/netlink/genetlink.c
net/openvswitch/datapath.c
net/tipc/topsrv.c
sound/aoa/soundbus/i2sbus/core.c
sound/core/control.c
sound/pci/ac97/ac97_codec.c
sound/pci/au88x0/au88x0.h
sound/pci/au88x0/au88x0_core.c
sound/pci/ca0106/ca0106_mixer.c
sound/pci/emu10k1/emumixer.c
sound/pci/hda/patch_realtek.c
sound/pci/rme9652/hdsp.c
sound/pci/rme9652/rme9652.c
sound/soc/amd/yc/acp6x-mach.c
sound/soc/codecs/Kconfig
sound/soc/codecs/cx2072x.h
sound/soc/codecs/jz4725b.c
sound/soc/codecs/mt6660.c
sound/soc/codecs/rt1019.c
sound/soc/codecs/rt1019.h
sound/soc/codecs/rt1308-sdw.c
sound/soc/codecs/rt1308-sdw.h
sound/soc/codecs/rt1308.h
sound/soc/codecs/rt5682s.c
sound/soc/codecs/rt5682s.h
sound/soc/codecs/tlv320adc3xxx.c
sound/soc/codecs/wm5102.c
sound/soc/codecs/wm5110.c
sound/soc/codecs/wm8962.c
sound/soc/codecs/wm8997.c
sound/soc/generic/audio-graph-card.c
sound/soc/generic/simple-card-utils.c
sound/soc/generic/simple-card.c
sound/soc/intel/boards/sof_rt5682.c
sound/soc/intel/boards/sof_sdw.c
sound/soc/intel/skylake/skl.c
sound/soc/qcom/Kconfig
sound/soc/qcom/lpass-cpu.c
sound/soc/soc-component.c
sound/soc/sof/intel/hda-codec.c
sound/soc/sof/intel/pci-mtl.c
sound/soc/sof/intel/pci-tgl.c
sound/soc/sof/ipc4-mtrace.c
sound/synth/emux/emux.c
sound/usb/implicit.c
sound/usb/mixer.c
tools/arch/arm64/include/asm/cputype.h
tools/arch/x86/include/asm/cpufeatures.h
tools/arch/x86/lib/memcpy_64.S
tools/build/Makefile.feature
tools/build/feature/Makefile
tools/build/feature/test-libbpf-bpf_program__set_insns.c [new file with mode: 0644]
tools/include/uapi/linux/in.h
tools/include/uapi/linux/perf_event.h
tools/include/uapi/linux/stat.h
tools/include/uapi/sound/asound.h
tools/perf/Documentation/arm-coresight.txt [moved from tools/perf/Documentation/perf-arm-coresight.txt with 100% similarity]
tools/perf/Makefile.config
tools/perf/arch/powerpc/entry/syscalls/syscall.tbl
tools/perf/builtin-record.c
tools/perf/check-headers.sh
tools/perf/pmu-events/arch/arm64/hisilicon/hip08/metrics.json
tools/perf/pmu-events/arch/powerpc/power10/nest_metrics.json
tools/perf/pmu-events/arch/s390/cf_z16/pai_crypto.json [moved from tools/perf/pmu-events/arch/s390/cf_z16/pai.json with 100% similarity]
tools/perf/tests/shell/test_intel_pt.sh
tools/perf/trace/beauty/statx.c
tools/perf/util/auxtrace.c
tools/perf/util/bpf-event.c
tools/perf/util/bpf-loader.c
tools/perf/util/include/linux/linkage.h
tools/power/pm-graph/README
tools/power/pm-graph/sleepgraph.8
tools/power/pm-graph/sleepgraph.py
tools/testing/selftests/Makefile
tools/testing/selftests/bpf/prog_tests/btf.c
tools/testing/selftests/bpf/progs/user_ringbuf_success.c
tools/testing/selftests/drivers/net/bonding/Makefile
tools/testing/selftests/drivers/net/bonding/dev_addr_lists.sh
tools/testing/selftests/drivers/net/bonding/net_forwarding_lib.sh [new symlink]
tools/testing/selftests/drivers/net/dsa/test_bridge_fdb_stress.sh
tools/testing/selftests/drivers/net/team/Makefile
tools/testing/selftests/drivers/net/team/dev_addr_lists.sh
tools/testing/selftests/drivers/net/team/lag_lib.sh [new symlink]
tools/testing/selftests/drivers/net/team/net_forwarding_lib.sh [new symlink]
tools/testing/selftests/ftrace/test.d/dynevent/test_duplicates.tc
tools/testing/selftests/ftrace/test.d/trigger/inter-event/trigger-synthetic-eprobe.tc
tools/testing/selftests/futex/functional/Makefile
tools/testing/selftests/intel_pstate/Makefile
tools/testing/selftests/kexec/Makefile
tools/testing/selftests/lib.mk
tools/testing/selftests/memory-hotplug/mem-on-off-test.sh
tools/testing/selftests/net/openvswitch/Makefile [new file with mode: 0644]
tools/testing/selftests/net/openvswitch/openvswitch.sh [new file with mode: 0755]
tools/testing/selftests/net/openvswitch/ovs-dpctl.py [new file with mode: 0644]

index 4f680dc..abd90ed 100644 (file)
@@ -1318,7 +1318,7 @@ instance. This setup would require the following commands:
        $ v4l2-ctl -d2 -i2
        $ v4l2-ctl -d2 -c horizontal_movement=4
        $ v4l2-ctl -d1 --overlay=1
-       $ v4l2-ctl -d1 -c loop_video=1
+       $ v4l2-ctl -d0 -c loop_video=1
        $ v4l2-ctl -d2 --stream-mmap --overlay=1
 
 And from another console:
index 0793c40..06f4ab1 100644 (file)
@@ -118,6 +118,12 @@ Text Searching
 CRC and Math Functions in Linux
 ===============================
 
+Arithmetic Overflow Checking
+----------------------------
+
+.. kernel-doc:: include/linux/overflow.h
+   :internal:
+
 CRC Functions
 -------------
 
index 1e2b9b6..2722dc7 100644 (file)
@@ -274,10 +274,6 @@ patternProperties:
           slew-rate:
             enum: [0, 1]
 
-          output-enable:
-            description:
-              This will internally disable the tri-state for MIO pins.
-
           drive-strength:
             description:
               Selects the drive strength for MIO pins, in mA.
index 3e2dae9..4b4d8e2 100644 (file)
@@ -107,9 +107,6 @@ Kernel utility functions
 .. kernel-doc:: kernel/panic.c
    :export:
 
-.. kernel-doc:: include/linux/overflow.h
-   :internal:
-
 Device Resource Management
 --------------------------
 
index d140070..1fa5ab8 100644 (file)
@@ -319,3 +319,13 @@ unpatched tree to confirm infrastructure didn't mangle it.
 Finally, go back and read
 :ref:`Documentation/process/submitting-patches.rst <submittingpatches>`
 to be sure you are not repeating some common mistake documented there.
+
+My company uses peer feedback in employee performance reviews. Can I ask netdev maintainers for feedback?
+---------------------------------------------------------------------------------------------------------
+
+Yes, especially if you spend significant amount of time reviewing code
+and go out of your way to improve shared infrastructure.
+
+The feedback must be requested by you, the contributor, and will always
+be shared with you (even if you request for it to be submitted to your
+manager).
index ea5fcf9..2034e7d 100644 (file)
@@ -15435,6 +15435,7 @@ S:      Maintained
 W:     http://openvswitch.org
 F:     include/uapi/linux/openvswitch.h
 F:     net/openvswitch/
+F:     tools/testing/selftests/net/openvswitch/
 
 OPERATING PERFORMANCE POINTS (OPP)
 M:     Viresh Kumar <vireshk@kernel.org>
@@ -16674,6 +16675,7 @@ F:      Documentation/driver-api/ptp.rst
 F:     drivers/net/phy/dp83640*
 F:     drivers/ptp/*
 F:     include/linux/ptp_cl*
+K:     (?:\b|_)ptp(?:\b|_)
 
 PTP VIRTUAL CLOCK SUPPORT
 M:     Yangbo Lu <yangbo.lu@nxp.com>
@@ -18773,7 +18775,7 @@ M:      Palmer Dabbelt <palmer@dabbelt.com>
 M:     Paul Walmsley <paul.walmsley@sifive.com>
 L:     linux-riscv@lists.infradead.org
 S:     Supported
-T:     git git://github.com/sifive/riscv-linux.git
+T:     git https://github.com/sifive/riscv-linux.git
 N:     sifive
 K:     [^@]sifive
 
index cd1edcf..3434c81 100644 (file)
                        dma-coherent;
                };
 
-               ehci@40000 {
+               usb@40000 {
                        dma-coherent;
                };
 
-               ohci@60000 {
+               usb@60000 {
                        dma-coherent;
                };
 
index 7077938..67556f4 100644 (file)
                        dma-coherent;
                };
 
-               ehci@40000 {
+               usb@40000 {
                        dma-coherent;
                };
 
-               ohci@60000 {
+               usb@60000 {
                        dma-coherent;
                };
 
index 99d3e71..b644353 100644 (file)
                        mac-address = [00 00 00 00 00 00]; /* Filled in by U-Boot */
                };
 
-               ehci@40000 {
+               usb@40000 {
                        compatible = "generic-ehci";
                        reg = < 0x40000 0x100 >;
                        interrupts = < 8 >;
                };
 
-               ohci@60000 {
+               usb@60000 {
                        compatible = "generic-ohci";
                        reg = < 0x60000 0x100 >;
                        interrupts = < 8 >;
index f48ba03..6691f42 100644 (file)
                        };
                };
 
-               ohci@60000 {
+               usb@60000 {
                        compatible = "snps,hsdk-v1.0-ohci", "generic-ohci";
                        reg = <0x60000 0x100>;
                        interrupts = <15>;
                        dma-coherent;
                };
 
-               ehci@40000 {
+               usb@40000 {
                        compatible = "snps,hsdk-v1.0-ehci", "generic-ehci";
                        reg = <0x40000 0x100>;
                        interrupts = <15>;
index cbb1797..90a4120 100644 (file)
@@ -46,7 +46,7 @@
                        clock-names = "stmmaceth";
                };
 
-               ehci@40000 {
+               usb@40000 {
                        compatible = "generic-ehci";
                        reg = < 0x40000 0x100 >;
                        interrupts = < 8 >;
index e31a8eb..8176416 100644 (file)
@@ -35,9 +35,6 @@ CONFIG_IP_PNP=y
 CONFIG_IP_PNP_DHCP=y
 CONFIG_IP_PNP_BOOTP=y
 CONFIG_IP_PNP_RARP=y
-# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
-# CONFIG_INET_XFRM_MODE_TUNNEL is not set
-# CONFIG_INET_XFRM_MODE_BEET is not set
 # CONFIG_IPV6 is not set
 CONFIG_DEVTMPFS=y
 # CONFIG_STANDALONE is not set
@@ -99,7 +96,6 @@ CONFIG_NFS_FS=y
 CONFIG_NFS_V3_ACL=y
 CONFIG_NLS_CODEPAGE_437=y
 CONFIG_NLS_ISO8859_1=y
-# CONFIG_ENABLE_MUST_CHECK is not set
 CONFIG_STRIP_ASM_SYMS=y
 CONFIG_SOFTLOCKUP_DETECTOR=y
 CONFIG_DEFAULT_HUNG_TASK_TIMEOUT=10
index e0e8567..d518127 100644 (file)
@@ -34,9 +34,6 @@ CONFIG_IP_PNP=y
 CONFIG_IP_PNP_DHCP=y
 CONFIG_IP_PNP_BOOTP=y
 CONFIG_IP_PNP_RARP=y
-# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
-# CONFIG_INET_XFRM_MODE_TUNNEL is not set
-# CONFIG_INET_XFRM_MODE_BEET is not set
 # CONFIG_IPV6 is not set
 CONFIG_DEVTMPFS=y
 # CONFIG_STANDALONE is not set
@@ -97,7 +94,6 @@ CONFIG_NFS_FS=y
 CONFIG_NFS_V3_ACL=y
 CONFIG_NLS_CODEPAGE_437=y
 CONFIG_NLS_ISO8859_1=y
-# CONFIG_ENABLE_MUST_CHECK is not set
 CONFIG_STRIP_ASM_SYMS=y
 CONFIG_SOFTLOCKUP_DETECTOR=y
 CONFIG_DEFAULT_HUNG_TASK_TIMEOUT=10
index fcbc952..2f336d9 100644 (file)
@@ -35,9 +35,6 @@ CONFIG_IP_PNP=y
 CONFIG_IP_PNP_DHCP=y
 CONFIG_IP_PNP_BOOTP=y
 CONFIG_IP_PNP_RARP=y
-# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
-# CONFIG_INET_XFRM_MODE_TUNNEL is not set
-# CONFIG_INET_XFRM_MODE_BEET is not set
 # CONFIG_IPV6 is not set
 CONFIG_DEVTMPFS=y
 # CONFIG_STANDALONE is not set
@@ -100,7 +97,6 @@ CONFIG_NFS_FS=y
 CONFIG_NFS_V3_ACL=y
 CONFIG_NLS_CODEPAGE_437=y
 CONFIG_NLS_ISO8859_1=y
-# CONFIG_ENABLE_MUST_CHECK is not set
 CONFIG_STRIP_ASM_SYMS=y
 CONFIG_SOFTLOCKUP_DETECTOR=y
 CONFIG_DEFAULT_HUNG_TASK_TIMEOUT=10
index d87ad7e..899b2fd 100644 (file)
@@ -59,6 +59,5 @@ CONFIG_EXT2_FS_XATTR=y
 CONFIG_TMPFS=y
 # CONFIG_MISC_FILESYSTEMS is not set
 CONFIG_NFS_FS=y
-# CONFIG_ENABLE_MUST_CHECK is not set
 CONFIG_DEBUG_MEMORY_INIT=y
 # CONFIG_DEBUG_PREEMPT is not set
index 8d82cdb..0d32aac 100644 (file)
@@ -59,6 +59,5 @@ CONFIG_EXT2_FS_XATTR=y
 CONFIG_TMPFS=y
 # CONFIG_MISC_FILESYSTEMS is not set
 CONFIG_NFS_FS=y
-# CONFIG_ENABLE_MUST_CHECK is not set
 CONFIG_SOFTLOCKUP_DETECTOR=y
 # CONFIG_DEBUG_PREEMPT is not set
index f856b03..d18378d 100644 (file)
@@ -85,7 +85,6 @@ CONFIG_NFS_FS=y
 CONFIG_NFS_V3_ACL=y
 CONFIG_NLS_CODEPAGE_437=y
 CONFIG_NLS_ISO8859_1=y
-# CONFIG_ENABLE_MUST_CHECK is not set
 CONFIG_STRIP_ASM_SYMS=y
 CONFIG_SOFTLOCKUP_DETECTOR=y
 CONFIG_DEFAULT_HUNG_TASK_TIMEOUT=10
index a1ce12b..3e98297 100644 (file)
@@ -56,5 +56,4 @@ CONFIG_EXT2_FS_XATTR=y
 CONFIG_TMPFS=y
 # CONFIG_MISC_FILESYSTEMS is not set
 CONFIG_NFS_FS=y
-# CONFIG_ENABLE_MUST_CHECK is not set
 # CONFIG_DEBUG_PREEMPT is not set
index ca10f4a..502c87f 100644 (file)
@@ -65,4 +65,3 @@ CONFIG_TMPFS=y
 # CONFIG_MISC_FILESYSTEMS is not set
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3_ACL=y
-# CONFIG_ENABLE_MUST_CHECK is not set
index 31b6ec3..f721cc3 100644 (file)
@@ -63,4 +63,3 @@ CONFIG_TMPFS=y
 # CONFIG_MISC_FILESYSTEMS is not set
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3_ACL=y
-# CONFIG_ENABLE_MUST_CHECK is not set
index 41a0037..1419fc9 100644 (file)
@@ -26,9 +26,6 @@ CONFIG_UNIX=y
 CONFIG_UNIX_DIAG=y
 CONFIG_NET_KEY=y
 CONFIG_INET=y
-# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
-# CONFIG_INET_XFRM_MODE_TUNNEL is not set
-# CONFIG_INET_XFRM_MODE_BEET is not set
 # CONFIG_IPV6 is not set
 # CONFIG_WIRELESS is not set
 CONFIG_DEVTMPFS=y
@@ -37,7 +34,6 @@ CONFIG_DEVTMPFS=y
 # CONFIG_BLK_DEV is not set
 CONFIG_NETDEVICES=y
 # CONFIG_NET_VENDOR_ARC is not set
-# CONFIG_NET_CADENCE is not set
 # CONFIG_NET_VENDOR_BROADCOM is not set
 CONFIG_EZCHIP_NPS_MANAGEMENT_ENET=y
 # CONFIG_NET_VENDOR_INTEL is not set
@@ -74,5 +70,5 @@ CONFIG_TMPFS=y
 # CONFIG_MISC_FILESYSTEMS is not set
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3_ACL=y
-# CONFIG_ENABLE_MUST_CHECK is not set
 CONFIG_FTRACE=y
+# CONFIG_NET_VENDOR_CADENCE is not set
index 4a94d16..6f0d2be 100644 (file)
@@ -35,15 +35,11 @@ CONFIG_PACKET=y
 CONFIG_UNIX=y
 CONFIG_INET=y
 CONFIG_IP_MULTICAST=y
-# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
-# CONFIG_INET_XFRM_MODE_TUNNEL is not set
-# CONFIG_INET_XFRM_MODE_BEET is not set
 # CONFIG_INET_DIAG is not set
 # CONFIG_IPV6 is not set
 # CONFIG_WIRELESS is not set
 CONFIG_DEVTMPFS=y
 CONFIG_NETDEVICES=y
-# CONFIG_NET_CADENCE is not set
 # CONFIG_NET_VENDOR_BROADCOM is not set
 # CONFIG_NET_VENDOR_INTEL is not set
 # CONFIG_NET_VENDOR_MARVELL is not set
@@ -94,12 +90,11 @@ CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y
 CONFIG_STRIP_ASM_SYMS=y
 CONFIG_DEBUG_FS=y
 CONFIG_HEADERS_INSTALL=y
-CONFIG_HEADERS_CHECK=y
 CONFIG_DEBUG_SECTION_MISMATCH=y
 CONFIG_MAGIC_SYSRQ=y
 CONFIG_DEBUG_MEMORY_INIT=y
 CONFIG_DEBUG_STACKOVERFLOW=y
 CONFIG_DETECT_HUNG_TASK=y
 CONFIG_SCHEDSTATS=y
-CONFIG_TIMER_STATS=y
 # CONFIG_CRYPTO_HW is not set
+# CONFIG_NET_VENDOR_CADENCE is not set
index 0c3b214..d3ef189 100644 (file)
@@ -58,8 +58,6 @@ CONFIG_SERIAL_OF_PLATFORM=y
 # CONFIG_HW_RANDOM is not set
 # CONFIG_HWMON is not set
 CONFIG_FB=y
-CONFIG_ARCPGU_RGB888=y
-CONFIG_ARCPGU_DISPTYPE=0
 # CONFIG_VGA_CONSOLE is not set
 CONFIG_FRAMEBUFFER_CONSOLE=y
 CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
@@ -87,7 +85,6 @@ CONFIG_NFS_FS=y
 CONFIG_NFS_V3_ACL=y
 CONFIG_NLS_CODEPAGE_437=y
 CONFIG_NLS_ISO8859_1=y
-# CONFIG_ENABLE_MUST_CHECK is not set
 CONFIG_STRIP_ASM_SYMS=y
 CONFIG_DEBUG_SHIRQ=y
 CONFIG_SOFTLOCKUP_DETECTOR=y
index f9ad9d3..944b347 100644 (file)
@@ -91,7 +91,6 @@ CONFIG_NFS_FS=y
 CONFIG_NFS_V3_ACL=y
 CONFIG_NLS_CODEPAGE_437=y
 CONFIG_NLS_ISO8859_1=y
-# CONFIG_ENABLE_MUST_CHECK is not set
 CONFIG_STRIP_ASM_SYMS=y
 CONFIG_DEBUG_SHIRQ=y
 CONFIG_SOFTLOCKUP_DETECTOR=y
index bdb7e19..f5a9364 100644 (file)
@@ -82,7 +82,7 @@ static inline __attribute__ ((const)) int fls(unsigned int x)
 /*
  * __fls: Similar to fls, but zero based (0-31)
  */
-static inline __attribute__ ((const)) int __fls(unsigned long x)
+static inline __attribute__ ((const)) unsigned long __fls(unsigned long x)
 {
        if (!x)
                return 0;
@@ -131,7 +131,7 @@ static inline __attribute__ ((const)) int fls(unsigned int x)
 /*
  * __fls: Similar to fls, but zero based (0-31). Also 0 if no bit set
  */
-static inline __attribute__ ((const)) int __fls(unsigned long x)
+static inline __attribute__ ((const)) unsigned long __fls(unsigned long x)
 {
        /* FLS insn has exactly same semantics as the API */
        return  __builtin_arc_fls(x);
index 5aab4f9..67ff06e 100644 (file)
@@ -21,7 +21,7 @@
  *      r25 contains the kernel current task ptr
  *  - Defined Stack Switching Macro to be reused in all intr/excp hdlrs
  *  - Shaved off 11 instructions from RESTORE_ALL_INT1 by using the
- *      address Write back load ld.ab instead of seperate ld/add instn
+ *      address Write back load ld.ab instead of separate ld/add instn
  *
  * Amit Bhor, Sameer Dhavale: Codito Technologies 2004
  */
index 8f777d6..8034738 100644 (file)
@@ -32,7 +32,7 @@ static inline void ioport_unmap(void __iomem *addr)
 {
 }
 
-extern void iounmap(const void __iomem *addr);
+extern void iounmap(const volatile void __iomem *addr);
 
 /*
  * io{read,write}{16,32}be() macros
index 64ca25d..ef68758 100644 (file)
 #define pmd_pfn(pmd)           ((pmd_val(pmd) & PAGE_MASK) >> PAGE_SHIFT)
 #define pmd_page(pmd)          virt_to_page(pmd_page_vaddr(pmd))
 #define set_pmd(pmdp, pmd)     (*(pmdp) = pmd)
-#define pmd_pgtable(pmd)       ((pgtable_t) pmd_page_vaddr(pmd))
+#define pmd_pgtable(pmd)       ((pgtable_t) pmd_page(pmd))
 
 /*
  * 4th level paging: pte
index ab9e75e..ad93fe6 100644 (file)
@@ -385,7 +385,7 @@ irqreturn_t do_IPI(int irq, void *dev_id)
  * API called by platform code to hookup arch-common ISR to their IPI IRQ
  *
  * Note: If IPI is provided by platform (vs. say ARC MCIP), their intc setup/map
- * function needs to call call irq_set_percpu_devid() for IPI IRQ, otherwise
+ * function needs to call irq_set_percpu_devid() for IPI IRQ, otherwise
  * request_percpu_irq() below will fail
  */
 static DEFINE_PER_CPU(int, ipi_dev);
index 5446967..55c6de1 100644 (file)
@@ -750,7 +750,7 @@ static inline void arc_slc_enable(void)
  *  -In SMP, if hardware caches are coherent
  *
  * There's a corollary case, where kernel READs from a userspace mapped page.
- * If the U-mapping is not congruent to to K-mapping, former needs flushing.
+ * If the U-mapping is not congruent to K-mapping, former needs flushing.
  */
 void flush_dcache_page(struct page *page)
 {
@@ -910,7 +910,7 @@ EXPORT_SYMBOL(flush_icache_range);
  * @vaddr is typically user vaddr (breakpoint) or kernel vaddr (vmalloc)
  *    However in one instance, when called by kprobe (for a breakpt in
  *    builtin kernel code) @vaddr will be paddr only, meaning CDU operation will
- *    use a paddr to index the cache (despite VIPT). This is fine since since a
+ *    use a paddr to index the cache (despite VIPT). This is fine since a
  *    builtin kernel page will not have any virtual mappings.
  *    kprobe on loadable module will be kernel vaddr.
  */
index 0ee75ac..712c231 100644 (file)
@@ -94,7 +94,7 @@ void __iomem *ioremap_prot(phys_addr_t paddr, unsigned long size,
 EXPORT_SYMBOL(ioremap_prot);
 
 
-void iounmap(const void __iomem *addr)
+void iounmap(const volatile void __iomem *addr)
 {
        /* weird double cast to handle phys_addr_t > 32 bits */
        if (arc_uncached_addr_space((phys_addr_t)(u32)addr))
index 6b48a3a..fa78595 100644 (file)
@@ -411,14 +411,16 @@ config RISCV_ISA_SVPBMT
 
           If you don't know what to do here, say Y.
 
-config CC_HAS_ZICBOM
+config TOOLCHAIN_HAS_ZICBOM
        bool
-       default y if 64BIT && $(cc-option,-mabi=lp64 -march=rv64ima_zicbom)
-       default y if 32BIT && $(cc-option,-mabi=ilp32 -march=rv32ima_zicbom)
+       default y
+       depends on !64BIT || $(cc-option,-mabi=lp64 -march=rv64ima_zicbom)
+       depends on !32BIT || $(cc-option,-mabi=ilp32 -march=rv32ima_zicbom)
+       depends on LLD_VERSION >= 150000 || LD_VERSION >= 23800
 
 config RISCV_ISA_ZICBOM
        bool "Zicbom extension support for non-coherent DMA operation"
-       depends on CC_HAS_ZICBOM
+       depends on TOOLCHAIN_HAS_ZICBOM
        depends on !XIP_KERNEL && MMU
        select RISCV_DMA_NONCOHERENT
        select RISCV_ALTERNATIVE
@@ -433,6 +435,13 @@ config RISCV_ISA_ZICBOM
 
           If you don't know what to do here, say Y.
 
+config TOOLCHAIN_HAS_ZIHINTPAUSE
+       bool
+       default y
+       depends on !64BIT || $(cc-option,-mabi=lp64 -march=rv64ima_zihintpause)
+       depends on !32BIT || $(cc-option,-mabi=ilp32 -march=rv32ima_zihintpause)
+       depends on LLD_VERSION >= 150000 || LD_VERSION >= 23600
+
 config FPU
        bool "FPU support"
        default y
index 1c8ec65..0d13b59 100644 (file)
@@ -59,12 +59,10 @@ toolchain-need-zicsr-zifencei := $(call cc-option-yn, -march=$(riscv-march-y)_zi
 riscv-march-$(toolchain-need-zicsr-zifencei) := $(riscv-march-y)_zicsr_zifencei
 
 # Check if the toolchain supports Zicbom extension
-toolchain-supports-zicbom := $(call cc-option-yn, -march=$(riscv-march-y)_zicbom)
-riscv-march-$(toolchain-supports-zicbom) := $(riscv-march-y)_zicbom
+riscv-march-$(CONFIG_TOOLCHAIN_HAS_ZICBOM) := $(riscv-march-y)_zicbom
 
 # Check if the toolchain supports Zihintpause extension
-toolchain-supports-zihintpause := $(call cc-option-yn, -march=$(riscv-march-y)_zihintpause)
-riscv-march-$(toolchain-supports-zihintpause) := $(riscv-march-y)_zihintpause
+riscv-march-$(CONFIG_TOOLCHAIN_HAS_ZIHINTPAUSE) := $(riscv-march-y)_zihintpause
 
 KBUILD_CFLAGS += -march=$(subst fd,,$(riscv-march-y))
 KBUILD_AFLAGS += -march=$(riscv-march-y)
index 38af2ec..6d58bbb 100644 (file)
@@ -14,8 +14,8 @@
 
 #define JUMP_LABEL_NOP_SIZE 4
 
-static __always_inline bool arch_static_branch(struct static_key *key,
-                                              bool branch)
+static __always_inline bool arch_static_branch(struct static_key * const key,
+                                              const bool branch)
 {
        asm_volatile_goto(
                "       .option push                            \n\t"
@@ -35,8 +35,8 @@ label:
        return true;
 }
 
-static __always_inline bool arch_static_branch_jump(struct static_key *key,
-                                                   bool branch)
+static __always_inline bool arch_static_branch_jump(struct static_key * const key,
+                                                   const bool branch)
 {
        asm_volatile_goto(
                "       .option push                            \n\t"
index 1e4f8b4..fa70cfe 100644 (file)
@@ -21,7 +21,7 @@ static inline void cpu_relax(void)
                 * Reduce instruction retirement.
                 * This assumes the PC changes.
                 */
-#ifdef __riscv_zihintpause
+#ifdef CONFIG_TOOLCHAIN_HAS_ZIHINTPAUSE
                __asm__ __volatile__ ("pause");
 #else
                /* Encoding of the pause instruction */
index fa427bd..852eccc 100644 (file)
@@ -213,6 +213,9 @@ static void print_mmu(struct seq_file *f)
 
 static void *c_start(struct seq_file *m, loff_t *pos)
 {
+       if (*pos == nr_cpu_ids)
+               return NULL;
+
        *pos = cpumask_next(*pos - 1, cpu_online_mask);
        if ((*pos) < nr_cpu_ids)
                return (void *)(uintptr_t)(1 + *pos);
index a22e418..e122670 100644 (file)
@@ -113,6 +113,8 @@ static void __init kasan_populate_pud(pgd_t *pgd,
                base_pud = pt_ops.get_pud_virt(pfn_to_phys(_pgd_pfn(*pgd)));
        } else if (pgd_none(*pgd)) {
                base_pud = memblock_alloc(PTRS_PER_PUD * sizeof(pud_t), PAGE_SIZE);
+               memcpy(base_pud, (void *)kasan_early_shadow_pud,
+                       sizeof(pud_t) * PTRS_PER_PUD);
        } else {
                base_pud = (pud_t *)pgd_page_vaddr(*pgd);
                if (base_pud == lm_alias(kasan_early_shadow_pud)) {
@@ -173,8 +175,11 @@ static void __init kasan_populate_p4d(pgd_t *pgd,
                base_p4d = pt_ops.get_p4d_virt(pfn_to_phys(_pgd_pfn(*pgd)));
        } else {
                base_p4d = (p4d_t *)pgd_page_vaddr(*pgd);
-               if (base_p4d == lm_alias(kasan_early_shadow_p4d))
+               if (base_p4d == lm_alias(kasan_early_shadow_p4d)) {
                        base_p4d = memblock_alloc(PTRS_PER_PUD * sizeof(p4d_t), PAGE_SIZE);
+                       memcpy(base_p4d, (void *)kasan_early_shadow_p4d,
+                               sizeof(p4d_t) * PTRS_PER_P4D);
+               }
        }
 
        p4dp = base_p4d + p4d_index(vaddr);
index b7664d0..8fa58b0 100644 (file)
 #include <asm/cpu_device_id.h>
 #include <asm/simd.h>
 
+#define POLYVAL_ALIGN  16
+#define POLYVAL_ALIGN_ATTR __aligned(POLYVAL_ALIGN)
+#define POLYVAL_ALIGN_EXTRA ((POLYVAL_ALIGN - 1) & ~(CRYPTO_MINALIGN - 1))
+#define POLYVAL_CTX_SIZE (sizeof(struct polyval_tfm_ctx) + POLYVAL_ALIGN_EXTRA)
 #define NUM_KEY_POWERS 8
 
 struct polyval_tfm_ctx {
        /*
         * These powers must be in the order h^8, ..., h^1.
         */
-       u8 key_powers[NUM_KEY_POWERS][POLYVAL_BLOCK_SIZE];
+       u8 key_powers[NUM_KEY_POWERS][POLYVAL_BLOCK_SIZE] POLYVAL_ALIGN_ATTR;
 };
 
 struct polyval_desc_ctx {
@@ -45,6 +49,11 @@ asmlinkage void clmul_polyval_update(const struct polyval_tfm_ctx *keys,
        const u8 *in, size_t nblocks, u8 *accumulator);
 asmlinkage void clmul_polyval_mul(u8 *op1, const u8 *op2);
 
+static inline struct polyval_tfm_ctx *polyval_tfm_ctx(struct crypto_shash *tfm)
+{
+       return PTR_ALIGN(crypto_shash_ctx(tfm), POLYVAL_ALIGN);
+}
+
 static void internal_polyval_update(const struct polyval_tfm_ctx *keys,
        const u8 *in, size_t nblocks, u8 *accumulator)
 {
@@ -72,7 +81,7 @@ static void internal_polyval_mul(u8 *op1, const u8 *op2)
 static int polyval_x86_setkey(struct crypto_shash *tfm,
                        const u8 *key, unsigned int keylen)
 {
-       struct polyval_tfm_ctx *tctx = crypto_shash_ctx(tfm);
+       struct polyval_tfm_ctx *tctx = polyval_tfm_ctx(tfm);
        int i;
 
        if (keylen != POLYVAL_BLOCK_SIZE)
@@ -102,7 +111,7 @@ static int polyval_x86_update(struct shash_desc *desc,
                         const u8 *src, unsigned int srclen)
 {
        struct polyval_desc_ctx *dctx = shash_desc_ctx(desc);
-       const struct polyval_tfm_ctx *tctx = crypto_shash_ctx(desc->tfm);
+       const struct polyval_tfm_ctx *tctx = polyval_tfm_ctx(desc->tfm);
        u8 *pos;
        unsigned int nblocks;
        unsigned int n;
@@ -143,7 +152,7 @@ static int polyval_x86_update(struct shash_desc *desc,
 static int polyval_x86_final(struct shash_desc *desc, u8 *dst)
 {
        struct polyval_desc_ctx *dctx = shash_desc_ctx(desc);
-       const struct polyval_tfm_ctx *tctx = crypto_shash_ctx(desc->tfm);
+       const struct polyval_tfm_ctx *tctx = polyval_tfm_ctx(desc->tfm);
 
        if (dctx->bytes) {
                internal_polyval_mul(dctx->buffer,
@@ -167,7 +176,7 @@ static struct shash_alg polyval_alg = {
                .cra_driver_name        = "polyval-clmulni",
                .cra_priority           = 200,
                .cra_blocksize          = POLYVAL_BLOCK_SIZE,
-               .cra_ctxsize            = sizeof(struct polyval_tfm_ctx),
+               .cra_ctxsize            = POLYVAL_CTX_SIZE,
                .cra_module             = THIS_MODULE,
        },
 };
index 97342c4..2e5a045 100644 (file)
@@ -587,6 +587,10 @@ static inline pgprot_t verify_rwx(pgprot_t old, pgprot_t new, unsigned long star
 {
        unsigned long end;
 
+       /* Kernel text is rw at boot up */
+       if (system_state == SYSTEM_BOOTING)
+               return new;
+
        /*
         * 32-bit has some unfixable W+X issues, like EFI code
         * and writeable data being in the same page.  Disable
index 9962042..00127ab 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/bpf.h>
 #include <linux/memory.h>
 #include <linux/sort.h>
+#include <linux/init.h>
 #include <asm/extable.h>
 #include <asm/set_memory.h>
 #include <asm/nospec-branch.h>
@@ -388,6 +389,18 @@ out:
        return ret;
 }
 
+int __init bpf_arch_init_dispatcher_early(void *ip)
+{
+       const u8 *nop_insn = x86_nops[5];
+
+       if (is_endbr(*(u32 *)ip))
+               ip += ENDBR_INSN_SIZE;
+
+       if (memcmp(ip, nop_insn, X86_PATCH_SIZE))
+               text_poke_early(ip, nop_insn, X86_PATCH_SIZE);
+       return 0;
+}
+
 int bpf_arch_text_poke(void *ip, enum bpf_text_poke_type t,
                       void *old_addr, void *new_addr)
 {
index ee4ce5b..3e252be 100644 (file)
@@ -27,7 +27,7 @@
  * Arbitrary retries in case the remote processor is slow to respond
  * to PCC commands
  */
-#define PCC_CMD_WAIT_RETRIES_NUM       500
+#define PCC_CMD_WAIT_RETRIES_NUM       500ULL
 
 struct pcc_data {
        struct pcc_mbox_chan *pcc_chan;
index 78c2804..f27914a 100644 (file)
@@ -425,6 +425,13 @@ static const struct dmi_system_id asus_laptop[] = {
                        DMI_MATCH(DMI_BOARD_NAME, "S5402ZA"),
                },
        },
+       {
+               .ident = "Asus Vivobook S5602ZA",
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+                       DMI_MATCH(DMI_BOARD_NAME, "S5602ZA"),
+               },
+       },
        { }
 };
 
index 024cc37..b47e93a 100644 (file)
@@ -789,6 +789,7 @@ static bool acpi_info_matches_ids(struct acpi_device_info *info,
 static const char * const acpi_ignore_dep_ids[] = {
        "PNP0D80", /* Windows-compatible System Power Management Controller */
        "INT33BD", /* Intel Baytrail Mailbox Device */
+       "LATT2021", /* Lattice FW Update Client Driver */
        NULL
 };
 
index 0d9064a..9cd8797 100644 (file)
@@ -668,6 +668,11 @@ static const struct dmi_system_id video_detect_dmi_table[] = {
        { },
 };
 
+static bool google_cros_ec_present(void)
+{
+       return acpi_dev_found("GOOG0004");
+}
+
 /*
  * Determine which type of backlight interface to use on this system,
  * First check cmdline, then dmi quirks, then do autodetect.
@@ -730,6 +735,13 @@ static enum acpi_backlight_type __acpi_video_get_backlight_type(bool native)
                        return acpi_backlight_video;
        }
 
+       /*
+        * Chromebooks that don't have backlight handle in ACPI table
+        * are supposed to use native backlight if it's available.
+        */
+       if (google_cros_ec_present() && native_available)
+               return acpi_backlight_native;
+
        /* No ACPI video (old hw), use vendor specific fw methods. */
        return acpi_backlight_vendor;
 }
index ead135c..6471b55 100644 (file)
@@ -2952,6 +2952,10 @@ static int genpd_iterate_idle_states(struct device_node *dn,
                np = it.node;
                if (!of_match_node(idle_state_match, np))
                        continue;
+
+               if (!of_device_is_available(np))
+                       continue;
+
                if (states) {
                        ret = genpd_parse_state(&states[i], np);
                        if (ret) {
index 4d6278a..2a5a37f 100644 (file)
@@ -229,7 +229,7 @@ EXPORT_SYMBOL_GPL(device_property_read_string);
  * Find a given string in a string array and if it is found return the
  * index back.
  *
- * Return: %0 if the property was found (success),
+ * Return: index, starting from %0, if the property was found (success),
  *        %-EINVAL if given arguments are not valid,
  *        %-ENODATA if the property does not have a value,
  *        %-EPROTO if the property is not an array of strings,
@@ -450,7 +450,7 @@ EXPORT_SYMBOL_GPL(fwnode_property_read_string);
  * Find a given string in a string array and if it is found return the
  * index back.
  *
- * Return: %0 if the property was found (success),
+ * Return: index, starting from %0, if the property was found (success),
  *        %-EINVAL if given arguments are not valid,
  *        %-ENODATA if the property does not have a value,
  *        %-EPROTO if the property is not an array of strings,
index fc3ebeb..6ff73c3 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/pm_qos.h>
 #include <trace/events/power.h>
 
+#include <asm/cpu.h>
 #include <asm/div64.h>
 #include <asm/msr.h>
 #include <asm/cpu_device_id.h>
@@ -280,10 +281,10 @@ static struct cpudata **all_cpu_data;
  * structure is used to store those callbacks.
  */
 struct pstate_funcs {
-       int (*get_max)(void);
-       int (*get_max_physical)(void);
-       int (*get_min)(void);
-       int (*get_turbo)(void);
+       int (*get_max)(int cpu);
+       int (*get_max_physical)(int cpu);
+       int (*get_min)(int cpu);
+       int (*get_turbo)(int cpu);
        int (*get_scaling)(void);
        int (*get_cpu_scaling)(int cpu);
        int (*get_aperf_mperf_shift)(void);
@@ -398,16 +399,6 @@ static int intel_pstate_get_cppc_guaranteed(int cpu)
 
        return cppc_perf.nominal_perf;
 }
-
-static u32 intel_pstate_cppc_nominal(int cpu)
-{
-       u64 nominal_perf;
-
-       if (cppc_get_nominal_perf(cpu, &nominal_perf))
-               return 0;
-
-       return nominal_perf;
-}
 #else /* CONFIG_ACPI_CPPC_LIB */
 static inline void intel_pstate_set_itmt_prio(int cpu)
 {
@@ -531,35 +522,18 @@ static void intel_pstate_hybrid_hwp_adjust(struct cpudata *cpu)
 {
        int perf_ctl_max_phys = cpu->pstate.max_pstate_physical;
        int perf_ctl_scaling = cpu->pstate.perf_ctl_scaling;
-       int perf_ctl_turbo = pstate_funcs.get_turbo();
-       int turbo_freq = perf_ctl_turbo * perf_ctl_scaling;
+       int perf_ctl_turbo = pstate_funcs.get_turbo(cpu->cpu);
        int scaling = cpu->pstate.scaling;
 
        pr_debug("CPU%d: perf_ctl_max_phys = %d\n", cpu->cpu, perf_ctl_max_phys);
-       pr_debug("CPU%d: perf_ctl_max = %d\n", cpu->cpu, pstate_funcs.get_max());
        pr_debug("CPU%d: perf_ctl_turbo = %d\n", cpu->cpu, perf_ctl_turbo);
        pr_debug("CPU%d: perf_ctl_scaling = %d\n", cpu->cpu, perf_ctl_scaling);
        pr_debug("CPU%d: HWP_CAP guaranteed = %d\n", cpu->cpu, cpu->pstate.max_pstate);
        pr_debug("CPU%d: HWP_CAP highest = %d\n", cpu->cpu, cpu->pstate.turbo_pstate);
        pr_debug("CPU%d: HWP-to-frequency scaling factor: %d\n", cpu->cpu, scaling);
 
-       /*
-        * If the product of the HWP performance scaling factor and the HWP_CAP
-        * highest performance is greater than the maximum turbo frequency
-        * corresponding to the pstate_funcs.get_turbo() return value, the
-        * scaling factor is too high, so recompute it to make the HWP_CAP
-        * highest performance correspond to the maximum turbo frequency.
-        */
-       cpu->pstate.turbo_freq = cpu->pstate.turbo_pstate * scaling;
-       if (turbo_freq < cpu->pstate.turbo_freq) {
-               cpu->pstate.turbo_freq = turbo_freq;
-               scaling = DIV_ROUND_UP(turbo_freq, cpu->pstate.turbo_pstate);
-               cpu->pstate.scaling = scaling;
-
-               pr_debug("CPU%d: refined HWP-to-frequency scaling factor: %d\n",
-                        cpu->cpu, scaling);
-       }
-
+       cpu->pstate.turbo_freq = rounddown(cpu->pstate.turbo_pstate * scaling,
+                                          perf_ctl_scaling);
        cpu->pstate.max_freq = rounddown(cpu->pstate.max_pstate * scaling,
                                         perf_ctl_scaling);
 
@@ -1740,7 +1714,7 @@ static void intel_pstate_hwp_enable(struct cpudata *cpudata)
        intel_pstate_update_epp_defaults(cpudata);
 }
 
-static int atom_get_min_pstate(void)
+static int atom_get_min_pstate(int not_used)
 {
        u64 value;
 
@@ -1748,7 +1722,7 @@ static int atom_get_min_pstate(void)
        return (value >> 8) & 0x7F;
 }
 
-static int atom_get_max_pstate(void)
+static int atom_get_max_pstate(int not_used)
 {
        u64 value;
 
@@ -1756,7 +1730,7 @@ static int atom_get_max_pstate(void)
        return (value >> 16) & 0x7F;
 }
 
-static int atom_get_turbo_pstate(void)
+static int atom_get_turbo_pstate(int not_used)
 {
        u64 value;
 
@@ -1834,23 +1808,23 @@ static void atom_get_vid(struct cpudata *cpudata)
        cpudata->vid.turbo = value & 0x7f;
 }
 
-static int core_get_min_pstate(void)
+static int core_get_min_pstate(int cpu)
 {
        u64 value;
 
-       rdmsrl(MSR_PLATFORM_INFO, value);
+       rdmsrl_on_cpu(cpu, MSR_PLATFORM_INFO, &value);
        return (value >> 40) & 0xFF;
 }
 
-static int core_get_max_pstate_physical(void)
+static int core_get_max_pstate_physical(int cpu)
 {
        u64 value;
 
-       rdmsrl(MSR_PLATFORM_INFO, value);
+       rdmsrl_on_cpu(cpu, MSR_PLATFORM_INFO, &value);
        return (value >> 8) & 0xFF;
 }
 
-static int core_get_tdp_ratio(u64 plat_info)
+static int core_get_tdp_ratio(int cpu, u64 plat_info)
 {
        /* Check how many TDP levels present */
        if (plat_info & 0x600000000) {
@@ -1860,13 +1834,13 @@ static int core_get_tdp_ratio(u64 plat_info)
                int err;
 
                /* Get the TDP level (0, 1, 2) to get ratios */
-               err = rdmsrl_safe(MSR_CONFIG_TDP_CONTROL, &tdp_ctrl);
+               err = rdmsrl_safe_on_cpu(cpu, MSR_CONFIG_TDP_CONTROL, &tdp_ctrl);
                if (err)
                        return err;
 
                /* TDP MSR are continuous starting at 0x648 */
                tdp_msr = MSR_CONFIG_TDP_NOMINAL + (tdp_ctrl & 0x03);
-               err = rdmsrl_safe(tdp_msr, &tdp_ratio);
+               err = rdmsrl_safe_on_cpu(cpu, tdp_msr, &tdp_ratio);
                if (err)
                        return err;
 
@@ -1883,7 +1857,7 @@ static int core_get_tdp_ratio(u64 plat_info)
        return -ENXIO;
 }
 
-static int core_get_max_pstate(void)
+static int core_get_max_pstate(int cpu)
 {
        u64 tar;
        u64 plat_info;
@@ -1891,10 +1865,10 @@ static int core_get_max_pstate(void)
        int tdp_ratio;
        int err;
 
-       rdmsrl(MSR_PLATFORM_INFO, plat_info);
+       rdmsrl_on_cpu(cpu, MSR_PLATFORM_INFO, &plat_info);
        max_pstate = (plat_info >> 8) & 0xFF;
 
-       tdp_ratio = core_get_tdp_ratio(plat_info);
+       tdp_ratio = core_get_tdp_ratio(cpu, plat_info);
        if (tdp_ratio <= 0)
                return max_pstate;
 
@@ -1903,7 +1877,7 @@ static int core_get_max_pstate(void)
                return tdp_ratio;
        }
 
-       err = rdmsrl_safe(MSR_TURBO_ACTIVATION_RATIO, &tar);
+       err = rdmsrl_safe_on_cpu(cpu, MSR_TURBO_ACTIVATION_RATIO, &tar);
        if (!err) {
                int tar_levels;
 
@@ -1918,13 +1892,13 @@ static int core_get_max_pstate(void)
        return max_pstate;
 }
 
-static int core_get_turbo_pstate(void)
+static int core_get_turbo_pstate(int cpu)
 {
        u64 value;
        int nont, ret;
 
-       rdmsrl(MSR_TURBO_RATIO_LIMIT, value);
-       nont = core_get_max_pstate();
+       rdmsrl_on_cpu(cpu, MSR_TURBO_RATIO_LIMIT, &value);
+       nont = core_get_max_pstate(cpu);
        ret = (value) & 255;
        if (ret <= nont)
                ret = nont;
@@ -1952,50 +1926,37 @@ static int knl_get_aperf_mperf_shift(void)
        return 10;
 }
 
-static int knl_get_turbo_pstate(void)
+static int knl_get_turbo_pstate(int cpu)
 {
        u64 value;
        int nont, ret;
 
-       rdmsrl(MSR_TURBO_RATIO_LIMIT, value);
-       nont = core_get_max_pstate();
+       rdmsrl_on_cpu(cpu, MSR_TURBO_RATIO_LIMIT, &value);
+       nont = core_get_max_pstate(cpu);
        ret = (((value) >> 8) & 0xFF);
        if (ret <= nont)
                ret = nont;
        return ret;
 }
 
-#ifdef CONFIG_ACPI_CPPC_LIB
-static u32 hybrid_ref_perf;
-
-static int hybrid_get_cpu_scaling(int cpu)
+static void hybrid_get_type(void *data)
 {
-       return DIV_ROUND_UP(core_get_scaling() * hybrid_ref_perf,
-                           intel_pstate_cppc_nominal(cpu));
+       u8 *cpu_type = data;
+
+       *cpu_type = get_this_hybrid_cpu_type();
 }
 
-static void intel_pstate_cppc_set_cpu_scaling(void)
+static int hybrid_get_cpu_scaling(int cpu)
 {
-       u32 min_nominal_perf = U32_MAX;
-       int cpu;
+       u8 cpu_type = 0;
 
-       for_each_present_cpu(cpu) {
-               u32 nominal_perf = intel_pstate_cppc_nominal(cpu);
+       smp_call_function_single(cpu, hybrid_get_type, &cpu_type, 1);
+       /* P-cores have a smaller perf level-to-freqency scaling factor. */
+       if (cpu_type == 0x40)
+               return 78741;
 
-               if (nominal_perf && nominal_perf < min_nominal_perf)
-                       min_nominal_perf = nominal_perf;
-       }
-
-       if (min_nominal_perf < U32_MAX) {
-               hybrid_ref_perf = min_nominal_perf;
-               pstate_funcs.get_cpu_scaling = hybrid_get_cpu_scaling;
-       }
+       return core_get_scaling();
 }
-#else
-static inline void intel_pstate_cppc_set_cpu_scaling(void)
-{
-}
-#endif /* CONFIG_ACPI_CPPC_LIB */
 
 static void intel_pstate_set_pstate(struct cpudata *cpu, int pstate)
 {
@@ -2025,10 +1986,10 @@ static void intel_pstate_max_within_limits(struct cpudata *cpu)
 
 static void intel_pstate_get_cpu_pstates(struct cpudata *cpu)
 {
-       int perf_ctl_max_phys = pstate_funcs.get_max_physical();
+       int perf_ctl_max_phys = pstate_funcs.get_max_physical(cpu->cpu);
        int perf_ctl_scaling = pstate_funcs.get_scaling();
 
-       cpu->pstate.min_pstate = pstate_funcs.get_min();
+       cpu->pstate.min_pstate = pstate_funcs.get_min(cpu->cpu);
        cpu->pstate.max_pstate_physical = perf_ctl_max_phys;
        cpu->pstate.perf_ctl_scaling = perf_ctl_scaling;
 
@@ -2044,8 +2005,8 @@ static void intel_pstate_get_cpu_pstates(struct cpudata *cpu)
                }
        } else {
                cpu->pstate.scaling = perf_ctl_scaling;
-               cpu->pstate.max_pstate = pstate_funcs.get_max();
-               cpu->pstate.turbo_pstate = pstate_funcs.get_turbo();
+               cpu->pstate.max_pstate = pstate_funcs.get_max(cpu->cpu);
+               cpu->pstate.turbo_pstate = pstate_funcs.get_turbo(cpu->cpu);
        }
 
        if (cpu->pstate.scaling == perf_ctl_scaling) {
@@ -3221,9 +3182,9 @@ static unsigned int force_load __initdata;
 
 static int __init intel_pstate_msrs_not_valid(void)
 {
-       if (!pstate_funcs.get_max() ||
-           !pstate_funcs.get_min() ||
-           !pstate_funcs.get_turbo())
+       if (!pstate_funcs.get_max(0) ||
+           !pstate_funcs.get_min(0) ||
+           !pstate_funcs.get_turbo(0))
                return -ENODEV;
 
        return 0;
@@ -3450,7 +3411,7 @@ static int __init intel_pstate_init(void)
                                default_driver = &intel_pstate;
 
                        if (boot_cpu_has(X86_FEATURE_HYBRID_CPU))
-                               intel_pstate_cppc_set_cpu_scaling();
+                               pstate_funcs.get_cpu_scaling = hybrid_get_cpu_scaling;
 
                        goto hwp_cpu_matched;
                }
index 978d397..84f44f7 100644 (file)
@@ -510,13 +510,13 @@ kfd_mem_dmamap_userptr(struct kgd_mem *mem,
        struct ttm_tt *ttm = bo->tbo.ttm;
        int ret;
 
+       if (WARN_ON(ttm->num_pages != src_ttm->num_pages))
+               return -EINVAL;
+
        ttm->sg = kmalloc(sizeof(*ttm->sg), GFP_KERNEL);
        if (unlikely(!ttm->sg))
                return -ENOMEM;
 
-       if (WARN_ON(ttm->num_pages != src_ttm->num_pages))
-               return -EINVAL;
-
        /* Same sequence as in amdgpu_ttm_tt_pin_userptr */
        ret = sg_alloc_table_from_pages(ttm->sg, src_ttm->pages,
                                        ttm->num_pages, 0,
index f6d9d5d..d2139ac 100644 (file)
@@ -326,7 +326,10 @@ static int amdgpu_ctx_init(struct amdgpu_ctx_mgr *mgr, int32_t priority,
        if (r)
                return r;
 
-       ctx->stable_pstate = current_stable_pstate;
+       if (mgr->adev->pm.stable_pstate_ctx)
+               ctx->stable_pstate = mgr->adev->pm.stable_pstate_ctx->stable_pstate;
+       else
+               ctx->stable_pstate = current_stable_pstate;
 
        return 0;
 }
index e0445e8..ddaecb2 100644 (file)
@@ -3210,6 +3210,15 @@ static int amdgpu_device_ip_resume_phase2(struct amdgpu_device *adev)
                        return r;
                }
                adev->ip_blocks[i].status.hw = true;
+
+               if (adev->in_s0ix && adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_SMC) {
+                       /* disable gfxoff for IP resume. The gfxoff will be re-enabled in
+                        * amdgpu_device_resume() after IP resume.
+                        */
+                       amdgpu_gfx_off_ctrl(adev, false);
+                       DRM_DEBUG("will disable gfxoff for re-initializing other blocks\n");
+               }
+
        }
 
        return 0;
@@ -4185,6 +4194,13 @@ int amdgpu_device_resume(struct drm_device *dev, bool fbcon)
        /* Make sure IB tests flushed */
        flush_delayed_work(&adev->delayed_init_work);
 
+       if (adev->in_s0ix) {
+               /* re-enable gfxoff after IP resume. This re-enables gfxoff after
+                * it was disabled for IP resume in amdgpu_device_ip_resume_phase2().
+                */
+               amdgpu_gfx_off_ctrl(adev, true);
+               DRM_DEBUG("will enable gfxoff for the mission mode\n");
+       }
        if (fbcon)
                drm_fb_helper_set_suspend_unlocked(adev_to_drm(adev)->fb_helper, false);
 
@@ -5381,7 +5397,7 @@ skip_hw_reset:
                        drm_sched_start(&ring->sched, !tmp_adev->asic_reset_res);
                }
 
-               if (adev->enable_mes)
+               if (adev->enable_mes && adev->ip_versions[GC_HWIP][0] != IP_VERSION(11, 0, 3))
                        amdgpu_mes_self_test(tmp_adev);
 
                if (!drm_drv_uses_atomic_modeset(adev_to_drm(tmp_adev)) && !job_signaled) {
index fe23e09..bf1ff8f 100644 (file)
@@ -344,6 +344,10 @@ static int amdgpu_firmware_info(struct drm_amdgpu_info_firmware *fw_info,
                fw_info->ver = adev->mes.ucode_fw_version[1];
                fw_info->feature = 0;
                break;
+       case AMDGPU_INFO_FW_IMU:
+               fw_info->ver = adev->gfx.imu_fw_version;
+               fw_info->feature = 0;
+               break;
        default:
                return -EINVAL;
        }
@@ -1520,6 +1524,15 @@ static int amdgpu_debugfs_firmware_info_show(struct seq_file *m, void *unused)
                           fw_info.feature, fw_info.ver);
        }
 
+       /* IMU */
+       query_fw.fw_type = AMDGPU_INFO_FW_IMU;
+       query_fw.index = 0;
+       ret = amdgpu_firmware_info(&fw_info, &query_fw, adev);
+       if (ret)
+               return ret;
+       seq_printf(m, "IMU feature version: %u, firmware version: 0x%08x\n",
+                  fw_info.feature, fw_info.ver);
+
        /* PSP SOS */
        query_fw.fw_type = AMDGPU_INFO_FW_SOS;
        ret = amdgpu_firmware_info(&fw_info, &query_fw, adev);
index dd0bc64..5cb62e6 100644 (file)
@@ -698,6 +698,7 @@ FW_VERSION_ATTR(rlc_srlg_fw_version, 0444, gfx.rlc_srlg_fw_version);
 FW_VERSION_ATTR(rlc_srls_fw_version, 0444, gfx.rlc_srls_fw_version);
 FW_VERSION_ATTR(mec_fw_version, 0444, gfx.mec_fw_version);
 FW_VERSION_ATTR(mec2_fw_version, 0444, gfx.mec2_fw_version);
+FW_VERSION_ATTR(imu_fw_version, 0444, gfx.imu_fw_version);
 FW_VERSION_ATTR(sos_fw_version, 0444, psp.sos.fw_version);
 FW_VERSION_ATTR(asd_fw_version, 0444, psp.asd_context.bin_desc.fw_version);
 FW_VERSION_ATTR(ta_ras_fw_version, 0444, psp.ras_context.context.bin_desc.fw_version);
@@ -719,7 +720,8 @@ static struct attribute *fw_attrs[] = {
        &dev_attr_ta_ras_fw_version.attr, &dev_attr_ta_xgmi_fw_version.attr,
        &dev_attr_smc_fw_version.attr, &dev_attr_sdma_fw_version.attr,
        &dev_attr_sdma2_fw_version.attr, &dev_attr_vcn_fw_version.attr,
-       &dev_attr_dmcu_fw_version.attr, NULL
+       &dev_attr_dmcu_fw_version.attr, &dev_attr_imu_fw_version.attr,
+       NULL
 };
 
 static const struct attribute_group fw_attr_group = {
index 9c765b0..c73abe5 100644 (file)
@@ -547,6 +547,7 @@ static void amdgpu_virt_populate_vf2pf_ucode_info(struct amdgpu_device *adev)
        POPULATE_UCODE_INFO(vf2pf_info, AMD_SRIOV_UCODE_ID_RLC_SRLS, adev->gfx.rlc_srls_fw_version);
        POPULATE_UCODE_INFO(vf2pf_info, AMD_SRIOV_UCODE_ID_MEC,      adev->gfx.mec_fw_version);
        POPULATE_UCODE_INFO(vf2pf_info, AMD_SRIOV_UCODE_ID_MEC2,     adev->gfx.mec2_fw_version);
+       POPULATE_UCODE_INFO(vf2pf_info, AMD_SRIOV_UCODE_ID_IMU,      adev->gfx.imu_fw_version);
        POPULATE_UCODE_INFO(vf2pf_info, AMD_SRIOV_UCODE_ID_SOS,      adev->psp.sos.fw_version);
        POPULATE_UCODE_INFO(vf2pf_info, AMD_SRIOV_UCODE_ID_ASD,
                            adev->psp.asd_context.bin_desc.fw_version);
index e78e4c2..6c97148 100644 (file)
@@ -70,6 +70,7 @@ enum amd_sriov_ucode_engine_id {
        AMD_SRIOV_UCODE_ID_RLC_SRLS,
        AMD_SRIOV_UCODE_ID_MEC,
        AMD_SRIOV_UCODE_ID_MEC2,
+       AMD_SRIOV_UCODE_ID_IMU,
        AMD_SRIOV_UCODE_ID_SOS,
        AMD_SRIOV_UCODE_ID_ASD,
        AMD_SRIOV_UCODE_ID_TA_RAS,
index 671ca5a..0fecc5b 100644 (file)
@@ -5051,6 +5051,7 @@ static int gfx_v11_0_set_powergating_state(void *handle,
        switch (adev->ip_versions[GC_HWIP][0]) {
        case IP_VERSION(11, 0, 0):
        case IP_VERSION(11, 0, 2):
+       case IP_VERSION(11, 0, 3):
                amdgpu_gfx_off_ctrl(adev, enable);
                break;
        case IP_VERSION(11, 0, 1):
index fef7d02..f141fad 100644 (file)
@@ -98,7 +98,14 @@ static int mes_v11_0_submit_pkt_and_poll_completion(struct amdgpu_mes *mes,
        struct amdgpu_device *adev = mes->adev;
        struct amdgpu_ring *ring = &mes->ring;
        unsigned long flags;
+       signed long timeout = adev->usec_timeout;
 
+       if (amdgpu_emu_mode) {
+               timeout *= 100;
+       } else if (amdgpu_sriov_vf(adev)) {
+               /* Worst case in sriov where all other 15 VF timeout, each VF needs about 600ms */
+               timeout = 15 * 600 * 1000;
+       }
        BUG_ON(size % 4 != 0);
 
        spin_lock_irqsave(&mes->ring_lock, flags);
@@ -118,7 +125,7 @@ static int mes_v11_0_submit_pkt_and_poll_completion(struct amdgpu_mes *mes,
        DRM_DEBUG("MES msg=%d was emitted\n", x_pkt->header.opcode);
 
        r = amdgpu_fence_wait_polling(ring, ring->fence_drv.sync_seq,
-                     adev->usec_timeout * (amdgpu_emu_mode ? 100 : 1));
+                     timeout);
        if (r < 1) {
                DRM_ERROR("MES failed to response msg=%d\n",
                          x_pkt->header.opcode);
index 4d304f2..998b5d1 100644 (file)
@@ -32,8 +32,6 @@
 #include "gc/gc_10_1_0_offset.h"
 #include "soc15_common.h"
 
-#define mmMM_ATC_L2_MISC_CG_Sienna_Cichlid                      0x064d
-#define mmMM_ATC_L2_MISC_CG_Sienna_Cichlid_BASE_IDX             0
 #define mmDAGB0_CNTL_MISC2_Sienna_Cichlid                       0x0070
 #define mmDAGB0_CNTL_MISC2_Sienna_Cichlid_BASE_IDX              0
 
@@ -574,7 +572,6 @@ static void mmhub_v2_0_update_medium_grain_clock_gating(struct amdgpu_device *ad
        case IP_VERSION(2, 1, 0):
        case IP_VERSION(2, 1, 1):
        case IP_VERSION(2, 1, 2):
-               def  = data  = RREG32_SOC15(MMHUB, 0, mmMM_ATC_L2_MISC_CG_Sienna_Cichlid);
                def1 = data1 = RREG32_SOC15(MMHUB, 0, mmDAGB0_CNTL_MISC2_Sienna_Cichlid);
                break;
        default:
@@ -608,8 +605,6 @@ static void mmhub_v2_0_update_medium_grain_clock_gating(struct amdgpu_device *ad
        case IP_VERSION(2, 1, 0):
        case IP_VERSION(2, 1, 1):
        case IP_VERSION(2, 1, 2):
-               if (def != data)
-                       WREG32_SOC15(MMHUB, 0, mmMM_ATC_L2_MISC_CG_Sienna_Cichlid, data);
                if (def1 != data1)
                        WREG32_SOC15(MMHUB, 0, mmDAGB0_CNTL_MISC2_Sienna_Cichlid, data1);
                break;
@@ -634,8 +629,8 @@ static void mmhub_v2_0_update_medium_grain_light_sleep(struct amdgpu_device *ade
        case IP_VERSION(2, 1, 0):
        case IP_VERSION(2, 1, 1):
        case IP_VERSION(2, 1, 2):
-               def  = data  = RREG32_SOC15(MMHUB, 0, mmMM_ATC_L2_MISC_CG_Sienna_Cichlid);
-               break;
+               /* There is no ATCL2 in MMHUB for 2.1.x */
+               return;
        default:
                def  = data  = RREG32_SOC15(MMHUB, 0, mmMM_ATC_L2_MISC_CG);
                break;
@@ -646,18 +641,8 @@ static void mmhub_v2_0_update_medium_grain_light_sleep(struct amdgpu_device *ade
        else
                data &= ~MM_ATC_L2_MISC_CG__MEM_LS_ENABLE_MASK;
 
-       if (def != data) {
-               switch (adev->ip_versions[MMHUB_HWIP][0]) {
-               case IP_VERSION(2, 1, 0):
-               case IP_VERSION(2, 1, 1):
-               case IP_VERSION(2, 1, 2):
-                       WREG32_SOC15(MMHUB, 0, mmMM_ATC_L2_MISC_CG_Sienna_Cichlid, data);
-                       break;
-               default:
-                       WREG32_SOC15(MMHUB, 0, mmMM_ATC_L2_MISC_CG, data);
-                       break;
-               }
-       }
+       if (def != data)
+               WREG32_SOC15(MMHUB, 0, mmMM_ATC_L2_MISC_CG, data);
 }
 
 static int mmhub_v2_0_set_clockgating(struct amdgpu_device *adev,
@@ -695,7 +680,10 @@ static void mmhub_v2_0_get_clockgating(struct amdgpu_device *adev, u64 *flags)
        case IP_VERSION(2, 1, 0):
        case IP_VERSION(2, 1, 1):
        case IP_VERSION(2, 1, 2):
-               data  = RREG32_SOC15(MMHUB, 0, mmMM_ATC_L2_MISC_CG_Sienna_Cichlid);
+               /* There is no ATCL2 in MMHUB for 2.1.x. Keep the status
+                * based on DAGB
+                */
+               data = MM_ATC_L2_MISC_CG__ENABLE_MASK;
                data1 = RREG32_SOC15(MMHUB, 0, mmDAGB0_CNTL_MISC2_Sienna_Cichlid);
                break;
        default:
index cd5f8b2..8bfdfd0 100644 (file)
@@ -795,6 +795,102 @@ static struct kfd_gpu_cache_info yellow_carp_cache_info[] = {
        },
 };
 
+static struct kfd_gpu_cache_info gfx1037_cache_info[] = {
+       {
+               /* TCP L1 Cache per CU */
+               .cache_size = 16,
+               .cache_level = 1,
+               .flags = (CRAT_CACHE_FLAGS_ENABLED |
+                               CRAT_CACHE_FLAGS_DATA_CACHE |
+                               CRAT_CACHE_FLAGS_SIMD_CACHE),
+               .num_cu_shared = 1,
+       },
+       {
+               /* Scalar L1 Instruction Cache per SQC */
+               .cache_size = 32,
+               .cache_level = 1,
+               .flags = (CRAT_CACHE_FLAGS_ENABLED |
+                               CRAT_CACHE_FLAGS_INST_CACHE |
+                               CRAT_CACHE_FLAGS_SIMD_CACHE),
+               .num_cu_shared = 2,
+       },
+       {
+               /* Scalar L1 Data Cache per SQC */
+               .cache_size = 16,
+               .cache_level = 1,
+               .flags = (CRAT_CACHE_FLAGS_ENABLED |
+                               CRAT_CACHE_FLAGS_DATA_CACHE |
+                               CRAT_CACHE_FLAGS_SIMD_CACHE),
+               .num_cu_shared = 2,
+       },
+       {
+               /* GL1 Data Cache per SA */
+               .cache_size = 128,
+               .cache_level = 1,
+               .flags = (CRAT_CACHE_FLAGS_ENABLED |
+                               CRAT_CACHE_FLAGS_DATA_CACHE |
+                               CRAT_CACHE_FLAGS_SIMD_CACHE),
+               .num_cu_shared = 2,
+       },
+       {
+               /* L2 Data Cache per GPU (Total Tex Cache) */
+               .cache_size = 256,
+               .cache_level = 2,
+               .flags = (CRAT_CACHE_FLAGS_ENABLED |
+                               CRAT_CACHE_FLAGS_DATA_CACHE |
+                               CRAT_CACHE_FLAGS_SIMD_CACHE),
+               .num_cu_shared = 2,
+       },
+};
+
+static struct kfd_gpu_cache_info gc_10_3_6_cache_info[] = {
+       {
+               /* TCP L1 Cache per CU */
+               .cache_size = 16,
+               .cache_level = 1,
+               .flags = (CRAT_CACHE_FLAGS_ENABLED |
+                         CRAT_CACHE_FLAGS_DATA_CACHE |
+                         CRAT_CACHE_FLAGS_SIMD_CACHE),
+               .num_cu_shared = 1,
+       },
+       {
+               /* Scalar L1 Instruction Cache per SQC */
+               .cache_size = 32,
+               .cache_level = 1,
+               .flags = (CRAT_CACHE_FLAGS_ENABLED |
+                         CRAT_CACHE_FLAGS_INST_CACHE |
+                         CRAT_CACHE_FLAGS_SIMD_CACHE),
+               .num_cu_shared = 2,
+       },
+       {
+               /* Scalar L1 Data Cache per SQC */
+               .cache_size = 16,
+               .cache_level = 1,
+               .flags = (CRAT_CACHE_FLAGS_ENABLED |
+                         CRAT_CACHE_FLAGS_DATA_CACHE |
+                         CRAT_CACHE_FLAGS_SIMD_CACHE),
+               .num_cu_shared = 2,
+       },
+       {
+               /* GL1 Data Cache per SA */
+               .cache_size = 128,
+               .cache_level = 1,
+               .flags = (CRAT_CACHE_FLAGS_ENABLED |
+                         CRAT_CACHE_FLAGS_DATA_CACHE |
+                         CRAT_CACHE_FLAGS_SIMD_CACHE),
+               .num_cu_shared = 2,
+       },
+       {
+               /* L2 Data Cache per GPU (Total Tex Cache) */
+               .cache_size = 256,
+               .cache_level = 2,
+               .flags = (CRAT_CACHE_FLAGS_ENABLED |
+                         CRAT_CACHE_FLAGS_DATA_CACHE |
+                         CRAT_CACHE_FLAGS_SIMD_CACHE),
+               .num_cu_shared = 2,
+       },
+};
+
 static void kfd_populated_cu_info_cpu(struct kfd_topology_device *dev,
                struct crat_subtype_computeunit *cu)
 {
@@ -1514,11 +1610,17 @@ static int kfd_fill_gpu_cache_info(struct kfd_dev *kdev,
                        num_of_cache_types = ARRAY_SIZE(beige_goby_cache_info);
                        break;
                case IP_VERSION(10, 3, 3):
-               case IP_VERSION(10, 3, 6): /* TODO: Double check these on production silicon */
-               case IP_VERSION(10, 3, 7): /* TODO: Double check these on production silicon */
                        pcache_info = yellow_carp_cache_info;
                        num_of_cache_types = ARRAY_SIZE(yellow_carp_cache_info);
                        break;
+               case IP_VERSION(10, 3, 6):
+                       pcache_info = gc_10_3_6_cache_info;
+                       num_of_cache_types = ARRAY_SIZE(gc_10_3_6_cache_info);
+                       break;
+               case IP_VERSION(10, 3, 7):
+                       pcache_info = gfx1037_cache_info;
+                       num_of_cache_types = ARRAY_SIZE(gfx1037_cache_info);
+                       break;
                case IP_VERSION(11, 0, 0):
                case IP_VERSION(11, 0, 1):
                case IP_VERSION(11, 0, 2):
index dfd3be4..e6854f7 100644 (file)
@@ -1369,7 +1369,7 @@ static bool dm_plane_format_mod_supported(struct drm_plane *plane,
 {
        struct amdgpu_device *adev = drm_to_adev(plane->dev);
        const struct drm_format_info *info = drm_format_info(format);
-       struct hw_asic_id asic_id = adev->dm.dc->ctx->asic_id;
+       int i;
 
        enum dm_micro_swizzle microtile = modifier_gfx9_swizzle_mode(modifier) & 3;
 
@@ -1386,49 +1386,13 @@ static bool dm_plane_format_mod_supported(struct drm_plane *plane,
                return true;
        }
 
-       /* check if swizzle mode is supported by this version of DCN */
-       switch (asic_id.chip_family) {
-       case FAMILY_SI:
-       case FAMILY_CI:
-       case FAMILY_KV:
-       case FAMILY_CZ:
-       case FAMILY_VI:
-               /* asics before AI does not have modifier support */
-               return false;
-       case FAMILY_AI:
-       case FAMILY_RV:
-       case FAMILY_NV:
-       case FAMILY_VGH:
-       case FAMILY_YELLOW_CARP:
-       case AMDGPU_FAMILY_GC_10_3_6:
-       case AMDGPU_FAMILY_GC_10_3_7:
-               switch (AMD_FMT_MOD_GET(TILE, modifier)) {
-               case AMD_FMT_MOD_TILE_GFX9_64K_R_X:
-               case AMD_FMT_MOD_TILE_GFX9_64K_D_X:
-               case AMD_FMT_MOD_TILE_GFX9_64K_S_X:
-               case AMD_FMT_MOD_TILE_GFX9_64K_D:
-                       return true;
-               default:
-                       return false;
-               }
-               break;
-       case AMDGPU_FAMILY_GC_11_0_0:
-       case AMDGPU_FAMILY_GC_11_0_1:
-               switch (AMD_FMT_MOD_GET(TILE, modifier)) {
-               case AMD_FMT_MOD_TILE_GFX11_256K_R_X:
-               case AMD_FMT_MOD_TILE_GFX9_64K_R_X:
-               case AMD_FMT_MOD_TILE_GFX9_64K_D_X:
-               case AMD_FMT_MOD_TILE_GFX9_64K_S_X:
-               case AMD_FMT_MOD_TILE_GFX9_64K_D:
-                       return true;
-               default:
-                       return false;
-               }
-               break;
-       default:
-               ASSERT(0); /* Unknown asic */
-               break;
+       /* Check that the modifier is on the list of the plane's supported modifiers. */
+       for (i = 0; i < plane->modifier_count; i++) {
+               if (modifier == plane->modifiers[i])
+                       break;
        }
+       if (i == plane->modifier_count)
+               return false;
 
        /*
         * For D swizzle the canonical modifier depends on the bpp, so check
index d732b6f..a7e0001 100644 (file)
@@ -1270,16 +1270,6 @@ void dcn20_pipe_control_lock(
                                        lock,
                                        &hw_locks,
                                        &inst_flags);
-       } else if (pipe->stream && pipe->stream->mall_stream_config.type == SUBVP_MAIN) {
-               union dmub_inbox0_cmd_lock_hw hw_lock_cmd = { 0 };
-               hw_lock_cmd.bits.command_code = DMUB_INBOX0_CMD__HW_LOCK;
-               hw_lock_cmd.bits.hw_lock_client = HW_LOCK_CLIENT_DRIVER;
-               hw_lock_cmd.bits.lock_pipe = 1;
-               hw_lock_cmd.bits.otg_inst = pipe->stream_res.tg->inst;
-               hw_lock_cmd.bits.lock = lock;
-               if (!lock)
-                       hw_lock_cmd.bits.should_release = 1;
-               dmub_hw_lock_mgr_inbox0_cmd(dc->ctx->dmub_srv, hw_lock_cmd);
        } else if (pipe->plane_state != NULL && pipe->plane_state->triplebuffer_flips) {
                if (lock)
                        pipe->stream_res.tg->funcs->triplebuffer_lock(pipe->stream_res.tg);
@@ -1856,7 +1846,7 @@ void dcn20_post_unlock_program_front_end(
 
                        for (j = 0; j < TIMEOUT_FOR_PIPE_ENABLE_MS*1000
                                        && hubp->funcs->hubp_is_flip_pending(hubp); j++)
-                               mdelay(1);
+                               udelay(1);
                }
        }
 
index d51d0c4..b03a781 100644 (file)
@@ -200,7 +200,7 @@ bool dcn32_all_pipes_have_stream_and_plane(struct dc *dc,
                struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
 
                if (!pipe->stream)
-                       return false;
+                       continue;
 
                if (!pipe->plane_state)
                        return false;
index 063f4a7..b76f0f7 100644 (file)
@@ -25,7 +25,7 @@
 #define SMU13_DRIVER_IF_V13_0_0_H
 
 //Increment this version if SkuTable_t or BoardTable_t change
-#define PPTABLE_VERSION 0x24
+#define PPTABLE_VERSION 0x26
 
 #define NUM_GFXCLK_DPM_LEVELS    16
 #define NUM_SOCCLK_DPM_LEVELS    8
 #define FEATURE_SPARE_63_BIT                  63
 #define NUM_FEATURES                          64
 
+#define ALLOWED_FEATURE_CTRL_DEFAULT 0xFFFFFFFFFFFFFFFFULL
+#define ALLOWED_FEATURE_CTRL_SCPM      ((1 << FEATURE_DPM_GFXCLK_BIT) | \
+                                                                       (1 << FEATURE_DPM_GFX_POWER_OPTIMIZER_BIT) | \
+                                                                       (1 << FEATURE_DPM_UCLK_BIT) | \
+                                                                       (1 << FEATURE_DPM_FCLK_BIT) | \
+                                                                       (1 << FEATURE_DPM_SOCCLK_BIT) | \
+                                                                       (1 << FEATURE_DPM_MP0CLK_BIT) | \
+                                                                       (1 << FEATURE_DPM_LINK_BIT) | \
+                                                                       (1 << FEATURE_DPM_DCN_BIT) | \
+                                                                       (1 << FEATURE_DS_GFXCLK_BIT) | \
+                                                                       (1 << FEATURE_DS_SOCCLK_BIT) | \
+                                                                       (1 << FEATURE_DS_FCLK_BIT) | \
+                                                                       (1 << FEATURE_DS_LCLK_BIT) | \
+                                                                       (1 << FEATURE_DS_DCFCLK_BIT) | \
+                                                                       (1 << FEATURE_DS_UCLK_BIT))
+
 //For use with feature control messages
 typedef enum {
   FEATURE_PWR_ALL,
@@ -133,6 +149,7 @@ typedef enum {
 #define DEBUG_OVERRIDE_DISABLE_DFLL                    0x00000200
 #define DEBUG_OVERRIDE_ENABLE_RLC_VF_BRINGUP_MODE      0x00000400
 #define DEBUG_OVERRIDE_DFLL_MASTER_MODE                0x00000800
+#define DEBUG_OVERRIDE_ENABLE_PROFILING_MODE           0x00001000
 
 // VR Mapping Bit Defines
 #define VR_MAPPING_VR_SELECT_MASK  0x01
@@ -262,15 +279,15 @@ typedef enum {
 } I2cControllerPort_e;
 
 typedef enum {
-  I2C_CONTROLLER_NAME_VR_GFX = 0,
-  I2C_CONTROLLER_NAME_VR_SOC,
-  I2C_CONTROLLER_NAME_VR_VMEMP,
-  I2C_CONTROLLER_NAME_VR_VDDIO,
-  I2C_CONTROLLER_NAME_LIQUID0,
-  I2C_CONTROLLER_NAME_LIQUID1,
-  I2C_CONTROLLER_NAME_PLX,
-  I2C_CONTROLLER_NAME_OTHER,
-  I2C_CONTROLLER_NAME_COUNT,
+       I2C_CONTROLLER_NAME_VR_GFX = 0,
+       I2C_CONTROLLER_NAME_VR_SOC,
+       I2C_CONTROLLER_NAME_VR_VMEMP,
+       I2C_CONTROLLER_NAME_VR_VDDIO,
+       I2C_CONTROLLER_NAME_LIQUID0,
+       I2C_CONTROLLER_NAME_LIQUID1,
+       I2C_CONTROLLER_NAME_PLX,
+       I2C_CONTROLLER_NAME_FAN_INTAKE,
+       I2C_CONTROLLER_NAME_COUNT,
 } I2cControllerName_e;
 
 typedef enum {
@@ -282,16 +299,17 @@ typedef enum {
   I2C_CONTROLLER_THROTTLER_LIQUID0,
   I2C_CONTROLLER_THROTTLER_LIQUID1,
   I2C_CONTROLLER_THROTTLER_PLX,
+  I2C_CONTROLLER_THROTTLER_FAN_INTAKE,
   I2C_CONTROLLER_THROTTLER_INA3221,
   I2C_CONTROLLER_THROTTLER_COUNT,
 } I2cControllerThrottler_e;
 
 typedef enum {
-  I2C_CONTROLLER_PROTOCOL_VR_XPDE132G5,
-  I2C_CONTROLLER_PROTOCOL_VR_IR35217,
-  I2C_CONTROLLER_PROTOCOL_TMP_TMP102A,
-  I2C_CONTROLLER_PROTOCOL_INA3221,
-  I2C_CONTROLLER_PROTOCOL_COUNT,
+       I2C_CONTROLLER_PROTOCOL_VR_XPDE132G5,
+       I2C_CONTROLLER_PROTOCOL_VR_IR35217,
+       I2C_CONTROLLER_PROTOCOL_TMP_MAX31875,
+       I2C_CONTROLLER_PROTOCOL_INA3221,
+       I2C_CONTROLLER_PROTOCOL_COUNT,
 } I2cControllerProtocol_e;
 
 typedef struct {
@@ -658,13 +676,20 @@ typedef struct {
 
 #define PP_NUM_OD_VF_CURVE_POINTS PP_NUM_RTAVFS_PWL_ZONES + 1
 
+typedef enum {
+       FAN_MODE_AUTO = 0,
+       FAN_MODE_MANUAL_LINEAR,
+} FanMode_e;
 
 typedef struct {
   uint32_t FeatureCtrlMask;
 
   //Voltage control
   int16_t                VoltageOffsetPerZoneBoundary[PP_NUM_OD_VF_CURVE_POINTS];
-  uint16_t               reserved[2];
+  uint16_t               VddGfxVmax;         // in mV
+
+  uint8_t                IdlePwrSavingFeaturesCtrl;
+  uint8_t                RuntimePwrSavingFeaturesCtrl;
 
   //Frequency changes
   int16_t                GfxclkFmin;           // MHz
@@ -674,7 +699,7 @@ typedef struct {
 
   //PPT
   int16_t                Ppt;         // %
-  int16_t                reserved1;
+  int16_t                Tdc;
 
   //Fan control
   uint8_t                FanLinearPwmPoints[NUM_OD_FAN_MAX_POINTS];
@@ -701,16 +726,19 @@ typedef struct {
   uint32_t FeatureCtrlMask;
 
   int16_t VoltageOffsetPerZoneBoundary;
-  uint16_t               reserved[2];
+  uint16_t               VddGfxVmax;         // in mV
+
+  uint8_t                IdlePwrSavingFeaturesCtrl;
+  uint8_t                RuntimePwrSavingFeaturesCtrl;
 
-  uint16_t               GfxclkFmin;           // MHz
-  uint16_t               GfxclkFmax;           // MHz
+  int16_t               GfxclkFmin;           // MHz
+  int16_t               GfxclkFmax;           // MHz
   uint16_t               UclkFmin;             // MHz
   uint16_t               UclkFmax;             // MHz
 
   //PPT
   int16_t                Ppt;         // %
-  int16_t                reserved1;
+  int16_t                Tdc;
 
   uint8_t                FanLinearPwmPoints;
   uint8_t                FanLinearTempPoints;
@@ -857,7 +885,8 @@ typedef struct {
   uint16_t  FanStartTempMin;
   uint16_t  FanStartTempMax;
 
-  uint32_t Spare[12];
+  uint16_t  PowerMinPpt0[POWER_SOURCE_COUNT];
+  uint32_t Spare[11];
 
 } MsgLimits_t;
 
@@ -1041,7 +1070,17 @@ typedef struct {
   uint32_t        GfxoffSpare[15];
 
   // GFX GPO
-  uint32_t        GfxGpoSpare[16];
+  uint32_t        DfllBtcMasterScalerM;
+  int32_t         DfllBtcMasterScalerB;
+  uint32_t        DfllBtcSlaveScalerM;
+  int32_t         DfllBtcSlaveScalerB;
+
+  uint32_t        DfllPccAsWaitCtrl; //GDFLL_AS_WAIT_CTRL_PCC register value to be passed to RLC msg
+  uint32_t        DfllPccAsStepCtrl; //GDFLL_AS_STEP_CTRL_PCC register value to be passed to RLC msg
+
+  uint32_t        DfllL2FrequencyBoostM; //Unitless (float)
+  uint32_t        DfllL2FrequencyBoostB; //In MHz (integer)
+  uint32_t        GfxGpoSpare[8];
 
   // GFX DCS
 
@@ -1114,12 +1153,14 @@ typedef struct {
   uint16_t IntakeTempHighIntakeAcousticLimit;
   uint16_t IntakeTempAcouticLimitReleaseRate;
 
-  uint16_t FanStalledTempLimitOffset;
+  int16_t FanAbnormalTempLimitOffset;
   uint16_t FanStalledTriggerRpm;
-  uint16_t FanAbnormalTriggerRpm;
-  uint16_t FanPadding;
+  uint16_t FanAbnormalTriggerRpmCoeff;
+  uint16_t FanAbnormalDetectionEnable;
 
-  uint32_t     FanSpare[14];
+  uint8_t      FanIntakeSensorSupport;
+  uint8_t      FanIntakePadding[3];
+  uint32_t     FanSpare[13];
 
   // SECTION: VDD_GFX AVFS
 
@@ -1198,8 +1239,13 @@ typedef struct {
   int16_t     TotalBoardPowerM;
   int16_t     TotalBoardPowerB;
 
+  //PMFW-11158
+  QuadraticInt_t qFeffCoeffGameClock[POWER_SOURCE_COUNT];
+  QuadraticInt_t qFeffCoeffBaseClock[POWER_SOURCE_COUNT];
+  QuadraticInt_t qFeffCoeffBoostClock[POWER_SOURCE_COUNT];
+
   // SECTION: Sku Reserved
-  uint32_t         Spare[61];
+  uint32_t         Spare[43];
 
   // Padding for MMHUB - do not modify this
   uint32_t     MmHubPadding[8];
@@ -1288,8 +1334,11 @@ typedef struct {
   uint32_t    PostVoltageSetBacoDelay; // in microseconds. Amount of time FW will wait after power good is established or PSI0 command is issued
   uint32_t    BacoEntryDelay; // in milliseconds. Amount of time FW will wait to trigger BACO entry after receiving entry notification from OS
 
+  uint8_t     FuseWritePowerMuxPresent;
+  uint8_t     FuseWritePadding[3];
+
   // SECTION: Board Reserved
-  uint32_t     BoardSpare[64];
+  uint32_t     BoardSpare[63];
 
   // SECTION: Structure Padding
 
@@ -1381,7 +1430,7 @@ typedef struct {
   uint16_t AverageTotalBoardPower;
 
   uint16_t AvgTemperature[TEMP_COUNT];
-  uint16_t TempPadding;
+  uint16_t AvgTemperatureFanIntake;
 
   uint8_t  PcieRate               ;
   uint8_t  PcieWidth              ;
@@ -1550,5 +1599,7 @@ typedef struct {
 #define IH_INTERRUPT_CONTEXT_ID_AUDIO_D0            0x5
 #define IH_INTERRUPT_CONTEXT_ID_AUDIO_D3            0x6
 #define IH_INTERRUPT_CONTEXT_ID_THERMAL_THROTTLING  0x7
+#define IH_INTERRUPT_CONTEXT_ID_FAN_ABNORMAL        0x8
+#define IH_INTERRUPT_CONTEXT_ID_FAN_RECOVERY        0x9
 
 #endif
index 8f72202..80fb583 100644 (file)
@@ -30,7 +30,7 @@
 #define SMU13_DRIVER_IF_VERSION_ALDE 0x08
 #define SMU13_DRIVER_IF_VERSION_SMU_V13_0_4 0x07
 #define SMU13_DRIVER_IF_VERSION_SMU_V13_0_5 0x04
-#define SMU13_DRIVER_IF_VERSION_SMU_V13_0_0 0x30
+#define SMU13_DRIVER_IF_VERSION_SMU_V13_0_0_10 0x32
 #define SMU13_DRIVER_IF_VERSION_SMU_V13_0_7 0x2C
 #define SMU13_DRIVER_IF_VERSION_SMU_V13_0_10 0x1D
 
index c4552ad..43fb102 100644 (file)
@@ -289,7 +289,8 @@ int smu_v13_0_check_fw_version(struct smu_context *smu)
                smu->smc_driver_if_version = SMU13_DRIVER_IF_VERSION_ALDE;
                break;
        case IP_VERSION(13, 0, 0):
-               smu->smc_driver_if_version = SMU13_DRIVER_IF_VERSION_SMU_V13_0_0;
+       case IP_VERSION(13, 0, 10):
+               smu->smc_driver_if_version = SMU13_DRIVER_IF_VERSION_SMU_V13_0_0_10;
                break;
        case IP_VERSION(13, 0, 7):
                smu->smc_driver_if_version = SMU13_DRIVER_IF_VERSION_SMU_V13_0_7;
@@ -305,9 +306,6 @@ int smu_v13_0_check_fw_version(struct smu_context *smu)
        case IP_VERSION(13, 0, 5):
                smu->smc_driver_if_version = SMU13_DRIVER_IF_VERSION_SMU_V13_0_5;
                break;
-       case IP_VERSION(13, 0, 10):
-               smu->smc_driver_if_version = SMU13_DRIVER_IF_VERSION_SMU_V13_0_10;
-               break;
        default:
                dev_err(adev->dev, "smu unsupported IP version: 0x%x.\n",
                        adev->ip_versions[MP1_HWIP][0]);
@@ -842,6 +840,7 @@ int smu_v13_0_gfx_off_control(struct smu_context *smu, bool enable)
        case IP_VERSION(13, 0, 5):
        case IP_VERSION(13, 0, 7):
        case IP_VERSION(13, 0, 8):
+       case IP_VERSION(13, 0, 10):
                if (!(adev->pm.pp_feature & PP_GFXOFF_MASK))
                        return 0;
                if (enable)
index d7483c1..083337a 100644 (file)
@@ -105,6 +105,7 @@ struct ps8640 {
        struct gpio_desc *gpio_powerdown;
        struct device_link *link;
        bool pre_enabled;
+       bool need_post_hpd_delay;
 };
 
 static const struct regmap_config ps8640_regmap_config[] = {
@@ -173,14 +174,31 @@ static int _ps8640_wait_hpd_asserted(struct ps8640 *ps_bridge, unsigned long wai
 {
        struct regmap *map = ps_bridge->regmap[PAGE2_TOP_CNTL];
        int status;
+       int ret;
 
        /*
         * Apparently something about the firmware in the chip signals that
         * HPD goes high by reporting GPIO9 as high (even though HPD isn't
         * actually connected to GPIO9).
         */
-       return regmap_read_poll_timeout(map, PAGE2_GPIO_H, status,
-                                       status & PS_GPIO9, wait_us / 10, wait_us);
+       ret = regmap_read_poll_timeout(map, PAGE2_GPIO_H, status,
+                                      status & PS_GPIO9, wait_us / 10, wait_us);
+
+       /*
+        * The first time we see HPD go high after a reset we delay an extra
+        * 50 ms. The best guess is that the MCU is doing "stuff" during this
+        * time (maybe talking to the panel) and we don't want to interrupt it.
+        *
+        * No locking is done around "need_post_hpd_delay". If we're here we
+        * know we're holding a PM Runtime reference and the only other place
+        * that touches this is PM Runtime resume.
+        */
+       if (!ret && ps_bridge->need_post_hpd_delay) {
+               ps_bridge->need_post_hpd_delay = false;
+               msleep(50);
+       }
+
+       return ret;
 }
 
 static int ps8640_wait_hpd_asserted(struct drm_dp_aux *aux, unsigned long wait_us)
@@ -381,6 +399,9 @@ static int __maybe_unused ps8640_resume(struct device *dev)
        msleep(50);
        gpiod_set_value(ps_bridge->gpio_reset, 0);
 
+       /* We just reset things, so we need a delay after the first HPD */
+       ps_bridge->need_post_hpd_delay = true;
+
        /*
         * Mystery 200 ms delay for the "MCU to be ready". It's unclear if
         * this is truly necessary since the MCU will already signal that
index c9be61d..47419d1 100644 (file)
@@ -3957,6 +3957,8 @@ intel_dp_handle_hdmi_link_status_change(struct intel_dp *intel_dp)
 
                drm_dp_pcon_hdmi_frl_link_error_count(&intel_dp->aux, &intel_dp->attached_connector->base);
 
+               intel_dp->frl.is_trained = false;
+
                /* Restart FRL training or fall back to TMDS mode */
                intel_dp_check_frl_training(intel_dp);
        }
index 6d2003d..a821e3d 100644 (file)
@@ -2293,11 +2293,11 @@ rcs_engine_wa_init(struct intel_engine_cs *engine, struct i915_wa_list *wal)
        }
 
        if (IS_DG1_GRAPHICS_STEP(i915, STEP_A0, STEP_B0) ||
-           IS_ROCKETLAKE(i915) || IS_TIGERLAKE(i915)) {
+           IS_ROCKETLAKE(i915) || IS_TIGERLAKE(i915) || IS_ALDERLAKE_P(i915)) {
                /*
                 * Wa_1607030317:tgl
                 * Wa_1607186500:tgl
-                * Wa_1607297627:tgl,rkl,dg1[a0]
+                * Wa_1607297627:tgl,rkl,dg1[a0],adlp
                 *
                 * On TGL and RKL there are multiple entries for this WA in the
                 * BSpec; some indicate this is an A0-only WA, others indicate
index 6ed5786..744cca5 100644 (file)
@@ -591,8 +591,15 @@ void intel_runtime_pm_enable(struct intel_runtime_pm *rpm)
                pm_runtime_use_autosuspend(kdev);
        }
 
-       /* Enable by default */
-       pm_runtime_allow(kdev);
+       /*
+        *  FIXME: Temp hammer to keep autosupend disable on lmem supported platforms.
+        *  As per PCIe specs 5.3.1.4.1, all iomem read write request over a PCIe
+        *  function will be unsupported in case PCIe endpoint function is in D3.
+        *  Let's keep i915 autosuspend control 'on' till we fix all known issue
+        *  with lmem access in D3.
+        */
+       if (!IS_DGFX(i915))
+               pm_runtime_allow(kdev);
 
        /*
         * The core calls the driver load handler with an RPM reference held.
index 4e0cbd6..3c9dfdb 100644 (file)
@@ -155,7 +155,7 @@ config DRM_MSM_HDMI
          Compile in support for the HDMI output MSM DRM driver. It can
          be a primary or a secondary display on device. Note that this is used
          only for the direct HDMI output. If the device outputs HDMI data
-         throught some kind of DSI-to-HDMI bridge, this option can be disabled.
+         through some kind of DSI-to-HDMI bridge, this option can be disabled.
 
 config DRM_MSM_HDMI_HDCP
        bool "Enable HDMI HDCP support in MSM DRM driver"
index 55f4433..a5c3d1e 100644 (file)
@@ -91,7 +91,7 @@ struct a6xx_state_memobj {
 static void *state_kcalloc(struct a6xx_gpu_state *a6xx_state, int nr, size_t objsize)
 {
        struct a6xx_state_memobj *obj =
-               kzalloc((nr * objsize) + sizeof(*obj), GFP_KERNEL);
+               kvzalloc((nr * objsize) + sizeof(*obj), GFP_KERNEL);
 
        if (!obj)
                return NULL;
@@ -813,6 +813,9 @@ static struct msm_gpu_state_bo *a6xx_snapshot_gmu_bo(
 {
        struct msm_gpu_state_bo *snapshot;
 
+       if (!bo->size)
+               return NULL;
+
        snapshot = state_kcalloc(a6xx_state, 1, sizeof(*snapshot));
        if (!snapshot)
                return NULL;
@@ -1040,8 +1043,13 @@ static void a6xx_gpu_state_destroy(struct kref *kref)
        if (a6xx_state->gmu_hfi)
                kvfree(a6xx_state->gmu_hfi->data);
 
-       list_for_each_entry_safe(obj, tmp, &a6xx_state->objs, node)
-               kfree(obj);
+       if (a6xx_state->gmu_debug)
+               kvfree(a6xx_state->gmu_debug->data);
+
+       list_for_each_entry_safe(obj, tmp, &a6xx_state->objs, node) {
+               list_del(&obj->node);
+               kvfree(obj);
+       }
 
        adreno_gpu_state_destroy(state);
        kfree(a6xx_state);
index 24b489b..6288064 100644 (file)
@@ -679,6 +679,9 @@ static int adreno_system_suspend(struct device *dev)
        struct msm_gpu *gpu = dev_to_gpu(dev);
        int remaining, ret;
 
+       if (!gpu)
+               return 0;
+
        suspend_scheduler(gpu);
 
        remaining = wait_event_timeout(gpu->retire_event,
@@ -700,7 +703,12 @@ out:
 
 static int adreno_system_resume(struct device *dev)
 {
-       resume_scheduler(dev_to_gpu(dev));
+       struct msm_gpu *gpu = dev_to_gpu(dev);
+
+       if (!gpu)
+               return 0;
+
+       resume_scheduler(gpu);
        return pm_runtime_force_resume(dev);
 }
 
index 382fb7f..5a0e849 100644 (file)
@@ -729,7 +729,12 @@ static char *adreno_gpu_ascii85_encode(u32 *src, size_t len)
        return buf;
 }
 
-/* len is expected to be in bytes */
+/* len is expected to be in bytes
+ *
+ * WARNING: *ptr should be allocated with kvmalloc or friends.  It can be free'd
+ * with kvfree() and replaced with a newly kvmalloc'd buffer on the first call
+ * when the unencoded raw data is encoded
+ */
 void adreno_show_object(struct drm_printer *p, void **ptr, int len,
                bool *encoded)
 {
index 7288041..7444b75 100644 (file)
@@ -56,8 +56,9 @@ static int mdp4_lvds_connector_get_modes(struct drm_connector *connector)
        return ret;
 }
 
-static int mdp4_lvds_connector_mode_valid(struct drm_connector *connector,
-                                struct drm_display_mode *mode)
+static enum drm_mode_status
+mdp4_lvds_connector_mode_valid(struct drm_connector *connector,
+                              struct drm_display_mode *mode)
 {
        struct mdp4_lvds_connector *mdp4_lvds_connector =
                        to_mdp4_lvds_connector(connector);
index 3854c9f..dd26ca6 100644 (file)
@@ -1243,8 +1243,7 @@ static int dp_ctrl_link_train(struct dp_ctrl_private *ctrl,
 {
        int ret = 0;
        const u8 *dpcd = ctrl->panel->dpcd;
-       u8 encoding = DP_SET_ANSI_8B10B;
-       u8 ssc;
+       u8 encoding[] = { 0, DP_SET_ANSI_8B10B };
        u8 assr;
        struct dp_link_info link_info = {0};
 
@@ -1256,13 +1255,11 @@ static int dp_ctrl_link_train(struct dp_ctrl_private *ctrl,
 
        dp_aux_link_configure(ctrl->aux, &link_info);
 
-       if (drm_dp_max_downspread(dpcd)) {
-               ssc = DP_SPREAD_AMP_0_5;
-               drm_dp_dpcd_write(ctrl->aux, DP_DOWNSPREAD_CTRL, &ssc, 1);
-       }
+       if (drm_dp_max_downspread(dpcd))
+               encoding[0] |= DP_SPREAD_AMP_0_5;
 
-       drm_dp_dpcd_write(ctrl->aux, DP_MAIN_LINK_CHANNEL_CODING_SET,
-                               &encoding, 1);
+       /* config DOWNSPREAD_CTRL and MAIN_LINK_CHANNEL_CODING_SET */
+       drm_dp_dpcd_write(ctrl->aux, DP_DOWNSPREAD_CTRL, encoding, 2);
 
        if (drm_dp_alternate_scrambler_reset_cap(dpcd)) {
                assr = DP_ALTERNATE_SCRAMBLER_RESET_ENABLE;
index bfd0aef..a49f6db 100644 (file)
@@ -1249,7 +1249,7 @@ int dp_display_request_irq(struct msm_dp *dp_display)
                return -EINVAL;
        }
 
-       rc = devm_request_irq(&dp->pdev->dev, dp->irq,
+       rc = devm_request_irq(dp_display->drm_dev->dev, dp->irq,
                        dp_display_irq_handler,
                        IRQF_TRIGGER_HIGH, "dp_display_isr", dp);
        if (rc < 0) {
@@ -1528,6 +1528,11 @@ void msm_dp_debugfs_init(struct msm_dp *dp_display, struct drm_minor *minor)
        }
 }
 
+static void of_dp_aux_depopulate_bus_void(void *data)
+{
+       of_dp_aux_depopulate_bus(data);
+}
+
 static int dp_display_get_next_bridge(struct msm_dp *dp)
 {
        int rc;
@@ -1552,10 +1557,16 @@ static int dp_display_get_next_bridge(struct msm_dp *dp)
                 * panel driver is probed asynchronously but is the best we
                 * can do without a bigger driver reorganization.
                 */
-               rc = devm_of_dp_aux_populate_ep_devices(dp_priv->aux);
+               rc = of_dp_aux_populate_bus(dp_priv->aux, NULL);
                of_node_put(aux_bus);
                if (rc)
                        goto error;
+
+               rc = devm_add_action_or_reset(dp->drm_dev->dev,
+                                               of_dp_aux_depopulate_bus_void,
+                                               dp_priv->aux);
+               if (rc)
+                       goto error;
        } else if (dp->is_edp) {
                DRM_ERROR("eDP aux_bus not found\n");
                return -ENODEV;
@@ -1568,7 +1579,7 @@ static int dp_display_get_next_bridge(struct msm_dp *dp)
         * For DisplayPort interfaces external bridges are optional, so
         * silently ignore an error if one is not present (-ENODEV).
         */
-       rc = dp_parser_find_next_bridge(dp_priv->parser);
+       rc = devm_dp_parser_find_next_bridge(dp->drm_dev->dev, dp_priv->parser);
        if (!dp->is_edp && rc == -ENODEV)
                return 0;
 
@@ -1597,6 +1608,12 @@ int msm_dp_modeset_init(struct msm_dp *dp_display, struct drm_device *dev,
                return -EINVAL;
 
        priv = dev->dev_private;
+
+       if (priv->num_bridges == ARRAY_SIZE(priv->bridges)) {
+               DRM_DEV_ERROR(dev->dev, "too many bridges\n");
+               return -ENOSPC;
+       }
+
        dp_display->drm_dev = dev;
 
        dp_priv = container_of(dp_display, struct dp_display_private, dp_display);
index 6df25f7..6db82f9 100644 (file)
@@ -31,6 +31,36 @@ static enum drm_connector_status dp_bridge_detect(struct drm_bridge *bridge)
                                        connector_status_disconnected;
 }
 
+static int dp_bridge_atomic_check(struct drm_bridge *bridge,
+                           struct drm_bridge_state *bridge_state,
+                           struct drm_crtc_state *crtc_state,
+                           struct drm_connector_state *conn_state)
+{
+       struct msm_dp *dp;
+
+       dp = to_dp_bridge(bridge)->dp_display;
+
+       drm_dbg_dp(dp->drm_dev, "is_connected = %s\n",
+               (dp->is_connected) ? "true" : "false");
+
+       /*
+        * There is no protection in the DRM framework to check if the display
+        * pipeline has been already disabled before trying to disable it again.
+        * Hence if the sink is unplugged, the pipeline gets disabled, but the
+        * crtc->active is still true. Any attempt to set the mode or manually
+        * disable this encoder will result in the crash.
+        *
+        * TODO: add support for telling the DRM subsystem that the pipeline is
+        * disabled by the hardware and thus all access to it should be forbidden.
+        * After that this piece of code can be removed.
+        */
+       if (bridge->ops & DRM_BRIDGE_OP_HPD)
+               return (dp->is_connected) ? 0 : -ENOTCONN;
+
+       return 0;
+}
+
+
 /**
  * dp_bridge_get_modes - callback to add drm modes via drm_mode_probed_add()
  * @bridge: Poiner to drm bridge
@@ -61,6 +91,9 @@ static int dp_bridge_get_modes(struct drm_bridge *bridge, struct drm_connector *
 }
 
 static const struct drm_bridge_funcs dp_bridge_ops = {
+       .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
+       .atomic_destroy_state   = drm_atomic_helper_bridge_destroy_state,
+       .atomic_reset           = drm_atomic_helper_bridge_reset,
        .enable       = dp_bridge_enable,
        .disable      = dp_bridge_disable,
        .post_disable = dp_bridge_post_disable,
@@ -68,6 +101,7 @@ static const struct drm_bridge_funcs dp_bridge_ops = {
        .mode_valid   = dp_bridge_mode_valid,
        .get_modes    = dp_bridge_get_modes,
        .detect       = dp_bridge_detect,
+       .atomic_check = dp_bridge_atomic_check,
 };
 
 struct drm_bridge *dp_bridge_init(struct msm_dp *dp_display, struct drm_device *dev,
index dd73221..dcbe893 100644 (file)
@@ -240,12 +240,12 @@ static int dp_parser_clock(struct dp_parser *parser)
        return 0;
 }
 
-int dp_parser_find_next_bridge(struct dp_parser *parser)
+int devm_dp_parser_find_next_bridge(struct device *dev, struct dp_parser *parser)
 {
-       struct device *dev = &parser->pdev->dev;
+       struct platform_device *pdev = parser->pdev;
        struct drm_bridge *bridge;
 
-       bridge = devm_drm_of_get_bridge(dev, dev->of_node, 1, 0);
+       bridge = devm_drm_of_get_bridge(dev, pdev->dev.of_node, 1, 0);
        if (IS_ERR(bridge))
                return PTR_ERR(bridge);
 
index 866c1a8..d30ab77 100644 (file)
@@ -138,8 +138,9 @@ struct dp_parser {
 struct dp_parser *dp_parser_get(struct platform_device *pdev);
 
 /**
- * dp_parser_find_next_bridge() - find an additional bridge to DP
+ * devm_dp_parser_find_next_bridge() - find an additional bridge to DP
  *
+ * @dev: device to tie bridge lifetime to
  * @parser: dp_parser data from client
  *
  * This function is used to find any additional bridge attached to
@@ -147,6 +148,6 @@ struct dp_parser *dp_parser_get(struct platform_device *pdev);
  *
  * Return: 0 if able to get the bridge, otherwise negative errno for failure.
  */
-int dp_parser_find_next_bridge(struct dp_parser *parser);
+int devm_dp_parser_find_next_bridge(struct device *dev, struct dp_parser *parser);
 
 #endif
index 39bbabb..8a95c74 100644 (file)
@@ -218,6 +218,12 @@ int msm_dsi_modeset_init(struct msm_dsi *msm_dsi, struct drm_device *dev,
                return -EINVAL;
 
        priv = dev->dev_private;
+
+       if (priv->num_bridges == ARRAY_SIZE(priv->bridges)) {
+               DRM_DEV_ERROR(dev->dev, "too many bridges\n");
+               return -ENOSPC;
+       }
+
        msm_dsi->dev = dev;
 
        ret = msm_dsi_host_modeset_init(msm_dsi->host, dev);
index 93fe61b..f28fb21 100644 (file)
@@ -300,6 +300,11 @@ int msm_hdmi_modeset_init(struct hdmi *hdmi,
        struct platform_device *pdev = hdmi->pdev;
        int ret;
 
+       if (priv->num_bridges == ARRAY_SIZE(priv->bridges)) {
+               DRM_DEV_ERROR(dev->dev, "too many bridges\n");
+               return -ENOSPC;
+       }
+
        hdmi->dev = dev;
        hdmi->encoder = encoder;
 
@@ -339,7 +344,7 @@ int msm_hdmi_modeset_init(struct hdmi *hdmi,
                goto fail;
        }
 
-       ret = devm_request_irq(&pdev->dev, hdmi->irq,
+       ret = devm_request_irq(dev->dev, hdmi->irq,
                        msm_hdmi_irq, IRQF_TRIGGER_HIGH,
                        "hdmi_isr", hdmi);
        if (ret < 0) {
index 28034c2..105b5b4 100644 (file)
@@ -247,6 +247,7 @@ static int msm_drm_uninit(struct device *dev)
 
        for (i = 0; i < priv->num_bridges; i++)
                drm_bridge_remove(priv->bridges[i]);
+       priv->num_bridges = 0;
 
        pm_runtime_get_sync(dev);
        msm_irq_uninstall(ddev);
index 5599d93..45a3e5c 100644 (file)
@@ -501,11 +501,11 @@ out:
  */
 static void submit_cleanup(struct msm_gem_submit *submit, bool error)
 {
-       unsigned cleanup_flags = BO_LOCKED | BO_OBJ_PINNED;
+       unsigned cleanup_flags = BO_LOCKED;
        unsigned i;
 
        if (error)
-               cleanup_flags |= BO_VMA_PINNED;
+               cleanup_flags |= BO_VMA_PINNED | BO_OBJ_PINNED;
 
        for (i = 0; i < submit->nr_bos; i++) {
                struct msm_gem_object *msm_obj = submit->bos[i].obj;
@@ -706,7 +706,7 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data,
        struct msm_drm_private *priv = dev->dev_private;
        struct drm_msm_gem_submit *args = data;
        struct msm_file_private *ctx = file->driver_priv;
-       struct msm_gem_submit *submit = NULL;
+       struct msm_gem_submit *submit;
        struct msm_gpu *gpu = priv->gpu;
        struct msm_gpu_submitqueue *queue;
        struct msm_ringbuffer *ring;
@@ -946,8 +946,7 @@ out_unlock:
                put_unused_fd(out_fence_fd);
        mutex_unlock(&queue->lock);
 out_post_unlock:
-       if (submit)
-               msm_gem_submit_put(submit);
+       msm_gem_submit_put(submit);
        if (!IS_ERR_OR_NULL(post_deps)) {
                for (i = 0; i < args->nr_out_syncobjs; ++i) {
                        kfree(post_deps[i].chain);
index 0098ee8..021f4e2 100644 (file)
@@ -997,4 +997,6 @@ void msm_gpu_cleanup(struct msm_gpu *gpu)
        }
 
        msm_devfreq_cleanup(gpu);
+
+       platform_set_drvdata(gpu->pdev, NULL);
 }
index ff911e7..58a72e6 100644 (file)
@@ -280,6 +280,10 @@ struct msm_gpu {
 static inline struct msm_gpu *dev_to_gpu(struct device *dev)
 {
        struct adreno_smmu_priv *adreno_smmu = dev_get_drvdata(dev);
+
+       if (!adreno_smmu)
+               return NULL;
+
        return container_of(adreno_smmu, struct msm_gpu, adreno_smmu);
 }
 
index cad4c35..57a8e95 100644 (file)
@@ -25,7 +25,8 @@ static struct dma_fence *msm_job_run(struct drm_sched_job *job)
 
                msm_gem_lock(obj);
                msm_gem_unpin_vma_fenced(submit->bos[i].vma, fctx);
-               submit->bos[i].flags &= ~BO_VMA_PINNED;
+               msm_gem_unpin_locked(obj);
+               submit->bos[i].flags &= ~(BO_VMA_PINNED | BO_OBJ_PINNED);
                msm_gem_unlock(obj);
        }
 
index 6137537..4b913db 100644 (file)
@@ -207,6 +207,7 @@ static void drm_sched_entity_kill_jobs_cb(struct dma_fence *f,
        struct drm_sched_job *job = container_of(cb, struct drm_sched_job,
                                                 finish_cb);
 
+       dma_fence_put(f);
        INIT_WORK(&job->work, drm_sched_entity_kill_jobs_work);
        schedule_work(&job->work);
 }
@@ -234,8 +235,10 @@ static void drm_sched_entity_kill_jobs(struct drm_sched_entity *entity)
                struct drm_sched_fence *s_fence = job->s_fence;
 
                /* Wait for all dependencies to avoid data corruptions */
-               while ((f = drm_sched_job_dependency(job, entity)))
+               while ((f = drm_sched_job_dependency(job, entity))) {
                        dma_fence_wait(f, false);
+                       dma_fence_put(f);
+               }
 
                drm_sched_fence_scheduled(s_fence);
                dma_fence_set_error(&s_fence->finished, -ESRCH);
@@ -250,6 +253,7 @@ static void drm_sched_entity_kill_jobs(struct drm_sched_entity *entity)
                        continue;
                }
 
+               dma_fence_get(entity->last_scheduled);
                r = dma_fence_add_callback(entity->last_scheduled,
                                           &job->finish_cb,
                                           drm_sched_entity_kill_jobs_cb);
index b9eeb87..07f0d79 100644 (file)
@@ -20,12 +20,12 @@ static struct gpiod_lookup_table *simatic_ipc_led_gpio_table;
 static struct gpiod_lookup_table simatic_ipc_led_gpio_table_127e = {
        .dev_id = "leds-gpio",
        .table = {
-               GPIO_LOOKUP_IDX("apollolake-pinctrl.0", 52, NULL, 1, GPIO_ACTIVE_LOW),
-               GPIO_LOOKUP_IDX("apollolake-pinctrl.0", 53, NULL, 2, GPIO_ACTIVE_LOW),
-               GPIO_LOOKUP_IDX("apollolake-pinctrl.0", 57, NULL, 3, GPIO_ACTIVE_LOW),
-               GPIO_LOOKUP_IDX("apollolake-pinctrl.0", 58, NULL, 4, GPIO_ACTIVE_LOW),
-               GPIO_LOOKUP_IDX("apollolake-pinctrl.0", 60, NULL, 5, GPIO_ACTIVE_LOW),
-               GPIO_LOOKUP_IDX("apollolake-pinctrl.0", 51, NULL, 0, GPIO_ACTIVE_LOW),
+               GPIO_LOOKUP_IDX("apollolake-pinctrl.0", 52, NULL, 0, GPIO_ACTIVE_LOW),
+               GPIO_LOOKUP_IDX("apollolake-pinctrl.0", 53, NULL, 1, GPIO_ACTIVE_LOW),
+               GPIO_LOOKUP_IDX("apollolake-pinctrl.0", 57, NULL, 2, GPIO_ACTIVE_LOW),
+               GPIO_LOOKUP_IDX("apollolake-pinctrl.0", 58, NULL, 3, GPIO_ACTIVE_LOW),
+               GPIO_LOOKUP_IDX("apollolake-pinctrl.0", 60, NULL, 4, GPIO_ACTIVE_LOW),
+               GPIO_LOOKUP_IDX("apollolake-pinctrl.0", 51, NULL, 5, GPIO_ACTIVE_LOW),
                GPIO_LOOKUP_IDX("apollolake-pinctrl.0", 56, NULL, 6, GPIO_ACTIVE_LOW),
                GPIO_LOOKUP_IDX("apollolake-pinctrl.0", 59, NULL, 7, GPIO_ACTIVE_HIGH),
        },
index 04b7566..f28440e 100644 (file)
@@ -339,6 +339,28 @@ static int vidioc_g_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *a
        return vivid_vid_out_g_fbuf(file, fh, a);
 }
 
+/*
+ * Only support the framebuffer of one of the vivid instances.
+ * Anything else is rejected.
+ */
+bool vivid_validate_fb(const struct v4l2_framebuffer *a)
+{
+       struct vivid_dev *dev;
+       int i;
+
+       for (i = 0; i < n_devs; i++) {
+               dev = vivid_devs[i];
+               if (!dev || !dev->video_pbase)
+                       continue;
+               if ((unsigned long)a->base == dev->video_pbase &&
+                   a->fmt.width <= dev->display_width &&
+                   a->fmt.height <= dev->display_height &&
+                   a->fmt.bytesperline <= dev->display_byte_stride)
+                       return true;
+       }
+       return false;
+}
+
 static int vidioc_s_fbuf(struct file *file, void *fh, const struct v4l2_framebuffer *a)
 {
        struct video_device *vdev = video_devdata(file);
@@ -920,8 +942,12 @@ static int vivid_detect_feature_set(struct vivid_dev *dev, int inst,
 
        /* how many inputs do we have and of what type? */
        dev->num_inputs = num_inputs[inst];
-       if (dev->num_inputs < 1)
-               dev->num_inputs = 1;
+       if (node_type & 0x20007) {
+               if (dev->num_inputs < 1)
+                       dev->num_inputs = 1;
+       } else {
+               dev->num_inputs = 0;
+       }
        if (dev->num_inputs >= MAX_INPUTS)
                dev->num_inputs = MAX_INPUTS;
        for (i = 0; i < dev->num_inputs; i++) {
@@ -938,8 +964,12 @@ static int vivid_detect_feature_set(struct vivid_dev *dev, int inst,
 
        /* how many outputs do we have and of what type? */
        dev->num_outputs = num_outputs[inst];
-       if (dev->num_outputs < 1)
-               dev->num_outputs = 1;
+       if (node_type & 0x40300) {
+               if (dev->num_outputs < 1)
+                       dev->num_outputs = 1;
+       } else {
+               dev->num_outputs = 0;
+       }
        if (dev->num_outputs >= MAX_OUTPUTS)
                dev->num_outputs = MAX_OUTPUTS;
        for (i = 0; i < dev->num_outputs; i++) {
index bfcfb35..473f359 100644 (file)
@@ -613,4 +613,6 @@ static inline bool vivid_is_hdmi_out(const struct vivid_dev *dev)
        return dev->output_type[dev->output] == HDMI;
 }
 
+bool vivid_validate_fb(const struct v4l2_framebuffer *a);
+
 #endif
index fbaec8a..ec25edc 100644 (file)
@@ -357,7 +357,7 @@ int vivid_fb_init(struct vivid_dev *dev)
        int ret;
 
        dev->video_buffer_size = MAX_OSD_HEIGHT * MAX_OSD_WIDTH * 2;
-       dev->video_vbase = kzalloc(dev->video_buffer_size, GFP_KERNEL | GFP_DMA32);
+       dev->video_vbase = kzalloc(dev->video_buffer_size, GFP_KERNEL);
        if (dev->video_vbase == NULL)
                return -ENOMEM;
        dev->video_pbase = virt_to_phys(dev->video_vbase);
index 86b158e..11620ea 100644 (file)
@@ -453,6 +453,12 @@ void vivid_update_format_cap(struct vivid_dev *dev, bool keep_controls)
        tpg_reset_source(&dev->tpg, dev->src_rect.width, dev->src_rect.height, dev->field_cap);
        dev->crop_cap = dev->src_rect;
        dev->crop_bounds_cap = dev->src_rect;
+       if (dev->bitmap_cap &&
+           (dev->compose_cap.width != dev->crop_cap.width ||
+            dev->compose_cap.height != dev->crop_cap.height)) {
+               vfree(dev->bitmap_cap);
+               dev->bitmap_cap = NULL;
+       }
        dev->compose_cap = dev->crop_cap;
        if (V4L2_FIELD_HAS_T_OR_B(dev->field_cap))
                dev->compose_cap.height /= 2;
@@ -460,6 +466,14 @@ void vivid_update_format_cap(struct vivid_dev *dev, bool keep_controls)
        tpg_s_video_aspect(&dev->tpg, vivid_get_video_aspect(dev));
        tpg_s_pixel_aspect(&dev->tpg, vivid_get_pixel_aspect(dev));
        tpg_update_mv_step(&dev->tpg);
+
+       /*
+        * We can be called from within s_ctrl, in that case we can't
+        * modify controls. Luckily we don't need to in that case.
+        */
+       if (keep_controls)
+               return;
+
        dims[0] = roundup(dev->src_rect.width, PIXEL_ARRAY_DIV);
        dims[1] = roundup(dev->src_rect.height, PIXEL_ARRAY_DIV);
        v4l2_ctrl_modify_dimensions(dev->pixel_array, dims);
@@ -913,6 +927,8 @@ int vivid_vid_cap_s_selection(struct file *file, void *fh, struct v4l2_selection
        struct vivid_dev *dev = video_drvdata(file);
        struct v4l2_rect *crop = &dev->crop_cap;
        struct v4l2_rect *compose = &dev->compose_cap;
+       unsigned orig_compose_w = compose->width;
+       unsigned orig_compose_h = compose->height;
        unsigned factor = V4L2_FIELD_HAS_T_OR_B(dev->field_cap) ? 2 : 1;
        int ret;
 
@@ -1029,17 +1045,17 @@ int vivid_vid_cap_s_selection(struct file *file, void *fh, struct v4l2_selection
                        s->r.height /= factor;
                }
                v4l2_rect_map_inside(&s->r, &dev->fmt_cap_rect);
-               if (dev->bitmap_cap && (compose->width != s->r.width ||
-                                       compose->height != s->r.height)) {
-                       vfree(dev->bitmap_cap);
-                       dev->bitmap_cap = NULL;
-               }
                *compose = s->r;
                break;
        default:
                return -EINVAL;
        }
 
+       if (dev->bitmap_cap && (compose->width != orig_compose_w ||
+                               compose->height != orig_compose_h)) {
+               vfree(dev->bitmap_cap);
+               dev->bitmap_cap = NULL;
+       }
        tpg_s_crop_compose(&dev->tpg, crop, compose);
        return 0;
 }
@@ -1276,7 +1292,14 @@ int vivid_vid_cap_s_fbuf(struct file *file, void *fh,
                return -EINVAL;
        if (a->fmt.bytesperline < (a->fmt.width * fmt->bit_depth[0]) / 8)
                return -EINVAL;
-       if (a->fmt.height * a->fmt.bytesperline < a->fmt.sizeimage)
+       if (a->fmt.bytesperline > a->fmt.sizeimage / a->fmt.height)
+               return -EINVAL;
+
+       /*
+        * Only support the framebuffer of one of the vivid instances.
+        * Anything else is rejected.
+        */
+       if (!vivid_validate_fb(a))
                return -EINVAL;
 
        dev->fb_vbase_cap = phys_to_virt((unsigned long)a->base);
index af48705..003c32f 100644 (file)
@@ -161,6 +161,20 @@ bool v4l2_valid_dv_timings(const struct v4l2_dv_timings *t,
            (bt->interlaced && !(caps & V4L2_DV_BT_CAP_INTERLACED)) ||
            (!bt->interlaced && !(caps & V4L2_DV_BT_CAP_PROGRESSIVE)))
                return false;
+
+       /* sanity checks for the blanking timings */
+       if (!bt->interlaced &&
+           (bt->il_vbackporch || bt->il_vsync || bt->il_vfrontporch))
+               return false;
+       if (bt->hfrontporch > 2 * bt->width ||
+           bt->hsync > 1024 || bt->hbackporch > 1024)
+               return false;
+       if (bt->vfrontporch > 4096 ||
+           bt->vsync > 128 || bt->vbackporch > 4096)
+               return false;
+       if (bt->interlaced && (bt->il_vfrontporch > 4096 ||
+           bt->il_vsync > 128 || bt->il_vbackporch > 4096))
+               return false;
        return fnc == NULL || fnc(t, fnc_handle);
 }
 EXPORT_SYMBOL_GPL(v4l2_valid_dv_timings);
index 54cd009..db6d8a0 100644 (file)
@@ -134,6 +134,7 @@ struct mmc_blk_data {
         * track of the current selected device partition.
         */
        unsigned int    part_curr;
+#define MMC_BLK_PART_INVALID   UINT_MAX        /* Unknown partition active */
        int     area_type;
 
        /* debugfs files (only in main mmc_blk_data) */
@@ -987,33 +988,39 @@ static unsigned int mmc_blk_data_timeout_ms(struct mmc_host *host,
        return ms;
 }
 
+/*
+ * Attempts to reset the card and get back to the requested partition.
+ * Therefore any error here must result in cancelling the block layer
+ * request, it must not be reattempted without going through the mmc_blk
+ * partition sanity checks.
+ */
 static int mmc_blk_reset(struct mmc_blk_data *md, struct mmc_host *host,
                         int type)
 {
        int err;
+       struct mmc_blk_data *main_md = dev_get_drvdata(&host->card->dev);
 
        if (md->reset_done & type)
                return -EEXIST;
 
        md->reset_done |= type;
        err = mmc_hw_reset(host->card);
+       /*
+        * A successful reset will leave the card in the main partition, but
+        * upon failure it might not be, so set it to MMC_BLK_PART_INVALID
+        * in that case.
+        */
+       main_md->part_curr = err ? MMC_BLK_PART_INVALID : main_md->part_type;
+       if (err)
+               return err;
        /* Ensure we switch back to the correct partition */
-       if (err) {
-               struct mmc_blk_data *main_md =
-                       dev_get_drvdata(&host->card->dev);
-               int part_err;
-
-               main_md->part_curr = main_md->part_type;
-               part_err = mmc_blk_part_switch(host->card, md->part_type);
-               if (part_err) {
-                       /*
-                        * We have failed to get back into the correct
-                        * partition, so we need to abort the whole request.
-                        */
-                       return -ENODEV;
-               }
-       }
-       return err;
+       if (mmc_blk_part_switch(host->card, md->part_type))
+               /*
+                * We have failed to get back into the correct
+                * partition, so we need to abort the whole request.
+                */
+               return -ENODEV;
+       return 0;
 }
 
 static inline void mmc_blk_reset_success(struct mmc_blk_data *md, int type)
@@ -1871,8 +1878,9 @@ static void mmc_blk_mq_rw_recovery(struct mmc_queue *mq, struct request *req)
                return;
 
        /* Reset before last retry */
-       if (mqrq->retries + 1 == MMC_MAX_RETRIES)
-               mmc_blk_reset(md, card->host, type);
+       if (mqrq->retries + 1 == MMC_MAX_RETRIES &&
+           mmc_blk_reset(md, card->host, type))
+               return;
 
        /* Command errors fail fast, so use all MMC_MAX_RETRIES */
        if (brq->sbc.error || brq->cmd.error)
index fefaa90..b396e39 100644 (file)
@@ -48,6 +48,7 @@ static enum mmc_issue_type mmc_cqe_issue_type(struct mmc_host *host,
        case REQ_OP_DRV_OUT:
        case REQ_OP_DISCARD:
        case REQ_OP_SECURE_ERASE:
+       case REQ_OP_WRITE_ZEROES:
                return MMC_ISSUE_SYNC;
        case REQ_OP_FLUSH:
                return mmc_cqe_can_dcmd(host) ? MMC_ISSUE_DCMD : MMC_ISSUE_SYNC;
@@ -493,6 +494,13 @@ void mmc_cleanup_queue(struct mmc_queue *mq)
        if (blk_queue_quiesced(q))
                blk_mq_unquiesce_queue(q);
 
+       /*
+        * If the recovery completes the last (and only remaining) request in
+        * the queue, and the card has been removed, we could end up here with
+        * the recovery not quite finished yet, so cancel it.
+        */
+       cancel_work_sync(&mq->recovery_work);
+
        blk_mq_free_tag_set(&mq->tag_set);
 
        /*
index c6268c3..babf21a 100644 (file)
@@ -291,7 +291,8 @@ static void sdio_release_func(struct device *dev)
 {
        struct sdio_func *func = dev_to_sdio_func(dev);
 
-       sdio_free_func_cis(func);
+       if (!(func->card->quirks & MMC_QUIRK_NONSTD_SDIO))
+               sdio_free_func_cis(func);
 
        kfree(func->info);
        kfree(func->tmpbuf);
index f324daa..fb1062a 100644 (file)
@@ -1075,9 +1075,10 @@ config MMC_SDHCI_OMAP
 
 config MMC_SDHCI_AM654
        tristate "Support for the SDHCI Controller in TI's AM654 SOCs"
-       depends on MMC_SDHCI_PLTFM && OF && REGMAP_MMIO
+       depends on MMC_SDHCI_PLTFM && OF
        select MMC_SDHCI_IO_ACCESSORS
        select MMC_CQHCI
+       select REGMAP_MMIO
        help
          This selects the Secure Digital Host Controller Interface (SDHCI)
          support present in TI's AM654 SOCs. The controller supports
index 55981b0..747df79 100644 (file)
@@ -1660,6 +1660,10 @@ static int sdhci_esdhc_imx_probe(struct platform_device *pdev)
                host->mmc_host_ops.execute_tuning = usdhc_execute_tuning;
        }
 
+       err = sdhci_esdhc_imx_probe_dt(pdev, host, imx_data);
+       if (err)
+               goto disable_ahb_clk;
+
        if (imx_data->socdata->flags & ESDHC_FLAG_MAN_TUNING)
                sdhci_esdhc_ops.platform_execute_tuning =
                                        esdhc_executing_tuning;
@@ -1667,13 +1671,15 @@ static int sdhci_esdhc_imx_probe(struct platform_device *pdev)
        if (imx_data->socdata->flags & ESDHC_FLAG_ERR004536)
                host->quirks |= SDHCI_QUIRK_BROKEN_ADMA;
 
-       if (imx_data->socdata->flags & ESDHC_FLAG_HS400)
+       if (host->caps & MMC_CAP_8_BIT_DATA &&
+           imx_data->socdata->flags & ESDHC_FLAG_HS400)
                host->mmc->caps2 |= MMC_CAP2_HS400;
 
        if (imx_data->socdata->flags & ESDHC_FLAG_BROKEN_AUTO_CMD23)
                host->quirks2 |= SDHCI_QUIRK2_ACMD23_BROKEN;
 
-       if (imx_data->socdata->flags & ESDHC_FLAG_HS400_ES) {
+       if (host->caps & MMC_CAP_8_BIT_DATA &&
+           imx_data->socdata->flags & ESDHC_FLAG_HS400_ES) {
                host->mmc->caps2 |= MMC_CAP2_HS400_ES;
                host->mmc_host_ops.hs400_enhanced_strobe =
                                        esdhc_hs400_enhanced_strobe;
@@ -1695,10 +1701,6 @@ static int sdhci_esdhc_imx_probe(struct platform_device *pdev)
                        goto disable_ahb_clk;
        }
 
-       err = sdhci_esdhc_imx_probe_dt(pdev, host, imx_data);
-       if (err)
-               goto disable_ahb_clk;
-
        sdhci_esdhc_imx_hwinit(host);
 
        err = sdhci_add_host(host);
index 169b847..34ea1ac 100644 (file)
@@ -914,6 +914,12 @@ static bool glk_broken_cqhci(struct sdhci_pci_slot *slot)
                dmi_match(DMI_SYS_VENDOR, "IRBIS"));
 }
 
+static bool jsl_broken_hs400es(struct sdhci_pci_slot *slot)
+{
+       return slot->chip->pdev->device == PCI_DEVICE_ID_INTEL_JSL_EMMC &&
+                       dmi_match(DMI_BIOS_VENDOR, "ASUSTeK COMPUTER INC.");
+}
+
 static int glk_emmc_probe_slot(struct sdhci_pci_slot *slot)
 {
        int ret = byt_emmc_probe_slot(slot);
@@ -922,9 +928,11 @@ static int glk_emmc_probe_slot(struct sdhci_pci_slot *slot)
                slot->host->mmc->caps2 |= MMC_CAP2_CQE;
 
        if (slot->chip->pdev->device != PCI_DEVICE_ID_INTEL_GLK_EMMC) {
-               slot->host->mmc->caps2 |= MMC_CAP2_HS400_ES;
-               slot->host->mmc_host_ops.hs400_enhanced_strobe =
-                                               intel_hs400_enhanced_strobe;
+               if (!jsl_broken_hs400es(slot)) {
+                       slot->host->mmc->caps2 |= MMC_CAP2_HS400_ES;
+                       slot->host->mmc_host_ops.hs400_enhanced_strobe =
+                                                       intel_hs400_enhanced_strobe;
+               }
                slot->host->mmc->caps2 |= MMC_CAP2_CQE_DCMD;
        }
 
index 18aa544..0b4ca0a 100644 (file)
@@ -562,7 +562,7 @@ static void mtd_check_of_node(struct mtd_info *mtd)
        if (!mtd_is_partition(mtd))
                return;
        parent = mtd->parent;
-       parent_dn = dev_of_node(&parent->dev);
+       parent_dn = of_node_get(dev_of_node(&parent->dev));
        if (!parent_dn)
                return;
 
index d4a0987..6f4cea8 100644 (file)
@@ -608,11 +608,12 @@ static int ebu_nand_probe(struct platform_device *pdev)
        ret = of_property_read_u32(chip_np, "reg", &cs);
        if (ret) {
                dev_err(dev, "failed to get chip select: %d\n", ret);
-               return ret;
+               goto err_of_node_put;
        }
        if (cs >= MAX_CS) {
                dev_err(dev, "got invalid chip select: %d\n", cs);
-               return -EINVAL;
+               ret = -EINVAL;
+               goto err_of_node_put;
        }
 
        ebu_host->cs_num = cs;
@@ -620,18 +621,22 @@ static int ebu_nand_probe(struct platform_device *pdev)
        resname = devm_kasprintf(dev, GFP_KERNEL, "nand_cs%d", cs);
        ebu_host->cs[cs].chipaddr = devm_platform_ioremap_resource_byname(pdev,
                                                                          resname);
-       if (IS_ERR(ebu_host->cs[cs].chipaddr))
-               return PTR_ERR(ebu_host->cs[cs].chipaddr);
+       if (IS_ERR(ebu_host->cs[cs].chipaddr)) {
+               ret = PTR_ERR(ebu_host->cs[cs].chipaddr);
+               goto err_of_node_put;
+       }
 
        ebu_host->clk = devm_clk_get(dev, NULL);
-       if (IS_ERR(ebu_host->clk))
-               return dev_err_probe(dev, PTR_ERR(ebu_host->clk),
-                                    "failed to get clock\n");
+       if (IS_ERR(ebu_host->clk)) {
+               ret = dev_err_probe(dev, PTR_ERR(ebu_host->clk),
+                                   "failed to get clock\n");
+               goto err_of_node_put;
+       }
 
        ret = clk_prepare_enable(ebu_host->clk);
        if (ret) {
                dev_err(dev, "failed to enable clock: %d\n", ret);
-               return ret;
+               goto err_of_node_put;
        }
 
        ebu_host->dma_tx = dma_request_chan(dev, "tx");
@@ -695,6 +700,8 @@ err_cleanup_dma:
        ebu_dma_cleanup(ebu_host);
 err_disable_unprepare_clk:
        clk_disable_unprepare(ebu_host->clk);
+err_of_node_put:
+       of_node_put(chip_np);
 
        return ret;
 }
index d9f2f1d..b9d1e96 100644 (file)
@@ -2678,7 +2678,7 @@ static int marvell_nand_chip_init(struct device *dev, struct marvell_nfc *nfc,
        chip->controller = &nfc->controller;
        nand_set_flash_node(chip, np);
 
-       if (!of_property_read_bool(np, "marvell,nand-keep-config"))
+       if (of_property_read_bool(np, "marvell,nand-keep-config"))
                chip->options |= NAND_KEEP_TIMINGS;
 
        mtd = nand_to_mtd(chip);
index e12f9f5..a9b9031 100644 (file)
@@ -1181,7 +1181,7 @@ static int tegra_nand_probe(struct platform_device *pdev)
        pm_runtime_enable(&pdev->dev);
        err = pm_runtime_resume_and_get(&pdev->dev);
        if (err)
-               return err;
+               goto err_dis_pm;
 
        err = reset_control_reset(rst);
        if (err) {
@@ -1215,6 +1215,8 @@ static int tegra_nand_probe(struct platform_device *pdev)
 err_put_pm:
        pm_runtime_put_sync_suspend(ctrl->dev);
        pm_runtime_force_suspend(ctrl->dev);
+err_dis_pm:
+       pm_runtime_disable(&pdev->dev);
        return err;
 }
 
index 50fcf4c..13daf9b 100644 (file)
@@ -233,11 +233,11 @@ static int bcm47xxpart_parse(struct mtd_info *master,
                }
 
                /* Read middle of the block */
-               err = mtd_read(master, offset + 0x8000, 0x4, &bytes_read,
+               err = mtd_read(master, offset + (blocksize / 2), 0x4, &bytes_read,
                               (uint8_t *)buf);
                if (err && !mtd_is_bitflip(err)) {
                        pr_err("mtd_read error while parsing (offset: 0x%X): %d\n",
-                              offset + 0x8000, err);
+                              offset + (blocksize / 2), err);
                        continue;
                }
 
index f2c6400..bee8fc4 100644 (file)
@@ -2724,7 +2724,9 @@ static int spi_nor_init(struct spi_nor *nor)
                 */
                WARN_ONCE(nor->flags & SNOR_F_BROKEN_RESET,
                          "enabling reset hack; may not recover from unexpected reboots\n");
-               return nor->params->set_4byte_addr_mode(nor, true);
+               err = nor->params->set_4byte_addr_mode(nor, true);
+               if (err && err != -ENOTSUPP)
+                       return err;
        }
 
        return 0;
index c469b2f..b0ed798 100644 (file)
@@ -322,14 +322,14 @@ static int mpc5xxx_can_probe(struct platform_device *ofdev)
                                               &mscan_clksrc);
        if (!priv->can.clock.freq) {
                dev_err(&ofdev->dev, "couldn't get MSCAN clock properties\n");
-               goto exit_free_mscan;
+               goto exit_put_clock;
        }
 
        err = register_mscandev(dev, mscan_clksrc);
        if (err) {
                dev_err(&ofdev->dev, "registering %s failed (err=%d)\n",
                        DRV_NAME, err);
-               goto exit_free_mscan;
+               goto exit_put_clock;
        }
 
        dev_info(&ofdev->dev, "MSCAN at 0x%p, irq %d, clock %d Hz\n",
@@ -337,7 +337,9 @@ static int mpc5xxx_can_probe(struct platform_device *ofdev)
 
        return 0;
 
-exit_free_mscan:
+exit_put_clock:
+       if (data->put_clock)
+               data->put_clock(ofdev);
        free_candev(dev);
 exit_dispose_irq:
        irq_dispose_mapping(irq);
index 567620d..198da64 100644 (file)
@@ -1157,11 +1157,13 @@ static void rcar_canfd_handle_global_receive(struct rcar_canfd_global *gpriv, u3
 {
        struct rcar_canfd_channel *priv = gpriv->ch[ch];
        u32 ridx = ch + RCANFD_RFFIFO_IDX;
-       u32 sts;
+       u32 sts, cc;
 
        /* Handle Rx interrupts */
        sts = rcar_canfd_read(priv->base, RCANFD_RFSTS(gpriv, ridx));
-       if (likely(sts & RCANFD_RFSTS_RFIF)) {
+       cc = rcar_canfd_read(priv->base, RCANFD_RFCC(gpriv, ridx));
+       if (likely(sts & RCANFD_RFSTS_RFIF &&
+                  cc & RCANFD_RFCC_RFIE)) {
                if (napi_schedule_prep(&priv->napi)) {
                        /* Disable Rx FIFO interrupts */
                        rcar_canfd_clear_bit(priv->base,
@@ -1244,11 +1246,9 @@ static void rcar_canfd_handle_channel_tx(struct rcar_canfd_global *gpriv, u32 ch
 
 static irqreturn_t rcar_canfd_channel_tx_interrupt(int irq, void *dev_id)
 {
-       struct rcar_canfd_global *gpriv = dev_id;
-       u32 ch;
+       struct rcar_canfd_channel *priv = dev_id;
 
-       for_each_set_bit(ch, &gpriv->channels_mask, gpriv->max_channels)
-               rcar_canfd_handle_channel_tx(gpriv, ch);
+       rcar_canfd_handle_channel_tx(priv->gpriv, priv->channel);
 
        return IRQ_HANDLED;
 }
@@ -1276,11 +1276,9 @@ static void rcar_canfd_handle_channel_err(struct rcar_canfd_global *gpriv, u32 c
 
 static irqreturn_t rcar_canfd_channel_err_interrupt(int irq, void *dev_id)
 {
-       struct rcar_canfd_global *gpriv = dev_id;
-       u32 ch;
+       struct rcar_canfd_channel *priv = dev_id;
 
-       for_each_set_bit(ch, &gpriv->channels_mask, gpriv->max_channels)
-               rcar_canfd_handle_channel_err(gpriv, ch);
+       rcar_canfd_handle_channel_err(priv->gpriv, priv->channel);
 
        return IRQ_HANDLED;
 }
@@ -1721,6 +1719,7 @@ static int rcar_canfd_channel_probe(struct rcar_canfd_global *gpriv, u32 ch,
        priv->ndev = ndev;
        priv->base = gpriv->base;
        priv->channel = ch;
+       priv->gpriv = gpriv;
        priv->can.clock.freq = fcan_freq;
        dev_info(&pdev->dev, "can_clk rate is %u\n", priv->can.clock.freq);
 
@@ -1749,7 +1748,7 @@ static int rcar_canfd_channel_probe(struct rcar_canfd_global *gpriv, u32 ch,
                }
                err = devm_request_irq(&pdev->dev, err_irq,
                                       rcar_canfd_channel_err_interrupt, 0,
-                                      irq_name, gpriv);
+                                      irq_name, priv);
                if (err) {
                        dev_err(&pdev->dev, "devm_request_irq CH Err(%d) failed, error %d\n",
                                err_irq, err);
@@ -1763,7 +1762,7 @@ static int rcar_canfd_channel_probe(struct rcar_canfd_global *gpriv, u32 ch,
                }
                err = devm_request_irq(&pdev->dev, tx_irq,
                                       rcar_canfd_channel_tx_interrupt, 0,
-                                      irq_name, gpriv);
+                                      irq_name, priv);
                if (err) {
                        dev_err(&pdev->dev, "devm_request_irq Tx (%d) failed, error %d\n",
                                tx_irq, err);
@@ -1789,7 +1788,6 @@ static int rcar_canfd_channel_probe(struct rcar_canfd_global *gpriv, u32 ch,
 
        priv->can.do_set_mode = rcar_canfd_do_set_mode;
        priv->can.do_get_berr_counter = rcar_canfd_get_berr_counter;
-       priv->gpriv = gpriv;
        SET_NETDEV_DEV(ndev, &pdev->dev);
 
        netif_napi_add_weight(ndev, &priv->napi, rcar_canfd_rx_poll,
index c320de4..24883a6 100644 (file)
@@ -1415,11 +1415,14 @@ static int mcp251x_can_probe(struct spi_device *spi)
 
        ret = mcp251x_gpio_setup(priv);
        if (ret)
-               goto error_probe;
+               goto out_unregister_candev;
 
        netdev_info(net, "MCP%x successfully initialized.\n", priv->model);
        return 0;
 
+out_unregister_candev:
+       unregister_candev(net);
+
 error_probe:
        destroy_workqueue(priv->wq);
        priv->wq = NULL;
index 7b52fda..66f672e 100644 (file)
@@ -1875,7 +1875,7 @@ static int kvaser_usb_hydra_start_chip(struct kvaser_usb_net_priv *priv)
 {
        int err;
 
-       init_completion(&priv->start_comp);
+       reinit_completion(&priv->start_comp);
 
        err = kvaser_usb_hydra_send_simple_cmd(priv->dev, CMD_START_CHIP_REQ,
                                               priv->channel);
@@ -1893,7 +1893,7 @@ static int kvaser_usb_hydra_stop_chip(struct kvaser_usb_net_priv *priv)
 {
        int err;
 
-       init_completion(&priv->stop_comp);
+       reinit_completion(&priv->stop_comp);
 
        /* Make sure we do not report invalid BUS_OFF from CMD_CHIP_STATE_EVENT
         * see comment in kvaser_usb_hydra_update_state()
index 50f2ac8..1995803 100644 (file)
@@ -1320,7 +1320,7 @@ static int kvaser_usb_leaf_start_chip(struct kvaser_usb_net_priv *priv)
 {
        int err;
 
-       init_completion(&priv->start_comp);
+       reinit_completion(&priv->start_comp);
 
        err = kvaser_usb_leaf_send_simple_cmd(priv->dev, CMD_START_CHIP,
                                              priv->channel);
@@ -1338,7 +1338,7 @@ static int kvaser_usb_leaf_stop_chip(struct kvaser_usb_net_priv *priv)
 {
        int err;
 
-       init_completion(&priv->stop_comp);
+       reinit_completion(&priv->stop_comp);
 
        err = kvaser_usb_leaf_send_simple_cmd(priv->dev, CMD_STOP_CHIP,
                                              priv->channel);
index 2af3da4..f409d7b 100644 (file)
@@ -285,6 +285,9 @@ static int xgbe_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 
                /* Yellow Carp devices do not need cdr workaround */
                pdata->vdata->an_cdr_workaround = 0;
+
+               /* Yellow Carp devices do not need rrc */
+               pdata->vdata->enable_rrc = 0;
        } else {
                pdata->xpcs_window_def_reg = PCS_V2_WINDOW_DEF;
                pdata->xpcs_window_sel_reg = PCS_V2_WINDOW_SELECT;
@@ -483,6 +486,7 @@ static struct xgbe_version_data xgbe_v2a = {
        .tx_desc_prefetch               = 5,
        .rx_desc_prefetch               = 5,
        .an_cdr_workaround              = 1,
+       .enable_rrc                     = 1,
 };
 
 static struct xgbe_version_data xgbe_v2b = {
@@ -498,6 +502,7 @@ static struct xgbe_version_data xgbe_v2b = {
        .tx_desc_prefetch               = 5,
        .rx_desc_prefetch               = 5,
        .an_cdr_workaround              = 1,
+       .enable_rrc                     = 1,
 };
 
 static const struct pci_device_id xgbe_pci_table[] = {
index 2156600..4064c3e 100644 (file)
@@ -239,6 +239,7 @@ enum xgbe_sfp_speed {
 #define XGBE_SFP_BASE_BR_1GBE_MAX              0x0d
 #define XGBE_SFP_BASE_BR_10GBE_MIN             0x64
 #define XGBE_SFP_BASE_BR_10GBE_MAX             0x68
+#define XGBE_MOLEX_SFP_BASE_BR_10GBE_MAX       0x78
 
 #define XGBE_SFP_BASE_CU_CABLE_LEN             18
 
@@ -284,6 +285,8 @@ struct xgbe_sfp_eeprom {
 #define XGBE_BEL_FUSE_VENDOR   "BEL-FUSE        "
 #define XGBE_BEL_FUSE_PARTNO   "1GBT-SFP06      "
 
+#define XGBE_MOLEX_VENDOR      "Molex Inc.      "
+
 struct xgbe_sfp_ascii {
        union {
                char vendor[XGBE_SFP_BASE_VENDOR_NAME_LEN + 1];
@@ -834,7 +837,11 @@ static bool xgbe_phy_sfp_bit_rate(struct xgbe_sfp_eeprom *sfp_eeprom,
                break;
        case XGBE_SFP_SPEED_10000:
                min = XGBE_SFP_BASE_BR_10GBE_MIN;
-               max = XGBE_SFP_BASE_BR_10GBE_MAX;
+               if (memcmp(&sfp_eeprom->base[XGBE_SFP_BASE_VENDOR_NAME],
+                          XGBE_MOLEX_VENDOR, XGBE_SFP_BASE_VENDOR_NAME_LEN) == 0)
+                       max = XGBE_MOLEX_SFP_BASE_BR_10GBE_MAX;
+               else
+                       max = XGBE_SFP_BASE_BR_10GBE_MAX;
                break;
        default:
                return false;
@@ -1151,7 +1158,10 @@ static void xgbe_phy_sfp_parse_eeprom(struct xgbe_prv_data *pdata)
        }
 
        /* Determine the type of SFP */
-       if (sfp_base[XGBE_SFP_BASE_10GBE_CC] & XGBE_SFP_BASE_10GBE_CC_SR)
+       if (phy_data->sfp_cable == XGBE_SFP_CABLE_PASSIVE &&
+           xgbe_phy_sfp_bit_rate(sfp_eeprom, XGBE_SFP_SPEED_10000))
+               phy_data->sfp_base = XGBE_SFP_BASE_10000_CR;
+       else if (sfp_base[XGBE_SFP_BASE_10GBE_CC] & XGBE_SFP_BASE_10GBE_CC_SR)
                phy_data->sfp_base = XGBE_SFP_BASE_10000_SR;
        else if (sfp_base[XGBE_SFP_BASE_10GBE_CC] & XGBE_SFP_BASE_10GBE_CC_LR)
                phy_data->sfp_base = XGBE_SFP_BASE_10000_LR;
@@ -1167,9 +1177,6 @@ static void xgbe_phy_sfp_parse_eeprom(struct xgbe_prv_data *pdata)
                phy_data->sfp_base = XGBE_SFP_BASE_1000_CX;
        else if (sfp_base[XGBE_SFP_BASE_1GBE_CC] & XGBE_SFP_BASE_1GBE_CC_T)
                phy_data->sfp_base = XGBE_SFP_BASE_1000_T;
-       else if ((phy_data->sfp_cable == XGBE_SFP_CABLE_PASSIVE) &&
-                xgbe_phy_sfp_bit_rate(sfp_eeprom, XGBE_SFP_SPEED_10000))
-               phy_data->sfp_base = XGBE_SFP_BASE_10000_CR;
 
        switch (phy_data->sfp_base) {
        case XGBE_SFP_BASE_1000_T:
@@ -1979,6 +1986,10 @@ static void xgbe_phy_rx_reset(struct xgbe_prv_data *pdata)
 
 static void xgbe_phy_pll_ctrl(struct xgbe_prv_data *pdata, bool enable)
 {
+       /* PLL_CTRL feature needs to be enabled for fixed PHY modes (Non-Autoneg) only */
+       if (pdata->phy.autoneg != AUTONEG_DISABLE)
+               return;
+
        XMDIO_WRITE_BITS(pdata, MDIO_MMD_PMAPMD, MDIO_VEND2_PMA_MISC_CTRL0,
                         XGBE_PMA_PLL_CTRL_MASK,
                         enable ? XGBE_PMA_PLL_CTRL_ENABLE
@@ -1989,7 +2000,7 @@ static void xgbe_phy_pll_ctrl(struct xgbe_prv_data *pdata, bool enable)
 }
 
 static void xgbe_phy_perform_ratechange(struct xgbe_prv_data *pdata,
-                                       unsigned int cmd, unsigned int sub_cmd)
+                                       enum xgbe_mb_cmd cmd, enum xgbe_mb_subcmd sub_cmd)
 {
        unsigned int s0 = 0;
        unsigned int wait;
@@ -2029,14 +2040,16 @@ static void xgbe_phy_perform_ratechange(struct xgbe_prv_data *pdata,
        xgbe_phy_rx_reset(pdata);
 
 reenable_pll:
-       /* Enable PLL re-initialization */
-       xgbe_phy_pll_ctrl(pdata, true);
+       /* Enable PLL re-initialization, not needed for PHY Power Off and RRC cmds */
+       if (cmd != XGBE_MB_CMD_POWER_OFF &&
+           cmd != XGBE_MB_CMD_RRC)
+               xgbe_phy_pll_ctrl(pdata, true);
 }
 
 static void xgbe_phy_rrc(struct xgbe_prv_data *pdata)
 {
        /* Receiver Reset Cycle */
-       xgbe_phy_perform_ratechange(pdata, 5, 0);
+       xgbe_phy_perform_ratechange(pdata, XGBE_MB_CMD_RRC, XGBE_MB_SUBCMD_NONE);
 
        netif_dbg(pdata, link, pdata->netdev, "receiver reset complete\n");
 }
@@ -2046,7 +2059,7 @@ static void xgbe_phy_power_off(struct xgbe_prv_data *pdata)
        struct xgbe_phy_data *phy_data = pdata->phy_data;
 
        /* Power off */
-       xgbe_phy_perform_ratechange(pdata, 0, 0);
+       xgbe_phy_perform_ratechange(pdata, XGBE_MB_CMD_POWER_OFF, XGBE_MB_SUBCMD_NONE);
 
        phy_data->cur_mode = XGBE_MODE_UNKNOWN;
 
@@ -2061,14 +2074,17 @@ static void xgbe_phy_sfi_mode(struct xgbe_prv_data *pdata)
 
        /* 10G/SFI */
        if (phy_data->sfp_cable != XGBE_SFP_CABLE_PASSIVE) {
-               xgbe_phy_perform_ratechange(pdata, 3, 0);
+               xgbe_phy_perform_ratechange(pdata, XGBE_MB_CMD_SET_10G_SFI, XGBE_MB_SUBCMD_ACTIVE);
        } else {
                if (phy_data->sfp_cable_len <= 1)
-                       xgbe_phy_perform_ratechange(pdata, 3, 1);
+                       xgbe_phy_perform_ratechange(pdata, XGBE_MB_CMD_SET_10G_SFI,
+                                                   XGBE_MB_SUBCMD_PASSIVE_1M);
                else if (phy_data->sfp_cable_len <= 3)
-                       xgbe_phy_perform_ratechange(pdata, 3, 2);
+                       xgbe_phy_perform_ratechange(pdata, XGBE_MB_CMD_SET_10G_SFI,
+                                                   XGBE_MB_SUBCMD_PASSIVE_3M);
                else
-                       xgbe_phy_perform_ratechange(pdata, 3, 3);
+                       xgbe_phy_perform_ratechange(pdata, XGBE_MB_CMD_SET_10G_SFI,
+                                                   XGBE_MB_SUBCMD_PASSIVE_OTHER);
        }
 
        phy_data->cur_mode = XGBE_MODE_SFI;
@@ -2083,7 +2099,7 @@ static void xgbe_phy_x_mode(struct xgbe_prv_data *pdata)
        xgbe_phy_set_redrv_mode(pdata);
 
        /* 1G/X */
-       xgbe_phy_perform_ratechange(pdata, 1, 3);
+       xgbe_phy_perform_ratechange(pdata, XGBE_MB_CMD_SET_1G, XGBE_MB_SUBCMD_1G_KX);
 
        phy_data->cur_mode = XGBE_MODE_X;
 
@@ -2097,7 +2113,7 @@ static void xgbe_phy_sgmii_1000_mode(struct xgbe_prv_data *pdata)
        xgbe_phy_set_redrv_mode(pdata);
 
        /* 1G/SGMII */
-       xgbe_phy_perform_ratechange(pdata, 1, 2);
+       xgbe_phy_perform_ratechange(pdata, XGBE_MB_CMD_SET_1G, XGBE_MB_SUBCMD_1G_SGMII);
 
        phy_data->cur_mode = XGBE_MODE_SGMII_1000;
 
@@ -2111,7 +2127,7 @@ static void xgbe_phy_sgmii_100_mode(struct xgbe_prv_data *pdata)
        xgbe_phy_set_redrv_mode(pdata);
 
        /* 100M/SGMII */
-       xgbe_phy_perform_ratechange(pdata, 1, 1);
+       xgbe_phy_perform_ratechange(pdata, XGBE_MB_CMD_SET_1G, XGBE_MB_SUBCMD_100MBITS);
 
        phy_data->cur_mode = XGBE_MODE_SGMII_100;
 
@@ -2125,7 +2141,7 @@ static void xgbe_phy_kr_mode(struct xgbe_prv_data *pdata)
        xgbe_phy_set_redrv_mode(pdata);
 
        /* 10G/KR */
-       xgbe_phy_perform_ratechange(pdata, 4, 0);
+       xgbe_phy_perform_ratechange(pdata, XGBE_MB_CMD_SET_10G_KR, XGBE_MB_SUBCMD_NONE);
 
        phy_data->cur_mode = XGBE_MODE_KR;
 
@@ -2139,7 +2155,7 @@ static void xgbe_phy_kx_2500_mode(struct xgbe_prv_data *pdata)
        xgbe_phy_set_redrv_mode(pdata);
 
        /* 2.5G/KX */
-       xgbe_phy_perform_ratechange(pdata, 2, 0);
+       xgbe_phy_perform_ratechange(pdata, XGBE_MB_CMD_SET_2_5G, XGBE_MB_SUBCMD_NONE);
 
        phy_data->cur_mode = XGBE_MODE_KX_2500;
 
@@ -2153,7 +2169,7 @@ static void xgbe_phy_kx_1000_mode(struct xgbe_prv_data *pdata)
        xgbe_phy_set_redrv_mode(pdata);
 
        /* 1G/KX */
-       xgbe_phy_perform_ratechange(pdata, 1, 3);
+       xgbe_phy_perform_ratechange(pdata, XGBE_MB_CMD_SET_1G, XGBE_MB_SUBCMD_1G_KX);
 
        phy_data->cur_mode = XGBE_MODE_KX_1000;
 
@@ -2640,7 +2656,7 @@ static int xgbe_phy_link_status(struct xgbe_prv_data *pdata, int *an_restart)
        }
 
        /* No link, attempt a receiver reset cycle */
-       if (phy_data->rrc_count++ > XGBE_RRC_FREQUENCY) {
+       if (pdata->vdata->enable_rrc && phy_data->rrc_count++ > XGBE_RRC_FREQUENCY) {
                phy_data->rrc_count = 0;
                xgbe_phy_rrc(pdata);
        }
index b875c43..71f24cb 100644 (file)
@@ -611,6 +611,31 @@ enum xgbe_mdio_mode {
        XGBE_MDIO_MODE_CL45,
 };
 
+enum xgbe_mb_cmd {
+       XGBE_MB_CMD_POWER_OFF = 0,
+       XGBE_MB_CMD_SET_1G,
+       XGBE_MB_CMD_SET_2_5G,
+       XGBE_MB_CMD_SET_10G_SFI,
+       XGBE_MB_CMD_SET_10G_KR,
+       XGBE_MB_CMD_RRC
+};
+
+enum xgbe_mb_subcmd {
+       XGBE_MB_SUBCMD_NONE = 0,
+
+       /* 10GbE SFP subcommands */
+       XGBE_MB_SUBCMD_ACTIVE = 0,
+       XGBE_MB_SUBCMD_PASSIVE_1M,
+       XGBE_MB_SUBCMD_PASSIVE_3M,
+       XGBE_MB_SUBCMD_PASSIVE_OTHER,
+
+       /* 1GbE Mode subcommands */
+       XGBE_MB_SUBCMD_10MBITS = 0,
+       XGBE_MB_SUBCMD_100MBITS,
+       XGBE_MB_SUBCMD_1G_SGMII,
+       XGBE_MB_SUBCMD_1G_KX
+};
+
 struct xgbe_phy {
        struct ethtool_link_ksettings lks;
 
@@ -1013,6 +1038,7 @@ struct xgbe_version_data {
        unsigned int tx_desc_prefetch;
        unsigned int rx_desc_prefetch;
        unsigned int an_cdr_workaround;
+       unsigned int enable_rrc;
 };
 
 struct xgbe_prv_data {
index 3d0e167..a018081 100644 (file)
@@ -1394,26 +1394,57 @@ static void aq_check_txsa_expiration(struct aq_nic_s *nic)
                        egress_sa_threshold_expired);
 }
 
+#define AQ_LOCKED_MDO_DEF(mdo)                                         \
+static int aq_locked_mdo_##mdo(struct macsec_context *ctx)             \
+{                                                                      \
+       struct aq_nic_s *nic = netdev_priv(ctx->netdev);                \
+       int ret;                                                        \
+       mutex_lock(&nic->macsec_mutex);                                 \
+       ret = aq_mdo_##mdo(ctx);                                        \
+       mutex_unlock(&nic->macsec_mutex);                               \
+       return ret;                                                     \
+}
+
+AQ_LOCKED_MDO_DEF(dev_open)
+AQ_LOCKED_MDO_DEF(dev_stop)
+AQ_LOCKED_MDO_DEF(add_secy)
+AQ_LOCKED_MDO_DEF(upd_secy)
+AQ_LOCKED_MDO_DEF(del_secy)
+AQ_LOCKED_MDO_DEF(add_rxsc)
+AQ_LOCKED_MDO_DEF(upd_rxsc)
+AQ_LOCKED_MDO_DEF(del_rxsc)
+AQ_LOCKED_MDO_DEF(add_rxsa)
+AQ_LOCKED_MDO_DEF(upd_rxsa)
+AQ_LOCKED_MDO_DEF(del_rxsa)
+AQ_LOCKED_MDO_DEF(add_txsa)
+AQ_LOCKED_MDO_DEF(upd_txsa)
+AQ_LOCKED_MDO_DEF(del_txsa)
+AQ_LOCKED_MDO_DEF(get_dev_stats)
+AQ_LOCKED_MDO_DEF(get_tx_sc_stats)
+AQ_LOCKED_MDO_DEF(get_tx_sa_stats)
+AQ_LOCKED_MDO_DEF(get_rx_sc_stats)
+AQ_LOCKED_MDO_DEF(get_rx_sa_stats)
+
 const struct macsec_ops aq_macsec_ops = {
-       .mdo_dev_open = aq_mdo_dev_open,
-       .mdo_dev_stop = aq_mdo_dev_stop,
-       .mdo_add_secy = aq_mdo_add_secy,
-       .mdo_upd_secy = aq_mdo_upd_secy,
-       .mdo_del_secy = aq_mdo_del_secy,
-       .mdo_add_rxsc = aq_mdo_add_rxsc,
-       .mdo_upd_rxsc = aq_mdo_upd_rxsc,
-       .mdo_del_rxsc = aq_mdo_del_rxsc,
-       .mdo_add_rxsa = aq_mdo_add_rxsa,
-       .mdo_upd_rxsa = aq_mdo_upd_rxsa,
-       .mdo_del_rxsa = aq_mdo_del_rxsa,
-       .mdo_add_txsa = aq_mdo_add_txsa,
-       .mdo_upd_txsa = aq_mdo_upd_txsa,
-       .mdo_del_txsa = aq_mdo_del_txsa,
-       .mdo_get_dev_stats = aq_mdo_get_dev_stats,
-       .mdo_get_tx_sc_stats = aq_mdo_get_tx_sc_stats,
-       .mdo_get_tx_sa_stats = aq_mdo_get_tx_sa_stats,
-       .mdo_get_rx_sc_stats = aq_mdo_get_rx_sc_stats,
-       .mdo_get_rx_sa_stats = aq_mdo_get_rx_sa_stats,
+       .mdo_dev_open = aq_locked_mdo_dev_open,
+       .mdo_dev_stop = aq_locked_mdo_dev_stop,
+       .mdo_add_secy = aq_locked_mdo_add_secy,
+       .mdo_upd_secy = aq_locked_mdo_upd_secy,
+       .mdo_del_secy = aq_locked_mdo_del_secy,
+       .mdo_add_rxsc = aq_locked_mdo_add_rxsc,
+       .mdo_upd_rxsc = aq_locked_mdo_upd_rxsc,
+       .mdo_del_rxsc = aq_locked_mdo_del_rxsc,
+       .mdo_add_rxsa = aq_locked_mdo_add_rxsa,
+       .mdo_upd_rxsa = aq_locked_mdo_upd_rxsa,
+       .mdo_del_rxsa = aq_locked_mdo_del_rxsa,
+       .mdo_add_txsa = aq_locked_mdo_add_txsa,
+       .mdo_upd_txsa = aq_locked_mdo_upd_txsa,
+       .mdo_del_txsa = aq_locked_mdo_del_txsa,
+       .mdo_get_dev_stats = aq_locked_mdo_get_dev_stats,
+       .mdo_get_tx_sc_stats = aq_locked_mdo_get_tx_sc_stats,
+       .mdo_get_tx_sa_stats = aq_locked_mdo_get_tx_sa_stats,
+       .mdo_get_rx_sc_stats = aq_locked_mdo_get_rx_sc_stats,
+       .mdo_get_rx_sa_stats = aq_locked_mdo_get_rx_sa_stats,
 };
 
 int aq_macsec_init(struct aq_nic_s *nic)
@@ -1435,6 +1466,7 @@ int aq_macsec_init(struct aq_nic_s *nic)
 
        nic->ndev->features |= NETIF_F_HW_MACSEC;
        nic->ndev->macsec_ops = &aq_macsec_ops;
+       mutex_init(&nic->macsec_mutex);
 
        return 0;
 }
@@ -1458,7 +1490,7 @@ int aq_macsec_enable(struct aq_nic_s *nic)
        if (!nic->macsec_cfg)
                return 0;
 
-       rtnl_lock();
+       mutex_lock(&nic->macsec_mutex);
 
        if (nic->aq_fw_ops->send_macsec_req) {
                struct macsec_cfg_request cfg = { 0 };
@@ -1507,7 +1539,7 @@ int aq_macsec_enable(struct aq_nic_s *nic)
        ret = aq_apply_macsec_cfg(nic);
 
 unlock:
-       rtnl_unlock();
+       mutex_unlock(&nic->macsec_mutex);
        return ret;
 }
 
@@ -1519,9 +1551,9 @@ void aq_macsec_work(struct aq_nic_s *nic)
        if (!netif_carrier_ok(nic->ndev))
                return;
 
-       rtnl_lock();
+       mutex_lock(&nic->macsec_mutex);
        aq_check_txsa_expiration(nic);
-       rtnl_unlock();
+       mutex_unlock(&nic->macsec_mutex);
 }
 
 int aq_macsec_rx_sa_cnt(struct aq_nic_s *nic)
@@ -1532,21 +1564,30 @@ int aq_macsec_rx_sa_cnt(struct aq_nic_s *nic)
        if (!cfg)
                return 0;
 
+       mutex_lock(&nic->macsec_mutex);
+
        for (i = 0; i < AQ_MACSEC_MAX_SC; i++) {
                if (!test_bit(i, &cfg->rxsc_idx_busy))
                        continue;
                cnt += hweight_long(cfg->aq_rxsc[i].rx_sa_idx_busy);
        }
 
+       mutex_unlock(&nic->macsec_mutex);
        return cnt;
 }
 
 int aq_macsec_tx_sc_cnt(struct aq_nic_s *nic)
 {
+       int cnt;
+
        if (!nic->macsec_cfg)
                return 0;
 
-       return hweight_long(nic->macsec_cfg->txsc_idx_busy);
+       mutex_lock(&nic->macsec_mutex);
+       cnt = hweight_long(nic->macsec_cfg->txsc_idx_busy);
+       mutex_unlock(&nic->macsec_mutex);
+
+       return cnt;
 }
 
 int aq_macsec_tx_sa_cnt(struct aq_nic_s *nic)
@@ -1557,12 +1598,15 @@ int aq_macsec_tx_sa_cnt(struct aq_nic_s *nic)
        if (!cfg)
                return 0;
 
+       mutex_lock(&nic->macsec_mutex);
+
        for (i = 0; i < AQ_MACSEC_MAX_SC; i++) {
                if (!test_bit(i, &cfg->txsc_idx_busy))
                        continue;
                cnt += hweight_long(cfg->aq_txsc[i].tx_sa_idx_busy);
        }
 
+       mutex_unlock(&nic->macsec_mutex);
        return cnt;
 }
 
@@ -1634,6 +1678,8 @@ u64 *aq_macsec_get_stats(struct aq_nic_s *nic, u64 *data)
        if (!cfg)
                return data;
 
+       mutex_lock(&nic->macsec_mutex);
+
        aq_macsec_update_stats(nic);
 
        common_stats = &cfg->stats;
@@ -1716,5 +1762,7 @@ u64 *aq_macsec_get_stats(struct aq_nic_s *nic, u64 *data)
 
        data += i;
 
+       mutex_unlock(&nic->macsec_mutex);
+
        return data;
 }
index 935ba88..ad33f85 100644 (file)
@@ -157,6 +157,8 @@ struct aq_nic_s {
        struct mutex fwreq_mutex;
 #if IS_ENABLED(CONFIG_MACSEC)
        struct aq_macsec_cfg *macsec_cfg;
+       /* mutex to protect data in macsec_cfg */
+       struct mutex macsec_mutex;
 #endif
        /* PTP support */
        struct aq_ptp_s *aq_ptp;
index 93ccf54..a737b19 100644 (file)
@@ -561,8 +561,6 @@ static netdev_tx_t bcm4908_enet_start_xmit(struct sk_buff *skb, struct net_devic
 
        if (++ring->write_idx == ring->length - 1)
                ring->write_idx = 0;
-       enet->netdev->stats.tx_bytes += skb->len;
-       enet->netdev->stats.tx_packets++;
 
        return NETDEV_TX_OK;
 }
@@ -635,6 +633,7 @@ static int bcm4908_enet_poll_tx(struct napi_struct *napi, int weight)
        struct bcm4908_enet_dma_ring_bd *buf_desc;
        struct bcm4908_enet_dma_ring_slot *slot;
        struct device *dev = enet->dev;
+       unsigned int bytes = 0;
        int handled = 0;
 
        while (handled < weight && tx_ring->read_idx != tx_ring->write_idx) {
@@ -645,12 +644,17 @@ static int bcm4908_enet_poll_tx(struct napi_struct *napi, int weight)
 
                dma_unmap_single(dev, slot->dma_addr, slot->len, DMA_TO_DEVICE);
                dev_kfree_skb(slot->skb);
-               if (++tx_ring->read_idx == tx_ring->length)
-                       tx_ring->read_idx = 0;
 
                handled++;
+               bytes += slot->len;
+
+               if (++tx_ring->read_idx == tx_ring->length)
+                       tx_ring->read_idx = 0;
        }
 
+       enet->netdev->stats.tx_packets += handled;
+       enet->netdev->stats.tx_bytes += bytes;
+
        if (handled < weight) {
                napi_complete_done(napi, handled);
                bcm4908_enet_dma_ring_intrs_on(enet, tx_ring);
index 867f14c..425d6cc 100644 (file)
@@ -1991,6 +1991,9 @@ static int bcm_sysport_open(struct net_device *dev)
                goto out_clk_disable;
        }
 
+       /* Indicate that the MAC is responsible for PHY PM */
+       phydev->mac_managed_pm = true;
+
        /* Reset house keeping link status */
        priv->old_duplex = -1;
        priv->old_link = -1;
index 51c9fd6..4f63f1b 100644 (file)
@@ -806,6 +806,7 @@ static int macb_mii_probe(struct net_device *dev)
 
        bp->phylink_config.dev = &dev->dev;
        bp->phylink_config.type = PHYLINK_NETDEV;
+       bp->phylink_config.mac_managed_pm = true;
 
        if (bp->phy_interface == PHY_INTERFACE_MODE_SGMII) {
                bp->phylink_config.poll_fixed_state = true;
index 31cfa12..fc68a32 100644 (file)
@@ -221,8 +221,8 @@ static int dpaa_netdev_init(struct net_device *net_dev,
        net_dev->netdev_ops = dpaa_ops;
        mac_addr = mac_dev->addr;
 
-       net_dev->mem_start = (unsigned long)mac_dev->vaddr;
-       net_dev->mem_end = (unsigned long)mac_dev->vaddr_end;
+       net_dev->mem_start = (unsigned long)priv->mac_dev->res->start;
+       net_dev->mem_end = (unsigned long)priv->mac_dev->res->end;
 
        net_dev->min_mtu = ETH_MIN_MTU;
        net_dev->max_mtu = dpaa_get_max_mtu();
index 258eb6c..4fee74c 100644 (file)
@@ -18,7 +18,7 @@ static ssize_t dpaa_eth_show_addr(struct device *dev,
 
        if (mac_dev)
                return sprintf(buf, "%llx",
-                               (unsigned long long)mac_dev->vaddr);
+                               (unsigned long long)mac_dev->res->start);
        else
                return sprintf(buf, "none");
 }
index 54bc92f..f8c06c3 100644 (file)
@@ -2090,7 +2090,12 @@ static void enetc_setup_rxbdr(struct enetc_hw *hw, struct enetc_bdr *rx_ring)
        else
                enetc_rxbdr_wr(hw, idx, ENETC_RBBSR, ENETC_RXB_DMA_SIZE);
 
+       /* Also prepare the consumer index in case page allocation never
+        * succeeds. In that case, hardware will never advance producer index
+        * to match consumer index, and will drop all frames.
+        */
        enetc_rxbdr_wr(hw, idx, ENETC_RBPIR, 0);
+       enetc_rxbdr_wr(hw, idx, ENETC_RBCIR, 1);
 
        /* enable Rx ints by setting pkt thr to 1 */
        enetc_rxbdr_wr(hw, idx, ENETC_RBICR0, ENETC_RBICR0_ICEN | 0x1);
index 98d5cd3..28ef4d3 100644 (file)
@@ -2432,6 +2432,31 @@ static u32 fec_enet_register_offset[] = {
        IEEE_R_DROP, IEEE_R_FRAME_OK, IEEE_R_CRC, IEEE_R_ALIGN, IEEE_R_MACERR,
        IEEE_R_FDXFC, IEEE_R_OCTETS_OK
 };
+/* for i.MX6ul */
+static u32 fec_enet_register_offset_6ul[] = {
+       FEC_IEVENT, FEC_IMASK, FEC_R_DES_ACTIVE_0, FEC_X_DES_ACTIVE_0,
+       FEC_ECNTRL, FEC_MII_DATA, FEC_MII_SPEED, FEC_MIB_CTRLSTAT, FEC_R_CNTRL,
+       FEC_X_CNTRL, FEC_ADDR_LOW, FEC_ADDR_HIGH, FEC_OPD, FEC_TXIC0, FEC_RXIC0,
+       FEC_HASH_TABLE_HIGH, FEC_HASH_TABLE_LOW, FEC_GRP_HASH_TABLE_HIGH,
+       FEC_GRP_HASH_TABLE_LOW, FEC_X_WMRK, FEC_R_DES_START_0,
+       FEC_X_DES_START_0, FEC_R_BUFF_SIZE_0, FEC_R_FIFO_RSFL, FEC_R_FIFO_RSEM,
+       FEC_R_FIFO_RAEM, FEC_R_FIFO_RAFL, FEC_RACC,
+       RMON_T_DROP, RMON_T_PACKETS, RMON_T_BC_PKT, RMON_T_MC_PKT,
+       RMON_T_CRC_ALIGN, RMON_T_UNDERSIZE, RMON_T_OVERSIZE, RMON_T_FRAG,
+       RMON_T_JAB, RMON_T_COL, RMON_T_P64, RMON_T_P65TO127, RMON_T_P128TO255,
+       RMON_T_P256TO511, RMON_T_P512TO1023, RMON_T_P1024TO2047,
+       RMON_T_P_GTE2048, RMON_T_OCTETS,
+       IEEE_T_DROP, IEEE_T_FRAME_OK, IEEE_T_1COL, IEEE_T_MCOL, IEEE_T_DEF,
+       IEEE_T_LCOL, IEEE_T_EXCOL, IEEE_T_MACERR, IEEE_T_CSERR, IEEE_T_SQE,
+       IEEE_T_FDXFC, IEEE_T_OCTETS_OK,
+       RMON_R_PACKETS, RMON_R_BC_PKT, RMON_R_MC_PKT, RMON_R_CRC_ALIGN,
+       RMON_R_UNDERSIZE, RMON_R_OVERSIZE, RMON_R_FRAG, RMON_R_JAB,
+       RMON_R_RESVD_O, RMON_R_P64, RMON_R_P65TO127, RMON_R_P128TO255,
+       RMON_R_P256TO511, RMON_R_P512TO1023, RMON_R_P1024TO2047,
+       RMON_R_P_GTE2048, RMON_R_OCTETS,
+       IEEE_R_DROP, IEEE_R_FRAME_OK, IEEE_R_CRC, IEEE_R_ALIGN, IEEE_R_MACERR,
+       IEEE_R_FDXFC, IEEE_R_OCTETS_OK
+};
 #else
 static __u32 fec_enet_register_version = 1;
 static u32 fec_enet_register_offset[] = {
@@ -2456,7 +2481,24 @@ static void fec_enet_get_regs(struct net_device *ndev,
        u32 *buf = (u32 *)regbuf;
        u32 i, off;
        int ret;
+#if defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x) || \
+       defined(CONFIG_M520x) || defined(CONFIG_M532x) || defined(CONFIG_ARM) || \
+       defined(CONFIG_ARM64) || defined(CONFIG_COMPILE_TEST)
+       u32 *reg_list;
+       u32 reg_cnt;
 
+       if (!of_machine_is_compatible("fsl,imx6ul")) {
+               reg_list = fec_enet_register_offset;
+               reg_cnt = ARRAY_SIZE(fec_enet_register_offset);
+       } else {
+               reg_list = fec_enet_register_offset_6ul;
+               reg_cnt = ARRAY_SIZE(fec_enet_register_offset_6ul);
+       }
+#else
+       /* coldfire */
+       static u32 *reg_list = fec_enet_register_offset;
+       static const u32 reg_cnt = ARRAY_SIZE(fec_enet_register_offset);
+#endif
        ret = pm_runtime_resume_and_get(dev);
        if (ret < 0)
                return;
@@ -2465,8 +2507,8 @@ static void fec_enet_get_regs(struct net_device *ndev,
 
        memset(buf, 0, regs->len);
 
-       for (i = 0; i < ARRAY_SIZE(fec_enet_register_offset); i++) {
-               off = fec_enet_register_offset[i];
+       for (i = 0; i < reg_cnt; i++) {
+               off = reg_list[i];
 
                if ((off == FEC_R_BOUND || off == FEC_R_FSTART) &&
                    !(fep->quirks & FEC_QUIRK_HAS_FRREG))
index 7b7526f..65df308 100644 (file)
@@ -279,7 +279,6 @@ static int mac_probe(struct platform_device *_of_dev)
        struct device_node      *mac_node, *dev_node;
        struct mac_device       *mac_dev;
        struct platform_device  *of_dev;
-       struct resource         *res;
        struct mac_priv_s       *priv;
        struct fman_mac_params   params;
        u32                      val;
@@ -338,24 +337,25 @@ static int mac_probe(struct platform_device *_of_dev)
        of_node_put(dev_node);
 
        /* Get the address of the memory mapped registers */
-       res = platform_get_mem_or_io(_of_dev, 0);
-       if (!res) {
+       mac_dev->res = platform_get_mem_or_io(_of_dev, 0);
+       if (!mac_dev->res) {
                dev_err(dev, "could not get registers\n");
                return -EINVAL;
        }
 
-       err = devm_request_resource(dev, fman_get_mem_region(priv->fman), res);
+       err = devm_request_resource(dev, fman_get_mem_region(priv->fman),
+                                   mac_dev->res);
        if (err) {
                dev_err_probe(dev, err, "could not request resource\n");
                return err;
        }
 
-       mac_dev->vaddr = devm_ioremap(dev, res->start, resource_size(res));
+       mac_dev->vaddr = devm_ioremap(dev, mac_dev->res->start,
+                                     resource_size(mac_dev->res));
        if (!mac_dev->vaddr) {
                dev_err(dev, "devm_ioremap() failed\n");
                return -EIO;
        }
-       mac_dev->vaddr_end = mac_dev->vaddr + resource_size(res);
 
        if (!of_device_is_available(mac_node))
                return -ENODEV;
index b95d384..13b69ca 100644 (file)
@@ -20,8 +20,8 @@ struct mac_priv_s;
 
 struct mac_device {
        void __iomem            *vaddr;
-       void __iomem            *vaddr_end;
        struct device           *dev;
+       struct resource         *res;
        u8                       addr[ETH_ALEN];
        struct fman_port        *port[2];
        u32                      if_support;
index 19eb839..061952c 100644 (file)
@@ -85,6 +85,7 @@ static int hinic_dbg_get_func_table(struct hinic_dev *nic_dev, int idx)
        struct tag_sml_funcfg_tbl *funcfg_table_elem;
        struct hinic_cmd_lt_rd *read_data;
        u16 out_size = sizeof(*read_data);
+       int ret = ~0;
        int err;
 
        read_data = kzalloc(sizeof(*read_data), GFP_KERNEL);
@@ -111,20 +112,25 @@ static int hinic_dbg_get_func_table(struct hinic_dev *nic_dev, int idx)
 
        switch (idx) {
        case VALID:
-               return funcfg_table_elem->dw0.bs.valid;
+               ret = funcfg_table_elem->dw0.bs.valid;
+               break;
        case RX_MODE:
-               return funcfg_table_elem->dw0.bs.nic_rx_mode;
+               ret = funcfg_table_elem->dw0.bs.nic_rx_mode;
+               break;
        case MTU:
-               return funcfg_table_elem->dw1.bs.mtu;
+               ret = funcfg_table_elem->dw1.bs.mtu;
+               break;
        case RQ_DEPTH:
-               return funcfg_table_elem->dw13.bs.cfg_rq_depth;
+               ret = funcfg_table_elem->dw13.bs.cfg_rq_depth;
+               break;
        case QUEUE_NUM:
-               return funcfg_table_elem->dw13.bs.cfg_q_num;
+               ret = funcfg_table_elem->dw13.bs.cfg_q_num;
+               break;
        }
 
        kfree(read_data);
 
-       return ~0;
+       return ret;
 }
 
 static ssize_t hinic_dbg_cmd_read(struct file *filp, char __user *buffer, size_t count,
index 78190e8..d39eec9 100644 (file)
@@ -924,7 +924,7 @@ int hinic_init_cmdqs(struct hinic_cmdqs *cmdqs, struct hinic_hwif *hwif,
 
 err_set_cmdq_depth:
        hinic_ceq_unregister_cb(&func_to_io->ceqs, HINIC_CEQ_CMDQ);
-
+       free_cmdq(&cmdqs->cmdq[HINIC_CMDQ_SYNC]);
 err_cmdq_ctxt:
        hinic_wqs_cmdq_free(&cmdqs->cmdq_pages, cmdqs->saved_wqs,
                            HINIC_MAX_CMDQ_TYPES);
index 94f4705..2779528 100644 (file)
@@ -877,7 +877,7 @@ int hinic_set_interrupt_cfg(struct hinic_hwdev *hwdev,
        if (err)
                return -EINVAL;
 
-       interrupt_info->lli_credit_cnt = temp_info.lli_timer_cnt;
+       interrupt_info->lli_credit_cnt = temp_info.lli_credit_cnt;
        interrupt_info->lli_timer_cnt = temp_info.lli_timer_cnt;
 
        err = hinic_msg_to_mgmt(&pfhwdev->pf_to_mgmt, HINIC_MOD_COMM,
index a5f08b9..f7e05b4 100644 (file)
@@ -1174,7 +1174,6 @@ int hinic_vf_func_init(struct hinic_hwdev *hwdev)
                        dev_err(&hwdev->hwif->pdev->dev,
                                "Failed to register VF, err: %d, status: 0x%x, out size: 0x%x\n",
                                err, register_info.status, out_size);
-                       hinic_unregister_vf_mbox_cb(hwdev, HINIC_MOD_L2NIC);
                        return -EIO;
                }
        } else {
index 294bdbb..b4aff59 100644 (file)
@@ -2900,6 +2900,7 @@ static struct device *ehea_register_port(struct ehea_port *port,
        ret = of_device_register(&port->ofdev);
        if (ret) {
                pr_err("failed to register device. ret=%d\n", ret);
+               put_device(&port->ofdev.dev);
                goto out;
        }
 
index 87f36d1..4a6a6e4 100644 (file)
@@ -3185,10 +3185,17 @@ static int i40e_get_rss_hash_opts(struct i40e_pf *pf, struct ethtool_rxnfc *cmd)
 
                if (cmd->flow_type == TCP_V4_FLOW ||
                    cmd->flow_type == UDP_V4_FLOW) {
-                       if (i_set & I40E_L3_SRC_MASK)
-                               cmd->data |= RXH_IP_SRC;
-                       if (i_set & I40E_L3_DST_MASK)
-                               cmd->data |= RXH_IP_DST;
+                       if (hw->mac.type == I40E_MAC_X722) {
+                               if (i_set & I40E_X722_L3_SRC_MASK)
+                                       cmd->data |= RXH_IP_SRC;
+                               if (i_set & I40E_X722_L3_DST_MASK)
+                                       cmd->data |= RXH_IP_DST;
+                       } else {
+                               if (i_set & I40E_L3_SRC_MASK)
+                                       cmd->data |= RXH_IP_SRC;
+                               if (i_set & I40E_L3_DST_MASK)
+                                       cmd->data |= RXH_IP_DST;
+                       }
                } else if (cmd->flow_type == TCP_V6_FLOW ||
                          cmd->flow_type == UDP_V6_FLOW) {
                        if (i_set & I40E_L3_V6_SRC_MASK)
@@ -3546,12 +3553,15 @@ static int i40e_get_rxnfc(struct net_device *netdev, struct ethtool_rxnfc *cmd,
 
 /**
  * i40e_get_rss_hash_bits - Read RSS Hash bits from register
+ * @hw: hw structure
  * @nfc: pointer to user request
  * @i_setc: bits currently set
  *
  * Returns value of bits to be set per user request
  **/
-static u64 i40e_get_rss_hash_bits(struct ethtool_rxnfc *nfc, u64 i_setc)
+static u64 i40e_get_rss_hash_bits(struct i40e_hw *hw,
+                                 struct ethtool_rxnfc *nfc,
+                                 u64 i_setc)
 {
        u64 i_set = i_setc;
        u64 src_l3 = 0, dst_l3 = 0;
@@ -3570,8 +3580,13 @@ static u64 i40e_get_rss_hash_bits(struct ethtool_rxnfc *nfc, u64 i_setc)
                dst_l3 = I40E_L3_V6_DST_MASK;
        } else if (nfc->flow_type == TCP_V4_FLOW ||
                  nfc->flow_type == UDP_V4_FLOW) {
-               src_l3 = I40E_L3_SRC_MASK;
-               dst_l3 = I40E_L3_DST_MASK;
+               if (hw->mac.type == I40E_MAC_X722) {
+                       src_l3 = I40E_X722_L3_SRC_MASK;
+                       dst_l3 = I40E_X722_L3_DST_MASK;
+               } else {
+                       src_l3 = I40E_L3_SRC_MASK;
+                       dst_l3 = I40E_L3_DST_MASK;
+               }
        } else {
                /* Any other flow type are not supported here */
                return i_set;
@@ -3589,6 +3604,7 @@ static u64 i40e_get_rss_hash_bits(struct ethtool_rxnfc *nfc, u64 i_setc)
        return i_set;
 }
 
+#define FLOW_PCTYPES_SIZE 64
 /**
  * i40e_set_rss_hash_opt - Enable/Disable flow types for RSS hash
  * @pf: pointer to the physical function struct
@@ -3601,9 +3617,11 @@ static int i40e_set_rss_hash_opt(struct i40e_pf *pf, struct ethtool_rxnfc *nfc)
        struct i40e_hw *hw = &pf->hw;
        u64 hena = (u64)i40e_read_rx_ctl(hw, I40E_PFQF_HENA(0)) |
                   ((u64)i40e_read_rx_ctl(hw, I40E_PFQF_HENA(1)) << 32);
-       u8 flow_pctype = 0;
+       DECLARE_BITMAP(flow_pctypes, FLOW_PCTYPES_SIZE);
        u64 i_set, i_setc;
 
+       bitmap_zero(flow_pctypes, FLOW_PCTYPES_SIZE);
+
        if (pf->flags & I40E_FLAG_MFP_ENABLED) {
                dev_err(&pf->pdev->dev,
                        "Change of RSS hash input set is not supported when MFP mode is enabled\n");
@@ -3619,36 +3637,35 @@ static int i40e_set_rss_hash_opt(struct i40e_pf *pf, struct ethtool_rxnfc *nfc)
 
        switch (nfc->flow_type) {
        case TCP_V4_FLOW:
-               flow_pctype = I40E_FILTER_PCTYPE_NONF_IPV4_TCP;
+               set_bit(I40E_FILTER_PCTYPE_NONF_IPV4_TCP, flow_pctypes);
                if (pf->hw_features & I40E_HW_MULTIPLE_TCP_UDP_RSS_PCTYPE)
-                       hena |=
-                         BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV4_TCP_SYN_NO_ACK);
+                       set_bit(I40E_FILTER_PCTYPE_NONF_IPV4_TCP_SYN_NO_ACK,
+                               flow_pctypes);
                break;
        case TCP_V6_FLOW:
-               flow_pctype = I40E_FILTER_PCTYPE_NONF_IPV6_TCP;
-               if (pf->hw_features & I40E_HW_MULTIPLE_TCP_UDP_RSS_PCTYPE)
-                       hena |=
-                         BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV4_TCP_SYN_NO_ACK);
+               set_bit(I40E_FILTER_PCTYPE_NONF_IPV6_TCP, flow_pctypes);
                if (pf->hw_features & I40E_HW_MULTIPLE_TCP_UDP_RSS_PCTYPE)
-                       hena |=
-                         BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV6_TCP_SYN_NO_ACK);
+                       set_bit(I40E_FILTER_PCTYPE_NONF_IPV6_TCP_SYN_NO_ACK,
+                               flow_pctypes);
                break;
        case UDP_V4_FLOW:
-               flow_pctype = I40E_FILTER_PCTYPE_NONF_IPV4_UDP;
-               if (pf->hw_features & I40E_HW_MULTIPLE_TCP_UDP_RSS_PCTYPE)
-                       hena |=
-                         BIT_ULL(I40E_FILTER_PCTYPE_NONF_UNICAST_IPV4_UDP) |
-                         BIT_ULL(I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV4_UDP);
-
+               set_bit(I40E_FILTER_PCTYPE_NONF_IPV4_UDP, flow_pctypes);
+               if (pf->hw_features & I40E_HW_MULTIPLE_TCP_UDP_RSS_PCTYPE) {
+                       set_bit(I40E_FILTER_PCTYPE_NONF_UNICAST_IPV4_UDP,
+                               flow_pctypes);
+                       set_bit(I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV4_UDP,
+                               flow_pctypes);
+               }
                hena |= BIT_ULL(I40E_FILTER_PCTYPE_FRAG_IPV4);
                break;
        case UDP_V6_FLOW:
-               flow_pctype = I40E_FILTER_PCTYPE_NONF_IPV6_UDP;
-               if (pf->hw_features & I40E_HW_MULTIPLE_TCP_UDP_RSS_PCTYPE)
-                       hena |=
-                         BIT_ULL(I40E_FILTER_PCTYPE_NONF_UNICAST_IPV6_UDP) |
-                         BIT_ULL(I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV6_UDP);
-
+               set_bit(I40E_FILTER_PCTYPE_NONF_IPV6_UDP, flow_pctypes);
+               if (pf->hw_features & I40E_HW_MULTIPLE_TCP_UDP_RSS_PCTYPE) {
+                       set_bit(I40E_FILTER_PCTYPE_NONF_UNICAST_IPV6_UDP,
+                               flow_pctypes);
+                       set_bit(I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV6_UDP,
+                               flow_pctypes);
+               }
                hena |= BIT_ULL(I40E_FILTER_PCTYPE_FRAG_IPV6);
                break;
        case AH_ESP_V4_FLOW:
@@ -3681,17 +3698,20 @@ static int i40e_set_rss_hash_opt(struct i40e_pf *pf, struct ethtool_rxnfc *nfc)
                return -EINVAL;
        }
 
-       if (flow_pctype) {
-               i_setc = (u64)i40e_read_rx_ctl(hw, I40E_GLQF_HASH_INSET(0,
-                                              flow_pctype)) |
-                       ((u64)i40e_read_rx_ctl(hw, I40E_GLQF_HASH_INSET(1,
-                                              flow_pctype)) << 32);
-               i_set = i40e_get_rss_hash_bits(nfc, i_setc);
-               i40e_write_rx_ctl(hw, I40E_GLQF_HASH_INSET(0, flow_pctype),
-                                 (u32)i_set);
-               i40e_write_rx_ctl(hw, I40E_GLQF_HASH_INSET(1, flow_pctype),
-                                 (u32)(i_set >> 32));
-               hena |= BIT_ULL(flow_pctype);
+       if (bitmap_weight(flow_pctypes, FLOW_PCTYPES_SIZE)) {
+               u8 flow_id;
+
+               for_each_set_bit(flow_id, flow_pctypes, FLOW_PCTYPES_SIZE) {
+                       i_setc = (u64)i40e_read_rx_ctl(hw, I40E_GLQF_HASH_INSET(0, flow_id)) |
+                                ((u64)i40e_read_rx_ctl(hw, I40E_GLQF_HASH_INSET(1, flow_id)) << 32);
+                       i_set = i40e_get_rss_hash_bits(&pf->hw, nfc, i_setc);
+
+                       i40e_write_rx_ctl(hw, I40E_GLQF_HASH_INSET(0, flow_id),
+                                         (u32)i_set);
+                       i40e_write_rx_ctl(hw, I40E_GLQF_HASH_INSET(1, flow_id),
+                                         (u32)(i_set >> 32));
+                       hena |= BIT_ULL(flow_id);
+               }
        }
 
        i40e_write_rx_ctl(hw, I40E_PFQF_HENA(0), (u32)hena);
index 7b3f30b..388c3d3 100644 (file)
@@ -1404,6 +1404,10 @@ struct i40e_lldp_variables {
 #define I40E_PFQF_CTL_0_HASHLUTSIZE_512        0x00010000
 
 /* INPUT SET MASK for RSS, flow director, and flexible payload */
+#define I40E_X722_L3_SRC_SHIFT         49
+#define I40E_X722_L3_SRC_MASK          (0x3ULL << I40E_X722_L3_SRC_SHIFT)
+#define I40E_X722_L3_DST_SHIFT         41
+#define I40E_X722_L3_DST_MASK          (0x3ULL << I40E_X722_L3_DST_SHIFT)
 #define I40E_L3_SRC_SHIFT              47
 #define I40E_L3_SRC_MASK               (0x3ULL << I40E_L3_SRC_SHIFT)
 #define I40E_L3_V6_SRC_SHIFT           43
index 7e9f6a6..72ddcef 100644 (file)
@@ -1536,10 +1536,12 @@ bool i40e_reset_vf(struct i40e_vf *vf, bool flr)
        if (test_bit(__I40E_VF_RESETS_DISABLED, pf->state))
                return true;
 
-       /* If the VFs have been disabled, this means something else is
-        * resetting the VF, so we shouldn't continue.
-        */
-       if (test_and_set_bit(__I40E_VF_DISABLE, pf->state))
+       /* Bail out if VFs are disabled. */
+       if (test_bit(__I40E_VF_DISABLE, pf->state))
+               return true;
+
+       /* If VF is being reset already we don't need to continue. */
+       if (test_and_set_bit(I40E_VF_STATE_RESETTING, &vf->vf_states))
                return true;
 
        i40e_trigger_vf_reset(vf, flr);
@@ -1576,7 +1578,7 @@ bool i40e_reset_vf(struct i40e_vf *vf, bool flr)
        i40e_cleanup_reset_vf(vf);
 
        i40e_flush(hw);
-       clear_bit(__I40E_VF_DISABLE, pf->state);
+       clear_bit(I40E_VF_STATE_RESETTING, &vf->vf_states);
 
        return true;
 }
@@ -1609,8 +1611,12 @@ bool i40e_reset_all_vfs(struct i40e_pf *pf, bool flr)
                return false;
 
        /* Begin reset on all VFs at once */
-       for (v = 0; v < pf->num_alloc_vfs; v++)
-               i40e_trigger_vf_reset(&pf->vf[v], flr);
+       for (v = 0; v < pf->num_alloc_vfs; v++) {
+               vf = &pf->vf[v];
+               /* If VF is being reset no need to trigger reset again */
+               if (!test_bit(I40E_VF_STATE_RESETTING, &vf->vf_states))
+                       i40e_trigger_vf_reset(&pf->vf[v], flr);
+       }
 
        /* HW requires some time to make sure it can flush the FIFO for a VF
         * when it resets it. Poll the VPGEN_VFRSTAT register for each VF in
@@ -1626,9 +1632,11 @@ bool i40e_reset_all_vfs(struct i40e_pf *pf, bool flr)
                 */
                while (v < pf->num_alloc_vfs) {
                        vf = &pf->vf[v];
-                       reg = rd32(hw, I40E_VPGEN_VFRSTAT(vf->vf_id));
-                       if (!(reg & I40E_VPGEN_VFRSTAT_VFRD_MASK))
-                               break;
+                       if (!test_bit(I40E_VF_STATE_RESETTING, &vf->vf_states)) {
+                               reg = rd32(hw, I40E_VPGEN_VFRSTAT(vf->vf_id));
+                               if (!(reg & I40E_VPGEN_VFRSTAT_VFRD_MASK))
+                                       break;
+                       }
 
                        /* If the current VF has finished resetting, move on
                         * to the next VF in sequence.
@@ -1656,6 +1664,10 @@ bool i40e_reset_all_vfs(struct i40e_pf *pf, bool flr)
                if (pf->vf[v].lan_vsi_idx == 0)
                        continue;
 
+               /* If VF is reset in another thread just continue */
+               if (test_bit(I40E_VF_STATE_RESETTING, &vf->vf_states))
+                       continue;
+
                i40e_vsi_stop_rings_no_wait(pf->vsi[pf->vf[v].lan_vsi_idx]);
        }
 
@@ -1667,6 +1679,10 @@ bool i40e_reset_all_vfs(struct i40e_pf *pf, bool flr)
                if (pf->vf[v].lan_vsi_idx == 0)
                        continue;
 
+               /* If VF is reset in another thread just continue */
+               if (test_bit(I40E_VF_STATE_RESETTING, &vf->vf_states))
+                       continue;
+
                i40e_vsi_wait_queues_disabled(pf->vsi[pf->vf[v].lan_vsi_idx]);
        }
 
@@ -1676,8 +1692,13 @@ bool i40e_reset_all_vfs(struct i40e_pf *pf, bool flr)
        mdelay(50);
 
        /* Finish the reset on each VF */
-       for (v = 0; v < pf->num_alloc_vfs; v++)
+       for (v = 0; v < pf->num_alloc_vfs; v++) {
+               /* If VF is reset in another thread just continue */
+               if (test_bit(I40E_VF_STATE_RESETTING, &vf->vf_states))
+                       continue;
+
                i40e_cleanup_reset_vf(&pf->vf[v]);
+       }
 
        i40e_flush(hw);
        clear_bit(__I40E_VF_DISABLE, pf->state);
index a554d0a..358bbdb 100644 (file)
@@ -39,6 +39,7 @@ enum i40e_vf_states {
        I40E_VF_STATE_MC_PROMISC,
        I40E_VF_STATE_UC_PROMISC,
        I40E_VF_STATE_PRE_ENABLE,
+       I40E_VF_STATE_RESETTING
 };
 
 /* VF capabilities */
index 59aab40..f5961bd 100644 (file)
@@ -485,7 +485,6 @@ ltq_etop_tx(struct sk_buff *skb, struct net_device *dev)
        len = skb->len < ETH_ZLEN ? ETH_ZLEN : skb->len;
 
        if ((desc->ctl & (LTQ_DMA_OWN | LTQ_DMA_C)) || ch->skb[ch->dma.desc]) {
-               dev_kfree_skb_any(skb);
                netdev_err(dev, "tx ring full\n");
                netif_tx_stop_queue(txq);
                return NETDEV_TX_BUSY;
index 0377392..46ba4c2 100644 (file)
@@ -2004,7 +2004,7 @@ void mlx5_cmd_init_async_ctx(struct mlx5_core_dev *dev,
        ctx->dev = dev;
        /* Starts at 1 to avoid doing wake_up if we are not cleaning up */
        atomic_set(&ctx->num_inflight, 1);
-       init_waitqueue_head(&ctx->wait);
+       init_completion(&ctx->inflight_done);
 }
 EXPORT_SYMBOL(mlx5_cmd_init_async_ctx);
 
@@ -2018,8 +2018,8 @@ EXPORT_SYMBOL(mlx5_cmd_init_async_ctx);
  */
 void mlx5_cmd_cleanup_async_ctx(struct mlx5_async_ctx *ctx)
 {
-       atomic_dec(&ctx->num_inflight);
-       wait_event(ctx->wait, atomic_read(&ctx->num_inflight) == 0);
+       if (!atomic_dec_and_test(&ctx->num_inflight))
+               wait_for_completion(&ctx->inflight_done);
 }
 EXPORT_SYMBOL(mlx5_cmd_cleanup_async_ctx);
 
@@ -2032,7 +2032,7 @@ static void mlx5_cmd_exec_cb_handler(int status, void *_work)
        status = cmd_status_err(ctx->dev, status, work->opcode, work->out);
        work->user_callback(status, work);
        if (atomic_dec_and_test(&ctx->num_inflight))
-               wake_up(&ctx->wait);
+               complete(&ctx->inflight_done);
 }
 
 int mlx5_cmd_exec_cb(struct mlx5_async_ctx *ctx, void *in, int in_size,
@@ -2050,7 +2050,7 @@ int mlx5_cmd_exec_cb(struct mlx5_async_ctx *ctx, void *in, int in_size,
        ret = cmd_exec(ctx->dev, in, in_size, out, out_size,
                       mlx5_cmd_exec_cb_handler, work, false);
        if (ret && atomic_dec_and_test(&ctx->num_inflight))
-               wake_up(&ctx->wait);
+               complete(&ctx->inflight_done);
 
        return ret;
 }
index 5bce554..cc7efde 100644 (file)
@@ -6,6 +6,7 @@
 
 #include "en.h"
 #include "en_stats.h"
+#include "en/txrx.h"
 #include <linux/ptp_classify.h>
 
 #define MLX5E_PTP_CHANNEL_IX 0
@@ -68,6 +69,14 @@ static inline bool mlx5e_use_ptpsq(struct sk_buff *skb)
                fk.ports.dst == htons(PTP_EV_PORT));
 }
 
+static inline bool mlx5e_ptpsq_fifo_has_room(struct mlx5e_txqsq *sq)
+{
+       if (!sq->ptpsq)
+               return true;
+
+       return mlx5e_skb_fifo_has_room(&sq->ptpsq->skb_fifo);
+}
+
 int mlx5e_ptp_open(struct mlx5e_priv *priv, struct mlx5e_params *params,
                   u8 lag_port, struct mlx5e_ptp **cp);
 void mlx5e_ptp_close(struct mlx5e_ptp *c);
index 10c9a8a..2e42d7c 100644 (file)
@@ -96,6 +96,7 @@ struct mlx5e_tc_flow {
        struct encap_flow_item encaps[MLX5_MAX_FLOW_FWD_VPORTS];
        struct mlx5e_tc_flow *peer_flow;
        struct mlx5e_mod_hdr_handle *mh; /* attached mod header instance */
+       struct mlx5e_mod_hdr_handle *slow_mh; /* attached mod header instance for slow path */
        struct mlx5e_hairpin_entry *hpe; /* attached hairpin instance */
        struct list_head hairpin; /* flows sharing the same hairpin */
        struct list_head peer;    /* flows with peer flow */
@@ -111,6 +112,7 @@ struct mlx5e_tc_flow {
        struct completion del_hw_done;
        struct mlx5_flow_attr *attr;
        struct list_head attrs;
+       u32 chain_mapping;
 };
 
 struct mlx5_flow_handle *
index 4456ad5..cb164b6 100644 (file)
@@ -58,6 +58,12 @@ bool mlx5e_poll_tx_cq(struct mlx5e_cq *cq, int napi_budget);
 void mlx5e_free_txqsq_descs(struct mlx5e_txqsq *sq);
 
 static inline bool
+mlx5e_skb_fifo_has_room(struct mlx5e_skb_fifo *fifo)
+{
+       return (*fifo->pc - *fifo->cc) < fifo->mask;
+}
+
+static inline bool
 mlx5e_wqc_has_room_for(struct mlx5_wq_cyc *wq, u16 cc, u16 pc, u16 n)
 {
        return (mlx5_wq_cyc_ctr2ix(wq, cc - pc) >= n) || (cc == pc);
index 2a8fd70..a715601 100644 (file)
@@ -101,7 +101,6 @@ static bool mlx5e_ipsec_update_esn_state(struct mlx5e_ipsec_sa_entry *sa_entry)
        struct xfrm_replay_state_esn *replay_esn;
        u32 seq_bottom = 0;
        u8 overlap;
-       u32 *esn;
 
        if (!(sa_entry->x->props.flags & XFRM_STATE_ESN)) {
                sa_entry->esn_state.trigger = 0;
@@ -116,11 +115,9 @@ static bool mlx5e_ipsec_update_esn_state(struct mlx5e_ipsec_sa_entry *sa_entry)
 
        sa_entry->esn_state.esn = xfrm_replay_seqhi(sa_entry->x,
                                                    htonl(seq_bottom));
-       esn = &sa_entry->esn_state.esn;
 
        sa_entry->esn_state.trigger = 1;
        if (unlikely(overlap && seq_bottom < MLX5E_IPSEC_ESN_SCOPE_MID)) {
-               ++(*esn);
                sa_entry->esn_state.overlap = 0;
                return true;
        } else if (unlikely(!overlap &&
index 4197006..2ef36cb 100644 (file)
@@ -432,7 +432,7 @@ static int mlx5e_macsec_update_rx_sa(struct mlx5e_macsec *macsec,
                                     bool active)
 {
        struct mlx5_core_dev *mdev = macsec->mdev;
-       struct mlx5_macsec_obj_attrs attrs;
+       struct mlx5_macsec_obj_attrs attrs = {};
        int err = 0;
 
        if (rx_sa->active != active)
@@ -444,7 +444,7 @@ static int mlx5e_macsec_update_rx_sa(struct mlx5e_macsec *macsec,
                return 0;
        }
 
-       attrs.sci = rx_sa->sci;
+       attrs.sci = cpu_to_be64((__force u64)rx_sa->sci);
        attrs.enc_key_id = rx_sa->enc_key_id;
        err = mlx5e_macsec_create_object(mdev, &attrs, false, &rx_sa->macsec_obj_id);
        if (err)
@@ -999,11 +999,11 @@ static int mlx5e_macsec_upd_rxsa(struct macsec_context *ctx)
        }
 
        rx_sa = rx_sc->rx_sa[assoc_num];
-       if (rx_sa) {
+       if (!rx_sa) {
                netdev_err(ctx->netdev,
-                          "MACsec offload rx_sc sci %lld rx_sa %d already exist\n",
+                          "MACsec offload rx_sc sci %lld rx_sa %d doesn't exist\n",
                           sci, assoc_num);
-               err = -EEXIST;
+               err = -EINVAL;
                goto out;
        }
 
@@ -1055,11 +1055,11 @@ static int mlx5e_macsec_del_rxsa(struct macsec_context *ctx)
        }
 
        rx_sa = rx_sc->rx_sa[assoc_num];
-       if (rx_sa) {
+       if (!rx_sa) {
                netdev_err(ctx->netdev,
-                          "MACsec offload rx_sc sci %lld rx_sa %d already exist\n",
+                          "MACsec offload rx_sc sci %lld rx_sa %d doesn't exist\n",
                           sci, assoc_num);
-               err = -EEXIST;
+               err = -EINVAL;
                goto out;
        }
 
@@ -1846,25 +1846,16 @@ err_hash:
 void mlx5e_macsec_cleanup(struct mlx5e_priv *priv)
 {
        struct mlx5e_macsec *macsec = priv->macsec;
-       struct mlx5_core_dev *mdev = macsec->mdev;
+       struct mlx5_core_dev *mdev = priv->mdev;
 
        if (!macsec)
                return;
 
        mlx5_notifier_unregister(mdev, &macsec->nb);
-
        mlx5e_macsec_fs_cleanup(macsec->macsec_fs);
-
-       /* Cleanup workqueue */
        destroy_workqueue(macsec->wq);
-
        mlx5e_macsec_aso_cleanup(&macsec->aso, mdev);
-
-       priv->macsec = NULL;
-
        rhashtable_destroy(&macsec->sci_hash);
-
        mutex_destroy(&macsec->lock);
-
        kfree(macsec);
 }
index 13dc628..1ac0cf0 100644 (file)
@@ -1180,7 +1180,7 @@ macsec_fs_rx_add_rule(struct mlx5e_macsec_fs *macsec_fs,
        rx_rule->rule[0] = rule;
 
        /* Rx crypto table without SCI rule */
-       if (cpu_to_be64((__force u64)attrs->sci) & ntohs(MACSEC_PORT_ES)) {
+       if ((cpu_to_be64((__force u64)attrs->sci) & 0xFFFF) == ntohs(MACSEC_PORT_ES)) {
                memset(spec, 0, sizeof(struct mlx5_flow_spec));
                memset(&dest, 0, sizeof(struct mlx5_flow_destination));
                memset(&flow_act, 0, sizeof(flow_act));
index 70a7a61..dd6fea9 100644 (file)
@@ -1405,8 +1405,13 @@ mlx5e_tc_offload_to_slow_path(struct mlx5_eswitch *esw,
                              struct mlx5e_tc_flow *flow,
                              struct mlx5_flow_spec *spec)
 {
+       struct mlx5e_tc_mod_hdr_acts mod_acts = {};
+       struct mlx5e_mod_hdr_handle *mh = NULL;
        struct mlx5_flow_attr *slow_attr;
        struct mlx5_flow_handle *rule;
+       bool fwd_and_modify_cap;
+       u32 chain_mapping = 0;
+       int err;
 
        slow_attr = mlx5_alloc_flow_attr(MLX5_FLOW_NAMESPACE_FDB);
        if (!slow_attr)
@@ -1417,13 +1422,56 @@ mlx5e_tc_offload_to_slow_path(struct mlx5_eswitch *esw,
        slow_attr->esw_attr->split_count = 0;
        slow_attr->flags |= MLX5_ATTR_FLAG_SLOW_PATH;
 
+       fwd_and_modify_cap = MLX5_CAP_ESW_FLOWTABLE((esw)->dev, fdb_modify_header_fwd_to_table);
+       if (!fwd_and_modify_cap)
+               goto skip_restore;
+
+       err = mlx5_chains_get_chain_mapping(esw_chains(esw), flow->attr->chain, &chain_mapping);
+       if (err)
+               goto err_get_chain;
+
+       err = mlx5e_tc_match_to_reg_set(esw->dev, &mod_acts, MLX5_FLOW_NAMESPACE_FDB,
+                                       CHAIN_TO_REG, chain_mapping);
+       if (err)
+               goto err_reg_set;
+
+       mh = mlx5e_mod_hdr_attach(esw->dev, get_mod_hdr_table(flow->priv, flow),
+                                 MLX5_FLOW_NAMESPACE_FDB, &mod_acts);
+       if (IS_ERR(mh)) {
+               err = PTR_ERR(mh);
+               goto err_attach;
+       }
+
+       slow_attr->action |= MLX5_FLOW_CONTEXT_ACTION_MOD_HDR;
+       slow_attr->modify_hdr = mlx5e_mod_hdr_get(mh);
+
+skip_restore:
        rule = mlx5e_tc_offload_fdb_rules(esw, flow, spec, slow_attr);
-       if (!IS_ERR(rule))
-               flow_flag_set(flow, SLOW);
+       if (IS_ERR(rule)) {
+               err = PTR_ERR(rule);
+               goto err_offload;
+       }
 
+       flow->slow_mh = mh;
+       flow->chain_mapping = chain_mapping;
+       flow_flag_set(flow, SLOW);
+
+       mlx5e_mod_hdr_dealloc(&mod_acts);
        kfree(slow_attr);
 
        return rule;
+
+err_offload:
+       if (fwd_and_modify_cap)
+               mlx5e_mod_hdr_detach(esw->dev, get_mod_hdr_table(flow->priv, flow), mh);
+err_attach:
+err_reg_set:
+       if (fwd_and_modify_cap)
+               mlx5_chains_put_chain_mapping(esw_chains(esw), chain_mapping);
+err_get_chain:
+       mlx5e_mod_hdr_dealloc(&mod_acts);
+       kfree(slow_attr);
+       return ERR_PTR(err);
 }
 
 void mlx5e_tc_unoffload_from_slow_path(struct mlx5_eswitch *esw,
@@ -1441,7 +1489,17 @@ void mlx5e_tc_unoffload_from_slow_path(struct mlx5_eswitch *esw,
        slow_attr->action = MLX5_FLOW_CONTEXT_ACTION_FWD_DEST;
        slow_attr->esw_attr->split_count = 0;
        slow_attr->flags |= MLX5_ATTR_FLAG_SLOW_PATH;
+       if (flow->slow_mh) {
+               slow_attr->action |= MLX5_FLOW_CONTEXT_ACTION_MOD_HDR;
+               slow_attr->modify_hdr = mlx5e_mod_hdr_get(flow->slow_mh);
+       }
        mlx5e_tc_unoffload_fdb_rules(esw, flow, slow_attr);
+       if (flow->slow_mh) {
+               mlx5e_mod_hdr_detach(esw->dev, get_mod_hdr_table(flow->priv, flow), flow->slow_mh);
+               mlx5_chains_put_chain_mapping(esw_chains(esw), flow->chain_mapping);
+               flow->chain_mapping = 0;
+               flow->slow_mh = NULL;
+       }
        flow_flag_clear(flow, SLOW);
        kfree(slow_attr);
 }
@@ -3575,6 +3633,10 @@ mlx5e_clone_flow_attr_for_post_act(struct mlx5_flow_attr *attr,
        attr2->action = 0;
        attr2->flags = 0;
        attr2->parse_attr = parse_attr;
+       attr2->esw_attr->out_count = 0;
+       attr2->esw_attr->split_count = 0;
+       attr2->dest_chain = 0;
+       attr2->dest_ft = NULL;
        return attr2;
 }
 
@@ -4008,6 +4070,7 @@ parse_tc_fdb_actions(struct mlx5e_priv *priv,
        struct mlx5e_tc_flow_parse_attr *parse_attr;
        struct mlx5_flow_attr *attr = flow->attr;
        struct mlx5_esw_flow_attr *esw_attr;
+       struct net_device *filter_dev;
        int err;
 
        err = flow_action_supported(flow_action, extack);
@@ -4016,6 +4079,7 @@ parse_tc_fdb_actions(struct mlx5e_priv *priv,
 
        esw_attr = attr->esw_attr;
        parse_attr = attr->parse_attr;
+       filter_dev = parse_attr->filter_dev;
        parse_state = &parse_attr->parse_state;
        mlx5e_tc_act_init_parse_state(parse_state, flow, flow_action, extack);
        parse_state->ct_priv = get_ct_priv(priv);
@@ -4025,13 +4089,21 @@ parse_tc_fdb_actions(struct mlx5e_priv *priv,
                return err;
 
        /* Forward to/from internal port can only have 1 dest */
-       if ((netif_is_ovs_master(parse_attr->filter_dev) || esw_attr->dest_int_port) &&
+       if ((netif_is_ovs_master(filter_dev) || esw_attr->dest_int_port) &&
            esw_attr->out_count > 1) {
                NL_SET_ERR_MSG_MOD(extack,
                                   "Rules with internal port can have only one destination");
                return -EOPNOTSUPP;
        }
 
+       /* Forward from tunnel/internal port to internal port is not supported */
+       if ((mlx5e_get_tc_tun(filter_dev) || netif_is_ovs_master(filter_dev)) &&
+           esw_attr->dest_int_port) {
+               NL_SET_ERR_MSG_MOD(extack,
+                                  "Forwarding from tunnel/internal port to internal port is not supported");
+               return -EOPNOTSUPP;
+       }
+
        err = actions_prepare_mod_hdr_actions(priv, flow, attr, extack);
        if (err)
                return err;
index bf2232a..6adca01 100644 (file)
@@ -392,6 +392,11 @@ mlx5e_txwqe_complete(struct mlx5e_txqsq *sq, struct sk_buff *skb,
        if (unlikely(sq->ptpsq)) {
                mlx5e_skb_cb_hwtstamp_init(skb);
                mlx5e_skb_fifo_push(&sq->ptpsq->skb_fifo, skb);
+               if (!netif_tx_queue_stopped(sq->txq) &&
+                   !mlx5e_skb_fifo_has_room(&sq->ptpsq->skb_fifo)) {
+                       netif_tx_stop_queue(sq->txq);
+                       sq->stats->stopped++;
+               }
                skb_get(skb);
        }
 
@@ -868,6 +873,7 @@ bool mlx5e_poll_tx_cq(struct mlx5e_cq *cq, int napi_budget)
 
        if (netif_tx_queue_stopped(sq->txq) &&
            mlx5e_wqc_has_room_for(&sq->wq, sq->cc, sq->pc, sq->stop_room) &&
+           mlx5e_ptpsq_fifo_has_room(sq) &&
            !test_bit(MLX5E_SQ_STATE_RECOVERING, &sq->state)) {
                netif_tx_wake_queue(sq->txq);
                stats->wake++;
index e8896f3..07c5839 100644 (file)
@@ -358,6 +358,23 @@ static int mlx5_pci_link_toggle(struct mlx5_core_dev *dev)
                err = -ETIMEDOUT;
        }
 
+       do {
+               err = pci_read_config_word(dev->pdev, PCI_DEVICE_ID, &reg16);
+               if (err)
+                       return err;
+               if (reg16 == dev_id)
+                       break;
+               msleep(20);
+       } while (!time_after(jiffies, timeout));
+
+       if (reg16 == dev_id) {
+               mlx5_core_info(dev, "Firmware responds to PCI config cycles again\n");
+       } else {
+               mlx5_core_err(dev, "Firmware is not responsive (0x%04x) after %llu ms\n",
+                             reg16, mlx5_tout_ms(dev, PCI_TOGGLE));
+               err = -ETIMEDOUT;
+       }
+
 restore:
        list_for_each_entry(sdev, &bridge_bus->devices, bus_list) {
                pci_cfg_access_unlock(sdev);
index baa8092..c971ff0 100644 (file)
@@ -3,6 +3,7 @@
 
 #include <linux/mlx5/device.h>
 #include <linux/mlx5/transobj.h>
+#include "clock.h"
 #include "aso.h"
 #include "wq.h"
 
@@ -179,6 +180,7 @@ static int create_aso_sq(struct mlx5_core_dev *mdev, int pdn,
 {
        void *in, *sqc, *wq;
        int inlen, err;
+       u8 ts_format;
 
        inlen = MLX5_ST_SZ_BYTES(create_sq_in) +
                sizeof(u64) * sq->wq_ctrl.buf.npages;
@@ -195,6 +197,11 @@ static int create_aso_sq(struct mlx5_core_dev *mdev, int pdn,
        MLX5_SET(sqc,  sqc, state, MLX5_SQC_STATE_RST);
        MLX5_SET(sqc,  sqc, flush_in_error_en, 1);
 
+       ts_format = mlx5_is_real_time_sq(mdev) ?
+                       MLX5_TIMESTAMP_FORMAT_REAL_TIME :
+                       MLX5_TIMESTAMP_FORMAT_FREE_RUNNING;
+       MLX5_SET(sqc, sqc, ts_format, ts_format);
+
        MLX5_SET(wq,   wq, wq_type,       MLX5_WQ_TYPE_CYCLIC);
        MLX5_SET(wq,   wq, uar_page,      mdev->mlx5e_res.hw_objs.bfreg.index);
        MLX5_SET(wq,   wq, log_wq_pg_sz,  sq->wq_ctrl.buf.page_shift -
index 839a01d..8ff1631 100644 (file)
@@ -122,7 +122,7 @@ void mlx5_mpfs_cleanup(struct mlx5_core_dev *dev)
 {
        struct mlx5_mpfs *mpfs = dev->priv.mpfs;
 
-       if (!MLX5_ESWITCH_MANAGER(dev))
+       if (!mpfs)
                return;
 
        WARN_ON(!hlist_empty(mpfs->hash));
@@ -137,7 +137,7 @@ int mlx5_mpfs_add_mac(struct mlx5_core_dev *dev, u8 *mac)
        int err = 0;
        u32 index;
 
-       if (!MLX5_ESWITCH_MANAGER(dev))
+       if (!mpfs)
                return 0;
 
        mutex_lock(&mpfs->lock);
@@ -185,7 +185,7 @@ int mlx5_mpfs_del_mac(struct mlx5_core_dev *dev, u8 *mac)
        int err = 0;
        u32 index;
 
-       if (!MLX5_ESWITCH_MANAGER(dev))
+       if (!mpfs)
                return 0;
 
        mutex_lock(&mpfs->lock);
index 0b459d8..283c4cc 100644 (file)
@@ -1872,6 +1872,10 @@ static void mlx5_pci_resume(struct pci_dev *pdev)
 
        err = mlx5_load_one(dev, false);
 
+       if (!err)
+               devlink_health_reporter_state_update(dev->priv.health.fw_fatal_reporter,
+                                                    DEVLINK_HEALTH_REPORTER_STATE_HEALTHY);
+
        mlx5_pci_trace(dev, "Done, err = %d, device %s\n", err,
                       !err ? "recovered" : "Failed");
 }
index ddfaf78..91ff19f 100644 (file)
@@ -1200,7 +1200,8 @@ free_rule:
        }
 
 remove_from_nic_tbl:
-       mlx5dr_matcher_remove_from_tbl_nic(dmn, nic_matcher);
+       if (!nic_matcher->rules)
+               mlx5dr_matcher_remove_from_tbl_nic(dmn, nic_matcher);
 
 free_hw_ste:
        mlx5dr_domain_nic_unlock(nic_dmn);
index 4685200..e6acd1e 100644 (file)
@@ -6851,7 +6851,7 @@ static int pcidev_init(struct pci_dev *pdev, const struct pci_device_id *id)
        char banner[sizeof(version)];
        struct ksz_switch *sw = NULL;
 
-       result = pci_enable_device(pdev);
+       result = pcim_enable_device(pdev);
        if (result)
                return result;
 
index e58a27f..fea4254 100644 (file)
@@ -656,7 +656,15 @@ void lan966x_stats_get(struct net_device *dev,
        stats->rx_dropped = dev->stats.rx_dropped +
                lan966x->stats[idx + SYS_COUNT_RX_LONG] +
                lan966x->stats[idx + SYS_COUNT_DR_LOCAL] +
-               lan966x->stats[idx + SYS_COUNT_DR_TAIL];
+               lan966x->stats[idx + SYS_COUNT_DR_TAIL] +
+               lan966x->stats[idx + SYS_COUNT_RX_RED_PRIO_0] +
+               lan966x->stats[idx + SYS_COUNT_RX_RED_PRIO_1] +
+               lan966x->stats[idx + SYS_COUNT_RX_RED_PRIO_2] +
+               lan966x->stats[idx + SYS_COUNT_RX_RED_PRIO_3] +
+               lan966x->stats[idx + SYS_COUNT_RX_RED_PRIO_4] +
+               lan966x->stats[idx + SYS_COUNT_RX_RED_PRIO_5] +
+               lan966x->stats[idx + SYS_COUNT_RX_RED_PRIO_6] +
+               lan966x->stats[idx + SYS_COUNT_RX_RED_PRIO_7];
 
        for (i = 0; i < LAN966X_NUM_TC; i++) {
                stats->rx_dropped +=
index 7e4061c..a42035c 100644 (file)
@@ -309,6 +309,7 @@ static void lan966x_fdma_tx_disable(struct lan966x_tx *tx)
                lan966x, FDMA_CH_DB_DISCARD);
 
        tx->activated = false;
+       tx->last_in_use = -1;
 }
 
 static void lan966x_fdma_tx_reload(struct lan966x_tx *tx)
@@ -687,17 +688,14 @@ static int lan966x_qsys_sw_status(struct lan966x *lan966x)
 
 static int lan966x_fdma_reload(struct lan966x *lan966x, int new_mtu)
 {
-       void *rx_dcbs, *tx_dcbs, *tx_dcbs_buf;
-       dma_addr_t rx_dma, tx_dma;
+       dma_addr_t rx_dma;
+       void *rx_dcbs;
        u32 size;
        int err;
 
        /* Store these for later to free them */
        rx_dma = lan966x->rx.dma;
-       tx_dma = lan966x->tx.dma;
        rx_dcbs = lan966x->rx.dcbs;
-       tx_dcbs = lan966x->tx.dcbs;
-       tx_dcbs_buf = lan966x->tx.dcbs_buf;
 
        napi_synchronize(&lan966x->napi);
        napi_disable(&lan966x->napi);
@@ -715,17 +713,6 @@ static int lan966x_fdma_reload(struct lan966x *lan966x, int new_mtu)
        size = ALIGN(size, PAGE_SIZE);
        dma_free_coherent(lan966x->dev, size, rx_dcbs, rx_dma);
 
-       lan966x_fdma_tx_disable(&lan966x->tx);
-       err = lan966x_fdma_tx_alloc(&lan966x->tx);
-       if (err)
-               goto restore_tx;
-
-       size = sizeof(struct lan966x_tx_dcb) * FDMA_DCB_MAX;
-       size = ALIGN(size, PAGE_SIZE);
-       dma_free_coherent(lan966x->dev, size, tx_dcbs, tx_dma);
-
-       kfree(tx_dcbs_buf);
-
        lan966x_fdma_wakeup_netdev(lan966x);
        napi_enable(&lan966x->napi);
 
@@ -735,11 +722,6 @@ restore:
        lan966x->rx.dcbs = rx_dcbs;
        lan966x_fdma_rx_start(&lan966x->rx);
 
-restore_tx:
-       lan966x->tx.dma = tx_dma;
-       lan966x->tx.dcbs = tx_dcbs;
-       lan966x->tx.dcbs_buf = tx_dcbs_buf;
-
        return err;
 }
 
index e66e548..71301db 100644 (file)
@@ -716,16 +716,26 @@ static u64 nfp_net_pf_get_app_cap(struct nfp_pf *pf)
        return val;
 }
 
-static int nfp_pf_cfg_hwinfo(struct nfp_pf *pf, bool sp_indiff)
+static void nfp_pf_cfg_hwinfo(struct nfp_pf *pf)
 {
        struct nfp_nsp *nsp;
        char hwinfo[32];
+       bool sp_indiff;
        int err;
 
        nsp = nfp_nsp_open(pf->cpp);
        if (IS_ERR(nsp))
-               return PTR_ERR(nsp);
+               return;
+
+       if (!nfp_nsp_has_hwinfo_set(nsp))
+               goto end;
 
+       sp_indiff = (nfp_net_pf_get_app_id(pf) == NFP_APP_FLOWER_NIC) ||
+                   (nfp_net_pf_get_app_cap(pf) & NFP_NET_APP_CAP_SP_INDIFF);
+
+       /* No need to clean `sp_indiff` in driver, management firmware
+        * will do it when application firmware is unloaded.
+        */
        snprintf(hwinfo, sizeof(hwinfo), "sp_indiff=%d", sp_indiff);
        err = nfp_nsp_hwinfo_set(nsp, hwinfo, sizeof(hwinfo));
        /* Not a fatal error, no need to return error to stop driver from loading */
@@ -739,21 +749,8 @@ static int nfp_pf_cfg_hwinfo(struct nfp_pf *pf, bool sp_indiff)
                pf->eth_tbl = __nfp_eth_read_ports(pf->cpp, nsp);
        }
 
+end:
        nfp_nsp_close(nsp);
-       return 0;
-}
-
-static int nfp_pf_nsp_cfg(struct nfp_pf *pf)
-{
-       bool sp_indiff = (nfp_net_pf_get_app_id(pf) == NFP_APP_FLOWER_NIC) ||
-                        (nfp_net_pf_get_app_cap(pf) & NFP_NET_APP_CAP_SP_INDIFF);
-
-       return nfp_pf_cfg_hwinfo(pf, sp_indiff);
-}
-
-static void nfp_pf_nsp_clean(struct nfp_pf *pf)
-{
-       nfp_pf_cfg_hwinfo(pf, false);
 }
 
 static int nfp_pci_probe(struct pci_dev *pdev,
@@ -856,13 +853,11 @@ static int nfp_pci_probe(struct pci_dev *pdev,
                goto err_fw_unload;
        }
 
-       err = nfp_pf_nsp_cfg(pf);
-       if (err)
-               goto err_fw_unload;
+       nfp_pf_cfg_hwinfo(pf);
 
        err = nfp_net_pci_probe(pf);
        if (err)
-               goto err_nsp_clean;
+               goto err_fw_unload;
 
        err = nfp_hwmon_register(pf);
        if (err) {
@@ -874,8 +869,6 @@ static int nfp_pci_probe(struct pci_dev *pdev,
 
 err_net_remove:
        nfp_net_pci_remove(pf);
-err_nsp_clean:
-       nfp_pf_nsp_clean(pf);
 err_fw_unload:
        kfree(pf->rtbl);
        nfp_mip_close(pf->mip);
@@ -915,7 +908,6 @@ static void __nfp_pci_shutdown(struct pci_dev *pdev, bool unload_fw)
 
        nfp_net_pci_remove(pf);
 
-       nfp_pf_nsp_clean(pf);
        vfree(pf->dumpspec);
        kfree(pf->rtbl);
        nfp_mip_close(pf->mip);
index 2240f6d..9b46579 100644 (file)
@@ -1961,11 +1961,13 @@ static int netsec_register_mdio(struct netsec_priv *priv, u32 phy_addr)
                        ret = PTR_ERR(priv->phydev);
                        dev_err(priv->dev, "get_phy_device err(%d)\n", ret);
                        priv->phydev = NULL;
+                       mdiobus_unregister(bus);
                        return -ENODEV;
                }
 
                ret = phy_device_register(priv->phydev);
                if (ret) {
+                       phy_device_free(priv->phydev);
                        mdiobus_unregister(bus);
                        dev_err(priv->dev,
                                "phy_device_register err(%d)\n", ret);
index 1fa09b4..d2c6a5d 100644 (file)
@@ -1229,6 +1229,8 @@ static int ave_init(struct net_device *ndev)
 
        phy_support_asym_pause(phydev);
 
+       phydev->mac_managed_pm = true;
+
        phy_attached_info(phydev);
 
        return 0;
@@ -1756,6 +1758,10 @@ static int ave_resume(struct device *dev)
 
        ave_global_reset(ndev);
 
+       ret = phy_init_hw(ndev->phydev);
+       if (ret)
+               return ret;
+
        ave_ethtool_get_wol(ndev, &wol);
        wol.wolopts = priv->wolopts;
        __ave_ethtool_set_wol(ndev, &wol);
index f7269d7..6656d76 100644 (file)
@@ -1243,6 +1243,12 @@ static const struct rk_gmac_ops rk3588_ops = {
        .set_rgmii_speed = rk3588_set_gmac_speed,
        .set_rmii_speed = rk3588_set_gmac_speed,
        .set_clock_selection = rk3588_set_clock_selection,
+       .regs_valid = true,
+       .regs = {
+               0xfe1b0000, /* gmac0 */
+               0xfe1c0000, /* gmac1 */
+               0x0, /* sentinel */
+       },
 };
 
 #define RV1108_GRF_GMAC_CON0           0X0900
index 383ef18..42f2c88 100644 (file)
@@ -179,10 +179,10 @@ static const struct ipa_gsi_endpoint_data ipa_gsi_endpoint_data[] = {
 static const struct ipa_resource ipa_resource_src[] = {
        [IPA_RESOURCE_TYPE_SRC_PKT_CONTEXTS] = {
                .limits[IPA_RSRC_GROUP_SRC_LWA_DL] = {
-                       .min = 1,       .max = 255,
+                       .min = 1,       .max = 63,
                },
                .limits[IPA_RSRC_GROUP_SRC_UL_DL] = {
-                       .min = 1,       .max = 255,
+                       .min = 1,       .max = 63,
                },
                .limits[IPA_RSRC_GROUP_SRC_UC_RX_Q] = {
                        .min = 1,       .max = 63,
index 3461ad3..49537fc 100644 (file)
@@ -434,6 +434,9 @@ static void ipa_idle_indication_cfg(struct ipa *ipa,
        const struct ipa_reg *reg;
        u32 val;
 
+       if (ipa->version < IPA_VERSION_3_5_1)
+               return;
+
        reg = ipa_reg(ipa, IDLE_INDICATION_CFG);
        val = ipa_reg_encode(reg, ENTER_IDLE_DEBOUNCE_THRESH,
                             enter_idle_debounce_thresh);
index 116b277..0d002c3 100644 (file)
@@ -127,112 +127,80 @@ static const u32 ipa_reg_counter_cfg_fmask[] = {
 IPA_REG_FIELDS(COUNTER_CFG, counter_cfg, 0x000001f0);
 
 static const u32 ipa_reg_src_rsrc_grp_01_rsrc_type_fmask[] = {
-       [X_MIN_LIM]                                     = GENMASK(5, 0),
-                                               /* Bits 6-7 reserved */
-       [X_MAX_LIM]                                     = GENMASK(13, 8),
-                                               /* Bits 14-15 reserved */
-       [Y_MIN_LIM]                                     = GENMASK(21, 16),
-                                               /* Bits 22-23 reserved */
-       [Y_MAX_LIM]                                     = GENMASK(29, 24),
-                                               /* Bits 30-31 reserved */
+       [X_MIN_LIM]                                     = GENMASK(7, 0),
+       [X_MAX_LIM]                                     = GENMASK(15, 8),
+       [Y_MIN_LIM]                                     = GENMASK(23, 16),
+       [Y_MAX_LIM]                                     = GENMASK(31, 24),
 };
 
 IPA_REG_STRIDE_FIELDS(SRC_RSRC_GRP_01_RSRC_TYPE, src_rsrc_grp_01_rsrc_type,
                      0x00000400, 0x0020);
 
 static const u32 ipa_reg_src_rsrc_grp_23_rsrc_type_fmask[] = {
-       [X_MIN_LIM]                                     = GENMASK(5, 0),
-                                               /* Bits 6-7 reserved */
-       [X_MAX_LIM]                                     = GENMASK(13, 8),
-                                               /* Bits 14-15 reserved */
-       [Y_MIN_LIM]                                     = GENMASK(21, 16),
-                                               /* Bits 22-23 reserved */
-       [Y_MAX_LIM]                                     = GENMASK(29, 24),
-                                               /* Bits 30-31 reserved */
+       [X_MIN_LIM]                                     = GENMASK(7, 0),
+       [X_MAX_LIM]                                     = GENMASK(15, 8),
+       [Y_MIN_LIM]                                     = GENMASK(23, 16),
+       [Y_MAX_LIM]                                     = GENMASK(31, 24),
 };
 
 IPA_REG_STRIDE_FIELDS(SRC_RSRC_GRP_23_RSRC_TYPE, src_rsrc_grp_23_rsrc_type,
                      0x00000404, 0x0020);
 
 static const u32 ipa_reg_src_rsrc_grp_45_rsrc_type_fmask[] = {
-       [X_MIN_LIM]                                     = GENMASK(5, 0),
-                                               /* Bits 6-7 reserved */
-       [X_MAX_LIM]                                     = GENMASK(13, 8),
-                                               /* Bits 14-15 reserved */
-       [Y_MIN_LIM]                                     = GENMASK(21, 16),
-                                               /* Bits 22-23 reserved */
-       [Y_MAX_LIM]                                     = GENMASK(29, 24),
-                                               /* Bits 30-31 reserved */
+       [X_MIN_LIM]                                     = GENMASK(7, 0),
+       [X_MAX_LIM]                                     = GENMASK(15, 8),
+       [Y_MIN_LIM]                                     = GENMASK(23, 16),
+       [Y_MAX_LIM]                                     = GENMASK(31, 24),
 };
 
 IPA_REG_STRIDE_FIELDS(SRC_RSRC_GRP_45_RSRC_TYPE, src_rsrc_grp_45_rsrc_type,
                      0x00000408, 0x0020);
 
 static const u32 ipa_reg_src_rsrc_grp_67_rsrc_type_fmask[] = {
-       [X_MIN_LIM]                                     = GENMASK(5, 0),
-                                               /* Bits 6-7 reserved */
-       [X_MAX_LIM]                                     = GENMASK(13, 8),
-                                               /* Bits 14-15 reserved */
-       [Y_MIN_LIM]                                     = GENMASK(21, 16),
-                                               /* Bits 22-23 reserved */
-       [Y_MAX_LIM]                                     = GENMASK(29, 24),
-                                               /* Bits 30-31 reserved */
+       [X_MIN_LIM]                                     = GENMASK(7, 0),
+       [X_MAX_LIM]                                     = GENMASK(15, 8),
+       [Y_MIN_LIM]                                     = GENMASK(23, 16),
+       [Y_MAX_LIM]                                     = GENMASK(31, 24),
 };
 
 IPA_REG_STRIDE_FIELDS(SRC_RSRC_GRP_67_RSRC_TYPE, src_rsrc_grp_67_rsrc_type,
                      0x0000040c, 0x0020);
 
 static const u32 ipa_reg_dst_rsrc_grp_01_rsrc_type_fmask[] = {
-       [X_MIN_LIM]                                     = GENMASK(5, 0),
-                                               /* Bits 6-7 reserved */
-       [X_MAX_LIM]                                     = GENMASK(13, 8),
-                                               /* Bits 14-15 reserved */
-       [Y_MIN_LIM]                                     = GENMASK(21, 16),
-                                               /* Bits 22-23 reserved */
-       [Y_MAX_LIM]                                     = GENMASK(29, 24),
-                                               /* Bits 30-31 reserved */
+       [X_MIN_LIM]                                     = GENMASK(7, 0),
+       [X_MAX_LIM]                                     = GENMASK(15, 8),
+       [Y_MIN_LIM]                                     = GENMASK(23, 16),
+       [Y_MAX_LIM]                                     = GENMASK(31, 24),
 };
 
 IPA_REG_STRIDE_FIELDS(DST_RSRC_GRP_01_RSRC_TYPE, dst_rsrc_grp_01_rsrc_type,
                      0x00000500, 0x0020);
 
 static const u32 ipa_reg_dst_rsrc_grp_23_rsrc_type_fmask[] = {
-       [X_MIN_LIM]                                     = GENMASK(5, 0),
-                                               /* Bits 6-7 reserved */
-       [X_MAX_LIM]                                     = GENMASK(13, 8),
-                                               /* Bits 14-15 reserved */
-       [Y_MIN_LIM]                                     = GENMASK(21, 16),
-                                               /* Bits 22-23 reserved */
-       [Y_MAX_LIM]                                     = GENMASK(29, 24),
-                                               /* Bits 30-31 reserved */
+       [X_MIN_LIM]                                     = GENMASK(7, 0),
+       [X_MAX_LIM]                                     = GENMASK(15, 8),
+       [Y_MIN_LIM]                                     = GENMASK(23, 16),
+       [Y_MAX_LIM]                                     = GENMASK(31, 24),
 };
 
 IPA_REG_STRIDE_FIELDS(DST_RSRC_GRP_23_RSRC_TYPE, dst_rsrc_grp_23_rsrc_type,
                      0x00000504, 0x0020);
 
 static const u32 ipa_reg_dst_rsrc_grp_45_rsrc_type_fmask[] = {
-       [X_MIN_LIM]                                     = GENMASK(5, 0),
-                                               /* Bits 6-7 reserved */
-       [X_MAX_LIM]                                     = GENMASK(13, 8),
-                                               /* Bits 14-15 reserved */
-       [Y_MIN_LIM]                                     = GENMASK(21, 16),
-                                               /* Bits 22-23 reserved */
-       [Y_MAX_LIM]                                     = GENMASK(29, 24),
-                                               /* Bits 30-31 reserved */
+       [X_MIN_LIM]                                     = GENMASK(7, 0),
+       [X_MAX_LIM]                                     = GENMASK(15, 8),
+       [Y_MIN_LIM]                                     = GENMASK(23, 16),
+       [Y_MAX_LIM]                                     = GENMASK(31, 24),
 };
 
 IPA_REG_STRIDE_FIELDS(DST_RSRC_GRP_45_RSRC_TYPE, dst_rsrc_grp_45_rsrc_type,
                      0x00000508, 0x0020);
 
 static const u32 ipa_reg_dst_rsrc_grp_67_rsrc_type_fmask[] = {
-       [X_MIN_LIM]                                     = GENMASK(5, 0),
-                                               /* Bits 6-7 reserved */
-       [X_MAX_LIM]                                     = GENMASK(13, 8),
-                                               /* Bits 14-15 reserved */
-       [Y_MIN_LIM]                                     = GENMASK(21, 16),
-                                               /* Bits 22-23 reserved */
-       [Y_MAX_LIM]                                     = GENMASK(29, 24),
-                                               /* Bits 30-31 reserved */
+       [X_MIN_LIM]                                     = GENMASK(7, 0),
+       [X_MAX_LIM]                                     = GENMASK(15, 8),
+       [Y_MIN_LIM]                                     = GENMASK(23, 16),
+       [Y_MAX_LIM]                                     = GENMASK(31, 24),
 };
 
 IPA_REG_STRIDE_FIELDS(DST_RSRC_GRP_67_RSRC_TYPE, dst_rsrc_grp_67_rsrc_type,
index b5f4df1..0052968 100644 (file)
@@ -117,6 +117,10 @@ static const struct attribute_group *nsim_bus_dev_attr_groups[] = {
 
 static void nsim_bus_dev_release(struct device *dev)
 {
+       struct nsim_bus_dev *nsim_bus_dev;
+
+       nsim_bus_dev = container_of(dev, struct nsim_bus_dev, dev);
+       kfree(nsim_bus_dev);
 }
 
 static struct device_type nsim_bus_dev_type = {
@@ -291,6 +295,8 @@ nsim_bus_dev_new(unsigned int id, unsigned int port_count, unsigned int num_queu
 
 err_nsim_bus_dev_id_free:
        ida_free(&nsim_bus_dev_ids, nsim_bus_dev->dev.id);
+       put_device(&nsim_bus_dev->dev);
+       nsim_bus_dev = NULL;
 err_nsim_bus_dev_free:
        kfree(nsim_bus_dev);
        return ERR_PTR(err);
@@ -300,9 +306,8 @@ static void nsim_bus_dev_del(struct nsim_bus_dev *nsim_bus_dev)
 {
        /* Disallow using nsim_bus_dev */
        smp_store_release(&nsim_bus_dev->init, false);
-       device_unregister(&nsim_bus_dev->dev);
        ida_free(&nsim_bus_dev_ids, nsim_bus_dev->dev.id);
-       kfree(nsim_bus_dev);
+       device_unregister(&nsim_bus_dev->dev);
 }
 
 static struct device_driver nsim_driver = {
index 794fc0c..a7880c7 100644 (file)
@@ -309,8 +309,10 @@ static int nsim_dev_debugfs_init(struct nsim_dev *nsim_dev)
        if (IS_ERR(nsim_dev->ddir))
                return PTR_ERR(nsim_dev->ddir);
        nsim_dev->ports_ddir = debugfs_create_dir("ports", nsim_dev->ddir);
-       if (IS_ERR(nsim_dev->ports_ddir))
-               return PTR_ERR(nsim_dev->ports_ddir);
+       if (IS_ERR(nsim_dev->ports_ddir)) {
+               err = PTR_ERR(nsim_dev->ports_ddir);
+               goto err_ddir;
+       }
        debugfs_create_bool("fw_update_status", 0600, nsim_dev->ddir,
                            &nsim_dev->fw_update_status);
        debugfs_create_u32("fw_update_overwrite_mask", 0600, nsim_dev->ddir,
@@ -346,7 +348,7 @@ static int nsim_dev_debugfs_init(struct nsim_dev *nsim_dev)
        nsim_dev->nodes_ddir = debugfs_create_dir("rate_nodes", nsim_dev->ddir);
        if (IS_ERR(nsim_dev->nodes_ddir)) {
                err = PTR_ERR(nsim_dev->nodes_ddir);
-               goto err_out;
+               goto err_ports_ddir;
        }
        debugfs_create_bool("fail_trap_drop_counter_get", 0600,
                            nsim_dev->ddir,
@@ -354,8 +356,9 @@ static int nsim_dev_debugfs_init(struct nsim_dev *nsim_dev)
        nsim_udp_tunnels_debugfs_create(nsim_dev);
        return 0;
 
-err_out:
+err_ports_ddir:
        debugfs_remove_recursive(nsim_dev->ports_ddir);
+err_ddir:
        debugfs_remove_recursive(nsim_dev->ddir);
        return err;
 }
@@ -442,7 +445,7 @@ static int nsim_dev_resources_register(struct devlink *devlink)
                                     &params);
        if (err) {
                pr_err("Failed to register IPv4 top resource\n");
-               goto out;
+               goto err_out;
        }
 
        err = devl_resource_register(devlink, "fib", (u64)-1,
@@ -450,7 +453,7 @@ static int nsim_dev_resources_register(struct devlink *devlink)
                                     NSIM_RESOURCE_IPV4, &params);
        if (err) {
                pr_err("Failed to register IPv4 FIB resource\n");
-               return err;
+               goto err_out;
        }
 
        err = devl_resource_register(devlink, "fib-rules", (u64)-1,
@@ -458,7 +461,7 @@ static int nsim_dev_resources_register(struct devlink *devlink)
                                     NSIM_RESOURCE_IPV4, &params);
        if (err) {
                pr_err("Failed to register IPv4 FIB rules resource\n");
-               return err;
+               goto err_out;
        }
 
        /* Resources for IPv6 */
@@ -468,7 +471,7 @@ static int nsim_dev_resources_register(struct devlink *devlink)
                                     &params);
        if (err) {
                pr_err("Failed to register IPv6 top resource\n");
-               goto out;
+               goto err_out;
        }
 
        err = devl_resource_register(devlink, "fib", (u64)-1,
@@ -476,7 +479,7 @@ static int nsim_dev_resources_register(struct devlink *devlink)
                                     NSIM_RESOURCE_IPV6, &params);
        if (err) {
                pr_err("Failed to register IPv6 FIB resource\n");
-               return err;
+               goto err_out;
        }
 
        err = devl_resource_register(devlink, "fib-rules", (u64)-1,
@@ -484,7 +487,7 @@ static int nsim_dev_resources_register(struct devlink *devlink)
                                     NSIM_RESOURCE_IPV6, &params);
        if (err) {
                pr_err("Failed to register IPv6 FIB rules resource\n");
-               return err;
+               goto err_out;
        }
 
        /* Resources for nexthops */
@@ -492,8 +495,14 @@ static int nsim_dev_resources_register(struct devlink *devlink)
                                     NSIM_RESOURCE_NEXTHOPS,
                                     DEVLINK_RESOURCE_ID_PARENT_TOP,
                                     &params);
+       if (err) {
+               pr_err("Failed to register NEXTHOPS resource\n");
+               goto err_out;
+       }
+       return 0;
 
-out:
+err_out:
+       devl_resources_unregister(devlink);
        return err;
 }
 
index f577449..85c06db 100644 (file)
@@ -54,16 +54,19 @@ static int virtual_nci_send(struct nci_dev *ndev, struct sk_buff *skb)
        mutex_lock(&nci_mutex);
        if (state != virtual_ncidev_enabled) {
                mutex_unlock(&nci_mutex);
+               kfree_skb(skb);
                return 0;
        }
 
        if (send_buff) {
                mutex_unlock(&nci_mutex);
+               kfree_skb(skb);
                return -1;
        }
        send_buff = skb_copy(skb, GFP_KERNEL);
        mutex_unlock(&nci_mutex);
        wake_up_interruptible(&wq);
+       consume_skb(skb);
 
        return 0;
 }
index 7e73207..9e46d83 100644 (file)
@@ -667,7 +667,7 @@ static u8 jz4755_lcd_24bit_funcs[] = { 1, 1, 1, 1, 0, 0, };
 static const struct group_desc jz4755_groups[] = {
        INGENIC_PIN_GROUP("uart0-data", jz4755_uart0_data, 0),
        INGENIC_PIN_GROUP("uart0-hwflow", jz4755_uart0_hwflow, 0),
-       INGENIC_PIN_GROUP("uart1-data", jz4755_uart1_data, 0),
+       INGENIC_PIN_GROUP("uart1-data", jz4755_uart1_data, 1),
        INGENIC_PIN_GROUP("uart2-data", jz4755_uart2_data, 1),
        INGENIC_PIN_GROUP("ssi-dt-b", jz4755_ssi_dt_b, 0),
        INGENIC_PIN_GROUP("ssi-dt-f", jz4755_ssi_dt_f, 0),
@@ -721,7 +721,7 @@ static const char *jz4755_ssi_groups[] = {
        "ssi-ce1-b", "ssi-ce1-f",
 };
 static const char *jz4755_mmc0_groups[] = { "mmc0-1bit", "mmc0-4bit", };
-static const char *jz4755_mmc1_groups[] = { "mmc0-1bit", "mmc0-4bit", };
+static const char *jz4755_mmc1_groups[] = { "mmc1-1bit", "mmc1-4bit", };
 static const char *jz4755_i2c_groups[] = { "i2c-data", };
 static const char *jz4755_cim_groups[] = { "cim-data", };
 static const char *jz4755_lcd_groups[] = {
index 62ce395..687aaa6 100644 (file)
@@ -1864,19 +1864,28 @@ static void ocelot_irq_unmask_level(struct irq_data *data)
        if (val & bit)
                ack = true;
 
+       /* Try to clear any rising edges */
+       if (!active && ack)
+               regmap_write_bits(info->map, REG(OCELOT_GPIO_INTR, info, gpio),
+                                 bit, bit);
+
        /* Enable the interrupt now */
        gpiochip_enable_irq(chip, gpio);
        regmap_update_bits(info->map, REG(OCELOT_GPIO_INTR_ENA, info, gpio),
                           bit, bit);
 
        /*
-        * In case the interrupt line is still active and the interrupt
-        * controller has not seen any changes in the interrupt line, then it
-        * means that there happen another interrupt while the line was active.
+        * In case the interrupt line is still active then it means that
+        * there happen another interrupt while the line was active.
         * So we missed that one, so we need to kick the interrupt again
         * handler.
         */
-       if (active && !ack) {
+       regmap_read(info->map, REG(OCELOT_GPIO_IN, info, gpio), &val);
+       if ((!(val & bit) && trigger_level == IRQ_TYPE_LEVEL_LOW) ||
+             (val & bit && trigger_level == IRQ_TYPE_LEVEL_HIGH))
+               active = true;
+
+       if (active) {
                struct ocelot_irq_work *work;
 
                work = kmalloc(sizeof(*work), GFP_ATOMIC);
index 7d2fbf8..c98f35a 100644 (file)
@@ -412,10 +412,6 @@ static int zynqmp_pinconf_cfg_set(struct pinctrl_dev *pctldev,
 
                        break;
                case PIN_CONFIG_BIAS_HIGH_IMPEDANCE:
-                       param = PM_PINCTRL_CONFIG_TRI_STATE;
-                       arg = PM_PINCTRL_TRI_STATE_ENABLE;
-                       ret = zynqmp_pm_pinctrl_set_config(pin, param, arg);
-                       break;
                case PIN_CONFIG_MODE_LOW_POWER:
                        /*
                         * These cases are mentioned in dts but configurable
@@ -424,11 +420,6 @@ static int zynqmp_pinconf_cfg_set(struct pinctrl_dev *pctldev,
                         */
                        ret = 0;
                        break;
-               case PIN_CONFIG_OUTPUT_ENABLE:
-                       param = PM_PINCTRL_CONFIG_TRI_STATE;
-                       arg = PM_PINCTRL_TRI_STATE_DISABLE;
-                       ret = zynqmp_pm_pinctrl_set_config(pin, param, arg);
-                       break;
                default:
                        dev_warn(pctldev->dev,
                                 "unsupported configuration parameter '%u'\n",
index a2abfe9..8bf8b21 100644 (file)
@@ -51,6 +51,7 @@
  *                  detection.
  * @skip_wake_irqs: Skip IRQs that are handled by wakeup interrupt controller
  * @disabled_for_mux: These IRQs were disabled because we muxed away.
+ * @ever_gpio:      This bit is set the first time we mux a pin to gpio_func.
  * @soc:            Reference to soc_data of platform specific data.
  * @regs:           Base addresses for the TLMM tiles.
  * @phys_base:      Physical base address
@@ -72,6 +73,7 @@ struct msm_pinctrl {
        DECLARE_BITMAP(enabled_irqs, MAX_NR_GPIO);
        DECLARE_BITMAP(skip_wake_irqs, MAX_NR_GPIO);
        DECLARE_BITMAP(disabled_for_mux, MAX_NR_GPIO);
+       DECLARE_BITMAP(ever_gpio, MAX_NR_GPIO);
 
        const struct msm_pinctrl_soc_data *soc;
        void __iomem *regs[MAX_NR_TILES];
@@ -218,6 +220,25 @@ static int msm_pinmux_set_mux(struct pinctrl_dev *pctldev,
 
        val = msm_readl_ctl(pctrl, g);
 
+       /*
+        * If this is the first time muxing to GPIO and the direction is
+        * output, make sure that we're not going to be glitching the pin
+        * by reading the current state of the pin and setting it as the
+        * output.
+        */
+       if (i == gpio_func && (val & BIT(g->oe_bit)) &&
+           !test_and_set_bit(group, pctrl->ever_gpio)) {
+               u32 io_val = msm_readl_io(pctrl, g);
+
+               if (io_val & BIT(g->in_bit)) {
+                       if (!(io_val & BIT(g->out_bit)))
+                               msm_writel_io(io_val | BIT(g->out_bit), pctrl, g);
+               } else {
+                       if (io_val & BIT(g->out_bit))
+                               msm_writel_io(io_val & ~BIT(g->out_bit), pctrl, g);
+               }
+       }
+
        if (egpio_func && i == egpio_func) {
                if (val & BIT(g->egpio_present))
                        val &= ~BIT(g->egpio_enable);
index ce859b3..96e790e 100644 (file)
@@ -663,6 +663,13 @@ static int amd_pmc_verify_czn_rtc(struct amd_pmc_dev *pdev, u32 *arg)
        struct rtc_time tm;
        int rc;
 
+       /* we haven't yet read SMU version */
+       if (!pdev->major) {
+               rc = amd_pmc_get_smu_version(pdev);
+               if (rc)
+                       return rc;
+       }
+
        if (pdev->major < 64 || (pdev->major == 64 && pdev->minor < 53))
                return 0;
 
index 613c45c..c685a70 100644 (file)
@@ -464,6 +464,15 @@ static const struct dmi_system_id asus_quirks[] = {
                },
                .driver_data = &quirk_asus_tablet_mode,
        },
+       {
+               .callback = dmi_matched,
+               .ident = "ASUS ROG FLOW X16",
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "GV601R"),
+               },
+               .driver_data = &quirk_asus_tablet_mode,
+       },
        {},
 };
 
index a1fe1e0..17ec582 100644 (file)
@@ -1914,6 +1914,8 @@ static const struct x86_cpu_id intel_pmc_core_ids[] = {
        X86_MATCH_INTEL_FAM6_MODEL(ALDERLAKE_N,         &tgl_reg_map),
        X86_MATCH_INTEL_FAM6_MODEL(ALDERLAKE,           &adl_reg_map),
        X86_MATCH_INTEL_FAM6_MODEL(RAPTORLAKE_P,        &tgl_reg_map),
+       X86_MATCH_INTEL_FAM6_MODEL(RAPTORLAKE,          &adl_reg_map),
+       X86_MATCH_INTEL_FAM6_MODEL(RAPTORLAKE_S,        &adl_reg_map),
        {}
 };
 
index 6a823b8..20e5c04 100644 (file)
@@ -263,6 +263,8 @@ enum tpacpi_hkey_event_t {
 #define TPACPI_DBG_BRGHT       0x0020
 #define TPACPI_DBG_MIXER       0x0040
 
+#define FAN_NOT_PRESENT                65535
+
 #define strlencmp(a, b) (strncmp((a), (b), strlen(b)))
 
 
@@ -8876,7 +8878,7 @@ static int __init fan_init(struct ibm_init_struct *iibm)
                        /* Try and probe the 2nd fan */
                        tp_features.second_fan = 1; /* needed for get_speed to work */
                        res = fan2_get_speed(&speed);
-                       if (res >= 0) {
+                       if (res >= 0 && speed != FAN_NOT_PRESENT) {
                                /* It responded - so let's assume it's there */
                                tp_features.second_fan = 1;
                                tp_features.second_fan_ctl = 1;
index 610413b..58cc2ba 100644 (file)
@@ -1233,6 +1233,9 @@ static u32 rtc_handler(void *context)
 
 static inline void rtc_wake_setup(struct device *dev)
 {
+       if (acpi_disabled)
+               return;
+
        acpi_install_fixed_event_handler(ACPI_EVENT_RTC, rtc_handler, dev);
        /*
         * After the RTC handler is installed, the Fixed_RTC event should
@@ -1286,7 +1289,6 @@ static void cmos_wake_setup(struct device *dev)
 
        use_acpi_alarm_quirks();
 
-       rtc_wake_setup(dev);
        acpi_rtc_info.wake_on = rtc_wake_on;
        acpi_rtc_info.wake_off = rtc_wake_off;
 
@@ -1344,6 +1346,9 @@ static void cmos_check_acpi_rtc_status(struct device *dev,
 {
 }
 
+static void rtc_wake_setup(struct device *dev)
+{
+}
 #endif
 
 #ifdef CONFIG_PNP
@@ -1354,6 +1359,8 @@ static int cmos_pnp_probe(struct pnp_dev *pnp, const struct pnp_device_id *id)
 {
        int irq, ret;
 
+       cmos_wake_setup(&pnp->dev);
+
        if (pnp_port_start(pnp, 0) == 0x70 && !pnp_irq_valid(pnp, 0)) {
                irq = 0;
 #ifdef CONFIG_X86
@@ -1372,7 +1379,7 @@ static int cmos_pnp_probe(struct pnp_dev *pnp, const struct pnp_device_id *id)
        if (ret)
                return ret;
 
-       cmos_wake_setup(&pnp->dev);
+       rtc_wake_setup(&pnp->dev);
 
        return 0;
 }
@@ -1461,6 +1468,7 @@ static int __init cmos_platform_probe(struct platform_device *pdev)
        int irq, ret;
 
        cmos_of_init(pdev);
+       cmos_wake_setup(&pdev->dev);
 
        if (RTC_IOMAPPED)
                resource = platform_get_resource(pdev, IORESOURCE_IO, 0);
@@ -1474,7 +1482,7 @@ static int __init cmos_platform_probe(struct platform_device *pdev)
        if (ret)
                return ret;
 
-       cmos_wake_setup(&pdev->dev);
+       rtc_wake_setup(&pdev->dev);
 
        return 0;
 }
index 8b22df8..4e981cc 100644 (file)
@@ -2993,7 +2993,7 @@ _base_config_dma_addressing(struct MPT3SAS_ADAPTER *ioc, struct pci_dev *pdev)
        u64 coherent_dma_mask, dma_mask;
 
        if (ioc->is_mcpu_endpoint || sizeof(dma_addr_t) == 4 ||
-           dma_get_required_mask(&pdev->dev) <= 32) {
+           dma_get_required_mask(&pdev->dev) <= DMA_BIT_MASK(32)) {
                ioc->dma_mask = 32;
                coherent_dma_mask = dma_mask = DMA_BIT_MASK(32);
        /* Set 63 bit DMA mask for all SAS3 and SAS35 controllers */
index a334e89..b905713 100644 (file)
@@ -398,7 +398,7 @@ static void aspeed_spi_get_windows(struct aspeed_spi *aspi,
                windows[cs].cs = cs;
                windows[cs].size = data->segment_end(aspi, reg_val) -
                        data->segment_start(aspi, reg_val);
-               windows[cs].offset = cs ? windows[cs - 1].offset + windows[cs - 1].size : 0;
+               windows[cs].offset = data->segment_start(aspi, reg_val) - aspi->ahb_base_phy;
                dev_vdbg(aspi->dev, "CE%d offset=0x%.8x size=0x%x\n", cs,
                         windows[cs].offset, windows[cs].size);
        }
@@ -1163,7 +1163,7 @@ static const struct aspeed_spi_data ast2500_spi_data = {
 static const struct aspeed_spi_data ast2600_fmc_data = {
        .max_cs        = 3,
        .hastype       = false,
-       .mode_bits     = SPI_RX_QUAD | SPI_RX_QUAD,
+       .mode_bits     = SPI_RX_QUAD | SPI_TX_QUAD,
        .we0           = 16,
        .ctl0          = CE0_CTRL_REG,
        .timing        = CE0_TIMING_COMPENSATION_REG,
@@ -1178,7 +1178,7 @@ static const struct aspeed_spi_data ast2600_fmc_data = {
 static const struct aspeed_spi_data ast2600_spi_data = {
        .max_cs        = 2,
        .hastype       = false,
-       .mode_bits     = SPI_RX_QUAD | SPI_RX_QUAD,
+       .mode_bits     = SPI_RX_QUAD | SPI_TX_QUAD,
        .we0           = 16,
        .ctl0          = CE0_CTRL_REG,
        .timing        = CE0_TIMING_COMPENSATION_REG,
index 15b1101..c900c2f 100644 (file)
@@ -1,4 +1,4 @@
-// SPDX-License-Identifier: GPL-2.0=or-later
+// SPDX-License-Identifier: GPL-2.0-or-later
 /* Copyright (C) 2022 Hewlett-Packard Development Company, L.P. */
 
 #include <linux/iopoll.h>
index 55f4ee2..605acb1 100644 (file)
 #define ERASE_OPCODE_SHIFT             8
 #define ERASE_OPCODE_MASK              (0xff << ERASE_OPCODE_SHIFT)
 #define ERASE_64K_OPCODE_SHIFT         16
-#define ERASE_64K_OPCODE_MASK          (0xff << ERASE_OPCODE_SHIFT)
+#define ERASE_64K_OPCODE_MASK          (0xff << ERASE_64K_OPCODE_SHIFT)
 
 /* Flash descriptor fields */
 #define FLVALSIG_MAGIC                 0x0ff0a55a
index cb075c1..7b64e64 100644 (file)
@@ -151,7 +151,7 @@ mpc52xx_spi_fsmstate_idle(int irq, struct mpc52xx_spi *ms, u8 status, u8 data)
        int spr, sppr;
        u8 ctrl1;
 
-       if (status && (irq != NO_IRQ))
+       if (status && irq)
                dev_err(&ms->master->dev, "spurious irq, status=0x%.2x\n",
                        status);
 
index 7d89510..678dc51 100644 (file)
@@ -1057,6 +1057,8 @@ static int spi_qup_probe(struct platform_device *pdev)
        else
                master->num_chipselect = num_cs;
 
+       master->use_gpio_descriptors = true;
+       master->max_native_cs = SPI_NUM_CHIPSELECTS;
        master->bus_num = pdev->id;
        master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | SPI_LOOP;
        master->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 32);
index c89592b..9049726 100644 (file)
@@ -1157,6 +1157,11 @@ static int tegra_qspi_combined_seq_xfer(struct tegra_qspi *tqspi,
                msg->actual_length += xfer->len;
                transfer_phase++;
        }
+       if (!xfer->cs_change) {
+               tegra_qspi_transfer_end(spi);
+               spi_transfer_delay_exec(xfer);
+       }
+       ret = 0;
 
 exit:
        msg->status = ret;
index 9e6bcc0..41e77de 100644 (file)
@@ -340,12 +340,9 @@ int aperture_remove_conflicting_pci_devices(struct pci_dev *pdev, const char *na
                size = pci_resource_len(pdev, bar);
                ret = aperture_remove_conflicting_devices(base, size, primary, name);
                if (ret)
-                       break;
+                       return ret;
        }
 
-       if (ret)
-               return ret;
-
        /*
         * WARNING: Apparently we must kick fbdev drivers before vgacon,
         * otherwise the vga fbdev driver falls over.
index 63c7ebb..6a11025 100644 (file)
@@ -911,7 +911,7 @@ static int load_elf_binary(struct linux_binprm *bprm)
                interp_elf_ex = kmalloc(sizeof(*interp_elf_ex), GFP_KERNEL);
                if (!interp_elf_ex) {
                        retval = -ENOMEM;
-                       goto out_free_ph;
+                       goto out_free_file;
                }
 
                /* Get the exec headers */
@@ -1354,6 +1354,7 @@ out:
 out_free_dentry:
        kfree(interp_elf_ex);
        kfree(interp_elf_phdata);
+out_free_file:
        allow_write_access(interpreter);
        if (interpreter)
                fput(interpreter);
index 1cca09a..2a24b1f 100644 (file)
@@ -205,14 +205,19 @@ static int allocate_filesystem_keyring(struct super_block *sb)
 }
 
 /*
- * This is called at unmount time to release all encryption keys that have been
- * added to the filesystem, along with the keyring that contains them.
+ * Release all encryption keys that have been added to the filesystem, along
+ * with the keyring that contains them.
  *
- * Note that besides clearing and freeing memory, this might need to evict keys
- * from the keyslots of an inline crypto engine.  Therefore, this must be called
- * while the filesystem's underlying block device(s) are still available.
+ * This is called at unmount time.  The filesystem's underlying block device(s)
+ * are still available at this time; this is important because after user file
+ * accesses have been allowed, this function may need to evict keys from the
+ * keyslots of an inline crypto engine, which requires the block device(s).
+ *
+ * This is also called when the super_block is being freed.  This is needed to
+ * avoid a memory leak if mounting fails after the "test_dummy_encryption"
+ * option was processed, as in that case the unmount-time call isn't made.
  */
-void fscrypt_sb_delete(struct super_block *sb)
+void fscrypt_destroy_keyring(struct super_block *sb)
 {
        struct fscrypt_keyring *keyring = sb->s_master_keys;
        size_t i;
index 349a5da..32dc8cf 100644 (file)
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -1197,11 +1197,11 @@ static int unshare_sighand(struct task_struct *me)
                        return -ENOMEM;
 
                refcount_set(&newsighand->count, 1);
-               memcpy(newsighand->action, oldsighand->action,
-                      sizeof(newsighand->action));
 
                write_lock_irq(&tasklist_lock);
                spin_lock(&oldsighand->siglock);
+               memcpy(newsighand->action, oldsighand->action,
+                      sizeof(newsighand->action));
                rcu_assign_pointer(me->sighand, newsighand);
                spin_unlock(&oldsighand->siglock);
                write_unlock_irq(&tasklist_lock);
index 6a82660..8d39e4f 100644 (file)
@@ -291,6 +291,7 @@ static void __put_super(struct super_block *s)
                WARN_ON(s->s_inode_lru.node);
                WARN_ON(!list_empty(&s->s_mounts));
                security_sb_free(s);
+               fscrypt_destroy_keyring(s);
                put_user_ns(s->s_user_ns);
                kfree(s->s_subtype);
                call_rcu(&s->rcu, destroy_super_rcu);
@@ -479,7 +480,7 @@ void generic_shutdown_super(struct super_block *sb)
                evict_inodes(sb);
                /* only nonzero refcount inodes can have marks */
                fsnotify_sb_delete(sb);
-               fscrypt_sb_delete(sb);
+               fscrypt_destroy_keyring(sb);
                security_sb_delete(sb);
 
                if (sb->s_dio_done_wq) {
index 9e7d46d..0566705 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/bpfptr.h>
 #include <linux/btf.h>
 #include <linux/rcupdate_trace.h>
+#include <linux/init.h>
 
 struct bpf_verifier_env;
 struct bpf_verifier_log;
@@ -970,6 +971,8 @@ struct bpf_trampoline *bpf_trampoline_get(u64 key,
                                          struct bpf_attach_target_info *tgt_info);
 void bpf_trampoline_put(struct bpf_trampoline *tr);
 int arch_prepare_bpf_dispatcher(void *image, void *buf, s64 *funcs, int num_funcs);
+int __init bpf_arch_init_dispatcher_early(void *ip);
+
 #define BPF_DISPATCHER_INIT(_name) {                           \
        .mutex = __MUTEX_INITIALIZER(_name.mutex),              \
        .func = &_name##_func,                                  \
@@ -983,6 +986,13 @@ int arch_prepare_bpf_dispatcher(void *image, void *buf, s64 *funcs, int num_func
        },                                                      \
 }
 
+#define BPF_DISPATCHER_INIT_CALL(_name)                                        \
+       static int __init _name##_init(void)                            \
+       {                                                               \
+               return bpf_arch_init_dispatcher_early(_name##_func);    \
+       }                                                               \
+       early_initcall(_name##_init)
+
 #ifdef CONFIG_X86_64
 #define BPF_DISPATCHER_ATTRIBUTES __attribute__((patchable_function_entry(5)))
 #else
@@ -1000,7 +1010,9 @@ int arch_prepare_bpf_dispatcher(void *image, void *buf, s64 *funcs, int num_func
        }                                                               \
        EXPORT_SYMBOL(bpf_dispatcher_##name##_func);                    \
        struct bpf_dispatcher bpf_dispatcher_##name =                   \
-               BPF_DISPATCHER_INIT(bpf_dispatcher_##name);
+               BPF_DISPATCHER_INIT(bpf_dispatcher_##name);             \
+       BPF_DISPATCHER_INIT_CALL(bpf_dispatcher_##name);
+
 #define DECLARE_BPF_DISPATCHER(name)                                   \
        unsigned int bpf_dispatcher_##name##_func(                      \
                const void *ctx,                                        \
index cad78b5..4f5f8a6 100644 (file)
@@ -307,7 +307,7 @@ fscrypt_free_dummy_policy(struct fscrypt_dummy_policy *dummy_policy)
 }
 
 /* keyring.c */
-void fscrypt_sb_delete(struct super_block *sb);
+void fscrypt_destroy_keyring(struct super_block *sb);
 int fscrypt_ioctl_add_key(struct file *filp, void __user *arg);
 int fscrypt_add_test_dummy_key(struct super_block *sb,
                               const struct fscrypt_dummy_policy *dummy_policy);
@@ -521,7 +521,7 @@ fscrypt_free_dummy_policy(struct fscrypt_dummy_policy *dummy_policy)
 }
 
 /* keyring.c */
-static inline void fscrypt_sb_delete(struct super_block *sb)
+static inline void fscrypt_destroy_keyring(struct super_block *sb)
 {
 }
 
index a12929b..af2ceb4 100644 (file)
@@ -970,7 +970,7 @@ void mlx5_cmd_allowed_opcode(struct mlx5_core_dev *dev, u16 opcode);
 struct mlx5_async_ctx {
        struct mlx5_core_dev *dev;
        atomic_t num_inflight;
-       struct wait_queue_head wait;
+       struct completion inflight_done;
 };
 
 struct mlx5_async_work;
index 19dfdd7..1d3be1a 100644 (file)
@@ -51,8 +51,8 @@ static inline bool __must_check __must_check_overflow(bool overflow)
        return unlikely(overflow);
 }
 
-/** check_add_overflow() - Calculate addition with overflow checking
- *
+/**
+ * check_add_overflow() - Calculate addition with overflow checking
  * @a: first addend
  * @b: second addend
  * @d: pointer to store sum
@@ -66,8 +66,8 @@ static inline bool __must_check __must_check_overflow(bool overflow)
 #define check_add_overflow(a, b, d)    \
        __must_check_overflow(__builtin_add_overflow(a, b, d))
 
-/** check_sub_overflow() - Calculate subtraction with overflow checking
- *
+/**
+ * check_sub_overflow() - Calculate subtraction with overflow checking
  * @a: minuend; value to subtract from
  * @b: subtrahend; value to subtract from @a
  * @d: pointer to store difference
@@ -81,8 +81,8 @@ static inline bool __must_check __must_check_overflow(bool overflow)
 #define check_sub_overflow(a, b, d)    \
        __must_check_overflow(__builtin_sub_overflow(a, b, d))
 
-/** check_mul_overflow() - Calculate multiplication with overflow checking
- *
+/**
+ * check_mul_overflow() - Calculate multiplication with overflow checking
  * @a: first factor
  * @b: second factor
  * @d: pointer to store product
@@ -96,23 +96,24 @@ static inline bool __must_check __must_check_overflow(bool overflow)
 #define check_mul_overflow(a, b, d)    \
        __must_check_overflow(__builtin_mul_overflow(a, b, d))
 
-/** check_shl_overflow() - Calculate a left-shifted value and check overflow
- *
+/**
+ * check_shl_overflow() - Calculate a left-shifted value and check overflow
  * @a: Value to be shifted
  * @s: How many bits left to shift
  * @d: Pointer to where to store the result
  *
  * Computes *@d = (@a << @s)
  *
- * Returns true if '*d' cannot hold the result or when 'a << s' doesn't
+ * Returns true if '*@d' cannot hold the result or when '@a << @s' doesn't
  * make sense. Example conditions:
- * - 'a << s' causes bits to be lost when stored in *d.
- * - 's' is garbage (e.g. negative) or so large that the result of
- *   'a << s' is guaranteed to be 0.
- * - 'a' is negative.
- * - 'a << s' sets the sign bit, if any, in '*d'.
  *
- * '*d' will hold the results of the attempted shift, but is not
+ * - '@a << @s' causes bits to be lost when stored in *@d.
+ * - '@s' is garbage (e.g. negative) or so large that the result of
+ *   '@a << @s' is guaranteed to be 0.
+ * - '@a' is negative.
+ * - '@a << @s' sets the sign bit, if any, in '*@d'.
+ *
+ * '*@d' will hold the results of the attempted shift, but is not
  * considered "safe for use" if true is returned.
  */
 #define check_shl_overflow(a, s, d) __must_check_overflow(({           \
@@ -129,7 +130,6 @@ static inline bool __must_check __must_check_overflow(bool overflow)
 
 /**
  * size_mul() - Calculate size_t multiplication with saturation at SIZE_MAX
- *
  * @factor1: first factor
  * @factor2: second factor
  *
@@ -149,7 +149,6 @@ static inline size_t __must_check size_mul(size_t factor1, size_t factor2)
 
 /**
  * size_add() - Calculate size_t addition with saturation at SIZE_MAX
- *
  * @addend1: first addend
  * @addend2: second addend
  *
@@ -169,7 +168,6 @@ static inline size_t __must_check size_add(size_t addend1, size_t addend2)
 
 /**
  * size_sub() - Calculate size_t subtraction with saturation at SIZE_MAX
- *
  * @minuend: value to subtract from
  * @subtrahend: value to subtract from @minuend
  *
@@ -192,7 +190,6 @@ static inline size_t __must_check size_sub(size_t minuend, size_t subtrahend)
 
 /**
  * array_size() - Calculate size of 2-dimensional array.
- *
  * @a: dimension one
  * @b: dimension two
  *
@@ -205,7 +202,6 @@ static inline size_t __must_check size_sub(size_t minuend, size_t subtrahend)
 
 /**
  * array3_size() - Calculate size of 3-dimensional array.
- *
  * @a: dimension one
  * @b: dimension two
  * @c: dimension three
@@ -220,7 +216,6 @@ static inline size_t __must_check size_sub(size_t minuend, size_t subtrahend)
 /**
  * flex_array_size() - Calculate size of a flexible array member
  *                     within an enclosing structure.
- *
  * @p: Pointer to the structure.
  * @member: Name of the flexible array member.
  * @count: Number of elements in the array.
@@ -237,7 +232,6 @@ static inline size_t __must_check size_sub(size_t minuend, size_t subtrahend)
 
 /**
  * struct_size() - Calculate size of structure with trailing flexible array.
- *
  * @p: Pointer to the structure.
  * @member: Name of the array member.
  * @count: Number of elements in the array.
index 2ba044d..8e984d7 100644 (file)
@@ -225,7 +225,7 @@ static inline void *spi_mem_get_drvdata(struct spi_mem *mem)
 /**
  * struct spi_controller_mem_ops - SPI memory operations
  * @adjust_op_size: shrink the data xfer of an operation to match controller's
- *                 limitations (can be alignment of max RX/TX size
+ *                 limitations (can be alignment or max RX/TX size
  *                 limitations)
  * @supports_op: check if an operation is supported by the controller
  * @exec_op: execute a SPI memory operation
index 3d08e67..9f97f73 100644 (file)
@@ -41,13 +41,21 @@ struct genl_info;
  * @mcgrps: multicast groups used by this family
  * @n_mcgrps: number of multicast groups
  * @resv_start_op: first operation for which reserved fields of the header
- *     can be validated, new families should leave this field at zero
+ *     can be validated and policies are required (see below);
+ *     new families should leave this field at zero
  * @mcgrp_offset: starting number of multicast group IDs in this family
  *     (private)
  * @ops: the operations supported by this family
  * @n_ops: number of operations supported by this family
  * @small_ops: the small-struct operations supported by this family
  * @n_small_ops: number of small-struct operations supported by this family
+ *
+ * Attribute policies (the combination of @policy and @maxattr fields)
+ * can be attached at the family level or at the operation level.
+ * If both are present the per-operation policy takes precedence.
+ * For operations before @resv_start_op lack of policy means that the core
+ * will perform no attribute parsing or validation. For newer operations
+ * if policy is not provided core will reject all TLV attributes.
  */
 struct genl_family {
        int                     id;             /* private */
index 9e464f6..22f8bab 100644 (file)
@@ -2585,7 +2585,7 @@ static inline gfp_t gfp_any(void)
 
 static inline gfp_t gfp_memcg_charge(void)
 {
-       return in_softirq() ? GFP_NOWAIT : GFP_KERNEL;
+       return in_softirq() ? GFP_ATOMIC : GFP_KERNEL;
 }
 
 static inline long sock_rcvtimeo(const struct sock *sk, bool noblock)
index eae443b..cc3dcc6 100644 (file)
@@ -138,6 +138,7 @@ int snd_ctl_remove(struct snd_card * card, struct snd_kcontrol * kcontrol);
 int snd_ctl_replace(struct snd_card *card, struct snd_kcontrol *kcontrol, bool add_on_replace);
 int snd_ctl_remove_id(struct snd_card * card, struct snd_ctl_elem_id *id);
 int snd_ctl_rename_id(struct snd_card * card, struct snd_ctl_elem_id *src_id, struct snd_ctl_elem_id *dst_id);
+void snd_ctl_rename(struct snd_card *card, struct snd_kcontrol *kctl, const char *name);
 int snd_ctl_activate_id(struct snd_card *card, struct snd_ctl_elem_id *id, int active);
 struct snd_kcontrol *snd_ctl_find_numid(struct snd_card * card, unsigned int numid);
 struct snd_kcontrol *snd_ctl_find_id(struct snd_card * card, struct snd_ctl_elem_id *id);
index a0b827f..25e049f 100644 (file)
@@ -177,6 +177,7 @@ void asoc_simple_convert_fixup(struct asoc_simple_data *data,
                                      struct snd_pcm_hw_params *params);
 void asoc_simple_parse_convert(struct device_node *np, char *prefix,
                               struct asoc_simple_data *data);
+bool asoc_simple_is_convert_required(const struct asoc_simple_data *data);
 
 int asoc_simple_parse_routing(struct snd_soc_card *card,
                                      char *prefix);
index 7ee65c0..0d93ec1 100644 (file)
@@ -763,6 +763,8 @@ struct drm_amdgpu_cs_chunk_data {
        #define AMDGPU_INFO_FW_MES_KIQ          0x19
        /* Subquery id: Query MES firmware version */
        #define AMDGPU_INFO_FW_MES              0x1a
+       /* Subquery id: Query IMU firmware version */
+       #define AMDGPU_INFO_FW_IMU              0x1b
 
 /* number of bytes moved for TTM migration */
 #define AMDGPU_INFO_NUM_BYTES_MOVED            0x0f
index 86cae23..29da1f4 100644 (file)
@@ -1601,7 +1601,8 @@ struct v4l2_bt_timings {
        ((bt)->width + V4L2_DV_BT_BLANKING_WIDTH(bt))
 #define V4L2_DV_BT_BLANKING_HEIGHT(bt) \
        ((bt)->vfrontporch + (bt)->vsync + (bt)->vbackporch + \
-        (bt)->il_vfrontporch + (bt)->il_vsync + (bt)->il_vbackporch)
+        ((bt)->interlaced ? \
+         ((bt)->il_vfrontporch + (bt)->il_vsync + (bt)->il_vbackporch) : 0))
 #define V4L2_DV_BT_FRAME_HEIGHT(bt) \
        ((bt)->height + V4L2_DV_BT_BLANKING_HEIGHT(bt))
 
index eba603c..35c07af 100644 (file)
@@ -4436,6 +4436,11 @@ static int btf_func_proto_check(struct btf_verifier_env *env,
                        return -EINVAL;
                }
 
+               if (btf_type_is_resolve_source_only(ret_type)) {
+                       btf_verifier_log_type(env, t, "Invalid return type");
+                       return -EINVAL;
+               }
+
                if (btf_type_needs_resolve(ret_type) &&
                    !env_type_is_resolved(env, ret_type_id)) {
                        err = btf_resolve(env, ret_type, ret_type_id);
index fa64b80..04f0a04 100644 (file)
@@ -4,6 +4,7 @@
 #include <linux/hash.h>
 #include <linux/bpf.h>
 #include <linux/filter.h>
+#include <linux/init.h>
 
 /* The BPF dispatcher is a multiway branch code generator. The
  * dispatcher is a mechanism to avoid the performance penalty of an
@@ -90,6 +91,11 @@ int __weak arch_prepare_bpf_dispatcher(void *image, void *buf, s64 *funcs, int n
        return -ENOTSUPP;
 }
 
+int __weak __init bpf_arch_init_dispatcher_early(void *ip)
+{
+       return -ENOTSUPP;
+}
+
 static int bpf_dispatcher_prepare(struct bpf_dispatcher *d, void *image, void *buf)
 {
        s64 ips[BPF_DISPATCHER_MAX] = {}, *ipsp = &ips[0];
index 5f83be1..4901fa1 100644 (file)
@@ -418,14 +418,17 @@ static void drain_mem_cache(struct bpf_mem_cache *c)
        /* No progs are using this bpf_mem_cache, but htab_map_free() called
         * bpf_mem_cache_free() for all remaining elements and they can be in
         * free_by_rcu or in waiting_for_gp lists, so drain those lists now.
+        *
+        * Except for waiting_for_gp list, there are no concurrent operations
+        * on these lists, so it is safe to use __llist_del_all().
         */
        llist_for_each_safe(llnode, t, __llist_del_all(&c->free_by_rcu))
                free_one(c, llnode);
        llist_for_each_safe(llnode, t, llist_del_all(&c->waiting_for_gp))
                free_one(c, llnode);
-       llist_for_each_safe(llnode, t, llist_del_all(&c->free_llist))
+       llist_for_each_safe(llnode, t, __llist_del_all(&c->free_llist))
                free_one(c, llnode);
-       llist_for_each_safe(llnode, t, llist_del_all(&c->free_llist_extra))
+       llist_for_each_safe(llnode, t, __llist_del_all(&c->free_llist_extra))
                free_one(c, llnode);
 }
 
@@ -493,6 +496,16 @@ void bpf_mem_alloc_destroy(struct bpf_mem_alloc *ma)
                rcu_in_progress = 0;
                for_each_possible_cpu(cpu) {
                        c = per_cpu_ptr(ma->cache, cpu);
+                       /*
+                        * refill_work may be unfinished for PREEMPT_RT kernel
+                        * in which irq work is invoked in a per-CPU RT thread.
+                        * It is also possible for kernel with
+                        * arch_irq_work_has_interrupt() being false and irq
+                        * work is invoked in timer interrupt. So waiting for
+                        * the completion of irq work to ease the handling of
+                        * concurrency.
+                        */
+                       irq_work_sync(&c->refill_work);
                        drain_mem_cache(c);
                        rcu_in_progress += atomic_read(&c->call_rcu_in_progress);
                }
@@ -507,6 +520,7 @@ void bpf_mem_alloc_destroy(struct bpf_mem_alloc *ma)
                        cc = per_cpu_ptr(ma->caches, cpu);
                        for (i = 0; i < NUM_CACHES; i++) {
                                c = &cc->cache[i];
+                               irq_work_sync(&c->refill_work);
                                drain_mem_cache(c);
                                rcu_in_progress += atomic_read(&c->call_rcu_in_progress);
                        }
index 014ee09..7f0a9f6 100644 (file)
@@ -6946,6 +6946,7 @@ static int set_user_ringbuf_callback_state(struct bpf_verifier_env *env,
        __mark_reg_not_init(env, &callee->regs[BPF_REG_5]);
 
        callee->in_callback_fn = true;
+       callee->callback_ret_range = tnum_range(0, 1);
        return 0;
 }
 
index f58a0aa..793c55a 100644 (file)
@@ -645,7 +645,7 @@ static void power_down(void)
        int error;
 
        if (hibernation_mode == HIBERNATION_SUSPEND) {
-               error = suspend_devices_and_enter(PM_SUSPEND_MEM);
+               error = suspend_devices_and_enter(mem_sleep_current);
                if (error) {
                        hibernation_mode = hibernation_ops ?
                                                HIBERNATION_PLATFORM :
index 6bb8e72..93416af 100644 (file)
@@ -1403,30 +1403,32 @@ static void rcu_poll_gp_seq_end(unsigned long *snap)
 // where caller does not hold the root rcu_node structure's lock.
 static void rcu_poll_gp_seq_start_unlocked(unsigned long *snap)
 {
+       unsigned long flags;
        struct rcu_node *rnp = rcu_get_root();
 
        if (rcu_init_invoked()) {
                lockdep_assert_irqs_enabled();
-               raw_spin_lock_irq_rcu_node(rnp);
+               raw_spin_lock_irqsave_rcu_node(rnp, flags);
        }
        rcu_poll_gp_seq_start(snap);
        if (rcu_init_invoked())
-               raw_spin_unlock_irq_rcu_node(rnp);
+               raw_spin_unlock_irqrestore_rcu_node(rnp, flags);
 }
 
 // Make the polled API aware of the end of a grace period, but where
 // caller does not hold the root rcu_node structure's lock.
 static void rcu_poll_gp_seq_end_unlocked(unsigned long *snap)
 {
+       unsigned long flags;
        struct rcu_node *rnp = rcu_get_root();
 
        if (rcu_init_invoked()) {
                lockdep_assert_irqs_enabled();
-               raw_spin_lock_irq_rcu_node(rnp);
+               raw_spin_lock_irqsave_rcu_node(rnp, flags);
        }
        rcu_poll_gp_seq_end(snap);
        if (rcu_init_invoked())
-               raw_spin_unlock_irq_rcu_node(rnp);
+               raw_spin_unlock_irqrestore_rcu_node(rnp, flags);
 }
 
 /*
index f5ae79c..a608746 100644 (file)
@@ -56,8 +56,8 @@ int string_stream_vadd(struct string_stream *stream,
        frag_container = alloc_string_stream_fragment(stream->test,
                                                      len,
                                                      stream->gfp);
-       if (!frag_container)
-               return -ENOMEM;
+       if (IS_ERR(frag_container))
+               return PTR_ERR(frag_container);
 
        len = vsnprintf(frag_container->fragment, len, fmt, args);
        spin_lock(&stream->lock);
index 90640a4..2a6992f 100644 (file)
@@ -265,7 +265,7 @@ static void kunit_fail(struct kunit *test, const struct kunit_loc *loc,
        kunit_set_failure(test);
 
        stream = alloc_string_stream(test, GFP_KERNEL);
-       if (!stream) {
+       if (IS_ERR(stream)) {
                WARN(true,
                     "Could not allocate stream to print failed assertion in %s:%d\n",
                     loc->file,
index 5369634..b8556a2 100644 (file)
 #include <linux/types.h>
 #include <linux/vmalloc.h>
 
+#define SKIP(cond, reason)             do {                    \
+       if (cond) {                                             \
+               kunit_skip(test, reason);                       \
+               return;                                         \
+       }                                                       \
+} while (0)
+
+/*
+ * Clang 11 and earlier generate unwanted libcalls for signed output
+ * on unsigned input.
+ */
+#if defined(CONFIG_CC_IS_CLANG) && __clang_major__ <= 11
+# define SKIP_SIGN_MISMATCH(t) SKIP(t, "Clang 11 unwanted libcalls")
+#else
+# define SKIP_SIGN_MISMATCH(t) do { } while (0)
+#endif
+
+/*
+ * Clang 13 and earlier generate unwanted libcalls for 64-bit tests on
+ * 32-bit hosts.
+ */
+#if defined(CONFIG_CC_IS_CLANG) && __clang_major__ <= 13 &&    \
+    BITS_PER_LONG != 64
+# define SKIP_64_ON_32(t)      SKIP(t, "Clang 13 unwanted libcalls")
+#else
+# define SKIP_64_ON_32(t)      do { } while (0)
+#endif
+
 #define DEFINE_TEST_ARRAY_TYPED(t1, t2, t)                     \
        static const struct test_ ## t1 ## _ ## t2 ## __ ## t { \
                t1 a;                                           \
@@ -94,7 +122,6 @@ DEFINE_TEST_ARRAY(u32) = {
        {-4U, 5U, 1U, -9U, -20U, true, false, true},
 };
 
-#if BITS_PER_LONG == 64
 DEFINE_TEST_ARRAY(u64) = {
        {0, 0, 0, 0, 0, false, false, false},
        {1, 1, 2, 0, 1, false, false, false},
@@ -118,7 +145,6 @@ DEFINE_TEST_ARRAY(u64) = {
         false, true, false},
        {-15ULL, 10ULL, -5ULL, -25ULL, -150ULL, false, false, true},
 };
-#endif
 
 DEFINE_TEST_ARRAY(s8) = {
        {0, 0, 0, 0, 0, false, false, false},
@@ -194,7 +220,6 @@ DEFINE_TEST_ARRAY(s32) = {
        {S32_MAX, S32_MAX, -2, 0, 1, true, false, true},
 };
 
-#if BITS_PER_LONG == 64
 DEFINE_TEST_ARRAY(s64) = {
        {0, 0, 0, 0, 0, false, false, false},
 
@@ -223,7 +248,6 @@ DEFINE_TEST_ARRAY(s64) = {
        {-128, -1, -129, -127, 128, false, false, false},
        {0, -S64_MAX, -S64_MAX, S64_MAX, 0, false, false, false},
 };
-#endif
 
 #define check_one_op(t, fmt, op, sym, a, b, r, of) do {                        \
        int _a_orig = a, _a_bump = a + 1;                               \
@@ -246,7 +270,7 @@ DEFINE_TEST_ARRAY(s64) = {
 
 #define DEFINE_TEST_FUNC_TYPED(n, t, fmt)                              \
 static void do_test_ ## n(struct kunit *test, const struct test_ ## n *p) \
-{                                                                      \
+{                                                                      \
        check_one_op(t, fmt, add, "+", p->a, p->b, p->sum, p->s_of);    \
        check_one_op(t, fmt, add, "+", p->b, p->a, p->sum, p->s_of);    \
        check_one_op(t, fmt, sub, "-", p->a, p->b, p->diff, p->d_of);   \
@@ -257,6 +281,12 @@ static void do_test_ ## n(struct kunit *test, const struct test_ ## n *p) \
 static void n ## _overflow_test(struct kunit *test) {                  \
        unsigned i;                                                     \
                                                                        \
+       SKIP_64_ON_32(__same_type(t, u64));                             \
+       SKIP_64_ON_32(__same_type(t, s64));                             \
+       SKIP_SIGN_MISMATCH(__same_type(n ## _tests[0].a, u32) &&        \
+                          __same_type(n ## _tests[0].b, u32) &&        \
+                          __same_type(n ## _tests[0].sum, int));       \
+                                                                       \
        for (i = 0; i < ARRAY_SIZE(n ## _tests); ++i)                   \
                do_test_ ## n(test, &n ## _tests[i]);                   \
        kunit_info(test, "%zu %s arithmetic tests finished\n",          \
@@ -272,10 +302,8 @@ DEFINE_TEST_FUNC(u16, "%d");
 DEFINE_TEST_FUNC(s16, "%d");
 DEFINE_TEST_FUNC(u32, "%u");
 DEFINE_TEST_FUNC(s32, "%d");
-#if BITS_PER_LONG == 64
 DEFINE_TEST_FUNC(u64, "%llu");
 DEFINE_TEST_FUNC(s64, "%lld");
-#endif
 
 DEFINE_TEST_ARRAY_TYPED(u32, u32, u8) = {
        {0, 0, 0, 0, 0, false, false, false},
@@ -715,13 +743,10 @@ static struct kunit_case overflow_test_cases[] = {
        KUNIT_CASE(s16_s16__s16_overflow_test),
        KUNIT_CASE(u32_u32__u32_overflow_test),
        KUNIT_CASE(s32_s32__s32_overflow_test),
-/* Clang 13 and earlier generate unwanted libcalls on 32-bit. */
-#if BITS_PER_LONG == 64
        KUNIT_CASE(u64_u64__u64_overflow_test),
        KUNIT_CASE(s64_s64__s64_overflow_test),
-#endif
-       KUNIT_CASE(u32_u32__u8_overflow_test),
        KUNIT_CASE(u32_u32__int_overflow_test),
+       KUNIT_CASE(u32_u32__u8_overflow_test),
        KUNIT_CASE(u8_u8__int_overflow_test),
        KUNIT_CASE(int_int__u8_overflow_test),
        KUNIT_CASE(shift_sane_test),
index b358a74..f2ba578 100644 (file)
@@ -369,18 +369,10 @@ static int __init test_rhltable(unsigned int entries)
        pr_info("test %d random rhlist add/delete operations\n", entries);
        for (j = 0; j < entries; j++) {
                u32 i = prandom_u32_max(entries);
-               u32 prand = get_random_u32();
+               u32 prand = prandom_u32_max(4);
 
                cond_resched();
 
-               if (prand == 0)
-                       prand = get_random_u32();
-
-               if (prand & 1) {
-                       prand >>= 1;
-                       continue;
-               }
-
                err = rhltable_remove(&rhlt, &rhl_test_objects[i].list_node, test_rht_params);
                if (test_bit(i, obj_in_table)) {
                        clear_bit(i, obj_in_table);
@@ -393,35 +385,29 @@ static int __init test_rhltable(unsigned int entries)
                }
 
                if (prand & 1) {
-                       prand >>= 1;
-                       continue;
-               }
-
-               err = rhltable_insert(&rhlt, &rhl_test_objects[i].list_node, test_rht_params);
-               if (err == 0) {
-                       if (WARN(test_and_set_bit(i, obj_in_table), "succeeded to insert same object %d", i))
-                               continue;
-               } else {
-                       if (WARN(!test_bit(i, obj_in_table), "failed to insert object %d", i))
-                               continue;
-               }
-
-               if (prand & 1) {
-                       prand >>= 1;
-                       continue;
+                       err = rhltable_insert(&rhlt, &rhl_test_objects[i].list_node, test_rht_params);
+                       if (err == 0) {
+                               if (WARN(test_and_set_bit(i, obj_in_table), "succeeded to insert same object %d", i))
+                                       continue;
+                       } else {
+                               if (WARN(!test_bit(i, obj_in_table), "failed to insert object %d", i))
+                                       continue;
+                       }
                }
 
-               i = prandom_u32_max(entries);
-               if (test_bit(i, obj_in_table)) {
-                       err = rhltable_remove(&rhlt, &rhl_test_objects[i].list_node, test_rht_params);
-                       WARN(err, "cannot remove element at slot %d", i);
-                       if (err == 0)
-                               clear_bit(i, obj_in_table);
-               } else {
-                       err = rhltable_insert(&rhlt, &rhl_test_objects[i].list_node, test_rht_params);
-                       WARN(err, "failed to insert object %d", i);
-                       if (err == 0)
-                               set_bit(i, obj_in_table);
+               if (prand & 2) {
+                       i = prandom_u32_max(entries);
+                       if (test_bit(i, obj_in_table)) {
+                               err = rhltable_remove(&rhlt, &rhl_test_objects[i].list_node, test_rht_params);
+                               WARN(err, "cannot remove element at slot %d", i);
+                               if (err == 0)
+                                       clear_bit(i, obj_in_table);
+                       } else {
+                               err = rhltable_insert(&rhlt, &rhl_test_objects[i].list_node, test_rht_params);
+                               WARN(err, "failed to insert object %d", i);
+                               if (err == 0)
+                                       set_bit(i, obj_in_table);
+                       }
                }
        }
 
index d7d86c9..55f29c9 100644 (file)
@@ -342,10 +342,12 @@ static void j1939_session_skb_drop_old(struct j1939_session *session)
                __skb_unlink(do_skb, &session->skb_queue);
                /* drop ref taken in j1939_session_skb_queue() */
                skb_unref(do_skb);
+               spin_unlock_irqrestore(&session->skb_queue.lock, flags);
 
                kfree_skb(do_skb);
+       } else {
+               spin_unlock_irqrestore(&session->skb_queue.lock, flags);
        }
-       spin_unlock_irqrestore(&session->skb_queue.lock, flags);
 }
 
 void j1939_session_skb_queue(struct j1939_session *session,
index 0ec2f59..f64654d 100644 (file)
@@ -117,6 +117,7 @@ static int net_assign_generic(struct net *net, unsigned int id, void *data)
 
 static int ops_init(const struct pernet_operations *ops, struct net *net)
 {
+       struct net_generic *ng;
        int err = -ENOMEM;
        void *data = NULL;
 
@@ -135,7 +136,13 @@ static int ops_init(const struct pernet_operations *ops, struct net *net)
        if (!err)
                return 0;
 
+       if (ops->id && ops->size) {
 cleanup:
+               ng = rcu_dereference_protected(net->gen,
+                                              lockdep_is_held(&pernet_ops_rwsem));
+               ng->ptr[*ops->id] = NULL;
+       }
+
        kfree(data);
 
 out:
index 1d9719e..d1a3fa6 100644 (file)
@@ -3971,7 +3971,7 @@ int skb_append_pagefrags(struct sk_buff *skb, struct page *page,
        } else if (i < MAX_SKB_FRAGS) {
                skb_zcopy_downgrade_managed(skb);
                get_page(page);
-               skb_fill_page_desc(skb, i, page, offset, size);
+               skb_fill_page_desc_noacc(skb, i, page, offset, size);
        } else {
                return -EMSGSIZE;
        }
index 1c94bb8..49c0a2a 100644 (file)
@@ -124,7 +124,7 @@ static int eeprom_prepare_data(const struct ethnl_req_info *req_base,
        if (ret)
                goto err_free;
 
-       ret = get_module_eeprom_by_page(dev, &page_data, info->extack);
+       ret = get_module_eeprom_by_page(dev, &page_data, info ? info->extack : NULL);
        if (ret < 0)
                goto err_ops;
 
index 5a471e1..e8683e4 100644 (file)
@@ -64,7 +64,7 @@ static int pse_prepare_data(const struct ethnl_req_info *req_base,
        if (ret < 0)
                return ret;
 
-       ret = pse_get_pse_attributes(dev, info->extack, data);
+       ret = pse_get_pse_attributes(dev, info ? info->extack : NULL, data);
 
        ethnl_ops_complete(dev);
 
index 6e55fae..1fa2fe0 100644 (file)
@@ -502,8 +502,10 @@ static int dgram_bind(struct sock *sk, struct sockaddr *uaddr, int len)
        if (err < 0)
                goto out;
 
-       if (addr->family != AF_IEEE802154)
+       if (addr->family != AF_IEEE802154) {
+               err = -EINVAL;
                goto out;
+       }
 
        ieee802154_addr_from_sa(&haddr, &addr->addr);
        dev = ieee802154_get_dev(sock_net(sk), &haddr);
index 943edf4..f361d3d 100644 (file)
@@ -389,7 +389,7 @@ static int __fib_validate_source(struct sk_buff *skb, __be32 src, __be32 dst,
        dev_match = dev_match || (res.type == RTN_LOCAL &&
                                  dev == net->loopback_dev);
        if (dev_match) {
-               ret = FIB_RES_NHC(res)->nhc_scope >= RT_SCOPE_LINK;
+               ret = FIB_RES_NHC(res)->nhc_scope >= RT_SCOPE_HOST;
                return ret;
        }
        if (no_addr)
@@ -401,7 +401,7 @@ static int __fib_validate_source(struct sk_buff *skb, __be32 src, __be32 dst,
        ret = 0;
        if (fib_lookup(net, &fl4, &res, FIB_LOOKUP_IGNORE_LINKSTATE) == 0) {
                if (res.type == RTN_UNICAST)
-                       ret = FIB_RES_NHC(res)->nhc_scope >= RT_SCOPE_LINK;
+                       ret = FIB_RES_NHC(res)->nhc_scope >= RT_SCOPE_HOST;
        }
        return ret;
 
index e9a7f70..f721c30 100644 (file)
@@ -1231,7 +1231,7 @@ static int fib_check_nh_nongw(struct net *net, struct fib_nh *nh,
 
        nh->fib_nh_dev = in_dev->dev;
        netdev_hold(nh->fib_nh_dev, &nh->fib_nh_dev_tracker, GFP_ATOMIC);
-       nh->fib_nh_scope = RT_SCOPE_LINK;
+       nh->fib_nh_scope = RT_SCOPE_HOST;
        if (!netif_carrier_ok(nh->fib_nh_dev))
                nh->fib_nh_flags |= RTNH_F_LINKDOWN;
        err = 0;
index 853a75a..d8ef053 100644 (file)
@@ -2534,7 +2534,7 @@ static int nh_create_ipv4(struct net *net, struct nexthop *nh,
        if (!err) {
                nh->nh_flags = fib_nh->fib_nh_flags;
                fib_info_update_nhc_saddr(net, &fib_nh->nh_common,
-                                         fib_nh->fib_nh_scope);
+                                         !fib_nh->fib_nh_scope ? 0 : fib_nh->fib_nh_scope - 1);
        } else {
                fib_nh_release(net, fib_nh);
        }
index bc2ea12..0640453 100644 (file)
@@ -2192,7 +2192,8 @@ void tcp_enter_loss(struct sock *sk)
  */
 static bool tcp_check_sack_reneging(struct sock *sk, int flag)
 {
-       if (flag & FLAG_SACK_RENEGING) {
+       if (flag & FLAG_SACK_RENEGING &&
+           flag & FLAG_SND_UNA_ADVANCED) {
                struct tcp_sock *tp = tcp_sk(sk);
                unsigned long delay = max(usecs_to_jiffies(tp->srtt_us >> 4),
                                          msecs_to_jiffies(10));
index 7a250ef..87d440f 100644 (file)
@@ -1874,11 +1874,13 @@ bool tcp_add_backlog(struct sock *sk, struct sk_buff *skb,
        __skb_push(skb, hdrlen);
 
 no_coalesce:
+       limit = (u32)READ_ONCE(sk->sk_rcvbuf) + (u32)(READ_ONCE(sk->sk_sndbuf) >> 1);
+
        /* Only socket owner can try to collapse/prune rx queues
         * to reduce memory overhead, so add a little headroom here.
         * Few sockets backlog are possibly concurrently non empty.
         */
-       limit = READ_ONCE(sk->sk_rcvbuf) + READ_ONCE(sk->sk_sndbuf) + 64*1024;
+       limit += 64 * 1024;
 
        if (unlikely(sk_add_backlog(sk, skb, limit))) {
                bh_unlock_sock(sk);
index 48b4ff0..c035a96 100644 (file)
@@ -1175,14 +1175,16 @@ static void ip6gre_tnl_link_config_route(struct ip6_tnl *t, int set_mtu,
                                dev->needed_headroom = dst_len;
 
                        if (set_mtu) {
-                               dev->mtu = rt->dst.dev->mtu - t_hlen;
+                               int mtu = rt->dst.dev->mtu - t_hlen;
+
                                if (!(t->parms.flags & IP6_TNL_F_IGN_ENCAP_LIMIT))
-                                       dev->mtu -= 8;
+                                       mtu -= 8;
                                if (dev->type == ARPHRD_ETHER)
-                                       dev->mtu -= ETH_HLEN;
+                                       mtu -= ETH_HLEN;
 
-                               if (dev->mtu < IPV6_MIN_MTU)
-                                       dev->mtu = IPV6_MIN_MTU;
+                               if (mtu < IPV6_MIN_MTU)
+                                       mtu = IPV6_MIN_MTU;
+                               WRITE_ONCE(dev->mtu, mtu);
                        }
                }
                ip6_rt_put(rt);
index cc5d5e7..2fb4c6a 100644 (file)
@@ -1450,8 +1450,8 @@ static void ip6_tnl_link_config(struct ip6_tnl *t)
        struct net_device *tdev = NULL;
        struct __ip6_tnl_parm *p = &t->parms;
        struct flowi6 *fl6 = &t->fl.u.ip6;
-       unsigned int mtu;
        int t_hlen;
+       int mtu;
 
        __dev_addr_set(dev, &p->laddr, sizeof(struct in6_addr));
        memcpy(dev->broadcast, &p->raddr, sizeof(struct in6_addr));
@@ -1498,12 +1498,13 @@ static void ip6_tnl_link_config(struct ip6_tnl *t)
                        dev->hard_header_len = tdev->hard_header_len + t_hlen;
                        mtu = min_t(unsigned int, tdev->mtu, IP6_MAX_MTU);
 
-                       dev->mtu = mtu - t_hlen;
+                       mtu = mtu - t_hlen;
                        if (!(t->parms.flags & IP6_TNL_F_IGN_ENCAP_LIMIT))
-                               dev->mtu -= 8;
+                               mtu -= 8;
 
-                       if (dev->mtu < IPV6_MIN_MTU)
-                               dev->mtu = IPV6_MIN_MTU;
+                       if (mtu < IPV6_MIN_MTU)
+                               mtu = IPV6_MIN_MTU;
+                       WRITE_ONCE(dev->mtu, mtu);
                }
        }
 }
index d27683e..5703d3c 100644 (file)
@@ -1124,10 +1124,12 @@ static void ipip6_tunnel_bind_dev(struct net_device *dev)
 
        if (tdev && !netif_is_l3_master(tdev)) {
                int t_hlen = tunnel->hlen + sizeof(struct iphdr);
+               int mtu;
 
-               dev->mtu = tdev->mtu - t_hlen;
-               if (dev->mtu < IPV6_MIN_MTU)
-                       dev->mtu = IPV6_MIN_MTU;
+               mtu = tdev->mtu - t_hlen;
+               if (mtu < IPV6_MIN_MTU)
+                       mtu = IPV6_MIN_MTU;
+               WRITE_ONCE(dev->mtu, mtu);
        }
 }
 
index 2772546..a500422 100644 (file)
@@ -162,7 +162,8 @@ static void kcm_rcv_ready(struct kcm_sock *kcm)
        /* Buffer limit is okay now, add to ready list */
        list_add_tail(&kcm->wait_rx_list,
                      &kcm->mux->kcm_rx_waiters);
-       kcm->rx_wait = true;
+       /* paired with lockless reads in kcm_rfree() */
+       WRITE_ONCE(kcm->rx_wait, true);
 }
 
 static void kcm_rfree(struct sk_buff *skb)
@@ -178,7 +179,7 @@ static void kcm_rfree(struct sk_buff *skb)
        /* For reading rx_wait and rx_psock without holding lock */
        smp_mb__after_atomic();
 
-       if (!kcm->rx_wait && !kcm->rx_psock &&
+       if (!READ_ONCE(kcm->rx_wait) && !READ_ONCE(kcm->rx_psock) &&
            sk_rmem_alloc_get(sk) < sk->sk_rcvlowat) {
                spin_lock_bh(&mux->rx_lock);
                kcm_rcv_ready(kcm);
@@ -237,7 +238,8 @@ try_again:
                if (kcm_queue_rcv_skb(&kcm->sk, skb)) {
                        /* Should mean socket buffer full */
                        list_del(&kcm->wait_rx_list);
-                       kcm->rx_wait = false;
+                       /* paired with lockless reads in kcm_rfree() */
+                       WRITE_ONCE(kcm->rx_wait, false);
 
                        /* Commit rx_wait to read in kcm_free */
                        smp_wmb();
@@ -280,10 +282,12 @@ static struct kcm_sock *reserve_rx_kcm(struct kcm_psock *psock,
        kcm = list_first_entry(&mux->kcm_rx_waiters,
                               struct kcm_sock, wait_rx_list);
        list_del(&kcm->wait_rx_list);
-       kcm->rx_wait = false;
+       /* paired with lockless reads in kcm_rfree() */
+       WRITE_ONCE(kcm->rx_wait, false);
 
        psock->rx_kcm = kcm;
-       kcm->rx_psock = psock;
+       /* paired with lockless reads in kcm_rfree() */
+       WRITE_ONCE(kcm->rx_psock, psock);
 
        spin_unlock_bh(&mux->rx_lock);
 
@@ -310,7 +314,8 @@ static void unreserve_rx_kcm(struct kcm_psock *psock,
        spin_lock_bh(&mux->rx_lock);
 
        psock->rx_kcm = NULL;
-       kcm->rx_psock = NULL;
+       /* paired with lockless reads in kcm_rfree() */
+       WRITE_ONCE(kcm->rx_psock, NULL);
 
        /* Commit kcm->rx_psock before sk_rmem_alloc_get to sync with
         * kcm_rfree
@@ -834,7 +839,7 @@ static ssize_t kcm_sendpage(struct socket *sock, struct page *page,
        }
 
        get_page(page);
-       skb_fill_page_desc(skb, i, page, offset, size);
+       skb_fill_page_desc_noacc(skb, i, page, offset, size);
        skb_shinfo(skb)->flags |= SKBFL_SHARED_FRAG;
 
 coalesced:
@@ -1240,7 +1245,8 @@ static void kcm_recv_disable(struct kcm_sock *kcm)
        if (!kcm->rx_psock) {
                if (kcm->rx_wait) {
                        list_del(&kcm->wait_rx_list);
-                       kcm->rx_wait = false;
+                       /* paired with lockless reads in kcm_rfree() */
+                       WRITE_ONCE(kcm->rx_wait, false);
                }
 
                requeue_rx_msgs(mux, &kcm->sk.sk_receive_queue);
@@ -1793,7 +1799,8 @@ static void kcm_done(struct kcm_sock *kcm)
 
        if (kcm->rx_wait) {
                list_del(&kcm->wait_rx_list);
-               kcm->rx_wait = false;
+               /* paired with lockless reads in kcm_rfree() */
+               WRITE_ONCE(kcm->rx_wait, false);
        }
        /* Move any pending receive messages to other kcm sockets */
        requeue_rx_msgs(mux, &sk->sk_receive_queue);
index c439125..726b47a 100644 (file)
@@ -132,7 +132,7 @@ static int
 ieee802154_parse_frame_start(struct sk_buff *skb, struct ieee802154_hdr *hdr)
 {
        int hlen;
-       struct ieee802154_mac_cb *cb = mac_cb_init(skb);
+       struct ieee802154_mac_cb *cb = mac_cb(skb);
 
        skb_reset_mac_header(skb);
 
@@ -294,8 +294,9 @@ void
 ieee802154_rx_irqsafe(struct ieee802154_hw *hw, struct sk_buff *skb, u8 lqi)
 {
        struct ieee802154_local *local = hw_to_local(hw);
+       struct ieee802154_mac_cb *cb = mac_cb_init(skb);
 
-       mac_cb(skb)->lqi = lqi;
+       cb->lqi = lqi;
        skb->pkt_type = IEEE802154_RX_MSG;
        skb_queue_tail(&local->skb_queue, skb);
        tasklet_schedule(&local->tasklet);
index f599ad4..b6dc6e2 100644 (file)
@@ -1673,6 +1673,37 @@ static void mptcp_set_nospace(struct sock *sk)
        set_bit(MPTCP_NOSPACE, &mptcp_sk(sk)->flags);
 }
 
+static int mptcp_sendmsg_fastopen(struct sock *sk, struct sock *ssk, struct msghdr *msg,
+                                 size_t len, int *copied_syn)
+{
+       unsigned int saved_flags = msg->msg_flags;
+       struct mptcp_sock *msk = mptcp_sk(sk);
+       int ret;
+
+       lock_sock(ssk);
+       msg->msg_flags |= MSG_DONTWAIT;
+       msk->connect_flags = O_NONBLOCK;
+       msk->is_sendmsg = 1;
+       ret = tcp_sendmsg_fastopen(ssk, msg, copied_syn, len, NULL);
+       msk->is_sendmsg = 0;
+       msg->msg_flags = saved_flags;
+       release_sock(ssk);
+
+       /* do the blocking bits of inet_stream_connect outside the ssk socket lock */
+       if (ret == -EINPROGRESS && !(msg->msg_flags & MSG_DONTWAIT)) {
+               ret = __inet_stream_connect(sk->sk_socket, msg->msg_name,
+                                           msg->msg_namelen, msg->msg_flags, 1);
+
+               /* Keep the same behaviour of plain TCP: zero the copied bytes in
+                * case of any error, except timeout or signal
+                */
+               if (ret && ret != -EINPROGRESS && ret != -ERESTARTSYS && ret != -EINTR)
+                       *copied_syn = 0;
+       }
+
+       return ret;
+}
+
 static int mptcp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
 {
        struct mptcp_sock *msk = mptcp_sk(sk);
@@ -1693,23 +1724,14 @@ static int mptcp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
 
        ssock = __mptcp_nmpc_socket(msk);
        if (unlikely(ssock && inet_sk(ssock->sk)->defer_connect)) {
-               struct sock *ssk = ssock->sk;
                int copied_syn = 0;
 
-               lock_sock(ssk);
-
-               ret = tcp_sendmsg_fastopen(ssk, msg, &copied_syn, len, NULL);
+               ret = mptcp_sendmsg_fastopen(sk, ssock->sk, msg, len, &copied_syn);
                copied += copied_syn;
-               if (ret == -EINPROGRESS && copied_syn > 0) {
-                       /* reflect the new state on the MPTCP socket */
-                       inet_sk_state_store(sk, inet_sk_state_load(ssk));
-                       release_sock(ssk);
+               if (ret == -EINPROGRESS && copied_syn > 0)
                        goto out;
-               } else if (ret) {
-                       release_sock(ssk);
+               else if (ret)
                        goto do_error;
-               }
-               release_sock(ssk);
        }
 
        timeo = sock_sndtimeo(sk, msg->msg_flags & MSG_DONTWAIT);
@@ -2952,7 +2974,7 @@ static void mptcp_close(struct sock *sk, long timeout)
        sock_put(sk);
 }
 
-static void mptcp_copy_inaddrs(struct sock *msk, const struct sock *ssk)
+void mptcp_copy_inaddrs(struct sock *msk, const struct sock *ssk)
 {
 #if IS_ENABLED(CONFIG_MPTCP_IPV6)
        const struct ipv6_pinfo *ssk6 = inet6_sk(ssk);
@@ -3507,10 +3529,73 @@ static int mptcp_ioctl(struct sock *sk, int cmd, unsigned long arg)
        return put_user(answ, (int __user *)arg);
 }
 
+static void mptcp_subflow_early_fallback(struct mptcp_sock *msk,
+                                        struct mptcp_subflow_context *subflow)
+{
+       subflow->request_mptcp = 0;
+       __mptcp_do_fallback(msk);
+}
+
+static int mptcp_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
+{
+       struct mptcp_subflow_context *subflow;
+       struct mptcp_sock *msk = mptcp_sk(sk);
+       struct socket *ssock;
+       int err = -EINVAL;
+
+       ssock = __mptcp_nmpc_socket(msk);
+       if (!ssock)
+               return -EINVAL;
+
+       mptcp_token_destroy(msk);
+       inet_sk_state_store(sk, TCP_SYN_SENT);
+       subflow = mptcp_subflow_ctx(ssock->sk);
+#ifdef CONFIG_TCP_MD5SIG
+       /* no MPTCP if MD5SIG is enabled on this socket or we may run out of
+        * TCP option space.
+        */
+       if (rcu_access_pointer(tcp_sk(ssock->sk)->md5sig_info))
+               mptcp_subflow_early_fallback(msk, subflow);
+#endif
+       if (subflow->request_mptcp && mptcp_token_new_connect(ssock->sk)) {
+               MPTCP_INC_STATS(sock_net(ssock->sk), MPTCP_MIB_TOKENFALLBACKINIT);
+               mptcp_subflow_early_fallback(msk, subflow);
+       }
+       if (likely(!__mptcp_check_fallback(msk)))
+               MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_MPCAPABLEACTIVE);
+
+       /* if reaching here via the fastopen/sendmsg path, the caller already
+        * acquired the subflow socket lock, too.
+        */
+       if (msk->is_sendmsg)
+               err = __inet_stream_connect(ssock, uaddr, addr_len, msk->connect_flags, 1);
+       else
+               err = inet_stream_connect(ssock, uaddr, addr_len, msk->connect_flags);
+       inet_sk(sk)->defer_connect = inet_sk(ssock->sk)->defer_connect;
+
+       /* on successful connect, the msk state will be moved to established by
+        * subflow_finish_connect()
+        */
+       if (unlikely(err && err != -EINPROGRESS)) {
+               inet_sk_state_store(sk, inet_sk_state_load(ssock->sk));
+               return err;
+       }
+
+       mptcp_copy_inaddrs(sk, ssock->sk);
+
+       /* unblocking connect, mptcp-level inet_stream_connect will error out
+        * without changing the socket state, update it here.
+        */
+       if (err == -EINPROGRESS)
+               sk->sk_socket->state = ssock->state;
+       return err;
+}
+
 static struct proto mptcp_prot = {
        .name           = "MPTCP",
        .owner          = THIS_MODULE,
        .init           = mptcp_init_sock,
+       .connect        = mptcp_connect,
        .disconnect     = mptcp_disconnect,
        .close          = mptcp_close,
        .accept         = mptcp_accept,
@@ -3562,78 +3647,16 @@ unlock:
        return err;
 }
 
-static void mptcp_subflow_early_fallback(struct mptcp_sock *msk,
-                                        struct mptcp_subflow_context *subflow)
-{
-       subflow->request_mptcp = 0;
-       __mptcp_do_fallback(msk);
-}
-
 static int mptcp_stream_connect(struct socket *sock, struct sockaddr *uaddr,
                                int addr_len, int flags)
 {
-       struct mptcp_sock *msk = mptcp_sk(sock->sk);
-       struct mptcp_subflow_context *subflow;
-       struct socket *ssock;
-       int err = -EINVAL;
+       int ret;
 
        lock_sock(sock->sk);
-       if (uaddr) {
-               if (addr_len < sizeof(uaddr->sa_family))
-                       goto unlock;
-
-               if (uaddr->sa_family == AF_UNSPEC) {
-                       err = mptcp_disconnect(sock->sk, flags);
-                       sock->state = err ? SS_DISCONNECTING : SS_UNCONNECTED;
-                       goto unlock;
-               }
-       }
-
-       if (sock->state != SS_UNCONNECTED && msk->subflow) {
-               /* pending connection or invalid state, let existing subflow
-                * cope with that
-                */
-               ssock = msk->subflow;
-               goto do_connect;
-       }
-
-       ssock = __mptcp_nmpc_socket(msk);
-       if (!ssock)
-               goto unlock;
-
-       mptcp_token_destroy(msk);
-       inet_sk_state_store(sock->sk, TCP_SYN_SENT);
-       subflow = mptcp_subflow_ctx(ssock->sk);
-#ifdef CONFIG_TCP_MD5SIG
-       /* no MPTCP if MD5SIG is enabled on this socket or we may run out of
-        * TCP option space.
-        */
-       if (rcu_access_pointer(tcp_sk(ssock->sk)->md5sig_info))
-               mptcp_subflow_early_fallback(msk, subflow);
-#endif
-       if (subflow->request_mptcp && mptcp_token_new_connect(ssock->sk)) {
-               MPTCP_INC_STATS(sock_net(ssock->sk), MPTCP_MIB_TOKENFALLBACKINIT);
-               mptcp_subflow_early_fallback(msk, subflow);
-       }
-       if (likely(!__mptcp_check_fallback(msk)))
-               MPTCP_INC_STATS(sock_net(sock->sk), MPTCP_MIB_MPCAPABLEACTIVE);
-
-do_connect:
-       err = ssock->ops->connect(ssock, uaddr, addr_len, flags);
-       inet_sk(sock->sk)->defer_connect = inet_sk(ssock->sk)->defer_connect;
-       sock->state = ssock->state;
-
-       /* on successful connect, the msk state will be moved to established by
-        * subflow_finish_connect()
-        */
-       if (!err || err == -EINPROGRESS)
-               mptcp_copy_inaddrs(sock->sk, ssock->sk);
-       else
-               inet_sk_state_store(sock->sk, inet_sk_state_load(ssock->sk));
-
-unlock:
+       mptcp_sk(sock->sk)->connect_flags = flags;
+       ret = __inet_stream_connect(sock, uaddr, addr_len, flags, 0);
        release_sock(sock->sk);
-       return err;
+       return ret;
 }
 
 static int mptcp_listen(struct socket *sock, int backlog)
@@ -3699,7 +3722,6 @@ static int mptcp_stream_accept(struct socket *sock, struct socket *newsock,
                if (mptcp_is_fully_established(newsk))
                        mptcp_pm_fully_established(msk, msk->first, GFP_KERNEL);
 
-               mptcp_copy_inaddrs(newsk, msk->first);
                mptcp_rcv_space_init(msk, msk->first);
                mptcp_propagate_sndbuf(newsk, msk->first);
 
index c0b5b46..6a09ab9 100644 (file)
@@ -285,7 +285,9 @@ struct mptcp_sock {
        u8              mpc_endpoint_id;
        u8              recvmsg_inq:1,
                        cork:1,
-                       nodelay:1;
+                       nodelay:1,
+                       is_sendmsg:1;
+       int             connect_flags;
        struct work_struct work;
        struct sk_buff  *ooo_last_skb;
        struct rb_root  out_of_order_queue;
@@ -599,6 +601,7 @@ int mptcp_is_checksum_enabled(const struct net *net);
 int mptcp_allow_join_id0(const struct net *net);
 unsigned int mptcp_stale_loss_cnt(const struct net *net);
 int mptcp_get_pm_type(const struct net *net);
+void mptcp_copy_inaddrs(struct sock *msk, const struct sock *ssk);
 void mptcp_subflow_fully_established(struct mptcp_subflow_context *subflow,
                                     struct mptcp_options_received *mp_opt);
 bool __mptcp_retransmit_pending_data(struct sock *sk);
index 07dd23d..02a54d5 100644 (file)
@@ -723,6 +723,8 @@ create_child:
                                goto dispose_child;
                        }
 
+                       if (new_msk)
+                               mptcp_copy_inaddrs(new_msk, child);
                        subflow_drop_ctx(child);
                        goto out;
                }
@@ -750,6 +752,11 @@ create_child:
                        ctx->conn = new_msk;
                        new_msk = NULL;
 
+                       /* set msk addresses early to ensure mptcp_pm_get_local_id()
+                        * uses the correct data
+                        */
+                       mptcp_copy_inaddrs(ctx->conn, child);
+
                        /* with OoO packets we can reach here without ingress
                         * mpc option
                         */
index 39b7c00..3e16527 100644 (file)
@@ -78,10 +78,29 @@ static unsigned long mc_group_start = 0x3 | BIT(GENL_ID_CTRL) |
 static unsigned long *mc_groups = &mc_group_start;
 static unsigned long mc_groups_longs = 1;
 
+/* We need the last attribute with non-zero ID therefore a 2-entry array */
+static struct nla_policy genl_policy_reject_all[] = {
+       { .type = NLA_REJECT },
+       { .type = NLA_REJECT },
+};
+
 static int genl_ctrl_event(int event, const struct genl_family *family,
                           const struct genl_multicast_group *grp,
                           int grp_id);
 
+static void
+genl_op_fill_in_reject_policy(const struct genl_family *family,
+                             struct genl_ops *op)
+{
+       BUILD_BUG_ON(ARRAY_SIZE(genl_policy_reject_all) - 1 != 1);
+
+       if (op->policy || op->cmd < family->resv_start_op)
+               return;
+
+       op->policy = genl_policy_reject_all;
+       op->maxattr = 1;
+}
+
 static const struct genl_family *genl_family_find_byid(unsigned int id)
 {
        return idr_find(&genl_fam_idr, id);
@@ -113,6 +132,8 @@ static void genl_op_from_full(const struct genl_family *family,
                op->maxattr = family->maxattr;
        if (!op->policy)
                op->policy = family->policy;
+
+       genl_op_fill_in_reject_policy(family, op);
 }
 
 static int genl_get_cmd_full(u32 cmd, const struct genl_family *family,
@@ -142,6 +163,8 @@ static void genl_op_from_small(const struct genl_family *family,
 
        op->maxattr = family->maxattr;
        op->policy = family->policy;
+
+       genl_op_fill_in_reject_policy(family, op);
 }
 
 static int genl_get_cmd_small(u32 cmd, const struct genl_family *family,
@@ -357,6 +380,8 @@ static int genl_validate_ops(const struct genl_family *family)
                genl_get_cmd_by_index(i, family, &op);
                if (op.dumpit == NULL && op.doit == NULL)
                        return -EINVAL;
+               if (WARN_ON(op.cmd >= family->resv_start_op && op.validate))
+                       return -EINVAL;
                for (j = i + 1; j < genl_get_cmd_cnt(family); j++) {
                        struct genl_ops op2;
 
index c8a9075..155263e 100644 (file)
@@ -1616,7 +1616,8 @@ static void ovs_dp_reset_user_features(struct sk_buff *skb,
        if (IS_ERR(dp))
                return;
 
-       WARN(dp->user_features, "Dropping previously announced user features\n");
+       pr_warn("%s: Dropping previously announced user features\n",
+               ovs_dp_name(dp));
        dp->user_features = 0;
 }
 
index 14fd05f..d92ec92 100644 (file)
@@ -450,12 +450,19 @@ static void tipc_conn_data_ready(struct sock *sk)
 static void tipc_topsrv_accept(struct work_struct *work)
 {
        struct tipc_topsrv *srv = container_of(work, struct tipc_topsrv, awork);
-       struct socket *lsock = srv->listener;
-       struct socket *newsock;
+       struct socket *newsock, *lsock;
        struct tipc_conn *con;
        struct sock *newsk;
        int ret;
 
+       spin_lock_bh(&srv->idr_lock);
+       if (!srv->listener) {
+               spin_unlock_bh(&srv->idr_lock);
+               return;
+       }
+       lsock = srv->listener;
+       spin_unlock_bh(&srv->idr_lock);
+
        while (1) {
                ret = kernel_accept(lsock, &newsock, O_NONBLOCK);
                if (ret < 0)
@@ -489,7 +496,7 @@ static void tipc_topsrv_listener_data_ready(struct sock *sk)
 
        read_lock_bh(&sk->sk_callback_lock);
        srv = sk->sk_user_data;
-       if (srv->listener)
+       if (srv)
                queue_work(srv->rcv_wq, &srv->awork);
        read_unlock_bh(&sk->sk_callback_lock);
 }
@@ -699,8 +706,9 @@ static void tipc_topsrv_stop(struct net *net)
        __module_get(lsock->sk->sk_prot_creator->owner);
        srv->listener = NULL;
        spin_unlock_bh(&srv->idr_lock);
-       sock_release(lsock);
+
        tipc_topsrv_work_stop(srv);
+       sock_release(lsock);
        idr_destroy(&srv->conn_idr);
        kfree(srv);
 }
index faf6b03..51ed2f3 100644 (file)
@@ -147,6 +147,7 @@ static int i2sbus_get_and_fixup_rsrc(struct device_node *np, int index,
        return rc;
 }
 
+/* Returns 1 if added, 0 for otherwise; don't return a negative value! */
 /* FIXME: look at device node refcounting */
 static int i2sbus_add_dev(struct macio_dev *macio,
                          struct i2sbus_control *control,
@@ -213,7 +214,7 @@ static int i2sbus_add_dev(struct macio_dev *macio,
         * either as the second one in that case is just a modem. */
        if (!ok) {
                kfree(dev);
-               return -ENODEV;
+               return 0;
        }
 
        mutex_init(&dev->lock);
@@ -302,6 +303,10 @@ static int i2sbus_add_dev(struct macio_dev *macio,
 
        if (soundbus_add_one(&dev->sound)) {
                printk(KERN_DEBUG "i2sbus: device registration error!\n");
+               if (dev->sound.ofdev.dev.kobj.state_initialized) {
+                       soundbus_dev_put(&dev->sound);
+                       return 0;
+               }
                goto err;
        }
 
index a727192..50e7ba6 100644 (file)
@@ -753,6 +753,29 @@ int snd_ctl_rename_id(struct snd_card *card, struct snd_ctl_elem_id *src_id,
 }
 EXPORT_SYMBOL(snd_ctl_rename_id);
 
+/**
+ * snd_ctl_rename - rename the control on the card
+ * @card: the card instance
+ * @kctl: the control to rename
+ * @name: the new name
+ *
+ * Renames the specified control on the card to the new name.
+ *
+ * Make sure to take the control write lock - down_write(&card->controls_rwsem).
+ */
+void snd_ctl_rename(struct snd_card *card, struct snd_kcontrol *kctl,
+                   const char *name)
+{
+       remove_hash_entries(card, kctl);
+
+       if (strscpy(kctl->id.name, name, sizeof(kctl->id.name)) < 0)
+               pr_warn("ALSA: Renamed control new name '%s' truncated to '%s'\n",
+                       name, kctl->id.name);
+
+       add_hash_entries(card, kctl);
+}
+EXPORT_SYMBOL(snd_ctl_rename);
+
 #ifndef CONFIG_SND_CTL_FAST_LOOKUP
 static struct snd_kcontrol *
 snd_ctl_find_numid_slow(struct snd_card *card, unsigned int numid)
index cb60a07..ff68532 100644 (file)
@@ -2009,6 +2009,7 @@ static int snd_ac97_dev_register(struct snd_device *device)
        err = device_register(&ac97->dev);
        if (err < 0) {
                ac97_err(ac97, "Can't register ac97 bus\n");
+               put_device(&ac97->dev);
                ac97->dev.bus = NULL;
                return err;
        }
@@ -2655,11 +2656,18 @@ EXPORT_SYMBOL(snd_ac97_resume);
  */
 static void set_ctl_name(char *dst, const char *src, const char *suffix)
 {
-       if (suffix)
-               sprintf(dst, "%s %s", src, suffix);
-       else
-               strcpy(dst, src);
-}      
+       const size_t msize = SNDRV_CTL_ELEM_ID_NAME_MAXLEN;
+
+       if (suffix) {
+               if (snprintf(dst, msize, "%s %s", src, suffix) >= msize)
+                       pr_warn("ALSA: AC97 control name '%s %s' truncated to '%s'\n",
+                               src, suffix, dst);
+       } else {
+               if (strscpy(dst, src, msize) < 0)
+                       pr_warn("ALSA: AC97 control name '%s' truncated to '%s'\n",
+                               src, dst);
+       }
+}
 
 /* remove the control with the given name and optional suffix */
 static int snd_ac97_remove_ctl(struct snd_ac97 *ac97, const char *name,
@@ -2686,8 +2694,11 @@ static int snd_ac97_rename_ctl(struct snd_ac97 *ac97, const char *src,
                               const char *dst, const char *suffix)
 {
        struct snd_kcontrol *kctl = ctl_find(ac97, src, suffix);
+       char name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
+
        if (kctl) {
-               set_ctl_name(kctl->id.name, dst, suffix);
+               set_ctl_name(name, dst, suffix);
+               snd_ctl_rename(ac97->bus->card, kctl, name);
                return 0;
        }
        return -ENOENT;
@@ -2706,11 +2717,17 @@ static int snd_ac97_swap_ctl(struct snd_ac97 *ac97, const char *s1,
                             const char *s2, const char *suffix)
 {
        struct snd_kcontrol *kctl1, *kctl2;
+       char name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
+
        kctl1 = ctl_find(ac97, s1, suffix);
        kctl2 = ctl_find(ac97, s2, suffix);
        if (kctl1 && kctl2) {
-               set_ctl_name(kctl1->id.name, s2, suffix);
-               set_ctl_name(kctl2->id.name, s1, suffix);
+               set_ctl_name(name, s2, suffix);
+               snd_ctl_rename(ac97->bus->card, kctl1, name);
+
+               set_ctl_name(name, s1, suffix);
+               snd_ctl_rename(ac97->bus->card, kctl2, name);
+
                return 0;
        }
        return -ENOENT;
index 0aa7af0..6cbb2bc 100644 (file)
@@ -141,7 +141,7 @@ struct snd_vortex {
 #ifndef CHIP_AU8810
        stream_t dma_wt[NR_WT];
        wt_voice_t wt_voice[NR_WT];     /* WT register cache. */
-       char mixwt[(NR_WT / NR_WTPB) * 6];      /* WT mixin objects */
+       s8 mixwt[(NR_WT / NR_WTPB) * 6];        /* WT mixin objects */
 #endif
 
        /* Global resources */
@@ -235,8 +235,8 @@ static int vortex_alsafmt_aspfmt(snd_pcm_format_t alsafmt, vortex_t *v);
 static void vortex_connect_default(vortex_t * vortex, int en);
 static int vortex_adb_allocroute(vortex_t * vortex, int dma, int nr_ch,
                                 int dir, int type, int subdev);
-static char vortex_adb_checkinout(vortex_t * vortex, int resmap[], int out,
-                                 int restype);
+static int vortex_adb_checkinout(vortex_t * vortex, int resmap[], int out,
+                                int restype);
 #ifndef CHIP_AU8810
 static int vortex_wt_allocroute(vortex_t * vortex, int dma, int nr_ch);
 static void vortex_wt_connect(vortex_t * vortex, int en);
index 2ed5100..f217c02 100644 (file)
@@ -1998,7 +1998,7 @@ static const int resnum[VORTEX_RESOURCE_LAST] =
  out: Mean checkout if != 0. Else mean Checkin resource.
  restype: Indicates type of resource to be checked in or out.
 */
-static char
+static int
 vortex_adb_checkinout(vortex_t * vortex, int resmap[], int out, int restype)
 {
        int i, qty = resnum[restype], resinuse = 0;
index 05f5601..f6381c0 100644 (file)
@@ -720,7 +720,7 @@ static int rename_ctl(struct snd_card *card, const char *src, const char *dst)
 {
        struct snd_kcontrol *kctl = ctl_find(card, src);
        if (kctl) {
-               strcpy(kctl->id.name, dst);
+               snd_ctl_rename(card, kctl, dst);
                return 0;
        }
        return -ENOENT;
index e9c0fe3..3c115f8 100644 (file)
@@ -1767,7 +1767,7 @@ static int rename_ctl(struct snd_card *card, const char *src, const char *dst)
 {
        struct snd_kcontrol *kctl = ctl_find(card, src);
        if (kctl) {
-               strcpy(kctl->id.name, dst);
+               snd_ctl_rename(card, kctl, dst);
                return 0;
        }
        return -ENOENT;
index e6c4bb5..701a72e 100644 (file)
@@ -2142,7 +2142,7 @@ static void rename_ctl(struct hda_codec *codec, const char *oldname,
 
        kctl = snd_hda_find_mixer_ctl(codec, oldname);
        if (kctl)
-               strcpy(kctl->id.name, newname);
+               snd_ctl_rename(codec->card, kctl, newname);
 }
 
 static void alc1220_fixup_gb_dual_codecs(struct hda_codec *codec,
@@ -6654,13 +6654,8 @@ static int comp_bind(struct device *dev)
 {
        struct hda_codec *cdc = dev_to_hda_codec(dev);
        struct alc_spec *spec = cdc->spec;
-       int ret;
 
-       ret = component_bind_all(dev, spec->comps);
-       if (ret)
-               return ret;
-
-       return 0;
+       return component_bind_all(dev, spec->comps);
 }
 
 static void comp_unbind(struct device *dev)
@@ -9328,6 +9323,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
        SND_PCI_QUIRK(0x103c, 0x8898, "HP EliteBook 845 G8 Notebook PC", ALC285_FIXUP_HP_LIMIT_INT_MIC_BOOST),
        SND_PCI_QUIRK(0x103c, 0x88d0, "HP Pavilion 15-eh1xxx (mainboard 88D0)", ALC287_FIXUP_HP_GPIO_LED),
        SND_PCI_QUIRK(0x103c, 0x8902, "HP OMEN 16", ALC285_FIXUP_HP_MUTE_LED),
+       SND_PCI_QUIRK(0x103c, 0x896d, "HP ZBook Firefly 16 G9", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED),
        SND_PCI_QUIRK(0x103c, 0x896e, "HP EliteBook x360 830 G9", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED),
        SND_PCI_QUIRK(0x103c, 0x8971, "HP EliteBook 830 G9", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED),
        SND_PCI_QUIRK(0x103c, 0x8972, "HP EliteBook 840 G9", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED),
@@ -9346,6 +9342,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
        SND_PCI_QUIRK(0x103c, 0x89aa, "HP EliteBook 630 G9", ALC236_FIXUP_HP_GPIO_LED),
        SND_PCI_QUIRK(0x103c, 0x89ac, "HP EliteBook 640 G9", ALC236_FIXUP_HP_GPIO_LED),
        SND_PCI_QUIRK(0x103c, 0x89ae, "HP EliteBook 650 G9", ALC236_FIXUP_HP_GPIO_LED),
+       SND_PCI_QUIRK(0x103c, 0x89c0, "HP ZBook Power 15.6 G9", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED),
        SND_PCI_QUIRK(0x103c, 0x89c3, "Zbook Studio G9", ALC245_FIXUP_CS35L41_SPI_4_HP_GPIO_LED),
        SND_PCI_QUIRK(0x103c, 0x89c6, "Zbook Fury 17 G9", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED),
        SND_PCI_QUIRK(0x103c, 0x89ca, "HP", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF),
@@ -9400,6 +9397,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
        SND_PCI_QUIRK(0x1043, 0x1ccd, "ASUS X555UB", ALC256_FIXUP_ASUS_MIC),
        SND_PCI_QUIRK(0x1043, 0x1d42, "ASUS Zephyrus G14 2022", ALC289_FIXUP_ASUS_GA401),
        SND_PCI_QUIRK(0x1043, 0x1d4e, "ASUS TM420", ALC256_FIXUP_ASUS_HPE),
+       SND_PCI_QUIRK(0x1043, 0x1e02, "ASUS UX3402", ALC245_FIXUP_CS35L41_SPI_2),
        SND_PCI_QUIRK(0x1043, 0x1e11, "ASUS Zephyrus G15", ALC289_FIXUP_ASUS_GA502),
        SND_PCI_QUIRK(0x1043, 0x1e51, "ASUS Zephyrus M15", ALC294_FIXUP_ASUS_GU502_PINS),
        SND_PCI_QUIRK(0x1043, 0x1e5e, "ASUS ROG Strix G513", ALC294_FIXUP_ASUS_G513_PINS),
index dcc43a8..65add92 100644 (file)
@@ -433,7 +433,7 @@ struct hdsp_midi {
     struct snd_rawmidi           *rmidi;
     struct snd_rawmidi_substream *input;
     struct snd_rawmidi_substream *output;
-    char                     istimer; /* timer in use */
+    signed char                     istimer; /* timer in use */
     struct timer_list       timer;
     spinlock_t               lock;
     int                             pending;
@@ -480,7 +480,7 @@ struct hdsp {
        pid_t                 playback_pid;
        int                   running;
        int                   system_sample_rate;
-       const char           *channel_map;
+       const signed char    *channel_map;
        int                   dev;
        int                   irq;
        unsigned long         port;
@@ -502,7 +502,7 @@ struct hdsp {
    where the data for that channel can be read/written from/to.
 */
 
-static const char channel_map_df_ss[HDSP_MAX_CHANNELS] = {
+static const signed char channel_map_df_ss[HDSP_MAX_CHANNELS] = {
        0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
        18, 19, 20, 21, 22, 23, 24, 25
 };
@@ -517,7 +517,7 @@ static const char channel_map_mf_ss[HDSP_MAX_CHANNELS] = { /* Multiface */
        -1, -1, -1, -1, -1, -1, -1, -1
 };
 
-static const char channel_map_ds[HDSP_MAX_CHANNELS] = {
+static const signed char channel_map_ds[HDSP_MAX_CHANNELS] = {
        /* ADAT channels are remapped */
        1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23,
        /* channels 12 and 13 are S/PDIF */
@@ -526,7 +526,7 @@ static const char channel_map_ds[HDSP_MAX_CHANNELS] = {
        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
 };
 
-static const char channel_map_H9632_ss[HDSP_MAX_CHANNELS] = {
+static const signed char channel_map_H9632_ss[HDSP_MAX_CHANNELS] = {
        /* ADAT channels */
        0, 1, 2, 3, 4, 5, 6, 7,
        /* SPDIF */
@@ -540,7 +540,7 @@ static const char channel_map_H9632_ss[HDSP_MAX_CHANNELS] = {
        -1, -1
 };
 
-static const char channel_map_H9632_ds[HDSP_MAX_CHANNELS] = {
+static const signed char channel_map_H9632_ds[HDSP_MAX_CHANNELS] = {
        /* ADAT */
        1, 3, 5, 7,
        /* SPDIF */
@@ -554,7 +554,7 @@ static const char channel_map_H9632_ds[HDSP_MAX_CHANNELS] = {
        -1, -1, -1, -1, -1, -1
 };
 
-static const char channel_map_H9632_qs[HDSP_MAX_CHANNELS] = {
+static const signed char channel_map_H9632_qs[HDSP_MAX_CHANNELS] = {
        /* ADAT is disabled in this mode */
        /* SPDIF */
        8, 9,
@@ -3939,7 +3939,7 @@ static snd_pcm_uframes_t snd_hdsp_hw_pointer(struct snd_pcm_substream *substream
        return hdsp_hw_pointer(hdsp);
 }
 
-static char *hdsp_channel_buffer_location(struct hdsp *hdsp,
+static signed char *hdsp_channel_buffer_location(struct hdsp *hdsp,
                                             int stream,
                                             int channel)
 
@@ -3964,7 +3964,7 @@ static int snd_hdsp_playback_copy(struct snd_pcm_substream *substream,
                                  void __user *src, unsigned long count)
 {
        struct hdsp *hdsp = snd_pcm_substream_chip(substream);
-       char *channel_buf;
+       signed char *channel_buf;
 
        if (snd_BUG_ON(pos + count > HDSP_CHANNEL_BUFFER_BYTES))
                return -EINVAL;
@@ -3982,7 +3982,7 @@ static int snd_hdsp_playback_copy_kernel(struct snd_pcm_substream *substream,
                                         void *src, unsigned long count)
 {
        struct hdsp *hdsp = snd_pcm_substream_chip(substream);
-       char *channel_buf;
+       signed char *channel_buf;
 
        channel_buf = hdsp_channel_buffer_location(hdsp, substream->pstr->stream, channel);
        if (snd_BUG_ON(!channel_buf))
@@ -3996,7 +3996,7 @@ static int snd_hdsp_capture_copy(struct snd_pcm_substream *substream,
                                 void __user *dst, unsigned long count)
 {
        struct hdsp *hdsp = snd_pcm_substream_chip(substream);
-       char *channel_buf;
+       signed char *channel_buf;
 
        if (snd_BUG_ON(pos + count > HDSP_CHANNEL_BUFFER_BYTES))
                return -EINVAL;
@@ -4014,7 +4014,7 @@ static int snd_hdsp_capture_copy_kernel(struct snd_pcm_substream *substream,
                                        void *dst, unsigned long count)
 {
        struct hdsp *hdsp = snd_pcm_substream_chip(substream);
-       char *channel_buf;
+       signed char *channel_buf;
 
        channel_buf = hdsp_channel_buffer_location(hdsp, substream->pstr->stream, channel);
        if (snd_BUG_ON(!channel_buf))
@@ -4028,7 +4028,7 @@ static int snd_hdsp_hw_silence(struct snd_pcm_substream *substream,
                               unsigned long count)
 {
        struct hdsp *hdsp = snd_pcm_substream_chip(substream);
-       char *channel_buf;
+       signed char *channel_buf;
 
        channel_buf = hdsp_channel_buffer_location (hdsp, substream->pstr->stream, channel);
        if (snd_BUG_ON(!channel_buf))
index 1d614fe..e7c320a 100644 (file)
@@ -230,7 +230,7 @@ struct snd_rme9652 {
        int last_spdif_sample_rate;     /* so that we can catch externally ... */
        int last_adat_sample_rate;      /* ... induced rate changes            */
 
-       const char *channel_map;
+       const signed char *channel_map;
 
        struct snd_card *card;
        struct snd_pcm *pcm;
@@ -247,12 +247,12 @@ struct snd_rme9652 {
    where the data for that channel can be read/written from/to.
 */
 
-static const char channel_map_9652_ss[26] = {
+static const signed char channel_map_9652_ss[26] = {
        0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
        18, 19, 20, 21, 22, 23, 24, 25
 };
 
-static const char channel_map_9636_ss[26] = {
+static const signed char channel_map_9636_ss[26] = {
        0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 
        /* channels 16 and 17 are S/PDIF */
        24, 25,
@@ -260,7 +260,7 @@ static const char channel_map_9636_ss[26] = {
        -1, -1, -1, -1, -1, -1, -1, -1
 };
 
-static const char channel_map_9652_ds[26] = {
+static const signed char channel_map_9652_ds[26] = {
        /* ADAT channels are remapped */
        1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23,
        /* channels 12 and 13 are S/PDIF */
@@ -269,7 +269,7 @@ static const char channel_map_9652_ds[26] = {
        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
 };
 
-static const char channel_map_9636_ds[26] = {
+static const signed char channel_map_9636_ds[26] = {
        /* ADAT channels are remapped */
        1, 3, 5, 7, 9, 11, 13, 15,
        /* channels 8 and 9 are S/PDIF */
@@ -1819,7 +1819,7 @@ static snd_pcm_uframes_t snd_rme9652_hw_pointer(struct snd_pcm_substream *substr
        return rme9652_hw_pointer(rme9652);
 }
 
-static char *rme9652_channel_buffer_location(struct snd_rme9652 *rme9652,
+static signed char *rme9652_channel_buffer_location(struct snd_rme9652 *rme9652,
                                             int stream,
                                             int channel)
 
@@ -1847,7 +1847,7 @@ static int snd_rme9652_playback_copy(struct snd_pcm_substream *substream,
                                     void __user *src, unsigned long count)
 {
        struct snd_rme9652 *rme9652 = snd_pcm_substream_chip(substream);
-       char *channel_buf;
+       signed char *channel_buf;
 
        if (snd_BUG_ON(pos + count > RME9652_CHANNEL_BUFFER_BYTES))
                return -EINVAL;
@@ -1867,7 +1867,7 @@ static int snd_rme9652_playback_copy_kernel(struct snd_pcm_substream *substream,
                                            void *src, unsigned long count)
 {
        struct snd_rme9652 *rme9652 = snd_pcm_substream_chip(substream);
-       char *channel_buf;
+       signed char *channel_buf;
 
        channel_buf = rme9652_channel_buffer_location(rme9652,
                                                      substream->pstr->stream,
@@ -1883,7 +1883,7 @@ static int snd_rme9652_capture_copy(struct snd_pcm_substream *substream,
                                    void __user *dst, unsigned long count)
 {
        struct snd_rme9652 *rme9652 = snd_pcm_substream_chip(substream);
-       char *channel_buf;
+       signed char *channel_buf;
 
        if (snd_BUG_ON(pos + count > RME9652_CHANNEL_BUFFER_BYTES))
                return -EINVAL;
@@ -1903,7 +1903,7 @@ static int snd_rme9652_capture_copy_kernel(struct snd_pcm_substream *substream,
                                           void *dst, unsigned long count)
 {
        struct snd_rme9652 *rme9652 = snd_pcm_substream_chip(substream);
-       char *channel_buf;
+       signed char *channel_buf;
 
        channel_buf = rme9652_channel_buffer_location(rme9652,
                                                      substream->pstr->stream,
@@ -1919,7 +1919,7 @@ static int snd_rme9652_hw_silence(struct snd_pcm_substream *substream,
                                  unsigned long count)
 {
        struct snd_rme9652 *rme9652 = snd_pcm_substream_chip(substream);
-       char *channel_buf;
+       signed char *channel_buf;
 
        channel_buf = rme9652_channel_buffer_location (rme9652,
                                                       substream->pstr->stream,
index 2cb50d5..6c0f1de 100644 (file)
@@ -49,6 +49,27 @@ static const struct dmi_system_id yc_acp_quirk_table[] = {
                .driver_data = &acp6x_card,
                .matches = {
                        DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "21D0"),
+               }
+       },
+       {
+               .driver_data = &acp6x_card,
+               .matches = {
+                       DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "21D0"),
+               }
+       },
+       {
+               .driver_data = &acp6x_card,
+               .matches = {
+                       DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "21D1"),
+               }
+       },
+       {
+               .driver_data = &acp6x_card,
+               .matches = {
+                       DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
                        DMI_MATCH(DMI_PRODUCT_NAME, "21D2"),
                }
        },
index e3b90c4..7022e62 100644 (file)
@@ -1629,6 +1629,7 @@ config SND_SOC_TFA989X
 config SND_SOC_TLV320ADC3XXX
        tristate "Texas Instruments TLV320ADC3001/3101 audio ADC"
        depends on I2C
+       depends on GPIOLIB
        help
         Enable support for Texas Instruments TLV320ADC3001 and TLV320ADC3101
         ADCs.
index ebdd567..09e3a92 100644 (file)
 #define CX2072X_PLBK_DRC_PARM_LEN      9
 #define CX2072X_CLASSD_AMP_LEN         6
 
-/* DAI interfae type */
+/* DAI interface type */
 #define CX2072X_DAI_HIFI       1
 #define CX2072X_DAI_DSP                2
 #define CX2072X_DAI_DSP_PWM    3 /* 4 ch, including mic and AEC */
index 5201a8f..71ea576 100644 (file)
@@ -136,14 +136,17 @@ enum {
 #define REG_CGR3_GO1L_OFFSET           0
 #define REG_CGR3_GO1L_MASK             (0x1f << REG_CGR3_GO1L_OFFSET)
 
+#define REG_CGR10_GIL_OFFSET           0
+#define REG_CGR10_GIR_OFFSET           4
+
 struct jz_icdc {
        struct regmap *regmap;
        void __iomem *base;
        struct clk *clk;
 };
 
-static const SNDRV_CTL_TLVD_DECLARE_DB_LINEAR(jz4725b_dac_tlv, -2250, 0);
-static const SNDRV_CTL_TLVD_DECLARE_DB_LINEAR(jz4725b_line_tlv, -1500, 600);
+static const SNDRV_CTL_TLVD_DECLARE_DB_SCALE(jz4725b_adc_tlv,     0, 150, 0);
+static const SNDRV_CTL_TLVD_DECLARE_DB_SCALE(jz4725b_dac_tlv, -2250, 150, 0);
 
 static const struct snd_kcontrol_new jz4725b_codec_controls[] = {
        SOC_DOUBLE_TLV("Master Playback Volume",
@@ -151,11 +154,11 @@ static const struct snd_kcontrol_new jz4725b_codec_controls[] = {
                       REG_CGR1_GODL_OFFSET,
                       REG_CGR1_GODR_OFFSET,
                       0xf, 1, jz4725b_dac_tlv),
-       SOC_DOUBLE_R_TLV("Master Capture Volume",
-                        JZ4725B_CODEC_REG_CGR3,
-                        JZ4725B_CODEC_REG_CGR2,
-                        REG_CGR2_GO1R_OFFSET,
-                        0x1f, 1, jz4725b_line_tlv),
+       SOC_DOUBLE_TLV("Master Capture Volume",
+                      JZ4725B_CODEC_REG_CGR10,
+                      REG_CGR10_GIL_OFFSET,
+                      REG_CGR10_GIR_OFFSET,
+                      0xf, 0, jz4725b_adc_tlv),
 
        SOC_SINGLE("Master Playback Switch", JZ4725B_CODEC_REG_CR1,
                   REG_CR1_DAC_MUTE_OFFSET, 1, 1),
@@ -180,7 +183,7 @@ static SOC_VALUE_ENUM_SINGLE_DECL(jz4725b_codec_adc_src_enum,
                                  jz4725b_codec_adc_src_texts,
                                  jz4725b_codec_adc_src_values);
 static const struct snd_kcontrol_new jz4725b_codec_adc_src_ctrl =
-                       SOC_DAPM_ENUM("Route", jz4725b_codec_adc_src_enum);
+       SOC_DAPM_ENUM("ADC Source Capture Route", jz4725b_codec_adc_src_enum);
 
 static const struct snd_kcontrol_new jz4725b_codec_mixer_controls[] = {
        SOC_DAPM_SINGLE("Line In Bypass", JZ4725B_CODEC_REG_CR1,
@@ -225,7 +228,7 @@ static const struct snd_soc_dapm_widget jz4725b_codec_dapm_widgets[] = {
        SND_SOC_DAPM_ADC("ADC", "Capture",
                         JZ4725B_CODEC_REG_PMR1, REG_PMR1_SB_ADC_OFFSET, 1),
 
-       SND_SOC_DAPM_MUX("ADC Source", SND_SOC_NOPM, 0, 0,
+       SND_SOC_DAPM_MUX("ADC Source Capture Route", SND_SOC_NOPM, 0, 0,
                         &jz4725b_codec_adc_src_ctrl),
 
        /* Mixer */
@@ -236,7 +239,8 @@ static const struct snd_soc_dapm_widget jz4725b_codec_dapm_widgets[] = {
        SND_SOC_DAPM_MIXER("DAC to Mixer", JZ4725B_CODEC_REG_CR1,
                           REG_CR1_DACSEL_OFFSET, 0, NULL, 0),
 
-       SND_SOC_DAPM_MIXER("Line In", SND_SOC_NOPM, 0, 0, NULL, 0),
+       SND_SOC_DAPM_MIXER("Line In", JZ4725B_CODEC_REG_PMR1,
+                          REG_PMR1_SB_LIN_OFFSET, 1, NULL, 0),
        SND_SOC_DAPM_MIXER("HP Out", JZ4725B_CODEC_REG_CR1,
                           REG_CR1_HP_DIS_OFFSET, 1, NULL, 0),
 
@@ -283,11 +287,11 @@ static const struct snd_soc_dapm_route jz4725b_codec_dapm_routes[] = {
        {"Mixer", NULL, "DAC to Mixer"},
 
        {"Mixer to ADC", NULL, "Mixer"},
-       {"ADC Source", "Mixer", "Mixer to ADC"},
-       {"ADC Source", "Line In", "Line In"},
-       {"ADC Source", "Mic 1", "Mic 1"},
-       {"ADC Source", "Mic 2", "Mic 2"},
-       {"ADC", NULL, "ADC Source"},
+       {"ADC Source Capture Route", "Mixer", "Mixer to ADC"},
+       {"ADC Source Capture Route", "Line In", "Line In"},
+       {"ADC Source Capture Route", "Mic 1", "Mic 1"},
+       {"ADC Source Capture Route", "Mic 2", "Mic 2"},
+       {"ADC", NULL, "ADC Source Capture Route"},
 
        {"Out Stage", NULL, "Mixer"},
        {"HP Out", NULL, "Out Stage"},
index 554c33e..cc2df5f 100644 (file)
@@ -503,14 +503,14 @@ static int mt6660_i2c_probe(struct i2c_client *client)
                dev_err(chip->dev, "read chip revision fail\n");
                goto probe_fail;
        }
+       pm_runtime_set_active(chip->dev);
+       pm_runtime_enable(chip->dev);
 
        ret = devm_snd_soc_register_component(chip->dev,
                                               &mt6660_component_driver,
                                               &mt6660_codec_dai, 1);
-       if (!ret) {
-               pm_runtime_set_active(chip->dev);
-               pm_runtime_enable(chip->dev);
-       }
+       if (ret)
+               pm_runtime_disable(chip->dev);
 
        return ret;
 
index b66bfec..49f527c 100644 (file)
@@ -391,18 +391,18 @@ static int rt1019_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
                        unsigned int rx_mask, int slots, int slot_width)
 {
        struct snd_soc_component *component = dai->component;
-       unsigned int val = 0, rx_slotnum;
+       unsigned int cn = 0, cl = 0, rx_slotnum;
        int ret = 0, first_bit;
 
        switch (slots) {
        case 4:
-               val |= RT1019_I2S_TX_4CH;
+               cn = RT1019_I2S_TX_4CH;
                break;
        case 6:
-               val |= RT1019_I2S_TX_6CH;
+               cn = RT1019_I2S_TX_6CH;
                break;
        case 8:
-               val |= RT1019_I2S_TX_8CH;
+               cn = RT1019_I2S_TX_8CH;
                break;
        case 2:
                break;
@@ -412,16 +412,16 @@ static int rt1019_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
 
        switch (slot_width) {
        case 20:
-               val |= RT1019_I2S_DL_20;
+               cl = RT1019_TDM_CL_20;
                break;
        case 24:
-               val |= RT1019_I2S_DL_24;
+               cl = RT1019_TDM_CL_24;
                break;
        case 32:
-               val |= RT1019_I2S_DL_32;
+               cl = RT1019_TDM_CL_32;
                break;
        case 8:
-               val |= RT1019_I2S_DL_8;
+               cl = RT1019_TDM_CL_8;
                break;
        case 16:
                break;
@@ -470,8 +470,10 @@ static int rt1019_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
                goto _set_tdm_err_;
        }
 
+       snd_soc_component_update_bits(component, RT1019_TDM_1,
+               RT1019_TDM_CL_MASK, cl);
        snd_soc_component_update_bits(component, RT1019_TDM_2,
-               RT1019_I2S_CH_TX_MASK | RT1019_I2S_DF_MASK, val);
+               RT1019_I2S_CH_TX_MASK, cn);
 
 _set_tdm_err_:
        return ret;
index 64df831..48ba15e 100644 (file)
 #define RT1019_TDM_BCLK_MASK           (0x1 << 6)
 #define RT1019_TDM_BCLK_NORM           (0x0 << 6)
 #define RT1019_TDM_BCLK_INV                    (0x1 << 6)
+#define RT1019_TDM_CL_MASK                     (0x7)
+#define RT1019_TDM_CL_8                                (0x4)
+#define RT1019_TDM_CL_32                       (0x3)
+#define RT1019_TDM_CL_24                       (0x2)
+#define RT1019_TDM_CL_20                       (0x1)
+#define RT1019_TDM_CL_16                       (0x0)
 
 /* 0x0401 TDM Control-2 */
 #define RT1019_I2S_CH_TX_MASK          (0x3 << 6)
index 5c29416..f99aed3 100644 (file)
@@ -50,6 +50,7 @@ static bool rt1308_volatile_register(struct device *dev, unsigned int reg)
        case 0x3008:
        case 0x300a:
        case 0xc000:
+       case 0xc710:
        case 0xc860 ... 0xc863:
        case 0xc870 ... 0xc873:
                return true;
@@ -200,6 +201,7 @@ static int rt1308_io_init(struct device *dev, struct sdw_slave *slave)
 {
        struct rt1308_sdw_priv *rt1308 = dev_get_drvdata(dev);
        int ret = 0;
+       unsigned int tmp;
 
        if (rt1308->hw_init)
                return 0;
@@ -231,6 +233,10 @@ static int rt1308_io_init(struct device *dev, struct sdw_slave *slave)
        /* sw reset */
        regmap_write(rt1308->regmap, RT1308_SDW_RESET, 0);
 
+       regmap_read(rt1308->regmap, 0xc710, &tmp);
+       rt1308->hw_ver = tmp;
+       dev_dbg(dev, "%s, hw_ver=0x%x\n", __func__, rt1308->hw_ver);
+
        /* initial settings */
        regmap_write(rt1308->regmap, 0xc103, 0xc0);
        regmap_write(rt1308->regmap, 0xc030, 0x17);
@@ -246,8 +252,14 @@ static int rt1308_io_init(struct device *dev, struct sdw_slave *slave)
        regmap_write(rt1308->regmap, 0xc062, 0x05);
        regmap_write(rt1308->regmap, 0xc171, 0x07);
        regmap_write(rt1308->regmap, 0xc173, 0x0d);
-       regmap_write(rt1308->regmap, 0xc311, 0x7f);
-       regmap_write(rt1308->regmap, 0xc900, 0x90);
+       if (rt1308->hw_ver == RT1308_VER_C) {
+               regmap_write(rt1308->regmap, 0xc311, 0x7f);
+               regmap_write(rt1308->regmap, 0xc300, 0x09);
+       } else {
+               regmap_write(rt1308->regmap, 0xc311, 0x4f);
+               regmap_write(rt1308->regmap, 0xc300, 0x0b);
+       }
+       regmap_write(rt1308->regmap, 0xc900, 0x5a);
        regmap_write(rt1308->regmap, 0xc1a0, 0x84);
        regmap_write(rt1308->regmap, 0xc1a1, 0x01);
        regmap_write(rt1308->regmap, 0xc360, 0x78);
@@ -257,7 +269,6 @@ static int rt1308_io_init(struct device *dev, struct sdw_slave *slave)
        regmap_write(rt1308->regmap, 0xc070, 0x00);
        regmap_write(rt1308->regmap, 0xc100, 0xd7);
        regmap_write(rt1308->regmap, 0xc101, 0xd7);
-       regmap_write(rt1308->regmap, 0xc300, 0x09);
 
        if (rt1308->first_hw_init) {
                regcache_cache_bypass(rt1308->regmap, false);
index 6668e19..62ce277 100644 (file)
@@ -139,10 +139,12 @@ static const struct reg_default rt1308_reg_defaults[] = {
        { 0x3005, 0x23 },
        { 0x3008, 0x02 },
        { 0x300a, 0x00 },
+       { 0xc000 | (RT1308_DATA_PATH << 4), 0x00 },
        { 0xc003 | (RT1308_DAC_SET << 4), 0x00 },
        { 0xc000 | (RT1308_POWER << 4), 0x00 },
        { 0xc001 | (RT1308_POWER << 4), 0x00 },
        { 0xc002 | (RT1308_POWER << 4), 0x00 },
+       { 0xc000 | (RT1308_POWER_STATUS << 4), 0x00 },
 };
 
 #define RT1308_SDW_OFFSET 0xc000
@@ -163,6 +165,7 @@ struct rt1308_sdw_priv {
        bool first_hw_init;
        int rx_mask;
        int slots;
+       int hw_ver;
 };
 
 struct sdw_stream_data {
index ff7c423..d3a0f91 100644 (file)
@@ -286,4 +286,9 @@ enum {
        RT1308_AIFS
 };
 
+enum rt1308_hw_ver {
+       RT1308_VER_C = 2,
+       RT1308_VER_D
+};
+
 #endif         /* end of _RT1308_H_ */
index 466a37f..80c673a 100644 (file)
@@ -1981,7 +1981,7 @@ static int rt5682s_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
                unsigned int rx_mask, int slots, int slot_width)
 {
        struct snd_soc_component *component = dai->component;
-       unsigned int cl, val = 0;
+       unsigned int cl, val = 0, tx_slotnum;
 
        if (tx_mask || rx_mask)
                snd_soc_component_update_bits(component,
@@ -1990,6 +1990,16 @@ static int rt5682s_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
                snd_soc_component_update_bits(component,
                        RT5682S_TDM_ADDA_CTRL_2, RT5682S_TDM_EN, 0);
 
+       /* Tx slot configuration */
+       tx_slotnum = hweight_long(tx_mask);
+       if (tx_slotnum) {
+               if (tx_slotnum > slots) {
+                       dev_err(component->dev, "Invalid or oversized Tx slots.\n");
+                       return -EINVAL;
+               }
+               val |= (tx_slotnum - 1) << RT5682S_TDM_ADC_DL_SFT;
+       }
+
        switch (slots) {
        case 4:
                val |= RT5682S_TDM_TX_CH_4;
@@ -2010,7 +2020,8 @@ static int rt5682s_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
        }
 
        snd_soc_component_update_bits(component, RT5682S_TDM_CTRL,
-               RT5682S_TDM_TX_CH_MASK | RT5682S_TDM_RX_CH_MASK, val);
+               RT5682S_TDM_TX_CH_MASK | RT5682S_TDM_RX_CH_MASK |
+               RT5682S_TDM_ADC_DL_MASK, val);
 
        switch (slot_width) {
        case 8:
index 824dc65..45464a0 100644 (file)
 #define RT5682S_TDM_RX_CH_8                    (0x3 << 8)
 #define RT5682S_TDM_ADC_LCA_MASK               (0x7 << 4)
 #define RT5682S_TDM_ADC_LCA_SFT                        4
+#define RT5682S_TDM_ADC_DL_MASK                        (0x3 << 0)
 #define RT5682S_TDM_ADC_DL_SFT                 0
 
 /* TDM control 2 (0x007a) */
index baab320..a969547 100644 (file)
@@ -1449,7 +1449,7 @@ static struct i2c_driver adc3xxx_i2c_driver = {
                   .of_match_table = tlv320adc3xxx_of_match,
                  },
        .probe_new = adc3xxx_i2c_probe,
-       .remove = adc3xxx_i2c_remove,
+       .remove = __exit_p(adc3xxx_i2c_remove),
        .id_table = adc3xxx_i2c_id,
 };
 
index c09c9ac..adaf886 100644 (file)
@@ -2099,6 +2099,9 @@ static int wm5102_probe(struct platform_device *pdev)
                regmap_update_bits(arizona->regmap, wm5102_digital_vu[i],
                                   WM5102_DIG_VU, WM5102_DIG_VU);
 
+       pm_runtime_enable(&pdev->dev);
+       pm_runtime_idle(&pdev->dev);
+
        ret = arizona_request_irq(arizona, ARIZONA_IRQ_DSP_IRQ1,
                                  "ADSP2 Compressed IRQ", wm5102_adsp2_irq,
                                  wm5102);
@@ -2131,9 +2134,6 @@ static int wm5102_probe(struct platform_device *pdev)
                goto err_spk_irqs;
        }
 
-       pm_runtime_enable(&pdev->dev);
-       pm_runtime_idle(&pdev->dev);
-
        return ret;
 
 err_spk_irqs:
@@ -2142,6 +2142,7 @@ err_dsp_irq:
        arizona_set_irq_wake(arizona, ARIZONA_IRQ_DSP_IRQ1, 0);
        arizona_free_irq(arizona, ARIZONA_IRQ_DSP_IRQ1, wm5102);
 err_jack_codec_dev:
+       pm_runtime_disable(&pdev->dev);
        arizona_jack_codec_dev_remove(&wm5102->core);
 
        return ret;
index fc634c9..e0b9716 100644 (file)
@@ -2457,6 +2457,9 @@ static int wm5110_probe(struct platform_device *pdev)
                regmap_update_bits(arizona->regmap, wm5110_digital_vu[i],
                                   WM5110_DIG_VU, WM5110_DIG_VU);
 
+       pm_runtime_enable(&pdev->dev);
+       pm_runtime_idle(&pdev->dev);
+
        ret = arizona_request_irq(arizona, ARIZONA_IRQ_DSP_IRQ1,
                                  "ADSP2 Compressed IRQ", wm5110_adsp2_irq,
                                  wm5110);
@@ -2489,9 +2492,6 @@ static int wm5110_probe(struct platform_device *pdev)
                goto err_spk_irqs;
        }
 
-       pm_runtime_enable(&pdev->dev);
-       pm_runtime_idle(&pdev->dev);
-
        return ret;
 
 err_spk_irqs:
@@ -2500,6 +2500,7 @@ err_dsp_irq:
        arizona_set_irq_wake(arizona, ARIZONA_IRQ_DSP_IRQ1, 0);
        arizona_free_irq(arizona, ARIZONA_IRQ_DSP_IRQ1, wm5110);
 err_jack_codec_dev:
+       pm_runtime_disable(&pdev->dev);
        arizona_jack_codec_dev_remove(&wm5110->core);
 
        return ret;
index 8104966..b4b4355 100644 (file)
@@ -1840,6 +1840,49 @@ SOC_SINGLE_TLV("SPKOUTR Mixer DACR Volume", WM8962_SPEAKER_MIXER_5,
               4, 1, 0, inmix_tlv),
 };
 
+static int tp_event(struct snd_soc_dapm_widget *w,
+                   struct snd_kcontrol *kcontrol, int event)
+{
+       int ret, reg, val, mask;
+       struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+
+       ret = pm_runtime_resume_and_get(component->dev);
+       if (ret < 0) {
+               dev_err(component->dev, "Failed to resume device: %d\n", ret);
+               return ret;
+       }
+
+       reg = WM8962_ADDITIONAL_CONTROL_4;
+
+       if (!strcmp(w->name, "TEMP_HP")) {
+               mask = WM8962_TEMP_ENA_HP_MASK;
+               val = WM8962_TEMP_ENA_HP;
+       } else if (!strcmp(w->name, "TEMP_SPK")) {
+               mask = WM8962_TEMP_ENA_SPK_MASK;
+               val = WM8962_TEMP_ENA_SPK;
+       } else {
+               pm_runtime_put(component->dev);
+               return -EINVAL;
+       }
+
+       switch (event) {
+       case SND_SOC_DAPM_POST_PMD:
+               val = 0;
+               fallthrough;
+       case SND_SOC_DAPM_POST_PMU:
+               ret = snd_soc_component_update_bits(component, reg, mask, val);
+               break;
+       default:
+               WARN(1, "Invalid event %d\n", event);
+               pm_runtime_put(component->dev);
+               return -EINVAL;
+       }
+
+       pm_runtime_put(component->dev);
+
+       return 0;
+}
+
 static int cp_event(struct snd_soc_dapm_widget *w,
                    struct snd_kcontrol *kcontrol, int event)
 {
@@ -2140,8 +2183,10 @@ SND_SOC_DAPM_SUPPLY("TOCLK", WM8962_ADDITIONAL_CONTROL_1, 0, 0, NULL, 0),
 SND_SOC_DAPM_SUPPLY_S("DSP2", 1, WM8962_DSP2_POWER_MANAGEMENT,
                      WM8962_DSP2_ENA_SHIFT, 0, dsp2_event,
                      SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
-SND_SOC_DAPM_SUPPLY("TEMP_HP", WM8962_ADDITIONAL_CONTROL_4, 2, 0, NULL, 0),
-SND_SOC_DAPM_SUPPLY("TEMP_SPK", WM8962_ADDITIONAL_CONTROL_4, 1, 0, NULL, 0),
+SND_SOC_DAPM_SUPPLY("TEMP_HP", SND_SOC_NOPM, 0, 0, tp_event,
+               SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD),
+SND_SOC_DAPM_SUPPLY("TEMP_SPK", SND_SOC_NOPM, 0, 0, tp_event,
+               SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD),
 
 SND_SOC_DAPM_MIXER("INPGAL", WM8962_LEFT_INPUT_PGA_CONTROL, 4, 0,
                   inpgal, ARRAY_SIZE(inpgal)),
@@ -3763,6 +3808,11 @@ static int wm8962_i2c_probe(struct i2c_client *i2c)
        if (ret < 0)
                goto err_pm_runtime;
 
+       regmap_update_bits(wm8962->regmap, WM8962_ADDITIONAL_CONTROL_4,
+                           WM8962_TEMP_ENA_HP_MASK, 0);
+       regmap_update_bits(wm8962->regmap, WM8962_ADDITIONAL_CONTROL_4,
+                           WM8962_TEMP_ENA_SPK_MASK, 0);
+
        regcache_cache_only(wm8962->regmap, true);
 
        /* The drivers should power up as needed */
index 77136a5..c0207e9 100644 (file)
@@ -1161,6 +1161,9 @@ static int wm8997_probe(struct platform_device *pdev)
                regmap_update_bits(arizona->regmap, wm8997_digital_vu[i],
                                   WM8997_DIG_VU, WM8997_DIG_VU);
 
+       pm_runtime_enable(&pdev->dev);
+       pm_runtime_idle(&pdev->dev);
+
        arizona_init_common(arizona);
 
        ret = arizona_init_vol_limit(arizona);
@@ -1179,14 +1182,12 @@ static int wm8997_probe(struct platform_device *pdev)
                goto err_spk_irqs;
        }
 
-       pm_runtime_enable(&pdev->dev);
-       pm_runtime_idle(&pdev->dev);
-
        return ret;
 
 err_spk_irqs:
        arizona_free_spk_irqs(arizona);
 err_jack_codec_dev:
+       pm_runtime_disable(&pdev->dev);
        arizona_jack_codec_dev_remove(&wm8997->core);
 
        return ret;
index b327372..fe7cf97 100644 (file)
@@ -417,7 +417,7 @@ static inline bool parse_as_dpcm_link(struct asoc_simple_priv *priv,
         * or has convert-xxx property
         */
        if ((of_get_child_count(codec_port) > 1) ||
-           (adata->convert_rate || adata->convert_channels))
+           asoc_simple_is_convert_required(adata))
                return true;
 
        return false;
index bef1683..be69bbc 100644 (file)
@@ -85,6 +85,21 @@ void asoc_simple_parse_convert(struct device_node *np,
 }
 EXPORT_SYMBOL_GPL(asoc_simple_parse_convert);
 
+/**
+ * asoc_simple_is_convert_required() - Query if HW param conversion was requested
+ * @data: Link data.
+ *
+ * Returns true if any HW param conversion was requested for this DAI link with
+ * any "convert-xxx" properties.
+ */
+bool asoc_simple_is_convert_required(const struct asoc_simple_data *data)
+{
+       return data->convert_rate ||
+              data->convert_channels ||
+              data->convert_sample_format;
+}
+EXPORT_SYMBOL_GPL(asoc_simple_is_convert_required);
+
 int asoc_simple_parse_daifmt(struct device *dev,
                             struct device_node *node,
                             struct device_node *codec,
index 78419e1..feb55b6 100644 (file)
@@ -393,8 +393,7 @@ static int __simple_for_each_link(struct asoc_simple_priv *priv,
                         * or has convert-xxx property
                         */
                        if (dpcm_selectable &&
-                           (num > 2 ||
-                            adata.convert_rate || adata.convert_channels)) {
+                           (num > 2 || asoc_simple_is_convert_required(&adata))) {
                                /*
                                 * np
                                 *       |1(CPU)|0(Codec)  li->cpu
index 2d09868..2358be2 100644 (file)
@@ -223,6 +223,18 @@ static const struct dmi_system_id sof_rt5682_quirk_table[] = {
                                        SOF_RT5682_SSP_AMP(2) |
                                        SOF_RT5682_NUM_HDMIDEV(4)),
        },
+       {
+               .callback = sof_rt5682_quirk_cb,
+               .matches = {
+                       DMI_MATCH(DMI_PRODUCT_FAMILY, "Google_Rex"),
+               },
+               .driver_data = (void *)(SOF_RT5682_MCLK_EN |
+                                       SOF_RT5682_SSP_CODEC(2) |
+                                       SOF_SPEAKER_AMP_PRESENT |
+                                       SOF_RT5682_SSP_AMP(0) |
+                                       SOF_RT5682_NUM_HDMIDEV(4)
+                                       ),
+       },
        {}
 };
 
index 2ff30b4..ee9857d 100644 (file)
@@ -202,6 +202,17 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = {
                                        SOF_SDW_PCH_DMIC |
                                        RT711_JD1),
        },
+       {
+               /* NUC15 LAPBC710 skews */
+               .callback = sof_sdw_quirk_cb,
+               .matches = {
+                       DMI_MATCH(DMI_BOARD_VENDOR, "Intel Corporation"),
+                       DMI_MATCH(DMI_BOARD_NAME, "LAPBC710"),
+               },
+               .driver_data = (void *)(SOF_SDW_TGL_HDMI |
+                                       SOF_SDW_PCH_DMIC |
+                                       RT711_JD1),
+       },
        /* TigerLake-SDCA devices */
        {
                .callback = sof_sdw_quirk_cb,
index bbba2df..3312b57 100644 (file)
@@ -689,11 +689,6 @@ static void load_codec_module(struct hda_codec *codec)
 
 #endif /* CONFIG_SND_SOC_INTEL_SKYLAKE_HDAUDIO_CODEC */
 
-static void skl_codec_device_exit(struct device *dev)
-{
-       snd_hdac_device_exit(dev_to_hdac_dev(dev));
-}
-
 static struct hda_codec *skl_codec_device_init(struct hdac_bus *bus, int addr)
 {
        struct hda_codec *codec;
@@ -706,12 +701,11 @@ static struct hda_codec *skl_codec_device_init(struct hdac_bus *bus, int addr)
        }
 
        codec->core.type = HDA_DEV_ASOC;
-       codec->core.dev.release = skl_codec_device_exit;
 
        ret = snd_hdac_device_register(&codec->core);
        if (ret) {
                dev_err(bus->dev, "failed to register hdac device\n");
-               snd_hdac_device_exit(&codec->core);
+               put_device(&codec->core.dev);
                return ERR_PTR(ret);
        }
 
index d0e59e0..8c7398b 100644 (file)
@@ -187,6 +187,7 @@ config SND_SOC_SC8280XP
 config SND_SOC_SC7180
        tristate "SoC Machine driver for SC7180 boards"
        depends on I2C && GPIOLIB
+       depends on SOUNDWIRE || SOUNDWIRE=n
        select SND_SOC_QCOM_COMMON
        select SND_SOC_LPASS_SC7180
        select SND_SOC_MAX98357A
index 8a56f38..5435384 100644 (file)
@@ -782,10 +782,20 @@ static bool lpass_hdmi_regmap_volatile(struct device *dev, unsigned int reg)
                return true;
        if (reg == LPASS_HDMI_TX_LEGACY_ADDR(v))
                return true;
+       if (reg == LPASS_HDMI_TX_VBIT_CTL_ADDR(v))
+               return true;
+       if (reg == LPASS_HDMI_TX_PARITY_ADDR(v))
+               return true;
 
        for (i = 0; i < v->hdmi_rdma_channels; ++i) {
                if (reg == LPAIF_HDMI_RDMACURR_REG(v, i))
                        return true;
+               if (reg == LPASS_HDMI_TX_DMA_ADDR(v, i))
+                       return true;
+               if (reg == LPASS_HDMI_TX_CH_LSB_ADDR(v, i))
+                       return true;
+               if (reg == LPASS_HDMI_TX_CH_MSB_ADDR(v, i))
+                       return true;
        }
        return false;
 }
index 659b9ad..e12f824 100644 (file)
@@ -1213,9 +1213,11 @@ int snd_soc_pcm_component_pm_runtime_get(struct snd_soc_pcm_runtime *rtd,
        int i;
 
        for_each_rtd_components(rtd, i, component) {
-               int ret = pm_runtime_resume_and_get(component->dev);
-               if (ret < 0 && ret != -EACCES)
+               int ret = pm_runtime_get_sync(component->dev);
+               if (ret < 0 && ret != -EACCES) {
+                       pm_runtime_put_noidle(component->dev);
                        return soc_component_ret(component, ret);
+               }
                /* mark stream if succeeded */
                soc_component_mark_push(component, stream, pm);
        }
index 1e9afc4..f2ec2a6 100644 (file)
@@ -109,11 +109,6 @@ EXPORT_SYMBOL_NS(hda_codec_jack_check, SND_SOC_SOF_HDA_AUDIO_CODEC);
 #define is_generic_config(x)   0
 #endif
 
-static void hda_codec_device_exit(struct device *dev)
-{
-       snd_hdac_device_exit(dev_to_hdac_dev(dev));
-}
-
 static struct hda_codec *hda_codec_device_init(struct hdac_bus *bus, int addr, int type)
 {
        struct hda_codec *codec;
@@ -126,12 +121,11 @@ static struct hda_codec *hda_codec_device_init(struct hdac_bus *bus, int addr, i
        }
 
        codec->core.type = type;
-       codec->core.dev.release = hda_codec_device_exit;
 
        ret = snd_hdac_device_register(&codec->core);
        if (ret) {
                dev_err(bus->dev, "failed to register hdac device\n");
-               snd_hdac_device_exit(&codec->core);
+               put_device(&codec->core.dev);
                return ERR_PTR(ret);
        }
 
index 899b00d..9f39da9 100644 (file)
@@ -38,7 +38,7 @@ static const struct sof_dev_desc mtl_desc = {
                [SOF_INTEL_IPC4] = "intel/sof-ace-tplg",
        },
        .default_fw_filename = {
-               [SOF_INTEL_IPC4] = "dsp_basefw.bin",
+               [SOF_INTEL_IPC4] = "sof-mtl.ri",
        },
        .nocodec_tplg_filename = "sof-mtl-nocodec.tplg",
        .ops = &sof_mtl_ops,
index 2d63cc2..4cfe4f2 100644 (file)
@@ -159,6 +159,34 @@ static const struct sof_dev_desc adl_desc = {
        .ops_init = sof_tgl_ops_init,
 };
 
+static const struct sof_dev_desc adl_n_desc = {
+       .machines               = snd_soc_acpi_intel_adl_machines,
+       .alt_machines           = snd_soc_acpi_intel_adl_sdw_machines,
+       .use_acpi_target_states = true,
+       .resindex_lpe_base      = 0,
+       .resindex_pcicfg_base   = -1,
+       .resindex_imr_base      = -1,
+       .irqindex_host_ipc      = -1,
+       .chip_info = &tgl_chip_info,
+       .ipc_supported_mask     = BIT(SOF_IPC) | BIT(SOF_INTEL_IPC4),
+       .ipc_default            = SOF_IPC,
+       .default_fw_path = {
+               [SOF_IPC] = "intel/sof",
+               [SOF_INTEL_IPC4] = "intel/avs/adl-n",
+       },
+       .default_tplg_path = {
+               [SOF_IPC] = "intel/sof-tplg",
+               [SOF_INTEL_IPC4] = "intel/avs-tplg",
+       },
+       .default_fw_filename = {
+               [SOF_IPC] = "sof-adl-n.ri",
+               [SOF_INTEL_IPC4] = "dsp_basefw.bin",
+       },
+       .nocodec_tplg_filename = "sof-adl-nocodec.tplg",
+       .ops = &sof_tgl_ops,
+       .ops_init = sof_tgl_ops_init,
+};
+
 static const struct sof_dev_desc rpls_desc = {
        .machines               = snd_soc_acpi_intel_rpl_machines,
        .alt_machines           = snd_soc_acpi_intel_rpl_sdw_machines,
@@ -246,7 +274,7 @@ static const struct pci_device_id sof_pci_ids[] = {
        { PCI_DEVICE(0x8086, 0x51cf), /* RPL-PX */
                .driver_data = (unsigned long)&rpl_desc},
        { PCI_DEVICE(0x8086, 0x54c8), /* ADL-N */
-               .driver_data = (unsigned long)&adl_desc},
+               .driver_data = (unsigned long)&adl_n_desc},
        { 0, }
 };
 MODULE_DEVICE_TABLE(pci, sof_pci_ids);
index 9c70800..70dea8a 100644 (file)
@@ -108,6 +108,7 @@ struct sof_mtrace_core_data {
        int id;
        u32 slot_offset;
        void *log_buffer;
+       struct mutex buffer_lock; /* for log_buffer alloc/free */
        u32 host_read_ptr;
        u32 dsp_write_ptr;
        /* pos update IPC arrived before the slot offset is known, queried */
@@ -128,14 +129,22 @@ static int sof_ipc4_mtrace_dfs_open(struct inode *inode, struct file *file)
        struct sof_mtrace_core_data *core_data = inode->i_private;
        int ret;
 
+       mutex_lock(&core_data->buffer_lock);
+
+       if (core_data->log_buffer) {
+               ret = -EBUSY;
+               goto out;
+       }
+
        ret = debugfs_file_get(file->f_path.dentry);
        if (unlikely(ret))
-               return ret;
+               goto out;
 
        core_data->log_buffer = kmalloc(SOF_MTRACE_SLOT_SIZE, GFP_KERNEL);
        if (!core_data->log_buffer) {
                debugfs_file_put(file->f_path.dentry);
-               return -ENOMEM;
+               ret = -ENOMEM;
+               goto out;
        }
 
        ret = simple_open(inode, file);
@@ -144,6 +153,9 @@ static int sof_ipc4_mtrace_dfs_open(struct inode *inode, struct file *file)
                debugfs_file_put(file->f_path.dentry);
        }
 
+out:
+       mutex_unlock(&core_data->buffer_lock);
+
        return ret;
 }
 
@@ -280,7 +292,10 @@ static int sof_ipc4_mtrace_dfs_release(struct inode *inode, struct file *file)
 
        debugfs_file_put(file->f_path.dentry);
 
+       mutex_lock(&core_data->buffer_lock);
        kfree(core_data->log_buffer);
+       core_data->log_buffer = NULL;
+       mutex_unlock(&core_data->buffer_lock);
 
        return 0;
 }
@@ -563,6 +578,7 @@ static int ipc4_mtrace_init(struct snd_sof_dev *sdev)
                struct sof_mtrace_core_data *core_data = &priv->cores[i];
 
                init_waitqueue_head(&core_data->trace_sleep);
+               mutex_init(&core_data->buffer_lock);
                core_data->sdev = sdev;
                core_data->id = i;
        }
index 5ed8e36..a870759 100644 (file)
@@ -126,15 +126,10 @@ EXPORT_SYMBOL(snd_emux_register);
  */
 int snd_emux_free(struct snd_emux *emu)
 {
-       unsigned long flags;
-
        if (! emu)
                return -EINVAL;
 
-       spin_lock_irqsave(&emu->voice_lock, flags);
-       if (emu->timer_active)
-               del_timer(&emu->tlist);
-       spin_unlock_irqrestore(&emu->voice_lock, flags);
+       del_timer_sync(&emu->tlist);
 
        snd_emux_proc_free(emu);
        snd_emux_delete_virmidi(emu);
index e1bf1b5..f3e8484 100644 (file)
@@ -47,6 +47,8 @@ struct snd_usb_implicit_fb_match {
 static const struct snd_usb_implicit_fb_match playback_implicit_fb_quirks[] = {
        /* Fixed EP */
        /* FIXME: check the availability of generic matching */
+       IMPLICIT_FB_FIXED_DEV(0x0763, 0x2030, 0x81, 3), /* M-Audio Fast Track C400 */
+       IMPLICIT_FB_FIXED_DEV(0x0763, 0x2031, 0x81, 3), /* M-Audio Fast Track C600 */
        IMPLICIT_FB_FIXED_DEV(0x0763, 0x2080, 0x81, 2), /* M-Audio FastTrack Ultra */
        IMPLICIT_FB_FIXED_DEV(0x0763, 0x2081, 0x81, 2), /* M-Audio FastTrack Ultra */
        IMPLICIT_FB_FIXED_DEV(0x2466, 0x8010, 0x81, 2), /* Fractal Audio Axe-Fx III */
index a564195..9105ec6 100644 (file)
@@ -1631,7 +1631,7 @@ static void check_no_speaker_on_headset(struct snd_kcontrol *kctl,
        if (!found)
                return;
 
-       strscpy(kctl->id.name, "Headphone", sizeof(kctl->id.name));
+       snd_ctl_rename(card, kctl, "Headphone");
 }
 
 static const struct usb_feature_control_info *get_feature_control_info(int control)
index 8aa0d27..abc4186 100644 (file)
@@ -60,6 +60,7 @@
 #define ARM_CPU_IMP_FUJITSU            0x46
 #define ARM_CPU_IMP_HISI               0x48
 #define ARM_CPU_IMP_APPLE              0x61
+#define ARM_CPU_IMP_AMPERE             0xC0
 
 #define ARM_CPU_PART_AEM_V8            0xD0F
 #define ARM_CPU_PART_FOUNDATION                0xD00
 #define APPLE_CPU_PART_M1_ICESTORM_MAX 0x028
 #define APPLE_CPU_PART_M1_FIRESTORM_MAX        0x029
 
+#define AMPERE_CPU_PART_AMPERE1                0xAC3
+
 #define MIDR_CORTEX_A53 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A53)
 #define MIDR_CORTEX_A57 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A57)
 #define MIDR_CORTEX_A72 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A72)
 #define MIDR_APPLE_M1_FIRESTORM_PRO MIDR_CPU_MODEL(ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M1_FIRESTORM_PRO)
 #define MIDR_APPLE_M1_ICESTORM_MAX MIDR_CPU_MODEL(ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M1_ICESTORM_MAX)
 #define MIDR_APPLE_M1_FIRESTORM_MAX MIDR_CPU_MODEL(ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M1_FIRESTORM_MAX)
+#define MIDR_AMPERE1 MIDR_CPU_MODEL(ARM_CPU_IMP_AMPERE, AMPERE_CPU_PART_AMPERE1)
 
 /* Fujitsu Erratum 010001 affects A64FX 1.0 and 1.1, (v0r0 and v1r0) */
 #define MIDR_FUJITSU_ERRATUM_010001            MIDR_FUJITSU_A64FX
index ef4775c..b71f4f2 100644 (file)
@@ -96,7 +96,7 @@
 #define X86_FEATURE_SYSCALL32          ( 3*32+14) /* "" syscall in IA32 userspace */
 #define X86_FEATURE_SYSENTER32         ( 3*32+15) /* "" sysenter in IA32 userspace */
 #define X86_FEATURE_REP_GOOD           ( 3*32+16) /* REP microcode works well */
-/* FREE!                                ( 3*32+17) */
+#define X86_FEATURE_AMD_LBR_V2         ( 3*32+17) /* AMD Last Branch Record Extension Version 2 */
 #define X86_FEATURE_LFENCE_RDTSC       ( 3*32+18) /* "" LFENCE synchronizes RDTSC */
 #define X86_FEATURE_ACC_POWER          ( 3*32+19) /* AMD Accumulated Power Mechanism */
 #define X86_FEATURE_NOPL               ( 3*32+20) /* The NOPL (0F 1F) instructions */
index d0d7b9b..5418e2f 100644 (file)
@@ -27,7 +27,7 @@
  * Output:
  * rax original destination
  */
-SYM_FUNC_START(__memcpy)
+SYM_TYPED_FUNC_START(__memcpy)
        ALTERNATIVE_2 "jmp memcpy_orig", "", X86_FEATURE_REP_GOOD, \
                      "jmp memcpy_erms", X86_FEATURE_ERMS
 
index 57619f2..38f8851 100644 (file)
@@ -103,6 +103,7 @@ FEATURE_TESTS_EXTRA :=                  \
          libbpf-bpf_prog_load           \
          libbpf-bpf_object__next_program \
          libbpf-bpf_object__next_map    \
+         libbpf-bpf_program__set_insns  \
          libbpf-bpf_create_map         \
          libpfm4                        \
          libdebuginfod                 \
index 04b07ff..690fe97 100644 (file)
@@ -63,6 +63,7 @@ FILES=                                          \
          test-libbpf-bpf_map_create.bin                \
          test-libbpf-bpf_object__next_program.bin \
          test-libbpf-bpf_object__next_map.bin   \
+         test-libbpf-bpf_program__set_insns.bin        \
          test-libbpf-btf__raw_data.bin          \
          test-get_cpuid.bin                     \
          test-sdt.bin                           \
@@ -316,6 +317,9 @@ $(OUTPUT)test-libbpf-bpf_object__next_program.bin:
 $(OUTPUT)test-libbpf-bpf_object__next_map.bin:
        $(BUILD) -lbpf
 
+$(OUTPUT)test-libbpf-bpf_program__set_insns.bin:
+       $(BUILD) -lbpf
+
 $(OUTPUT)test-libbpf-btf__raw_data.bin:
        $(BUILD) -lbpf
 
diff --git a/tools/build/feature/test-libbpf-bpf_program__set_insns.c b/tools/build/feature/test-libbpf-bpf_program__set_insns.c
new file mode 100644 (file)
index 0000000..f3b7f18
--- /dev/null
@@ -0,0 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <bpf/libbpf.h>
+
+int main(void)
+{
+       bpf_program__set_insns(NULL /* prog */, NULL /* new_insns */, 0 /* new_insn_cnt */);
+       return 0;
+}
index 1416822..f243ce6 100644 (file)
@@ -68,6 +68,8 @@ enum {
 #define IPPROTO_PIM            IPPROTO_PIM
   IPPROTO_COMP = 108,          /* Compression Header Protocol          */
 #define IPPROTO_COMP           IPPROTO_COMP
+  IPPROTO_L2TP = 115,          /* Layer 2 Tunnelling Protocol          */
+#define IPPROTO_L2TP           IPPROTO_L2TP
   IPPROTO_SCTP = 132,          /* Stream Control Transport Protocol    */
 #define IPPROTO_SCTP           IPPROTO_SCTP
   IPPROTO_UDPLITE = 136,       /* UDP-Lite (RFC 3828)                  */
@@ -188,21 +190,13 @@ struct ip_mreq_source {
 };
 
 struct ip_msfilter {
+       __be32          imsf_multiaddr;
+       __be32          imsf_interface;
+       __u32           imsf_fmode;
+       __u32           imsf_numsrc;
        union {
-               struct {
-                       __be32          imsf_multiaddr_aux;
-                       __be32          imsf_interface_aux;
-                       __u32           imsf_fmode_aux;
-                       __u32           imsf_numsrc_aux;
-                       __be32          imsf_slist[1];
-               };
-               struct {
-                       __be32          imsf_multiaddr;
-                       __be32          imsf_interface;
-                       __u32           imsf_fmode;
-                       __u32           imsf_numsrc;
-                       __be32          imsf_slist_flex[];
-               };
+               __be32          imsf_slist[1];
+               __DECLARE_FLEX_ARRAY(__be32, imsf_slist_flex);
        };
 };
 
index ea6defa..ccb7f5d 100644 (file)
@@ -164,8 +164,6 @@ enum perf_event_sample_format {
        PERF_SAMPLE_WEIGHT_STRUCT               = 1U << 24,
 
        PERF_SAMPLE_MAX = 1U << 25,             /* non-ABI */
-
-       __PERF_SAMPLE_CALLCHAIN_EARLY           = 1ULL << 63, /* non-ABI; internal use */
 };
 
 #define PERF_SAMPLE_WEIGHT_TYPE        (PERF_SAMPLE_WEIGHT | PERF_SAMPLE_WEIGHT_STRUCT)
@@ -263,6 +261,17 @@ enum {
        PERF_BR_MAX,
 };
 
+/*
+ * Common branch speculation outcome classification
+ */
+enum {
+       PERF_BR_SPEC_NA                 = 0,    /* Not available */
+       PERF_BR_SPEC_WRONG_PATH         = 1,    /* Speculative but on wrong path */
+       PERF_BR_NON_SPEC_CORRECT_PATH   = 2,    /* Non-speculative but on correct path */
+       PERF_BR_SPEC_CORRECT_PATH       = 3,    /* Speculative and on correct path */
+       PERF_BR_SPEC_MAX,
+};
+
 enum {
        PERF_BR_NEW_FAULT_ALGN          = 0,    /* Alignment fault */
        PERF_BR_NEW_FAULT_DATA          = 1,    /* Data fault */
@@ -282,11 +291,11 @@ enum {
        PERF_BR_PRIV_HV         = 3,
 };
 
-#define PERF_BR_ARM64_FIQ              PERF_BR_NEW_ARCH_1
-#define PERF_BR_ARM64_DEBUG_HALT       PERF_BR_NEW_ARCH_2
-#define PERF_BR_ARM64_DEBUG_EXIT       PERF_BR_NEW_ARCH_3
-#define PERF_BR_ARM64_DEBUG_INST       PERF_BR_NEW_ARCH_4
-#define PERF_BR_ARM64_DEBUG_DATA       PERF_BR_NEW_ARCH_5
+#define PERF_BR_ARM64_FIQ              PERF_BR_NEW_ARCH_1
+#define PERF_BR_ARM64_DEBUG_HALT       PERF_BR_NEW_ARCH_2
+#define PERF_BR_ARM64_DEBUG_EXIT       PERF_BR_NEW_ARCH_3
+#define PERF_BR_ARM64_DEBUG_INST       PERF_BR_NEW_ARCH_4
+#define PERF_BR_ARM64_DEBUG_DATA       PERF_BR_NEW_ARCH_5
 
 #define PERF_SAMPLE_BRANCH_PLM_ALL \
        (PERF_SAMPLE_BRANCH_USER|\
@@ -1397,6 +1406,7 @@ union perf_mem_data_src {
  *     abort: aborting a hardware transaction
  *    cycles: cycles from last branch (or 0 if not supported)
  *      type: branch type
+ *      spec: branch speculation info (or 0 if not supported)
  */
 struct perf_branch_entry {
        __u64   from;
@@ -1407,9 +1417,10 @@ struct perf_branch_entry {
                abort:1,    /* transaction abort */
                cycles:16,  /* cycle count to last branch */
                type:4,     /* branch type */
+               spec:2,     /* branch speculation info */
                new_type:4, /* additional branch type */
                priv:3,     /* privilege level */
-               reserved:33;
+               reserved:31;
 };
 
 union perf_sample_weight {
index 1500a0f..7cab2c6 100644 (file)
@@ -124,7 +124,8 @@ struct statx {
        __u32   stx_dev_minor;
        /* 0x90 */
        __u64   stx_mnt_id;
-       __u64   __spare2;
+       __u32   stx_dio_mem_align;      /* Memory buffer alignment for direct I/O */
+       __u32   stx_dio_offset_align;   /* File offset alignment for direct I/O */
        /* 0xa0 */
        __u64   __spare3[12];   /* Spare space for future expansion */
        /* 0x100 */
@@ -152,6 +153,7 @@ struct statx {
 #define STATX_BASIC_STATS      0x000007ffU     /* The stuff in the normal stat struct */
 #define STATX_BTIME            0x00000800U     /* Want/got stx_btime */
 #define STATX_MNT_ID           0x00001000U     /* Got stx_mnt_id */
+#define STATX_DIOALIGN         0x00002000U     /* Want/got direct I/O alignment info */
 
 #define STATX__RESERVED                0x80000000U     /* Reserved for future struct statx expansion */
 
index 3974a2a..de6810e 100644 (file)
@@ -3,22 +3,6 @@
  *  Advanced Linux Sound Architecture - ALSA - Driver
  *  Copyright (c) 1994-2003 by Jaroslav Kysela <perex@perex.cz>,
  *                             Abramo Bagnara <abramo@alsa-project.org>
- *
- *
- *   This program is free software; you can redistribute it and/or modify
- *   it under the terms of the GNU General Public License as published by
- *   the Free Software Foundation; either version 2 of the License, or
- *   (at your option) any later version.
- *
- *   This program is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *   GNU General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
- *
  */
 
 #ifndef _UAPI__SOUND_ASOUND_H
index 6fd4b13..898226e 100644 (file)
@@ -588,6 +588,10 @@ ifndef NO_LIBELF
           ifeq ($(feature-libbpf-bpf_object__next_map), 1)
             CFLAGS += -DHAVE_LIBBPF_BPF_OBJECT__NEXT_MAP
           endif
+          $(call feature_check,libbpf-bpf_program__set_insns)
+          ifeq ($(feature-libbpf-bpf_program__set_insns), 1)
+            CFLAGS += -DHAVE_LIBBPF_BPF_PROGRAM__SET_INSNS
+          endif
           $(call feature_check,libbpf-btf__raw_data)
           ifeq ($(feature-libbpf-btf__raw_data), 1)
             CFLAGS += -DHAVE_LIBBPF_BTF__RAW_DATA
@@ -604,6 +608,7 @@ ifndef NO_LIBELF
         CFLAGS += -DHAVE_LIBBPF_BPF_PROG_LOAD
         CFLAGS += -DHAVE_LIBBPF_BPF_OBJECT__NEXT_PROGRAM
         CFLAGS += -DHAVE_LIBBPF_BPF_OBJECT__NEXT_MAP
+        CFLAGS += -DHAVE_LIBBPF_BPF_PROGRAM__SET_INSNS
         CFLAGS += -DHAVE_LIBBPF_BTF__RAW_DATA
         CFLAGS += -DHAVE_LIBBPF_BPF_MAP_CREATE
       endif
index 2bca64f..e9e0df4 100644 (file)
 176    64      rt_sigtimedwait                 sys_rt_sigtimedwait
 177    nospu   rt_sigqueueinfo                 sys_rt_sigqueueinfo             compat_sys_rt_sigqueueinfo
 178    nospu   rt_sigsuspend                   sys_rt_sigsuspend               compat_sys_rt_sigsuspend
-179    common  pread64                         sys_pread64                     compat_sys_ppc_pread64
-180    common  pwrite64                        sys_pwrite64                    compat_sys_ppc_pwrite64
+179    32      pread64                         sys_ppc_pread64                 compat_sys_ppc_pread64
+179    64      pread64                         sys_pread64
+180    32      pwrite64                        sys_ppc_pwrite64                compat_sys_ppc_pwrite64
+180    64      pwrite64                        sys_pwrite64
 181    common  chown                           sys_chown
 182    common  getcwd                          sys_getcwd
 183    common  capget                          sys_capget
 188    common  putpmsg                         sys_ni_syscall
 189    nospu   vfork                           sys_vfork
 190    common  ugetrlimit                      sys_getrlimit                   compat_sys_getrlimit
-191    common  readahead                       sys_readahead                   compat_sys_ppc_readahead
+191    32      readahead                       sys_ppc_readahead               compat_sys_ppc_readahead
+191    64      readahead                       sys_readahead
 192    32      mmap2                           sys_mmap2                       compat_sys_mmap2
-193    32      truncate64                      sys_truncate64                  compat_sys_ppc_truncate64
-194    32      ftruncate64                     sys_ftruncate64                 compat_sys_ppc_ftruncate64
+193    32      truncate64                      sys_ppc_truncate64              compat_sys_ppc_truncate64
+194    32      ftruncate64                     sys_ppc_ftruncate64             compat_sys_ppc_ftruncate64
 195    32      stat64                          sys_stat64
 196    32      lstat64                         sys_lstat64
 197    32      fstat64                         sys_fstat64
 230    common  io_submit                       sys_io_submit                   compat_sys_io_submit
 231    common  io_cancel                       sys_io_cancel
 232    nospu   set_tid_address                 sys_set_tid_address
-233    common  fadvise64                       sys_fadvise64                   compat_sys_ppc32_fadvise64
+233    32      fadvise64                       sys_ppc32_fadvise64             compat_sys_ppc32_fadvise64
+233    64      fadvise64                       sys_fadvise64
 234    nospu   exit_group                      sys_exit_group
 235    nospu   lookup_dcookie                  sys_lookup_dcookie              compat_sys_lookup_dcookie
 236    common  epoll_create                    sys_epoll_create
index 52d254b..e128b85 100644 (file)
@@ -649,7 +649,7 @@ static int record__pushfn(struct mmap *map, void *to, void *bf, size_t size)
 static volatile int signr = -1;
 static volatile int child_finished;
 #ifdef HAVE_EVENTFD_SUPPORT
-static int done_fd = -1;
+static volatile int done_fd = -1;
 #endif
 
 static void sig_handler(int sig)
@@ -661,19 +661,24 @@ static void sig_handler(int sig)
 
        done = 1;
 #ifdef HAVE_EVENTFD_SUPPORT
-{
-       u64 tmp = 1;
-       /*
-        * It is possible for this signal handler to run after done is checked
-        * in the main loop, but before the perf counter fds are polled. If this
-        * happens, the poll() will continue to wait even though done is set,
-        * and will only break out if either another signal is received, or the
-        * counters are ready for read. To ensure the poll() doesn't sleep when
-        * done is set, use an eventfd (done_fd) to wake up the poll().
-        */
-       if (write(done_fd, &tmp, sizeof(tmp)) < 0)
-               pr_err("failed to signal wakeup fd, error: %m\n");
-}
+       if (done_fd >= 0) {
+               u64 tmp = 1;
+               int orig_errno = errno;
+
+               /*
+                * It is possible for this signal handler to run after done is
+                * checked in the main loop, but before the perf counter fds are
+                * polled. If this happens, the poll() will continue to wait
+                * even though done is set, and will only break out if either
+                * another signal is received, or the counters are ready for
+                * read. To ensure the poll() doesn't sleep when done is set,
+                * use an eventfd (done_fd) to wake up the poll().
+                */
+               if (write(done_fd, &tmp, sizeof(tmp)) < 0)
+                       pr_err("failed to signal wakeup fd, error: %m\n");
+
+               errno = orig_errno;
+       }
 #endif // HAVE_EVENTFD_SUPPORT
 }
 
@@ -2834,8 +2839,12 @@ out_free_threads:
 
 out_delete_session:
 #ifdef HAVE_EVENTFD_SUPPORT
-       if (done_fd >= 0)
-               close(done_fd);
+       if (done_fd >= 0) {
+               fd = done_fd;
+               done_fd = -1;
+
+               close(fd);
+       }
 #endif
        zstd_fini(&session->zstd_data);
        perf_session__delete(session);
index 6ee44b1..eacca9a 100755 (executable)
@@ -143,7 +143,7 @@ for i in $SYNC_CHECK_FILES; do
 done
 
 # diff with extra ignore lines
-check arch/x86/lib/memcpy_64.S        '-I "^EXPORT_SYMBOL" -I "^#include <asm/export.h>" -I"^SYM_FUNC_START\(_LOCAL\)*(memcpy_\(erms\|orig\))"'
+check arch/x86/lib/memcpy_64.S        '-I "^EXPORT_SYMBOL" -I "^#include <asm/export.h>" -I"^SYM_FUNC_START\(_LOCAL\)*(memcpy_\(erms\|orig\))" -I"^#include <linux/cfi_types.h>"'
 check arch/x86/lib/memset_64.S        '-I "^EXPORT_SYMBOL" -I "^#include <asm/export.h>" -I"^SYM_FUNC_START\(_LOCAL\)*(memset_\(erms\|orig\))"'
 check arch/x86/include/asm/amd-ibs.h  '-I "^#include [<\"]\(asm/\)*msr-index.h"'
 check arch/arm64/include/asm/cputype.h '-I "^#include [<\"]\(asm/\)*sysreg.h"'
index 6970203..6443a06 100644 (file)
         "MetricName": "indirect_branch"
     },
     {
-        "MetricExpr": "(armv8_pmuv3_0@event\\=0x1014@ + armv8_pmuv3_0@event\\=0x1018@) / BR_MIS_PRED",
+        "MetricExpr": "(armv8_pmuv3_0@event\\=0x1013@ + armv8_pmuv3_0@event\\=0x1016@) / BR_MIS_PRED",
         "PublicDescription": "Push branch L3 topdown metric",
         "BriefDescription": "Push branch L3 topdown metric",
         "MetricGroup": "TopDownL3",
         "MetricName": "push_branch"
     },
     {
-        "MetricExpr": "armv8_pmuv3_0@event\\=0x100c@ / BR_MIS_PRED",
+        "MetricExpr": "armv8_pmuv3_0@event\\=0x100d@ / BR_MIS_PRED",
         "PublicDescription": "Pop branch L3 topdown metric",
         "BriefDescription": "Pop branch L3 topdown metric",
         "MetricGroup": "TopDownL3",
         "MetricName": "pop_branch"
     },
     {
-        "MetricExpr": "(BR_MIS_PRED - armv8_pmuv3_0@event\\=0x1010@ - armv8_pmuv3_0@event\\=0x1014@ - armv8_pmuv3_0@event\\=0x1018@ - armv8_pmuv3_0@event\\=0x100c@) / BR_MIS_PRED",
+        "MetricExpr": "(BR_MIS_PRED - armv8_pmuv3_0@event\\=0x1010@ - armv8_pmuv3_0@event\\=0x1013@ - armv8_pmuv3_0@event\\=0x1016@ - armv8_pmuv3_0@event\\=0x100d@) / BR_MIS_PRED",
         "PublicDescription": "Other branch L3 topdown metric",
         "BriefDescription": "Other branch L3 topdown metric",
         "MetricGroup": "TopDownL3",
index 8ba3e81..fe050d4 100644 (file)
@@ -1,13 +1,13 @@
 [
     {
       "MetricName": "VEC_GROUP_PUMP_RETRY_RATIO_P01",
-      "MetricExpr": "(hv_24x7@PM_PB_RTY_VG_PUMP01\\,chip\\=?@ / hv_24x7@PM_PB_VG_PUMP01\\,chip\\=?@) * 100",
+      "MetricExpr": "(hv_24x7@PM_PB_RTY_VG_PUMP01\\,chip\\=?@ / (1 + hv_24x7@PM_PB_VG_PUMP01\\,chip\\=?@)) * 100",
       "ScaleUnit": "1%",
       "AggregationMode": "PerChip"
     },
     {
       "MetricName": "VEC_GROUP_PUMP_RETRY_RATIO_P23",
-      "MetricExpr": "(hv_24x7@PM_PB_RTY_VG_PUMP23\\,chip\\=?@ / hv_24x7@PM_PB_VG_PUMP23\\,chip\\=?@) * 100",
+      "MetricExpr": "(hv_24x7@PM_PB_RTY_VG_PUMP23\\,chip\\=?@ / (1 + hv_24x7@PM_PB_VG_PUMP23\\,chip\\=?@)) * 100",
       "ScaleUnit": "1%",
       "AggregationMode": "PerChip"
     },
     },
     {
       "MetricName": "REMOTE_NODE_PUMPS_RETRIES_RATIO_P01",
-      "MetricExpr": "(hv_24x7@PM_PB_RTY_RNS_PUMP01\\,chip\\=?@ / hv_24x7@PM_PB_RNS_PUMP01\\,chip\\=?@) * 100",
+      "MetricExpr": "(hv_24x7@PM_PB_RTY_RNS_PUMP01\\,chip\\=?@ / (1 + hv_24x7@PM_PB_RNS_PUMP01\\,chip\\=?@)) * 100",
       "ScaleUnit": "1%",
       "AggregationMode": "PerChip"
     },
     {
       "MetricName": "REMOTE_NODE_PUMPS_RETRIES_RATIO_P23",
-      "MetricExpr": "(hv_24x7@PM_PB_RTY_RNS_PUMP23\\,chip\\=?@ / hv_24x7@PM_PB_RNS_PUMP23\\,chip\\=?@) * 100",
+      "MetricExpr": "(hv_24x7@PM_PB_RTY_RNS_PUMP23\\,chip\\=?@ / (1 + hv_24x7@PM_PB_RNS_PUMP23\\,chip\\=?@)) * 100",
       "ScaleUnit": "1%",
       "AggregationMode": "PerChip"
     },
     },
     {
       "MetricName": "XLINK0_OUT_TOTAL_UTILIZATION",
-      "MetricExpr": "((hv_24x7@PM_XLINK0_OUT_ODD_TOTAL_UTIL\\,chip\\=?@ + hv_24x7@PM_XLINK0_OUT_EVEN_TOTAL_UTIL\\,chip\\=?@) / (hv_24x7@PM_XLINK0_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_XLINK0_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
+      "MetricExpr": "((hv_24x7@PM_XLINK0_OUT_ODD_TOTAL_UTIL\\,chip\\=?@ + hv_24x7@PM_XLINK0_OUT_EVEN_TOTAL_UTIL\\,chip\\=?@) / (1 + hv_24x7@PM_XLINK0_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_XLINK0_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
       "ScaleUnit": "1%",
       "AggregationMode": "PerChip"
     },
     {
       "MetricName": "XLINK1_OUT_TOTAL_UTILIZATION",
-      "MetricExpr": "((hv_24x7@PM_XLINK1_OUT_ODD_TOTAL_UTIL\\,chip\\=?@ + hv_24x7@PM_XLINK1_OUT_EVEN_TOTAL_UTIL\\,chip\\=?@) / (hv_24x7@PM_XLINK1_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_XLINK1_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
+      "MetricExpr": "((hv_24x7@PM_XLINK1_OUT_ODD_TOTAL_UTIL\\,chip\\=?@ + hv_24x7@PM_XLINK1_OUT_EVEN_TOTAL_UTIL\\,chip\\=?@) / (1 + hv_24x7@PM_XLINK1_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_XLINK1_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
       "ScaleUnit": "1%",
       "AggregationMode": "PerChip"
     },
     {
       "MetricName": "XLINK2_OUT_TOTAL_UTILIZATION",
-      "MetricExpr": "((hv_24x7@PM_XLINK2_OUT_ODD_TOTAL_UTIL\\,chip\\=?@ + hv_24x7@PM_XLINK2_OUT_EVEN_TOTAL_UTIL\\,chip\\=?@) / (hv_24x7@PM_XLINK2_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_XLINK2_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
+      "MetricExpr": "((hv_24x7@PM_XLINK2_OUT_ODD_TOTAL_UTIL\\,chip\\=?@ + hv_24x7@PM_XLINK2_OUT_EVEN_TOTAL_UTIL\\,chip\\=?@) / (1 + hv_24x7@PM_XLINK2_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_XLINK2_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
       "ScaleUnit": "1%",
       "AggregationMode": "PerChip"
     },
     {
       "MetricName": "XLINK3_OUT_TOTAL_UTILIZATION",
-      "MetricExpr": "((hv_24x7@PM_XLINK3_OUT_ODD_TOTAL_UTIL\\,chip\\=?@ + hv_24x7@PM_XLINK3_OUT_EVEN_TOTAL_UTIL\\,chip\\=?@) / (hv_24x7@PM_XLINK3_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_XLINK3_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
+      "MetricExpr": "((hv_24x7@PM_XLINK3_OUT_ODD_TOTAL_UTIL\\,chip\\=?@ + hv_24x7@PM_XLINK3_OUT_EVEN_TOTAL_UTIL\\,chip\\=?@) / (1 + hv_24x7@PM_XLINK3_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_XLINK3_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
       "ScaleUnit": "1%",
       "AggregationMode": "PerChip"
     },
     {
       "MetricName": "XLINK4_OUT_TOTAL_UTILIZATION",
-      "MetricExpr": "((hv_24x7@PM_XLINK4_OUT_ODD_TOTAL_UTIL\\,chip\\=?@ + hv_24x7@PM_XLINK4_OUT_EVEN_TOTAL_UTIL\\,chip\\=?@) / (hv_24x7@PM_XLINK4_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_XLINK4_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
+      "MetricExpr": "((hv_24x7@PM_XLINK4_OUT_ODD_TOTAL_UTIL\\,chip\\=?@ + hv_24x7@PM_XLINK4_OUT_EVEN_TOTAL_UTIL\\,chip\\=?@) / (1 + hv_24x7@PM_XLINK4_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_XLINK4_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
       "ScaleUnit": "1%",
       "AggregationMode": "PerChip"
     },
     {
       "MetricName": "XLINK5_OUT_TOTAL_UTILIZATION",
-      "MetricExpr": "((hv_24x7@PM_XLINK5_OUT_ODD_TOTAL_UTIL\\,chip\\=?@ + hv_24x7@PM_XLINK5_OUT_EVEN_TOTAL_UTIL\\,chip\\=?@) / (hv_24x7@PM_XLINK5_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_XLINK5_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
+      "MetricExpr": "((hv_24x7@PM_XLINK5_OUT_ODD_TOTAL_UTIL\\,chip\\=?@ + hv_24x7@PM_XLINK5_OUT_EVEN_TOTAL_UTIL\\,chip\\=?@) / (1 + hv_24x7@PM_XLINK5_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_XLINK5_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
       "ScaleUnit": "1%",
       "AggregationMode": "PerChip"
     },
     {
       "MetricName": "XLINK6_OUT_TOTAL_UTILIZATION",
-      "MetricExpr": "((hv_24x7@PM_XLINK6_OUT_ODD_TOTAL_UTIL\\,chip\\=?@ + hv_24x7@PM_XLINK6_OUT_EVEN_TOTAL_UTIL\\,chip\\=?@) / (hv_24x7@PM_XLINK6_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_XLINK6_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
+      "MetricExpr": "((hv_24x7@PM_XLINK6_OUT_ODD_TOTAL_UTIL\\,chip\\=?@ + hv_24x7@PM_XLINK6_OUT_EVEN_TOTAL_UTIL\\,chip\\=?@) / (1 + hv_24x7@PM_XLINK6_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_XLINK6_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
       "ScaleUnit": "1%",
       "AggregationMode": "PerChip"
     },
     {
       "MetricName": "XLINK7_OUT_TOTAL_UTILIZATION",
-      "MetricExpr": "((hv_24x7@PM_XLINK7_OUT_ODD_TOTAL_UTIL\\,chip\\=?@ + hv_24x7@PM_XLINK7_OUT_EVEN_TOTAL_UTIL\\,chip\\=?@) / (hv_24x7@PM_XLINK7_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_XLINK7_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
+      "MetricExpr": "((hv_24x7@PM_XLINK7_OUT_ODD_TOTAL_UTIL\\,chip\\=?@ + hv_24x7@PM_XLINK7_OUT_EVEN_TOTAL_UTIL\\,chip\\=?@) / (1 + hv_24x7@PM_XLINK7_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_XLINK7_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
       "ScaleUnit": "1%",
       "AggregationMode": "PerChip"
     },
     {
       "MetricName": "XLINK0_OUT_DATA_UTILIZATION",
-      "MetricExpr": "((hv_24x7@PM_XLINK0_OUT_ODD_DATA\\,chip\\=?@ + hv_24x7@PM_XLINK0_OUT_EVEN_DATA\\,chip\\=?@) / (hv_24x7@PM_XLINK0_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_XLINK0_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
+      "MetricExpr": "((hv_24x7@PM_XLINK0_OUT_ODD_DATA\\,chip\\=?@ + hv_24x7@PM_XLINK0_OUT_EVEN_DATA\\,chip\\=?@) / (1 + hv_24x7@PM_XLINK0_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_XLINK0_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
       "ScaleUnit": "1.063%",
       "AggregationMode": "PerChip"
     },
     {
       "MetricName": "XLINK1_OUT_DATA_UTILIZATION",
-      "MetricExpr": "((hv_24x7@PM_XLINK1_OUT_ODD_DATA\\,chip\\=?@ + hv_24x7@PM_XLINK1_OUT_EVEN_DATA\\,chip\\=?@) / (hv_24x7@PM_XLINK1_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_XLINK1_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
+      "MetricExpr": "((hv_24x7@PM_XLINK1_OUT_ODD_DATA\\,chip\\=?@ + hv_24x7@PM_XLINK1_OUT_EVEN_DATA\\,chip\\=?@) / (1 + hv_24x7@PM_XLINK1_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_XLINK1_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
       "ScaleUnit": "1.063%",
       "AggregationMode": "PerChip"
     },
     {
       "MetricName": "XLINK2_OUT_DATA_UTILIZATION",
-      "MetricExpr": "((hv_24x7@PM_XLINK2_OUT_ODD_DATA\\,chip\\=?@ + hv_24x7@PM_XLINK2_OUT_EVEN_DATA\\,chip\\=?@) / (hv_24x7@PM_XLINK2_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_XLINK2_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
+      "MetricExpr": "((hv_24x7@PM_XLINK2_OUT_ODD_DATA\\,chip\\=?@ + hv_24x7@PM_XLINK2_OUT_EVEN_DATA\\,chip\\=?@) / (1 + hv_24x7@PM_XLINK2_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_XLINK2_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
       "ScaleUnit": "1.063%",
       "AggregationMode": "PerChip"
     },
     {
       "MetricName": "XLINK3_OUT_DATA_UTILIZATION",
-      "MetricExpr": "((hv_24x7@PM_XLINK3_OUT_ODD_DATA\\,chip\\=?@ + hv_24x7@PM_XLINK3_OUT_EVEN_DATA\\,chip\\=?@) / (hv_24x7@PM_XLINK3_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_XLINK3_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
+      "MetricExpr": "((hv_24x7@PM_XLINK3_OUT_ODD_DATA\\,chip\\=?@ + hv_24x7@PM_XLINK3_OUT_EVEN_DATA\\,chip\\=?@) / (1 + hv_24x7@PM_XLINK3_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_XLINK3_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
       "ScaleUnit": "1.063%",
       "AggregationMode": "PerChip"
     },
     {
       "MetricName": "XLINK4_OUT_DATA_UTILIZATION",
-      "MetricExpr": "((hv_24x7@PM_XLINK4_OUT_ODD_DATA\\,chip\\=?@ + hv_24x7@PM_XLINK4_OUT_EVEN_DATA\\,chip\\=?@) / (hv_24x7@PM_XLINK4_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_XLINK4_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
+      "MetricExpr": "((hv_24x7@PM_XLINK4_OUT_ODD_DATA\\,chip\\=?@ + hv_24x7@PM_XLINK4_OUT_EVEN_DATA\\,chip\\=?@) / (1 + hv_24x7@PM_XLINK4_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_XLINK4_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
       "ScaleUnit": "1.063%",
       "AggregationMode": "PerChip"
     },
     {
       "MetricName": "XLINK5_OUT_DATA_UTILIZATION",
-      "MetricExpr": "((hv_24x7@PM_XLINK5_OUT_ODD_DATA\\,chip\\=?@ + hv_24x7@PM_XLINK5_OUT_EVEN_DATA\\,chip\\=?@) / (hv_24x7@PM_XLINK5_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_XLINK5_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
+      "MetricExpr": "((hv_24x7@PM_XLINK5_OUT_ODD_DATA\\,chip\\=?@ + hv_24x7@PM_XLINK5_OUT_EVEN_DATA\\,chip\\=?@) / (1 + hv_24x7@PM_XLINK5_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_XLINK5_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
       "ScaleUnit": "1.063%",
       "AggregationMode": "PerChip"
     },
     {
       "MetricName": "XLINK6_OUT_DATA_UTILIZATION",
-      "MetricExpr": "((hv_24x7@PM_XLINK6_OUT_ODD_DATA\\,chip\\=?@ + hv_24x7@PM_XLINK6_OUT_EVEN_DATA\\,chip\\=?@) / (hv_24x7@PM_XLINK6_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_XLINK6_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
+      "MetricExpr": "((hv_24x7@PM_XLINK6_OUT_ODD_DATA\\,chip\\=?@ + hv_24x7@PM_XLINK6_OUT_EVEN_DATA\\,chip\\=?@) / (1 + hv_24x7@PM_XLINK6_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_XLINK6_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
       "ScaleUnit": "1.063%",
       "AggregationMode": "PerChip"
     },
     {
       "MetricName": "XLINK7_OUT_DATA_UTILIZATION",
-      "MetricExpr": "((hv_24x7@PM_XLINK7_OUT_ODD_DATA\\,chip\\=?@ + hv_24x7@PM_XLINK7_OUT_EVEN_DATA\\,chip\\=?@) / (hv_24x7@PM_XLINK7_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_XLINK7_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
+      "MetricExpr": "((hv_24x7@PM_XLINK7_OUT_ODD_DATA\\,chip\\=?@ + hv_24x7@PM_XLINK7_OUT_EVEN_DATA\\,chip\\=?@) / (1 + hv_24x7@PM_XLINK7_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_XLINK7_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
       "ScaleUnit": "1.063%",
       "AggregationMode": "PerChip"
     },
     {
       "MetricName": "ALINK0_OUT_TOTAL_UTILIZATION",
-      "MetricExpr": "((hv_24x7@PM_ALINK0_OUT_ODD_TOTAL_UTIL\\,chip\\=?@ + hv_24x7@PM_ALINK0_OUT_EVEN_TOTAL_UTIL\\,chip\\=?@) / (hv_24x7@PM_ALINK0_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_ALINK0_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
+      "MetricExpr": "((hv_24x7@PM_ALINK0_OUT_ODD_TOTAL_UTIL\\,chip\\=?@ + hv_24x7@PM_ALINK0_OUT_EVEN_TOTAL_UTIL\\,chip\\=?@) / (1 + hv_24x7@PM_ALINK0_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_ALINK0_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
       "ScaleUnit": "1%",
       "AggregationMode": "PerChip"
     },
     {
       "MetricName": "ALINK1_OUT_TOTAL_UTILIZATION",
-      "MetricExpr": "((hv_24x7@PM_ALINK1_OUT_ODD_TOTAL_UTIL\\,chip\\=?@ + hv_24x7@PM_ALINK1_OUT_EVEN_TOTAL_UTIL\\,chip\\=?@) / (hv_24x7@PM_ALINK1_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_ALINK1_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
+      "MetricExpr": "((hv_24x7@PM_ALINK1_OUT_ODD_TOTAL_UTIL\\,chip\\=?@ + hv_24x7@PM_ALINK1_OUT_EVEN_TOTAL_UTIL\\,chip\\=?@) / (1 + hv_24x7@PM_ALINK1_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_ALINK1_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
       "ScaleUnit": "1%",
       "AggregationMode": "PerChip"
     },
     {
       "MetricName": "ALINK2_OUT_TOTAL_UTILIZATION",
-      "MetricExpr": "((hv_24x7@PM_ALINK2_OUT_ODD_TOTAL_UTIL\\,chip\\=?@ + hv_24x7@PM_ALINK2_OUT_EVEN_TOTAL_UTIL\\,chip\\=?@) / (hv_24x7@PM_ALINK2_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_ALINK2_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
+      "MetricExpr": "((hv_24x7@PM_ALINK2_OUT_ODD_TOTAL_UTIL\\,chip\\=?@ + hv_24x7@PM_ALINK2_OUT_EVEN_TOTAL_UTIL\\,chip\\=?@) / (1 + hv_24x7@PM_ALINK2_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_ALINK2_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
       "ScaleUnit": "1%",
       "AggregationMode": "PerChip"
     },
     {
       "MetricName": "ALINK3_OUT_TOTAL_UTILIZATION",
-      "MetricExpr": "((hv_24x7@PM_ALINK3_OUT_ODD_TOTAL_UTIL\\,chip\\=?@ + hv_24x7@PM_ALINK3_OUT_EVEN_TOTAL_UTIL\\,chip\\=?@) / (hv_24x7@PM_ALINK3_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_ALINK3_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
+      "MetricExpr": "((hv_24x7@PM_ALINK3_OUT_ODD_TOTAL_UTIL\\,chip\\=?@ + hv_24x7@PM_ALINK3_OUT_EVEN_TOTAL_UTIL\\,chip\\=?@) / (1 + hv_24x7@PM_ALINK3_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_ALINK3_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
       "ScaleUnit": "1%",
       "AggregationMode": "PerChip"
     },
     {
       "MetricName": "ALINK4_OUT_TOTAL_UTILIZATION",
-      "MetricExpr": "((hv_24x7@PM_ALINK4_OUT_ODD_TOTAL_UTIL\\,chip\\=?@ + hv_24x7@PM_ALINK4_OUT_EVEN_TOTAL_UTIL\\,chip\\=?@) / (hv_24x7@PM_ALINK4_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_ALINK4_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
+      "MetricExpr": "((hv_24x7@PM_ALINK4_OUT_ODD_TOTAL_UTIL\\,chip\\=?@ + hv_24x7@PM_ALINK4_OUT_EVEN_TOTAL_UTIL\\,chip\\=?@) / (1 + hv_24x7@PM_ALINK4_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_ALINK4_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
       "ScaleUnit": "1%",
       "AggregationMode": "PerChip"
     },
     {
       "MetricName": "ALINK5_OUT_TOTAL_UTILIZATION",
-      "MetricExpr": "((hv_24x7@PM_ALINK5_OUT_ODD_TOTAL_UTIL\\,chip\\=?@ + hv_24x7@PM_ALINK5_OUT_EVEN_TOTAL_UTIL\\,chip\\=?@) / (hv_24x7@PM_ALINK5_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_ALINK5_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
+      "MetricExpr": "((hv_24x7@PM_ALINK5_OUT_ODD_TOTAL_UTIL\\,chip\\=?@ + hv_24x7@PM_ALINK5_OUT_EVEN_TOTAL_UTIL\\,chip\\=?@) / (1 + hv_24x7@PM_ALINK5_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_ALINK5_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
       "ScaleUnit": "1%",
       "AggregationMode": "PerChip"
     },
     {
       "MetricName": "ALINK6_OUT_TOTAL_UTILIZATION",
-      "MetricExpr": "((hv_24x7@PM_ALINK6_OUT_ODD_TOTAL_UTIL\\,chip\\=?@ + hv_24x7@PM_ALINK6_OUT_EVEN_TOTAL_UTIL\\,chip\\=?@) / (hv_24x7@PM_ALINK6_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_ALINK6_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
+      "MetricExpr": "((hv_24x7@PM_ALINK6_OUT_ODD_TOTAL_UTIL\\,chip\\=?@ + hv_24x7@PM_ALINK6_OUT_EVEN_TOTAL_UTIL\\,chip\\=?@) / (1 + hv_24x7@PM_ALINK6_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_ALINK6_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
       "ScaleUnit": "1%",
       "AggregationMode": "PerChip"
     },
     {
       "MetricName": "ALINK7_OUT_TOTAL_UTILIZATION",
-      "MetricExpr": "((hv_24x7@PM_ALINK7_OUT_ODD_TOTAL_UTIL\\,chip\\=?@ + hv_24x7@PM_ALINK7_OUT_EVEN_TOTAL_UTIL\\,chip\\=?@) / (hv_24x7@PM_ALINK7_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_ALINK7_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
+      "MetricExpr": "((hv_24x7@PM_ALINK7_OUT_ODD_TOTAL_UTIL\\,chip\\=?@ + hv_24x7@PM_ALINK7_OUT_EVEN_TOTAL_UTIL\\,chip\\=?@) / (1 + hv_24x7@PM_ALINK7_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_ALINK7_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
       "ScaleUnit": "1%",
       "AggregationMode": "PerChip"
     },
     {
       "MetricName": "ALINK0_OUT_DATA_UTILIZATION",
-      "MetricExpr": "((hv_24x7@PM_ALINK0_OUT_ODD_DATA\\,chip\\=?@ + hv_24x7@PM_ALINK0_OUT_EVEN_DATA\\,chip\\=?@) / (hv_24x7@PM_ALINK0_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_ALINK0_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
+      "MetricExpr": "((hv_24x7@PM_ALINK0_OUT_ODD_DATA\\,chip\\=?@ + hv_24x7@PM_ALINK0_OUT_EVEN_DATA\\,chip\\=?@) / (1 + hv_24x7@PM_ALINK0_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_ALINK0_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
       "ScaleUnit": "1.063%",
       "AggregationMode": "PerChip"
     },
     {
       "MetricName": "ALINK1_OUT_DATA_UTILIZATION",
-      "MetricExpr": "((hv_24x7@PM_ALINK1_OUT_ODD_DATA\\,chip\\=?@ + hv_24x7@PM_ALINK1_OUT_EVEN_DATA\\,chip\\=?@) / (hv_24x7@PM_ALINK1_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_ALINK1_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
+      "MetricExpr": "((hv_24x7@PM_ALINK1_OUT_ODD_DATA\\,chip\\=?@ + hv_24x7@PM_ALINK1_OUT_EVEN_DATA\\,chip\\=?@) / (1 + hv_24x7@PM_ALINK1_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_ALINK1_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
       "ScaleUnit": "1.063%",
       "AggregationMode": "PerChip"
     },
     {
       "MetricName": "ALINK2_OUT_DATA_UTILIZATION",
-      "MetricExpr": "((hv_24x7@PM_ALINK2_OUT_ODD_DATA\\,chip\\=?@ + hv_24x7@PM_ALINK2_OUT_EVEN_DATA\\,chip\\=?@) / (hv_24x7@PM_ALINK2_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_ALINK2_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
+      "MetricExpr": "((hv_24x7@PM_ALINK2_OUT_ODD_DATA\\,chip\\=?@ + hv_24x7@PM_ALINK2_OUT_EVEN_DATA\\,chip\\=?@) / (1 + hv_24x7@PM_ALINK2_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_ALINK2_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
       "ScaleUnit": "1.063%",
       "AggregationMode": "PerChip"
     },
     {
       "MetricName": "ALINK3_OUT_DATA_UTILIZATION",
-      "MetricExpr": "((hv_24x7@PM_ALINK3_OUT_ODD_DATA\\,chip\\=?@ + hv_24x7@PM_ALINK3_OUT_EVEN_DATA\\,chip\\=?@) / (hv_24x7@PM_ALINK3_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_ALINK3_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
+      "MetricExpr": "((hv_24x7@PM_ALINK3_OUT_ODD_DATA\\,chip\\=?@ + hv_24x7@PM_ALINK3_OUT_EVEN_DATA\\,chip\\=?@) / (1 + hv_24x7@PM_ALINK3_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_ALINK3_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
       "ScaleUnit": "1.063%",
       "AggregationMode": "PerChip"
     },
     {
       "MetricName": "ALINK4_OUT_DATA_UTILIZATION",
-      "MetricExpr": "((hv_24x7@PM_ALINK4_OUT_ODD_DATA\\,chip\\=?@ + hv_24x7@PM_ALINK4_OUT_EVEN_DATA\\,chip\\=?@) / (hv_24x7@PM_ALINK4_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_ALINK4_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
+      "MetricExpr": "((hv_24x7@PM_ALINK4_OUT_ODD_DATA\\,chip\\=?@ + hv_24x7@PM_ALINK4_OUT_EVEN_DATA\\,chip\\=?@) / (1 + hv_24x7@PM_ALINK4_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_ALINK4_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
       "ScaleUnit": "1.063%",
       "AggregationMode": "PerChip"
     },
     {
       "MetricName": "ALINK5_OUT_DATA_UTILIZATION",
-      "MetricExpr": "((hv_24x7@PM_ALINK5_OUT_ODD_DATA\\,chip\\=?@ + hv_24x7@PM_ALINK5_OUT_EVEN_DATA\\,chip\\=?@) / (hv_24x7@PM_ALINK5_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_ALINK5_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
+      "MetricExpr": "((hv_24x7@PM_ALINK5_OUT_ODD_DATA\\,chip\\=?@ + hv_24x7@PM_ALINK5_OUT_EVEN_DATA\\,chip\\=?@) / (1 + hv_24x7@PM_ALINK5_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_ALINK5_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
       "ScaleUnit": "1.063%",
       "AggregationMode": "PerChip"
     },
     {
       "MetricName": "ALINK6_OUT_DATA_UTILIZATION",
-      "MetricExpr": "((hv_24x7@PM_ALINK6_OUT_ODD_DATA\\,chip\\=?@ + hv_24x7@PM_ALINK6_OUT_EVEN_DATA\\,chip\\=?@) / (hv_24x7@PM_ALINK6_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_ALINK6_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
+      "MetricExpr": "((hv_24x7@PM_ALINK6_OUT_ODD_DATA\\,chip\\=?@ + hv_24x7@PM_ALINK6_OUT_EVEN_DATA\\,chip\\=?@) / (1 + hv_24x7@PM_ALINK6_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_ALINK6_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
       "ScaleUnit": "1.063%",
       "AggregationMode": "PerChip"
     },
     {
       "MetricName": "ALINK7_OUT_DATA_UTILIZATION",
-      "MetricExpr": "((hv_24x7@PM_ALINK7_OUT_ODD_DATA\\,chip\\=?@ + hv_24x7@PM_ALINK7_OUT_EVEN_DATA\\,chip\\=?@) / (hv_24x7@PM_ALINK7_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_ALINK7_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
+      "MetricExpr": "((hv_24x7@PM_ALINK7_OUT_ODD_DATA\\,chip\\=?@ + hv_24x7@PM_ALINK7_OUT_EVEN_DATA\\,chip\\=?@) / (1 + hv_24x7@PM_ALINK7_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_ALINK7_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
       "ScaleUnit": "1.063%",
       "AggregationMode": "PerChip"
     },
index 4c0aabb..f5ed7b1 100755 (executable)
@@ -526,6 +526,12 @@ test_kernel_trace()
 test_virtual_lbr()
 {
        echo "--- Test virtual LBR ---"
+       # Check if python script is supported
+       libpython=$(perf version --build-options | grep python | grep -cv OFF)
+       if [ "${libpython}" != "1" ] ; then
+               echo "SKIP: python scripting is not supported"
+               return 2
+       fi
 
        # Python script to determine the maximum size of branch stacks
        cat << "_end_of_file_" > "${maxbrstack}"
index 110f0c6..5f5320f 100644 (file)
@@ -66,6 +66,7 @@ size_t syscall_arg__scnprintf_statx_mask(char *bf, size_t size, struct syscall_a
        P_FLAG(BLOCKS);
        P_FLAG(BTIME);
        P_FLAG(MNT_ID);
+       P_FLAG(DIOALIGN);
 
 #undef P_FLAG
 
index 60d8beb..46ada5e 100644 (file)
@@ -2325,11 +2325,19 @@ struct sym_args {
        bool            near;
 };
 
+static bool kern_sym_name_match(const char *kname, const char *name)
+{
+       size_t n = strlen(name);
+
+       return !strcmp(kname, name) ||
+              (!strncmp(kname, name, n) && kname[n] == '\t');
+}
+
 static bool kern_sym_match(struct sym_args *args, const char *name, char type)
 {
        /* A function with the same name, and global or the n'th found or any */
        return kallsyms__is_function(type) &&
-              !strcmp(name, args->name) &&
+              kern_sym_name_match(name, args->name) &&
               ((args->global && isupper(type)) ||
                (args->selected && ++(args->cnt) == args->idx) ||
                (!args->global && !args->selected));
index eee64dd..cc7c1f9 100644 (file)
@@ -36,6 +36,11 @@ struct btf *btf__load_from_kernel_by_id(__u32 id)
 #endif
 
 #ifndef HAVE_LIBBPF_BPF_PROG_LOAD
+LIBBPF_API int bpf_load_program(enum bpf_prog_type type,
+                               const struct bpf_insn *insns, size_t insns_cnt,
+                               const char *license, __u32 kern_version,
+                               char *log_buf, size_t log_buf_sz);
+
 int bpf_prog_load(enum bpf_prog_type prog_type,
                  const char *prog_name __maybe_unused,
                  const char *license,
index d657594..f4adecc 100644 (file)
 
 #include <internal/xyarray.h>
 
+#ifndef HAVE_LIBBPF_BPF_PROGRAM__SET_INSNS
+int bpf_program__set_insns(struct bpf_program *prog __maybe_unused,
+                          struct bpf_insn *new_insns __maybe_unused, size_t new_insn_cnt __maybe_unused)
+{
+       pr_err("%s: not support, update libbpf\n", __func__);
+       return -ENOTSUP;
+}
+
+int libbpf_register_prog_handler(const char *sec __maybe_unused,
+                                 enum bpf_prog_type prog_type __maybe_unused,
+                                 enum bpf_attach_type exp_attach_type __maybe_unused,
+                                 const struct libbpf_prog_handler_opts *opts __maybe_unused)
+{
+       pr_err("%s: not support, update libbpf\n", __func__);
+       return -ENOTSUP;
+}
+#endif
+
 /* temporarily disable libbpf deprecation warnings */
 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
 
index aa0c517..75e2248 100644 (file)
        SYM_ALIAS(alias, name, SYM_T_FUNC, SYM_L_WEAK)
 #endif
 
+// In the kernel sources (include/linux/cfi_types.h), this has a different
+// definition when CONFIG_CFI_CLANG is used, for tools/ just use the !clang
+// definition:
+#ifndef SYM_TYPED_START
+#define SYM_TYPED_START(name, linkage, align...)        \
+        SYM_START(name, linkage, align)
+#endif
+
+#ifndef SYM_TYPED_FUNC_START
+#define SYM_TYPED_FUNC_START(name)                      \
+        SYM_TYPED_START(name, SYM_L_GLOBAL, SYM_A_ALIGN)
+#endif
+
 #endif /* PERF_LINUX_LINKAGE_H_ */
index e6020c0..3213dbe 100644 (file)
@@ -6,22 +6,22 @@
    |_|                    |___/          |_|
 
    pm-graph: suspend/resume/boot timing analysis tools
-    Version: 5.9
+    Version: 5.10
      Author: Todd Brandt <todd.e.brandt@intel.com>
-  Home Page: https://01.org/pm-graph
+  Home Page: https://www.intel.com/content/www/us/en/developer/topic-technology/open/pm-graph/overview.html
 
  Report bugs/issues at bugzilla.kernel.org Tools/pm-graph
        - https://bugzilla.kernel.org/buglist.cgi?component=pm-graph&product=Tools
 
  Full documentation available online & in man pages
        - Getting Started:
-         https://01.org/pm-graph/documentation/getting-started
+         https://www.intel.com/content/www/us/en/developer/articles/technical/usage.html
 
-       - Config File Format:
-         https://01.org/pm-graph/documentation/3-config-file-format
+       - Feature Summary:
+         https://www.intel.com/content/www/us/en/developer/topic-technology/open/pm-graph/features.html
 
        - upstream version in git:
-         https://github.com/intel/pm-graph/
+         git clone https://github.com/intel/pm-graph/
 
  Table of Contents
        - Overview
index 5126271..643271b 100644 (file)
@@ -78,6 +78,9 @@ This helps maintain the consistency of test data for better comparison.
 If a wifi connection is available, check that it reconnects after resume. Include
 the reconnect time in the total resume time calculation and treat wifi timeouts
 as resume failures.
+.TP
+\fB-wifitrace\fR
+Trace through the wifi reconnect time and include it in the timeline.
 
 .SS "advanced"
 .TP
index 33981ad..cfe3433 100755 (executable)
@@ -86,7 +86,7 @@ def ascii(text):
 #       store system values and test parameters
 class SystemValues:
        title = 'SleepGraph'
-       version = '5.9'
+       version = '5.10'
        ansi = False
        rs = 0
        display = ''
@@ -100,6 +100,7 @@ class SystemValues:
        ftracelog = False
        acpidebug = True
        tstat = True
+       wifitrace = False
        mindevlen = 0.0001
        mincglen = 0.0
        cgphase = ''
@@ -124,6 +125,7 @@ class SystemValues:
        epath = '/sys/kernel/debug/tracing/events/power/'
        pmdpath = '/sys/power/pm_debug_messages'
        s0ixpath = '/sys/module/intel_pmc_core/parameters/warn_on_s0ix_failures'
+       s0ixres = '/sys/devices/system/cpu/cpuidle/low_power_idle_system_residency_us'
        acpipath='/sys/module/acpi/parameters/debug_level'
        traceevents = [
                'suspend_resume',
@@ -180,6 +182,7 @@ class SystemValues:
        tmstart = 'SUSPEND START %Y%m%d-%H:%M:%S.%f'
        tmend = 'RESUME COMPLETE %Y%m%d-%H:%M:%S.%f'
        tracefuncs = {
+               'async_synchronize_full': {},
                'sys_sync': {},
                'ksys_sync': {},
                '__pm_notifier_call_chain': {},
@@ -304,6 +307,7 @@ class SystemValues:
                [2, 'suspendstats', 'sh', '-c', 'grep -v invalid /sys/power/suspend_stats/*'],
                [2, 'cpuidle', 'sh', '-c', 'grep -v invalid /sys/devices/system/cpu/cpu*/cpuidle/state*/s2idle/*'],
                [2, 'battery', 'sh', '-c', 'grep -v invalid /sys/class/power_supply/*/*'],
+               [2, 'thermal', 'sh', '-c', 'grep . /sys/class/thermal/thermal_zone*/temp'],
        ]
        cgblacklist = []
        kprobes = dict()
@@ -777,7 +781,7 @@ class SystemValues:
                        return
                if not quiet:
                        sysvals.printSystemInfo(False)
-                       pprint('INITIALIZING FTRACE...')
+                       pprint('INITIALIZING FTRACE')
                # turn trace off
                self.fsetVal('0', 'tracing_on')
                self.cleanupFtrace()
@@ -841,7 +845,7 @@ class SystemValues:
                                for name in self.dev_tracefuncs:
                                        self.defaultKprobe(name, self.dev_tracefuncs[name])
                        if not quiet:
-                               pprint('INITIALIZING KPROBES...')
+                               pprint('INITIALIZING KPROBES')
                        self.addKprobes(self.verbose)
                if(self.usetraceevents):
                        # turn trace events on
@@ -1133,6 +1137,15 @@ class SystemValues:
                                self.cfgdef[file] = fp.read().strip()
                        fp.write(value)
                        fp.close()
+       def s0ixSupport(self):
+               if not os.path.exists(self.s0ixres) or not os.path.exists(self.mempowerfile):
+                       return False
+               fp = open(sysvals.mempowerfile, 'r')
+               data = fp.read().strip()
+               fp.close()
+               if '[s2idle]' in data:
+                       return True
+               return False
        def haveTurbostat(self):
                if not self.tstat:
                        return False
@@ -1146,7 +1159,7 @@ class SystemValues:
                        self.vprint(out)
                        return True
                return False
-       def turbostat(self):
+       def turbostat(self, s0ixready):
                cmd = self.getExec('turbostat')
                rawout = keyline = valline = ''
                fullcmd = '%s -q -S echo freeze > %s' % (cmd, self.powerfile)
@@ -1173,6 +1186,8 @@ class SystemValues:
                for key in keyline:
                        idx = keyline.index(key)
                        val = valline[idx]
+                       if key == 'SYS%LPI' and not s0ixready and re.match('^[0\.]*$', val):
+                               continue
                        out.append('%s=%s' % (key, val))
                return '|'.join(out)
        def netfixon(self, net='both'):
@@ -1183,14 +1198,6 @@ class SystemValues:
                out = ascii(fp.read()).strip()
                fp.close()
                return out
-       def wifiRepair(self):
-               out = self.netfixon('wifi')
-               if not out or 'error' in out.lower():
-                       return ''
-               m = re.match('WIFI \S* ONLINE (?P<action>\S*)', out)
-               if not m:
-                       return 'dead'
-               return m.group('action')
        def wifiDetails(self, dev):
                try:
                        info = open('/sys/class/net/%s/device/uevent' % dev, 'r').read().strip()
@@ -1220,11 +1227,6 @@ class SystemValues:
                                return '%s reconnected %.2f' % \
                                        (self.wifiDetails(dev), max(0, time.time() - start))
                        time.sleep(0.01)
-               if self.netfix:
-                       res = self.wifiRepair()
-                       if res:
-                               timeout = max(0, time.time() - start)
-                               return '%s %s %d' % (self.wifiDetails(dev), res, timeout)
                return '%s timeout %d' % (self.wifiDetails(dev), timeout)
        def errorSummary(self, errinfo, msg):
                found = False
@@ -1346,6 +1348,20 @@ class SystemValues:
                        for i in self.rslist:
                                self.setVal(self.rstgt, i)
                        pprint('runtime suspend settings restored on %d devices' % len(self.rslist))
+       def start(self, pm):
+               if self.useftrace:
+                       self.dlog('start ftrace tracing')
+                       self.fsetVal('1', 'tracing_on')
+                       if self.useprocmon:
+                               self.dlog('start the process monitor')
+                               pm.start()
+       def stop(self, pm):
+               if self.useftrace:
+                       if self.useprocmon:
+                               self.dlog('stop the process monitor')
+                               pm.stop()
+                       self.dlog('stop ftrace tracing')
+                       self.fsetVal('0', 'tracing_on')
 
 sysvals = SystemValues()
 switchvalues = ['enable', 'disable', 'on', 'off', 'true', 'false', '1', '0']
@@ -1643,19 +1659,20 @@ class Data:
                ubiquitous = False
                if kprobename in dtf and 'ub' in dtf[kprobename]:
                        ubiquitous = True
-               title = cdata+' '+rdata
-               mstr = '\(.*\) *(?P<args>.*) *\((?P<caller>.*)\+.* arg1=(?P<ret>.*)'
-               m = re.match(mstr, title)
-               if m:
-                       c = m.group('caller')
-                       a = m.group('args').strip()
-                       r = m.group('ret')
+               mc = re.match('\(.*\) *(?P<args>.*)', cdata)
+               mr = re.match('\((?P<caller>\S*).* arg1=(?P<ret>.*)', rdata)
+               if mc and mr:
+                       c = mr.group('caller').split('+')[0]
+                       a = mc.group('args').strip()
+                       r = mr.group('ret')
                        if len(r) > 6:
                                r = ''
                        else:
                                r = 'ret=%s ' % r
                        if ubiquitous and c in dtf and 'ub' in dtf[c]:
                                return False
+               else:
+                       return False
                color = sysvals.kprobeColor(kprobename)
                e = DevFunction(displayname, a, c, r, start, end, ubiquitous, proc, pid, color)
                tgtdev['src'].append(e)
@@ -1772,6 +1789,14 @@ class Data:
                                                e.time = self.trimTimeVal(e.time, t0, dT, left)
                                                e.end = self.trimTimeVal(e.end, t0, dT, left)
                                                e.length = e.end - e.time
+                               if('cpuexec' in d):
+                                       cpuexec = dict()
+                                       for e in d['cpuexec']:
+                                               c0, cN = e
+                                               c0 = self.trimTimeVal(c0, t0, dT, left)
+                                               cN = self.trimTimeVal(cN, t0, dT, left)
+                                               cpuexec[(c0, cN)] = d['cpuexec'][e]
+                                       d['cpuexec'] = cpuexec
                for dir in ['suspend', 'resume']:
                        list = []
                        for e in self.errorinfo[dir]:
@@ -2086,75 +2111,43 @@ class Data:
                return d
        def addProcessUsageEvent(self, name, times):
                # get the start and end times for this process
-               maxC = 0
-               tlast = 0
-               start = -1
-               end = -1
+               cpuexec = dict()
+               tlast = start = end = -1
                for t in sorted(times):
-                       if tlast == 0:
+                       if tlast < 0:
                                tlast = t
                                continue
-                       if name in self.pstl[t]:
-                               if start == -1 or tlast < start:
+                       if name in self.pstl[t] and self.pstl[t][name] > 0:
+                               if start < 0:
                                        start = tlast
-                               if end == -1 or t > end:
-                                       end = t
+                               end, key = t, (tlast, t)
+                               maxj = (t - tlast) * 1024.0
+                               cpuexec[key] = min(1.0, float(self.pstl[t][name]) / maxj)
                        tlast = t
-               if start == -1 or end == -1:
-                       return 0
+               if start < 0 or end < 0:
+                       return
                # add a new action for this process and get the object
                out = self.newActionGlobal(name, start, end, -3)
-               if not out:
-                       return 0
-               phase, devname = out
-               dev = self.dmesg[phase]['list'][devname]
-               # get the cpu exec data
-               tlast = 0
-               clast = 0
-               cpuexec = dict()
-               for t in sorted(times):
-                       if tlast == 0 or t <= start or t > end:
-                               tlast = t
-                               continue
-                       list = self.pstl[t]
-                       c = 0
-                       if name in list:
-                               c = list[name]
-                       if c > maxC:
-                               maxC = c
-                       if c != clast:
-                               key = (tlast, t)
-                               cpuexec[key] = c
-                               tlast = t
-                               clast = c
-               dev['cpuexec'] = cpuexec
-               return maxC
+               if out:
+                       phase, devname = out
+                       dev = self.dmesg[phase]['list'][devname]
+                       dev['cpuexec'] = cpuexec
        def createProcessUsageEvents(self):
-               # get an array of process names
-               proclist = []
-               for t in sorted(self.pstl):
-                       pslist = self.pstl[t]
-                       for ps in sorted(pslist):
-                               if ps not in proclist:
-                                       proclist.append(ps)
-               # get a list of data points for suspend and resume
-               tsus = []
-               tres = []
+               # get an array of process names and times
+               proclist = {'sus': dict(), 'res': dict()}
+               tdata = {'sus': [], 'res': []}
                for t in sorted(self.pstl):
-                       if t < self.tSuspended:
-                               tsus.append(t)
-                       else:
-                               tres.append(t)
+                       dir = 'sus' if t < self.tSuspended else 'res'
+                       for ps in sorted(self.pstl[t]):
+                               if ps not in proclist[dir]:
+                                       proclist[dir][ps] = 0
+                       tdata[dir].append(t)
                # process the events for suspend and resume
-               if len(proclist) > 0:
+               if len(proclist['sus']) > 0 or len(proclist['res']) > 0:
                        sysvals.vprint('Process Execution:')
-               for ps in proclist:
-                       c = self.addProcessUsageEvent(ps, tsus)
-                       if c > 0:
-                               sysvals.vprint('%25s (sus): %d' % (ps, c))
-                       c = self.addProcessUsageEvent(ps, tres)
-                       if c > 0:
-                               sysvals.vprint('%25s (res): %d' % (ps, c))
+               for dir in ['sus', 'res']:
+                       for ps in sorted(proclist[dir]):
+                               self.addProcessUsageEvent(ps, tdata[dir])
        def handleEndMarker(self, time, msg=''):
                dm = self.dmesg
                self.setEnd(time, msg)
@@ -3218,7 +3211,7 @@ class ProcessMonitor:
 #       markers, and/or kprobes required for primary parsing.
 def doesTraceLogHaveTraceEvents():
        kpcheck = ['_cal: (', '_ret: (']
-       techeck = ['suspend_resume', 'device_pm_callback']
+       techeck = ['suspend_resume', 'device_pm_callback', 'tracing_mark_write']
        tmcheck = ['SUSPEND START', 'RESUME COMPLETE']
        sysvals.usekprobes = False
        fp = sysvals.openlog(sysvals.ftracefile, 'r')
@@ -3241,7 +3234,7 @@ def doesTraceLogHaveTraceEvents():
                                check.remove(i)
                tmcheck = check
        fp.close()
-       sysvals.usetraceevents = True if len(techeck) < 2 else False
+       sysvals.usetraceevents = True if len(techeck) < 3 else False
        sysvals.usetracemarkers = True if len(tmcheck) == 0 else False
 
 # Function: appendIncompleteTraceLog
@@ -3456,6 +3449,8 @@ def parseTraceLog(live=False):
                        continue
                # process cpu exec line
                if t.type == 'tracing_mark_write':
+                       if t.name == 'CMD COMPLETE' and data.tKernRes == 0:
+                               data.tKernRes = t.time
                        m = re.match(tp.procexecfmt, t.name)
                        if(m):
                                parts, msg = 1, m.group('ps')
@@ -3674,6 +3669,9 @@ def parseTraceLog(live=False):
                                e = next((x for x in reversed(tp.ktemp[key]) if x['end'] < 0), 0)
                                if not e:
                                        continue
+                               if (t.time - e['begin']) * 1000 < sysvals.mindevlen:
+                                       tp.ktemp[key].pop()
+                                       continue
                                e['end'] = t.time
                                e['rdata'] = kprobedata
                                # end of kernel resume
@@ -4213,6 +4211,8 @@ def callgraphHTML(sv, hf, num, cg, title, color, devid):
                        fmt = '<n>(%.3f ms @ '+sv.timeformat+')</n>'
                        flen = fmt % (line.length*1000, line.time)
                if line.isLeaf():
+                       if line.length * 1000 < sv.mincglen:
+                               continue
                        hf.write(html_func_leaf.format(line.name, flen))
                elif line.freturn:
                        hf.write(html_func_end)
@@ -4827,14 +4827,11 @@ def createHTML(testruns, testfail):
                                        if('cpuexec' in dev):
                                                for t in sorted(dev['cpuexec']):
                                                        start, end = t
-                                                       j = float(dev['cpuexec'][t]) / 5
-                                                       if j > 1.0:
-                                                               j = 1.0
                                                        height = '%.3f' % (rowheight/3)
                                                        top = '%.3f' % (rowtop + devtl.scaleH + 2*rowheight/3)
                                                        left = '%f' % (((start-m0)*100)/mTotal)
                                                        width = '%f' % ((end-start)*100/mTotal)
-                                                       color = 'rgba(255, 0, 0, %f)' % j
+                                                       color = 'rgba(255, 0, 0, %f)' % dev['cpuexec'][t]
                                                        devtl.html += \
                                                                html_cpuexec.format(left, top, height, width, color)
                                        if('src' not in dev):
@@ -5453,17 +5450,9 @@ def executeSuspend(quiet=False):
                call('sync', shell=True)
        sv.dlog('read dmesg')
        sv.initdmesg()
-       # start ftrace
-       if sv.useftrace:
-               if not quiet:
-                       pprint('START TRACING')
-               sv.dlog('start ftrace tracing')
-               sv.fsetVal('1', 'tracing_on')
-               if sv.useprocmon:
-                       sv.dlog('start the process monitor')
-                       pm.start()
-       sv.dlog('run the cmdinfo list before')
+       sv.dlog('cmdinfo before')
        sv.cmdinfo(True)
+       sv.start(pm)
        # execute however many s/r runs requested
        for count in range(1,sv.execcount+1):
                # x2delay in between test runs
@@ -5500,6 +5489,7 @@ def executeSuspend(quiet=False):
                        if res != 0:
                                tdata['error'] = 'cmd returned %d' % res
                else:
+                       s0ixready = sv.s0ixSupport()
                        mode = sv.suspendmode
                        if sv.memmode and os.path.exists(sv.mempowerfile):
                                mode = 'mem'
@@ -5509,9 +5499,10 @@ def executeSuspend(quiet=False):
                                sv.testVal(sv.diskpowerfile, 'radio', sv.diskmode)
                        if sv.acpidebug:
                                sv.testVal(sv.acpipath, 'acpi', '0xe')
-                       if mode == 'freeze' and sv.haveTurbostat():
+                       if ((mode == 'freeze') or (sv.memmode == 's2idle')) \
+                               and sv.haveTurbostat():
                                # execution will pause here
-                               turbo = sv.turbostat()
+                               turbo = sv.turbostat(s0ixready)
                                if turbo:
                                        tdata['turbo'] = turbo
                        else:
@@ -5522,7 +5513,8 @@ def executeSuspend(quiet=False):
                                        pf.close()
                                except Exception as e:
                                        tdata['error'] = str(e)
-               sv.dlog('system returned from resume')
+               sv.fsetVal('CMD COMPLETE', 'trace_marker')
+               sv.dlog('system returned')
                # reset everything
                sv.testVal('restoreall')
                if(sv.rtcwake):
@@ -5535,33 +5527,29 @@ def executeSuspend(quiet=False):
                        sv.fsetVal('WAIT END', 'trace_marker')
                # return from suspend
                pprint('RESUME COMPLETE')
-               sv.fsetVal(datetime.now().strftime(sv.tmend), 'trace_marker')
+               if(count < sv.execcount):
+                       sv.fsetVal(datetime.now().strftime(sv.tmend), 'trace_marker')
+               elif(not sv.wifitrace):
+                       sv.fsetVal(datetime.now().strftime(sv.tmend), 'trace_marker')
+                       sv.stop(pm)
                if sv.wifi and wifi:
                        tdata['wifi'] = sv.pollWifi(wifi)
                        sv.dlog('wifi check, %s' % tdata['wifi'])
-                       if sv.netfix:
-                               netfixout = sv.netfixon('wired')
-               elif sv.netfix:
-                       netfixout = sv.netfixon()
-               if sv.netfix and netfixout:
-                       tdata['netfix'] = netfixout
+               if(count == sv.execcount and sv.wifitrace):
+                       sv.fsetVal(datetime.now().strftime(sv.tmend), 'trace_marker')
+                       sv.stop(pm)
+               if sv.netfix:
+                       tdata['netfix'] = sv.netfixon()
                        sv.dlog('netfix, %s' % tdata['netfix'])
                if(sv.suspendmode == 'mem' or sv.suspendmode == 'command'):
                        sv.dlog('read the ACPI FPDT')
                        tdata['fw'] = getFPDT(False)
                testdata.append(tdata)
-       sv.dlog('run the cmdinfo list after')
+       sv.dlog('cmdinfo after')
        cmdafter = sv.cmdinfo(False)
-       # stop ftrace
-       if sv.useftrace:
-               if sv.useprocmon:
-                       sv.dlog('stop the process monitor')
-                       pm.stop()
-               sv.fsetVal('0', 'tracing_on')
        # grab a copy of the dmesg output
        if not quiet:
                pprint('CAPTURING DMESG')
-       sysvals.dlog('EXECUTION TRACE END')
        sv.getdmesg(testdata)
        # grab a copy of the ftrace output
        if sv.useftrace:
@@ -6350,6 +6338,8 @@ def data_from_html(file, outpath, issues, fulldetail=False):
                if not m:
                        continue
                name, time, phase = m.group('n'), m.group('t'), m.group('p')
+               if name == 'async_synchronize_full':
+                       continue
                if ' async' in name or ' sync' in name:
                        name = ' '.join(name.split(' ')[:-1])
                if phase.startswith('suspend'):
@@ -6701,6 +6691,7 @@ def printHelp():
        '   -skiphtml    Run the test and capture the trace logs, but skip the timeline (default: disabled)\n'\
        '   -result fn   Export a results table to a text file for parsing.\n'\
        '   -wifi        If a wifi connection is available, check that it reconnects after resume.\n'\
+       '   -wifitrace   Trace kernel execution through wifi reconnect.\n'\
        '   -netfix      Use netfix to reset the network in the event it fails to resume.\n'\
        '  [testprep]\n'\
        '   -sync        Sync the filesystems before starting the test\n'\
@@ -6828,6 +6819,8 @@ if __name__ == '__main__':
                        sysvals.sync = True
                elif(arg == '-wifi'):
                        sysvals.wifi = True
+               elif(arg == '-wifitrace'):
+                       sysvals.wifitrace = True
                elif(arg == '-netfix'):
                        sysvals.netfix = True
                elif(arg == '-gzip'):
index 0464b2c..f07aef7 100644 (file)
@@ -49,6 +49,7 @@ TARGETS += net
 TARGETS += net/af_unix
 TARGETS += net/forwarding
 TARGETS += net/mptcp
+TARGETS += net/openvswitch
 TARGETS += netfilter
 TARGETS += nsfs
 TARGETS += pidfd
index 127b8ca..24dd621 100644 (file)
@@ -3936,6 +3936,19 @@ static struct btf_raw_test raw_tests[] = {
        .err_str = "Invalid type_id",
 },
 {
+       .descr = "decl_tag test #16, func proto, return type",
+       .raw_types = {
+               BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),                          /* [1] */
+               BTF_VAR_ENC(NAME_TBD, 1, 0),                                            /* [2] */
+               BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DECL_TAG, 0, 0), 2), (-1), /* [3] */
+               BTF_FUNC_PROTO_ENC(3, 0),                                               /* [4] */
+               BTF_END_RAW,
+       },
+       BTF_STR_SEC("\0local\0tag1"),
+       .btf_load_err = true,
+       .err_str = "Invalid return type",
+},
+{
        .descr = "type_tag test #1",
        .raw_types = {
                BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),  /* [1] */
index 099c23d..b39093d 100644 (file)
@@ -47,14 +47,14 @@ record_sample(struct bpf_dynptr *dynptr, void *context)
                if (status) {
                        bpf_printk("bpf_dynptr_read() failed: %d\n", status);
                        err = 1;
-                       return 0;
+                       return 1;
                }
        } else {
                sample = bpf_dynptr_data(dynptr, 0, sizeof(*sample));
                if (!sample) {
                        bpf_printk("Unexpectedly failed to get sample\n");
                        err = 2;
-                       return 0;
+                       return 1;
                }
                stack_sample = *sample;
        }
index e9dab5f..6b8d2e2 100644 (file)
@@ -7,6 +7,8 @@ TEST_PROGS := \
        bond-lladdr-target.sh \
        dev_addr_lists.sh
 
-TEST_FILES := lag_lib.sh
+TEST_FILES := \
+       lag_lib.sh \
+       net_forwarding_lib.sh
 
 include ../../../lib.mk
index e6fa24e..5cfe7d8 100755 (executable)
@@ -14,7 +14,7 @@ ALL_TESTS="
 REQUIRE_MZ=no
 NUM_NETIFS=0
 lib_dir=$(dirname "$0")
-source "$lib_dir"/../../../net/forwarding/lib.sh
+source "$lib_dir"/net_forwarding_lib.sh
 
 source "$lib_dir"/lag_lib.sh
 
diff --git a/tools/testing/selftests/drivers/net/bonding/net_forwarding_lib.sh b/tools/testing/selftests/drivers/net/bonding/net_forwarding_lib.sh
new file mode 120000 (symlink)
index 0000000..39c9682
--- /dev/null
@@ -0,0 +1 @@
+../../../net/forwarding/lib.sh
\ No newline at end of file
index dca8be6..a1f269e 100755 (executable)
@@ -18,8 +18,8 @@ NUM_NETIFS=1
 REQUIRE_JQ="no"
 REQUIRE_MZ="no"
 NETIF_CREATE="no"
-lib_dir=$(dirname $0)/../../../net/forwarding
-source $lib_dir/lib.sh
+lib_dir=$(dirname "$0")
+source "$lib_dir"/lib.sh
 
 cleanup() {
        echo "Cleaning up"
index 642d8df..6a86e61 100644 (file)
@@ -3,4 +3,8 @@
 
 TEST_PROGS := dev_addr_lists.sh
 
+TEST_FILES := \
+       lag_lib.sh \
+       net_forwarding_lib.sh
+
 include ../../../lib.mk
index debda72..3391311 100755 (executable)
@@ -11,14 +11,14 @@ ALL_TESTS="
 REQUIRE_MZ=no
 NUM_NETIFS=0
 lib_dir=$(dirname "$0")
-source "$lib_dir"/../../../net/forwarding/lib.sh
+source "$lib_dir"/net_forwarding_lib.sh
 
-source "$lib_dir"/../bonding/lag_lib.sh
+source "$lib_dir"/lag_lib.sh
 
 
 destroy()
 {
-       local ifnames=(dummy0 dummy1 team0 mv0)
+       local ifnames=(dummy1 dummy2 team0 mv0)
        local ifname
 
        for ifname in "${ifnames[@]}"; do
diff --git a/tools/testing/selftests/drivers/net/team/lag_lib.sh b/tools/testing/selftests/drivers/net/team/lag_lib.sh
new file mode 120000 (symlink)
index 0000000..e1347a1
--- /dev/null
@@ -0,0 +1 @@
+../bonding/lag_lib.sh
\ No newline at end of file
diff --git a/tools/testing/selftests/drivers/net/team/net_forwarding_lib.sh b/tools/testing/selftests/drivers/net/team/net_forwarding_lib.sh
new file mode 120000 (symlink)
index 0000000..39c9682
--- /dev/null
@@ -0,0 +1 @@
+../../../net/forwarding/lib.sh
\ No newline at end of file
index db52257..d3a79da 100644 (file)
@@ -1,7 +1,7 @@
 #!/bin/sh
 # SPDX-License-Identifier: GPL-2.0
 # description: Generic dynamic event - check if duplicate events are caught
-# requires: dynamic_events "e[:[<group>/]<event>] <attached-group>.<attached-event> [<args>]":README
+# requires: dynamic_events "e[:[<group>/][<event>]] <attached-group>.<attached-event> [<args>]":README
 
 echo 0 > events/enable
 
index 914fe2e..6461c37 100644 (file)
@@ -1,7 +1,7 @@
 #!/bin/sh
 # SPDX-License-Identifier: GPL-2.0
 # description: event trigger - test inter-event histogram trigger eprobe on synthetic event
-# requires: dynamic_events synthetic_events events/syscalls/sys_enter_openat/hist "e[:[<group>/]<event>] <attached-group>.<attached-event> [<args>]":README
+# requires: dynamic_events synthetic_events events/syscalls/sys_enter_openat/hist "e[:[<group>/][<event>]] <attached-group>.<attached-event> [<args>]":README
 
 echo 0 > events/enable
 
index 7321490..5a0e0df 100644 (file)
@@ -3,11 +3,11 @@ INCLUDES := -I../include -I../../ -I../../../../../usr/include/
 CFLAGS := $(CFLAGS) -g -O2 -Wall -D_GNU_SOURCE -pthread $(INCLUDES) $(KHDR_INCLUDES)
 LDLIBS := -lpthread -lrt
 
-HEADERS := \
+LOCAL_HDRS := \
        ../include/futextest.h \
        ../include/atomic.h \
        ../include/logging.h
-TEST_GEN_FILES := \
+TEST_GEN_PROGS := \
        futex_wait_timeout \
        futex_wait_wouldblock \
        futex_requeue_pi \
@@ -24,5 +24,3 @@ TEST_PROGS := run.sh
 top_srcdir = ../../../../..
 DEFAULT_INSTALL_HDR_PATH := 1
 include ../../lib.mk
-
-$(TEST_GEN_FILES): $(HEADERS)
index 39f0fa2..05d66ef 100644 (file)
@@ -2,10 +2,10 @@
 CFLAGS := $(CFLAGS) -Wall -D_GNU_SOURCE
 LDLIBS += -lm
 
-uname_M := $(shell uname -m 2>/dev/null || echo not)
-ARCH ?= $(shell echo $(uname_M) | sed -e s/i.86/x86/ -e s/x86_64/x86/)
+ARCH ?= $(shell uname -m 2>/dev/null || echo not)
+ARCH_PROCESSED := $(shell echo $(ARCH) | sed -e s/i.86/x86/ -e s/x86_64/x86/)
 
-ifeq (x86,$(ARCH))
+ifeq (x86,$(ARCH_PROCESSED))
 TEST_GEN_FILES := msr aperf
 endif
 
index 806a150..67fe7a4 100644 (file)
@@ -1,10 +1,10 @@
 # SPDX-License-Identifier: GPL-2.0-only
 # Makefile for kexec tests
 
-uname_M := $(shell uname -m 2>/dev/null || echo not)
-ARCH ?= $(shell echo $(uname_M) | sed -e s/i.86/x86/ -e s/x86_64/x86/)
+ARCH ?= $(shell uname -m 2>/dev/null || echo not)
+ARCH_PROCESSED := $(shell echo $(ARCH) | sed -e s/i.86/x86/ -e s/x86_64/x86/)
 
-ifeq ($(ARCH),$(filter $(ARCH),x86 ppc64le))
+ifeq ($(ARCH_PROCESSED),$(filter $(ARCH_PROCESSED),x86 ppc64le))
 TEST_PROGS := test_kexec_load.sh test_kexec_file_load.sh
 TEST_FILES := kexec_common_lib.sh
 
index 9d4cb94..a3ea3d4 100644 (file)
@@ -70,7 +70,7 @@ endef
 run_tests: all
 ifdef building_out_of_srctree
        @if [ "X$(TEST_PROGS)$(TEST_PROGS_EXTENDED)$(TEST_FILES)" != "X" ]; then \
-               rsync -aq $(TEST_PROGS) $(TEST_PROGS_EXTENDED) $(TEST_FILES) $(OUTPUT); \
+               rsync -aLq $(TEST_PROGS) $(TEST_PROGS_EXTENDED) $(TEST_FILES) $(OUTPUT); \
        fi
        @if [ "X$(TEST_PROGS)" != "X" ]; then \
                $(call RUN_TESTS, $(TEST_GEN_PROGS) $(TEST_CUSTOM_PROGS) \
@@ -84,7 +84,7 @@ endif
 
 define INSTALL_SINGLE_RULE
        $(if $(INSTALL_LIST),@mkdir -p $(INSTALL_PATH))
-       $(if $(INSTALL_LIST),rsync -a $(INSTALL_LIST) $(INSTALL_PATH)/)
+       $(if $(INSTALL_LIST),rsync -aL $(INSTALL_LIST) $(INSTALL_PATH)/)
 endef
 
 define INSTALL_RULE
index 74ee506..611be86 100755 (executable)
@@ -138,7 +138,6 @@ online_all_offline_memory()
 {
        for memory in `hotpluggable_offline_memory`; do
                if ! online_memory_expect_success $memory; then
-                       echo "$FUNCNAME $memory: unexpected fail" >&2
                        retval=1
                fi
        done
diff --git a/tools/testing/selftests/net/openvswitch/Makefile b/tools/testing/selftests/net/openvswitch/Makefile
new file mode 100644 (file)
index 0000000..2f1508a
--- /dev/null
@@ -0,0 +1,13 @@
+# SPDX-License-Identifier: GPL-2.0
+
+top_srcdir = ../../../../..
+
+CFLAGS =  -Wall -Wl,--no-as-needed -O2 -g -I$(top_srcdir)/usr/include $(KHDR_INCLUDES)
+
+TEST_PROGS := openvswitch.sh
+
+TEST_FILES := ovs-dpctl.py
+
+EXTRA_CLEAN := test_netlink_checks
+
+include ../../lib.mk
diff --git a/tools/testing/selftests/net/openvswitch/openvswitch.sh b/tools/testing/selftests/net/openvswitch/openvswitch.sh
new file mode 100755 (executable)
index 0000000..7ce4670
--- /dev/null
@@ -0,0 +1,218 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0
+#
+# OVS kernel module self tests
+
+# Kselftest framework requirement - SKIP code is 4.
+ksft_skip=4
+
+PAUSE_ON_FAIL=no
+VERBOSE=0
+TRACING=0
+
+tests="
+       netlink_checks                          ovsnl: validate netlink attrs and settings"
+
+info() {
+    [ $VERBOSE = 0 ] || echo $*
+}
+
+ovs_base=`pwd`
+sbxs=
+sbx_add () {
+       info "adding sandbox '$1'"
+
+       sbxs="$sbxs $1"
+
+       NO_BIN=0
+
+       # Create sandbox.
+       local d="$ovs_base"/$1
+       if [ -e $d ]; then
+               info "removing $d"
+               rm -rf "$d"
+       fi
+       mkdir "$d" || return 1
+       ovs_setenv $1
+}
+
+ovs_exit_sig() {
+       [ -e ${ovs_dir}/cleanup ] && . "$ovs_dir/cleanup"
+}
+
+on_exit() {
+       echo "$1" > ${ovs_dir}/cleanup.tmp
+       cat ${ovs_dir}/cleanup >> ${ovs_dir}/cleanup.tmp
+       mv ${ovs_dir}/cleanup.tmp ${ovs_dir}/cleanup
+}
+
+ovs_setenv() {
+       sandbox=$1
+
+       ovs_dir=$ovs_base${1:+/$1}; export ovs_dir
+
+       test -e ${ovs_dir}/cleanup || : > ${ovs_dir}/cleanup
+}
+
+ovs_sbx() {
+       if test "X$2" != X; then
+               (ovs_setenv $1; shift; "$@" >> ${ovs_dir}/debug.log)
+       else
+               ovs_setenv $1
+       fi
+}
+
+ovs_add_dp () {
+       info "Adding DP/Bridge IF: sbx:$1 dp:$2 {$3, $4, $5}"
+       sbxname="$1"
+       shift
+       ovs_sbx "$sbxname" python3 $ovs_base/ovs-dpctl.py add-dp $*
+       on_exit "ovs_sbx $sbxname python3 $ovs_base/ovs-dpctl.py del-dp $1;"
+}
+
+usage() {
+       echo
+       echo "$0 [OPTIONS] [TEST]..."
+       echo "If no TEST argument is given, all tests will be run."
+       echo
+       echo "Options"
+       echo "  -t: capture traffic via tcpdump"
+       echo "  -v: verbose"
+       echo "  -p: pause on failure"
+       echo
+       echo "Available tests${tests}"
+       exit 1
+}
+
+# netlink_validation
+# - Create a dp
+# - check no warning with "old version" simulation
+test_netlink_checks () {
+       sbx_add "test_netlink_checks" || return 1
+
+       info "setting up new DP"
+       ovs_add_dp "test_netlink_checks" nv0 || return 1
+       # now try again
+       PRE_TEST=$(dmesg | grep -E "RIP: [0-9a-fA-Fx]+:ovs_dp_cmd_new\+")
+       ovs_add_dp "test_netlink_checks" nv0 -V 0 || return 1
+       POST_TEST=$(dmesg | grep -E "RIP: [0-9a-fA-Fx]+:ovs_dp_cmd_new\+")
+       if [ "$PRE_TEST" != "$POST_TEST" ]; then
+               info "failed - gen warning"
+               return 1
+       fi
+
+       return 0
+}
+
+run_test() {
+       (
+       tname="$1"
+       tdesc="$2"
+
+       if ! lsmod | grep openvswitch >/dev/null 2>&1; then
+               stdbuf -o0 printf "TEST: %-60s  [NOMOD]\n" "${tdesc}"
+               return $ksft_skip
+       fi
+
+       if python3 ovs-dpctl.py -h 2>&1 | \
+            grep "Need to install the python" >/dev/null 2>&1; then
+               stdbuf -o0 printf "TEST: %-60s  [PYLIB]\n" "${tdesc}"
+               return $ksft_skip
+       fi
+       printf "TEST: %-60s  [START]\n" "${tname}"
+
+       unset IFS
+
+       eval test_${tname}
+       ret=$?
+
+       if [ $ret -eq 0 ]; then
+               printf "TEST: %-60s  [ OK ]\n" "${tdesc}"
+               ovs_exit_sig
+               rm -rf "$ovs_dir"
+       elif [ $ret -eq 1 ]; then
+               printf "TEST: %-60s  [FAIL]\n" "${tdesc}"
+               if [ "${PAUSE_ON_FAIL}" = "yes" ]; then
+                       echo
+                       echo "Pausing. Logs in $ovs_dir/. Hit enter to continue"
+                       read a
+               fi
+               ovs_exit_sig
+               [ "${PAUSE_ON_FAIL}" = "yes" ] || rm -rf "$ovs_dir"
+               exit 1
+       elif [ $ret -eq $ksft_skip ]; then
+               printf "TEST: %-60s  [SKIP]\n" "${tdesc}"
+       elif [ $ret -eq 2 ]; then
+               rm -rf test_${tname}
+               run_test "$1" "$2"
+       fi
+
+       return $ret
+       )
+       ret=$?
+       case $ret in
+               0)
+                       [ $all_skipped = true ] && [ $exitcode=$ksft_skip ] && exitcode=0
+                       all_skipped=false
+               ;;
+               $ksft_skip)
+                       [ $all_skipped = true ] && exitcode=$ksft_skip
+               ;;
+               *)
+                       all_skipped=false
+                       exitcode=1
+               ;;
+       esac
+
+       return $ret
+}
+
+
+exitcode=0
+desc=0
+all_skipped=true
+
+while getopts :pvt o
+do
+       case $o in
+       p) PAUSE_ON_FAIL=yes;;
+       v) VERBOSE=1;;
+       t) if which tcpdump > /dev/null 2>&1; then
+               TRACING=1
+          else
+               echo "=== tcpdump not available, tracing disabled"
+          fi
+          ;;
+       *) usage;;
+       esac
+done
+shift $(($OPTIND-1))
+
+IFS="  
+"
+
+for arg do
+       # Check first that all requested tests are available before running any
+       command -v > /dev/null "test_${arg}" || { echo "=== Test ${arg} not found"; usage; }
+done
+
+name=""
+desc=""
+for t in ${tests}; do
+       [ "${name}" = "" ]      && name="${t}"  && continue
+       [ "${desc}" = "" ]      && desc="${t}"
+
+       run_this=1
+       for arg do
+               [ "${arg}" != "${arg#--*}" ] && continue
+               [ "${arg}" = "${name}" ] && run_this=1 && break
+               run_this=0
+       done
+       if [ $run_this -eq 1 ]; then
+               run_test "${name}" "${desc}"
+       fi
+       name=""
+       desc=""
+done
+
+exit ${exitcode}
diff --git a/tools/testing/selftests/net/openvswitch/ovs-dpctl.py b/tools/testing/selftests/net/openvswitch/ovs-dpctl.py
new file mode 100644 (file)
index 0000000..3243c90
--- /dev/null
@@ -0,0 +1,351 @@
+#!/usr/bin/env python3
+# SPDX-License-Identifier: GPL-2.0
+
+# Controls the openvswitch module.  Part of the kselftest suite, but
+# can be used for some diagnostic purpose as well.
+
+import argparse
+import errno
+import sys
+
+try:
+    from pyroute2 import NDB
+
+    from pyroute2.netlink import NLM_F_ACK
+    from pyroute2.netlink import NLM_F_REQUEST
+    from pyroute2.netlink import genlmsg
+    from pyroute2.netlink import nla
+    from pyroute2.netlink.exceptions import NetlinkError
+    from pyroute2.netlink.generic import GenericNetlinkSocket
+except ModuleNotFoundError:
+    print("Need to install the python pyroute2 package.")
+    sys.exit(0)
+
+
+OVS_DATAPATH_FAMILY = "ovs_datapath"
+OVS_VPORT_FAMILY = "ovs_vport"
+OVS_FLOW_FAMILY = "ovs_flow"
+OVS_PACKET_FAMILY = "ovs_packet"
+OVS_METER_FAMILY = "ovs_meter"
+OVS_CT_LIMIT_FAMILY = "ovs_ct_limit"
+
+OVS_DATAPATH_VERSION = 2
+OVS_DP_CMD_NEW = 1
+OVS_DP_CMD_DEL = 2
+OVS_DP_CMD_GET = 3
+OVS_DP_CMD_SET = 4
+
+OVS_VPORT_CMD_NEW = 1
+OVS_VPORT_CMD_DEL = 2
+OVS_VPORT_CMD_GET = 3
+OVS_VPORT_CMD_SET = 4
+
+
+class ovs_dp_msg(genlmsg):
+    # include the OVS version
+    # We need a custom header rather than just being able to rely on
+    # genlmsg because fields ends up not expressing everything correctly
+    # if we use the canonical example of setting fields = (('customfield',),)
+    fields = genlmsg.fields + (("dpifindex", "I"),)
+
+
+class OvsDatapath(GenericNetlinkSocket):
+
+    OVS_DP_F_VPORT_PIDS = 1 << 1
+    OVS_DP_F_DISPATCH_UPCALL_PER_CPU = 1 << 3
+
+    class dp_cmd_msg(ovs_dp_msg):
+        """
+        Message class that will be used to communicate with the kernel module.
+        """
+
+        nla_map = (
+            ("OVS_DP_ATTR_UNSPEC", "none"),
+            ("OVS_DP_ATTR_NAME", "asciiz"),
+            ("OVS_DP_ATTR_UPCALL_PID", "uint32"),
+            ("OVS_DP_ATTR_STATS", "dpstats"),
+            ("OVS_DP_ATTR_MEGAFLOW_STATS", "megaflowstats"),
+            ("OVS_DP_ATTR_USER_FEATURES", "uint32"),
+            ("OVS_DP_ATTR_PAD", "none"),
+            ("OVS_DP_ATTR_MASKS_CACHE_SIZE", "uint32"),
+            ("OVS_DP_ATTR_PER_CPU_PIDS", "array(uint32)"),
+        )
+
+        class dpstats(nla):
+            fields = (
+                ("hit", "=Q"),
+                ("missed", "=Q"),
+                ("lost", "=Q"),
+                ("flows", "=Q"),
+            )
+
+        class megaflowstats(nla):
+            fields = (
+                ("mask_hit", "=Q"),
+                ("masks", "=I"),
+                ("padding", "=I"),
+                ("cache_hits", "=Q"),
+                ("pad1", "=Q"),
+            )
+
+    def __init__(self):
+        GenericNetlinkSocket.__init__(self)
+        self.bind(OVS_DATAPATH_FAMILY, OvsDatapath.dp_cmd_msg)
+
+    def info(self, dpname, ifindex=0):
+        msg = OvsDatapath.dp_cmd_msg()
+        msg["cmd"] = OVS_DP_CMD_GET
+        msg["version"] = OVS_DATAPATH_VERSION
+        msg["reserved"] = 0
+        msg["dpifindex"] = ifindex
+        msg["attrs"].append(["OVS_DP_ATTR_NAME", dpname])
+
+        try:
+            reply = self.nlm_request(
+                msg, msg_type=self.prid, msg_flags=NLM_F_REQUEST
+            )
+            reply = reply[0]
+        except NetlinkError as ne:
+            if ne.code == errno.ENODEV:
+                reply = None
+            else:
+                raise ne
+
+        return reply
+
+    def create(self, dpname, shouldUpcall=False, versionStr=None):
+        msg = OvsDatapath.dp_cmd_msg()
+        msg["cmd"] = OVS_DP_CMD_NEW
+        if versionStr is None:
+            msg["version"] = OVS_DATAPATH_VERSION
+        else:
+            msg["version"] = int(versionStr.split(":")[0], 0)
+        msg["reserved"] = 0
+        msg["dpifindex"] = 0
+        msg["attrs"].append(["OVS_DP_ATTR_NAME", dpname])
+
+        dpfeatures = 0
+        if versionStr is not None and versionStr.find(":") != -1:
+            dpfeatures = int(versionStr.split(":")[1], 0)
+        else:
+            dpfeatures = OvsDatapath.OVS_DP_F_VPORT_PIDS
+
+        msg["attrs"].append(["OVS_DP_ATTR_USER_FEATURES", dpfeatures])
+        if not shouldUpcall:
+            msg["attrs"].append(["OVS_DP_ATTR_UPCALL_PID", 0])
+
+        try:
+            reply = self.nlm_request(
+                msg, msg_type=self.prid, msg_flags=NLM_F_REQUEST | NLM_F_ACK
+            )
+            reply = reply[0]
+        except NetlinkError as ne:
+            if ne.code == errno.EEXIST:
+                reply = None
+            else:
+                raise ne
+
+        return reply
+
+    def destroy(self, dpname):
+        msg = OvsDatapath.dp_cmd_msg()
+        msg["cmd"] = OVS_DP_CMD_DEL
+        msg["version"] = OVS_DATAPATH_VERSION
+        msg["reserved"] = 0
+        msg["dpifindex"] = 0
+        msg["attrs"].append(["OVS_DP_ATTR_NAME", dpname])
+
+        try:
+            reply = self.nlm_request(
+                msg, msg_type=self.prid, msg_flags=NLM_F_REQUEST | NLM_F_ACK
+            )
+            reply = reply[0]
+        except NetlinkError as ne:
+            if ne.code == errno.ENODEV:
+                reply = None
+            else:
+                raise ne
+
+        return reply
+
+
+class OvsVport(GenericNetlinkSocket):
+    class ovs_vport_msg(ovs_dp_msg):
+        nla_map = (
+            ("OVS_VPORT_ATTR_UNSPEC", "none"),
+            ("OVS_VPORT_ATTR_PORT_NO", "uint32"),
+            ("OVS_VPORT_ATTR_TYPE", "uint32"),
+            ("OVS_VPORT_ATTR_NAME", "asciiz"),
+            ("OVS_VPORT_ATTR_OPTIONS", "none"),
+            ("OVS_VPORT_ATTR_UPCALL_PID", "array(uint32)"),
+            ("OVS_VPORT_ATTR_STATS", "vportstats"),
+            ("OVS_VPORT_ATTR_PAD", "none"),
+            ("OVS_VPORT_ATTR_IFINDEX", "uint32"),
+            ("OVS_VPORT_ATTR_NETNSID", "uint32"),
+        )
+
+        class vportstats(nla):
+            fields = (
+                ("rx_packets", "=Q"),
+                ("tx_packets", "=Q"),
+                ("rx_bytes", "=Q"),
+                ("tx_bytes", "=Q"),
+                ("rx_errors", "=Q"),
+                ("tx_errors", "=Q"),
+                ("rx_dropped", "=Q"),
+                ("tx_dropped", "=Q"),
+            )
+
+    def type_to_str(vport_type):
+        if vport_type == 1:
+            return "netdev"
+        elif vport_type == 2:
+            return "internal"
+        elif vport_type == 3:
+            return "gre"
+        elif vport_type == 4:
+            return "vxlan"
+        elif vport_type == 5:
+            return "geneve"
+        return "unknown:%d" % vport_type
+
+    def __init__(self):
+        GenericNetlinkSocket.__init__(self)
+        self.bind(OVS_VPORT_FAMILY, OvsVport.ovs_vport_msg)
+
+    def info(self, vport_name, dpifindex=0, portno=None):
+        msg = OvsVport.ovs_vport_msg()
+
+        msg["cmd"] = OVS_VPORT_CMD_GET
+        msg["version"] = OVS_DATAPATH_VERSION
+        msg["reserved"] = 0
+        msg["dpifindex"] = dpifindex
+
+        if portno is None:
+            msg["attrs"].append(["OVS_VPORT_ATTR_NAME", vport_name])
+        else:
+            msg["attrs"].append(["OVS_VPORT_ATTR_PORT_NO", portno])
+
+        try:
+            reply = self.nlm_request(
+                msg, msg_type=self.prid, msg_flags=NLM_F_REQUEST
+            )
+            reply = reply[0]
+        except NetlinkError as ne:
+            if ne.code == errno.ENODEV:
+                reply = None
+            else:
+                raise ne
+        return reply
+
+
+def print_ovsdp_full(dp_lookup_rep, ifindex, ndb=NDB()):
+    dp_name = dp_lookup_rep.get_attr("OVS_DP_ATTR_NAME")
+    base_stats = dp_lookup_rep.get_attr("OVS_DP_ATTR_STATS")
+    megaflow_stats = dp_lookup_rep.get_attr("OVS_DP_ATTR_MEGAFLOW_STATS")
+    user_features = dp_lookup_rep.get_attr("OVS_DP_ATTR_USER_FEATURES")
+    masks_cache_size = dp_lookup_rep.get_attr("OVS_DP_ATTR_MASKS_CACHE_SIZE")
+
+    print("%s:" % dp_name)
+    print(
+        "  lookups: hit:%d missed:%d lost:%d"
+        % (base_stats["hit"], base_stats["missed"], base_stats["lost"])
+    )
+    print("  flows:%d" % base_stats["flows"])
+    pkts = base_stats["hit"] + base_stats["missed"]
+    avg = (megaflow_stats["mask_hit"] / pkts) if pkts != 0 else 0.0
+    print(
+        "  masks: hit:%d total:%d hit/pkt:%f"
+        % (megaflow_stats["mask_hit"], megaflow_stats["masks"], avg)
+    )
+    print("  caches:")
+    print("    masks-cache: size:%d" % masks_cache_size)
+
+    if user_features is not None:
+        print("  features: 0x%X" % user_features)
+
+    # port print out
+    vpl = OvsVport()
+    for iface in ndb.interfaces:
+        rep = vpl.info(iface.ifname, ifindex)
+        if rep is not None:
+            print(
+                "  port %d: %s (%s)"
+                % (
+                    rep.get_attr("OVS_VPORT_ATTR_PORT_NO"),
+                    rep.get_attr("OVS_VPORT_ATTR_NAME"),
+                    OvsVport.type_to_str(rep.get_attr("OVS_VPORT_ATTR_TYPE")),
+                )
+            )
+
+
+def main(argv):
+    parser = argparse.ArgumentParser()
+    parser.add_argument(
+        "-v",
+        "--verbose",
+        action="count",
+        help="Increment 'verbose' output counter.",
+    )
+    subparsers = parser.add_subparsers()
+
+    showdpcmd = subparsers.add_parser("show")
+    showdpcmd.add_argument(
+        "showdp", metavar="N", type=str, nargs="?", help="Datapath Name"
+    )
+
+    adddpcmd = subparsers.add_parser("add-dp")
+    adddpcmd.add_argument("adddp", help="Datapath Name")
+    adddpcmd.add_argument(
+        "-u",
+        "--upcall",
+        action="store_true",
+        help="Leave open a reader for upcalls",
+    )
+    adddpcmd.add_argument(
+        "-V",
+        "--versioning",
+        required=False,
+        help="Specify a custom version / feature string",
+    )
+
+    deldpcmd = subparsers.add_parser("del-dp")
+    deldpcmd.add_argument("deldp", help="Datapath Name")
+
+    args = parser.parse_args()
+
+    ovsdp = OvsDatapath()
+    ndb = NDB()
+
+    if hasattr(args, "showdp"):
+        found = False
+        for iface in ndb.interfaces:
+            rep = None
+            if args.showdp is None:
+                rep = ovsdp.info(iface.ifname, 0)
+            elif args.showdp == iface.ifname:
+                rep = ovsdp.info(iface.ifname, 0)
+
+            if rep is not None:
+                found = True
+                print_ovsdp_full(rep, iface.index, ndb)
+
+        if not found:
+            msg = "No DP found"
+            if args.showdp is not None:
+                msg += ":'%s'" % args.showdp
+            print(msg)
+    elif hasattr(args, "adddp"):
+        rep = ovsdp.create(args.adddp, args.upcall, args.versioning)
+        if rep is None:
+            print("DP '%s' already exists" % args.adddp)
+        else:
+            print("DP '%s' added" % args.adddp)
+    elif hasattr(args, "deldp"):
+        ovsdp.destroy(args.deldp)
+
+    return 0
+
+
+if __name__ == "__main__":
+    sys.exit(main(sys.argv))