]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
Merge tag 'pm-6.7-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 8 Dec 2023 19:57:55 +0000 (11:57 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 8 Dec 2023 19:57:55 +0000 (11:57 -0800)
Pull power management fix from Rafael Wysocki:
 "Fix cpufreq reference counting in the DTPM (dynamic thermal and power
  management) power capping framework (Lukasz Luba)"

* tag 'pm-6.7-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm:
  powercap: DTPM: Fix missing cpufreq_cpu_put() calls

300 files changed:
.mailmap
CREDITS
Documentation/ABI/testing/sysfs-bus-optee-devices
Documentation/devicetree/bindings/display/bridge/adi,adv7533.yaml
Documentation/devicetree/bindings/display/fsl,lcdif.yaml
Documentation/devicetree/bindings/display/mediatek/mediatek,dsi.yaml
Documentation/devicetree/bindings/interrupt-controller/qcom,mpm.yaml
Documentation/devicetree/bindings/perf/riscv,pmu.yaml
Documentation/devicetree/bindings/pwm/imx-pwm.yaml
Documentation/devicetree/bindings/soc/rockchip/grf.yaml
Documentation/networking/tcp_ao.rst
MAINTAINERS
arch/arm/boot/dts/broadcom/bcm2711-rpi-400.dts
arch/arm/boot/dts/nxp/imx/imx6q-skov-reve-mi1010ait-1cp1.dts
arch/arm/boot/dts/nxp/imx/imx6ul-pico.dtsi
arch/arm/boot/dts/nxp/imx/imx7s.dtsi
arch/arm/boot/dts/nxp/mxs/imx28-xea.dts
arch/arm/boot/dts/rockchip/rk3128.dtsi
arch/arm/boot/dts/rockchip/rk322x.dtsi
arch/arm/include/asm/kexec.h
arch/arm/kernel/Makefile
arch/arm/mach-imx/mmdc.c
arch/arm64/boot/dts/freescale/imx8-apalis-v1.1.dtsi
arch/arm64/boot/dts/freescale/imx8-ss-dma.dtsi
arch/arm64/boot/dts/freescale/imx8-ss-lsio.dtsi
arch/arm64/boot/dts/freescale/imx8mp.dtsi
arch/arm64/boot/dts/freescale/imx8mq.dtsi
arch/arm64/boot/dts/freescale/imx8qm-ss-dma.dtsi
arch/arm64/boot/dts/freescale/imx8ulp.dtsi
arch/arm64/boot/dts/freescale/imx93-tqma9352-mba93xxla.dts
arch/arm64/boot/dts/freescale/imx93.dtsi
arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts
arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts
arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3.dts
arch/arm64/boot/dts/mediatek/mt7986a.dtsi
arch/arm64/boot/dts/mediatek/mt8173-evb.dts
arch/arm64/boot/dts/mediatek/mt8183-evb.dts
arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi.dtsi
arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi
arch/arm64/boot/dts/mediatek/mt8183.dtsi
arch/arm64/boot/dts/mediatek/mt8186.dtsi
arch/arm64/boot/dts/mediatek/mt8195-cherry.dtsi
arch/arm64/boot/dts/mediatek/mt8195.dtsi
arch/arm64/boot/dts/rockchip/px30-ringneck-haikou.dts
arch/arm64/boot/dts/rockchip/rk3328.dtsi
arch/arm64/boot/dts/rockchip/rk3399-gru-chromebook.dtsi
arch/arm64/boot/dts/rockchip/rk3399-gru-scarlet-dumo.dts
arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi
arch/arm64/boot/dts/rockchip/rk3399.dtsi
arch/arm64/boot/dts/rockchip/rk356x.dtsi
arch/arm64/boot/dts/rockchip/rk3588-turing-rk1.dtsi
arch/arm64/boot/dts/rockchip/rk3588s-orangepi-5.dts
arch/arm64/boot/dts/rockchip/rk3588s-pinctrl.dtsi
arch/arm64/boot/dts/rockchip/rk3588s.dtsi
arch/parisc/include/asm/bug.h
arch/riscv/boot/dts/microchip/mpfs-icicle-kit.dts
arch/riscv/boot/dts/microchip/mpfs-m100pfsevp.dts
arch/riscv/boot/dts/microchip/mpfs-polarberry.dts
arch/riscv/boot/dts/microchip/mpfs-sev-kit.dts
arch/riscv/boot/dts/microchip/mpfs-tysom-m.dts
arch/riscv/boot/dts/microchip/mpfs.dtsi
arch/riscv/boot/dts/sophgo/cv1800b.dtsi
arch/riscv/errata/andes/errata.c
arch/riscv/kernel/head.S
arch/riscv/kernel/module.c
arch/riscv/kernel/sys_riscv.c
arch/riscv/kernel/tests/module_test/test_uleb128.S
arch/riscv/kernel/traps_misaligned.c
arch/x86/coco/tdx/tdx.c
arch/x86/entry/common.c
arch/x86/entry/entry_64_compat.S
arch/x86/include/asm/ia32.h
arch/x86/include/asm/idtentry.h
arch/x86/include/asm/proto.h
arch/x86/kernel/idt.c
arch/x86/mm/mem_encrypt_amd.c
arch/x86/net/bpf_jit_comp.c
arch/x86/xen/enlighten_pv.c
arch/x86/xen/xen-asm.S
drivers/acpi/utils.c
drivers/base/cpu.c
drivers/base/memory.c
drivers/base/regmap/regcache.c
drivers/firmware/arm_ffa/driver.c
drivers/firmware/arm_scmi/perf.c
drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
drivers/gpu/drm/amd/amdgpu/amdgpu_mca.h
drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c
drivers/gpu/drm/amd/amdgpu/hdp_v4_0.c
drivers/gpu/drm/amd/amdgpu/psp_v13_0.c
drivers/gpu/drm/amd/amdgpu/soc15.c
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c
drivers/gpu/drm/amd/display/dc/dml/Makefile
drivers/gpu/drm/amd/display/dc/dml2/display_mode_core.c
drivers/gpu/drm/amd/include/kgd_pp_interface.h
drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h
drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu14_driver_if_v14_0_0.h
drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c
drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_0_ppt.c
drivers/gpu/drm/bridge/Kconfig
drivers/gpu/drm/drm_atomic_helper.c
drivers/gpu/drm/exynos/exynos_drm_dma.c
drivers/gpu/drm/exynos/exynos_hdmi.c
drivers/gpu/drm/i915/display/icl_dsi.c
drivers/gpu/drm/i915/display/intel_crt.c
drivers/gpu/drm/i915/display/intel_display.c
drivers/gpu/drm/i915/display/intel_display.h
drivers/gpu/drm/i915/display/intel_dp.c
drivers/gpu/drm/i915/display/intel_dp_mst.c
drivers/gpu/drm/i915/display/intel_dsb.c
drivers/gpu/drm/i915/display/intel_dvo.c
drivers/gpu/drm/i915/display/intel_hdmi.c
drivers/gpu/drm/i915/display/intel_lvds.c
drivers/gpu/drm/i915/display/intel_sdvo.c
drivers/gpu/drm/i915/display/intel_tv.c
drivers/gpu/drm/i915/display/vlv_dsi.c
drivers/gpu/drm/nouveau/dispnv50/disp.c
drivers/gpu/drm/nouveau/include/nvrm/535.113.01/common/shared/msgq/inc/msgq/msgq_priv.h
drivers/gpu/drm/nouveau/nvkm/subdev/gsp/r535.c
drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmtu102.c
drivers/gpu/drm/panfrost/panfrost_devfreq.c
drivers/gpu/drm/panfrost/panfrost_gem.c
drivers/hwmon/acpi_power_meter.c
drivers/hwmon/corsair-psu.c
drivers/hwmon/ltc2991.c
drivers/hwmon/max31827.c
drivers/hwmon/nzxt-kraken2.c
drivers/iommu/iommufd/device.c
drivers/iommu/iommufd/hw_pagetable.c
drivers/iommu/iommufd/ioas.c
drivers/iommu/iommufd/iommufd_private.h
drivers/iommu/iommufd/main.c
drivers/iommu/iommufd/selftest.c
drivers/iommu/iommufd/vfio_compat.c
drivers/leds/trigger/ledtrig-netdev.c
drivers/net/arcnet/arcdevice.h
drivers/net/arcnet/com20020-pci.c
drivers/net/dsa/microchip/ksz_common.c
drivers/net/dsa/mv88e6xxx/pcs-639x.c
drivers/net/ethernet/aquantia/atlantic/aq_ptp.c
drivers/net/ethernet/aquantia/atlantic/aq_ptp.h
drivers/net/ethernet/aquantia/atlantic/aq_ring.c
drivers/net/ethernet/broadcom/bnxt/bnxt_tc.c
drivers/net/ethernet/broadcom/tg3.c
drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c
drivers/net/ethernet/hisilicon/hns/hns_enet.c
drivers/net/ethernet/hisilicon/hns/hns_enet.h
drivers/net/ethernet/intel/i40e/i40e_main.c
drivers/net/ethernet/intel/iavf/iavf_ethtool.c
drivers/net/ethernet/intel/iavf/iavf_txrx.h
drivers/net/ethernet/intel/ice/ice_sriov.c
drivers/net/ethernet/intel/ice/ice_vf_vsi_vlan_ops.c
drivers/net/ethernet/intel/ice/ice_virtchnl.c
drivers/net/ethernet/marvell/octeontx2/af/mbox.h
drivers/net/ethernet/marvell/octeontx2/af/mcs.c
drivers/net/ethernet/marvell/octeontx2/af/mcs.h
drivers/net/ethernet/marvell/octeontx2/af/mcs_reg.h
drivers/net/ethernet/marvell/octeontx2/af/rvu.c
drivers/net/ethernet/marvell/octeontx2/af/rvu.h
drivers/net/ethernet/marvell/octeontx2/af/rvu_devlink.c
drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c
drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c
drivers/net/ethernet/marvell/octeontx2/af/rvu_reg.c
drivers/net/ethernet/marvell/octeontx2/af/rvu_reg.h
drivers/net/ethernet/marvell/octeontx2/nic/otx2_ethtool.c
drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c
drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.c
drivers/net/ethernet/netronome/nfp/flower/tunnel_conf.c
drivers/net/ethernet/pensando/ionic/ionic_dev.h
drivers/net/ethernet/pensando/ionic/ionic_lif.c
drivers/net/ethernet/realtek/r8169_main.c
drivers/net/ethernet/stmicro/stmmac/dwmac5.c
drivers/net/ethernet/stmicro/stmmac/dwmac5.h
drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
drivers/net/ethernet/stmicro/stmmac/hwif.h
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c
drivers/net/hyperv/Kconfig
drivers/net/usb/r8152.c
drivers/net/veth.c
drivers/of/dynamic.c
drivers/platform/mellanox/mlxbf-bootctl.c
drivers/platform/mellanox/mlxbf-pmc.c
drivers/platform/surface/aggregator/core.c
drivers/platform/x86/Kconfig
drivers/platform/x86/asus-nb-wmi.c
drivers/platform/x86/asus-wmi.c
drivers/platform/x86/asus-wmi.h
drivers/platform/x86/wmi.c
drivers/pwm/pwm-bcm2835.c
drivers/tee/optee/device.c
drivers/vdpa/mlx5/net/mlx5_vnet.c
drivers/vdpa/pds/debugfs.c
drivers/vdpa/pds/vdpa_dev.c
fs/Kconfig
fs/nilfs2/sufile.c
fs/nilfs2/the_nilfs.c
fs/proc/task_mmu.c
fs/squashfs/block.c
include/drm/drm_atomic_helper.h
include/linux/arm_ffa.h
include/linux/bpf.h
include/linux/highmem.h
include/linux/hugetlb.h
include/linux/platform_data/x86/asus-wmi.h
include/linux/stmmac.h
include/linux/tcp.h
include/linux/units.h
include/linux/usb/r8152.h
include/net/genetlink.h
include/net/tcp.h
include/net/tcp_ao.h
kernel/Kconfig.kexec
kernel/bpf/arraymap.c
kernel/bpf/core.c
kernel/cgroup/legacy_freezer.c
kernel/trace/ring_buffer.c
kernel/trace/trace.c
kernel/workqueue.c
lib/group_cpus.c
mm/Kconfig
mm/damon/core.c
mm/damon/sysfs-schemes.c
mm/filemap.c
mm/hugetlb.c
mm/kmemleak.c
mm/madvise.c
mm/memcontrol.c
mm/memory.c
mm/memory_hotplug.c
net/core/drop_monitor.c
net/core/filter.c
net/ipv4/ip_gre.c
net/ipv4/tcp.c
net/ipv4/tcp_ao.c
net/ipv4/tcp_input.c
net/ipv4/tcp_ipv4.c
net/ipv4/tcp_minisocks.c
net/ipv4/tcp_output.c
net/ipv6/ip6_fib.c
net/ipv6/tcp_ipv6.c
net/netfilter/nf_bpf_link.c
net/netfilter/nf_tables_api.c
net/netfilter/nft_dynset.c
net/netfilter/nft_exthdr.c
net/netfilter/nft_fib.c
net/netfilter/nft_set_pipapo.c
net/netfilter/xt_owner.c
net/netlink/genetlink.c
net/packet/af_packet.c
net/packet/internal.h
net/psample/psample.c
net/smc/af_smc.c
net/smc/smc_clc.c
net/smc/smc_clc.h
net/tls/tls_sw.c
net/vmw_vsock/virtio_transport_common.c
net/xdp/xsk.c
scripts/checkstack.pl
scripts/dtc/dt-extract-compatibles
scripts/gdb/linux/device.py
scripts/gdb/linux/tasks.py
sound/core/pcm.c
sound/drivers/pcmtest.c
sound/pci/hda/patch_realtek.c
sound/soc/amd/acp-config.c
sound/soc/amd/yc/acp6x-mach.c
sound/soc/codecs/cs43130.c
sound/soc/codecs/da7219-aad.c
sound/soc/codecs/hdac_hda.c
sound/soc/codecs/lpass-tx-macro.c
sound/soc/codecs/nau8822.c
sound/soc/codecs/rt5645.c
sound/soc/codecs/wm8974.c
sound/soc/codecs/wm_adsp.c
sound/soc/fsl/Kconfig
sound/soc/fsl/fsl_sai.c
sound/soc/fsl/fsl_xcvr.c
sound/soc/intel/boards/skl_hda_dsp_generic.c
sound/soc/intel/boards/sof_sdw.c
sound/soc/intel/skylake/skl-pcm.c
sound/soc/intel/skylake/skl-sst-ipc.c
sound/soc/qcom/sc8280xp.c
sound/soc/soc-ops.c
sound/soc/soc-pcm.c
sound/soc/sof/ipc3-topology.c
sound/soc/sof/ipc4-control.c
sound/soc/sof/ipc4-topology.c
sound/soc/sof/ipc4-topology.h
sound/soc/sof/mediatek/mt8186/mt8186.c
sound/soc/sof/sof-audio.c
sound/soc/sof/sof-audio.h
sound/soc/sof/topology.c
sound/usb/mixer_quirks.c
tools/testing/selftests/bpf/prog_tests/tailcalls.c
tools/testing/selftests/bpf/progs/tailcall_poke.c [new file with mode: 0644]
tools/testing/selftests/iommu/iommufd_utils.h
tools/testing/selftests/mm/Makefile
tools/testing/selftests/mm/pagemap_ioctl.c

index 43031441b2d922b3126b26ba754ea748a3f63540..19eb49e55836b0c086a63225158db62991cef8b9 100644 (file)
--- a/.mailmap
+++ b/.mailmap
@@ -117,6 +117,7 @@ Changbin Du <changbin.du@intel.com> <changbin.du@gmail.com>
 Changbin Du <changbin.du@intel.com> <changbin.du@intel.com>
 Chao Yu <chao@kernel.org> <chao2.yu@samsung.com>
 Chao Yu <chao@kernel.org> <yuchao0@huawei.com>
+Chester Lin <chester62515@gmail.com> <clin@suse.com>
 Chris Chiu <chris.chiu@canonical.com> <chiu@endlessm.com>
 Chris Chiu <chris.chiu@canonical.com> <chiu@endlessos.org>
 Chris Lew <quic_clew@quicinc.com> <clew@codeaurora.org>
diff --git a/CREDITS b/CREDITS
index f33a33fd2371707b5b22e99408dc18cae59653de..81845c39e3cf3755394488ec44a507095d952a03 100644 (file)
--- a/CREDITS
+++ b/CREDITS
@@ -2944,6 +2944,14 @@ D: IPX development and support
 N: Venkatesh Pallipadi (Venki)
 D: x86/HPET
 
+N: Antti Palosaari
+E: crope@iki.fi
+D: Various DVB drivers
+W: https://palosaari.fi/linux/
+S: Yliopistokatu 1 D 513
+S: FI-90570 Oulu
+S: FINLAND
+
 N: Kyungmin Park
 E: kyungmin.park@samsung.com
 D: Samsung S5Pv210 and Exynos4210 mobile platforms
index 0f58701367b66a57201e4a1bf1520cc069cc4122..af31e5a22d89fcc0b07413c8722fa64af3e1a5f0 100644 (file)
@@ -6,3 +6,12 @@ Description:
                OP-TEE bus provides reference to registered drivers under this directory. The <uuid>
                matches Trusted Application (TA) driver and corresponding TA in secure OS. Drivers
                are free to create needed API under optee-ta-<uuid> directory.
+
+What:          /sys/bus/tee/devices/optee-ta-<uuid>/need_supplicant
+Date:          November 2023
+KernelVersion: 6.7
+Contact:       op-tee@lists.trustedfirmware.org
+Description:
+               Allows to distinguish whether an OP-TEE based TA/device requires user-space
+               tee-supplicant to function properly or not. This attribute will be present for
+               devices which depend on tee-supplicant to be running.
index 987aa83c2649436f23ccfaf2a3e38ab77a8b6f7d..df20a3c9c74479afcc219f7445801998464e6762 100644 (file)
@@ -9,6 +9,9 @@ title: Analog Devices ADV7533/35 HDMI Encoders
 maintainers:
   - Laurent Pinchart <laurent.pinchart@ideasonboard.com>
 
+allOf:
+  - $ref: /schemas/sound/dai-common.yaml#
+
 description: |
   The ADV7533 and ADV7535 are HDMI audio and video transmitters
   compatible with HDMI 1.4 and DVI 1.0. They support color space
@@ -89,6 +92,9 @@ properties:
     $ref: /schemas/types.yaml#/definitions/uint32
     enum: [ 1, 2, 3, 4 ]
 
+  "#sound-dai-cells":
+    const: 0
+
   ports:
     description:
       The ADV7533/35 has two video ports and one audio port.
index fc11ab5fc4654e555202b51ebf029982f57f0469..1c2be8d6f6334052058b203ea79ef89cbf50a049 100644 (file)
@@ -51,7 +51,10 @@ properties:
     minItems: 1
 
   interrupts:
-    maxItems: 1
+    items:
+      - description: LCDIF DMA interrupt
+      - description: LCDIF Error interrupt
+    minItems: 1
 
   power-domains:
     maxItems: 1
@@ -131,6 +134,21 @@ allOf:
     then:
       required:
         - power-domains
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - fsl,imx23-lcdif
+    then:
+      properties:
+        interrupts:
+          minItems: 2
+          maxItems: 2
+    else:
+      properties:
+        interrupts:
+          maxItems: 1
 
 examples:
   - |
index 537e5304b73006062596cf40af749b885301d05e..ed24b617090b065ff000d265aacf0e2547e7fd5f 100644 (file)
@@ -10,7 +10,6 @@ maintainers:
   - Chun-Kuang Hu <chunkuang.hu@kernel.org>
   - Philipp Zabel <p.zabel@pengutronix.de>
   - Jitao Shi <jitao.shi@mediatek.com>
-  - Xinlei Lee <xinlei.lee@mediatek.com>
 
 description: |
   The MediaTek DSI function block is a sink of the display subsystem and can
index 509d20c091af8231f728b1639b872db862a4e375..6a206111d4e0f0a737a71b0615ffd3084c3d9a7d 100644 (file)
@@ -62,6 +62,9 @@ properties:
         - description: MPM pin number
         - description: GIC SPI number for the MPM pin
 
+  '#power-domain-cells':
+    const: 0
+
 required:
   - compatible
   - reg
@@ -93,4 +96,5 @@ examples:
                            <86 183>,
                            <90 260>,
                            <91 260>;
+        #power-domain-cells = <0>;
     };
index c8448de2f2a07c8999d936ea7584058d1823a319..d01c677ad3c765e52cf69c9c93423daaeff13831 100644 (file)
@@ -90,7 +90,7 @@ properties:
             bitmap of all MHPMCOUNTERx that can monitor the range of events
 
 dependencies:
-  "riscv,event-to-mhpmevent": [ "riscv,event-to-mhpmcounters" ]
+  riscv,event-to-mhpmevent: [ "riscv,event-to-mhpmcounters" ]
 
 required:
   - compatible
index c01dff3b7f843eba22f21d556f9f316bbffa757a..a84a240a61dc1f92c403dfb973420751a2c00068 100644 (file)
@@ -14,12 +14,10 @@ allOf:
 
 properties:
   "#pwm-cells":
-    description: |
-      Should be 2 for i.MX1 and 3 for i.MX27 and newer SoCs. See pwm.yaml
-      in this directory for a description of the cells format.
-    enum:
-      - 2
-      - 3
+    description:
+      The only third cell flag supported by this binding is
+      PWM_POLARITY_INVERTED. fsl,imx1-pwm does not support this flags.
+    const: 3
 
   compatible:
     oneOf:
index e4fa6a07b4fa2c6fc5f2d94d15e0c57b1bf51783..1309bf5ae0cdd1c68a5fad255edb9d21c2a17317 100644 (file)
@@ -233,6 +233,7 @@ allOf:
               - rockchip,rk3399-grf
               - rockchip,rk3399-pmugrf
               - rockchip,rk3568-pmugrf
+              - rockchip,rk3588-pmugrf
               - rockchip,rv1108-grf
               - rockchip,rv1108-pmugrf
 
index cfa5bf1cc5423cd68ad7d83a9d7e734744481085..8a58321acce72fc23c7ab56ffa05e738c79e0c74 100644 (file)
@@ -99,7 +99,7 @@ also [6.1]::
    when it is no longer considered permitted.
 
 Linux TCP-AO will try its best to prevent you from removing a key that's
-being used, considering it a key management failure. But sine keeping
+being used, considering it a key management failure. But since keeping
 an outdated key may become a security issue and as a peer may
 unintentionally prevent the removal of an old key by always setting
 it as RNextKeyID - a forced key removal mechanism is provided, where
index 788be9ab5b733a151bbd1ef85fe07414f374016c..d33cdf3d3ca64a6bf59c66049fa13790ef5e3d9c 100644 (file)
@@ -171,13 +171,10 @@ S:        Supported
 F:     drivers/soc/fujitsu/a64fx-diag.c
 
 A8293 MEDIA DRIVER
-M:     Antti Palosaari <crope@iki.fi>
 L:     linux-media@vger.kernel.org
-S:     Maintained
+S:     Orphan
 W:     https://linuxtv.org
-W:     http://palosaari.fi/linux/
 Q:     http://patchwork.linuxtv.org/project/linux-media/list/
-T:     git git://linuxtv.org/anttip/media_tree.git
 F:     drivers/media/dvb-frontends/a8293*
 
 AACRAID SCSI RAID DRIVER
@@ -576,23 +573,17 @@ F:        drivers/iio/accel/adxl372_i2c.c
 F:     drivers/iio/accel/adxl372_spi.c
 
 AF9013 MEDIA DRIVER
-M:     Antti Palosaari <crope@iki.fi>
 L:     linux-media@vger.kernel.org
-S:     Maintained
+S:     Orphan
 W:     https://linuxtv.org
-W:     http://palosaari.fi/linux/
 Q:     http://patchwork.linuxtv.org/project/linux-media/list/
-T:     git git://linuxtv.org/anttip/media_tree.git
 F:     drivers/media/dvb-frontends/af9013*
 
 AF9033 MEDIA DRIVER
-M:     Antti Palosaari <crope@iki.fi>
 L:     linux-media@vger.kernel.org
-S:     Maintained
+S:     Orphan
 W:     https://linuxtv.org
-W:     http://palosaari.fi/linux/
 Q:     http://patchwork.linuxtv.org/project/linux-media/list/
-T:     git git://linuxtv.org/anttip/media_tree.git
 F:     drivers/media/dvb-frontends/af9033*
 
 AFFS FILE SYSTEM
@@ -650,13 +641,10 @@ F:        fs/aio.c
 F:     include/linux/*aio*.h
 
 AIRSPY MEDIA DRIVER
-M:     Antti Palosaari <crope@iki.fi>
 L:     linux-media@vger.kernel.org
-S:     Maintained
+S:     Orphan
 W:     https://linuxtv.org
-W:     http://palosaari.fi/linux/
 Q:     http://patchwork.linuxtv.org/project/linux-media/list/
-T:     git git://linuxtv.org/anttip/media_tree.git
 F:     drivers/media/usb/airspy/
 
 ALACRITECH GIGABIT ETHERNET DRIVER
@@ -2155,6 +2143,7 @@ S:        Maintained
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/shawnguo/linux.git
 F:     arch/arm/boot/dts/nxp/imx/
 F:     arch/arm/boot/dts/nxp/mxs/
+F:     arch/arm64/boot/dts/freescale/
 X:     arch/arm64/boot/dts/freescale/fsl-*
 X:     arch/arm64/boot/dts/freescale/qoriq-*
 X:     drivers/media/i2c/
@@ -2535,7 +2524,7 @@ F:        drivers/*/*/*wpcm*
 F:     drivers/*/*wpcm*
 
 ARM/NXP S32G ARCHITECTURE
-M:     Chester Lin <clin@suse.com>
+M:     Chester Lin <chester62515@gmail.com>
 R:     Andreas Färber <afaerber@suse.de>
 R:     Matthias Brugger <mbrugger@suse.com>
 R:     NXP S32 Linux Team <s32@nxp.com>
@@ -5604,13 +5593,10 @@ F:      Documentation/driver-api/media/drivers/cx88*
 F:     drivers/media/pci/cx88/
 
 CXD2820R MEDIA DRIVER
-M:     Antti Palosaari <crope@iki.fi>
 L:     linux-media@vger.kernel.org
-S:     Maintained
+S:     Orphan
 W:     https://linuxtv.org
-W:     http://palosaari.fi/linux/
 Q:     http://patchwork.linuxtv.org/project/linux-media/list/
-T:     git git://linuxtv.org/anttip/media_tree.git
 F:     drivers/media/dvb-frontends/cxd2820r*
 
 CXGB3 ETHERNET DRIVER (CXGB3)
@@ -5723,13 +5709,10 @@ F:      Documentation/devicetree/bindings/input/cypress-sf.yaml
 F:     drivers/input/keyboard/cypress-sf.c
 
 CYPRESS_FIRMWARE MEDIA DRIVER
-M:     Antti Palosaari <crope@iki.fi>
 L:     linux-media@vger.kernel.org
-S:     Maintained
+S:     Orphan
 W:     https://linuxtv.org
-W:     http://palosaari.fi/linux/
 Q:     http://patchwork.linuxtv.org/project/linux-media/list/
-T:     git git://linuxtv.org/anttip/media_tree.git
 F:     drivers/media/common/cypress_firmware*
 
 CYTTSP TOUCHSCREEN DRIVER
@@ -7319,53 +7302,38 @@ T:      git git://linuxtv.org/media_tree.git
 F:     drivers/media/pci/dt3155/
 
 DVB_USB_AF9015 MEDIA DRIVER
-M:     Antti Palosaari <crope@iki.fi>
 L:     linux-media@vger.kernel.org
-S:     Maintained
+S:     Orphan
 W:     https://linuxtv.org
-W:     http://palosaari.fi/linux/
 Q:     http://patchwork.linuxtv.org/project/linux-media/list/
-T:     git git://linuxtv.org/anttip/media_tree.git
 F:     drivers/media/usb/dvb-usb-v2/af9015*
 
 DVB_USB_AF9035 MEDIA DRIVER
-M:     Antti Palosaari <crope@iki.fi>
 L:     linux-media@vger.kernel.org
-S:     Maintained
+S:     Orphan
 W:     https://linuxtv.org
-W:     http://palosaari.fi/linux/
 Q:     http://patchwork.linuxtv.org/project/linux-media/list/
-T:     git git://linuxtv.org/anttip/media_tree.git
 F:     drivers/media/usb/dvb-usb-v2/af9035*
 
 DVB_USB_ANYSEE MEDIA DRIVER
-M:     Antti Palosaari <crope@iki.fi>
 L:     linux-media@vger.kernel.org
-S:     Maintained
+S:     Orphan
 W:     https://linuxtv.org
-W:     http://palosaari.fi/linux/
 Q:     http://patchwork.linuxtv.org/project/linux-media/list/
-T:     git git://linuxtv.org/anttip/media_tree.git
 F:     drivers/media/usb/dvb-usb-v2/anysee*
 
 DVB_USB_AU6610 MEDIA DRIVER
-M:     Antti Palosaari <crope@iki.fi>
 L:     linux-media@vger.kernel.org
-S:     Maintained
+S:     Orphan
 W:     https://linuxtv.org
-W:     http://palosaari.fi/linux/
 Q:     http://patchwork.linuxtv.org/project/linux-media/list/
-T:     git git://linuxtv.org/anttip/media_tree.git
 F:     drivers/media/usb/dvb-usb-v2/au6610*
 
 DVB_USB_CE6230 MEDIA DRIVER
-M:     Antti Palosaari <crope@iki.fi>
 L:     linux-media@vger.kernel.org
-S:     Maintained
+S:     Orphan
 W:     https://linuxtv.org
-W:     http://palosaari.fi/linux/
 Q:     http://patchwork.linuxtv.org/project/linux-media/list/
-T:     git git://linuxtv.org/anttip/media_tree.git
 F:     drivers/media/usb/dvb-usb-v2/ce6230*
 
 DVB_USB_CXUSB MEDIA DRIVER
@@ -7379,22 +7347,17 @@ T:      git git://linuxtv.org/media_tree.git
 F:     drivers/media/usb/dvb-usb/cxusb*
 
 DVB_USB_EC168 MEDIA DRIVER
-M:     Antti Palosaari <crope@iki.fi>
 L:     linux-media@vger.kernel.org
-S:     Maintained
+S:     Orphan
 W:     https://linuxtv.org
-W:     http://palosaari.fi/linux/
 Q:     http://patchwork.linuxtv.org/project/linux-media/list/
-T:     git git://linuxtv.org/anttip/media_tree.git
 F:     drivers/media/usb/dvb-usb-v2/ec168*
 
 DVB_USB_GL861 MEDIA DRIVER
-M:     Antti Palosaari <crope@iki.fi>
 L:     linux-media@vger.kernel.org
-S:     Maintained
+S:     Orphan
 W:     https://linuxtv.org
 Q:     http://patchwork.linuxtv.org/project/linux-media/list/
-T:     git git://linuxtv.org/anttip/media_tree.git
 F:     drivers/media/usb/dvb-usb-v2/gl861*
 
 DVB_USB_MXL111SF MEDIA DRIVER
@@ -7408,23 +7371,18 @@ T:      git git://linuxtv.org/mkrufky/mxl111sf.git
 F:     drivers/media/usb/dvb-usb-v2/mxl111sf*
 
 DVB_USB_RTL28XXU MEDIA DRIVER
-M:     Antti Palosaari <crope@iki.fi>
 L:     linux-media@vger.kernel.org
-S:     Maintained
+S:     Orphan
 W:     https://linuxtv.org
-W:     http://palosaari.fi/linux/
 Q:     http://patchwork.linuxtv.org/project/linux-media/list/
-T:     git git://linuxtv.org/anttip/media_tree.git
 F:     drivers/media/usb/dvb-usb-v2/rtl28xxu*
 
 DVB_USB_V2 MEDIA DRIVER
-M:     Antti Palosaari <crope@iki.fi>
 L:     linux-media@vger.kernel.org
-S:     Maintained
+S:     Orphan
 W:     https://linuxtv.org
 W:     http://palosaari.fi/linux/
 Q:     http://patchwork.linuxtv.org/project/linux-media/list/
-T:     git git://linuxtv.org/anttip/media_tree.git
 F:     drivers/media/usb/dvb-usb-v2/dvb_usb*
 F:     drivers/media/usb/dvb-usb-v2/usb_urb.c
 
@@ -7466,13 +7424,10 @@ F:      Documentation/devicetree/bindings/input/e3x0-button.txt
 F:     drivers/input/misc/e3x0-button.c
 
 E4000 MEDIA DRIVER
-M:     Antti Palosaari <crope@iki.fi>
 L:     linux-media@vger.kernel.org
-S:     Maintained
+S:     Orphan
 W:     https://linuxtv.org
-W:     http://palosaari.fi/linux/
 Q:     http://patchwork.linuxtv.org/project/linux-media/list/
-T:     git git://linuxtv.org/anttip/media_tree.git
 F:     drivers/media/tuners/e4000*
 
 EARTH_PT1 MEDIA DRIVER
@@ -7488,13 +7443,10 @@ S:      Odd Fixes
 F:     drivers/media/pci/pt3/
 
 EC100 MEDIA DRIVER
-M:     Antti Palosaari <crope@iki.fi>
 L:     linux-media@vger.kernel.org
-S:     Maintained
+S:     Orphan
 W:     https://linuxtv.org
-W:     http://palosaari.fi/linux/
 Q:     http://patchwork.linuxtv.org/project/linux-media/list/
-T:     git git://linuxtv.org/anttip/media_tree.git
 F:     drivers/media/dvb-frontends/ec100*
 
 ECRYPT FILE SYSTEM
@@ -8112,13 +8064,10 @@ F:      drivers/media/tuners/fc0011.c
 F:     drivers/media/tuners/fc0011.h
 
 FC2580 MEDIA DRIVER
-M:     Antti Palosaari <crope@iki.fi>
 L:     linux-media@vger.kernel.org
-S:     Maintained
+S:     Orphan
 W:     https://linuxtv.org
-W:     http://palosaari.fi/linux/
 Q:     http://patchwork.linuxtv.org/project/linux-media/list/
-T:     git git://linuxtv.org/anttip/media_tree.git
 F:     drivers/media/tuners/fc2580*
 
 FCOE SUBSYSTEM (libfc, libfcoe, fcoe)
@@ -9248,13 +9197,10 @@ F:      include/trace/events/habanalabs.h
 F:     include/uapi/drm/habanalabs_accel.h
 
 HACKRF MEDIA DRIVER
-M:     Antti Palosaari <crope@iki.fi>
 L:     linux-media@vger.kernel.org
-S:     Maintained
+S:     Orphan
 W:     https://linuxtv.org
-W:     http://palosaari.fi/linux/
 Q:     http://patchwork.linuxtv.org/project/linux-media/list/
-T:     git git://linuxtv.org/anttip/media_tree.git
 F:     drivers/media/usb/hackrf/
 
 HANDSHAKE UPCALL FOR TRANSPORT LAYER SECURITY
@@ -11327,13 +11273,10 @@ F:    Documentation/hwmon/it87.rst
 F:     drivers/hwmon/it87.c
 
 IT913X MEDIA DRIVER
-M:     Antti Palosaari <crope@iki.fi>
 L:     linux-media@vger.kernel.org
-S:     Maintained
+S:     Orphan
 W:     https://linuxtv.org
-W:     http://palosaari.fi/linux/
 Q:     http://patchwork.linuxtv.org/project/linux-media/list/
-T:     git git://linuxtv.org/anttip/media_tree.git
 F:     drivers/media/tuners/it913x*
 
 ITE IT66121 HDMI BRIDGE DRIVER
@@ -12206,6 +12149,13 @@ F:     include/linux/nd.h
 F:     include/uapi/linux/ndctl.h
 F:     tools/testing/nvdimm/
 
+LIBRARY CODE
+M:     Andrew Morton <akpm@linux-foundation.org>
+L:     linux-kernel@vger.kernel.org
+S:     Supported
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm.git mm-nonmm-unstable
+F:     lib/*
+
 LICENSES and SPDX stuff
 M:     Thomas Gleixner <tglx@linutronix.de>
 M:     Greg Kroah-Hartman <gregkh@linuxfoundation.org>
@@ -12685,13 +12635,10 @@ W:    http://www.tazenda.demon.co.uk/phil/linux-hp
 F:     arch/m68k/hp300/
 
 M88DS3103 MEDIA DRIVER
-M:     Antti Palosaari <crope@iki.fi>
 L:     linux-media@vger.kernel.org
-S:     Maintained
+S:     Orphan
 W:     https://linuxtv.org
-W:     http://palosaari.fi/linux/
 Q:     http://patchwork.linuxtv.org/project/linux-media/list/
-T:     git git://linuxtv.org/anttip/media_tree.git
 F:     drivers/media/dvb-frontends/m88ds3103*
 
 M88RS2000 MEDIA DRIVER
@@ -14585,20 +14532,16 @@ F:    include/asm-generic/tlb.h
 F:     mm/mmu_gather.c
 
 MN88472 MEDIA DRIVER
-M:     Antti Palosaari <crope@iki.fi>
 L:     linux-media@vger.kernel.org
-S:     Maintained
+S:     Orphan
 W:     https://linuxtv.org
-W:     http://palosaari.fi/linux/
 Q:     http://patchwork.linuxtv.org/project/linux-media/list/
 F:     drivers/media/dvb-frontends/mn88472*
 
 MN88473 MEDIA DRIVER
-M:     Antti Palosaari <crope@iki.fi>
 L:     linux-media@vger.kernel.org
-S:     Maintained
+S:     Orphan
 W:     https://linuxtv.org
-W:     http://palosaari.fi/linux/
 Q:     http://patchwork.linuxtv.org/project/linux-media/list/
 F:     drivers/media/dvb-frontends/mn88473*
 
@@ -14686,23 +14629,17 @@ S:    Orphan
 F:     drivers/platform/x86/msi-wmi.c
 
 MSI001 MEDIA DRIVER
-M:     Antti Palosaari <crope@iki.fi>
 L:     linux-media@vger.kernel.org
-S:     Maintained
+S:     Orphan
 W:     https://linuxtv.org
-W:     http://palosaari.fi/linux/
 Q:     http://patchwork.linuxtv.org/project/linux-media/list/
-T:     git git://linuxtv.org/anttip/media_tree.git
 F:     drivers/media/tuners/msi001*
 
 MSI2500 MEDIA DRIVER
-M:     Antti Palosaari <crope@iki.fi>
 L:     linux-media@vger.kernel.org
-S:     Maintained
+S:     Orphan
 W:     https://linuxtv.org
-W:     http://palosaari.fi/linux/
 Q:     http://patchwork.linuxtv.org/project/linux-media/list/
-T:     git git://linuxtv.org/anttip/media_tree.git
 F:     drivers/media/usb/msi2500/
 
 MSTAR INTERRUPT CONTROLLER DRIVER
@@ -15066,6 +15003,7 @@ F:      lib/random32.c
 F:     net/
 F:     tools/net/
 F:     tools/testing/selftests/net/
+X:     net/9p/
 X:     net/bluetooth/
 
 NETWORKING [IPSEC]
@@ -17773,13 +17711,10 @@ F:    drivers/bus/fsl-mc/
 F:     include/uapi/linux/fsl_mc.h
 
 QT1010 MEDIA DRIVER
-M:     Antti Palosaari <crope@iki.fi>
 L:     linux-media@vger.kernel.org
-S:     Maintained
+S:     Orphan
 W:     https://linuxtv.org
-W:     http://palosaari.fi/linux/
 Q:     http://patchwork.linuxtv.org/project/linux-media/list/
-T:     git git://linuxtv.org/anttip/media_tree.git
 F:     drivers/media/tuners/qt1010*
 
 QUALCOMM ATH12K WIRELESS DRIVER
@@ -18834,33 +18769,24 @@ S:    Maintained
 F:     drivers/tty/rpmsg_tty.c
 
 RTL2830 MEDIA DRIVER
-M:     Antti Palosaari <crope@iki.fi>
 L:     linux-media@vger.kernel.org
-S:     Maintained
+S:     Orphan
 W:     https://linuxtv.org
-W:     http://palosaari.fi/linux/
 Q:     http://patchwork.linuxtv.org/project/linux-media/list/
-T:     git git://linuxtv.org/anttip/media_tree.git
 F:     drivers/media/dvb-frontends/rtl2830*
 
 RTL2832 MEDIA DRIVER
-M:     Antti Palosaari <crope@iki.fi>
 L:     linux-media@vger.kernel.org
-S:     Maintained
+S:     Orphan
 W:     https://linuxtv.org
-W:     http://palosaari.fi/linux/
 Q:     http://patchwork.linuxtv.org/project/linux-media/list/
-T:     git git://linuxtv.org/anttip/media_tree.git
 F:     drivers/media/dvb-frontends/rtl2832*
 
 RTL2832_SDR MEDIA DRIVER
-M:     Antti Palosaari <crope@iki.fi>
 L:     linux-media@vger.kernel.org
-S:     Maintained
+S:     Orphan
 W:     https://linuxtv.org
-W:     http://palosaari.fi/linux/
 Q:     http://patchwork.linuxtv.org/project/linux-media/list/
-T:     git git://linuxtv.org/anttip/media_tree.git
 F:     drivers/media/dvb-frontends/rtl2832_sdr*
 
 RTL8180 WIRELESS DRIVER
@@ -19670,13 +19596,10 @@ F:    drivers/media/platform/renesas/sh_vou.c
 F:     include/media/drv-intf/sh_vou.h
 
 SI2157 MEDIA DRIVER
-M:     Antti Palosaari <crope@iki.fi>
 L:     linux-media@vger.kernel.org
-S:     Maintained
+S:     Orphan
 W:     https://linuxtv.org
-W:     http://palosaari.fi/linux/
 Q:     http://patchwork.linuxtv.org/project/linux-media/list/
-T:     git git://linuxtv.org/anttip/media_tree.git
 F:     drivers/media/tuners/si2157*
 
 SI2165 MEDIA DRIVER
@@ -19688,13 +19611,10 @@ Q:    http://patchwork.linuxtv.org/project/linux-media/list/
 F:     drivers/media/dvb-frontends/si2165*
 
 SI2168 MEDIA DRIVER
-M:     Antti Palosaari <crope@iki.fi>
 L:     linux-media@vger.kernel.org
-S:     Maintained
+S:     Orphan
 W:     https://linuxtv.org
-W:     http://palosaari.fi/linux/
 Q:     http://patchwork.linuxtv.org/project/linux-media/list/
-T:     git git://linuxtv.org/anttip/media_tree.git
 F:     drivers/media/dvb-frontends/si2168*
 
 SI470X FM RADIO RECEIVER I2C DRIVER
@@ -21196,33 +21116,24 @@ W:    http://tcp-lp-mod.sourceforge.net/
 F:     net/ipv4/tcp_lp.c
 
 TDA10071 MEDIA DRIVER
-M:     Antti Palosaari <crope@iki.fi>
 L:     linux-media@vger.kernel.org
-S:     Maintained
+S:     Orphan
 W:     https://linuxtv.org
-W:     http://palosaari.fi/linux/
 Q:     http://patchwork.linuxtv.org/project/linux-media/list/
-T:     git git://linuxtv.org/anttip/media_tree.git
 F:     drivers/media/dvb-frontends/tda10071*
 
 TDA18212 MEDIA DRIVER
-M:     Antti Palosaari <crope@iki.fi>
 L:     linux-media@vger.kernel.org
-S:     Maintained
+S:     Orphan
 W:     https://linuxtv.org
-W:     http://palosaari.fi/linux/
 Q:     http://patchwork.linuxtv.org/project/linux-media/list/
-T:     git git://linuxtv.org/anttip/media_tree.git
 F:     drivers/media/tuners/tda18212*
 
 TDA18218 MEDIA DRIVER
-M:     Antti Palosaari <crope@iki.fi>
 L:     linux-media@vger.kernel.org
-S:     Maintained
+S:     Orphan
 W:     https://linuxtv.org
-W:     http://palosaari.fi/linux/
 Q:     http://patchwork.linuxtv.org/project/linux-media/list/
-T:     git git://linuxtv.org/anttip/media_tree.git
 F:     drivers/media/tuners/tda18218*
 
 TDA18250 MEDIA DRIVER
@@ -22158,13 +22069,10 @@ F:    include/uapi/linux/serial_core.h
 F:     include/uapi/linux/tty.h
 
 TUA9001 MEDIA DRIVER
-M:     Antti Palosaari <crope@iki.fi>
 L:     linux-media@vger.kernel.org
-S:     Maintained
+S:     Orphan
 W:     https://linuxtv.org
-W:     http://palosaari.fi/linux/
 Q:     http://patchwork.linuxtv.org/project/linux-media/list/
-T:     git git://linuxtv.org/anttip/media_tree.git
 F:     drivers/media/tuners/tua9001*
 
 TULIP NETWORK DRIVERS
@@ -24109,20 +24017,16 @@ S:    Orphan
 F:     drivers/net/wireless/zydas/zd1211rw/
 
 ZD1301 MEDIA DRIVER
-M:     Antti Palosaari <crope@iki.fi>
 L:     linux-media@vger.kernel.org
-S:     Maintained
+S:     Orphan
 W:     https://linuxtv.org/
-W:     http://palosaari.fi/linux/
 Q:     https://patchwork.linuxtv.org/project/linux-media/list/
 F:     drivers/media/usb/dvb-usb-v2/zd1301*
 
 ZD1301_DEMOD MEDIA DRIVER
-M:     Antti Palosaari <crope@iki.fi>
 L:     linux-media@vger.kernel.org
-S:     Maintained
+S:     Orphan
 W:     https://linuxtv.org/
-W:     http://palosaari.fi/linux/
 Q:     https://patchwork.linuxtv.org/project/linux-media/list/
 F:     drivers/media/dvb-frontends/zd1301_demod*
 
index 1ab8184302db448c2407fdc8929096dd1072cfa3..5a2869a18bd555cbacdb92c5a7cdee18cf6ef842 100644 (file)
@@ -36,9 +36,7 @@
        gpios = <&gpio 42 GPIO_ACTIVE_HIGH>;
 };
 
-&leds {
-       /delete-node/ led_act;
-};
+/delete-node/ &led_act;
 
 &pm {
        /delete-property/ system-power-controller;
index a3f247c722b438bcb91d6a22bee2633158b5fde7..0342a79ccd5db2c6e450121a9a157f2d0aaf77e5 100644 (file)
@@ -37,9 +37,9 @@
 
 &clks {
        assigned-clocks = <&clks IMX6QDL_CLK_LDB_DI0_SEL>,
-                         <&clks IMX6QDL_CLK_LDB_DI1_SEL>;
+                         <&clks IMX6QDL_CLK_LDB_DI1_SEL>, <&clks IMX6QDL_CLK_ENET_REF_SEL>;
        assigned-clock-parents = <&clks IMX6QDL_CLK_PLL5_VIDEO_DIV>,
-                                <&clks IMX6QDL_CLK_PLL5_VIDEO_DIV>;
+                                <&clks IMX6QDL_CLK_PLL5_VIDEO_DIV>, <&clk50m_phy>;
 };
 
 &hdmi {
index 4ffe99ed55ca2c000efd480ee54a914cb9c2b14b..07dcecbe485dca41b66f3deef932f750d31f5544 100644 (file)
                        max-speed = <100>;
                        interrupt-parent = <&gpio5>;
                        interrupts = <6 IRQ_TYPE_LEVEL_LOW>;
+                       clocks = <&clks IMX6UL_CLK_ENET_REF>;
+                       clock-names = "rmii-ref";
                };
        };
 };
index 29b8fd03567a54431e16f239d2f3202317f16451..5387da8a2a0a37f4d9662a5498d4612f379b8e4b 100644 (file)
                        };
 
                        gpt1: timer@302d0000 {
-                               compatible = "fsl,imx7d-gpt", "fsl,imx6sx-gpt";
+                               compatible = "fsl,imx7d-gpt", "fsl,imx6dl-gpt";
                                reg = <0x302d0000 0x10000>;
                                interrupts = <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clks IMX7D_GPT1_ROOT_CLK>,
                        };
 
                        gpt2: timer@302e0000 {
-                               compatible = "fsl,imx7d-gpt", "fsl,imx6sx-gpt";
+                               compatible = "fsl,imx7d-gpt", "fsl,imx6dl-gpt";
                                reg = <0x302e0000 0x10000>;
                                interrupts = <GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clks IMX7D_GPT2_ROOT_CLK>,
                        };
 
                        gpt3: timer@302f0000 {
-                               compatible = "fsl,imx7d-gpt", "fsl,imx6sx-gpt";
+                               compatible = "fsl,imx7d-gpt", "fsl,imx6dl-gpt";
                                reg = <0x302f0000 0x10000>;
                                interrupts = <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clks IMX7D_GPT3_ROOT_CLK>,
                        };
 
                        gpt4: timer@30300000 {
-                               compatible = "fsl,imx7d-gpt", "fsl,imx6sx-gpt";
+                               compatible = "fsl,imx7d-gpt", "fsl,imx6dl-gpt";
                                reg = <0x30300000 0x10000>;
                                interrupts = <GIC_SPI 52 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clks IMX7D_GPT4_ROOT_CLK>,
index a400c108f66a2d33f7e9ca3cf74421ad506ac75c..6c5e6856648af94099e3064081c1adb0fc792022 100644 (file)
@@ -8,6 +8,7 @@
 #include "imx28-lwe.dtsi"
 
 / {
+       model = "Liebherr XEA board";
        compatible = "lwn,imx28-xea", "fsl,imx28";
 };
 
index 7bf557c995614980a513a44915e579be6abe0304..01edf244ddeef6d6120a397cb40601a70b2fdc1a 100644 (file)
                        };
 
                        sdmmc_pwren: sdmmc-pwren {
-                               rockchip,pins = <1 RK_PB6 1 &pcfg_pull_default>;
+                               rockchip,pins = <1 RK_PB6 RK_FUNC_GPIO &pcfg_pull_default>;
                        };
 
                        sdmmc_bus4: sdmmc-bus4 {
index ffc16d6b97e1bd139957928889b5a21c6288407b..a721744cbfd17f76d6abac5c879311d12d0aaa87 100644 (file)
 
                        power-domain@RK3228_PD_VOP {
                                reg = <RK3228_PD_VOP>;
-                               clocks =<&cru ACLK_VOP>,
-                                       <&cru DCLK_VOP>,
-                                       <&cru HCLK_VOP>;
+                               clocks = <&cru ACLK_VOP>,
+                                        <&cru DCLK_VOP>,
+                                        <&cru HCLK_VOP>;
                                pm_qos = <&qos_vop>;
                                #power-domain-cells = <0>;
                        };
index e62832dcba7600d0780cec8462ff8e432ec788d9..a8287e7ab9d41ac88f2f30630c428bc18429eeff 100644 (file)
@@ -2,8 +2,6 @@
 #ifndef _ARM_KEXEC_H
 #define _ARM_KEXEC_H
 
-#ifdef CONFIG_KEXEC
-
 /* Maximum physical address we can use pages from */
 #define KEXEC_SOURCE_MEMORY_LIMIT (-1UL)
 /* Maximum address we can reach in physical address mode */
@@ -82,6 +80,4 @@ static inline struct page *boot_pfn_to_page(unsigned long boot_pfn)
 
 #endif /* __ASSEMBLY__ */
 
-#endif /* CONFIG_KEXEC */
-
 #endif /* _ARM_KEXEC_H */
index d53f56d6f840857a838517586f10ceb12f05412b..771264d4726a732030c9af167ab535a3395a532b 100644 (file)
@@ -59,7 +59,7 @@ obj-$(CONFIG_FUNCTION_TRACER) += entry-ftrace.o
 obj-$(CONFIG_DYNAMIC_FTRACE)   += ftrace.o insn.o patch.o
 obj-$(CONFIG_FUNCTION_GRAPH_TRACER)    += ftrace.o insn.o patch.o
 obj-$(CONFIG_JUMP_LABEL)       += jump_label.o insn.o patch.o
-obj-$(CONFIG_KEXEC)            += machine_kexec.o relocate_kernel.o
+obj-$(CONFIG_KEXEC_CORE)       += machine_kexec.o relocate_kernel.o
 # Main staffs in KPROBES are in arch/arm/probes/ .
 obj-$(CONFIG_KPROBES)          += patch.o insn.o
 obj-$(CONFIG_OABI_COMPAT)      += sys_oabi-compat.o
index 2157493b78a9bd3cbb98508b29d504ca5d196281..df69af9323754f06527458b1d7bb37dbe75f158b 100644 (file)
@@ -501,6 +501,10 @@ static int imx_mmdc_perf_init(struct platform_device *pdev, void __iomem *mmdc_b
 
        name = devm_kasprintf(&pdev->dev,
                                GFP_KERNEL, "mmdc%d", ret);
+       if (!name) {
+               ret = -ENOMEM;
+               goto pmu_release_id;
+       }
 
        pmu_mmdc->mmdc_ipg_clk = mmdc_ipg_clk;
        pmu_mmdc->devtype_data = (struct fsl_mmdc_devtype_data *)of_id->data;
@@ -523,9 +527,10 @@ static int imx_mmdc_perf_init(struct platform_device *pdev, void __iomem *mmdc_b
 
 pmu_register_err:
        pr_warn("MMDC Perf PMU failed (%d), disabled\n", ret);
-       ida_simple_remove(&mmdc_ida, pmu_mmdc->id);
        cpuhp_state_remove_instance_nocalls(cpuhp_mmdc_state, &pmu_mmdc->node);
        hrtimer_cancel(&pmu_mmdc->hrtimer);
+pmu_release_id:
+       ida_simple_remove(&mmdc_ida, pmu_mmdc->id);
 pmu_free:
        kfree(pmu_mmdc);
        return ret;
index 5ce5fbf2b38e4a0d2e15802ce9638e6e28ebba7e..f69b0c17560aee381f5384928b3d6071f3f141bd 100644 (file)
                pinctrl-0 = <&pinctrl_wifi_pdn>;
                gpio = <&lsio_gpio1 28 GPIO_ACTIVE_HIGH>;
                enable-active-high;
+               regulator-always-on;
                regulator-name = "wifi_pwrdn_fake_regulator";
                regulator-settling-time-us = <100>;
-
-               regulator-state-mem {
-                       regulator-off-in-suspend;
-               };
        };
 
        reg_pcie_switch: regulator-pcie-switch {
index ce66d30a4839b1562a25fafb4c7e24676077be78..b0bb77150adccb6c9610c1b0dcf510100495a772 100644 (file)
@@ -149,7 +149,7 @@ dma_subsys: bus@5a000000 {
                clock-names = "ipg", "per";
                assigned-clocks = <&clk IMX_SC_R_LCD_0_PWM_0 IMX_SC_PM_CLK_PER>;
                assigned-clock-rates = <24000000>;
-               #pwm-cells = <2>;
+               #pwm-cells = <3>;
                power-domains = <&pd IMX_SC_R_LCD_0_PWM_0>;
        };
 
index 49ad3413db9487c6635d8c8f30ea93d6ded497c0..7e510b21bbac555b38cede99f97b4edc177bf520 100644 (file)
@@ -29,7 +29,7 @@ lsio_subsys: bus@5d000000 {
                         <&pwm0_lpcg 1>;
                assigned-clocks = <&clk IMX_SC_R_PWM_0 IMX_SC_PM_CLK_PER>;
                assigned-clock-rates = <24000000>;
-               #pwm-cells = <2>;
+               #pwm-cells = <3>;
                interrupts = <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH>;
                status = "disabled";
        };
@@ -42,7 +42,7 @@ lsio_subsys: bus@5d000000 {
                         <&pwm1_lpcg 1>;
                assigned-clocks = <&clk IMX_SC_R_PWM_1 IMX_SC_PM_CLK_PER>;
                assigned-clock-rates = <24000000>;
-               #pwm-cells = <2>;
+               #pwm-cells = <3>;
                interrupts = <GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>;
                status = "disabled";
        };
@@ -55,7 +55,7 @@ lsio_subsys: bus@5d000000 {
                         <&pwm2_lpcg 1>;
                assigned-clocks = <&clk IMX_SC_R_PWM_2 IMX_SC_PM_CLK_PER>;
                assigned-clock-rates = <24000000>;
-               #pwm-cells = <2>;
+               #pwm-cells = <3>;
                interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>;
                status = "disabled";
        };
@@ -68,7 +68,7 @@ lsio_subsys: bus@5d000000 {
                         <&pwm3_lpcg 1>;
                assigned-clocks = <&clk IMX_SC_R_PWM_3 IMX_SC_PM_CLK_PER>;
                assigned-clock-rates = <24000000>;
-               #pwm-cells = <2>;
+               #pwm-cells = <3>;
                interrupts = <GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>;
                status = "disabled";
        };
index c9a610ba483689f8e595ff1e1bfab3b4cbc97fa4..1264da6012f9296be3fd062cdcced456a6b7e997 100644 (file)
                                phys = <&usb3_phy0>, <&usb3_phy0>;
                                phy-names = "usb2-phy", "usb3-phy";
                                snps,gfladj-refclk-lpm-sel-quirk;
+                               snps,parkmode-disable-ss-quirk;
                        };
 
                };
                                phys = <&usb3_phy1>, <&usb3_phy1>;
                                phy-names = "usb2-phy", "usb3-phy";
                                snps,gfladj-refclk-lpm-sel-quirk;
+                               snps,parkmode-disable-ss-quirk;
                        };
                };
 
index 4b1ce9fc1758474b4bff5cca6473e5f9eb4cacbc..c6dc3ba0d43b23f88af1656a28f1b3f1ccab0b98 100644 (file)
                        phys = <&usb3_phy0>, <&usb3_phy0>;
                        phy-names = "usb2-phy", "usb3-phy";
                        power-domains = <&pgc_otg1>;
+                       snps,parkmode-disable-ss-quirk;
                        status = "disabled";
                };
 
                        phys = <&usb3_phy1>, <&usb3_phy1>;
                        phy-names = "usb2-phy", "usb3-phy";
                        power-domains = <&pgc_otg2>;
+                       snps,parkmode-disable-ss-quirk;
                        status = "disabled";
                };
 
index 01539df335f8c2ff82ed88ff46b16f7684600293..8439dd6b3935344a903762f29826a30ebc3e799a 100644 (file)
        status = "okay";
 };
 
+&edma3 {
+       power-domains = <&pd IMX_SC_R_DMA_1_CH0>,
+                    <&pd IMX_SC_R_DMA_1_CH1>,
+                    <&pd IMX_SC_R_DMA_1_CH2>,
+                    <&pd IMX_SC_R_DMA_1_CH3>,
+                    <&pd IMX_SC_R_DMA_1_CH4>,
+                    <&pd IMX_SC_R_DMA_1_CH5>,
+                    <&pd IMX_SC_R_DMA_1_CH6>,
+                    <&pd IMX_SC_R_DMA_1_CH7>;
+};
+
 &flexcan1 {
        fsl,clk-source = /bits/ 8 <1>;
 };
index f22c1ac391c9b97b2f80a3a5108eb3a343ba3bfb..c4a0082f30d3164456e1a1bc8856cb6a378709e0 100644 (file)
                        };
                };
 
-               gpioe: gpio@2d000080 {
+               gpioe: gpio@2d000000 {
                                compatible = "fsl,imx8ulp-gpio";
                                reg = <0x2d000000 0x1000>;
                                gpio-controller;
                                gpio-ranges = <&iomuxc1 0 32 24>;
                };
 
-               gpiof: gpio@2d010080 {
+               gpiof: gpio@2d010000 {
                                compatible = "fsl,imx8ulp-gpio";
                                reg = <0x2d010000 0x1000>;
                                gpio-controller;
                        };
                };
 
-               gpiod: gpio@2e200080 {
+               gpiod: gpio@2e200000 {
                        compatible = "fsl,imx8ulp-gpio";
                        reg = <0x2e200000 0x1000>;
                        gpio-controller;
index f06139bdff97e383bc3729abbd7116eff48e23ce..3c5c67ebee5d306e47277439532c55b62d7a1c3c 100644 (file)
                fsl,pins = <
                        MX93_PAD_UART2_TXD__LPUART2_TX          0x31e
                        MX93_PAD_UART2_RXD__LPUART2_RX          0x31e
-                       MX93_PAD_SAI1_TXD0__LPUART2_RTS_B       0x31e
+                       MX93_PAD_SAI1_TXD0__LPUART2_RTS_B       0x51e
                >;
        };
 
index ceccf476644072156319648f406610c827ee0792..34c0540276d1668a2ba568f76bbb0984af38bade 100644 (file)
                                        compatible = "fsl,imx93-src-slice";
                                        reg = <0x44462400 0x400>, <0x44465800 0x400>;
                                        #power-domain-cells = <0>;
-                                       clocks = <&clk IMX93_CLK_MEDIA_AXI>,
+                                       clocks = <&clk IMX93_CLK_NIC_MEDIA_GATE>,
                                                 <&clk IMX93_CLK_MEDIA_APB>;
                                };
                        };
                        };
                };
 
-               gpio2: gpio@43810080 {
+               gpio2: gpio@43810000 {
                        compatible = "fsl,imx93-gpio", "fsl,imx8ulp-gpio";
                        reg = <0x43810000 0x1000>;
                        gpio-controller;
                        gpio-ranges = <&iomuxc 0 4 30>;
                };
 
-               gpio3: gpio@43820080 {
+               gpio3: gpio@43820000 {
                        compatible = "fsl,imx93-gpio", "fsl,imx8ulp-gpio";
                        reg = <0x43820000 0x1000>;
                        gpio-controller;
                                      <&iomuxc 26 34 2>, <&iomuxc 28 0 4>;
                };
 
-               gpio4: gpio@43830080 {
+               gpio4: gpio@43830000 {
                        compatible = "fsl,imx93-gpio", "fsl,imx8ulp-gpio";
                        reg = <0x43830000 0x1000>;
                        gpio-controller;
                        gpio-ranges = <&iomuxc 0 38 28>, <&iomuxc 28 36 2>;
                };
 
-               gpio1: gpio@47400080 {
+               gpio1: gpio@47400000 {
                        compatible = "fsl,imx93-gpio", "fsl,imx8ulp-gpio";
                        reg = <0x47400000 0x1000>;
                        gpio-controller;
index 3b7a176b79047d489b91f632357e6a0b57db7a25..c46682150e502abb2b62cc1d3170e81d475cf1b0 100644 (file)
@@ -73,7 +73,7 @@
                };
        };
 
-       memory {
+       memory@40000000 {
                reg = <0 0x40000000 0 0x40000000>;
        };
 
index a885a3fbe4562228b6f56da0fa9d5a55549d8979..2dc1bdc74e2124224d5810b4f255453605bd4999 100644 (file)
@@ -55,7 +55,7 @@
                };
        };
 
-       memory {
+       memory@40000000 {
                reg = <0 0x40000000 0 0x20000000>;
        };
 
index af4a4309bda4b93191601f6e38fc6044211278a9..b876e501216be8e19176d458a06183749015bc70 100644 (file)
                compatible = "sff,sfp";
                i2c-bus = <&i2c_sfp1>;
                los-gpios = <&pio 46 GPIO_ACTIVE_HIGH>;
+               maximum-power-milliwatt = <3000>;
                mod-def0-gpios = <&pio 49 GPIO_ACTIVE_LOW>;
                tx-disable-gpios = <&pio 20 GPIO_ACTIVE_HIGH>;
                tx-fault-gpios = <&pio 7 GPIO_ACTIVE_HIGH>;
                i2c-bus = <&i2c_sfp2>;
                los-gpios = <&pio 31 GPIO_ACTIVE_HIGH>;
                mod-def0-gpios = <&pio 47 GPIO_ACTIVE_LOW>;
+               maximum-power-milliwatt = <3000>;
                tx-disable-gpios = <&pio 15 GPIO_ACTIVE_HIGH>;
                tx-fault-gpios = <&pio 48 GPIO_ACTIVE_HIGH>;
        };
                        trip = <&cpu_trip_active_high>;
                };
 
-               cpu-active-low {
+               cpu-active-med {
                        /* active: set fan to cooling level 1 */
                        cooling-device = <&fan 1 1>;
-                       trip = <&cpu_trip_active_low>;
+                       trip = <&cpu_trip_active_med>;
                };
 
-               cpu-passive {
-                       /* passive: set fan to cooling level 0 */
+               cpu-active-low {
+                       /* active: set fan to cooling level 0 */
                        cooling-device = <&fan 0 0>;
-                       trip = <&cpu_trip_passive>;
+                       trip = <&cpu_trip_active_low>;
                };
        };
 };
index 24eda00e320d3a8873a702966f8b674b737425a3..fc751e049953c27ff9df7787642d0bd6016ad458 100644 (file)
                        reg = <0 0x11230000 0 0x1000>,
                              <0 0x11c20000 0 0x1000>;
                        interrupts = <GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH>;
+                       assigned-clocks = <&topckgen CLK_TOP_EMMC_416M_SEL>,
+                                         <&topckgen CLK_TOP_EMMC_250M_SEL>;
+                       assigned-clock-parents = <&apmixedsys CLK_APMIXED_MPLL>,
+                                                <&topckgen CLK_TOP_NET1PLL_D5_D2>;
                        clocks = <&topckgen CLK_TOP_EMMC_416M_SEL>,
                                 <&infracfg CLK_INFRA_MSDC_HCK_CK>,
                                 <&infracfg CLK_INFRA_MSDC_CK>,
                        thermal-sensors = <&thermal 0>;
 
                        trips {
+                               cpu_trip_crit: crit {
+                                       temperature = <125000>;
+                                       hysteresis = <2000>;
+                                       type = "critical";
+                               };
+
+                               cpu_trip_hot: hot {
+                                       temperature = <120000>;
+                                       hysteresis = <2000>;
+                                       type = "hot";
+                               };
+
                                cpu_trip_active_high: active-high {
                                        temperature = <115000>;
                                        hysteresis = <2000>;
                                        type = "active";
                                };
 
-                               cpu_trip_active_low: active-low {
+                               cpu_trip_active_med: active-med {
                                        temperature = <85000>;
                                        hysteresis = <2000>;
                                        type = "active";
                                };
 
-                               cpu_trip_passive: passive {
-                                       temperature = <40000>;
+                               cpu_trip_active_low: active-low {
+                                       temperature = <60000>;
                                        hysteresis = <2000>;
-                                       type = "passive";
+                                       type = "active";
                                };
                        };
                };
index 5122963d8743ab3fd5049032369976099e1a26d6..d258c80213b26420bb8c4590e35153f2fb4c9db0 100644 (file)
@@ -44,7 +44,7 @@
                id-gpio = <&pio 16 GPIO_ACTIVE_HIGH>;
        };
 
-       usb_p1_vbus: regulator@0 {
+       usb_p1_vbus: regulator-usb-p1 {
                compatible = "regulator-fixed";
                regulator-name = "usb_vbus";
                regulator-min-microvolt = <5000000>;
@@ -53,7 +53,7 @@
                enable-active-high;
        };
 
-       usb_p0_vbus: regulator@1 {
+       usb_p0_vbus: regulator-usb-p0 {
                compatible = "regulator-fixed";
                regulator-name = "vbus";
                regulator-min-microvolt = <5000000>;
index ce336a48c897329ca045a7e81655985f9a4795b5..77f9ab94c00bd98e791df6067f2e0e8bfdf5c7cb 100644 (file)
                #address-cells = <2>;
                #size-cells = <2>;
                ranges;
-               scp_mem_reserved: scp_mem_region {
+               scp_mem_reserved: memory@50000000 {
                        compatible = "shared-dma-pool";
                        reg = <0 0x50000000 0 0x2900000>;
                        no-map;
                };
        };
 
-       ntc@0 {
+       thermal-sensor {
                compatible = "murata,ncp03wf104";
                pullup-uv = <1800000>;
                pullup-ohm = <390000>;
index bf97b60ae4d17eaf3902db1ca31dac496aa0f5be..820260348de9b655f051b0d9fc1eb78721e73fd6 100644 (file)
@@ -91,6 +91,8 @@
 
 &dsi0 {
        status = "okay";
+       /delete-property/#size-cells;
+       /delete-property/#address-cells;
        /delete-node/panel@0;
        ports {
                port {
        };
 
        touchscreen_pins: touchscreen-pins {
-               touch_int_odl {
+               touch-int-odl {
                        pinmux = <PINMUX_GPIO155__FUNC_GPIO155>;
                        input-enable;
                        bias-pull-up;
                };
 
-               touch_rst_l {
+               touch-rst-l {
                        pinmux = <PINMUX_GPIO156__FUNC_GPIO156>;
                        output-high;
                };
        };
 
        trackpad_pins: trackpad-pins {
-               trackpad_int {
+               trackpad-int {
                        pinmux = <PINMUX_GPIO7__FUNC_GPIO7>;
                        input-enable;
                        bias-disable; /* pulled externally */
index bf7de35ffcbc8ae440c34761d0a8578b9b69bc73..7881a27be0297096c6e633825b63ed01ddfd2970 100644 (file)
                #size-cells = <2>;
                ranges;
 
-               scp_mem_reserved: scp_mem_region {
+               scp_mem_reserved: memory@50000000 {
                        compatible = "shared-dma-pool";
                        reg = <0 0x50000000 0 0x2900000>;
                        no-map;
 
 &pio {
        aud_pins_default: audiopins {
-               pins_bus {
+               pins-bus {
                        pinmux = <PINMUX_GPIO97__FUNC_I2S2_MCK>,
                                <PINMUX_GPIO98__FUNC_I2S2_BCK>,
                                <PINMUX_GPIO101__FUNC_I2S2_LRCK>,
        };
 
        aud_pins_tdm_out_on: audiotdmouton {
-               pins_bus {
+               pins-bus {
                        pinmux = <PINMUX_GPIO169__FUNC_TDM_BCK_2ND>,
                                <PINMUX_GPIO170__FUNC_TDM_LRCK_2ND>,
                                <PINMUX_GPIO171__FUNC_TDM_DATA0_2ND>,
        };
 
        aud_pins_tdm_out_off: audiotdmoutoff {
-               pins_bus {
+               pins-bus {
                        pinmux = <PINMUX_GPIO169__FUNC_GPIO169>,
                                <PINMUX_GPIO170__FUNC_GPIO170>,
                                <PINMUX_GPIO171__FUNC_GPIO171>,
        };
 
        bt_pins: bt-pins {
-               pins_bt_en {
+               pins-bt-en {
                        pinmux = <PINMUX_GPIO120__FUNC_GPIO120>;
                        output-low;
                };
        };
 
-       ec_ap_int_odl: ec_ap_int_odl {
+       ec_ap_int_odl: ec-ap-int-odl {
                pins1 {
                        pinmux = <PINMUX_GPIO151__FUNC_GPIO151>;
                        input-enable;
                };
        };
 
-       h1_int_od_l: h1_int_od_l {
+       h1_int_od_l: h1-int-od-l {
                pins1 {
                        pinmux = <PINMUX_GPIO153__FUNC_GPIO153>;
                        input-enable;
        };
 
        i2c0_pins: i2c0 {
-               pins_bus {
+               pins-bus {
                        pinmux = <PINMUX_GPIO82__FUNC_SDA0>,
                                 <PINMUX_GPIO83__FUNC_SCL0>;
                        mediatek,pull-up-adv = <3>;
        };
 
        i2c1_pins: i2c1 {
-               pins_bus {
+               pins-bus {
                        pinmux = <PINMUX_GPIO81__FUNC_SDA1>,
                                 <PINMUX_GPIO84__FUNC_SCL1>;
                        mediatek,pull-up-adv = <3>;
        };
 
        i2c2_pins: i2c2 {
-               pins_bus {
+               pins-bus {
                        pinmux = <PINMUX_GPIO103__FUNC_SCL2>,
                                 <PINMUX_GPIO104__FUNC_SDA2>;
                        bias-disable;
        };
 
        i2c3_pins: i2c3 {
-               pins_bus {
+               pins-bus {
                        pinmux = <PINMUX_GPIO50__FUNC_SCL3>,
                                 <PINMUX_GPIO51__FUNC_SDA3>;
                        mediatek,pull-up-adv = <3>;
        };
 
        i2c4_pins: i2c4 {
-               pins_bus {
+               pins-bus {
                        pinmux = <PINMUX_GPIO105__FUNC_SCL4>,
                                 <PINMUX_GPIO106__FUNC_SDA4>;
                        bias-disable;
        };
 
        i2c5_pins: i2c5 {
-               pins_bus {
+               pins-bus {
                        pinmux = <PINMUX_GPIO48__FUNC_SCL5>,
                                 <PINMUX_GPIO49__FUNC_SDA5>;
                        mediatek,pull-up-adv = <3>;
        };
 
        i2c6_pins: i2c6 {
-               pins_bus {
+               pins-bus {
                        pinmux = <PINMUX_GPIO11__FUNC_SCL6>,
                                 <PINMUX_GPIO12__FUNC_SDA6>;
                        bias-disable;
        };
 
        mmc0_pins_default: mmc0-pins-default {
-               pins_cmd_dat {
+               pins-cmd-dat {
                        pinmux = <PINMUX_GPIO123__FUNC_MSDC0_DAT0>,
                                 <PINMUX_GPIO128__FUNC_MSDC0_DAT1>,
                                 <PINMUX_GPIO125__FUNC_MSDC0_DAT2>,
                        mediatek,pull-up-adv = <01>;
                };
 
-               pins_clk {
+               pins-clk {
                        pinmux = <PINMUX_GPIO124__FUNC_MSDC0_CLK>;
                        drive-strength = <MTK_DRIVE_14mA>;
                        mediatek,pull-down-adv = <10>;
                };
 
-               pins_rst {
+               pins-rst {
                        pinmux = <PINMUX_GPIO133__FUNC_MSDC0_RSTB>;
                        drive-strength = <MTK_DRIVE_14mA>;
                        mediatek,pull-down-adv = <01>;
        };
 
        mmc0_pins_uhs: mmc0-pins-uhs {
-               pins_cmd_dat {
+               pins-cmd-dat {
                        pinmux = <PINMUX_GPIO123__FUNC_MSDC0_DAT0>,
                                 <PINMUX_GPIO128__FUNC_MSDC0_DAT1>,
                                 <PINMUX_GPIO125__FUNC_MSDC0_DAT2>,
                        mediatek,pull-up-adv = <01>;
                };
 
-               pins_clk {
+               pins-clk {
                        pinmux = <PINMUX_GPIO124__FUNC_MSDC0_CLK>;
                        drive-strength = <MTK_DRIVE_14mA>;
                        mediatek,pull-down-adv = <10>;
                };
 
-               pins_ds {
+               pins-ds {
                        pinmux = <PINMUX_GPIO131__FUNC_MSDC0_DSL>;
                        drive-strength = <MTK_DRIVE_14mA>;
                        mediatek,pull-down-adv = <10>;
                };
 
-               pins_rst {
+               pins-rst {
                        pinmux = <PINMUX_GPIO133__FUNC_MSDC0_RSTB>;
                        drive-strength = <MTK_DRIVE_14mA>;
                        mediatek,pull-up-adv = <01>;
        };
 
        mmc1_pins_default: mmc1-pins-default {
-               pins_cmd_dat {
+               pins-cmd-dat {
                        pinmux = <PINMUX_GPIO31__FUNC_MSDC1_CMD>,
                                 <PINMUX_GPIO32__FUNC_MSDC1_DAT0>,
                                 <PINMUX_GPIO34__FUNC_MSDC1_DAT1>,
                        mediatek,pull-up-adv = <10>;
                };
 
-               pins_clk {
+               pins-clk {
                        pinmux = <PINMUX_GPIO29__FUNC_MSDC1_CLK>;
                        input-enable;
                        mediatek,pull-down-adv = <10>;
        };
 
        mmc1_pins_uhs: mmc1-pins-uhs {
-               pins_cmd_dat {
+               pins-cmd-dat {
                        pinmux = <PINMUX_GPIO31__FUNC_MSDC1_CMD>,
                                 <PINMUX_GPIO32__FUNC_MSDC1_DAT0>,
                                 <PINMUX_GPIO34__FUNC_MSDC1_DAT1>,
                        mediatek,pull-up-adv = <10>;
                };
 
-               pins_clk {
+               pins-clk {
                        pinmux = <PINMUX_GPIO29__FUNC_MSDC1_CLK>;
                        drive-strength = <MTK_DRIVE_8mA>;
                        mediatek,pull-down-adv = <10>;
                };
        };
 
-       panel_pins_default: panel_pins_default {
-               panel_reset {
+       panel_pins_default: panel-pins-default {
+               panel-reset {
                        pinmux = <PINMUX_GPIO45__FUNC_GPIO45>;
                        output-low;
                        bias-pull-up;
                };
        };
 
-       pwm0_pin_default: pwm0_pin_default {
+       pwm0_pin_default: pwm0-pin-default {
                pins1 {
                        pinmux = <PINMUX_GPIO176__FUNC_GPIO176>;
                        output-high;
        };
 
        scp_pins: scp {
-               pins_scp_uart {
+               pins-scp-uart {
                        pinmux = <PINMUX_GPIO110__FUNC_TP_URXD1_AO>,
                                 <PINMUX_GPIO112__FUNC_TP_UTXD1_AO>;
                };
        };
 
        spi0_pins: spi0 {
-               pins_spi {
+               pins-spi {
                        pinmux = <PINMUX_GPIO85__FUNC_SPI0_MI>,
                                 <PINMUX_GPIO86__FUNC_GPIO86>,
                                 <PINMUX_GPIO87__FUNC_SPI0_MO>,
        };
 
        spi1_pins: spi1 {
-               pins_spi {
+               pins-spi {
                        pinmux = <PINMUX_GPIO161__FUNC_SPI1_A_MI>,
                                 <PINMUX_GPIO162__FUNC_SPI1_A_CSB>,
                                 <PINMUX_GPIO163__FUNC_SPI1_A_MO>,
        };
 
        spi2_pins: spi2 {
-               pins_spi {
+               pins-spi {
                        pinmux = <PINMUX_GPIO0__FUNC_SPI2_CSB>,
                                 <PINMUX_GPIO1__FUNC_SPI2_MO>,
                                 <PINMUX_GPIO2__FUNC_SPI2_CLK>;
                        bias-disable;
                };
-               pins_spi_mi {
+               pins-spi-mi {
                        pinmux = <PINMUX_GPIO94__FUNC_SPI2_MI>;
                        mediatek,pull-down-adv = <00>;
                };
        };
 
        spi3_pins: spi3 {
-               pins_spi {
+               pins-spi {
                        pinmux = <PINMUX_GPIO21__FUNC_SPI3_MI>,
                                 <PINMUX_GPIO22__FUNC_SPI3_CSB>,
                                 <PINMUX_GPIO23__FUNC_SPI3_MO>,
        };
 
        spi4_pins: spi4 {
-               pins_spi {
+               pins-spi {
                        pinmux = <PINMUX_GPIO17__FUNC_SPI4_MI>,
                                 <PINMUX_GPIO18__FUNC_SPI4_CSB>,
                                 <PINMUX_GPIO19__FUNC_SPI4_MO>,
        };
 
        spi5_pins: spi5 {
-               pins_spi {
+               pins-spi {
                        pinmux = <PINMUX_GPIO13__FUNC_SPI5_MI>,
                                 <PINMUX_GPIO14__FUNC_SPI5_CSB>,
                                 <PINMUX_GPIO15__FUNC_SPI5_MO>,
        };
 
        uart0_pins_default: uart0-pins-default {
-               pins_rx {
+               pins-rx {
                        pinmux = <PINMUX_GPIO95__FUNC_URXD0>;
                        input-enable;
                        bias-pull-up;
                };
-               pins_tx {
+               pins-tx {
                        pinmux = <PINMUX_GPIO96__FUNC_UTXD0>;
                };
        };
 
        uart1_pins_default: uart1-pins-default {
-               pins_rx {
+               pins-rx {
                        pinmux = <PINMUX_GPIO121__FUNC_URXD1>;
                        input-enable;
                        bias-pull-up;
                };
-               pins_tx {
+               pins-tx {
                        pinmux = <PINMUX_GPIO115__FUNC_UTXD1>;
                };
-               pins_rts {
+               pins-rts {
                        pinmux = <PINMUX_GPIO47__FUNC_URTS1>;
                        output-enable;
                };
-               pins_cts {
+               pins-cts {
                        pinmux = <PINMUX_GPIO46__FUNC_UCTS1>;
                        input-enable;
                };
        };
 
        uart1_pins_sleep: uart1-pins-sleep {
-               pins_rx {
+               pins-rx {
                        pinmux = <PINMUX_GPIO121__FUNC_GPIO121>;
                        input-enable;
                        bias-pull-up;
                };
-               pins_tx {
+               pins-tx {
                        pinmux = <PINMUX_GPIO115__FUNC_UTXD1>;
                };
-               pins_rts {
+               pins-rts {
                        pinmux = <PINMUX_GPIO47__FUNC_URTS1>;
                        output-enable;
                };
-               pins_cts {
+               pins-cts {
                        pinmux = <PINMUX_GPIO46__FUNC_UCTS1>;
                        input-enable;
                };
        };
 
        wifi_pins_pwrseq: wifi-pins-pwrseq {
-               pins_wifi_enable {
+               pins-wifi-enable {
                        pinmux = <PINMUX_GPIO119__FUNC_GPIO119>;
                        output-low;
                };
        };
 
        wifi_pins_wakeup: wifi-pins-wakeup {
-               pins_wifi_wakeup {
+               pins-wifi-wakeup {
                        pinmux = <PINMUX_GPIO113__FUNC_GPIO113>;
                        input-enable;
                };
index 5169779d01dfb418e9f6306d4533c57ed6bcfcfe..976dc968b3ca14de97798bd5e823dbf552ca8300 100644 (file)
                        nvmem-cell-names = "calibration-data";
                };
 
-               thermal_zones: thermal-zones {
-                       cpu_thermal: cpu-thermal {
-                               polling-delay-passive = <100>;
-                               polling-delay = <500>;
-                               thermal-sensors = <&thermal 0>;
-                               sustainable-power = <5000>;
-
-                               trips {
-                                       threshold: trip-point0 {
-                                               temperature = <68000>;
-                                               hysteresis = <2000>;
-                                               type = "passive";
-                                       };
-
-                                       target: trip-point1 {
-                                               temperature = <80000>;
-                                               hysteresis = <2000>;
-                                               type = "passive";
-                                       };
-
-                                       cpu_crit: cpu-crit {
-                                               temperature = <115000>;
-                                               hysteresis = <2000>;
-                                               type = "critical";
-                                       };
-                               };
-
-                               cooling-maps {
-                                       map0 {
-                                               trip = <&target>;
-                                               cooling-device = <&cpu0
-                                                       THERMAL_NO_LIMIT
-                                                       THERMAL_NO_LIMIT>,
-                                                                <&cpu1
-                                                       THERMAL_NO_LIMIT
-                                                       THERMAL_NO_LIMIT>,
-                                                                <&cpu2
-                                                       THERMAL_NO_LIMIT
-                                                       THERMAL_NO_LIMIT>,
-                                                                <&cpu3
-                                                       THERMAL_NO_LIMIT
-                                                       THERMAL_NO_LIMIT>;
-                                               contribution = <3072>;
-                                       };
-                                       map1 {
-                                               trip = <&target>;
-                                               cooling-device = <&cpu4
-                                                       THERMAL_NO_LIMIT
-                                                       THERMAL_NO_LIMIT>,
-                                                                <&cpu5
-                                                       THERMAL_NO_LIMIT
-                                                       THERMAL_NO_LIMIT>,
-                                                                <&cpu6
-                                                       THERMAL_NO_LIMIT
-                                                       THERMAL_NO_LIMIT>,
-                                                                <&cpu7
-                                                       THERMAL_NO_LIMIT
-                                                       THERMAL_NO_LIMIT>;
-                                               contribution = <1024>;
-                                       };
-                               };
-                       };
-
-                       /* The tzts1 ~ tzts6 don't need to polling */
-                       /* The tzts1 ~ tzts6 don't need to thermal throttle */
-
-                       tzts1: tzts1 {
-                               polling-delay-passive = <0>;
-                               polling-delay = <0>;
-                               thermal-sensors = <&thermal 1>;
-                               sustainable-power = <5000>;
-                               trips {};
-                               cooling-maps {};
-                       };
-
-                       tzts2: tzts2 {
-                               polling-delay-passive = <0>;
-                               polling-delay = <0>;
-                               thermal-sensors = <&thermal 2>;
-                               sustainable-power = <5000>;
-                               trips {};
-                               cooling-maps {};
-                       };
-
-                       tzts3: tzts3 {
-                               polling-delay-passive = <0>;
-                               polling-delay = <0>;
-                               thermal-sensors = <&thermal 3>;
-                               sustainable-power = <5000>;
-                               trips {};
-                               cooling-maps {};
-                       };
-
-                       tzts4: tzts4 {
-                               polling-delay-passive = <0>;
-                               polling-delay = <0>;
-                               thermal-sensors = <&thermal 4>;
-                               sustainable-power = <5000>;
-                               trips {};
-                               cooling-maps {};
-                       };
-
-                       tzts5: tzts5 {
-                               polling-delay-passive = <0>;
-                               polling-delay = <0>;
-                               thermal-sensors = <&thermal 5>;
-                               sustainable-power = <5000>;
-                               trips {};
-                               cooling-maps {};
-                       };
-
-                       tztsABB: tztsABB {
-                               polling-delay-passive = <0>;
-                               polling-delay = <0>;
-                               thermal-sensors = <&thermal 6>;
-                               sustainable-power = <5000>;
-                               trips {};
-                               cooling-maps {};
-                       };
-               };
-
                pwm0: pwm@1100e000 {
                        compatible = "mediatek,mt8183-disp-pwm";
                        reg = <0 0x1100e000 0 0x1000>;
                        power-domains = <&spm MT8183_POWER_DOMAIN_CAM>;
                };
        };
+
+       thermal_zones: thermal-zones {
+               cpu_thermal: cpu-thermal {
+                       polling-delay-passive = <100>;
+                       polling-delay = <500>;
+                       thermal-sensors = <&thermal 0>;
+                       sustainable-power = <5000>;
+
+                       trips {
+                               threshold: trip-point0 {
+                                       temperature = <68000>;
+                                       hysteresis = <2000>;
+                                       type = "passive";
+                               };
+
+                               target: trip-point1 {
+                                       temperature = <80000>;
+                                       hysteresis = <2000>;
+                                       type = "passive";
+                               };
+
+                               cpu_crit: cpu-crit {
+                                       temperature = <115000>;
+                                       hysteresis = <2000>;
+                                       type = "critical";
+                               };
+                       };
+
+                       cooling-maps {
+                               map0 {
+                                       trip = <&target>;
+                                       cooling-device = <&cpu0
+                                               THERMAL_NO_LIMIT
+                                               THERMAL_NO_LIMIT>,
+                                                        <&cpu1
+                                               THERMAL_NO_LIMIT
+                                               THERMAL_NO_LIMIT>,
+                                                        <&cpu2
+                                               THERMAL_NO_LIMIT
+                                               THERMAL_NO_LIMIT>,
+                                                        <&cpu3
+                                               THERMAL_NO_LIMIT
+                                               THERMAL_NO_LIMIT>;
+                                       contribution = <3072>;
+                               };
+                               map1 {
+                                       trip = <&target>;
+                                       cooling-device = <&cpu4
+                                               THERMAL_NO_LIMIT
+                                               THERMAL_NO_LIMIT>,
+                                                        <&cpu5
+                                               THERMAL_NO_LIMIT
+                                               THERMAL_NO_LIMIT>,
+                                                        <&cpu6
+                                               THERMAL_NO_LIMIT
+                                               THERMAL_NO_LIMIT>,
+                                                        <&cpu7
+                                               THERMAL_NO_LIMIT
+                                               THERMAL_NO_LIMIT>;
+                                       contribution = <1024>;
+                               };
+                       };
+               };
+
+               /* The tzts1 ~ tzts6 don't need to polling */
+               /* The tzts1 ~ tzts6 don't need to thermal throttle */
+
+               tzts1: tzts1 {
+                       polling-delay-passive = <0>;
+                       polling-delay = <0>;
+                       thermal-sensors = <&thermal 1>;
+                       sustainable-power = <5000>;
+                       trips {};
+                       cooling-maps {};
+               };
+
+               tzts2: tzts2 {
+                       polling-delay-passive = <0>;
+                       polling-delay = <0>;
+                       thermal-sensors = <&thermal 2>;
+                       sustainable-power = <5000>;
+                       trips {};
+                       cooling-maps {};
+               };
+
+               tzts3: tzts3 {
+                       polling-delay-passive = <0>;
+                       polling-delay = <0>;
+                       thermal-sensors = <&thermal 3>;
+                       sustainable-power = <5000>;
+                       trips {};
+                       cooling-maps {};
+               };
+
+               tzts4: tzts4 {
+                       polling-delay-passive = <0>;
+                       polling-delay = <0>;
+                       thermal-sensors = <&thermal 4>;
+                       sustainable-power = <5000>;
+                       trips {};
+                       cooling-maps {};
+               };
+
+               tzts5: tzts5 {
+                       polling-delay-passive = <0>;
+                       polling-delay = <0>;
+                       thermal-sensors = <&thermal 5>;
+                       sustainable-power = <5000>;
+                       trips {};
+                       cooling-maps {};
+               };
+
+               tztsABB: tztsABB {
+                       polling-delay-passive = <0>;
+                       polling-delay = <0>;
+                       thermal-sensors = <&thermal 6>;
+                       sustainable-power = <5000>;
+                       trips {};
+                       cooling-maps {};
+               };
+       };
 };
index f04ae70c470aa3f409579187c12ac9eac77b4cd9..df0c04f2ba1da9c934e08c76bf5146ff20d694e0 100644 (file)
                                        reg = <MT8186_POWER_DOMAIN_CSIRX_TOP>;
                                        clocks = <&topckgen CLK_TOP_SENINF>,
                                                 <&topckgen CLK_TOP_SENINF1>;
-                                       clock-names = "csirx_top0", "csirx_top1";
+                                       clock-names = "subsys-csirx-top0",
+                                                     "subsys-csirx-top1";
                                        #power-domain-cells = <0>;
                                };
 
                                        reg = <MT8186_POWER_DOMAIN_ADSP_AO>;
                                        clocks = <&topckgen CLK_TOP_AUDIODSP>,
                                                 <&topckgen CLK_TOP_ADSP_BUS>;
-                                       clock-names = "audioadsp", "adsp_bus";
+                                       clock-names = "audioadsp",
+                                                     "subsys-adsp-bus";
                                        #address-cells = <1>;
                                        #size-cells = <0>;
                                        #power-domain-cells = <1>;
                                                 <&mmsys CLK_MM_SMI_COMMON>,
                                                 <&mmsys CLK_MM_SMI_GALS>,
                                                 <&mmsys CLK_MM_SMI_IOMMU>;
-                                       clock-names = "disp", "mdp", "smi_infra", "smi_common",
-                                                    "smi_gals", "smi_iommu";
+                                       clock-names = "disp", "mdp",
+                                                     "subsys-smi-infra",
+                                                     "subsys-smi-common",
+                                                     "subsys-smi-gals",
+                                                     "subsys-smi-iommu";
                                        mediatek,infracfg = <&infracfg_ao>;
                                        #address-cells = <1>;
                                        #size-cells = <0>;
 
                                        power-domain@MT8186_POWER_DOMAIN_CAM {
                                                reg = <MT8186_POWER_DOMAIN_CAM>;
-                                               clocks = <&topckgen CLK_TOP_CAM>,
-                                                        <&topckgen CLK_TOP_SENINF>,
+                                               clocks = <&topckgen CLK_TOP_SENINF>,
                                                         <&topckgen CLK_TOP_SENINF1>,
                                                         <&topckgen CLK_TOP_SENINF2>,
                                                         <&topckgen CLK_TOP_SENINF3>,
+                                                        <&camsys CLK_CAM2MM_GALS>,
                                                         <&topckgen CLK_TOP_CAMTM>,
-                                                        <&camsys CLK_CAM2MM_GALS>;
-                                               clock-names = "cam-top", "cam0", "cam1", "cam2",
-                                                            "cam3", "cam-tm", "gals";
+                                                        <&topckgen CLK_TOP_CAM>;
+                                               clock-names = "cam0", "cam1", "cam2",
+                                                             "cam3", "gals",
+                                                             "subsys-cam-tm",
+                                                             "subsys-cam-top";
                                                mediatek,infracfg = <&infracfg_ao>;
                                                #address-cells = <1>;
                                                #size-cells = <0>;
 
                                        power-domain@MT8186_POWER_DOMAIN_IMG {
                                                reg = <MT8186_POWER_DOMAIN_IMG>;
-                                               clocks = <&topckgen CLK_TOP_IMG1>,
-                                                        <&imgsys1 CLK_IMG1_GALS_IMG1>;
-                                               clock-names = "img-top", "gals";
+                                               clocks = <&imgsys1 CLK_IMG1_GALS_IMG1>,
+                                                        <&topckgen CLK_TOP_IMG1>;
+                                               clock-names = "gals", "subsys-img-top";
                                                mediatek,infracfg = <&infracfg_ao>;
                                                #address-cells = <1>;
                                                #size-cells = <0>;
                                                         <&ipesys CLK_IPE_LARB20>,
                                                         <&ipesys CLK_IPE_SMI_SUBCOM>,
                                                         <&ipesys CLK_IPE_GALS_IPE>;
-                                               clock-names = "ipe-top", "ipe-larb0", "ipe-larb1",
-                                                             "ipe-smi", "ipe-gals";
+                                               clock-names = "subsys-ipe-top",
+                                                             "subsys-ipe-larb0",
+                                                             "subsys-ipe-larb1",
+                                                             "subsys-ipe-smi",
+                                                             "subsys-ipe-gals";
                                                mediatek,infracfg = <&infracfg_ao>;
                                                #power-domain-cells = <0>;
                                        };
                                                clocks = <&topckgen CLK_TOP_WPE>,
                                                         <&wpesys CLK_WPE_SMI_LARB8_CK_EN>,
                                                         <&wpesys CLK_WPE_SMI_LARB8_PCLK_EN>;
-                                               clock-names = "wpe0", "larb-ck", "larb-pclk";
+                                               clock-names = "wpe0",
+                                                             "subsys-larb-ck",
+                                                             "subsys-larb-pclk";
                                                mediatek,infracfg = <&infracfg_ao>;
                                                #power-domain-cells = <0>;
                                        };
                        #address-cells = <1>;
                        #size-cells = <1>;
 
-                       gpu_speedbin: gpu-speed-bin@59c {
+                       gpu_speedbin: gpu-speedbin@59c {
                                reg = <0x59c 0x4>;
                                bits = <0 3>;
                        };
index dd5b89b73190392cedeb7ecb7822fa9613c18b1d..5a7cab489ff3ace4d45807378c6bc9973af994cf 100644 (file)
        pinctrl-0 = <&i2c7_pins>;
 
        pmic@34 {
-               #interrupt-cells = <1>;
+               #interrupt-cells = <2>;
                compatible = "mediatek,mt6360";
                reg = <0x34>;
                interrupt-controller;
index 54c674c45b49a27c223b4240db452284f01f5f15..e0ac2e9f5b7204a646514f1793b880b7adeb36fe 100644 (file)
 
                                        power-domain@MT8195_POWER_DOMAIN_VENC_CORE1 {
                                                reg = <MT8195_POWER_DOMAIN_VENC_CORE1>;
+                                               clocks = <&vencsys_core1 CLK_VENC_CORE1_LARB>;
+                                               clock-names = "venc1-larb";
                                                mediatek,infracfg = <&infracfg_ao>;
                                                #power-domain-cells = <0>;
                                        };
 
                                                power-domain@MT8195_POWER_DOMAIN_VENC {
                                                        reg = <MT8195_POWER_DOMAIN_VENC>;
+                                                       clocks = <&vencsys CLK_VENC_LARB>;
+                                                       clock-names = "venc0-larb";
                                                        mediatek,infracfg = <&infracfg_ao>;
                                                        #power-domain-cells = <0>;
                                                };
                        reg = <0 0x1b010000 0 0x1000>;
                        mediatek,larb-id = <20>;
                        mediatek,smi = <&smi_common_vpp>;
-                       clocks = <&vencsys_core1 CLK_VENC_CORE1_LARB>,
+                       clocks = <&vencsys_core1 CLK_VENC_CORE1_VENC>,
                                 <&vencsys_core1 CLK_VENC_CORE1_GALS>,
                                 <&vppsys0 CLK_VPP0_GALS_VDO0_VDO1_VENCSYS_CORE1>;
                        clock-names = "apb", "smi", "gals";
index de0a1f2af983bee33e127f87e2cdba16b544e54c..7d4c5324c61bced0e082a366fbf8d27ea213bf14 100644 (file)
@@ -86,7 +86,7 @@
        sgtl5000_clk: sgtl5000-oscillator {
                compatible = "fixed-clock";
                #clock-cells = <0>;
-               clock-frequency  = <24576000>;
+               clock-frequency = <24576000>;
        };
 
        dc_12v: dc-12v-regulator {
index e729e7a22b23a6a2e93374665d6f1ce2d03e9596..cc8209795c3e53b7be5ce1e5a2f7262469767b71 100644 (file)
 
        vdec: video-codec@ff360000 {
                compatible = "rockchip,rk3328-vdec", "rockchip,rk3399-vdec";
-               reg = <0x0 0xff360000 0x0 0x400>;
+               reg = <0x0 0xff360000 0x0 0x480>;
                interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
                clocks = <&cru ACLK_RKVDEC>, <&cru HCLK_RKVDEC>,
                         <&cru SCLK_VDEC_CABAC>, <&cru SCLK_VDEC_CORE>;
index 5c1929d41cc0b700998f7aa048cc815306b0f97c..cacbad35cfc854ce6823fe9901165f42cfbd2aef 100644 (file)
@@ -509,8 +509,7 @@ ap_i2c_tp: &i2c5 {
 &pci_rootport {
        mvl_wifi: wifi@0,0 {
                compatible = "pci1b4b,2b42";
-               reg = <0x83010000 0x0 0x00000000 0x0 0x00100000
-                      0x83010000 0x0 0x00100000 0x0 0x00100000>;
+               reg = <0x0000 0x0 0x0 0x0 0x0>;
                interrupt-parent = <&gpio0>;
                interrupts = <8 IRQ_TYPE_LEVEL_LOW>;
                pinctrl-names = "default";
index 853e88455e750ec1738c10cb42d75e0f2eed3985..9e4b12ed62cbed9f1bc8e1970c4d3b57d253ac32 100644 (file)
@@ -34,8 +34,8 @@
 &pci_rootport {
        wifi@0,0 {
                compatible = "qcom,ath10k";
-               reg = <0x00010000 0x0 0x00000000 0x0 0x00000000>,
-                     <0x03010010 0x0 0x00000000 0x0 0x00200000>;
+               reg = <0x00000000 0x0 0x00000000 0x0 0x00000000>,
+                     <0x03000010 0x0 0x00000000 0x0 0x00200000>;
                qcom,ath10k-calibration-variant = "GO_DUMO";
        };
 };
index c9bf1d5c3a426418f97e34c0043c8013de690e0f..789fd0dcc88baadb05367b16d80b6c7019941160 100644 (file)
@@ -489,6 +489,7 @@ ap_i2c_audio: &i2c8 {
                #address-cells = <3>;
                #size-cells = <2>;
                ranges;
+               device_type = "pci";
        };
 };
 
index faf02e59d6c73ccc573dd52f357953bc17d68742..da0dfb237f853f9403f2acfa007e82c0418375b8 100644 (file)
                        power-domain@RK3399_PD_VDU {
                                reg = <RK3399_PD_VDU>;
                                clocks = <&cru ACLK_VDU>,
-                                        <&cru HCLK_VDU>;
+                                        <&cru HCLK_VDU>,
+                                        <&cru SCLK_VDU_CA>,
+                                        <&cru SCLK_VDU_CORE>;
                                pm_qos = <&qos_video_m1_r>,
                                         <&qos_video_m1_w>;
                                #power-domain-cells = <0>;
 
        vdec: video-codec@ff660000 {
                compatible = "rockchip,rk3399-vdec";
-               reg = <0x0 0xff660000 0x0 0x400>;
+               reg = <0x0 0xff660000 0x0 0x480>;
                interrupts = <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH 0>;
                clocks = <&cru ACLK_VDU>, <&cru HCLK_VDU>,
                         <&cru SCLK_VDU_CA>, <&cru SCLK_VDU_CORE>;
index 0964761e3ce9eb6a650fe3f038bfd169b4c1c94e..c19c0f1b3778fe79f68d3657cb2b6512f70913f2 100644 (file)
                             <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>,
                             <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>,
                             <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>;
-               interrupt-names = "sys", "pmc", "msi", "legacy", "err";
+               interrupt-names = "sys", "pmc", "msg", "legacy", "err";
                bus-range = <0x0 0xf>;
                clocks = <&cru ACLK_PCIE20_MST>, <&cru ACLK_PCIE20_SLV>,
                         <&cru ACLK_PCIE20_DBI>, <&cru PCLK_PCIE20>,
index 9570b34aca2e9308b63fb49bd44af8415454b515..d88c0e852356518a95f9dd9d8bb1c5bccd999384 100644 (file)
 &pinctrl {
        fan {
                fan_int: fan-int {
-                       rockchip,pins = <0 RK_PA4 RK_FUNC_GPIO &pcfg_pull_none>;
+                       rockchip,pins = <0 RK_PA4 RK_FUNC_GPIO &pcfg_pull_up>;
                };
        };
 
        hym8563 {
                hym8563_int: hym8563-int {
-                       rockchip,pins = <0 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>;
+                       rockchip,pins = <0 RK_PB0 RK_FUNC_GPIO &pcfg_pull_up>;
                };
        };
 
index 8f399c4317bdadb54540b2099d1e869fa94d979d..e3a839a12dc6f07bb4247fc30bb2af18b15d4ac2 100644 (file)
@@ -38,7 +38,7 @@
        leds {
                compatible = "gpio-leds";
                pinctrl-names = "default";
-               pinctrl-0 =<&leds_gpio>;
+               pinctrl-0 = <&leds_gpio>;
 
                led-1 {
                        gpios = <&gpio1 RK_PA2 GPIO_ACTIVE_HIGH>;
index 63151d9d237755f4c471e96e18dd90e09675de47..30db12c4fc82b54ca90eefafa4720bda57e0f9e4 100644 (file)
                emmc_data_strobe: emmc-data-strobe {
                        rockchip,pins =
                                /* emmc_data_strobe */
-                               <2 RK_PA2 1 &pcfg_pull_none>;
+                               <2 RK_PA2 1 &pcfg_pull_down>;
                };
        };
 
index 7064c0e9179f1d868c5ebf28645f1f83a205098e..8aa0499f9b032d3a2da92d416421e56df15e9f06 100644 (file)
                             <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH 0>,
                             <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH 0>,
                             <GIC_SPI 58 IRQ_TYPE_LEVEL_HIGH 0>;
-               interrupt-names = "ch0", "ch1", "ch2", "ch3";
                rockchip,pmu = <&pmu1grf>;
        };
 
index 1641ff9a8b83e0bab486f45d398a026d2bc83acb..833555f74ffa7241a44af41f58b32164ba381169 100644 (file)
@@ -71,7 +71,7 @@
                asm volatile("\n"                                       \
                             "1:\t" PARISC_BUG_BREAK_ASM "\n"           \
                             "\t.pushsection __bug_table,\"a\"\n"       \
-                            "\t.align %2\n"                            \
+                            "\t.align 4\n"                             \
                             "2:\t" __BUG_REL(1b) "\n"                  \
                             "\t.short %0\n"                            \
                             "\t.blockz %1-4-2\n"                       \
index 90b261114763753565001398edcb4c86e3631ab1..dce96f27cc89a4af44c61209be59a105c49d05ca 100644 (file)
@@ -8,9 +8,6 @@
 #include <dt-bindings/gpio/gpio.h>
 #include <dt-bindings/leds/common.h>
 
-/* Clock frequency (in Hz) of the rtcclk */
-#define RTCCLK_FREQ            1000000
-
 / {
        model = "Microchip PolarFire-SoC Icicle Kit";
        compatible = "microchip,mpfs-icicle-reference-rtlv2210", "microchip,mpfs-icicle-kit",
                stdout-path = "serial1:115200n8";
        };
 
-       cpus {
-               timebase-frequency = <RTCCLK_FREQ>;
-       };
-
        leds {
                compatible = "gpio-leds";
 
index 184cb36a175e40742763510b8b1e7eca6d9c784a..a8d623ee9fa4cedacb177fbe7ebf94a5eb3df3d3 100644 (file)
@@ -10,9 +10,6 @@
 #include "mpfs.dtsi"
 #include "mpfs-m100pfs-fabric.dtsi"
 
-/* Clock frequency (in Hz) of the rtcclk */
-#define MTIMER_FREQ    1000000
-
 / {
        model = "Aries Embedded M100PFEVPS";
        compatible = "aries,m100pfsevp", "microchip,mpfs";
                stdout-path = "serial1:115200n8";
        };
 
-       cpus {
-               timebase-frequency = <MTIMER_FREQ>;
-       };
-
        ddrc_cache_lo: memory@80000000 {
                device_type = "memory";
                reg = <0x0 0x80000000 0x0 0x40000000>;
index c87cc2d8fe29fa2174bbedca08c272c7331283b8..ea0808ab104255ea6cfcff1a1bc99adbbdc81905 100644 (file)
@@ -6,9 +6,6 @@
 #include "mpfs.dtsi"
 #include "mpfs-polarberry-fabric.dtsi"
 
-/* Clock frequency (in Hz) of the rtcclk */
-#define MTIMER_FREQ    1000000
-
 / {
        model = "Sundance PolarBerry";
        compatible = "sundance,polarberry", "microchip,mpfs";
                stdout-path = "serial0:115200n8";
        };
 
-       cpus {
-               timebase-frequency = <MTIMER_FREQ>;
-       };
-
        ddrc_cache_lo: memory@80000000 {
                device_type = "memory";
                reg = <0x0 0x80000000 0x0 0x2e000000>;
index 013cb666c72da8e539a4bfbc8c5ddeb560272160..f9a89057943834766cb60b14a70a855df416566f 100644 (file)
@@ -6,9 +6,6 @@
 #include "mpfs.dtsi"
 #include "mpfs-sev-kit-fabric.dtsi"
 
-/* Clock frequency (in Hz) of the rtcclk */
-#define MTIMER_FREQ            1000000
-
 / {
        #address-cells = <2>;
        #size-cells = <2>;
                stdout-path = "serial1:115200n8";
        };
 
-       cpus {
-               timebase-frequency = <MTIMER_FREQ>;
-       };
-
        reserved-memory {
                #address-cells = <2>;
                #size-cells = <2>;
index e0797c7e1b3553a9f5623f730bb974c2101c6812..d1120f5f2c0153bbc9b967dd360159b6c6ee50e1 100644 (file)
@@ -11,9 +11,6 @@
 #include "mpfs.dtsi"
 #include "mpfs-tysom-m-fabric.dtsi"
 
-/* Clock frequency (in Hz) of the rtcclk */
-#define MTIMER_FREQ            1000000
-
 / {
        model = "Aldec TySOM-M-MPFS250T-REV2";
        compatible = "aldec,tysom-m-mpfs250t-rev2", "microchip,mpfs";
                stdout-path = "serial1:115200n8";
        };
 
-       cpus {
-               timebase-frequency = <MTIMER_FREQ>;
-       };
-
        ddrc_cache_lo: memory@80000000 {
                device_type = "memory";
                reg = <0x0 0x80000000 0x0 0x30000000>;
index a6faf24f1dbaf659eb9f0df6baadc34fa3246f52..266489d43912fc4457cb2bad3cc8d9d67b8d4dcd 100644 (file)
@@ -13,6 +13,7 @@
        cpus {
                #address-cells = <1>;
                #size-cells = <0>;
+               timebase-frequency = <1000000>;
 
                cpu0: cpu@0 {
                        compatible = "sifive,e51", "sifive,rocket0", "riscv";
index df40e87ee063292417622cd89c71a117ce38cb7c..aec6401a467b02a17d2bd25a369222bca815d83b 100644 (file)
@@ -34,7 +34,6 @@
                        cpu0_intc: interrupt-controller {
                                compatible = "riscv,cpu-intc";
                                interrupt-controller;
-                               #address-cells = <0>;
                                #interrupt-cells = <1>;
                        };
                };
index 197db68cc8daf711ad05a1469697ef50dcd9acd7..17a90486972468fce5e85c9287f091da14a77e66 100644 (file)
@@ -38,29 +38,35 @@ static long ax45mp_iocp_sw_workaround(void)
        return ret.error ? 0 : ret.value;
 }
 
-static bool errata_probe_iocp(unsigned int stage, unsigned long arch_id, unsigned long impid)
+static void errata_probe_iocp(unsigned int stage, unsigned long arch_id, unsigned long impid)
 {
+       static bool done;
+
        if (!IS_ENABLED(CONFIG_ERRATA_ANDES_CMO))
-               return false;
+               return;
+
+       if (done)
+               return;
+
+       done = true;
 
        if (arch_id != ANDESTECH_AX45MP_MARCHID || impid != ANDESTECH_AX45MP_MIMPID)
-               return false;
+               return;
 
        if (!ax45mp_iocp_sw_workaround())
-               return false;
+               return;
 
        /* Set this just to make core cbo code happy */
        riscv_cbom_block_size = 1;
        riscv_noncoherent_supported();
-
-       return true;
 }
 
 void __init_or_module andes_errata_patch_func(struct alt_entry *begin, struct alt_entry *end,
                                              unsigned long archid, unsigned long impid,
                                              unsigned int stage)
 {
-       errata_probe_iocp(stage, archid, impid);
+       if (stage == RISCV_ALTERNATIVES_BOOT)
+               errata_probe_iocp(stage, archid, impid);
 
        /* we have nothing to patch here ATM so just return back */
 }
index b77397432403d9ef028fea6855cdc97aea143d00..76ace1e0b46f623a119cc07a08ad8923079e1c81 100644 (file)
@@ -154,7 +154,6 @@ secondary_start_sbi:
        XIP_FIXUP_OFFSET a3
        add a3, a3, a1
        REG_L sp, (a3)
-       scs_load_current
 
 .Lsecondary_start_common:
 
@@ -165,6 +164,7 @@ secondary_start_sbi:
        call relocate_enable_mmu
 #endif
        call .Lsetup_trap_vector
+       scs_load_current
        tail smp_callin
 #endif /* CONFIG_SMP */
 
index 56a8c78e9e215eab146fac7ae9b645723f75a063..aac019ed63b1bdaa766262a5266deb4c8c5a4bdf 100644 (file)
@@ -40,15 +40,6 @@ struct relocation_handlers {
                                  long buffer);
 };
 
-unsigned int initialize_relocation_hashtable(unsigned int num_relocations);
-void process_accumulated_relocations(struct module *me);
-int add_relocation_to_accumulate(struct module *me, int type, void *location,
-                                unsigned int hashtable_bits, Elf_Addr v);
-
-struct hlist_head *relocation_hashtable;
-
-struct list_head used_buckets_list;
-
 /*
  * The auipc+jalr instruction pair can reach any PC-relative offset
  * in the range [-2^31 - 2^11, 2^31 - 2^11)
@@ -64,7 +55,7 @@ static bool riscv_insn_valid_32bit_offset(ptrdiff_t val)
 
 static int riscv_insn_rmw(void *location, u32 keep, u32 set)
 {
-       u16 *parcel = location;
+       __le16 *parcel = location;
        u32 insn = (u32)le16_to_cpu(parcel[0]) | (u32)le16_to_cpu(parcel[1]) << 16;
 
        insn &= keep;
@@ -77,7 +68,7 @@ static int riscv_insn_rmw(void *location, u32 keep, u32 set)
 
 static int riscv_insn_rvc_rmw(void *location, u16 keep, u16 set)
 {
-       u16 *parcel = location;
+       __le16 *parcel = location;
        u16 insn = le16_to_cpu(*parcel);
 
        insn &= keep;
@@ -604,7 +595,10 @@ static const struct relocation_handlers reloc_handlers[] = {
        /* 192-255 nonstandard ABI extensions  */
 };
 
-void process_accumulated_relocations(struct module *me)
+static void
+process_accumulated_relocations(struct module *me,
+                               struct hlist_head **relocation_hashtable,
+                               struct list_head *used_buckets_list)
 {
        /*
         * Only ADD/SUB/SET/ULEB128 should end up here.
@@ -624,18 +618,25 @@ void process_accumulated_relocations(struct module *me)
         *      - Each relocation entry for a location address
         */
        struct used_bucket *bucket_iter;
+       struct used_bucket *bucket_iter_tmp;
        struct relocation_head *rel_head_iter;
+       struct hlist_node *rel_head_iter_tmp;
        struct relocation_entry *rel_entry_iter;
+       struct relocation_entry *rel_entry_iter_tmp;
        int curr_type;
        void *location;
        long buffer;
 
-       list_for_each_entry(bucket_iter, &used_buckets_list, head) {
-               hlist_for_each_entry(rel_head_iter, bucket_iter->bucket, node) {
+       list_for_each_entry_safe(bucket_iter, bucket_iter_tmp,
+                                used_buckets_list, head) {
+               hlist_for_each_entry_safe(rel_head_iter, rel_head_iter_tmp,
+                                         bucket_iter->bucket, node) {
                        buffer = 0;
                        location = rel_head_iter->location;
-                       list_for_each_entry(rel_entry_iter,
-                                           rel_head_iter->rel_entry, head) {
+                       list_for_each_entry_safe(rel_entry_iter,
+                                                rel_entry_iter_tmp,
+                                                rel_head_iter->rel_entry,
+                                                head) {
                                curr_type = rel_entry_iter->type;
                                reloc_handlers[curr_type].reloc_handler(
                                        me, &buffer, rel_entry_iter->value);
@@ -648,11 +649,14 @@ void process_accumulated_relocations(struct module *me)
                kfree(bucket_iter);
        }
 
-       kfree(relocation_hashtable);
+       kfree(*relocation_hashtable);
 }
 
-int add_relocation_to_accumulate(struct module *me, int type, void *location,
-                                unsigned int hashtable_bits, Elf_Addr v)
+static int add_relocation_to_accumulate(struct module *me, int type,
+                                       void *location,
+                                       unsigned int hashtable_bits, Elf_Addr v,
+                                       struct hlist_head *relocation_hashtable,
+                                       struct list_head *used_buckets_list)
 {
        struct relocation_entry *entry;
        struct relocation_head *rel_head;
@@ -661,6 +665,10 @@ int add_relocation_to_accumulate(struct module *me, int type, void *location,
        unsigned long hash;
 
        entry = kmalloc(sizeof(*entry), GFP_KERNEL);
+
+       if (!entry)
+               return -ENOMEM;
+
        INIT_LIST_HEAD(&entry->head);
        entry->type = type;
        entry->value = v;
@@ -669,7 +677,10 @@ int add_relocation_to_accumulate(struct module *me, int type, void *location,
 
        current_head = &relocation_hashtable[hash];
 
-       /* Find matching location (if any) */
+       /*
+        * Search for the relocation_head for the relocations that happen at the
+        * provided location
+        */
        bool found = false;
        struct relocation_head *rel_head_iter;
 
@@ -681,19 +692,45 @@ int add_relocation_to_accumulate(struct module *me, int type, void *location,
                }
        }
 
+       /*
+        * If there has not yet been any relocations at the provided location,
+        * create a relocation_head for that location and populate it with this
+        * relocation_entry.
+        */
        if (!found) {
                rel_head = kmalloc(sizeof(*rel_head), GFP_KERNEL);
+
+               if (!rel_head) {
+                       kfree(entry);
+                       return -ENOMEM;
+               }
+
                rel_head->rel_entry =
                        kmalloc(sizeof(struct list_head), GFP_KERNEL);
+
+               if (!rel_head->rel_entry) {
+                       kfree(entry);
+                       kfree(rel_head);
+                       return -ENOMEM;
+               }
+
                INIT_LIST_HEAD(rel_head->rel_entry);
                rel_head->location = location;
                INIT_HLIST_NODE(&rel_head->node);
                if (!current_head->first) {
                        bucket =
                                kmalloc(sizeof(struct used_bucket), GFP_KERNEL);
+
+                       if (!bucket) {
+                               kfree(entry);
+                               kfree(rel_head);
+                               kfree(rel_head->rel_entry);
+                               return -ENOMEM;
+                       }
+
                        INIT_LIST_HEAD(&bucket->head);
                        bucket->bucket = current_head;
-                       list_add(&bucket->head, &used_buckets_list);
+                       list_add(&bucket->head, used_buckets_list);
                }
                hlist_add_head(&rel_head->node, current_head);
        }
@@ -704,7 +741,9 @@ int add_relocation_to_accumulate(struct module *me, int type, void *location,
        return 0;
 }
 
-unsigned int initialize_relocation_hashtable(unsigned int num_relocations)
+static unsigned int
+initialize_relocation_hashtable(unsigned int num_relocations,
+                               struct hlist_head **relocation_hashtable)
 {
        /* Can safely assume that bits is not greater than sizeof(long) */
        unsigned long hashtable_size = roundup_pow_of_two(num_relocations);
@@ -720,12 +759,13 @@ unsigned int initialize_relocation_hashtable(unsigned int num_relocations)
 
        hashtable_size <<= should_double_size;
 
-       relocation_hashtable = kmalloc_array(hashtable_size,
-                                            sizeof(*relocation_hashtable),
-                                            GFP_KERNEL);
-       __hash_init(relocation_hashtable, hashtable_size);
+       *relocation_hashtable = kmalloc_array(hashtable_size,
+                                             sizeof(*relocation_hashtable),
+                                             GFP_KERNEL);
+       if (!*relocation_hashtable)
+               return -ENOMEM;
 
-       INIT_LIST_HEAD(&used_buckets_list);
+       __hash_init(*relocation_hashtable, hashtable_size);
 
        return hashtable_bits;
 }
@@ -742,7 +782,17 @@ int apply_relocate_add(Elf_Shdr *sechdrs, const char *strtab,
        Elf_Addr v;
        int res;
        unsigned int num_relocations = sechdrs[relsec].sh_size / sizeof(*rel);
-       unsigned int hashtable_bits = initialize_relocation_hashtable(num_relocations);
+       struct hlist_head *relocation_hashtable;
+       struct list_head used_buckets_list;
+       unsigned int hashtable_bits;
+
+       hashtable_bits = initialize_relocation_hashtable(num_relocations,
+                                                        &relocation_hashtable);
+
+       if (hashtable_bits < 0)
+               return hashtable_bits;
+
+       INIT_LIST_HEAD(&used_buckets_list);
 
        pr_debug("Applying relocate section %u to %u\n", relsec,
               sechdrs[relsec].sh_info);
@@ -823,14 +873,18 @@ int apply_relocate_add(Elf_Shdr *sechdrs, const char *strtab,
                }
 
                if (reloc_handlers[type].accumulate_handler)
-                       res = add_relocation_to_accumulate(me, type, location, hashtable_bits, v);
+                       res = add_relocation_to_accumulate(me, type, location,
+                                                          hashtable_bits, v,
+                                                          relocation_hashtable,
+                                                          &used_buckets_list);
                else
                        res = handler(me, location, v);
                if (res)
                        return res;
        }
 
-       process_accumulated_relocations(me);
+       process_accumulated_relocations(me, &relocation_hashtable,
+                                       &used_buckets_list);
 
        return 0;
 }
index c712037dbe10ec88b9ee8f5d8559f9b73c6608fa..a2ca5b7756a5b0ca716de4fe9ae8bd51693bdb97 100644 (file)
@@ -169,7 +169,7 @@ static void hwprobe_isa_ext0(struct riscv_hwprobe *pair,
        pair->value &= ~missing;
 }
 
-static bool hwprobe_ext0_has(const struct cpumask *cpus, unsigned long ext)
+static bool hwprobe_ext0_has(const struct cpumask *cpus, u64 ext)
 {
        struct riscv_hwprobe pair;
 
index 90f22049d553e0e99b73ccc1291a57a2fb48aa0e..8515ed7cd8c120f75d592c401aa383da629c5729 100644 (file)
@@ -6,13 +6,13 @@
 .text
 .global test_uleb_basic
 test_uleb_basic:
-       ld      a0, second
+       lw      a0, second
        addi    a0, a0, -127
        ret
 
 .global test_uleb_large
 test_uleb_large:
-       ld      a0, fourth
+       lw      a0, fourth
        addi    a0, a0, -0x07e8
        ret
 
@@ -22,10 +22,10 @@ first:
 second:
        .reloc second, R_RISCV_SET_ULEB128, second
        .reloc second, R_RISCV_SUB_ULEB128, first
-       .dword 0
+       .word 0
 third:
        .space 1000
 fourth:
        .reloc fourth, R_RISCV_SET_ULEB128, fourth
        .reloc fourth, R_RISCV_SUB_ULEB128, third
-       .dword 0
+       .word 0
index 5eba37147caa96c077eb9ffb89233e1f679fed6d..5255f8134aeff5484e24d83b727ff9908a1b1c44 100644 (file)
@@ -550,16 +550,14 @@ int handle_misaligned_store(struct pt_regs *regs)
        } else if ((insn & INSN_MASK_C_SD) == INSN_MATCH_C_SD) {
                len = 8;
                val.data_ulong = GET_RS2S(insn, regs);
-       } else if ((insn & INSN_MASK_C_SDSP) == INSN_MATCH_C_SDSP &&
-                  ((insn >> SH_RD) & 0x1f)) {
+       } else if ((insn & INSN_MASK_C_SDSP) == INSN_MATCH_C_SDSP) {
                len = 8;
                val.data_ulong = GET_RS2C(insn, regs);
 #endif
        } else if ((insn & INSN_MASK_C_SW) == INSN_MATCH_C_SW) {
                len = 4;
                val.data_ulong = GET_RS2S(insn, regs);
-       } else if ((insn & INSN_MASK_C_SWSP) == INSN_MATCH_C_SWSP &&
-                  ((insn >> SH_RD) & 0x1f)) {
+       } else if ((insn & INSN_MASK_C_SWSP) == INSN_MATCH_C_SWSP) {
                len = 4;
                val.data_ulong = GET_RS2C(insn, regs);
        } else if ((insn & INSN_MASK_C_FSD) == INSN_MATCH_C_FSD) {
index 1b5d17a9f70dde9f711c53ea2db97762d73eadf3..cf1f13c8217569f6bd82eb6d513c37210628ebd2 100644 (file)
@@ -10,6 +10,7 @@
 #include <asm/coco.h>
 #include <asm/tdx.h>
 #include <asm/vmx.h>
+#include <asm/ia32.h>
 #include <asm/insn.h>
 #include <asm/insn-eval.h>
 #include <asm/pgtable.h>
index d813160b14d85172c307b9436a6703ab9b6b1768..6356060caaf311af8370ccaeb69aab85847b62d1 100644 (file)
@@ -26,6 +26,7 @@
 #include <xen/events.h>
 #endif
 
+#include <asm/apic.h>
 #include <asm/desc.h>
 #include <asm/traps.h>
 #include <asm/vdso.h>
@@ -167,7 +168,96 @@ static __always_inline void do_syscall_32_irqs_on(struct pt_regs *regs, int nr)
        }
 }
 
-/* Handles int $0x80 */
+#ifdef CONFIG_IA32_EMULATION
+static __always_inline bool int80_is_external(void)
+{
+       const unsigned int offs = (0x80 / 32) * 0x10;
+       const u32 bit = BIT(0x80 % 32);
+
+       /* The local APIC on XENPV guests is fake */
+       if (cpu_feature_enabled(X86_FEATURE_XENPV))
+               return false;
+
+       /*
+        * If vector 0x80 is set in the APIC ISR then this is an external
+        * interrupt. Either from broken hardware or injected by a VMM.
+        *
+        * Note: In guest mode this is only valid for secure guests where
+        * the secure module fully controls the vAPIC exposed to the guest.
+        */
+       return apic_read(APIC_ISR + offs) & bit;
+}
+
+/**
+ * int80_emulation - 32-bit legacy syscall entry
+ *
+ * This entry point can be used by 32-bit and 64-bit programs to perform
+ * 32-bit system calls.  Instances of INT $0x80 can be found inline in
+ * various programs and libraries.  It is also used by the vDSO's
+ * __kernel_vsyscall fallback for hardware that doesn't support a faster
+ * entry method.  Restarted 32-bit system calls also fall back to INT
+ * $0x80 regardless of what instruction was originally used to do the
+ * system call.
+ *
+ * This is considered a slow path.  It is not used by most libc
+ * implementations on modern hardware except during process startup.
+ *
+ * The arguments for the INT $0x80 based syscall are on stack in the
+ * pt_regs structure:
+ *   eax:                              system call number
+ *   ebx, ecx, edx, esi, edi, ebp:     arg1 - arg 6
+ */
+DEFINE_IDTENTRY_RAW(int80_emulation)
+{
+       int nr;
+
+       /* Kernel does not use INT $0x80! */
+       if (unlikely(!user_mode(regs))) {
+               irqentry_enter(regs);
+               instrumentation_begin();
+               panic("Unexpected external interrupt 0x80\n");
+       }
+
+       /*
+        * Establish kernel context for instrumentation, including for
+        * int80_is_external() below which calls into the APIC driver.
+        * Identical for soft and external interrupts.
+        */
+       enter_from_user_mode(regs);
+
+       instrumentation_begin();
+       add_random_kstack_offset();
+
+       /* Validate that this is a soft interrupt to the extent possible */
+       if (unlikely(int80_is_external()))
+               panic("Unexpected external interrupt 0x80\n");
+
+       /*
+        * The low level idtentry code pushed -1 into regs::orig_ax
+        * and regs::ax contains the syscall number.
+        *
+        * User tracing code (ptrace or signal handlers) might assume
+        * that the regs::orig_ax contains a 32-bit number on invoking
+        * a 32-bit syscall.
+        *
+        * Establish the syscall convention by saving the 32bit truncated
+        * syscall number in regs::orig_ax and by invalidating regs::ax.
+        */
+       regs->orig_ax = regs->ax & GENMASK(31, 0);
+       regs->ax = -ENOSYS;
+
+       nr = syscall_32_enter(regs);
+
+       local_irq_enable();
+       nr = syscall_enter_from_user_mode_work(regs, nr);
+       do_syscall_32_irqs_on(regs, nr);
+
+       instrumentation_end();
+       syscall_exit_to_user_mode(regs);
+}
+#else /* CONFIG_IA32_EMULATION */
+
+/* Handles int $0x80 on a 32bit kernel */
 __visible noinstr void do_int80_syscall_32(struct pt_regs *regs)
 {
        int nr = syscall_32_enter(regs);
@@ -186,6 +276,7 @@ __visible noinstr void do_int80_syscall_32(struct pt_regs *regs)
        instrumentation_end();
        syscall_exit_to_user_mode(regs);
 }
+#endif /* !CONFIG_IA32_EMULATION */
 
 static noinstr bool __do_fast_syscall_32(struct pt_regs *regs)
 {
index 27c05d08558aaadec8dea7ed8568036e277efd2c..de94e2e84ecca927d9aa0e1ab99466466c163d44 100644 (file)
@@ -275,80 +275,3 @@ SYM_INNER_LABEL(entry_SYSRETL_compat_end, SYM_L_GLOBAL)
        ANNOTATE_NOENDBR
        int3
 SYM_CODE_END(entry_SYSCALL_compat)
-
-/*
- * 32-bit legacy system call entry.
- *
- * 32-bit x86 Linux system calls traditionally used the INT $0x80
- * instruction.  INT $0x80 lands here.
- *
- * This entry point can be used by 32-bit and 64-bit programs to perform
- * 32-bit system calls.  Instances of INT $0x80 can be found inline in
- * various programs and libraries.  It is also used by the vDSO's
- * __kernel_vsyscall fallback for hardware that doesn't support a faster
- * entry method.  Restarted 32-bit system calls also fall back to INT
- * $0x80 regardless of what instruction was originally used to do the
- * system call.
- *
- * This is considered a slow path.  It is not used by most libc
- * implementations on modern hardware except during process startup.
- *
- * Arguments:
- * eax  system call number
- * ebx  arg1
- * ecx  arg2
- * edx  arg3
- * esi  arg4
- * edi  arg5
- * ebp  arg6
- */
-SYM_CODE_START(entry_INT80_compat)
-       UNWIND_HINT_ENTRY
-       ENDBR
-       /*
-        * Interrupts are off on entry.
-        */
-       ASM_CLAC                        /* Do this early to minimize exposure */
-       ALTERNATIVE "swapgs", "", X86_FEATURE_XENPV
-
-       /*
-        * User tracing code (ptrace or signal handlers) might assume that
-        * the saved RAX contains a 32-bit number when we're invoking a 32-bit
-        * syscall.  Just in case the high bits are nonzero, zero-extend
-        * the syscall number.  (This could almost certainly be deleted
-        * with no ill effects.)
-        */
-       movl    %eax, %eax
-
-       /* switch to thread stack expects orig_ax and rdi to be pushed */
-       pushq   %rax                    /* pt_regs->orig_ax */
-
-       /* Need to switch before accessing the thread stack. */
-       SWITCH_TO_KERNEL_CR3 scratch_reg=%rax
-
-       /* In the Xen PV case we already run on the thread stack. */
-       ALTERNATIVE "", "jmp .Lint80_keep_stack", X86_FEATURE_XENPV
-
-       movq    %rsp, %rax
-       movq    PER_CPU_VAR(pcpu_hot + X86_top_of_stack), %rsp
-
-       pushq   5*8(%rax)               /* regs->ss */
-       pushq   4*8(%rax)               /* regs->rsp */
-       pushq   3*8(%rax)               /* regs->eflags */
-       pushq   2*8(%rax)               /* regs->cs */
-       pushq   1*8(%rax)               /* regs->ip */
-       pushq   0*8(%rax)               /* regs->orig_ax */
-.Lint80_keep_stack:
-
-       PUSH_AND_CLEAR_REGS rax=$-ENOSYS
-       UNWIND_HINT_REGS
-
-       cld
-
-       IBRS_ENTER
-       UNTRAIN_RET
-
-       movq    %rsp, %rdi
-       call    do_int80_syscall_32
-       jmp     swapgs_restore_regs_and_return_to_usermode
-SYM_CODE_END(entry_INT80_compat)
index 5a2ae24b1204f932e15ff3d5f08232e541e54be5..9805629479d968b3c483879bc5ca56a3373d7504 100644 (file)
@@ -75,6 +75,11 @@ static inline bool ia32_enabled(void)
        return __ia32_enabled;
 }
 
+static inline void ia32_disable(void)
+{
+       __ia32_enabled = false;
+}
+
 #else /* !CONFIG_IA32_EMULATION */
 
 static inline bool ia32_enabled(void)
@@ -82,6 +87,8 @@ static inline bool ia32_enabled(void)
        return IS_ENABLED(CONFIG_X86_32);
 }
 
+static inline void ia32_disable(void) {}
+
 #endif
 
 #endif /* _ASM_X86_IA32_H */
index 05fd175cec7d5c9a617fd1f3c1462ade1d44b06e..13639e57e1f8af4c24c0c656a9f0801516bf25f4 100644 (file)
@@ -569,6 +569,10 @@ DECLARE_IDTENTRY_RAW(X86_TRAP_UD,          exc_invalid_op);
 DECLARE_IDTENTRY_RAW(X86_TRAP_BP,              exc_int3);
 DECLARE_IDTENTRY_RAW_ERRORCODE(X86_TRAP_PF,    exc_page_fault);
 
+#if defined(CONFIG_IA32_EMULATION)
+DECLARE_IDTENTRY_RAW(IA32_SYSCALL_VECTOR,      int80_emulation);
+#endif
+
 #ifdef CONFIG_X86_MCE
 #ifdef CONFIG_X86_64
 DECLARE_IDTENTRY_MCE(X86_TRAP_MC,      exc_machine_check);
index 4d84122bd6433b165dff727887667965637ee7e4..484f4f0131a5cceedf373804573074010a9892b0 100644 (file)
@@ -32,10 +32,6 @@ void entry_SYSCALL_compat(void);
 void entry_SYSCALL_compat_safe_stack(void);
 void entry_SYSRETL_compat_unsafe_stack(void);
 void entry_SYSRETL_compat_end(void);
-void entry_INT80_compat(void);
-#ifdef CONFIG_XEN_PV
-void xen_entry_INT80_compat(void);
-#endif
 #else /* !CONFIG_IA32_EMULATION */
 #define entry_SYSCALL_compat NULL
 #define entry_SYSENTER_compat NULL
index 8857abc706e469f73edf7f98953838eebdd05354..660b601f1d6c33e9ad62ec2d12d860e92d4ea420 100644 (file)
@@ -121,7 +121,7 @@ static const __initconst struct idt_data def_idts[] = {
 
 static const struct idt_data ia32_idt[] __initconst = {
 #if defined(CONFIG_IA32_EMULATION)
-       SYSG(IA32_SYSCALL_VECTOR,       entry_INT80_compat),
+       SYSG(IA32_SYSCALL_VECTOR,       asm_int80_emulation),
 #elif defined(CONFIG_X86_32)
        SYSG(IA32_SYSCALL_VECTOR,       entry_INT80_32),
 #endif
index a68f2dda0948c211e0ee4f1f2e4a000f513c463a..70b91de2e053abb5f181612e3db295b16def3c02 100644 (file)
@@ -32,6 +32,7 @@
 #include <asm/msr.h>
 #include <asm/cmdline.h>
 #include <asm/sev.h>
+#include <asm/ia32.h>
 
 #include "mm_internal.h"
 
@@ -481,6 +482,16 @@ void __init sme_early_init(void)
         */
        if (sev_status & MSR_AMD64_SEV_ES_ENABLED)
                x86_cpuinit.parallel_bringup = false;
+
+       /*
+        * The VMM is capable of injecting interrupt 0x80 and triggering the
+        * compatibility syscall path.
+        *
+        * By default, the 32-bit emulation is disabled in order to ensure
+        * the safety of the VM.
+        */
+       if (sev_status & MSR_AMD64_SEV_ENABLED)
+               ia32_disable();
 }
 
 void __init mem_encrypt_free_decrypted_mem(void)
index 8c10d9abc2394fc43f75f3324dd8d0e42c3f797a..e89e415aa7435311991a945575519a593a2abb44 100644 (file)
@@ -3025,3 +3025,49 @@ void arch_bpf_stack_walk(bool (*consume_fn)(void *cookie, u64 ip, u64 sp, u64 bp
 #endif
        WARN(1, "verification of programs using bpf_throw should have failed\n");
 }
+
+void bpf_arch_poke_desc_update(struct bpf_jit_poke_descriptor *poke,
+                              struct bpf_prog *new, struct bpf_prog *old)
+{
+       u8 *old_addr, *new_addr, *old_bypass_addr;
+       int ret;
+
+       old_bypass_addr = old ? NULL : poke->bypass_addr;
+       old_addr = old ? (u8 *)old->bpf_func + poke->adj_off : NULL;
+       new_addr = new ? (u8 *)new->bpf_func + poke->adj_off : NULL;
+
+       /*
+        * On program loading or teardown, the program's kallsym entry
+        * might not be in place, so we use __bpf_arch_text_poke to skip
+        * the kallsyms check.
+        */
+       if (new) {
+               ret = __bpf_arch_text_poke(poke->tailcall_target,
+                                          BPF_MOD_JUMP,
+                                          old_addr, new_addr);
+               BUG_ON(ret < 0);
+               if (!old) {
+                       ret = __bpf_arch_text_poke(poke->tailcall_bypass,
+                                                  BPF_MOD_JUMP,
+                                                  poke->bypass_addr,
+                                                  NULL);
+                       BUG_ON(ret < 0);
+               }
+       } else {
+               ret = __bpf_arch_text_poke(poke->tailcall_bypass,
+                                          BPF_MOD_JUMP,
+                                          old_bypass_addr,
+                                          poke->bypass_addr);
+               BUG_ON(ret < 0);
+               /* let other CPUs finish the execution of program
+                * so that it will not possible to expose them
+                * to invalid nop, stack unwind, nop state
+                */
+               if (!ret)
+                       synchronize_rcu();
+               ret = __bpf_arch_text_poke(poke->tailcall_target,
+                                          BPF_MOD_JUMP,
+                                          old_addr, NULL);
+               BUG_ON(ret < 0);
+       }
+}
index bbbfdd495ebd3ac590fd152e0504c6bedae611de..aeb33e0a3f763370b00daf427063b2010f0bcf40 100644 (file)
@@ -704,7 +704,7 @@ static struct trap_array_entry trap_array[] = {
        TRAP_ENTRY(exc_int3,                            false ),
        TRAP_ENTRY(exc_overflow,                        false ),
 #ifdef CONFIG_IA32_EMULATION
-       { entry_INT80_compat,          xen_entry_INT80_compat,          false },
+       TRAP_ENTRY(int80_emulation,                     false ),
 #endif
        TRAP_ENTRY(exc_page_fault,                      false ),
        TRAP_ENTRY(exc_divide_error,                    false ),
index 9e5e680087853a34f8a2fc7a935e60e2c28f12d5..1a9cd18dfbd31208e5d1bcfa53f4a6e90bc81cf6 100644 (file)
@@ -156,7 +156,7 @@ xen_pv_trap asm_xenpv_exc_machine_check
 #endif /* CONFIG_X86_MCE */
 xen_pv_trap asm_exc_simd_coprocessor_error
 #ifdef CONFIG_IA32_EMULATION
-xen_pv_trap entry_INT80_compat
+xen_pv_trap asm_int80_emulation
 #endif
 xen_pv_trap asm_exc_xen_unknown_trap
 xen_pv_trap asm_exc_xen_hypervisor_callback
index 28c75242fca9c456afb53ffa7b77758cd088ec6b..62944e35fcee2980446a743c0099c8bfc26cbf6e 100644 (file)
@@ -399,13 +399,13 @@ acpi_evaluate_reference(acpi_handle handle,
                acpi_handle_debug(list->handles[i], "Found in reference list\n");
        }
 
-end:
        if (ACPI_FAILURE(status)) {
                list->count = 0;
                kfree(list->handles);
                list->handles = NULL;
        }
 
+end:
        kfree(buffer.pointer);
 
        return status;
index 9ea22e165acd679b1e6ef72433104bed858cfc22..548491de818ef126f598eba06287bf7899418398 100644 (file)
@@ -144,7 +144,7 @@ static DEVICE_ATTR(release, S_IWUSR, NULL, cpu_release_store);
 #endif /* CONFIG_ARCH_CPU_PROBE_RELEASE */
 #endif /* CONFIG_HOTPLUG_CPU */
 
-#ifdef CONFIG_KEXEC
+#ifdef CONFIG_KEXEC_CORE
 #include <linux/kexec.h>
 
 static ssize_t crash_notes_show(struct device *dev,
@@ -189,14 +189,14 @@ static const struct attribute_group crash_note_cpu_attr_group = {
 #endif
 
 static const struct attribute_group *common_cpu_attr_groups[] = {
-#ifdef CONFIG_KEXEC
+#ifdef CONFIG_KEXEC_CORE
        &crash_note_cpu_attr_group,
 #endif
        NULL
 };
 
 static const struct attribute_group *hotplugable_cpu_attr_groups[] = {
-#ifdef CONFIG_KEXEC
+#ifdef CONFIG_KEXEC_CORE
        &crash_note_cpu_attr_group,
 #endif
        NULL
index f3b9a4d0fa3bb2a9c0c03614bae78f206b0c77b2..8a13babd826ce3c96a7f73bf7a7e723179e047b1 100644 (file)
@@ -180,6 +180,9 @@ static inline unsigned long memblk_nr_poison(struct memory_block *mem)
 }
 #endif
 
+/*
+ * Must acquire mem_hotplug_lock in write mode.
+ */
 static int memory_block_online(struct memory_block *mem)
 {
        unsigned long start_pfn = section_nr_to_pfn(mem->start_section_nr);
@@ -204,10 +207,11 @@ static int memory_block_online(struct memory_block *mem)
        if (mem->altmap)
                nr_vmemmap_pages = mem->altmap->free;
 
+       mem_hotplug_begin();
        if (nr_vmemmap_pages) {
                ret = mhp_init_memmap_on_memory(start_pfn, nr_vmemmap_pages, zone);
                if (ret)
-                       return ret;
+                       goto out;
        }
 
        ret = online_pages(start_pfn + nr_vmemmap_pages,
@@ -215,7 +219,7 @@ static int memory_block_online(struct memory_block *mem)
        if (ret) {
                if (nr_vmemmap_pages)
                        mhp_deinit_memmap_on_memory(start_pfn, nr_vmemmap_pages);
-               return ret;
+               goto out;
        }
 
        /*
@@ -227,9 +231,14 @@ static int memory_block_online(struct memory_block *mem)
                                          nr_vmemmap_pages);
 
        mem->zone = zone;
+out:
+       mem_hotplug_done();
        return ret;
 }
 
+/*
+ * Must acquire mem_hotplug_lock in write mode.
+ */
 static int memory_block_offline(struct memory_block *mem)
 {
        unsigned long start_pfn = section_nr_to_pfn(mem->start_section_nr);
@@ -247,6 +256,7 @@ static int memory_block_offline(struct memory_block *mem)
        if (mem->altmap)
                nr_vmemmap_pages = mem->altmap->free;
 
+       mem_hotplug_begin();
        if (nr_vmemmap_pages)
                adjust_present_page_count(pfn_to_page(start_pfn), mem->group,
                                          -nr_vmemmap_pages);
@@ -258,13 +268,15 @@ static int memory_block_offline(struct memory_block *mem)
                if (nr_vmemmap_pages)
                        adjust_present_page_count(pfn_to_page(start_pfn),
                                                  mem->group, nr_vmemmap_pages);
-               return ret;
+               goto out;
        }
 
        if (nr_vmemmap_pages)
                mhp_deinit_memmap_on_memory(start_pfn, nr_vmemmap_pages);
 
        mem->zone = NULL;
+out:
+       mem_hotplug_done();
        return ret;
 }
 
index 92592f944a3df2bab401ecfc1f1ecaf80af2747d..ac63a73ccdaaa23f119966c10f71f0bd28fb43a8 100644 (file)
@@ -410,8 +410,7 @@ out:
                        rb_entry(node, struct regmap_range_node, node);
 
                /* If there's nothing in the cache there's nothing to sync */
-               ret = regcache_read(map, this->selector_reg, &i);
-               if (ret != 0)
+               if (regcache_read(map, this->selector_reg, &i) != 0)
                        continue;
 
                ret = _regmap_write(map, this->selector_reg, i);
index 07b72c67924704aa41ce19df458dc5ad4c46a48b..6146b2927d5c56af6bc3b9722c1789f29a4498fe 100644 (file)
@@ -99,6 +99,7 @@ struct ffa_drv_info {
        void *tx_buffer;
        bool mem_ops_native;
        bool bitmap_created;
+       bool notif_enabled;
        unsigned int sched_recv_irq;
        unsigned int cpuhp_state;
        struct ffa_pcpu_irq __percpu *irq_pcpu;
@@ -782,7 +783,7 @@ static void ffa_notification_info_get(void)
                        if (ids_processed >= max_ids - 1)
                                break;
 
-                       part_id = packed_id_list[++ids_processed];
+                       part_id = packed_id_list[ids_processed++];
 
                        if (!ids_count[list]) { /* Global Notification */
                                __do_sched_recv_cb(part_id, 0, false);
@@ -794,7 +795,7 @@ static void ffa_notification_info_get(void)
                                if (ids_processed >= max_ids - 1)
                                        break;
 
-                               vcpu_id = packed_id_list[++ids_processed];
+                               vcpu_id = packed_id_list[ids_processed++];
 
                                __do_sched_recv_cb(part_id, vcpu_id, true);
                        }
@@ -889,6 +890,8 @@ static int ffa_memory_lend(struct ffa_mem_ops_args *args)
 
 #define FFA_SECURE_PARTITION_ID_FLAG   BIT(15)
 
+#define ffa_notifications_disabled()   (!drv_info->notif_enabled)
+
 enum notify_type {
        NON_SECURE_VM,
        SECURE_PARTITION,
@@ -908,6 +911,9 @@ static int ffa_sched_recv_cb_update(u16 part_id, ffa_sched_recv_cb callback,
        struct ffa_dev_part_info *partition;
        bool cb_valid;
 
+       if (ffa_notifications_disabled())
+               return -EOPNOTSUPP;
+
        partition = xa_load(&drv_info->partition_info, part_id);
        write_lock(&partition->rw_lock);
 
@@ -1001,6 +1007,9 @@ static int ffa_notify_relinquish(struct ffa_device *dev, int notify_id)
        int rc;
        enum notify_type type = ffa_notify_type_get(dev->vm_id);
 
+       if (ffa_notifications_disabled())
+               return -EOPNOTSUPP;
+
        if (notify_id >= FFA_MAX_NOTIFICATIONS)
                return -EINVAL;
 
@@ -1027,6 +1036,9 @@ static int ffa_notify_request(struct ffa_device *dev, bool is_per_vcpu,
        u32 flags = 0;
        enum notify_type type = ffa_notify_type_get(dev->vm_id);
 
+       if (ffa_notifications_disabled())
+               return -EOPNOTSUPP;
+
        if (notify_id >= FFA_MAX_NOTIFICATIONS)
                return -EINVAL;
 
@@ -1057,6 +1069,9 @@ static int ffa_notify_send(struct ffa_device *dev, int notify_id,
 {
        u32 flags = 0;
 
+       if (ffa_notifications_disabled())
+               return -EOPNOTSUPP;
+
        if (is_per_vcpu)
                flags |= (PER_VCPU_NOTIFICATION_FLAG | vcpu << 16);
 
@@ -1233,7 +1248,7 @@ static void ffa_partitions_cleanup(void)
        if (!count)
                return;
 
-       info = kcalloc(count, sizeof(**info), GFP_KERNEL);
+       info = kcalloc(count, sizeof(*info), GFP_KERNEL);
        if (!info)
                return;
 
@@ -1311,8 +1326,10 @@ static int ffa_sched_recv_irq_map(void)
 
 static void ffa_sched_recv_irq_unmap(void)
 {
-       if (drv_info->sched_recv_irq)
+       if (drv_info->sched_recv_irq) {
                irq_dispose_mapping(drv_info->sched_recv_irq);
+               drv_info->sched_recv_irq = 0;
+       }
 }
 
 static int ffa_cpuhp_pcpu_irq_enable(unsigned int cpu)
@@ -1329,17 +1346,23 @@ static int ffa_cpuhp_pcpu_irq_disable(unsigned int cpu)
 
 static void ffa_uninit_pcpu_irq(void)
 {
-       if (drv_info->cpuhp_state)
+       if (drv_info->cpuhp_state) {
                cpuhp_remove_state(drv_info->cpuhp_state);
+               drv_info->cpuhp_state = 0;
+       }
 
-       if (drv_info->notif_pcpu_wq)
+       if (drv_info->notif_pcpu_wq) {
                destroy_workqueue(drv_info->notif_pcpu_wq);
+               drv_info->notif_pcpu_wq = NULL;
+       }
 
        if (drv_info->sched_recv_irq)
                free_percpu_irq(drv_info->sched_recv_irq, drv_info->irq_pcpu);
 
-       if (drv_info->irq_pcpu)
+       if (drv_info->irq_pcpu) {
                free_percpu(drv_info->irq_pcpu);
+               drv_info->irq_pcpu = NULL;
+       }
 }
 
 static int ffa_init_pcpu_irq(unsigned int irq)
@@ -1388,22 +1411,23 @@ static void ffa_notifications_cleanup(void)
                ffa_notification_bitmap_destroy();
                drv_info->bitmap_created = false;
        }
+       drv_info->notif_enabled = false;
 }
 
-static int ffa_notifications_setup(void)
+static void ffa_notifications_setup(void)
 {
        int ret, irq;
 
        ret = ffa_features(FFA_NOTIFICATION_BITMAP_CREATE, 0, NULL, NULL);
        if (ret) {
-               pr_err("Notifications not supported, continuing with it ..\n");
-               return 0;
+               pr_info("Notifications not supported, continuing with it ..\n");
+               return;
        }
 
        ret = ffa_notification_bitmap_create();
        if (ret) {
-               pr_err("notification_bitmap_create error %d\n", ret);
-               return ret;
+               pr_info("Notification bitmap create error %d\n", ret);
+               return;
        }
        drv_info->bitmap_created = true;
 
@@ -1422,14 +1446,11 @@ static int ffa_notifications_setup(void)
        hash_init(drv_info->notifier_hash);
        mutex_init(&drv_info->notify_lock);
 
-       /* Register internal scheduling callback */
-       ret = ffa_sched_recv_cb_update(drv_info->vm_id, ffa_self_notif_handle,
-                                      drv_info, true);
-       if (!ret)
-               return ret;
+       drv_info->notif_enabled = true;
+       return;
 cleanup:
+       pr_info("Notification setup failed %d, not enabled\n", ret);
        ffa_notifications_cleanup();
-       return ret;
 }
 
 static int __init ffa_init(void)
@@ -1483,17 +1504,18 @@ static int __init ffa_init(void)
        mutex_init(&drv_info->rx_lock);
        mutex_init(&drv_info->tx_lock);
 
-       ffa_setup_partitions();
-
        ffa_set_up_mem_ops_native_flag();
 
-       ret = ffa_notifications_setup();
+       ffa_notifications_setup();
+
+       ffa_setup_partitions();
+
+       ret = ffa_sched_recv_cb_update(drv_info->vm_id, ffa_self_notif_handle,
+                                      drv_info, true);
        if (ret)
-               goto partitions_cleanup;
+               pr_info("Failed to register driver sched callback %d\n", ret);
 
        return 0;
-partitions_cleanup:
-       ffa_partitions_cleanup();
 free_pages:
        if (drv_info->tx_buffer)
                free_pages_exact(drv_info->tx_buffer, RXTX_BUFFER_SIZE);
index c2435be0ae1be851b58fafef7242fc54bcf43774..e11555de99ab867c41306f95caad0e55174b9ab4 100644 (file)
@@ -152,7 +152,7 @@ struct perf_dom_info {
        u32 opp_count;
        u32 sustained_freq_khz;
        u32 sustained_perf_level;
-       u32 mult_factor;
+       unsigned long mult_factor;
        struct scmi_perf_domain_info info;
        struct scmi_opp opp[MAX_OPPS];
        struct scmi_fc_info *fc_info;
@@ -268,13 +268,14 @@ scmi_perf_domain_attributes_get(const struct scmi_protocol_handle *ph,
                dom_info->sustained_perf_level =
                                        le32_to_cpu(attr->sustained_perf_level);
                if (!dom_info->sustained_freq_khz ||
-                   !dom_info->sustained_perf_level)
+                   !dom_info->sustained_perf_level ||
+                   dom_info->level_indexing_mode)
                        /* CPUFreq converts to kHz, hence default 1000 */
                        dom_info->mult_factor = 1000;
                else
                        dom_info->mult_factor =
-                                       (dom_info->sustained_freq_khz * 1000) /
-                                       dom_info->sustained_perf_level;
+                                       (dom_info->sustained_freq_khz * 1000UL)
+                                       dom_info->sustained_perf_level;
                strscpy(dom_info->info.name, attr->name,
                        SCMI_SHORT_NAME_MAX_SIZE);
        }
@@ -798,7 +799,7 @@ static int scmi_dvfs_device_opps_add(const struct scmi_protocol_handle *ph,
                if (!dom->level_indexing_mode)
                        freq = dom->opp[idx].perf * dom->mult_factor;
                else
-                       freq = dom->opp[idx].indicative_freq * 1000;
+                       freq = dom->opp[idx].indicative_freq * dom->mult_factor;
 
                data.level = dom->opp[idx].perf;
                data.freq = freq;
@@ -845,7 +846,8 @@ static int scmi_dvfs_freq_set(const struct scmi_protocol_handle *ph, u32 domain,
        } else {
                struct scmi_opp *opp;
 
-               opp = LOOKUP_BY_FREQ(dom->opps_by_freq, freq / 1000);
+               opp = LOOKUP_BY_FREQ(dom->opps_by_freq,
+                                    freq / dom->mult_factor);
                if (!opp)
                        return -EIO;
 
@@ -879,7 +881,7 @@ static int scmi_dvfs_freq_get(const struct scmi_protocol_handle *ph, u32 domain,
                if (!opp)
                        return -EIO;
 
-               *freq = opp->indicative_freq * 1000;
+               *freq = opp->indicative_freq * dom->mult_factor;
        }
 
        return ret;
@@ -902,7 +904,7 @@ static int scmi_dvfs_est_power_get(const struct scmi_protocol_handle *ph,
                if (!dom->level_indexing_mode)
                        opp_freq = opp->perf * dom->mult_factor;
                else
-                       opp_freq = opp->indicative_freq * 1000;
+                       opp_freq = opp->indicative_freq * dom->mult_factor;
 
                if (opp_freq < *freq)
                        continue;
index 5c0817cbc7c2b1b10ab4e22b19f89d8ef120c5f0..1f64d8cbb14df8cd210271107b8cf8bb045249df 100644 (file)
@@ -3791,10 +3791,6 @@ static void amdgpu_device_set_mcbp(struct amdgpu_device *adev)
                adev->gfx.mcbp = true;
        else if (amdgpu_mcbp == 0)
                adev->gfx.mcbp = false;
-       else if ((amdgpu_ip_version(adev, GC_HWIP, 0) >= IP_VERSION(9, 0, 0)) &&
-                (amdgpu_ip_version(adev, GC_HWIP, 0) < IP_VERSION(10, 0, 0)) &&
-                adev->gfx.num_gfx_rings)
-               adev->gfx.mcbp = true;
 
        if (amdgpu_sriov_vf(adev))
                adev->gfx.mcbp = true;
@@ -4531,6 +4527,8 @@ int amdgpu_device_suspend(struct drm_device *dev, bool fbcon)
        if (r)
                return r;
 
+       amdgpu_ttm_set_buffer_funcs_status(adev, false);
+
        amdgpu_fence_driver_hw_fini(adev);
 
        amdgpu_device_ip_suspend_phase2(adev);
index 2b488fcf2f95b2021872383c39c1c03b22004531..e51e8918e6671aa27bb7ce239a19594a43638f10 100644 (file)
@@ -46,6 +46,8 @@
 #define MCA_REG__STATUS__ERRORCODEEXT(x)       MCA_REG_FIELD(x, 21, 16)
 #define MCA_REG__STATUS__ERRORCODE(x)          MCA_REG_FIELD(x, 15, 0)
 
+#define MCA_REG__SYND__ERRORINFORMATION(x)     MCA_REG_FIELD(x, 17, 0)
+
 enum amdgpu_mca_ip {
        AMDGPU_MCA_IP_UNKNOW = -1,
        AMDGPU_MCA_IP_PSP = 0,
index a3dc68e989108e52c71a24bd97fff44f6183f8db..63fb4cd85e53b71c106daa9a5e3179da6cc42b1c 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/reboot.h>
 #include <linux/syscalls.h>
 #include <linux/pm_runtime.h>
+#include <linux/list_sort.h>
 
 #include "amdgpu.h"
 #include "amdgpu_ras.h"
@@ -3665,6 +3666,21 @@ static struct ras_err_node *amdgpu_ras_error_node_new(void)
        return err_node;
 }
 
+static int ras_err_info_cmp(void *priv, const struct list_head *a, const struct list_head *b)
+{
+       struct ras_err_node *nodea = container_of(a, struct ras_err_node, node);
+       struct ras_err_node *nodeb = container_of(b, struct ras_err_node, node);
+       struct amdgpu_smuio_mcm_config_info *infoa = &nodea->err_info.mcm_info;
+       struct amdgpu_smuio_mcm_config_info *infob = &nodeb->err_info.mcm_info;
+
+       if (unlikely(infoa->socket_id != infob->socket_id))
+               return infoa->socket_id - infob->socket_id;
+       else
+               return infoa->die_id - infob->die_id;
+
+       return 0;
+}
+
 static struct ras_err_info *amdgpu_ras_error_get_info(struct ras_err_data *err_data,
                                                      struct amdgpu_smuio_mcm_config_info *mcm_info)
 {
@@ -3682,6 +3698,7 @@ static struct ras_err_info *amdgpu_ras_error_get_info(struct ras_err_data *err_d
 
        err_data->err_list_count++;
        list_add_tail(&err_node->node, &err_data->err_node_list);
+       list_sort(NULL, &err_data->err_node_list, ras_err_info_cmp);
 
        return &err_node->err_info;
 }
index 49e934975719772ca3195747c24b9c941ca057ab..4db6bb73ead427d1c95a98ed55b42cadb0af0e95 100644 (file)
@@ -129,6 +129,11 @@ static void hdp_v4_0_get_clockgating_state(struct amdgpu_device *adev,
 {
        int data;
 
+       if (amdgpu_ip_version(adev, HDP_HWIP, 0) == IP_VERSION(4, 4, 2)) {
+               /* Default enabled */
+               *flags |= AMD_CG_SUPPORT_HDP_MGCG;
+               return;
+       }
        /* AMD_CG_SUPPORT_HDP_LS */
        data = RREG32(SOC15_REG_OFFSET(HDP, 0, mmHDP_MEM_POWER_LS));
        if (data & HDP_MEM_POWER_LS__LS_ENABLE_MASK)
index 3cf4684d0d3f3c2cef3138faa4bc264d838f6b0c..df1844d0800f2e5d9bcbc9d546ef3e52e060b733 100644 (file)
@@ -60,7 +60,7 @@ MODULE_FIRMWARE("amdgpu/psp_14_0_0_ta.bin");
 #define GFX_CMD_USB_PD_USE_LFB 0x480
 
 /* Retry times for vmbx ready wait */
-#define PSP_VMBX_POLLING_LIMIT 20000
+#define PSP_VMBX_POLLING_LIMIT 3000
 
 /* VBIOS gfl defines */
 #define MBOX_READY_MASK 0x80000000
@@ -161,14 +161,18 @@ static int psp_v13_0_wait_for_vmbx_ready(struct psp_context *psp)
 static int psp_v13_0_wait_for_bootloader(struct psp_context *psp)
 {
        struct amdgpu_device *adev = psp->adev;
-       int retry_loop, ret;
+       int retry_loop, retry_cnt, ret;
 
+       retry_cnt =
+               (amdgpu_ip_version(adev, MP0_HWIP, 0) == IP_VERSION(13, 0, 6)) ?
+                       PSP_VMBX_POLLING_LIMIT :
+                       10;
        /* Wait for bootloader to signify that it is ready having bit 31 of
         * C2PMSG_35 set to 1. All other bits are expected to be cleared.
         * If there is an error in processing command, bits[7:0] will be set.
         * This is applicable for PSP v13.0.6 and newer.
         */
-       for (retry_loop = 0; retry_loop < PSP_VMBX_POLLING_LIMIT; retry_loop++) {
+       for (retry_loop = 0; retry_loop < retry_cnt; retry_loop++) {
                ret = psp_wait_for(
                        psp, SOC15_REG_OFFSET(MP0, 0, regMP0_SMN_C2PMSG_35),
                        0x80000000, 0xffffffff, false);
@@ -821,7 +825,7 @@ static int psp_v13_0_query_boot_status(struct psp_context *psp)
        if (amdgpu_ip_version(adev, MP0_HWIP, 0) != IP_VERSION(13, 0, 6))
                return 0;
 
-       if (RREG32_SOC15(MP0, 0, regMP0_SMN_C2PMSG_59) < 0x00a10007)
+       if (RREG32_SOC15(MP0, 0, regMP0_SMN_C2PMSG_59) < 0x00a10109)
                return 0;
 
        for_each_inst(i, inst_mask) {
index c82776e5e9aa2a154fd04ba61616bc3864fad9b1..51342809af03478f5a1767c7eed98007110ca01b 100644 (file)
@@ -1423,11 +1423,14 @@ static void soc15_common_get_clockgating_state(void *handle, u64 *flags)
        if (amdgpu_sriov_vf(adev))
                *flags = 0;
 
-       adev->nbio.funcs->get_clockgating_state(adev, flags);
+       if (adev->nbio.funcs && adev->nbio.funcs->get_clockgating_state)
+               adev->nbio.funcs->get_clockgating_state(adev, flags);
 
-       adev->hdp.funcs->get_clock_gating_state(adev, flags);
+       if (adev->hdp.funcs && adev->hdp.funcs->get_clock_gating_state)
+               adev->hdp.funcs->get_clock_gating_state(adev, flags);
 
-       if (amdgpu_ip_version(adev, MP0_HWIP, 0) != IP_VERSION(13, 0, 2)) {
+       if ((amdgpu_ip_version(adev, MP0_HWIP, 0) != IP_VERSION(13, 0, 2)) &&
+           (amdgpu_ip_version(adev, MP0_HWIP, 0) != IP_VERSION(13, 0, 6))) {
                /* AMD_CG_SUPPORT_DRM_MGCG */
                data = RREG32(SOC15_REG_OFFSET(MP0, 0, mmMP0_MISC_CGTT_CTRL0));
                if (!(data & 0x01000000))
@@ -1440,9 +1443,11 @@ static void soc15_common_get_clockgating_state(void *handle, u64 *flags)
        }
 
        /* AMD_CG_SUPPORT_ROM_MGCG */
-       adev->smuio.funcs->get_clock_gating_state(adev, flags);
+       if (adev->smuio.funcs && adev->smuio.funcs->get_clock_gating_state)
+               adev->smuio.funcs->get_clock_gating_state(adev, flags);
 
-       adev->df.funcs->get_clockgating_state(adev, flags);
+       if (adev->df.funcs && adev->df.funcs->get_clockgating_state)
+               adev->df.funcs->get_clockgating_state(adev, flags);
 }
 
 static int soc15_common_set_powergating_state(void *handle,
index c7a29bb737e24d0394e770529f1d3f43d0333aae..aac98f93545a22eb38464be4ba32ef41e4b77dfd 100644 (file)
@@ -63,6 +63,12 @@ static void apply_edid_quirks(struct edid *edid, struct dc_edid_caps *edid_caps)
                DRM_DEBUG_DRIVER("Disabling FAMS on monitor with panel id %X\n", panel_id);
                edid_caps->panel_patch.disable_fams = true;
                break;
+       /* Workaround for some monitors that do not clear DPCD 0x317 if FreeSync is unsupported */
+       case drm_edid_encode_panel_id('A', 'U', 'O', 0xA7AB):
+       case drm_edid_encode_panel_id('A', 'U', 'O', 0xE69B):
+               DRM_DEBUG_DRIVER("Clearing DPCD 0x317 on monitor with panel id %X\n", panel_id);
+               edid_caps->panel_patch.remove_sink_ext_caps = true;
+               break;
        default:
                return;
        }
index 7cdb1a8a0ba06b9e471d2faf0935d2b4e8e9d626..6a96810a477e6775f81437b405ac13dc1d892d83 100644 (file)
@@ -2386,7 +2386,13 @@ static enum bp_result get_vram_info_v30(
                return BP_RESULT_BADBIOSTABLE;
 
        info->num_chans = info_v30->channel_num;
-       info->dram_channel_width_bytes = (1 << info_v30->channel_width) / 8;
+       /* As suggested by VBIOS we should always use
+        * dram_channel_width_bytes = 2 when using VRAM
+        * table version 3.0. This is because the channel_width
+        * param in the VRAM info table is changed in 7000 series and
+        * no longer represents the memory channel width.
+        */
+       info->dram_channel_width_bytes = 2;
 
        return result;
 }
index ea7d60f9a9b45afb9500cda966ca8faf6dfbf985..6042a5a6a44f8c32187b2bea702892572f08ec57 100644 (file)
@@ -61,8 +61,12 @@ endif
 endif
 
 ifneq ($(CONFIG_FRAME_WARN),0)
+ifeq ($(filter y,$(CONFIG_KASAN)$(CONFIG_KCSAN)),y)
+frame_warn_flag := -Wframe-larger-than=3072
+else
 frame_warn_flag := -Wframe-larger-than=2048
 endif
+endif
 
 CFLAGS_$(AMDDALPATH)/dc/dml/display_mode_lib.o := $(dml_ccflags)
 CFLAGS_$(AMDDALPATH)/dc/dml/display_mode_vba.o := $(dml_ccflags)
index 59718ee33e5137e728921e286034f513505e8816..4d1336e5afc2c38c6bb5fa7dbbe363383f75e20d 100644 (file)
@@ -9447,12 +9447,12 @@ void dml_core_mode_programming(struct display_mode_lib_st *mode_lib, const struc
 
                // Output
                CalculateWatermarks_params->Watermark = &s->dummy_watermark; // Watermarks *Watermark
-               CalculateWatermarks_params->DRAMClockChangeSupport = &mode_lib->ms.support.DRAMClockChangeSupport[j];
+               CalculateWatermarks_params->DRAMClockChangeSupport = &mode_lib->ms.support.DRAMClockChangeSupport[0];
                CalculateWatermarks_params->MaxActiveDRAMClockChangeLatencySupported = &s->dummy_single_array[0][0]; // dml_float_t *MaxActiveDRAMClockChangeLatencySupported[]
                CalculateWatermarks_params->SubViewportLinesNeededInMALL = &mode_lib->ms.SubViewportLinesNeededInMALL[j]; // dml_uint_t SubViewportLinesNeededInMALL[]
-               CalculateWatermarks_params->FCLKChangeSupport = &mode_lib->ms.support.FCLKChangeSupport[j];
+               CalculateWatermarks_params->FCLKChangeSupport = &mode_lib->ms.support.FCLKChangeSupport[0];
                CalculateWatermarks_params->MaxActiveFCLKChangeLatencySupported = &s->dummy_single[0]; // dml_float_t *MaxActiveFCLKChangeLatencySupported
-               CalculateWatermarks_params->USRRetrainingSupport = &mode_lib->ms.support.USRRetrainingSupport[j];
+               CalculateWatermarks_params->USRRetrainingSupport = &mode_lib->ms.support.USRRetrainingSupport[0];
 
                CalculateWatermarksMALLUseAndDRAMSpeedChangeSupport(
                        &mode_lib->scratch,
index 0d1209f2cf313bb2b4244cab48ba808aa9dba027..1c5049e894e30e1640d5da41049c2cca7980d076 100644 (file)
@@ -1085,6 +1085,10 @@ struct gpu_metrics_v3_0 {
        uint16_t                        average_dram_reads;
        /* time filtered DRAM write bandwidth [MB/sec] */
        uint16_t                        average_dram_writes;
+       /* time filtered IPU read bandwidth [MB/sec] */
+       uint16_t                        average_ipu_reads;
+       /* time filtered IPU write bandwidth [MB/sec] */
+       uint16_t                        average_ipu_writes;
 
        /* Driver attached timestamp (in ns) */
        uint64_t                        system_clock_counter;
@@ -1104,6 +1108,8 @@ struct gpu_metrics_v3_0 {
        uint32_t                        average_all_core_power;
        /* calculated core power [mW] */
        uint16_t                        average_core_power[16];
+       /* time filtered total system power [mW] */
+       uint16_t                        average_sys_power;
        /* maximum IRM defined STAPM power limit [mW] */
        uint16_t                        stapm_power_limit;
        /* time filtered STAPM power limit [mW] */
@@ -1116,6 +1122,8 @@ struct gpu_metrics_v3_0 {
        uint16_t                        average_ipuclk_frequency;
        uint16_t                        average_fclk_frequency;
        uint16_t                        average_vclk_frequency;
+       uint16_t                        average_uclk_frequency;
+       uint16_t                        average_mpipu_frequency;
 
        /* Current clocks */
        /* target core frequency [MHz] */
@@ -1125,6 +1133,15 @@ struct gpu_metrics_v3_0 {
        /* GFXCLK frequency limit enforced on GFX [MHz] */
        uint16_t                        current_gfx_maxfreq;
 
+       /* Throttle Residency (ASIC dependent) */
+       uint32_t                        throttle_residency_prochot;
+       uint32_t                        throttle_residency_spl;
+       uint32_t                        throttle_residency_fppt;
+       uint32_t                        throttle_residency_sppt;
+       uint32_t                        throttle_residency_thm_core;
+       uint32_t                        throttle_residency_thm_gfx;
+       uint32_t                        throttle_residency_thm_soc;
+
        /* Metrics table alpha filter time constant [us] */
        uint32_t                        time_filter_alphavalue;
 };
index 23fa71cafb145fba9fba66274e2ddcb080e5be7d..f8b2e6cc2568886a797c5dbecac78486f76df6ed 100644 (file)
@@ -1408,6 +1408,16 @@ typedef enum {
        METRICS_PCIE_WIDTH,
        METRICS_CURR_FANPWM,
        METRICS_CURR_SOCKETPOWER,
+       METRICS_AVERAGE_VPECLK,
+       METRICS_AVERAGE_IPUCLK,
+       METRICS_AVERAGE_MPIPUCLK,
+       METRICS_THROTTLER_RESIDENCY_PROCHOT,
+       METRICS_THROTTLER_RESIDENCY_SPL,
+       METRICS_THROTTLER_RESIDENCY_FPPT,
+       METRICS_THROTTLER_RESIDENCY_SPPT,
+       METRICS_THROTTLER_RESIDENCY_THM_CORE,
+       METRICS_THROTTLER_RESIDENCY_THM_GFX,
+       METRICS_THROTTLER_RESIDENCY_THM_SOC,
 } MetricsMember_t;
 
 enum smu_cmn2asic_mapping_type {
index 22f88842a7fd21e9dd089c0896ff9b03b1876fd4..8f42771e1f0a2836c9cf874cfe3cc3e56658386e 100644 (file)
@@ -27,7 +27,7 @@
 // *** IMPORTANT ***
 // SMU TEAM: Always increment the interface version if
 // any structure is changed in this file
-#define PMFW_DRIVER_IF_VERSION 6
+#define PMFW_DRIVER_IF_VERSION 7
 
 typedef struct {
   int32_t value;
@@ -150,37 +150,50 @@ typedef struct {
 } DpmClocks_t;
 
 typedef struct {
-  uint16_t CoreFrequency[16];        //Target core frequency [MHz]
-  uint16_t CorePower[16];            //CAC calculated core power [mW]
-  uint16_t CoreTemperature[16];      //TSEN measured core temperature [centi-C]
-  uint16_t GfxTemperature;           //TSEN measured GFX temperature [centi-C]
-  uint16_t SocTemperature;           //TSEN measured SOC temperature [centi-C]
-  uint16_t StapmOpnLimit;            //Maximum IRM defined STAPM power limit [mW]
-  uint16_t StapmCurrentLimit;        //Time filtered STAPM power limit [mW]
-  uint16_t InfrastructureCpuMaxFreq; //CCLK frequency limit enforced on classic cores [MHz]
-  uint16_t InfrastructureGfxMaxFreq; //GFXCLK frequency limit enforced on GFX [MHz]
-  uint16_t SkinTemp;                 //Maximum skin temperature reported by APU and HS2 chassis sensors [centi-C]
-  uint16_t GfxclkFrequency;          //Time filtered target GFXCLK frequency [MHz]
-  uint16_t FclkFrequency;            //Time filtered target FCLK frequency [MHz]
-  uint16_t GfxActivity;              //Time filtered GFX busy % [0-100]
-  uint16_t SocclkFrequency;          //Time filtered target SOCCLK frequency [MHz]
-  uint16_t VclkFrequency;            //Time filtered target VCLK frequency [MHz]
-  uint16_t VcnActivity;              //Time filtered VCN busy % [0-100]
-  uint16_t VpeclkFrequency;          //Time filtered target VPECLK frequency [MHz]
-  uint16_t IpuclkFrequency;          //Time filtered target IPUCLK frequency [MHz]
-  uint16_t IpuBusy[8];               //Time filtered IPU per-column busy % [0-100]
-  uint16_t DRAMReads;                //Time filtered DRAM read bandwidth [MB/sec]
-  uint16_t DRAMWrites;               //Time filtered DRAM write bandwidth [MB/sec]
-  uint16_t CoreC0Residency[16];      //Time filtered per-core C0 residency % [0-100]
-  uint16_t IpuPower;                 //Time filtered IPU power [mW]
-  uint32_t ApuPower;                 //Time filtered APU power [mW]
-  uint32_t GfxPower;                 //Time filtered GFX power [mW]
-  uint32_t dGpuPower;                //Time filtered dGPU power [mW]
-  uint32_t SocketPower;              //Time filtered power used for PPT/STAPM [APU+dGPU] [mW]
-  uint32_t AllCorePower;             //Time filtered sum of core power across all cores in the socket [mW]
-  uint32_t FilterAlphaValue;         //Metrics table alpha filter time constant [us]
-  uint32_t MetricsCounter;           //Counter that is incremented on every metrics table update [PM_TIMER cycles]
-  uint32_t spare[16];
+  uint16_t CoreFrequency[16];          //Target core frequency [MHz]
+  uint16_t CorePower[16];              //CAC calculated core power [mW]
+  uint16_t CoreTemperature[16];        //TSEN measured core temperature [centi-C]
+  uint16_t GfxTemperature;             //TSEN measured GFX temperature [centi-C]
+  uint16_t SocTemperature;             //TSEN measured SOC temperature [centi-C]
+  uint16_t StapmOpnLimit;              //Maximum IRM defined STAPM power limit [mW]
+  uint16_t StapmCurrentLimit;          //Time filtered STAPM power limit [mW]
+  uint16_t InfrastructureCpuMaxFreq;   //CCLK frequency limit enforced on classic cores [MHz]
+  uint16_t InfrastructureGfxMaxFreq;   //GFXCLK frequency limit enforced on GFX [MHz]
+  uint16_t SkinTemp;                   //Maximum skin temperature reported by APU and HS2 chassis sensors [centi-C]
+  uint16_t GfxclkFrequency;            //Time filtered target GFXCLK frequency [MHz]
+  uint16_t FclkFrequency;              //Time filtered target FCLK frequency [MHz]
+  uint16_t GfxActivity;                //Time filtered GFX busy % [0-100]
+  uint16_t SocclkFrequency;            //Time filtered target SOCCLK frequency [MHz]
+  uint16_t VclkFrequency;              //Time filtered target VCLK frequency [MHz]
+  uint16_t VcnActivity;                //Time filtered VCN busy % [0-100]
+  uint16_t VpeclkFrequency;            //Time filtered target VPECLK frequency [MHz]
+  uint16_t IpuclkFrequency;            //Time filtered target IPUCLK frequency [MHz]
+  uint16_t IpuBusy[8];                 //Time filtered IPU per-column busy % [0-100]
+  uint16_t DRAMReads;                  //Time filtered DRAM read bandwidth [MB/sec]
+  uint16_t DRAMWrites;                 //Time filtered DRAM write bandwidth [MB/sec]
+  uint16_t CoreC0Residency[16];        //Time filtered per-core C0 residency % [0-100]
+  uint16_t IpuPower;                   //Time filtered IPU power [mW]
+  uint32_t ApuPower;                   //Time filtered APU power [mW]
+  uint32_t GfxPower;                   //Time filtered GFX power [mW]
+  uint32_t dGpuPower;                  //Time filtered dGPU power [mW]
+  uint32_t SocketPower;                //Time filtered power used for PPT/STAPM [APU+dGPU] [mW]
+  uint32_t AllCorePower;               //Time filtered sum of core power across all cores in the socket [mW]
+  uint32_t FilterAlphaValue;           //Metrics table alpha filter time constant [us]
+  uint32_t MetricsCounter;             //Counter that is incremented on every metrics table update [PM_TIMER cycles]
+  uint16_t MemclkFrequency;            //Time filtered target MEMCLK frequency [MHz]
+  uint16_t MpipuclkFrequency;          //Time filtered target MPIPUCLK frequency [MHz]
+  uint16_t IpuReads;                   //Time filtered IPU read bandwidth [MB/sec]
+  uint16_t IpuWrites;                  //Time filtered IPU write bandwidth [MB/sec]
+  uint32_t ThrottleResidency_PROCHOT;  //Counter that is incremented on every metrics table update when PROCHOT was engaged [PM_TIMER cycles]
+  uint32_t ThrottleResidency_SPL;      //Counter that is incremented on every metrics table update when SPL was engaged [PM_TIMER cycles]
+  uint32_t ThrottleResidency_FPPT;     //Counter that is incremented on every metrics table update when fast PPT was engaged [PM_TIMER cycles]
+  uint32_t ThrottleResidency_SPPT;     //Counter that is incremented on every metrics table update when slow PPT was engaged [PM_TIMER cycles]
+  uint32_t ThrottleResidency_THM_CORE; //Counter that is incremented on every metrics table update when CORE thermal throttling was engaged [PM_TIMER cycles]
+  uint32_t ThrottleResidency_THM_GFX;  //Counter that is incremented on every metrics table update when GFX thermal throttling was engaged [PM_TIMER cycles]
+  uint32_t ThrottleResidency_THM_SOC;  //Counter that is incremented on every metrics table update when SOC thermal throttling was engaged [PM_TIMER cycles]
+  uint16_t Psys;                       //Time filtered Psys power [mW]
+  uint16_t spare1;
+  uint32_t spare[6];
 } SmuMetrics_t;
 
 //ISP tile definitions
index 0e5a77c3c2e216362b2e5363f1ec25f62940ede3..900a2d9e6d85481abd728cbdd11c9fe66e826a09 100644 (file)
@@ -2593,13 +2593,20 @@ static bool mca_gfx_smu_bank_is_valid(const struct mca_ras_info *mca_ras, struct
 static bool mca_smu_bank_is_valid(const struct mca_ras_info *mca_ras, struct amdgpu_device *adev,
                                  enum amdgpu_mca_error_type type, struct mca_bank_entry *entry)
 {
+       struct smu_context *smu = adev->powerplay.pp_handle;
        uint32_t errcode, instlo;
 
        instlo = REG_GET_FIELD(entry->regs[MCA_REG_IDX_IPID], MCMP1_IPIDT0, InstanceIdLo);
        if (instlo != 0x03b30400)
                return false;
 
-       errcode = REG_GET_FIELD(entry->regs[MCA_REG_IDX_STATUS], MCMP1_STATUST0, ErrorCode);
+       if (!(adev->flags & AMD_IS_APU) && smu->smc_fw_version >= 0x00555600) {
+               errcode = MCA_REG__SYND__ERRORINFORMATION(entry->regs[MCA_REG_IDX_SYND]);
+               errcode &= 0xff;
+       } else {
+               errcode = REG_GET_FIELD(entry->regs[MCA_REG_IDX_STATUS], MCMP1_STATUST0, ErrorCode);
+       }
+
        return mca_smu_check_error_code(adev, mca_ras, errcode);
 }
 
index 03b38c3a9968431914912131c8a82794dca4c283..94ccdbfd709092ba24ceea84c8ea125e861e8544 100644 (file)
@@ -246,11 +246,20 @@ static int smu_v14_0_0_get_smu_metrics_data(struct smu_context *smu,
                *value = 0;
                break;
        case METRICS_AVERAGE_UCLK:
-               *value = 0;
+               *value = metrics->MemclkFrequency;
                break;
        case METRICS_AVERAGE_FCLK:
                *value = metrics->FclkFrequency;
                break;
+       case METRICS_AVERAGE_VPECLK:
+               *value = metrics->VpeclkFrequency;
+               break;
+       case METRICS_AVERAGE_IPUCLK:
+               *value = metrics->IpuclkFrequency;
+               break;
+       case METRICS_AVERAGE_MPIPUCLK:
+               *value = metrics->MpipuclkFrequency;
+               break;
        case METRICS_AVERAGE_GFXACTIVITY:
                *value = metrics->GfxActivity / 100;
                break;
@@ -270,8 +279,26 @@ static int smu_v14_0_0_get_smu_metrics_data(struct smu_context *smu,
                *value = metrics->SocTemperature / 100 *
                SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
                break;
-       case METRICS_THROTTLER_STATUS:
-               *value = 0;
+       case METRICS_THROTTLER_RESIDENCY_PROCHOT:
+               *value = metrics->ThrottleResidency_PROCHOT;
+               break;
+       case METRICS_THROTTLER_RESIDENCY_SPL:
+               *value = metrics->ThrottleResidency_SPL;
+               break;
+       case METRICS_THROTTLER_RESIDENCY_FPPT:
+               *value = metrics->ThrottleResidency_FPPT;
+               break;
+       case METRICS_THROTTLER_RESIDENCY_SPPT:
+               *value = metrics->ThrottleResidency_SPPT;
+               break;
+       case METRICS_THROTTLER_RESIDENCY_THM_CORE:
+               *value = metrics->ThrottleResidency_THM_CORE;
+               break;
+       case METRICS_THROTTLER_RESIDENCY_THM_GFX:
+               *value = metrics->ThrottleResidency_THM_GFX;
+               break;
+       case METRICS_THROTTLER_RESIDENCY_THM_SOC:
+               *value = metrics->ThrottleResidency_THM_SOC;
                break;
        case METRICS_VOLTAGE_VDDGFX:
                *value = 0;
@@ -498,6 +525,8 @@ static ssize_t smu_v14_0_0_get_gpu_metrics(struct smu_context *smu,
                sizeof(uint16_t) * 16);
        gpu_metrics->average_dram_reads = metrics.DRAMReads;
        gpu_metrics->average_dram_writes = metrics.DRAMWrites;
+       gpu_metrics->average_ipu_reads = metrics.IpuReads;
+       gpu_metrics->average_ipu_writes = metrics.IpuWrites;
 
        gpu_metrics->average_socket_power = metrics.SocketPower;
        gpu_metrics->average_ipu_power = metrics.IpuPower;
@@ -505,6 +534,7 @@ static ssize_t smu_v14_0_0_get_gpu_metrics(struct smu_context *smu,
        gpu_metrics->average_gfx_power = metrics.GfxPower;
        gpu_metrics->average_dgpu_power = metrics.dGpuPower;
        gpu_metrics->average_all_core_power = metrics.AllCorePower;
+       gpu_metrics->average_sys_power = metrics.Psys;
        memcpy(&gpu_metrics->average_core_power[0],
                &metrics.CorePower[0],
                sizeof(uint16_t) * 16);
@@ -515,6 +545,8 @@ static ssize_t smu_v14_0_0_get_gpu_metrics(struct smu_context *smu,
        gpu_metrics->average_fclk_frequency = metrics.FclkFrequency;
        gpu_metrics->average_vclk_frequency = metrics.VclkFrequency;
        gpu_metrics->average_ipuclk_frequency = metrics.IpuclkFrequency;
+       gpu_metrics->average_uclk_frequency = metrics.MemclkFrequency;
+       gpu_metrics->average_mpipu_frequency = metrics.MpipuclkFrequency;
 
        memcpy(&gpu_metrics->current_coreclk[0],
                &metrics.CoreFrequency[0],
@@ -522,6 +554,14 @@ static ssize_t smu_v14_0_0_get_gpu_metrics(struct smu_context *smu,
        gpu_metrics->current_core_maxfreq = metrics.InfrastructureCpuMaxFreq;
        gpu_metrics->current_gfx_maxfreq = metrics.InfrastructureGfxMaxFreq;
 
+       gpu_metrics->throttle_residency_prochot = metrics.ThrottleResidency_PROCHOT;
+       gpu_metrics->throttle_residency_spl = metrics.ThrottleResidency_SPL;
+       gpu_metrics->throttle_residency_fppt = metrics.ThrottleResidency_FPPT;
+       gpu_metrics->throttle_residency_sppt = metrics.ThrottleResidency_SPPT;
+       gpu_metrics->throttle_residency_thm_core = metrics.ThrottleResidency_THM_CORE;
+       gpu_metrics->throttle_residency_thm_gfx = metrics.ThrottleResidency_THM_GFX;
+       gpu_metrics->throttle_residency_thm_soc = metrics.ThrottleResidency_THM_SOC;
+
        gpu_metrics->time_filter_alphavalue = metrics.FilterAlphaValue;
        gpu_metrics->system_clock_counter = ktime_get_boottime_ns();
 
index ba82a1142adf730e9ce8ab31b45bf0eb62405504..3e6a4e2044c0eb8bf6e099dcc3a22e0fc5810c42 100644 (file)
@@ -313,6 +313,7 @@ config DRM_TOSHIBA_TC358768
        select REGMAP_I2C
        select DRM_PANEL
        select DRM_MIPI_DSI
+       select VIDEOMODE_HELPERS
        help
          Toshiba TC358768AXBG/TC358778XBG DSI bridge chip driver.
 
index 2444fc33dd7c77e2e512f80f086d422218b953e7..68ffcc0b00dca11f64e7839fdfc8933888acc053 100644 (file)
@@ -2012,7 +2012,7 @@ int drm_atomic_helper_commit(struct drm_device *dev,
                        return ret;
 
                drm_atomic_helper_async_commit(dev, state);
-               drm_atomic_helper_cleanup_planes(dev, state);
+               drm_atomic_helper_unprepare_planes(dev, state);
 
                return 0;
        }
@@ -2072,7 +2072,7 @@ int drm_atomic_helper_commit(struct drm_device *dev,
        return 0;
 
 err:
-       drm_atomic_helper_cleanup_planes(dev, state);
+       drm_atomic_helper_unprepare_planes(dev, state);
        return ret;
 }
 EXPORT_SYMBOL(drm_atomic_helper_commit);
@@ -2650,6 +2650,39 @@ fail_prepare_fb:
 }
 EXPORT_SYMBOL(drm_atomic_helper_prepare_planes);
 
+/**
+ * drm_atomic_helper_unprepare_planes - release plane resources on aborts
+ * @dev: DRM device
+ * @state: atomic state object with old state structures
+ *
+ * This function cleans up plane state, specifically framebuffers, from the
+ * atomic state. It undoes the effects of drm_atomic_helper_prepare_planes()
+ * when aborting an atomic commit. For cleaning up after a successful commit
+ * use drm_atomic_helper_cleanup_planes().
+ */
+void drm_atomic_helper_unprepare_planes(struct drm_device *dev,
+                                       struct drm_atomic_state *state)
+{
+       struct drm_plane *plane;
+       struct drm_plane_state *new_plane_state;
+       int i;
+
+       for_each_new_plane_in_state(state, plane, new_plane_state, i) {
+               const struct drm_plane_helper_funcs *funcs = plane->helper_private;
+
+               if (funcs->end_fb_access)
+                       funcs->end_fb_access(plane, new_plane_state);
+       }
+
+       for_each_new_plane_in_state(state, plane, new_plane_state, i) {
+               const struct drm_plane_helper_funcs *funcs = plane->helper_private;
+
+               if (funcs->cleanup_fb)
+                       funcs->cleanup_fb(plane, new_plane_state);
+       }
+}
+EXPORT_SYMBOL(drm_atomic_helper_unprepare_planes);
+
 static bool plane_crtc_active(const struct drm_plane_state *state)
 {
        return state->crtc && state->crtc->state->active;
@@ -2784,6 +2817,17 @@ void drm_atomic_helper_commit_planes(struct drm_device *dev,
 
                funcs->atomic_flush(crtc, old_state);
        }
+
+       /*
+        * Signal end of framebuffer access here before hw_done. After hw_done,
+        * a later commit might have already released the plane state.
+        */
+       for_each_old_plane_in_state(old_state, plane, old_plane_state, i) {
+               const struct drm_plane_helper_funcs *funcs = plane->helper_private;
+
+               if (funcs->end_fb_access)
+                       funcs->end_fb_access(plane, old_plane_state);
+       }
 }
 EXPORT_SYMBOL(drm_atomic_helper_commit_planes);
 
@@ -2911,40 +2955,22 @@ EXPORT_SYMBOL(drm_atomic_helper_disable_planes_on_crtc);
  * configuration. Hence the old configuration must be perserved in @old_state to
  * be able to call this function.
  *
- * This function must also be called on the new state when the atomic update
- * fails at any point after calling drm_atomic_helper_prepare_planes().
+ * This function may not be called on the new state when the atomic update
+ * fails at any point after calling drm_atomic_helper_prepare_planes(). Use
+ * drm_atomic_helper_unprepare_planes() in this case.
  */
 void drm_atomic_helper_cleanup_planes(struct drm_device *dev,
                                      struct drm_atomic_state *old_state)
 {
        struct drm_plane *plane;
-       struct drm_plane_state *old_plane_state, *new_plane_state;
+       struct drm_plane_state *old_plane_state;
        int i;
 
-       for_each_oldnew_plane_in_state(old_state, plane, old_plane_state, new_plane_state, i) {
+       for_each_old_plane_in_state(old_state, plane, old_plane_state, i) {
                const struct drm_plane_helper_funcs *funcs = plane->helper_private;
 
-               if (funcs->end_fb_access)
-                       funcs->end_fb_access(plane, new_plane_state);
-       }
-
-       for_each_oldnew_plane_in_state(old_state, plane, old_plane_state, new_plane_state, i) {
-               const struct drm_plane_helper_funcs *funcs;
-               struct drm_plane_state *plane_state;
-
-               /*
-                * This might be called before swapping when commit is aborted,
-                * in which case we have to cleanup the new state.
-                */
-               if (old_plane_state == plane->state)
-                       plane_state = new_plane_state;
-               else
-                       plane_state = old_plane_state;
-
-               funcs = plane->helper_private;
-
                if (funcs->cleanup_fb)
-                       funcs->cleanup_fb(plane, plane_state);
+                       funcs->cleanup_fb(plane, old_plane_state);
        }
 }
 EXPORT_SYMBOL(drm_atomic_helper_cleanup_planes);
index a971590b81323021cd697b8a71bc4686e2c40ca4..e2c7373f20c6b791f9706c1dad0758f363c63073 100644 (file)
@@ -107,18 +107,16 @@ int exynos_drm_register_dma(struct drm_device *drm, struct device *dev,
                return 0;
 
        if (!priv->mapping) {
-               void *mapping;
+               void *mapping = NULL;
 
                if (IS_ENABLED(CONFIG_ARM_DMA_USE_IOMMU))
                        mapping = arm_iommu_create_mapping(&platform_bus_type,
                                EXYNOS_DEV_ADDR_START, EXYNOS_DEV_ADDR_SIZE);
                else if (IS_ENABLED(CONFIG_IOMMU_DMA))
                        mapping = iommu_get_domain_for_dev(priv->dma_dev);
-               else
-                       mapping = ERR_PTR(-ENODEV);
 
-               if (IS_ERR(mapping))
-                       return PTR_ERR(mapping);
+               if (!mapping)
+                       return -ENODEV;
                priv->mapping = mapping;
        }
 
index f3aaa4ea3e68208b1f6bfccaf49a2d646e43ded1..dd9903eab563eee8537dfb731dca112f1dd53dea 100644 (file)
@@ -1861,6 +1861,8 @@ static int hdmi_bind(struct device *dev, struct device *master, void *data)
                return ret;
 
        crtc = exynos_drm_crtc_get_by_type(drm_dev, EXYNOS_DISPLAY_TYPE_HDMI);
+       if (IS_ERR(crtc))
+               return PTR_ERR(crtc);
        crtc->pipe_clk = &hdata->phy_clk;
 
        ret = hdmi_create_connector(encoder);
index c4585e445198d3a3f51c6398b3b14dbe8ba9adea..67143a0f518930d755385e18df6abb362680a6b5 100644 (file)
@@ -1440,6 +1440,13 @@ static void gen11_dsi_post_disable(struct intel_atomic_state *state,
 static enum drm_mode_status gen11_dsi_mode_valid(struct drm_connector *connector,
                                                 struct drm_display_mode *mode)
 {
+       struct drm_i915_private *i915 = to_i915(connector->dev);
+       enum drm_mode_status status;
+
+       status = intel_cpu_transcoder_mode_valid(i915, mode);
+       if (status != MODE_OK)
+               return status;
+
        /* FIXME: DSC? */
        return intel_dsi_mode_valid(connector, mode);
 }
index 913e5d230a4df9ae519cb626e2e515969d49cca3..6f6b348b8a40544f8cd0ccd301ce0fd0ba00b3f2 100644 (file)
@@ -348,8 +348,13 @@ intel_crt_mode_valid(struct drm_connector *connector,
        struct drm_device *dev = connector->dev;
        struct drm_i915_private *dev_priv = to_i915(dev);
        int max_dotclk = dev_priv->max_dotclk_freq;
+       enum drm_mode_status status;
        int max_clock;
 
+       status = intel_cpu_transcoder_mode_valid(dev_priv, mode);
+       if (status != MODE_OK)
+               return status;
+
        if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
                return MODE_NO_DBLESCAN;
 
index a2a806262c9e1f4e35c955ca40998fe70a56eb6e..63ba4d54a715290ce1128c67788ff3b19777b935 100644 (file)
@@ -906,12 +906,18 @@ static bool needs_async_flip_vtd_wa(const struct intel_crtc_state *crtc_state)
 static bool planes_enabling(const struct intel_crtc_state *old_crtc_state,
                            const struct intel_crtc_state *new_crtc_state)
 {
+       if (!new_crtc_state->hw.active)
+               return false;
+
        return is_enabling(active_planes, old_crtc_state, new_crtc_state);
 }
 
 static bool planes_disabling(const struct intel_crtc_state *old_crtc_state,
                             const struct intel_crtc_state *new_crtc_state)
 {
+       if (!old_crtc_state->hw.active)
+               return false;
+
        return is_disabling(active_planes, old_crtc_state, new_crtc_state);
 }
 
@@ -928,6 +934,9 @@ static bool vrr_params_changed(const struct intel_crtc_state *old_crtc_state,
 static bool vrr_enabling(const struct intel_crtc_state *old_crtc_state,
                         const struct intel_crtc_state *new_crtc_state)
 {
+       if (!new_crtc_state->hw.active)
+               return false;
+
        return is_enabling(vrr.enable, old_crtc_state, new_crtc_state) ||
                (new_crtc_state->vrr.enable &&
                 (new_crtc_state->update_m_n || new_crtc_state->update_lrr ||
@@ -937,6 +946,9 @@ static bool vrr_enabling(const struct intel_crtc_state *old_crtc_state,
 static bool vrr_disabling(const struct intel_crtc_state *old_crtc_state,
                          const struct intel_crtc_state *new_crtc_state)
 {
+       if (!old_crtc_state->hw.active)
+               return false;
+
        return is_disabling(vrr.enable, old_crtc_state, new_crtc_state) ||
                (old_crtc_state->vrr.enable &&
                 (new_crtc_state->update_m_n || new_crtc_state->update_lrr ||
@@ -7476,7 +7488,7 @@ int intel_atomic_commit(struct drm_device *dev, struct drm_atomic_state *_state,
                for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i)
                        intel_color_cleanup_commit(new_crtc_state);
 
-               drm_atomic_helper_cleanup_planes(dev, &state->base);
+               drm_atomic_helper_unprepare_planes(dev, &state->base);
                intel_runtime_pm_put(&dev_priv->runtime_pm, state->wakeref);
                return ret;
        }
@@ -7857,6 +7869,16 @@ enum drm_mode_status intel_mode_valid(struct drm_device *dev,
            mode->vtotal > vtotal_max)
                return MODE_V_ILLEGAL;
 
+       return MODE_OK;
+}
+
+enum drm_mode_status intel_cpu_transcoder_mode_valid(struct drm_i915_private *dev_priv,
+                                                    const struct drm_display_mode *mode)
+{
+       /*
+        * Additional transcoder timing limits,
+        * excluding BXT/GLK DSI transcoders.
+        */
        if (DISPLAY_VER(dev_priv) >= 5) {
                if (mode->hdisplay < 64 ||
                    mode->htotal - mode->hdisplay < 32)
index 0e5dffe8f0189ec5a57b74bd4fc4e23b5ede65df..a05c7e2b782eac9beedfddea4050a0b0c70e3ec4 100644 (file)
@@ -403,6 +403,9 @@ enum drm_mode_status
 intel_mode_valid_max_plane_size(struct drm_i915_private *dev_priv,
                                const struct drm_display_mode *mode,
                                bool bigjoiner);
+enum drm_mode_status
+intel_cpu_transcoder_mode_valid(struct drm_i915_private *i915,
+                               const struct drm_display_mode *mode);
 enum phy intel_port_to_phy(struct drm_i915_private *i915, enum port port);
 bool is_trans_port_sync_mode(const struct intel_crtc_state *state);
 bool is_trans_port_sync_master(const struct intel_crtc_state *state);
index 2852958dd4e75808523485633eb86d3e759d65df..b21bcd40f11100de9027a4509f618a3fa9a1d720 100644 (file)
@@ -1172,6 +1172,10 @@ intel_dp_mode_valid(struct drm_connector *_connector,
        enum drm_mode_status status;
        bool dsc = false, bigjoiner = false;
 
+       status = intel_cpu_transcoder_mode_valid(dev_priv, mode);
+       if (status != MODE_OK)
+               return status;
+
        if (mode->flags & DRM_MODE_FLAG_DBLCLK)
                return MODE_H_ILLEGAL;
 
index 851b312bd84494cca9e074bb5f3fb2dcf49472bf..aa10612626136d5f51d4eda2a7b2f002dd9983f6 100644 (file)
@@ -959,6 +959,10 @@ intel_dp_mst_mode_valid_ctx(struct drm_connector *connector,
                return 0;
        }
 
+       *status = intel_cpu_transcoder_mode_valid(dev_priv, mode);
+       if (*status != MODE_OK)
+               return 0;
+
        if (mode->flags & DRM_MODE_FLAG_DBLSCAN) {
                *status = MODE_NO_DBLESCAN;
                return 0;
@@ -993,6 +997,10 @@ intel_dp_mst_mode_valid_ctx(struct drm_connector *connector,
        if (intel_dp_need_bigjoiner(intel_dp, mode->hdisplay, target_clock)) {
                bigjoiner = true;
                max_dotclk *= 2;
+
+               /* TODO: add support for bigjoiner */
+               *status = MODE_CLOCK_HIGH;
+               return 0;
        }
 
        if (DISPLAY_VER(dev_priv) >= 10 &&
@@ -1027,11 +1035,15 @@ intel_dp_mst_mode_valid_ctx(struct drm_connector *connector,
         * Big joiner configuration needs DSC for TGL which is not true for
         * XE_LPD where uncompressed joiner is supported.
         */
-       if (DISPLAY_VER(dev_priv) < 13 && bigjoiner && !dsc)
-               return MODE_CLOCK_HIGH;
+       if (DISPLAY_VER(dev_priv) < 13 && bigjoiner && !dsc) {
+               *status = MODE_CLOCK_HIGH;
+               return 0;
+       }
 
-       if (mode_rate > max_rate && !dsc)
-               return MODE_CLOCK_HIGH;
+       if (mode_rate > max_rate && !dsc) {
+               *status = MODE_CLOCK_HIGH;
+               return 0;
+       }
 
        *status = intel_mode_valid_max_plane_size(dev_priv, mode, false);
        return 0;
index 78b6fe24dcd8bbdf1c70095320337852c3d096bb..7fd6280c54a79afa9d81517bb9c30283f7e0e987 100644 (file)
@@ -340,7 +340,7 @@ static int intel_dsb_dewake_scanline(const struct intel_crtc_state *crtc_state)
 }
 
 static void _intel_dsb_commit(struct intel_dsb *dsb, u32 ctrl,
-                             unsigned int dewake_scanline)
+                             int dewake_scanline)
 {
        struct intel_crtc *crtc = dsb->crtc;
        struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
index 55d6743374bdd64da887e8d58630abbffcea8ada..9111e9d46486d8920077eb2cbd3b01c09f911a16 100644 (file)
@@ -217,11 +217,17 @@ intel_dvo_mode_valid(struct drm_connector *_connector,
                     struct drm_display_mode *mode)
 {
        struct intel_connector *connector = to_intel_connector(_connector);
+       struct drm_i915_private *i915 = to_i915(connector->base.dev);
        struct intel_dvo *intel_dvo = intel_attached_dvo(connector);
        const struct drm_display_mode *fixed_mode =
                intel_panel_fixed_mode(connector, mode);
        int max_dotclk = to_i915(connector->base.dev)->max_dotclk_freq;
        int target_clock = mode->clock;
+       enum drm_mode_status status;
+
+       status = intel_cpu_transcoder_mode_valid(i915, mode);
+       if (status != MODE_OK)
+               return status;
 
        if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
                return MODE_NO_DBLESCAN;
index ac315f8e782017e04540e9e46e372066217f5e38..bfa456fa7d25c90144dda94733c1683940934b85 100644 (file)
@@ -1983,6 +1983,10 @@ intel_hdmi_mode_valid(struct drm_connector *connector,
        bool ycbcr_420_only;
        enum intel_output_format sink_format;
 
+       status = intel_cpu_transcoder_mode_valid(dev_priv, mode);
+       if (status != MODE_OK)
+               return status;
+
        if ((mode->flags & DRM_MODE_FLAG_3D_MASK) == DRM_MODE_FLAG_3D_FRAME_PACKING)
                clock *= 2;
 
index 2a4ca7e65775e5723077add76bab7bad1507752a..bcbdd1984fd9089577f208d4f17ddfc858a25b13 100644 (file)
@@ -389,11 +389,16 @@ intel_lvds_mode_valid(struct drm_connector *_connector,
                      struct drm_display_mode *mode)
 {
        struct intel_connector *connector = to_intel_connector(_connector);
+       struct drm_i915_private *i915 = to_i915(connector->base.dev);
        const struct drm_display_mode *fixed_mode =
                intel_panel_fixed_mode(connector, mode);
        int max_pixclk = to_i915(connector->base.dev)->max_dotclk_freq;
        enum drm_mode_status status;
 
+       status = intel_cpu_transcoder_mode_valid(i915, mode);
+       if (status != MODE_OK)
+               return status;
+
        if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
                return MODE_NO_DBLESCAN;
 
index a636f42ceae555bd2c34ec8746128273f3e2c00d..a9ac7d45d1f3324c2b327c9c217c262cac7f5e4d 100644 (file)
@@ -1921,13 +1921,19 @@ static enum drm_mode_status
 intel_sdvo_mode_valid(struct drm_connector *connector,
                      struct drm_display_mode *mode)
 {
+       struct drm_i915_private *i915 = to_i915(connector->dev);
        struct intel_sdvo *intel_sdvo = intel_attached_sdvo(to_intel_connector(connector));
        struct intel_sdvo_connector *intel_sdvo_connector =
                to_intel_sdvo_connector(connector);
-       int max_dotclk = to_i915(connector->dev)->max_dotclk_freq;
        bool has_hdmi_sink = intel_has_hdmi_sink(intel_sdvo_connector, connector->state);
+       int max_dotclk = i915->max_dotclk_freq;
+       enum drm_mode_status status;
        int clock = mode->clock;
 
+       status = intel_cpu_transcoder_mode_valid(i915, mode);
+       if (status != MODE_OK)
+               return status;
+
        if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
                return MODE_NO_DBLESCAN;
 
index 31a79fdfc8128485141b39accb07804f669fc7b6..2ee4f0d9585136e889732b59e7bd91e3498f7714 100644 (file)
@@ -958,8 +958,14 @@ static enum drm_mode_status
 intel_tv_mode_valid(struct drm_connector *connector,
                    struct drm_display_mode *mode)
 {
+       struct drm_i915_private *i915 = to_i915(connector->dev);
        const struct tv_mode *tv_mode = intel_tv_mode_find(connector->state);
-       int max_dotclk = to_i915(connector->dev)->max_dotclk_freq;
+       int max_dotclk = i915->max_dotclk_freq;
+       enum drm_mode_status status;
+
+       status = intel_cpu_transcoder_mode_valid(i915, mode);
+       if (status != MODE_OK)
+               return status;
 
        if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
                return MODE_NO_DBLESCAN;
index 55da627a8b8d222911cd49b1ca18437db2ee4bf4..f488394d3108e417cfb59ddbe6a12935e927639b 100644 (file)
@@ -1541,9 +1541,25 @@ static const struct drm_encoder_funcs intel_dsi_funcs = {
        .destroy = intel_dsi_encoder_destroy,
 };
 
+static enum drm_mode_status vlv_dsi_mode_valid(struct drm_connector *connector,
+                                              struct drm_display_mode *mode)
+{
+       struct drm_i915_private *i915 = to_i915(connector->dev);
+
+       if (IS_VALLEYVIEW(i915) || IS_CHERRYVIEW(i915)) {
+               enum drm_mode_status status;
+
+               status = intel_cpu_transcoder_mode_valid(i915, mode);
+               if (status != MODE_OK)
+                       return status;
+       }
+
+       return intel_dsi_mode_valid(connector, mode);
+}
+
 static const struct drm_connector_helper_funcs intel_dsi_connector_helper_funcs = {
        .get_modes = intel_dsi_get_modes,
-       .mode_valid = intel_dsi_mode_valid,
+       .mode_valid = vlv_dsi_mode_valid,
        .atomic_check = intel_digital_connector_atomic_check,
 };
 
index 7840b6428afbe468b2ad51ac2f59c3fc2c77a3e1..118807e38422b6fb69babfb410de64aa09cfb41c 100644 (file)
@@ -2474,7 +2474,7 @@ nv50_disp_atomic_commit(struct drm_device *dev,
 
 err_cleanup:
        if (ret)
-               drm_atomic_helper_cleanup_planes(dev, state);
+               drm_atomic_helper_unprepare_planes(dev, state);
 done:
        pm_runtime_put_autosuspend(dev->dev);
        return ret;
index 5a2f273d95c8cf0247980a3e8076b0aa2ba6495e..0e32e71e123f3726dfc005d78b139c010f476a82 100644 (file)
  * DEALINGS IN THE SOFTWARE.
  */
 
+/**
+ * msgqTxHeader -- TX queue data structure
+ * @version: the version of this structure, must be 0
+ * @size: the size of the entire queue, including this header
+ * @msgSize: the padded size of queue element, 16 is minimum
+ * @msgCount: the number of elements in this queue
+ * @writePtr: head index of this queue
+ * @flags: 1 = swap the RX pointers
+ * @rxHdrOff: offset of readPtr in this structure
+ * @entryOff: offset of beginning of queue (msgqRxHeader), relative to
+ *          beginning of this structure
+ *
+ * The command queue is a queue of RPCs that are sent from the driver to the
+ * GSP.  The status queue is a queue of messages/responses from GSP-RM to the
+ * driver.  Although the driver allocates memory for both queues, the command
+ * queue is owned by the driver and the status queue is owned by GSP-RM.  In
+ * addition, the headers of the two queues must not share the same 4K page.
+ *
+ * Each queue is prefixed with this data structure.  The idea is that a queue
+ * and its header are written to only by their owner.  That is, only the
+ * driver writes to the command queue and command queue header, and only the
+ * GSP writes to the status (receive) queue and its header.
+ *
+ * This is enforced by the concept of "swapping" the RX pointers.  This is
+ * why the 'flags' field must be set to 1.  'rxHdrOff' is how the GSP knows
+ * where the where the tail pointer of its status queue.
+ *
+ * When the driver writes a new RPC to the command queue, it updates writePtr.
+ * When it reads a new message from the status queue, it updates readPtr.  In
+ * this way, the GSP knows when a new command is in the queue (it polls
+ * writePtr) and it knows how much free space is in the status queue (it
+ * checks readPtr).  The driver never cares about how much free space is in
+ * the status queue.
+ *
+ * As usual, producers write to the head pointer, and consumers read from the
+ * tail pointer.  When head == tail, the queue is empty.
+ *
+ * So to summarize:
+ * command.writePtr = head of command queue
+ * command.readPtr = tail of status queue
+ * status.writePtr = head of status queue
+ * status.readPtr = tail of command queue
+ */
 typedef struct
 {
     NvU32 version;   // queue version
@@ -38,6 +81,14 @@ typedef struct
     NvU32 entryOff;  // Offset of entries from start of backing store.
 } msgqTxHeader;
 
+/**
+ * msgqRxHeader - RX queue data structure
+ * @readPtr: tail index of the other queue
+ *
+ * Although this is a separate struct, it could easily be merged into
+ * msgqTxHeader.  msgqTxHeader.rxHdrOff is simply the offset of readPtr
+ * from the beginning of msgqTxHeader.
+ */
 typedef struct
 {
     NvU32 readPtr; // message id of last message read
index f6725a5f5bfb8ade0295872731cbfea19d6c8857..44fb86841c058a1ef9961936fd1f4637059dce89 100644 (file)
@@ -1377,6 +1377,13 @@ r535_gsp_msg_post_event(void *priv, u32 fn, void *repv, u32 repc)
        return 0;
 }
 
+/**
+ * r535_gsp_msg_run_cpu_sequencer() -- process I/O commands from the GSP
+ *
+ * The GSP sequencer is a list of I/O commands that the GSP can send to
+ * the driver to perform for various purposes.  The most common usage is to
+ * perform a special mid-initialization reset.
+ */
 static int
 r535_gsp_msg_run_cpu_sequencer(void *priv, u32 fn, void *repv, u32 repc)
 {
@@ -1716,6 +1723,23 @@ r535_gsp_libos_id8(const char *name)
        return id;
 }
 
+/**
+ * create_pte_array() - creates a PTE array of a physically contiguous buffer
+ * @ptes: pointer to the array
+ * @addr: base address of physically contiguous buffer (GSP_PAGE_SIZE aligned)
+ * @size: size of the buffer
+ *
+ * GSP-RM sometimes expects physically-contiguous buffers to have an array of
+ * "PTEs" for each page in that buffer.  Although in theory that allows for
+ * the buffer to be physically discontiguous, GSP-RM does not currently
+ * support that.
+ *
+ * In this case, the PTEs are DMA addresses of each page of the buffer.  Since
+ * the buffer is physically contiguous, calculating all the PTEs is simple
+ * math.
+ *
+ * See memdescGetPhysAddrsForGpu()
+ */
 static void create_pte_array(u64 *ptes, dma_addr_t addr, size_t size)
 {
        unsigned int num_pages = DIV_ROUND_UP_ULL(size, GSP_PAGE_SIZE);
@@ -1725,6 +1749,35 @@ static void create_pte_array(u64 *ptes, dma_addr_t addr, size_t size)
                ptes[i] = (u64)addr + (i << GSP_PAGE_SHIFT);
 }
 
+/**
+ * r535_gsp_libos_init() -- create the libos arguments structure
+ *
+ * The logging buffers are byte queues that contain encoded printf-like
+ * messages from GSP-RM.  They need to be decoded by a special application
+ * that can parse the buffers.
+ *
+ * The 'loginit' buffer contains logs from early GSP-RM init and
+ * exception dumps.  The 'logrm' buffer contains the subsequent logs. Both are
+ * written to directly by GSP-RM and can be any multiple of GSP_PAGE_SIZE.
+ *
+ * The physical address map for the log buffer is stored in the buffer
+ * itself, starting with offset 1. Offset 0 contains the "put" pointer.
+ *
+ * The GSP only understands 4K pages (GSP_PAGE_SIZE), so even if the kernel is
+ * configured for a larger page size (e.g. 64K pages), we need to give
+ * the GSP an array of 4K pages. Fortunately, since the buffer is
+ * physically contiguous, it's simple math to calculate the addresses.
+ *
+ * The buffers must be a multiple of GSP_PAGE_SIZE.  GSP-RM also currently
+ * ignores the @kind field for LOGINIT, LOGINTR, and LOGRM, but expects the
+ * buffers to be physically contiguous anyway.
+ *
+ * The memory allocated for the arguments must remain until the GSP sends the
+ * init_done RPC.
+ *
+ * See _kgspInitLibosLoggingStructures (allocates memory for buffers)
+ * See kgspSetupLibosInitArgs_IMPL (creates pLibosInitArgs[] array)
+ */
 static int
 r535_gsp_libos_init(struct nvkm_gsp *gsp)
 {
@@ -1835,6 +1888,35 @@ nvkm_gsp_radix3_dtor(struct nvkm_gsp *gsp, struct nvkm_gsp_radix3 *rx3)
                nvkm_gsp_mem_dtor(gsp, &rx3->mem[i]);
 }
 
+/**
+ * nvkm_gsp_radix3_sg - build a radix3 table from a S/G list
+ *
+ * The GSP uses a three-level page table, called radix3, to map the firmware.
+ * Each 64-bit "pointer" in the table is either the bus address of an entry in
+ * the next table (for levels 0 and 1) or the bus address of the next page in
+ * the GSP firmware image itself.
+ *
+ * Level 0 contains a single entry in one page that points to the first page
+ * of level 1.
+ *
+ * Level 1, since it's also only one page in size, contains up to 512 entries,
+ * one for each page in Level 2.
+ *
+ * Level 2 can be up to 512 pages in size, and each of those entries points to
+ * the next page of the firmware image.  Since there can be up to 512*512
+ * pages, that limits the size of the firmware to 512*512*GSP_PAGE_SIZE = 1GB.
+ *
+ * Internally, the GSP has its window into system memory, but the base
+ * physical address of the aperture is not 0.  In fact, it varies depending on
+ * the GPU architecture.  Since the GPU is a PCI device, this window is
+ * accessed via DMA and is therefore bound by IOMMU translation.  The end
+ * result is that GSP-RM must translate the bus addresses in the table to GSP
+ * physical addresses.  All this should happen transparently.
+ *
+ * Returns 0 on success, or negative error code
+ *
+ * See kgspCreateRadix3_IMPL
+ */
 static int
 nvkm_gsp_radix3_sg(struct nvkm_device *device, struct sg_table *sgt, u64 size,
                   struct nvkm_gsp_radix3 *rx3)
index e34bc60764010f8307a01ce4fe21808bb99e5e43..8379e72d77ab2b81dc16c11400b8e35641a6e906 100644 (file)
@@ -31,7 +31,7 @@ tu102_vmm_flush(struct nvkm_vmm *vmm, int depth)
 
        type |= 0x00000001; /* PAGE_ALL */
        if (atomic_read(&vmm->engref[NVKM_SUBDEV_BAR]))
-               type |= 0x00000004; /* HUB_ONLY */
+               type |= 0x00000006; /* HUB_ONLY | ALL PDB (hack) */
 
        mutex_lock(&vmm->mmu->mutex);
 
index f59c82ea887013c6b4a333a01fc5c3e1444bbc04..2d30da38c2c3e44b833a9af53dd0cfd1b770d57a 100644 (file)
@@ -29,14 +29,20 @@ static void panfrost_devfreq_update_utilization(struct panfrost_devfreq *pfdevfr
 static int panfrost_devfreq_target(struct device *dev, unsigned long *freq,
                                   u32 flags)
 {
+       struct panfrost_device *ptdev = dev_get_drvdata(dev);
        struct dev_pm_opp *opp;
+       int err;
 
        opp = devfreq_recommended_opp(dev, freq, flags);
        if (IS_ERR(opp))
                return PTR_ERR(opp);
        dev_pm_opp_put(opp);
 
-       return dev_pm_opp_set_rate(dev, *freq);
+       err =  dev_pm_opp_set_rate(dev, *freq);
+       if (!err)
+               ptdev->pfdevfreq.current_frequency = *freq;
+
+       return err;
 }
 
 static void panfrost_devfreq_reset(struct panfrost_devfreq *pfdevfreq)
@@ -58,7 +64,6 @@ static int panfrost_devfreq_get_dev_status(struct device *dev,
        spin_lock_irqsave(&pfdevfreq->lock, irqflags);
 
        panfrost_devfreq_update_utilization(pfdevfreq);
-       pfdevfreq->current_frequency = status->current_frequency;
 
        status->total_time = ktime_to_ns(ktime_add(pfdevfreq->busy_time,
                                                   pfdevfreq->idle_time));
@@ -164,6 +169,14 @@ int panfrost_devfreq_init(struct panfrost_device *pfdev)
 
        panfrost_devfreq_profile.initial_freq = cur_freq;
 
+       /*
+        * We could wait until panfrost_devfreq_target() to set this value, but
+        * since the simple_ondemand governor works asynchronously, there's a
+        * chance by the time someone opens the device's fdinfo file, current
+        * frequency hasn't been updated yet, so let's just do an early set.
+        */
+       pfdevfreq->current_frequency = cur_freq;
+
        /*
         * Set the recommend OPP this will enable and configure the regulator
         * if any and will avoid a switch off by regulator_late_cleanup()
index 0cf64456e29a4f74cc21e8fa3e57772e4eb506ee..d47b40b82b0bc4d189a2fa6772aaf3a91ee54c18 100644 (file)
@@ -200,7 +200,7 @@ static enum drm_gem_object_status panfrost_gem_status(struct drm_gem_object *obj
        struct panfrost_gem_object *bo = to_panfrost_bo(obj);
        enum drm_gem_object_status res = 0;
 
-       if (bo->base.pages)
+       if (bo->base.base.import_attach || bo->base.pages)
                res |= DRM_GEM_OBJECT_RESIDENT;
 
        if (bo->base.madv == PANFROST_MADV_DONTNEED)
index 8db740214ffda93090e832e7e6f2cbaa36d79ef1..703666b95bf49b1b6cc3ec349e067ee82bcf178d 100644 (file)
@@ -31,6 +31,7 @@
 #define POWER_METER_CAN_NOTIFY (1 << 3)
 #define POWER_METER_IS_BATTERY (1 << 8)
 #define UNKNOWN_HYSTERESIS     0xFFFFFFFF
+#define UNKNOWN_POWER          0xFFFFFFFF
 
 #define METER_NOTIFY_CONFIG    0x80
 #define METER_NOTIFY_TRIP      0x81
@@ -348,6 +349,9 @@ static ssize_t show_power(struct device *dev,
        update_meter(resource);
        mutex_unlock(&resource->lock);
 
+       if (resource->power == UNKNOWN_POWER)
+               return -ENODATA;
+
        return sprintf(buf, "%llu\n", resource->power * 1000);
 }
 
index 904890598c116b9de1bac58e8d7a68e87aa1a8fc..2c7c92272fe3998a138b864077a8117d43a9470d 100644 (file)
@@ -899,7 +899,23 @@ static struct hid_driver corsairpsu_driver = {
        .reset_resume   = corsairpsu_resume,
 #endif
 };
-module_hid_driver(corsairpsu_driver);
+
+static int __init corsair_init(void)
+{
+       return hid_register_driver(&corsairpsu_driver);
+}
+
+static void __exit corsair_exit(void)
+{
+       hid_unregister_driver(&corsairpsu_driver);
+}
+
+/*
+ * With module_init() the driver would load before the HID bus when
+ * built-in, so use late_initcall() instead.
+ */
+late_initcall(corsair_init);
+module_exit(corsair_exit);
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Wilken Gottwalt <wilken.gottwalt@posteo.net>");
index bd63c61129a94aa85eb46d83b60e89309b9ebe62..fc53fdcb2b6caad55b78b87e7289210aa8e46d47 100644 (file)
@@ -373,7 +373,7 @@ static int ltc2991_init(struct ltc2991_state *st)
                           LTC2991_REPEAT_ACQ_EN);
        if (ret)
                return dev_err_probe(st->dev, ret,
-                                    "Error: Failed to set contiuous mode.\n");
+                                    "Error: Failed to set continuous mode.\n");
 
        /* Enable all channels and trigger conversions */
        return regmap_write(st->regmap, LTC2991_CH_EN_TRIGGER,
index fd1fed1a797cd4ed2ae14b98dc09088cde292e4b..a1ce6514566912424c42a87af8e255da7fff29d1 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/i2c.h>
 #include <linux/mutex.h>
 #include <linux/regmap.h>
+#include <linux/regulator/consumer.h>
 
 #define MAX31827_T_REG                 0x0
 #define MAX31827_CONFIGURATION_REG     0x2
index 428c77b5fce5a2a01967c40b47d01287994a554b..7caf387eb1449fd2148256d3711475a2b858c951 100644 (file)
@@ -161,13 +161,13 @@ static int kraken2_probe(struct hid_device *hdev,
        ret = hid_hw_start(hdev, HID_CONNECT_HIDRAW);
        if (ret) {
                hid_err(hdev, "hid hw start failed with %d\n", ret);
-               goto fail_and_stop;
+               return ret;
        }
 
        ret = hid_hw_open(hdev);
        if (ret) {
                hid_err(hdev, "hid hw open failed with %d\n", ret);
-               goto fail_and_close;
+               goto fail_and_stop;
        }
 
        priv->hwmon_dev = hwmon_device_register_with_info(&hdev->dev, "kraken2",
index 59d3a07300d934484e11cf3a15f68543e11e168a..873630c111c1fc70a5297f101a67a83090f7f9ff 100644 (file)
@@ -571,7 +571,7 @@ iommufd_device_auto_get_domain(struct iommufd_device *idev,
                        continue;
                destroy_hwpt = (*do_attach)(idev, hwpt);
                if (IS_ERR(destroy_hwpt)) {
-                       iommufd_put_object(&hwpt->obj);
+                       iommufd_put_object(idev->ictx, &hwpt->obj);
                        /*
                         * -EINVAL means the domain is incompatible with the
                         * device. Other error codes should propagate to
@@ -583,7 +583,7 @@ iommufd_device_auto_get_domain(struct iommufd_device *idev,
                        goto out_unlock;
                }
                *pt_id = hwpt->obj.id;
-               iommufd_put_object(&hwpt->obj);
+               iommufd_put_object(idev->ictx, &hwpt->obj);
                goto out_unlock;
        }
 
@@ -652,7 +652,7 @@ static int iommufd_device_change_pt(struct iommufd_device *idev, u32 *pt_id,
                destroy_hwpt = ERR_PTR(-EINVAL);
                goto out_put_pt_obj;
        }
-       iommufd_put_object(pt_obj);
+       iommufd_put_object(idev->ictx, pt_obj);
 
        /* This destruction has to be after we unlock everything */
        if (destroy_hwpt)
@@ -660,7 +660,7 @@ static int iommufd_device_change_pt(struct iommufd_device *idev, u32 *pt_id,
        return 0;
 
 out_put_pt_obj:
-       iommufd_put_object(pt_obj);
+       iommufd_put_object(idev->ictx, pt_obj);
        return PTR_ERR(destroy_hwpt);
 }
 
@@ -792,7 +792,7 @@ static int iommufd_access_change_ioas_id(struct iommufd_access *access, u32 id)
        if (IS_ERR(ioas))
                return PTR_ERR(ioas);
        rc = iommufd_access_change_ioas(access, ioas);
-       iommufd_put_object(&ioas->obj);
+       iommufd_put_object(access->ictx, &ioas->obj);
        return rc;
 }
 
@@ -941,7 +941,7 @@ void iommufd_access_notify_unmap(struct io_pagetable *iopt, unsigned long iova,
 
                access->ops->unmap(access->data, iova, length);
 
-               iommufd_put_object(&access->obj);
+               iommufd_put_object(access->ictx, &access->obj);
                xa_lock(&ioas->iopt.access_list);
        }
        xa_unlock(&ioas->iopt.access_list);
@@ -1243,6 +1243,6 @@ int iommufd_get_hw_info(struct iommufd_ucmd *ucmd)
 out_free:
        kfree(data);
 out_put:
-       iommufd_put_object(&idev->obj);
+       iommufd_put_object(ucmd->ictx, &idev->obj);
        return rc;
 }
index 2abbeafdbd22d86019f665662f30fb367c40bd2e..cbb5df0a6c32f835b50535a84bde3f44bfb4d6db 100644 (file)
@@ -318,9 +318,9 @@ out_unlock:
        if (ioas)
                mutex_unlock(&ioas->mutex);
 out_put_pt:
-       iommufd_put_object(pt_obj);
+       iommufd_put_object(ucmd->ictx, pt_obj);
 out_put_idev:
-       iommufd_put_object(&idev->obj);
+       iommufd_put_object(ucmd->ictx, &idev->obj);
        return rc;
 }
 
@@ -345,7 +345,7 @@ int iommufd_hwpt_set_dirty_tracking(struct iommufd_ucmd *ucmd)
        rc = iopt_set_dirty_tracking(&ioas->iopt, hwpt_paging->common.domain,
                                     enable);
 
-       iommufd_put_object(&hwpt_paging->common.obj);
+       iommufd_put_object(ucmd->ictx, &hwpt_paging->common.obj);
        return rc;
 }
 
@@ -368,6 +368,6 @@ int iommufd_hwpt_get_dirty_bitmap(struct iommufd_ucmd *ucmd)
        rc = iopt_read_and_clear_dirty_data(
                &ioas->iopt, hwpt_paging->common.domain, cmd->flags, cmd);
 
-       iommufd_put_object(&hwpt_paging->common.obj);
+       iommufd_put_object(ucmd->ictx, &hwpt_paging->common.obj);
        return rc;
 }
index d5624577f79f1b69940a4006b6bf092c04ea97a5..74224827654815fbe16ea0da18128ca470c15ffd 100644 (file)
@@ -105,7 +105,7 @@ int iommufd_ioas_iova_ranges(struct iommufd_ucmd *ucmd)
                rc = -EMSGSIZE;
 out_put:
        up_read(&ioas->iopt.iova_rwsem);
-       iommufd_put_object(&ioas->obj);
+       iommufd_put_object(ucmd->ictx, &ioas->obj);
        return rc;
 }
 
@@ -175,7 +175,7 @@ out_free:
                interval_tree_remove(node, &allowed_iova);
                kfree(container_of(node, struct iopt_allowed, node));
        }
-       iommufd_put_object(&ioas->obj);
+       iommufd_put_object(ucmd->ictx, &ioas->obj);
        return rc;
 }
 
@@ -228,7 +228,7 @@ int iommufd_ioas_map(struct iommufd_ucmd *ucmd)
        cmd->iova = iova;
        rc = iommufd_ucmd_respond(ucmd, sizeof(*cmd));
 out_put:
-       iommufd_put_object(&ioas->obj);
+       iommufd_put_object(ucmd->ictx, &ioas->obj);
        return rc;
 }
 
@@ -258,7 +258,7 @@ int iommufd_ioas_copy(struct iommufd_ucmd *ucmd)
                return PTR_ERR(src_ioas);
        rc = iopt_get_pages(&src_ioas->iopt, cmd->src_iova, cmd->length,
                            &pages_list);
-       iommufd_put_object(&src_ioas->obj);
+       iommufd_put_object(ucmd->ictx, &src_ioas->obj);
        if (rc)
                return rc;
 
@@ -279,7 +279,7 @@ int iommufd_ioas_copy(struct iommufd_ucmd *ucmd)
        cmd->dst_iova = iova;
        rc = iommufd_ucmd_respond(ucmd, sizeof(*cmd));
 out_put_dst:
-       iommufd_put_object(&dst_ioas->obj);
+       iommufd_put_object(ucmd->ictx, &dst_ioas->obj);
 out_pages:
        iopt_free_pages_list(&pages_list);
        return rc;
@@ -315,7 +315,7 @@ int iommufd_ioas_unmap(struct iommufd_ucmd *ucmd)
        rc = iommufd_ucmd_respond(ucmd, sizeof(*cmd));
 
 out_put:
-       iommufd_put_object(&ioas->obj);
+       iommufd_put_object(ucmd->ictx, &ioas->obj);
        return rc;
 }
 
@@ -393,6 +393,6 @@ int iommufd_ioas_option(struct iommufd_ucmd *ucmd)
                rc = -EOPNOTSUPP;
        }
 
-       iommufd_put_object(&ioas->obj);
+       iommufd_put_object(ucmd->ictx, &ioas->obj);
        return rc;
 }
index a74cfefffbc6c5045c7b22063f66978f1f275e59..abae041e256f7ed1a0a6fcc68a48087098effc6b 100644 (file)
@@ -21,6 +21,7 @@ struct iommufd_ctx {
        struct file *file;
        struct xarray objects;
        struct xarray groups;
+       wait_queue_head_t destroy_wait;
 
        u8 account_mode;
        /* Compatibility with VFIO no iommu */
@@ -135,7 +136,7 @@ enum iommufd_object_type {
 
 /* Base struct for all objects with a userspace ID handle. */
 struct iommufd_object {
-       struct rw_semaphore destroy_rwsem;
+       refcount_t shortterm_users;
        refcount_t users;
        enum iommufd_object_type type;
        unsigned int id;
@@ -143,10 +144,15 @@ struct iommufd_object {
 
 static inline bool iommufd_lock_obj(struct iommufd_object *obj)
 {
-       if (!down_read_trylock(&obj->destroy_rwsem))
+       if (!refcount_inc_not_zero(&obj->users))
                return false;
-       if (!refcount_inc_not_zero(&obj->users)) {
-               up_read(&obj->destroy_rwsem);
+       if (!refcount_inc_not_zero(&obj->shortterm_users)) {
+               /*
+                * If the caller doesn't already have a ref on obj this must be
+                * called under the xa_lock. Otherwise the caller is holding a
+                * ref on users. Thus it cannot be one before this decrement.
+                */
+               refcount_dec(&obj->users);
                return false;
        }
        return true;
@@ -154,10 +160,16 @@ static inline bool iommufd_lock_obj(struct iommufd_object *obj)
 
 struct iommufd_object *iommufd_get_object(struct iommufd_ctx *ictx, u32 id,
                                          enum iommufd_object_type type);
-static inline void iommufd_put_object(struct iommufd_object *obj)
+static inline void iommufd_put_object(struct iommufd_ctx *ictx,
+                                     struct iommufd_object *obj)
 {
+       /*
+        * Users first, then shortterm so that REMOVE_WAIT_SHORTTERM never sees
+        * a spurious !0 users with a 0 shortterm_users.
+        */
        refcount_dec(&obj->users);
-       up_read(&obj->destroy_rwsem);
+       if (refcount_dec_and_test(&obj->shortterm_users))
+               wake_up_interruptible_all(&ictx->destroy_wait);
 }
 
 void iommufd_object_abort(struct iommufd_ctx *ictx, struct iommufd_object *obj);
@@ -165,17 +177,49 @@ void iommufd_object_abort_and_destroy(struct iommufd_ctx *ictx,
                                      struct iommufd_object *obj);
 void iommufd_object_finalize(struct iommufd_ctx *ictx,
                             struct iommufd_object *obj);
-void __iommufd_object_destroy_user(struct iommufd_ctx *ictx,
-                                  struct iommufd_object *obj, bool allow_fail);
+
+enum {
+       REMOVE_WAIT_SHORTTERM = 1,
+};
+int iommufd_object_remove(struct iommufd_ctx *ictx,
+                         struct iommufd_object *to_destroy, u32 id,
+                         unsigned int flags);
+
+/*
+ * The caller holds a users refcount and wants to destroy the object. At this
+ * point the caller has no shortterm_users reference and at least the xarray
+ * will be holding one.
+ */
 static inline void iommufd_object_destroy_user(struct iommufd_ctx *ictx,
                                               struct iommufd_object *obj)
 {
-       __iommufd_object_destroy_user(ictx, obj, false);
+       int ret;
+
+       ret = iommufd_object_remove(ictx, obj, obj->id, REMOVE_WAIT_SHORTTERM);
+
+       /*
+        * If there is a bug and we couldn't destroy the object then we did put
+        * back the caller's users refcount and will eventually try to free it
+        * again during close.
+        */
+       WARN_ON(ret);
 }
-static inline void iommufd_object_deref_user(struct iommufd_ctx *ictx,
-                                            struct iommufd_object *obj)
+
+/*
+ * The HWPT allocated by autodomains is used in possibly many devices and
+ * is automatically destroyed when its refcount reaches zero.
+ *
+ * If userspace uses the HWPT manually, even for a short term, then it will
+ * disrupt this refcounting and the auto-free in the kernel will not work.
+ * Userspace that tries to use the automatically allocated HWPT must be careful
+ * to ensure that it is consistently destroyed, eg by not racing accesses
+ * and by not attaching an automatic HWPT to a device manually.
+ */
+static inline void
+iommufd_object_put_and_try_destroy(struct iommufd_ctx *ictx,
+                                  struct iommufd_object *obj)
 {
-       __iommufd_object_destroy_user(ictx, obj, true);
+       iommufd_object_remove(ictx, obj, obj->id, 0);
 }
 
 struct iommufd_object *_iommufd_object_alloc(struct iommufd_ctx *ictx,
@@ -311,7 +355,7 @@ static inline void iommufd_hw_pagetable_put(struct iommufd_ctx *ictx,
                lockdep_assert_not_held(&hwpt_paging->ioas->mutex);
 
                if (hwpt_paging->auto_domain) {
-                       iommufd_object_deref_user(ictx, &hwpt->obj);
+                       iommufd_object_put_and_try_destroy(ictx, &hwpt->obj);
                        return;
                }
        }
index 45b9d40773b13a4255c3d6114240fd7e2a469eef..c9091e46d208abeea14aea1c649a016c39a077ba 100644 (file)
@@ -33,7 +33,6 @@ struct iommufd_object *_iommufd_object_alloc(struct iommufd_ctx *ictx,
                                             size_t size,
                                             enum iommufd_object_type type)
 {
-       static struct lock_class_key obj_keys[IOMMUFD_OBJ_MAX];
        struct iommufd_object *obj;
        int rc;
 
@@ -41,15 +40,8 @@ struct iommufd_object *_iommufd_object_alloc(struct iommufd_ctx *ictx,
        if (!obj)
                return ERR_PTR(-ENOMEM);
        obj->type = type;
-       /*
-        * In most cases the destroy_rwsem is obtained with try so it doesn't
-        * interact with lockdep, however on destroy we have to sleep. This
-        * means if we have to destroy an object while holding a get on another
-        * object it triggers lockdep. Using one locking class per object type
-        * is a simple and reasonable way to avoid this.
-        */
-       __init_rwsem(&obj->destroy_rwsem, "iommufd_object::destroy_rwsem",
-                    &obj_keys[type]);
+       /* Starts out bias'd by 1 until it is removed from the xarray */
+       refcount_set(&obj->shortterm_users, 1);
        refcount_set(&obj->users, 1);
 
        /*
@@ -129,92 +121,113 @@ struct iommufd_object *iommufd_get_object(struct iommufd_ctx *ictx, u32 id,
        return obj;
 }
 
+static int iommufd_object_dec_wait_shortterm(struct iommufd_ctx *ictx,
+                                            struct iommufd_object *to_destroy)
+{
+       if (refcount_dec_and_test(&to_destroy->shortterm_users))
+               return 0;
+
+       if (wait_event_timeout(ictx->destroy_wait,
+                               refcount_read(&to_destroy->shortterm_users) ==
+                                       0,
+                               msecs_to_jiffies(10000)))
+               return 0;
+
+       pr_crit("Time out waiting for iommufd object to become free\n");
+       refcount_inc(&to_destroy->shortterm_users);
+       return -EBUSY;
+}
+
 /*
  * Remove the given object id from the xarray if the only reference to the
- * object is held by the xarray. The caller must call ops destroy().
+ * object is held by the xarray.
  */
-static struct iommufd_object *iommufd_object_remove(struct iommufd_ctx *ictx,
-                                                   u32 id, bool extra_put)
+int iommufd_object_remove(struct iommufd_ctx *ictx,
+                         struct iommufd_object *to_destroy, u32 id,
+                         unsigned int flags)
 {
        struct iommufd_object *obj;
        XA_STATE(xas, &ictx->objects, id);
-
-       xa_lock(&ictx->objects);
-       obj = xas_load(&xas);
-       if (xa_is_zero(obj) || !obj) {
-               obj = ERR_PTR(-ENOENT);
-               goto out_xa;
-       }
+       bool zerod_shortterm = false;
+       int ret;
 
        /*
-        * If the caller is holding a ref on obj we put it here under the
-        * spinlock.
+        * The purpose of the shortterm_users is to ensure deterministic
+        * destruction of objects used by external drivers and destroyed by this
+        * function. Any temporary increment of the refcount must increment
+        * shortterm_users, such as during ioctl execution.
         */
-       if (extra_put)
+       if (flags & REMOVE_WAIT_SHORTTERM) {
+               ret = iommufd_object_dec_wait_shortterm(ictx, to_destroy);
+               if (ret) {
+                       /*
+                        * We have a bug. Put back the callers reference and
+                        * defer cleaning this object until close.
+                        */
+                       refcount_dec(&to_destroy->users);
+                       return ret;
+               }
+               zerod_shortterm = true;
+       }
+
+       xa_lock(&ictx->objects);
+       obj = xas_load(&xas);
+       if (to_destroy) {
+               /*
+                * If the caller is holding a ref on obj we put it here under
+                * the spinlock.
+                */
                refcount_dec(&obj->users);
 
+               if (WARN_ON(obj != to_destroy)) {
+                       ret = -ENOENT;
+                       goto err_xa;
+               }
+       } else if (xa_is_zero(obj) || !obj) {
+               ret = -ENOENT;
+               goto err_xa;
+       }
+
        if (!refcount_dec_if_one(&obj->users)) {
-               obj = ERR_PTR(-EBUSY);
-               goto out_xa;
+               ret = -EBUSY;
+               goto err_xa;
        }
 
        xas_store(&xas, NULL);
        if (ictx->vfio_ioas == container_of(obj, struct iommufd_ioas, obj))
                ictx->vfio_ioas = NULL;
-
-out_xa:
        xa_unlock(&ictx->objects);
 
-       /* The returned object reference count is zero */
-       return obj;
-}
-
-/*
- * The caller holds a users refcount and wants to destroy the object. Returns
- * true if the object was destroyed. In all cases the caller no longer has a
- * reference on obj.
- */
-void __iommufd_object_destroy_user(struct iommufd_ctx *ictx,
-                                  struct iommufd_object *obj, bool allow_fail)
-{
-       struct iommufd_object *ret;
-
        /*
-        * The purpose of the destroy_rwsem is to ensure deterministic
-        * destruction of objects used by external drivers and destroyed by this
-        * function. Any temporary increment of the refcount must hold the read
-        * side of this, such as during ioctl execution.
-        */
-       down_write(&obj->destroy_rwsem);
-       ret = iommufd_object_remove(ictx, obj->id, true);
-       up_write(&obj->destroy_rwsem);
-
-       if (allow_fail && IS_ERR(ret))
-               return;
-
-       /*
-        * If there is a bug and we couldn't destroy the object then we did put
-        * back the caller's refcount and will eventually try to free it again
-        * during close.
+        * Since users is zero any positive users_shortterm must be racing
+        * iommufd_put_object(), or we have a bug.
         */
-       if (WARN_ON(IS_ERR(ret)))
-               return;
+       if (!zerod_shortterm) {
+               ret = iommufd_object_dec_wait_shortterm(ictx, obj);
+               if (WARN_ON(ret))
+                       return ret;
+       }
 
        iommufd_object_ops[obj->type].destroy(obj);
        kfree(obj);
+       return 0;
+
+err_xa:
+       if (zerod_shortterm) {
+               /* Restore the xarray owned reference */
+               refcount_set(&obj->shortterm_users, 1);
+       }
+       xa_unlock(&ictx->objects);
+
+       /* The returned object reference count is zero */
+       return ret;
 }
 
 static int iommufd_destroy(struct iommufd_ucmd *ucmd)
 {
        struct iommu_destroy *cmd = ucmd->cmd;
-       struct iommufd_object *obj;
 
-       obj = iommufd_object_remove(ucmd->ictx, cmd->id, false);
-       if (IS_ERR(obj))
-               return PTR_ERR(obj);
-       iommufd_object_ops[obj->type].destroy(obj);
-       kfree(obj);
-       return 0;
+       return iommufd_object_remove(ucmd->ictx, NULL, cmd->id, 0);
 }
 
 static int iommufd_fops_open(struct inode *inode, struct file *filp)
@@ -238,6 +251,7 @@ static int iommufd_fops_open(struct inode *inode, struct file *filp)
        xa_init_flags(&ictx->objects, XA_FLAGS_ALLOC1 | XA_FLAGS_ACCOUNT);
        xa_init(&ictx->groups);
        ictx->file = filp;
+       init_waitqueue_head(&ictx->destroy_wait);
        filp->private_data = ictx;
        return 0;
 }
index 5d93434003d8ad666af55e212372e37b81c06895..022ef8f55088a6b1e7d452ad4260510cca5bb303 100644 (file)
@@ -86,7 +86,7 @@ void iommufd_test_syz_conv_iova_id(struct iommufd_ucmd *ucmd,
        if (IS_ERR(ioas))
                return;
        *iova = iommufd_test_syz_conv_iova(&ioas->iopt, iova);
-       iommufd_put_object(&ioas->obj);
+       iommufd_put_object(ucmd->ictx, &ioas->obj);
 }
 
 struct mock_iommu_domain {
@@ -500,7 +500,7 @@ get_md_pagetable(struct iommufd_ucmd *ucmd, u32 mockpt_id,
                return hwpt;
        if (hwpt->domain->type != IOMMU_DOMAIN_UNMANAGED ||
            hwpt->domain->ops != mock_ops.default_domain_ops) {
-               iommufd_put_object(&hwpt->obj);
+               iommufd_put_object(ucmd->ictx, &hwpt->obj);
                return ERR_PTR(-EINVAL);
        }
        *mock = container_of(hwpt->domain, struct mock_iommu_domain, domain);
@@ -518,7 +518,7 @@ get_md_pagetable_nested(struct iommufd_ucmd *ucmd, u32 mockpt_id,
                return hwpt;
        if (hwpt->domain->type != IOMMU_DOMAIN_NESTED ||
            hwpt->domain->ops != &domain_nested_ops) {
-               iommufd_put_object(&hwpt->obj);
+               iommufd_put_object(ucmd->ictx, &hwpt->obj);
                return ERR_PTR(-EINVAL);
        }
        *mock_nested = container_of(hwpt->domain,
@@ -681,7 +681,7 @@ static int iommufd_test_mock_domain_replace(struct iommufd_ucmd *ucmd,
        rc = iommufd_ucmd_respond(ucmd, sizeof(*cmd));
 
 out_dev_obj:
-       iommufd_put_object(dev_obj);
+       iommufd_put_object(ucmd->ictx, dev_obj);
        return rc;
 }
 
@@ -699,7 +699,7 @@ static int iommufd_test_add_reserved(struct iommufd_ucmd *ucmd,
        down_write(&ioas->iopt.iova_rwsem);
        rc = iopt_reserve_iova(&ioas->iopt, start, start + length - 1, NULL);
        up_write(&ioas->iopt.iova_rwsem);
-       iommufd_put_object(&ioas->obj);
+       iommufd_put_object(ucmd->ictx, &ioas->obj);
        return rc;
 }
 
@@ -754,7 +754,7 @@ static int iommufd_test_md_check_pa(struct iommufd_ucmd *ucmd,
        rc = 0;
 
 out_put:
-       iommufd_put_object(&hwpt->obj);
+       iommufd_put_object(ucmd->ictx, &hwpt->obj);
        return rc;
 }
 
@@ -1233,7 +1233,7 @@ static int iommufd_test_dirty(struct iommufd_ucmd *ucmd, unsigned int mockpt_id,
 out_free:
        kvfree(tmp);
 out_put:
-       iommufd_put_object(&hwpt->obj);
+       iommufd_put_object(ucmd->ictx, &hwpt->obj);
        return rc;
 }
 
index 538fbf76354d13d5b7f6478a82dd40e2daf67add..a3ad5f0b6c59dddc8fdd17723eb01ff8342c86ab 100644 (file)
@@ -41,7 +41,7 @@ int iommufd_vfio_compat_ioas_get_id(struct iommufd_ctx *ictx, u32 *out_ioas_id)
        if (IS_ERR(ioas))
                return PTR_ERR(ioas);
        *out_ioas_id = ioas->obj.id;
-       iommufd_put_object(&ioas->obj);
+       iommufd_put_object(ictx, &ioas->obj);
        return 0;
 }
 EXPORT_SYMBOL_NS_GPL(iommufd_vfio_compat_ioas_get_id, IOMMUFD_VFIO);
@@ -98,7 +98,7 @@ int iommufd_vfio_compat_ioas_create(struct iommufd_ctx *ictx)
 
        if (ictx->vfio_ioas && iommufd_lock_obj(&ictx->vfio_ioas->obj)) {
                ret = 0;
-               iommufd_put_object(&ictx->vfio_ioas->obj);
+               iommufd_put_object(ictx, &ictx->vfio_ioas->obj);
                goto out_abort;
        }
        ictx->vfio_ioas = ioas;
@@ -133,7 +133,7 @@ int iommufd_vfio_ioas(struct iommufd_ucmd *ucmd)
                if (IS_ERR(ioas))
                        return PTR_ERR(ioas);
                cmd->ioas_id = ioas->obj.id;
-               iommufd_put_object(&ioas->obj);
+               iommufd_put_object(ucmd->ictx, &ioas->obj);
                return iommufd_ucmd_respond(ucmd, sizeof(*cmd));
 
        case IOMMU_VFIO_IOAS_SET:
@@ -143,7 +143,7 @@ int iommufd_vfio_ioas(struct iommufd_ucmd *ucmd)
                xa_lock(&ucmd->ictx->objects);
                ucmd->ictx->vfio_ioas = ioas;
                xa_unlock(&ucmd->ictx->objects);
-               iommufd_put_object(&ioas->obj);
+               iommufd_put_object(ucmd->ictx, &ioas->obj);
                return 0;
 
        case IOMMU_VFIO_IOAS_CLEAR:
@@ -190,7 +190,7 @@ static int iommufd_vfio_map_dma(struct iommufd_ctx *ictx, unsigned int cmd,
        iova = map.iova;
        rc = iopt_map_user_pages(ictx, &ioas->iopt, &iova, u64_to_user_ptr(map.vaddr),
                                 map.size, iommu_prot, 0);
-       iommufd_put_object(&ioas->obj);
+       iommufd_put_object(ictx, &ioas->obj);
        return rc;
 }
 
@@ -249,7 +249,7 @@ static int iommufd_vfio_unmap_dma(struct iommufd_ctx *ictx, unsigned int cmd,
                rc = -EFAULT;
 
 err_put:
-       iommufd_put_object(&ioas->obj);
+       iommufd_put_object(ictx, &ioas->obj);
        return rc;
 }
 
@@ -272,7 +272,7 @@ static int iommufd_vfio_cc_iommu(struct iommufd_ctx *ictx)
        }
        mutex_unlock(&ioas->mutex);
 
-       iommufd_put_object(&ioas->obj);
+       iommufd_put_object(ictx, &ioas->obj);
        return rc;
 }
 
@@ -349,7 +349,7 @@ static int iommufd_vfio_set_iommu(struct iommufd_ctx *ictx, unsigned long type)
         */
        if (type == VFIO_TYPE1_IOMMU)
                rc = iopt_disable_large_pages(&ioas->iopt);
-       iommufd_put_object(&ioas->obj);
+       iommufd_put_object(ictx, &ioas->obj);
        return rc;
 }
 
@@ -511,7 +511,7 @@ static int iommufd_vfio_iommu_get_info(struct iommufd_ctx *ictx,
 
 out_put:
        up_read(&ioas->iopt.iova_rwsem);
-       iommufd_put_object(&ioas->obj);
+       iommufd_put_object(ictx, &ioas->obj);
        return rc;
 }
 
index e358e77e4b38f9c6885fd01da7daff0dc7c46b5f..d76214fa9ad8645441e9c53814719ba0109f30ac 100644 (file)
@@ -226,6 +226,11 @@ static int set_device_name(struct led_netdev_data *trigger_data,
 
        cancel_delayed_work_sync(&trigger_data->work);
 
+       /*
+        * Take RTNL lock before trigger_data lock to prevent potential
+        * deadlock with netdev notifier registration.
+        */
+       rtnl_lock();
        mutex_lock(&trigger_data->lock);
 
        if (trigger_data->net_dev) {
@@ -245,16 +250,14 @@ static int set_device_name(struct led_netdev_data *trigger_data,
        trigger_data->carrier_link_up = false;
        trigger_data->link_speed = SPEED_UNKNOWN;
        trigger_data->duplex = DUPLEX_UNKNOWN;
-       if (trigger_data->net_dev != NULL) {
-               rtnl_lock();
+       if (trigger_data->net_dev)
                get_device_state(trigger_data);
-               rtnl_unlock();
-       }
 
        trigger_data->last_activity = 0;
 
        set_baseline_state(trigger_data);
        mutex_unlock(&trigger_data->lock);
+       rtnl_unlock();
 
        return 0;
 }
index 19e996a829c9db8008e51becadc9acbc5b6e0832..b54275389f8acf1cd11341288f3692ca9e1c9f5d 100644 (file)
@@ -186,6 +186,8 @@ do {                                                                        \
 #define ARC_IS_5MBIT    1   /* card default speed is 5MBit */
 #define ARC_CAN_10MBIT  2   /* card uses COM20022, supporting 10MBit,
                                 but default is 2.5MBit. */
+#define ARC_HAS_LED     4   /* card has software controlled LEDs */
+#define ARC_HAS_ROTARY  8   /* card has rotary encoder */
 
 /* information needed to define an encapsulation driver */
 struct ArcProto {
index c580acb8b1d34e75a87c079a6a17e3f395b62878..7b5c8bb02f11941f6210200c23ee2f74272d49a3 100644 (file)
@@ -213,12 +213,13 @@ static int com20020pci_probe(struct pci_dev *pdev,
                if (!strncmp(ci->name, "EAE PLX-PCI FB2", 15))
                        lp->backplane = 1;
 
-               /* Get the dev_id from the PLX rotary coder */
-               if (!strncmp(ci->name, "EAE PLX-PCI MA1", 15))
-                       dev_id_mask = 0x3;
-               dev->dev_id = (inb(priv->misc + ci->rotary) >> 4) & dev_id_mask;
-
-               snprintf(dev->name, sizeof(dev->name), "arc%d-%d", dev->dev_id, i);
+               if (ci->flags & ARC_HAS_ROTARY) {
+                       /* Get the dev_id from the PLX rotary coder */
+                       if (!strncmp(ci->name, "EAE PLX-PCI MA1", 15))
+                               dev_id_mask = 0x3;
+                       dev->dev_id = (inb(priv->misc + ci->rotary) >> 4) & dev_id_mask;
+                       snprintf(dev->name, sizeof(dev->name), "arc%d-%d", dev->dev_id, i);
+               }
 
                if (arcnet_inb(ioaddr, COM20020_REG_R_STATUS) == 0xFF) {
                        pr_err("IO address %Xh is empty!\n", ioaddr);
@@ -230,6 +231,10 @@ static int com20020pci_probe(struct pci_dev *pdev,
                        goto err_free_arcdev;
                }
 
+               ret = com20020_found(dev, IRQF_SHARED);
+               if (ret)
+                       goto err_free_arcdev;
+
                card = devm_kzalloc(&pdev->dev, sizeof(struct com20020_dev),
                                    GFP_KERNEL);
                if (!card) {
@@ -239,41 +244,39 @@ static int com20020pci_probe(struct pci_dev *pdev,
 
                card->index = i;
                card->pci_priv = priv;
-               card->tx_led.brightness_set = led_tx_set;
-               card->tx_led.default_trigger = devm_kasprintf(&pdev->dev,
-                                               GFP_KERNEL, "arc%d-%d-tx",
-                                               dev->dev_id, i);
-               card->tx_led.name = devm_kasprintf(&pdev->dev, GFP_KERNEL,
-                                               "pci:green:tx:%d-%d",
-                                               dev->dev_id, i);
-
-               card->tx_led.dev = &dev->dev;
-               card->recon_led.brightness_set = led_recon_set;
-               card->recon_led.default_trigger = devm_kasprintf(&pdev->dev,
-                                               GFP_KERNEL, "arc%d-%d-recon",
-                                               dev->dev_id, i);
-               card->recon_led.name = devm_kasprintf(&pdev->dev, GFP_KERNEL,
-                                               "pci:red:recon:%d-%d",
-                                               dev->dev_id, i);
-               card->recon_led.dev = &dev->dev;
-               card->dev = dev;
-
-               ret = devm_led_classdev_register(&pdev->dev, &card->tx_led);
-               if (ret)
-                       goto err_free_arcdev;
 
-               ret = devm_led_classdev_register(&pdev->dev, &card->recon_led);
-               if (ret)
-                       goto err_free_arcdev;
-
-               dev_set_drvdata(&dev->dev, card);
-
-               ret = com20020_found(dev, IRQF_SHARED);
-               if (ret)
-                       goto err_free_arcdev;
-
-               devm_arcnet_led_init(dev, dev->dev_id, i);
+               if (ci->flags & ARC_HAS_LED) {
+                       card->tx_led.brightness_set = led_tx_set;
+                       card->tx_led.default_trigger = devm_kasprintf(&pdev->dev,
+                                                       GFP_KERNEL, "arc%d-%d-tx",
+                                                       dev->dev_id, i);
+                       card->tx_led.name = devm_kasprintf(&pdev->dev, GFP_KERNEL,
+                                                       "pci:green:tx:%d-%d",
+                                                       dev->dev_id, i);
+
+                       card->tx_led.dev = &dev->dev;
+                       card->recon_led.brightness_set = led_recon_set;
+                       card->recon_led.default_trigger = devm_kasprintf(&pdev->dev,
+                                                       GFP_KERNEL, "arc%d-%d-recon",
+                                                       dev->dev_id, i);
+                       card->recon_led.name = devm_kasprintf(&pdev->dev, GFP_KERNEL,
+                                                       "pci:red:recon:%d-%d",
+                                                       dev->dev_id, i);
+                       card->recon_led.dev = &dev->dev;
+
+                       ret = devm_led_classdev_register(&pdev->dev, &card->tx_led);
+                       if (ret)
+                               goto err_free_arcdev;
+
+                       ret = devm_led_classdev_register(&pdev->dev, &card->recon_led);
+                       if (ret)
+                               goto err_free_arcdev;
+
+                       dev_set_drvdata(&dev->dev, card);
+                       devm_arcnet_led_init(dev, dev->dev_id, i);
+               }
 
+               card->dev = dev;
                list_add(&card->list, &priv->list_dev);
                continue;
 
@@ -329,7 +332,7 @@ static struct com20020_pci_card_info card_info_5mbit = {
 };
 
 static struct com20020_pci_card_info card_info_sohard = {
-       .name = "PLX-PCI",
+       .name = "SOHARD SH ARC-PCI",
        .devcount = 1,
        /* SOHARD needs PCI base addr 4 */
        .chan_map_tbl = {
@@ -364,7 +367,7 @@ static struct com20020_pci_card_info card_info_eae_arc1 = {
                },
        },
        .rotary = 0x0,
-       .flags = ARC_CAN_10MBIT,
+       .flags = ARC_HAS_ROTARY | ARC_HAS_LED | ARC_CAN_10MBIT,
 };
 
 static struct com20020_pci_card_info card_info_eae_ma1 = {
@@ -396,7 +399,7 @@ static struct com20020_pci_card_info card_info_eae_ma1 = {
                },
        },
        .rotary = 0x0,
-       .flags = ARC_CAN_10MBIT,
+       .flags = ARC_HAS_ROTARY | ARC_HAS_LED | ARC_CAN_10MBIT,
 };
 
 static struct com20020_pci_card_info card_info_eae_fb2 = {
@@ -421,7 +424,7 @@ static struct com20020_pci_card_info card_info_eae_fb2 = {
                },
        },
        .rotary = 0x0,
-       .flags = ARC_CAN_10MBIT,
+       .flags = ARC_HAS_ROTARY | ARC_HAS_LED | ARC_CAN_10MBIT,
 };
 
 static const struct pci_device_id com20020pci_id_table[] = {
index 3fed406fb46ae6361c5d1819470b750083e60ef6..ff4b39601c937b78df3090fc5742f87a194e15be 100644 (file)
@@ -2713,10 +2713,18 @@ static int ksz_connect_tag_protocol(struct dsa_switch *ds,
 {
        struct ksz_tagger_data *tagger_data;
 
-       tagger_data = ksz_tagger_data(ds);
-       tagger_data->xmit_work_fn = ksz_port_deferred_xmit;
-
-       return 0;
+       switch (proto) {
+       case DSA_TAG_PROTO_KSZ8795:
+               return 0;
+       case DSA_TAG_PROTO_KSZ9893:
+       case DSA_TAG_PROTO_KSZ9477:
+       case DSA_TAG_PROTO_LAN937X:
+               tagger_data = ksz_tagger_data(ds);
+               tagger_data->xmit_work_fn = ksz_port_deferred_xmit;
+               return 0;
+       default:
+               return -EPROTONOSUPPORT;
+       }
 }
 
 static int ksz_port_vlan_filtering(struct dsa_switch *ds, int port,
index 9a8429f5d09cbf90bd4341614a273072068414ec..d758a6c1b226380f7b9335a73ce90fdc2e65ddce 100644 (file)
@@ -465,6 +465,7 @@ mv88e639x_pcs_select(struct mv88e6xxx_chip *chip, int port,
        case PHY_INTERFACE_MODE_10GBASER:
        case PHY_INTERFACE_MODE_XAUI:
        case PHY_INTERFACE_MODE_RXAUI:
+       case PHY_INTERFACE_MODE_USXGMII:
                return &mpcs->xg_pcs;
 
        default:
@@ -873,7 +874,8 @@ static int mv88e6393x_xg_pcs_post_config(struct phylink_pcs *pcs,
        struct mv88e639x_pcs *mpcs = xg_pcs_to_mv88e639x_pcs(pcs);
        int err;
 
-       if (interface == PHY_INTERFACE_MODE_10GBASER) {
+       if (interface == PHY_INTERFACE_MODE_10GBASER ||
+           interface == PHY_INTERFACE_MODE_USXGMII) {
                err = mv88e6393x_erratum_5_2(mpcs);
                if (err)
                        return err;
@@ -886,12 +888,37 @@ static int mv88e6393x_xg_pcs_post_config(struct phylink_pcs *pcs,
        return mv88e639x_xg_pcs_enable(mpcs);
 }
 
+static void mv88e6393x_xg_pcs_get_state(struct phylink_pcs *pcs,
+                                       struct phylink_link_state *state)
+{
+       struct mv88e639x_pcs *mpcs = xg_pcs_to_mv88e639x_pcs(pcs);
+       u16 status, lp_status;
+       int err;
+
+       if (state->interface != PHY_INTERFACE_MODE_USXGMII)
+               return mv88e639x_xg_pcs_get_state(pcs, state);
+
+       state->link = false;
+
+       err = mv88e639x_read(mpcs, MV88E6390_USXGMII_PHY_STATUS, &status);
+       err = err ? : mv88e639x_read(mpcs, MV88E6390_USXGMII_LP_STATUS, &lp_status);
+       if (err) {
+               dev_err(mpcs->mdio.dev.parent,
+                       "can't read USXGMII status: %pe\n", ERR_PTR(err));
+               return;
+       }
+
+       state->link = !!(status & MDIO_USXGMII_LINK);
+       state->an_complete = state->link;
+       phylink_decode_usxgmii_word(state, lp_status);
+}
+
 static const struct phylink_pcs_ops mv88e6393x_xg_pcs_ops = {
        .pcs_enable = mv88e6393x_xg_pcs_enable,
        .pcs_disable = mv88e6393x_xg_pcs_disable,
        .pcs_pre_config = mv88e6393x_xg_pcs_pre_config,
        .pcs_post_config = mv88e6393x_xg_pcs_post_config,
-       .pcs_get_state = mv88e639x_xg_pcs_get_state,
+       .pcs_get_state = mv88e6393x_xg_pcs_get_state,
        .pcs_config = mv88e639x_xg_pcs_config,
 };
 
index 80b44043e6c53f07a1c54b5100f19f7d0d8bee08..28c9b6f1a54f148d056c8106de3427c0fd479cce 100644 (file)
@@ -553,17 +553,17 @@ void aq_ptp_tx_hwtstamp(struct aq_nic_s *aq_nic, u64 timestamp)
 
 /* aq_ptp_rx_hwtstamp - utility function which checks for RX time stamp
  * @adapter: pointer to adapter struct
- * @skb: particular skb to send timestamp with
+ * @shhwtstamps: particular skb_shared_hwtstamps to save timestamp
  *
  * if the timestamp is valid, we convert it into the timecounter ns
  * value, then store that result into the hwtstamps structure which
  * is passed up the network stack
  */
-static void aq_ptp_rx_hwtstamp(struct aq_ptp_s *aq_ptp, struct sk_buff *skb,
+static void aq_ptp_rx_hwtstamp(struct aq_ptp_s *aq_ptp, struct skb_shared_hwtstamps *shhwtstamps,
                               u64 timestamp)
 {
        timestamp -= atomic_read(&aq_ptp->offset_ingress);
-       aq_ptp_convert_to_hwtstamp(aq_ptp, skb_hwtstamps(skb), timestamp);
+       aq_ptp_convert_to_hwtstamp(aq_ptp, shhwtstamps, timestamp);
 }
 
 void aq_ptp_hwtstamp_config_get(struct aq_ptp_s *aq_ptp,
@@ -639,7 +639,7 @@ bool aq_ptp_ring(struct aq_nic_s *aq_nic, struct aq_ring_s *ring)
               &aq_ptp->ptp_rx == ring || &aq_ptp->hwts_rx == ring;
 }
 
-u16 aq_ptp_extract_ts(struct aq_nic_s *aq_nic, struct sk_buff *skb, u8 *p,
+u16 aq_ptp_extract_ts(struct aq_nic_s *aq_nic, struct skb_shared_hwtstamps *shhwtstamps, u8 *p,
                      unsigned int len)
 {
        struct aq_ptp_s *aq_ptp = aq_nic->aq_ptp;
@@ -648,7 +648,7 @@ u16 aq_ptp_extract_ts(struct aq_nic_s *aq_nic, struct sk_buff *skb, u8 *p,
                                                   p, len, &timestamp);
 
        if (ret > 0)
-               aq_ptp_rx_hwtstamp(aq_ptp, skb, timestamp);
+               aq_ptp_rx_hwtstamp(aq_ptp, shhwtstamps, timestamp);
 
        return ret;
 }
index 28ccb7ca2df9e7d5b71b92c8dce9bea3b21d3a5e..210b723f22072cdbe09ca89111916346a7316803 100644 (file)
@@ -67,7 +67,7 @@ int aq_ptp_hwtstamp_config_set(struct aq_ptp_s *aq_ptp,
 /* Return either ring is belong to PTP or not*/
 bool aq_ptp_ring(struct aq_nic_s *aq_nic, struct aq_ring_s *ring);
 
-u16 aq_ptp_extract_ts(struct aq_nic_s *aq_nic, struct sk_buff *skb, u8 *p,
+u16 aq_ptp_extract_ts(struct aq_nic_s *aq_nic, struct skb_shared_hwtstamps *shhwtstamps, u8 *p,
                      unsigned int len);
 
 struct ptp_clock *aq_ptp_get_ptp_clock(struct aq_ptp_s *aq_ptp);
@@ -143,7 +143,7 @@ static inline bool aq_ptp_ring(struct aq_nic_s *aq_nic, struct aq_ring_s *ring)
 }
 
 static inline u16 aq_ptp_extract_ts(struct aq_nic_s *aq_nic,
-                                   struct sk_buff *skb, u8 *p,
+                                   struct skb_shared_hwtstamps *shhwtstamps, u8 *p,
                                    unsigned int len)
 {
        return 0;
index 4de22eed099a8443fb8ac9fb88199baeae36bbb7..694daeaf3e6150b3c0581f354bad9ce5a93eed0b 100644 (file)
@@ -647,7 +647,7 @@ static int __aq_ring_rx_clean(struct aq_ring_s *self, struct napi_struct *napi,
                }
                if (is_ptp_ring)
                        buff->len -=
-                               aq_ptp_extract_ts(self->aq_nic, skb,
+                               aq_ptp_extract_ts(self->aq_nic, skb_hwtstamps(skb),
                                                  aq_buf_vaddr(&buff->rxdata),
                                                  buff->len);
 
@@ -742,6 +742,8 @@ static int __aq_ring_xdp_clean(struct aq_ring_s *rx_ring,
                struct aq_ring_buff_s *buff = &rx_ring->buff_ring[rx_ring->sw_head];
                bool is_ptp_ring = aq_ptp_ring(rx_ring->aq_nic, rx_ring);
                struct aq_ring_buff_s *buff_ = NULL;
+               u16 ptp_hwtstamp_len = 0;
+               struct skb_shared_hwtstamps shhwtstamps;
                struct sk_buff *skb = NULL;
                unsigned int next_ = 0U;
                struct xdp_buff xdp;
@@ -810,11 +812,12 @@ static int __aq_ring_xdp_clean(struct aq_ring_s *rx_ring,
                hard_start = page_address(buff->rxdata.page) +
                             buff->rxdata.pg_off - rx_ring->page_offset;
 
-               if (is_ptp_ring)
-                       buff->len -=
-                               aq_ptp_extract_ts(rx_ring->aq_nic, skb,
-                                                 aq_buf_vaddr(&buff->rxdata),
-                                                 buff->len);
+               if (is_ptp_ring) {
+                       ptp_hwtstamp_len = aq_ptp_extract_ts(rx_ring->aq_nic, &shhwtstamps,
+                                                            aq_buf_vaddr(&buff->rxdata),
+                                                            buff->len);
+                       buff->len -= ptp_hwtstamp_len;
+               }
 
                xdp_init_buff(&xdp, frame_sz, &rx_ring->xdp_rxq);
                xdp_prepare_buff(&xdp, hard_start, rx_ring->page_offset,
@@ -834,6 +837,9 @@ static int __aq_ring_xdp_clean(struct aq_ring_s *rx_ring,
                if (IS_ERR(skb) || !skb)
                        continue;
 
+               if (ptp_hwtstamp_len > 0)
+                       *skb_hwtstamps(skb) = shhwtstamps;
+
                if (buff->is_vlan)
                        __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q),
                                               buff->vlan_rx_tag);
index 38d89d80b4a9c7ed2470b6ce6ddb8a3557e9069e..273c9ba48f09a179ee175fbab10fde84f0738836 100644 (file)
@@ -2075,6 +2075,7 @@ destroy_flow_table:
        rhashtable_destroy(&tc_info->flow_table);
 free_tc_info:
        kfree(tc_info);
+       bp->tc_info = NULL;
        return rc;
 }
 
index 48b6191efa56c70cc82ba0a83bb5ee64e6bb3fe2..f52830dfb26a1e52f517e61e9108f6f9f80e13a4 100644 (file)
@@ -6474,6 +6474,14 @@ static void tg3_dump_state(struct tg3 *tp)
        int i;
        u32 *regs;
 
+       /* If it is a PCI error, all registers will be 0xffff,
+        * we don't dump them out, just report the error and return
+        */
+       if (tp->pdev->error_state != pci_channel_io_normal) {
+               netdev_err(tp->dev, "PCI channel ERROR!\n");
+               return;
+       }
+
        regs = kzalloc(TG3_REG_BLK_SIZE, GFP_ATOMIC);
        if (!regs)
                return;
@@ -11259,7 +11267,8 @@ static void tg3_reset_task(struct work_struct *work)
        rtnl_lock();
        tg3_full_lock(tp, 0);
 
-       if (tp->pcierr_recovery || !netif_running(tp->dev)) {
+       if (tp->pcierr_recovery || !netif_running(tp->dev) ||
+           tp->pdev->error_state != pci_channel_io_normal) {
                tg3_flag_clear(tp, RESET_TASK_PENDING);
                tg3_full_unlock(tp);
                rtnl_unlock();
index 928d934cb21a5af1a0fbdc144a12dbee5e4e1960..f75668c479351913e20f54c103125bbd345b8a47 100644 (file)
@@ -66,6 +66,27 @@ static enum mac_mode hns_get_enet_interface(const struct hns_mac_cb *mac_cb)
        }
 }
 
+static u32 hns_mac_link_anti_shake(struct mac_driver *mac_ctrl_drv)
+{
+#define HNS_MAC_LINK_WAIT_TIME 5
+#define HNS_MAC_LINK_WAIT_CNT 40
+
+       u32 link_status = 0;
+       int i;
+
+       if (!mac_ctrl_drv->get_link_status)
+               return link_status;
+
+       for (i = 0; i < HNS_MAC_LINK_WAIT_CNT; i++) {
+               msleep(HNS_MAC_LINK_WAIT_TIME);
+               mac_ctrl_drv->get_link_status(mac_ctrl_drv, &link_status);
+               if (!link_status)
+                       break;
+       }
+
+       return link_status;
+}
+
 void hns_mac_get_link_status(struct hns_mac_cb *mac_cb, u32 *link_status)
 {
        struct mac_driver *mac_ctrl_drv;
@@ -83,6 +104,14 @@ void hns_mac_get_link_status(struct hns_mac_cb *mac_cb, u32 *link_status)
                                                               &sfp_prsnt);
                if (!ret)
                        *link_status = *link_status && sfp_prsnt;
+
+               /* for FIBER port, it may have a fake link up.
+                * when the link status changes from down to up, we need to do
+                * anti-shake. the anti-shake time is base on tests.
+                * only FIBER port need to do this.
+                */
+               if (*link_status && !mac_cb->link)
+                       *link_status = hns_mac_link_anti_shake(mac_ctrl_drv);
        }
 
        mac_cb->link = *link_status;
index 0900abf5c5086b9836c28f4a9f11d550b6ccaaa5..8a713eed446582f87916c71586a19542dec79252 100644 (file)
@@ -142,7 +142,8 @@ MODULE_DEVICE_TABLE(acpi, hns_enet_acpi_match);
 
 static void fill_desc(struct hnae_ring *ring, void *priv,
                      int size, dma_addr_t dma, int frag_end,
-                     int buf_num, enum hns_desc_type type, int mtu)
+                     int buf_num, enum hns_desc_type type, int mtu,
+                     bool is_gso)
 {
        struct hnae_desc *desc = &ring->desc[ring->next_to_use];
        struct hnae_desc_cb *desc_cb = &ring->desc_cb[ring->next_to_use];
@@ -275,6 +276,15 @@ static int hns_nic_maybe_stop_tso(
        return 0;
 }
 
+static int hns_nic_maybe_stop_tx_v2(struct sk_buff **out_skb, int *bnum,
+                                   struct hnae_ring *ring)
+{
+       if (skb_is_gso(*out_skb))
+               return hns_nic_maybe_stop_tso(out_skb, bnum, ring);
+       else
+               return hns_nic_maybe_stop_tx(out_skb, bnum, ring);
+}
+
 static void fill_tso_desc(struct hnae_ring *ring, void *priv,
                          int size, dma_addr_t dma, int frag_end,
                          int buf_num, enum hns_desc_type type, int mtu)
@@ -300,6 +310,19 @@ static void fill_tso_desc(struct hnae_ring *ring, void *priv,
                                mtu);
 }
 
+static void fill_desc_v2(struct hnae_ring *ring, void *priv,
+                        int size, dma_addr_t dma, int frag_end,
+                        int buf_num, enum hns_desc_type type, int mtu,
+                        bool is_gso)
+{
+       if (is_gso)
+               fill_tso_desc(ring, priv, size, dma, frag_end, buf_num, type,
+                             mtu);
+       else
+               fill_v2_desc(ring, priv, size, dma, frag_end, buf_num, type,
+                            mtu);
+}
+
 netdev_tx_t hns_nic_net_xmit_hw(struct net_device *ndev,
                                struct sk_buff *skb,
                                struct hns_nic_ring_data *ring_data)
@@ -313,6 +336,7 @@ netdev_tx_t hns_nic_net_xmit_hw(struct net_device *ndev,
        int seg_num;
        dma_addr_t dma;
        int size, next_to_use;
+       bool is_gso;
        int i;
 
        switch (priv->ops.maybe_stop_tx(&skb, &buf_num, ring)) {
@@ -339,8 +363,9 @@ netdev_tx_t hns_nic_net_xmit_hw(struct net_device *ndev,
                ring->stats.sw_err_cnt++;
                goto out_err_tx_ok;
        }
+       is_gso = skb_is_gso(skb);
        priv->ops.fill_desc(ring, skb, size, dma, seg_num == 1 ? 1 : 0,
-                           buf_num, DESC_TYPE_SKB, ndev->mtu);
+                           buf_num, DESC_TYPE_SKB, ndev->mtu, is_gso);
 
        /* fill the fragments */
        for (i = 1; i < seg_num; i++) {
@@ -354,7 +379,7 @@ netdev_tx_t hns_nic_net_xmit_hw(struct net_device *ndev,
                }
                priv->ops.fill_desc(ring, skb_frag_page(frag), size, dma,
                                    seg_num - 1 == i ? 1 : 0, buf_num,
-                                   DESC_TYPE_PAGE, ndev->mtu);
+                                   DESC_TYPE_PAGE, ndev->mtu, is_gso);
        }
 
        /*complete translate all packets*/
@@ -1776,15 +1801,6 @@ static int hns_nic_set_features(struct net_device *netdev,
                        netdev_info(netdev, "enet v1 do not support tso!\n");
                break;
        default:
-               if (features & (NETIF_F_TSO | NETIF_F_TSO6)) {
-                       priv->ops.fill_desc = fill_tso_desc;
-                       priv->ops.maybe_stop_tx = hns_nic_maybe_stop_tso;
-                       /* The chip only support 7*4096 */
-                       netif_set_tso_max_size(netdev, 7 * 4096);
-               } else {
-                       priv->ops.fill_desc = fill_v2_desc;
-                       priv->ops.maybe_stop_tx = hns_nic_maybe_stop_tx;
-               }
                break;
        }
        netdev->features = features;
@@ -2159,16 +2175,9 @@ static void hns_nic_set_priv_ops(struct net_device *netdev)
                priv->ops.maybe_stop_tx = hns_nic_maybe_stop_tx;
        } else {
                priv->ops.get_rxd_bnum = get_v2rx_desc_bnum;
-               if ((netdev->features & NETIF_F_TSO) ||
-                   (netdev->features & NETIF_F_TSO6)) {
-                       priv->ops.fill_desc = fill_tso_desc;
-                       priv->ops.maybe_stop_tx = hns_nic_maybe_stop_tso;
-                       /* This chip only support 7*4096 */
-                       netif_set_tso_max_size(netdev, 7 * 4096);
-               } else {
-                       priv->ops.fill_desc = fill_v2_desc;
-                       priv->ops.maybe_stop_tx = hns_nic_maybe_stop_tx;
-               }
+               priv->ops.fill_desc = fill_desc_v2;
+               priv->ops.maybe_stop_tx = hns_nic_maybe_stop_tx_v2;
+               netif_set_tso_max_size(netdev, 7 * 4096);
                /* enable tso when init
                 * control tso on/off through TSE bit in bd
                 */
index ffa9d6573f54bcfebf50cf851ee6134289cd293b..3f3ee032f631c4ca371b27c3ddc766d66b5c3788 100644 (file)
@@ -44,7 +44,8 @@ struct hns_nic_ring_data {
 struct hns_nic_ops {
        void (*fill_desc)(struct hnae_ring *ring, void *priv,
                          int size, dma_addr_t dma, int frag_end,
-                         int buf_num, enum hns_desc_type type, int mtu);
+                         int buf_num, enum hns_desc_type type, int mtu,
+                         bool is_gso);
        int (*maybe_stop_tx)(struct sk_buff **out_skb,
                             int *bnum, struct hnae_ring *ring);
        void (*get_rxd_bnum)(u32 bnum_flag, int *out_bnum);
index f7a332e51524d1a28b2895cf16ce2c2e22639109..1ab8dbe2d8800d0ca3e158870dc8580a604c444c 100644 (file)
@@ -16224,7 +16224,7 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
               I40E_PRTGL_SAH_MFS_MASK) >> I40E_PRTGL_SAH_MFS_SHIFT;
        if (val < MAX_FRAME_SIZE_DEFAULT)
                dev_warn(&pdev->dev, "MFS for port %x has been set below the default: %x\n",
-                        i, val);
+                        pf->hw.port, val);
 
        /* Add a filter to drop all Flow control frames from any VSI from being
         * transmitted. By doing so we stop a malicious VF from sending out
index 6f236d1a6444e83cd86abed8c51c1d744ed642f4..19cbfe554689f4718f8366d0792b2d19c678f2e3 100644 (file)
@@ -827,18 +827,10 @@ static int __iavf_set_coalesce(struct net_device *netdev,
        struct iavf_adapter *adapter = netdev_priv(netdev);
        int i;
 
-       if (ec->rx_coalesce_usecs == 0) {
-               if (ec->use_adaptive_rx_coalesce)
-                       netif_info(adapter, drv, netdev, "rx-usecs=0, need to disable adaptive-rx for a complete disable\n");
-       } else if ((ec->rx_coalesce_usecs < IAVF_MIN_ITR) ||
-                  (ec->rx_coalesce_usecs > IAVF_MAX_ITR)) {
+       if (ec->rx_coalesce_usecs > IAVF_MAX_ITR) {
                netif_info(adapter, drv, netdev, "Invalid value, rx-usecs range is 0-8160\n");
                return -EINVAL;
-       } else if (ec->tx_coalesce_usecs == 0) {
-               if (ec->use_adaptive_tx_coalesce)
-                       netif_info(adapter, drv, netdev, "tx-usecs=0, need to disable adaptive-tx for a complete disable\n");
-       } else if ((ec->tx_coalesce_usecs < IAVF_MIN_ITR) ||
-                  (ec->tx_coalesce_usecs > IAVF_MAX_ITR)) {
+       } else if (ec->tx_coalesce_usecs > IAVF_MAX_ITR) {
                netif_info(adapter, drv, netdev, "Invalid value, tx-usecs range is 0-8160\n");
                return -EINVAL;
        }
index 7e6ee32d19b696dcd04cbbbc7e72526ad9adf1f0..10ba36602c0c14c72f61d4a27776e3f98469065f 100644 (file)
@@ -15,7 +15,6 @@
  */
 #define IAVF_ITR_DYNAMIC       0x8000  /* use top bit as a flag */
 #define IAVF_ITR_MASK          0x1FFE  /* mask for ITR register value */
-#define IAVF_MIN_ITR                2  /* reg uses 2 usec resolution */
 #define IAVF_ITR_100K              10  /* all values below must be even */
 #define IAVF_ITR_50K               20
 #define IAVF_ITR_20K               50
index 2a5e6616cc0a794afd8d46dd63fb5d98a85f52b7..e1494f24f661d3c2c791846b5bdc2a1f2af8ff03 100644 (file)
@@ -374,16 +374,11 @@ static void ice_ena_vf_mappings(struct ice_vf *vf)
  */
 int ice_calc_vf_reg_idx(struct ice_vf *vf, struct ice_q_vector *q_vector)
 {
-       struct ice_pf *pf;
-
        if (!vf || !q_vector)
                return -EINVAL;
 
-       pf = vf->pf;
-
        /* always add one to account for the OICR being the first MSIX */
-       return pf->sriov_base_vector + pf->vfs.num_msix_per * vf->vf_id +
-               q_vector->v_idx + 1;
+       return vf->first_vector_idx + q_vector->v_idx + 1;
 }
 
 /**
index d7b10dc67f0352a2caca63eb79742925bbea13e7..80dc4bcdd3a41cd0baa0e3e29f0fddb29053341f 100644 (file)
@@ -32,7 +32,6 @@ static void ice_port_vlan_on(struct ice_vsi *vsi)
                /* setup outer VLAN ops */
                vlan_ops->set_port_vlan = ice_vsi_set_outer_port_vlan;
                vlan_ops->clear_port_vlan = ice_vsi_clear_outer_port_vlan;
-               vlan_ops->clear_port_vlan = ice_vsi_clear_outer_port_vlan;
 
                /* setup inner VLAN ops */
                vlan_ops = &vsi->inner_vlan_ops;
@@ -47,8 +46,13 @@ static void ice_port_vlan_on(struct ice_vsi *vsi)
 
                vlan_ops->set_port_vlan = ice_vsi_set_inner_port_vlan;
                vlan_ops->clear_port_vlan = ice_vsi_clear_inner_port_vlan;
-               vlan_ops->clear_port_vlan = ice_vsi_clear_inner_port_vlan;
        }
+
+       /* all Rx traffic should be in the domain of the assigned port VLAN,
+        * so prevent disabling Rx VLAN filtering
+        */
+       vlan_ops->dis_rx_filtering = noop_vlan;
+
        vlan_ops->ena_rx_filtering = ice_vsi_ena_rx_vlan_filtering;
 }
 
@@ -77,6 +81,8 @@ static void ice_port_vlan_off(struct ice_vsi *vsi)
                vlan_ops->del_vlan = ice_vsi_del_vlan;
        }
 
+       vlan_ops->dis_rx_filtering = ice_vsi_dis_rx_vlan_filtering;
+
        if (!test_bit(ICE_FLAG_VF_VLAN_PRUNING, pf->flags))
                vlan_ops->ena_rx_filtering = noop_vlan;
        else
@@ -141,7 +147,6 @@ void ice_vf_vsi_init_vlan_ops(struct ice_vsi *vsi)
                &vsi->outer_vlan_ops : &vsi->inner_vlan_ops;
 
        vlan_ops->add_vlan = ice_vsi_add_vlan;
-       vlan_ops->dis_rx_filtering = ice_vsi_dis_rx_vlan_filtering;
        vlan_ops->ena_tx_filtering = ice_vsi_ena_tx_vlan_filtering;
        vlan_ops->dis_tx_filtering = ice_vsi_dis_tx_vlan_filtering;
 }
index de11b3186bd7ea5731c3b63850841ffa39279ac8..1c7b4ded948b63205a72217cda869218e3cf10bf 100644 (file)
@@ -1523,7 +1523,6 @@ static int ice_vc_cfg_irq_map_msg(struct ice_vf *vf, u8 *msg)
        u16 num_q_vectors_mapped, vsi_id, vector_id;
        struct virtchnl_irq_map_info *irqmap_info;
        struct virtchnl_vector_map *map;
-       struct ice_pf *pf = vf->pf;
        struct ice_vsi *vsi;
        int i;
 
@@ -1535,7 +1534,7 @@ static int ice_vc_cfg_irq_map_msg(struct ice_vf *vf, u8 *msg)
         * there is actually at least a single VF queue vector mapped
         */
        if (!test_bit(ICE_VF_STATE_ACTIVE, vf->vf_states) ||
-           pf->vfs.num_msix_per < num_q_vectors_mapped ||
+           vf->num_msix < num_q_vectors_mapped ||
            !num_q_vectors_mapped) {
                v_ret = VIRTCHNL_STATUS_ERR_PARAM;
                goto error_param;
@@ -1557,7 +1556,7 @@ static int ice_vc_cfg_irq_map_msg(struct ice_vf *vf, u8 *msg)
                /* vector_id is always 0-based for each VF, and can never be
                 * larger than or equal to the max allowed interrupts per VF
                 */
-               if (!(vector_id < pf->vfs.num_msix_per) ||
+               if (!(vector_id < vf->num_msix) ||
                    !ice_vc_isvalid_vsi_id(vf, vsi_id) ||
                    (!vector_id && (map->rxq_map || map->txq_map))) {
                        v_ret = VIRTCHNL_STATUS_ERR_PARAM;
index 6845556581c3fa3f01c74e8a138d1c6a7a945723..5df42634ceb84c2dca063559a7e83685d12563aa 100644 (file)
@@ -1945,7 +1945,7 @@ struct mcs_hw_info {
        u8 tcam_entries;        /* RX/TX Tcam entries per mcs block */
        u8 secy_entries;        /* RX/TX SECY entries per mcs block */
        u8 sc_entries;          /* RX/TX SC CAM entries per mcs block */
-       u8 sa_entries;          /* PN table entries = SA entries */
+       u16 sa_entries;         /* PN table entries = SA entries */
        u64 rsvd[16];
 };
 
index c43f19dfbd74403817b8f65a336e57104bbeb61a..c1775bd01c2b4879f6ca2edb57310c04e4c52588 100644 (file)
@@ -117,7 +117,7 @@ void mcs_get_rx_secy_stats(struct mcs *mcs, struct mcs_secy_stats *stats, int id
        reg = MCSX_CSE_RX_MEM_SLAVE_INPKTSSECYTAGGEDCTLX(id);
        stats->pkt_tagged_ctl_cnt = mcs_reg_read(mcs, reg);
 
-       reg = MCSX_CSE_RX_MEM_SLAVE_INPKTSSECYUNTAGGEDORNOTAGX(id);
+       reg = MCSX_CSE_RX_MEM_SLAVE_INPKTSSECYUNTAGGEDX(id);
        stats->pkt_untaged_cnt = mcs_reg_read(mcs, reg);
 
        reg = MCSX_CSE_RX_MEM_SLAVE_INPKTSSECYCTLX(id);
@@ -215,7 +215,7 @@ void mcs_get_sc_stats(struct mcs *mcs, struct mcs_sc_stats *stats,
                reg = MCSX_CSE_RX_MEM_SLAVE_INPKTSSCNOTVALIDX(id);
                stats->pkt_notvalid_cnt = mcs_reg_read(mcs, reg);
 
-               reg = MCSX_CSE_RX_MEM_SLAVE_INPKTSSCUNCHECKEDOROKX(id);
+               reg = MCSX_CSE_RX_MEM_SLAVE_INPKTSSCUNCHECKEDX(id);
                stats->pkt_unchecked_cnt = mcs_reg_read(mcs, reg);
 
                if (mcs->hw->mcs_blks > 1) {
@@ -1219,6 +1219,17 @@ struct mcs *mcs_get_pdata(int mcs_id)
        return NULL;
 }
 
+bool is_mcs_bypass(int mcs_id)
+{
+       struct mcs *mcs_dev;
+
+       list_for_each_entry(mcs_dev, &mcs_list, mcs_list) {
+               if (mcs_dev->mcs_id == mcs_id)
+                       return mcs_dev->bypass;
+       }
+       return true;
+}
+
 void mcs_set_port_cfg(struct mcs *mcs, struct mcs_port_cfg_set_req *req)
 {
        u64 val = 0;
@@ -1436,7 +1447,7 @@ static int mcs_x2p_calibration(struct mcs *mcs)
        return err;
 }
 
-static void mcs_set_external_bypass(struct mcs *mcs, u8 bypass)
+static void mcs_set_external_bypass(struct mcs *mcs, bool bypass)
 {
        u64 val;
 
@@ -1447,6 +1458,7 @@ static void mcs_set_external_bypass(struct mcs *mcs, u8 bypass)
        else
                val &= ~BIT_ULL(6);
        mcs_reg_write(mcs, MCSX_MIL_GLOBAL, val);
+       mcs->bypass = bypass;
 }
 
 static void mcs_global_cfg(struct mcs *mcs)
index 0f89dcb764654b604cee5967296ca58101d02c35..f927cc61dfd21f996a4b85f43d695a71eb44358d 100644 (file)
@@ -149,6 +149,7 @@ struct mcs {
        u16                     num_vec;
        void                    *rvu;
        u16                     *tx_sa_active;
+       bool                      bypass;
 };
 
 struct mcs_ops {
@@ -206,6 +207,7 @@ void mcs_get_custom_tag_cfg(struct mcs *mcs, struct mcs_custom_tag_cfg_get_req *
 int mcs_alloc_ctrlpktrule(struct rsrc_bmap *rsrc, u16 *pf_map, u16 offset, u16 pcifunc);
 int mcs_free_ctrlpktrule(struct mcs *mcs, struct mcs_free_ctrl_pkt_rule_req *req);
 int mcs_ctrlpktrule_write(struct mcs *mcs, struct mcs_ctrl_pkt_rule_write_req *req);
+bool is_mcs_bypass(int mcs_id);
 
 /* CN10K-B APIs */
 void cn10kb_mcs_set_hw_capabilities(struct mcs *mcs);
index f3ab01fc363c8deb6261e185097ac6c04f7e84aa..f4c6de89002c1d92e203a7455e86ceefa8d8f418 100644 (file)
                offset = 0x9d8ull;                      \
        offset; })
 
+#define MCSX_CSE_RX_MEM_SLAVE_INPKTSSCUNCHECKEDX(a) ({ \
+       u64 offset;                                     \
+                                                       \
+       offset = 0xee80ull;                             \
+       if (mcs->hw->mcs_blks > 1)                      \
+               offset = 0xe818ull;                     \
+       offset += (a) * 0x8ull;                         \
+       offset; })
+
+#define MCSX_CSE_RX_MEM_SLAVE_INPKTSSECYUNTAGGEDX(a) ({        \
+       u64 offset;                                     \
+                                                       \
+       offset = 0xa680ull;                             \
+       if (mcs->hw->mcs_blks > 1)                      \
+               offset = 0xd018ull;                     \
+       offset += (a) * 0x8ull;                         \
+       offset; })
+
+#define MCSX_CSE_RX_MEM_SLAVE_INPKTSSCLATEORDELAYEDX(a)        ({      \
+       u64 offset;                                             \
+                                                               \
+       offset = 0xf680ull;                                     \
+       if (mcs->hw->mcs_blks > 1)                              \
+               offset = 0xe018ull;                             \
+       offset += (a) * 0x8ull;                                 \
+       offset; })
+
 #define MCSX_CSE_RX_MEM_SLAVE_INOCTETSSCDECRYPTEDX(a)  (0xe680ull + (a) * 0x8ull)
 #define MCSX_CSE_RX_MEM_SLAVE_INOCTETSSCVALIDATEX(a)   (0xde80ull + (a) * 0x8ull)
-#define MCSX_CSE_RX_MEM_SLAVE_INPKTSSECYUNTAGGEDORNOTAGX(a)    (0xa680ull + (a) * 0x8ull)
 #define MCSX_CSE_RX_MEM_SLAVE_INPKTSSECYNOTAGX(a)      (0xd218 + (a) * 0x8ull)
-#define MCSX_CSE_RX_MEM_SLAVE_INPKTSSECYUNTAGGEDX(a)   (0xd018ull + (a) * 0x8ull)
-#define MCSX_CSE_RX_MEM_SLAVE_INPKTSSCUNCHECKEDOROKX(a)        (0xee80ull + (a) * 0x8ull)
 #define MCSX_CSE_RX_MEM_SLAVE_INPKTSSECYCTLX(a)                (0xb680ull + (a) * 0x8ull)
-#define MCSX_CSE_RX_MEM_SLAVE_INPKTSSCLATEORDELAYEDX(a) (0xf680ull + (a) * 0x8ull)
 #define MCSX_CSE_RX_MEM_SLAVE_INPKTSSAINVALIDX(a)      (0x12680ull + (a) * 0x8ull)
 #define MCSX_CSE_RX_MEM_SLAVE_INPKTSSANOTUSINGSAERRORX(a) (0x15680ull + (a) * 0x8ull)
 #define MCSX_CSE_RX_MEM_SLAVE_INPKTSSANOTVALIDX(a)     (0x13680ull + (a) * 0x8ull)
index 22c395c7d040b494886060257b13bed6e0b01bb8..731bb82b577c20b753c6ad396527997ed4ca2362 100644 (file)
@@ -2631,6 +2631,9 @@ static void __rvu_flr_handler(struct rvu *rvu, u16 pcifunc)
        rvu_npc_free_mcam_entries(rvu, pcifunc, -1);
        rvu_mac_reset(rvu, pcifunc);
 
+       if (rvu->mcs_blk_cnt)
+               rvu_mcs_flr_handler(rvu, pcifunc);
+
        mutex_unlock(&rvu->flr_lock);
 }
 
index c4d999ef5ab4b2cf9cb3f388e3b452e87fd3fad7..cce2806aaa50cc0712562664f72aa5b6fc67d2d7 100644 (file)
@@ -345,6 +345,7 @@ struct nix_hw {
        struct nix_txvlan txvlan;
        struct nix_ipolicer *ipolicer;
        u64    *tx_credits;
+       u8      cc_mcs_cnt;
 };
 
 /* RVU block's capabilities or functionality,
index c70932625d0da0a396c732167b023f822a63271d..62780d8b4f9ac84758f3dc921d552217280d9469 100644 (file)
@@ -1087,7 +1087,7 @@ static int rvu_npa_register_reporters(struct rvu_devlink *rvu_dl)
 
        rvu_dl->devlink_wq = create_workqueue("rvu_devlink_wq");
        if (!rvu_dl->devlink_wq)
-               goto err;
+               return -ENOMEM;
 
        INIT_WORK(&rvu_reporters->intr_work, rvu_npa_intr_work);
        INIT_WORK(&rvu_reporters->err_work, rvu_npa_err_work);
@@ -1095,9 +1095,6 @@ static int rvu_npa_register_reporters(struct rvu_devlink *rvu_dl)
        INIT_WORK(&rvu_reporters->ras_work, rvu_npa_ras_work);
 
        return 0;
-err:
-       rvu_npa_health_reporters_destroy(rvu_dl);
-       return -ENOMEM;
 }
 
 static int rvu_npa_health_reporters_create(struct rvu_devlink *rvu_dl)
index c112c71ff576f8a693412ff30b435eb0ee3a193f..4227ebb4a758db2bd86aa714ddc0e8ca5c2f8322 100644 (file)
@@ -12,6 +12,7 @@
 #include "rvu_reg.h"
 #include "rvu.h"
 #include "npc.h"
+#include "mcs.h"
 #include "cgx.h"
 #include "lmac_common.h"
 #include "rvu_npc_hash.h"
@@ -4389,6 +4390,12 @@ static void nix_link_config(struct rvu *rvu, int blkaddr,
                            SDP_HW_MAX_FRS << 16 | NIC_HW_MIN_FRS);
        }
 
+       /* Get MCS external bypass status for CN10K-B */
+       if (mcs_get_blkcnt() == 1) {
+               /* Adjust for 2 credits when external bypass is disabled */
+               nix_hw->cc_mcs_cnt = is_mcs_bypass(0) ? 0 : 2;
+       }
+
        /* Set credits for Tx links assuming max packet length allowed.
         * This will be reconfigured based on MTU set for PF/VF.
         */
@@ -4412,6 +4419,7 @@ static void nix_link_config(struct rvu *rvu, int blkaddr,
                        tx_credits = (lmac_fifo_len - lmac_max_frs) / 16;
                        /* Enable credits and set credit pkt count to max allowed */
                        cfg =  (tx_credits << 12) | (0x1FF << 2) | BIT_ULL(1);
+                       cfg |= FIELD_PREP(NIX_AF_LINKX_MCS_CNT_MASK, nix_hw->cc_mcs_cnt);
 
                        link = iter + slink;
                        nix_hw->tx_credits[link] = tx_credits;
index 16cfc802e348d9d5bc7bc6f2ef4e52eae3c0000b..f65805860c8d4ee486734a7be5be774e5ed9712c 100644 (file)
@@ -389,7 +389,13 @@ static u64 npc_get_default_entry_action(struct rvu *rvu, struct npc_mcam *mcam,
        int bank, nixlf, index;
 
        /* get ucast entry rule entry index */
-       nix_get_nixlf(rvu, pf_func, &nixlf, NULL);
+       if (nix_get_nixlf(rvu, pf_func, &nixlf, NULL)) {
+               dev_err(rvu->dev, "%s: nixlf not attached to pcifunc:0x%x\n",
+                       __func__, pf_func);
+               /* Action 0 is drop */
+               return 0;
+       }
+
        index = npc_get_nixlf_mcam_index(mcam, pf_func, nixlf,
                                         NIXLF_UCAST_ENTRY);
        bank = npc_get_bank(mcam, index);
index b3150f05329196fc4bedd965a2387de602c5a3f0..d46ac29adb966dec7dea89e50fbcdbbd0f5e61a4 100644 (file)
@@ -31,8 +31,8 @@ static struct hw_reg_map txsch_reg_map[NIX_TXSCH_LVL_CNT] = {
        {NIX_TXSCH_LVL_TL4, 3, 0xFFFF, {{0x0B00, 0x0B08}, {0x0B10, 0x0B18},
                              {0x1200, 0x12E0} } },
        {NIX_TXSCH_LVL_TL3, 4, 0xFFFF, {{0x1000, 0x10E0}, {0x1600, 0x1608},
-                             {0x1610, 0x1618}, {0x1700, 0x17B0} } },
-       {NIX_TXSCH_LVL_TL2, 2, 0xFFFF, {{0x0E00, 0x0EE0}, {0x1700, 0x17B0} } },
+                             {0x1610, 0x1618}, {0x1700, 0x17C8} } },
+       {NIX_TXSCH_LVL_TL2, 2, 0xFFFF, {{0x0E00, 0x0EE0}, {0x1700, 0x17C8} } },
        {NIX_TXSCH_LVL_TL1, 1, 0xFFFF, {{0x0C00, 0x0D98} } },
 };
 
index b42e631e52d0fd686144881bb255f1529a80879e..18c1c9f361cc623c4b0247bc184142635458cdf2 100644 (file)
 
 #define NIX_AF_LINKX_BASE_MASK         GENMASK_ULL(11, 0)
 #define NIX_AF_LINKX_RANGE_MASK                GENMASK_ULL(19, 16)
+#define NIX_AF_LINKX_MCS_CNT_MASK      GENMASK_ULL(33, 32)
 
 /* SSO */
 #define SSO_AF_CONST                   (0x1000)
index 9efcec549834e800ff82465838ad59653f30115a..53f6258a973c287883a4fa63393115dcbfa63bb5 100644 (file)
@@ -334,9 +334,12 @@ static void otx2_get_pauseparam(struct net_device *netdev,
        if (is_otx2_lbkvf(pfvf->pdev))
                return;
 
+       mutex_lock(&pfvf->mbox.lock);
        req = otx2_mbox_alloc_msg_cgx_cfg_pause_frm(&pfvf->mbox);
-       if (!req)
+       if (!req) {
+               mutex_unlock(&pfvf->mbox.lock);
                return;
+       }
 
        if (!otx2_sync_mbox_msg(&pfvf->mbox)) {
                rsp = (struct cgx_pause_frm_cfg *)
@@ -344,6 +347,7 @@ static void otx2_get_pauseparam(struct net_device *netdev,
                pause->rx_pause = rsp->rx_pause;
                pause->tx_pause = rsp->tx_pause;
        }
+       mutex_unlock(&pfvf->mbox.lock);
 }
 
 static int otx2_set_pauseparam(struct net_device *netdev,
index 532e324bdcc8e6cbd975017474d06a6af303ae85..0c17ebdda148735b0e2954778ca8cb777696cc97 100644 (file)
@@ -1688,6 +1688,14 @@ static void otx2_do_set_rx_mode(struct otx2_nic *pf)
        mutex_unlock(&pf->mbox.lock);
 }
 
+static void otx2_set_irq_coalesce(struct otx2_nic *pfvf)
+{
+       int cint;
+
+       for (cint = 0; cint < pfvf->hw.cint_cnt; cint++)
+               otx2_config_irq_coalescing(pfvf, cint);
+}
+
 static void otx2_dim_work(struct work_struct *w)
 {
        struct dim_cq_moder cur_moder;
@@ -1703,6 +1711,7 @@ static void otx2_dim_work(struct work_struct *w)
                CQ_TIMER_THRESH_MAX : cur_moder.usec;
        pfvf->hw.cq_ecount_wait = (cur_moder.pkts > NAPI_POLL_WEIGHT) ?
                NAPI_POLL_WEIGHT : cur_moder.pkts;
+       otx2_set_irq_coalesce(pfvf);
        dim->state = DIM_START_MEASURE;
 }
 
index 6ee15f3c25ede947ce0103a7d8b00cd7291c177e..4d519ea833b2c7c4fa439ee56fdd07962221030c 100644 (file)
@@ -512,11 +512,18 @@ static void otx2_adjust_adaptive_coalese(struct otx2_nic *pfvf, struct otx2_cq_p
 {
        struct dim_sample dim_sample;
        u64 rx_frames, rx_bytes;
+       u64 tx_frames, tx_bytes;
 
        rx_frames = OTX2_GET_RX_STATS(RX_BCAST) + OTX2_GET_RX_STATS(RX_MCAST) +
                OTX2_GET_RX_STATS(RX_UCAST);
        rx_bytes = OTX2_GET_RX_STATS(RX_OCTS);
-       dim_update_sample(pfvf->napi_events, rx_frames, rx_bytes, &dim_sample);
+       tx_bytes = OTX2_GET_TX_STATS(TX_OCTS);
+       tx_frames = OTX2_GET_TX_STATS(TX_UCAST);
+
+       dim_update_sample(pfvf->napi_events,
+                         rx_frames + tx_frames,
+                         rx_bytes + tx_bytes,
+                         &dim_sample);
        net_dim(&cq_poll->dim, dim_sample);
 }
 
@@ -558,16 +565,9 @@ int otx2_napi_handler(struct napi_struct *napi, int budget)
                if (pfvf->flags & OTX2_FLAG_INTF_DOWN)
                        return workdone;
 
-               /* Check for adaptive interrupt coalesce */
-               if (workdone != 0 &&
-                   ((pfvf->flags & OTX2_FLAG_ADPTV_INT_COAL_ENABLED) ==
-                    OTX2_FLAG_ADPTV_INT_COAL_ENABLED)) {
-                       /* Adjust irq coalese using net_dim */
+               /* Adjust irq coalese using net_dim */
+               if (pfvf->flags & OTX2_FLAG_ADPTV_INT_COAL_ENABLED)
                        otx2_adjust_adaptive_coalese(pfvf, cq_poll);
-                       /* Update irq coalescing */
-                       for (i = 0; i < pfvf->hw.cint_cnt; i++)
-                               otx2_config_irq_coalescing(pfvf, i);
-               }
 
                if (unlikely(!filled_cnt)) {
                        struct refill_work *work;
index 060a77f2265d9a12e0c675a1a43e9f06ba95a1b2..e522845c7c211619a252bb995dec65160d7a1ae5 100644 (file)
@@ -160,6 +160,18 @@ struct nfp_tun_mac_addr_offload {
        u8 addr[ETH_ALEN];
 };
 
+/**
+ * struct nfp_neigh_update_work - update neighbour information to nfp
+ * @work:      Work queue for writing neigh to the nfp
+ * @n:         neighbour entry
+ * @app:       Back pointer to app
+ */
+struct nfp_neigh_update_work {
+       struct work_struct work;
+       struct neighbour *n;
+       struct nfp_app *app;
+};
+
 enum nfp_flower_mac_offload_cmd {
        NFP_TUNNEL_MAC_OFFLOAD_ADD =            0,
        NFP_TUNNEL_MAC_OFFLOAD_DEL =            1,
@@ -607,38 +619,30 @@ err:
        nfp_flower_cmsg_warn(app, "Neighbour configuration failed.\n");
 }
 
-static int
-nfp_tun_neigh_event_handler(struct notifier_block *nb, unsigned long event,
-                           void *ptr)
+static void
+nfp_tun_release_neigh_update_work(struct nfp_neigh_update_work *update_work)
 {
-       struct nfp_flower_priv *app_priv;
-       struct netevent_redirect *redir;
-       struct neighbour *n;
+       neigh_release(update_work->n);
+       kfree(update_work);
+}
+
+static void nfp_tun_neigh_update(struct work_struct *work)
+{
+       struct nfp_neigh_update_work *update_work;
        struct nfp_app *app;
+       struct neighbour *n;
        bool neigh_invalid;
        int err;
 
-       switch (event) {
-       case NETEVENT_REDIRECT:
-               redir = (struct netevent_redirect *)ptr;
-               n = redir->neigh;
-               break;
-       case NETEVENT_NEIGH_UPDATE:
-               n = (struct neighbour *)ptr;
-               break;
-       default:
-               return NOTIFY_DONE;
-       }
-
-       neigh_invalid = !(n->nud_state & NUD_VALID) || n->dead;
-
-       app_priv = container_of(nb, struct nfp_flower_priv, tun.neigh_nb);
-       app = app_priv->app;
+       update_work = container_of(work, struct nfp_neigh_update_work, work);
+       app = update_work->app;
+       n = update_work->n;
 
        if (!nfp_flower_get_port_id_from_netdev(app, n->dev))
-               return NOTIFY_DONE;
+               goto out;
 
 #if IS_ENABLED(CONFIG_INET)
+       neigh_invalid = !(n->nud_state & NUD_VALID) || n->dead;
        if (n->tbl->family == AF_INET6) {
 #if IS_ENABLED(CONFIG_IPV6)
                struct flowi6 flow6 = {};
@@ -655,13 +659,11 @@ nfp_tun_neigh_event_handler(struct notifier_block *nb, unsigned long event,
                        dst = ip6_dst_lookup_flow(dev_net(n->dev), NULL,
                                                  &flow6, NULL);
                        if (IS_ERR(dst))
-                               return NOTIFY_DONE;
+                               goto out;
 
                        dst_release(dst);
                }
                nfp_tun_write_neigh(n->dev, app, &flow6, n, true, false);
-#else
-               return NOTIFY_DONE;
 #endif /* CONFIG_IPV6 */
        } else {
                struct flowi4 flow4 = {};
@@ -678,17 +680,71 @@ nfp_tun_neigh_event_handler(struct notifier_block *nb, unsigned long event,
                        rt = ip_route_output_key(dev_net(n->dev), &flow4);
                        err = PTR_ERR_OR_ZERO(rt);
                        if (err)
-                               return NOTIFY_DONE;
+                               goto out;
 
                        ip_rt_put(rt);
                }
                nfp_tun_write_neigh(n->dev, app, &flow4, n, false, false);
        }
-#else
-       return NOTIFY_DONE;
 #endif /* CONFIG_INET */
+out:
+       nfp_tun_release_neigh_update_work(update_work);
+}
 
-       return NOTIFY_OK;
+static struct nfp_neigh_update_work *
+nfp_tun_alloc_neigh_update_work(struct nfp_app *app, struct neighbour *n)
+{
+       struct nfp_neigh_update_work *update_work;
+
+       update_work = kzalloc(sizeof(*update_work), GFP_ATOMIC);
+       if (!update_work)
+               return NULL;
+
+       INIT_WORK(&update_work->work, nfp_tun_neigh_update);
+       neigh_hold(n);
+       update_work->n = n;
+       update_work->app = app;
+
+       return update_work;
+}
+
+static int
+nfp_tun_neigh_event_handler(struct notifier_block *nb, unsigned long event,
+                           void *ptr)
+{
+       struct nfp_neigh_update_work *update_work;
+       struct nfp_flower_priv *app_priv;
+       struct netevent_redirect *redir;
+       struct neighbour *n;
+       struct nfp_app *app;
+
+       switch (event) {
+       case NETEVENT_REDIRECT:
+               redir = (struct netevent_redirect *)ptr;
+               n = redir->neigh;
+               break;
+       case NETEVENT_NEIGH_UPDATE:
+               n = (struct neighbour *)ptr;
+               break;
+       default:
+               return NOTIFY_DONE;
+       }
+#if IS_ENABLED(CONFIG_IPV6)
+       if (n->tbl != ipv6_stub->nd_tbl && n->tbl != &arp_tbl)
+#else
+       if (n->tbl != &arp_tbl)
+#endif
+               return NOTIFY_DONE;
+
+       app_priv = container_of(nb, struct nfp_flower_priv, tun.neigh_nb);
+       app = app_priv->app;
+       update_work = nfp_tun_alloc_neigh_update_work(app, n);
+       if (!update_work)
+               return NOTIFY_DONE;
+
+       queue_work(system_highpri_wq, &update_work->work);
+
+       return NOTIFY_DONE;
 }
 
 void nfp_tunnel_request_route_v4(struct nfp_app *app, struct sk_buff *skb)
@@ -706,6 +762,7 @@ void nfp_tunnel_request_route_v4(struct nfp_app *app, struct sk_buff *skb)
        netdev = nfp_app_dev_get(app, be32_to_cpu(payload->ingress_port), NULL);
        if (!netdev)
                goto fail_rcu_unlock;
+       dev_hold(netdev);
 
        flow.daddr = payload->ipv4_addr;
        flow.flowi4_proto = IPPROTO_UDP;
@@ -725,13 +782,16 @@ void nfp_tunnel_request_route_v4(struct nfp_app *app, struct sk_buff *skb)
        ip_rt_put(rt);
        if (!n)
                goto fail_rcu_unlock;
+       rcu_read_unlock();
+
        nfp_tun_write_neigh(n->dev, app, &flow, n, false, true);
        neigh_release(n);
-       rcu_read_unlock();
+       dev_put(netdev);
        return;
 
 fail_rcu_unlock:
        rcu_read_unlock();
+       dev_put(netdev);
        nfp_flower_cmsg_warn(app, "Requested route not found.\n");
 }
 
@@ -749,6 +809,7 @@ void nfp_tunnel_request_route_v6(struct nfp_app *app, struct sk_buff *skb)
        netdev = nfp_app_dev_get(app, be32_to_cpu(payload->ingress_port), NULL);
        if (!netdev)
                goto fail_rcu_unlock;
+       dev_hold(netdev);
 
        flow.daddr = payload->ipv6_addr;
        flow.flowi6_proto = IPPROTO_UDP;
@@ -766,14 +827,16 @@ void nfp_tunnel_request_route_v6(struct nfp_app *app, struct sk_buff *skb)
        dst_release(dst);
        if (!n)
                goto fail_rcu_unlock;
+       rcu_read_unlock();
 
        nfp_tun_write_neigh(n->dev, app, &flow, n, true, true);
        neigh_release(n);
-       rcu_read_unlock();
+       dev_put(netdev);
        return;
 
 fail_rcu_unlock:
        rcu_read_unlock();
+       dev_put(netdev);
        nfp_flower_cmsg_warn(app, "Requested IPv6 route not found.\n");
 }
 
index 1dbc3cb50b1d905469eb31b24857bf15ca3aa029..9b54630400752976471746828142dd494b2cd7f2 100644 (file)
@@ -223,7 +223,7 @@ struct ionic_desc_info {
        void *cb_arg;
 };
 
-#define IONIC_QUEUE_NAME_MAX_SZ                32
+#define IONIC_QUEUE_NAME_MAX_SZ                16
 
 struct ionic_queue {
        struct device *dev;
index edc14730ce88b5f7db438d37b4ad2e93da3cb813..bad919343180e9fa8e2c40d145ac527a9534b98c 100644 (file)
@@ -49,24 +49,24 @@ static void ionic_lif_queue_identify(struct ionic_lif *lif);
 static void ionic_dim_work(struct work_struct *work)
 {
        struct dim *dim = container_of(work, struct dim, work);
+       struct ionic_intr_info *intr;
        struct dim_cq_moder cur_moder;
        struct ionic_qcq *qcq;
+       struct ionic_lif *lif;
        u32 new_coal;
 
        cur_moder = net_dim_get_rx_moderation(dim->mode, dim->profile_ix);
        qcq = container_of(dim, struct ionic_qcq, dim);
-       new_coal = ionic_coal_usec_to_hw(qcq->q.lif->ionic, cur_moder.usec);
+       lif = qcq->q.lif;
+       new_coal = ionic_coal_usec_to_hw(lif->ionic, cur_moder.usec);
        new_coal = new_coal ? new_coal : 1;
 
-       if (qcq->intr.dim_coal_hw != new_coal) {
-               unsigned int qi = qcq->cq.bound_q->index;
-               struct ionic_lif *lif = qcq->q.lif;
-
-               qcq->intr.dim_coal_hw = new_coal;
+       intr = &qcq->intr;
+       if (intr->dim_coal_hw != new_coal) {
+               intr->dim_coal_hw = new_coal;
 
                ionic_intr_coal_init(lif->ionic->idev.intr_ctrl,
-                                    lif->rxqcqs[qi]->intr.index,
-                                    qcq->intr.dim_coal_hw);
+                                    intr->index, intr->dim_coal_hw);
        }
 
        dim->state = DIM_START_MEASURE;
index 62cabeeb842a135684ead5de19bab9872a422ba3..bb787a52bc754412cba47ce6f13381361e6fc44a 100644 (file)
@@ -196,6 +196,7 @@ enum rtl_registers {
                                        /* No threshold before first PCI xfer */
 #define        RX_FIFO_THRESH                  (7 << RXCFG_FIFO_SHIFT)
 #define        RX_EARLY_OFF                    (1 << 11)
+#define        RX_PAUSE_SLOT_ON                (1 << 11)       /* 8125b and later */
 #define        RXCFG_DMA_SHIFT                 8
                                        /* Unlimited maximum PCI burst. */
 #define        RX_DMA_BURST                    (7 << RXCFG_DMA_SHIFT)
@@ -2306,9 +2307,13 @@ static void rtl_init_rxcfg(struct rtl8169_private *tp)
        case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_53:
                RTL_W32(tp, RxConfig, RX128_INT_EN | RX_MULTI_EN | RX_DMA_BURST | RX_EARLY_OFF);
                break;
-       case RTL_GIGA_MAC_VER_61 ... RTL_GIGA_MAC_VER_63:
+       case RTL_GIGA_MAC_VER_61:
                RTL_W32(tp, RxConfig, RX_FETCH_DFLT_8125 | RX_DMA_BURST);
                break;
+       case RTL_GIGA_MAC_VER_63:
+               RTL_W32(tp, RxConfig, RX_FETCH_DFLT_8125 | RX_DMA_BURST |
+                       RX_PAUSE_SLOT_ON);
+               break;
        default:
                RTL_W32(tp, RxConfig, RX128_INT_EN | RX_DMA_BURST);
                break;
index e95d35f1e5a0c8f7932601905bdf2b9fb7600e1e..8fd167501fa0ea10a5f4489bc1d06fef6591b4d9 100644 (file)
@@ -710,28 +710,22 @@ void dwmac5_est_irq_status(void __iomem *ioaddr, struct net_device *dev,
        }
 }
 
-void dwmac5_fpe_configure(void __iomem *ioaddr, u32 num_txq, u32 num_rxq,
+void dwmac5_fpe_configure(void __iomem *ioaddr, struct stmmac_fpe_cfg *cfg,
+                         u32 num_txq, u32 num_rxq,
                          bool enable)
 {
        u32 value;
 
-       if (!enable) {
-               value = readl(ioaddr + MAC_FPE_CTRL_STS);
-
-               value &= ~EFPE;
-
-               writel(value, ioaddr + MAC_FPE_CTRL_STS);
-               return;
+       if (enable) {
+               cfg->fpe_csr = EFPE;
+               value = readl(ioaddr + GMAC_RXQ_CTRL1);
+               value &= ~GMAC_RXQCTRL_FPRQ;
+               value |= (num_rxq - 1) << GMAC_RXQCTRL_FPRQ_SHIFT;
+               writel(value, ioaddr + GMAC_RXQ_CTRL1);
+       } else {
+               cfg->fpe_csr = 0;
        }
-
-       value = readl(ioaddr + GMAC_RXQ_CTRL1);
-       value &= ~GMAC_RXQCTRL_FPRQ;
-       value |= (num_rxq - 1) << GMAC_RXQCTRL_FPRQ_SHIFT;
-       writel(value, ioaddr + GMAC_RXQ_CTRL1);
-
-       value = readl(ioaddr + MAC_FPE_CTRL_STS);
-       value |= EFPE;
-       writel(value, ioaddr + MAC_FPE_CTRL_STS);
+       writel(cfg->fpe_csr, ioaddr + MAC_FPE_CTRL_STS);
 }
 
 int dwmac5_fpe_irq_status(void __iomem *ioaddr, struct net_device *dev)
@@ -741,6 +735,9 @@ int dwmac5_fpe_irq_status(void __iomem *ioaddr, struct net_device *dev)
 
        status = FPE_EVENT_UNKNOWN;
 
+       /* Reads from the MAC_FPE_CTRL_STS register should only be performed
+        * here, since the status flags of MAC_FPE_CTRL_STS are "clear on read"
+        */
        value = readl(ioaddr + MAC_FPE_CTRL_STS);
 
        if (value & TRSP) {
@@ -766,19 +763,15 @@ int dwmac5_fpe_irq_status(void __iomem *ioaddr, struct net_device *dev)
        return status;
 }
 
-void dwmac5_fpe_send_mpacket(void __iomem *ioaddr, enum stmmac_mpacket_type type)
+void dwmac5_fpe_send_mpacket(void __iomem *ioaddr, struct stmmac_fpe_cfg *cfg,
+                            enum stmmac_mpacket_type type)
 {
-       u32 value;
+       u32 value = cfg->fpe_csr;
 
-       value = readl(ioaddr + MAC_FPE_CTRL_STS);
-
-       if (type == MPACKET_VERIFY) {
-               value &= ~SRSP;
+       if (type == MPACKET_VERIFY)
                value |= SVER;
-       } else {
-               value &= ~SVER;
+       else if (type == MPACKET_RESPONSE)
                value |= SRSP;
-       }
 
        writel(value, ioaddr + MAC_FPE_CTRL_STS);
 }
index 53c138d0ff4808d3ca4b4f3fcd456afbe85ae493..34e620790eb37160383e431a431c493545412395 100644 (file)
@@ -153,9 +153,11 @@ int dwmac5_est_configure(void __iomem *ioaddr, struct stmmac_est *cfg,
                         unsigned int ptp_rate);
 void dwmac5_est_irq_status(void __iomem *ioaddr, struct net_device *dev,
                           struct stmmac_extra_stats *x, u32 txqcnt);
-void dwmac5_fpe_configure(void __iomem *ioaddr, u32 num_txq, u32 num_rxq,
+void dwmac5_fpe_configure(void __iomem *ioaddr, struct stmmac_fpe_cfg *cfg,
+                         u32 num_txq, u32 num_rxq,
                          bool enable);
 void dwmac5_fpe_send_mpacket(void __iomem *ioaddr,
+                            struct stmmac_fpe_cfg *cfg,
                             enum stmmac_mpacket_type type);
 int dwmac5_fpe_irq_status(void __iomem *ioaddr, struct net_device *dev);
 
index 453e88b75be08a71d67472fc5bd31b680fd1fd51..a74e71db79f949227525ceedb2d915eb88430aa9 100644 (file)
@@ -1484,7 +1484,8 @@ static int dwxgmac3_est_configure(void __iomem *ioaddr, struct stmmac_est *cfg,
        return 0;
 }
 
-static void dwxgmac3_fpe_configure(void __iomem *ioaddr, u32 num_txq,
+static void dwxgmac3_fpe_configure(void __iomem *ioaddr, struct stmmac_fpe_cfg *cfg,
+                                  u32 num_txq,
                                   u32 num_rxq, bool enable)
 {
        u32 value;
index b95d3e1378136eb485ea88370a6da42a1a75edd7..68aa2d5ca6e56774b03701098abf41c30eb4ac50 100644 (file)
@@ -412,9 +412,11 @@ struct stmmac_ops {
                             unsigned int ptp_rate);
        void (*est_irq_status)(void __iomem *ioaddr, struct net_device *dev,
                               struct stmmac_extra_stats *x, u32 txqcnt);
-       void (*fpe_configure)(void __iomem *ioaddr, u32 num_txq, u32 num_rxq,
+       void (*fpe_configure)(void __iomem *ioaddr, struct stmmac_fpe_cfg *cfg,
+                             u32 num_txq, u32 num_rxq,
                              bool enable);
        void (*fpe_send_mpacket)(void __iomem *ioaddr,
+                                struct stmmac_fpe_cfg *cfg,
                                 enum stmmac_mpacket_type type);
        int (*fpe_irq_status)(void __iomem *ioaddr, struct net_device *dev);
 };
index 2afb2bd25977a2265d998fb2203bbe3a70a9d3f5..37e64283f9107c4c06689d457a061ef9d38b582f 100644 (file)
@@ -964,7 +964,8 @@ static void stmmac_fpe_link_state_handle(struct stmmac_priv *priv, bool is_up)
        bool *hs_enable = &fpe_cfg->hs_enable;
 
        if (is_up && *hs_enable) {
-               stmmac_fpe_send_mpacket(priv, priv->ioaddr, MPACKET_VERIFY);
+               stmmac_fpe_send_mpacket(priv, priv->ioaddr, fpe_cfg,
+                                       MPACKET_VERIFY);
        } else {
                *lo_state = FPE_STATE_OFF;
                *lp_state = FPE_STATE_OFF;
@@ -5839,6 +5840,7 @@ static void stmmac_fpe_event_status(struct stmmac_priv *priv, int status)
                /* If user has requested FPE enable, quickly response */
                if (*hs_enable)
                        stmmac_fpe_send_mpacket(priv, priv->ioaddr,
+                                               fpe_cfg,
                                                MPACKET_RESPONSE);
        }
 
@@ -7263,6 +7265,7 @@ static void stmmac_fpe_lp_task(struct work_struct *work)
                if (*lo_state == FPE_STATE_ENTERING_ON &&
                    *lp_state == FPE_STATE_ENTERING_ON) {
                        stmmac_fpe_configure(priv, priv->ioaddr,
+                                            fpe_cfg,
                                             priv->plat->tx_queues_to_use,
                                             priv->plat->rx_queues_to_use,
                                             *enable);
@@ -7281,6 +7284,7 @@ static void stmmac_fpe_lp_task(struct work_struct *work)
                        netdev_info(priv->dev, SEND_VERIFY_MPAKCET_FMT,
                                    *lo_state, *lp_state);
                        stmmac_fpe_send_mpacket(priv, priv->ioaddr,
+                                               fpe_cfg,
                                                MPACKET_VERIFY);
                }
                /* Sleep then retry */
@@ -7295,6 +7299,7 @@ void stmmac_fpe_handshake(struct stmmac_priv *priv, bool enable)
        if (priv->plat->fpe_cfg->hs_enable != enable) {
                if (enable) {
                        stmmac_fpe_send_mpacket(priv, priv->ioaddr,
+                                               priv->plat->fpe_cfg,
                                                MPACKET_VERIFY);
                } else {
                        priv->plat->fpe_cfg->lo_fpe_state = FPE_STATE_OFF;
@@ -7755,6 +7760,7 @@ int stmmac_suspend(struct device *dev)
        if (priv->dma_cap.fpesel) {
                /* Disable FPE */
                stmmac_fpe_configure(priv, priv->ioaddr,
+                                    priv->plat->fpe_cfg,
                                     priv->plat->tx_queues_to_use,
                                     priv->plat->rx_queues_to_use, false);
 
index ac41ef4cbd2f0243e984d81171ef15ea0173edff..6ad3e0a119366672d0cab3e2c3a1d4b1409abf92 100644 (file)
@@ -1079,6 +1079,7 @@ disable:
 
        priv->plat->fpe_cfg->enable = false;
        stmmac_fpe_configure(priv, priv->ioaddr,
+                            priv->plat->fpe_cfg,
                             priv->plat->tx_queues_to_use,
                             priv->plat->rx_queues_to_use,
                             false);
index ca7bf7f897d36b08e16402cb6be10c664dfc6478..c8cbd85adcf99527f947f4b5a63dc616b533987e 100644 (file)
@@ -3,5 +3,6 @@ config HYPERV_NET
        tristate "Microsoft Hyper-V virtual network driver"
        depends on HYPERV
        select UCS2_STRING
+       select NLS
        help
          Select this option to enable the Hyper-V virtual network driver.
index 2c5c1e91ded613b5e9a23d5c5b93f70bac57c862..9bf2140fd0a1f4dc97a0553854c83cca184d574b 100644 (file)
@@ -3000,6 +3000,8 @@ static void rtl8152_nic_reset(struct r8152 *tp)
                ocp_write_byte(tp, MCU_TYPE_PLA, PLA_CR, CR_RST);
 
                for (i = 0; i < 1000; i++) {
+                       if (test_bit(RTL8152_INACCESSIBLE, &tp->flags))
+                               break;
                        if (!(ocp_read_byte(tp, MCU_TYPE_PLA, PLA_CR) & CR_RST))
                                break;
                        usleep_range(100, 400);
@@ -3329,6 +3331,8 @@ static void rtl_disable(struct r8152 *tp)
        rxdy_gated_en(tp, true);
 
        for (i = 0; i < 1000; i++) {
+               if (test_bit(RTL8152_INACCESSIBLE, &tp->flags))
+                       break;
                ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL);
                if ((ocp_data & FIFO_EMPTY) == FIFO_EMPTY)
                        break;
@@ -3336,6 +3340,8 @@ static void rtl_disable(struct r8152 *tp)
        }
 
        for (i = 0; i < 1000; i++) {
+               if (test_bit(RTL8152_INACCESSIBLE, &tp->flags))
+                       break;
                if (ocp_read_word(tp, MCU_TYPE_PLA, PLA_TCR0) & TCR0_TX_EMPTY)
                        break;
                usleep_range(1000, 2000);
@@ -5499,6 +5505,8 @@ static void wait_oob_link_list_ready(struct r8152 *tp)
        int i;
 
        for (i = 0; i < 1000; i++) {
+               if (test_bit(RTL8152_INACCESSIBLE, &tp->flags))
+                       break;
                ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL);
                if (ocp_data & LINK_LIST_READY)
                        break;
@@ -5513,6 +5521,8 @@ static void r8156b_wait_loading_flash(struct r8152 *tp)
                int i;
 
                for (i = 0; i < 100; i++) {
+                       if (test_bit(RTL8152_INACCESSIBLE, &tp->flags))
+                               break;
                        if (ocp_read_word(tp, MCU_TYPE_USB, USB_GPHY_CTRL) & GPHY_PATCH_DONE)
                                break;
                        usleep_range(1000, 2000);
@@ -5635,6 +5645,8 @@ static int r8153_pre_firmware_1(struct r8152 *tp)
        for (i = 0; i < 104; i++) {
                u32 ocp_data = ocp_read_byte(tp, MCU_TYPE_USB, USB_WDT1_CTRL);
 
+               if (test_bit(RTL8152_INACCESSIBLE, &tp->flags))
+                       return -ENODEV;
                if (!(ocp_data & WTD1_EN))
                        break;
                usleep_range(1000, 2000);
@@ -5791,6 +5803,8 @@ static void r8153_aldps_en(struct r8152 *tp, bool enable)
                data &= ~EN_ALDPS;
                ocp_reg_write(tp, OCP_POWER_CFG, data);
                for (i = 0; i < 20; i++) {
+                       if (test_bit(RTL8152_INACCESSIBLE, &tp->flags))
+                               return;
                        usleep_range(1000, 2000);
                        if (ocp_read_word(tp, MCU_TYPE_PLA, 0xe000) & 0x0100)
                                break;
@@ -8397,6 +8411,8 @@ static int rtl8152_pre_reset(struct usb_interface *intf)
        struct r8152 *tp = usb_get_intfdata(intf);
        struct net_device *netdev;
 
+       rtnl_lock();
+
        if (!tp || !test_bit(PROBED_WITH_NO_ERRORS, &tp->flags))
                return 0;
 
@@ -8428,20 +8444,17 @@ static int rtl8152_post_reset(struct usb_interface *intf)
        struct sockaddr sa;
 
        if (!tp || !test_bit(PROBED_WITH_NO_ERRORS, &tp->flags))
-               return 0;
+               goto exit;
 
        rtl_set_accessible(tp);
 
        /* reset the MAC address in case of policy change */
-       if (determine_ethernet_addr(tp, &sa) >= 0) {
-               rtnl_lock();
+       if (determine_ethernet_addr(tp, &sa) >= 0)
                dev_set_mac_address (tp->netdev, &sa, NULL);
-               rtnl_unlock();
-       }
 
        netdev = tp->netdev;
        if (!netif_running(netdev))
-               return 0;
+               goto exit;
 
        set_bit(WORK_ENABLE, &tp->flags);
        if (netif_carrier_ok(netdev)) {
@@ -8460,6 +8473,8 @@ static int rtl8152_post_reset(struct usb_interface *intf)
        if (!list_empty(&tp->rx_done))
                napi_schedule(&tp->napi);
 
+exit:
+       rtnl_unlock();
        return 0;
 }
 
@@ -10034,6 +10049,7 @@ static const struct usb_device_id rtl8152_table[] = {
        { USB_DEVICE(VENDOR_ID_NVIDIA,  0x09ff) },
        { USB_DEVICE(VENDOR_ID_TPLINK,  0x0601) },
        { USB_DEVICE(VENDOR_ID_DLINK,   0xb301) },
+       { USB_DEVICE(VENDOR_ID_ASUS,    0x1976) },
        {}
 };
 
index 57efb3454c57aca0c5bf4e790226f2c7176c8468..977861c46b1fe16a27872b5df76e067409ae2da2 100644 (file)
@@ -790,7 +790,8 @@ static int veth_convert_skb_to_xdp_buff(struct veth_rq *rq,
 
                        skb_add_rx_frag(nskb, i, page, page_offset, size,
                                        truesize);
-                       if (skb_copy_bits(skb, off, page_address(page),
+                       if (skb_copy_bits(skb, off,
+                                         page_address(page) + page_offset,
                                          size)) {
                                consume_skb(nskb);
                                goto drop;
index f63250c650cafdae49c7b558d47528a1af632689..3bf27052832f302ac72d366b986629e03db4e900 100644 (file)
@@ -98,8 +98,9 @@ int of_reconfig_notify(unsigned long action, struct of_reconfig_data *p)
  *
  * Returns the new state of a device based on the notifier used.
  *
- * Return: 0 on device going from enabled to disabled, 1 on device
- * going from disabled to enabled and -1 on no change.
+ * Return: OF_RECONFIG_CHANGE_REMOVE on device going from enabled to
+ * disabled, OF_RECONFIG_CHANGE_ADD on device going from disabled to
+ * enabled and OF_RECONFIG_NO_CHANGE on no change.
  */
 int of_reconfig_get_state_change(unsigned long action, struct of_reconfig_data *pr)
 {
index 1ac7dab22c637e9d6bffab03c75217c03b7e51de..c1aef3a8fb2de28cd78bb0a86e979eb8ea2d580b 100644 (file)
@@ -20,6 +20,7 @@
 
 #define MLXBF_BOOTCTL_SB_SECURE_MASK           0x03
 #define MLXBF_BOOTCTL_SB_TEST_MASK             0x0c
+#define MLXBF_BOOTCTL_SB_DEV_MASK              BIT(4)
 
 #define MLXBF_SB_KEY_NUM                       4
 
@@ -40,11 +41,18 @@ static struct mlxbf_bootctl_name boot_names[] = {
        { MLXBF_BOOTCTL_NONE, "none" },
 };
 
+enum {
+       MLXBF_BOOTCTL_SB_LIFECYCLE_PRODUCTION = 0,
+       MLXBF_BOOTCTL_SB_LIFECYCLE_GA_SECURE = 1,
+       MLXBF_BOOTCTL_SB_LIFECYCLE_GA_NON_SECURE = 2,
+       MLXBF_BOOTCTL_SB_LIFECYCLE_RMA = 3
+};
+
 static const char * const mlxbf_bootctl_lifecycle_states[] = {
-       [0] = "Production",
-       [1] = "GA Secured",
-       [2] = "GA Non-Secured",
-       [3] = "RMA",
+       [MLXBF_BOOTCTL_SB_LIFECYCLE_PRODUCTION] = "Production",
+       [MLXBF_BOOTCTL_SB_LIFECYCLE_GA_SECURE] = "GA Secured",
+       [MLXBF_BOOTCTL_SB_LIFECYCLE_GA_NON_SECURE] = "GA Non-Secured",
+       [MLXBF_BOOTCTL_SB_LIFECYCLE_RMA] = "RMA",
 };
 
 /* Log header format. */
@@ -247,25 +255,30 @@ static ssize_t second_reset_action_store(struct device *dev,
 static ssize_t lifecycle_state_show(struct device *dev,
                                    struct device_attribute *attr, char *buf)
 {
+       int status_bits;
+       int use_dev_key;
+       int test_state;
        int lc_state;
 
-       lc_state = mlxbf_bootctl_smc(MLXBF_BOOTCTL_GET_TBB_FUSE_STATUS,
-                                    MLXBF_BOOTCTL_FUSE_STATUS_LIFECYCLE);
-       if (lc_state < 0)
-               return lc_state;
+       status_bits = mlxbf_bootctl_smc(MLXBF_BOOTCTL_GET_TBB_FUSE_STATUS,
+                                       MLXBF_BOOTCTL_FUSE_STATUS_LIFECYCLE);
+       if (status_bits < 0)
+               return status_bits;
 
-       lc_state &=
-               MLXBF_BOOTCTL_SB_TEST_MASK | MLXBF_BOOTCTL_SB_SECURE_MASK;
+       use_dev_key = status_bits & MLXBF_BOOTCTL_SB_DEV_MASK;
+       test_state = status_bits & MLXBF_BOOTCTL_SB_TEST_MASK;
+       lc_state = status_bits & MLXBF_BOOTCTL_SB_SECURE_MASK;
 
        /*
         * If the test bits are set, we specify that the current state may be
         * due to using the test bits.
         */
-       if (lc_state & MLXBF_BOOTCTL_SB_TEST_MASK) {
-               lc_state &= MLXBF_BOOTCTL_SB_SECURE_MASK;
-
+       if (test_state) {
                return sprintf(buf, "%s(test)\n",
                               mlxbf_bootctl_lifecycle_states[lc_state]);
+       } else if (use_dev_key &&
+                  (lc_state == MLXBF_BOOTCTL_SB_LIFECYCLE_GA_SECURE)) {
+               return sprintf(buf, "Secured (development)\n");
        }
 
        return sprintf(buf, "%s\n", mlxbf_bootctl_lifecycle_states[lc_state]);
index 0b427fc24a96e76986dc15f35370469305e385c9..1dd84c7a79de97f44b25c48fd241db068492b4f9 100644 (file)
@@ -1771,6 +1771,8 @@ static int mlxbf_pmc_init_perftype_counter(struct device *dev, int blk_num)
        attr->dev_attr.show = mlxbf_pmc_event_list_show;
        attr->nr = blk_num;
        attr->dev_attr.attr.name = devm_kasprintf(dev, GFP_KERNEL, "event_list");
+       if (!attr->dev_attr.attr.name)
+               return -ENOMEM;
        pmc->block[blk_num].block_attr[i] = &attr->dev_attr.attr;
        attr = NULL;
 
@@ -1784,6 +1786,8 @@ static int mlxbf_pmc_init_perftype_counter(struct device *dev, int blk_num)
                attr->nr = blk_num;
                attr->dev_attr.attr.name = devm_kasprintf(dev, GFP_KERNEL,
                                                          "enable");
+               if (!attr->dev_attr.attr.name)
+                       return -ENOMEM;
                pmc->block[blk_num].block_attr[++i] = &attr->dev_attr.attr;
                attr = NULL;
        }
@@ -1810,6 +1814,8 @@ static int mlxbf_pmc_init_perftype_counter(struct device *dev, int blk_num)
                attr->nr = blk_num;
                attr->dev_attr.attr.name = devm_kasprintf(dev, GFP_KERNEL,
                                                          "counter%d", j);
+               if (!attr->dev_attr.attr.name)
+                       return -ENOMEM;
                pmc->block[blk_num].block_attr[++i] = &attr->dev_attr.attr;
                attr = NULL;
 
@@ -1821,6 +1827,8 @@ static int mlxbf_pmc_init_perftype_counter(struct device *dev, int blk_num)
                attr->nr = blk_num;
                attr->dev_attr.attr.name = devm_kasprintf(dev, GFP_KERNEL,
                                                          "event%d", j);
+               if (!attr->dev_attr.attr.name)
+                       return -ENOMEM;
                pmc->block[blk_num].block_attr[++i] = &attr->dev_attr.attr;
                attr = NULL;
        }
@@ -1853,6 +1861,8 @@ static int mlxbf_pmc_init_perftype_reg(struct device *dev, int blk_num)
                attr->nr = blk_num;
                attr->dev_attr.attr.name = devm_kasprintf(dev, GFP_KERNEL,
                                                          events[j].evt_name);
+               if (!attr->dev_attr.attr.name)
+                       return -ENOMEM;
                pmc->block[blk_num].block_attr[i] = &attr->dev_attr.attr;
                attr = NULL;
                i++;
@@ -1882,6 +1892,8 @@ static int mlxbf_pmc_create_groups(struct device *dev, int blk_num)
        pmc->block[blk_num].block_attr_grp.attrs = pmc->block[blk_num].block_attr;
        pmc->block[blk_num].block_attr_grp.name = devm_kasprintf(
                dev, GFP_KERNEL, pmc->block_name[blk_num]);
+       if (!pmc->block[blk_num].block_attr_grp.name)
+               return -ENOMEM;
        pmc->groups[pmc->group_num] = &pmc->block[blk_num].block_attr_grp;
        pmc->group_num++;
 
@@ -2063,6 +2075,8 @@ static int mlxbf_pmc_probe(struct platform_device *pdev)
 
        pmc->hwmon_dev = devm_hwmon_device_register_with_groups(
                dev, "bfperf", pmc, pmc->groups);
+       if (IS_ERR(pmc->hwmon_dev))
+               return PTR_ERR(pmc->hwmon_dev);
        platform_set_drvdata(pdev, pmc);
 
        return 0;
index 1a6373dea109cc2b63ad887bb0adb08cadd4a7e5..6152be38398c48feac4b48a5084faea7448365c1 100644 (file)
@@ -231,9 +231,12 @@ static int ssam_receive_buf(struct serdev_device *dev, const unsigned char *buf,
                            size_t n)
 {
        struct ssam_controller *ctrl;
+       int ret;
 
        ctrl = serdev_device_get_drvdata(dev);
-       return ssam_controller_receive_buf(ctrl, buf, n);
+       ret = ssam_controller_receive_buf(ctrl, buf, n);
+
+       return ret < 0 ? 0 : ret;
 }
 
 static void ssam_write_wakeup(struct serdev_device *dev)
index 7e69fdaccdd5357cebe8ad44aa7cb5f17c714690..c94f31a5c6a3364707f82b4ec64b193940f2d196 100644 (file)
@@ -263,6 +263,7 @@ config ASUS_WMI
        depends on RFKILL || RFKILL = n
        depends on HOTPLUG_PCI
        depends on ACPI_VIDEO || ACPI_VIDEO = n
+       depends on SERIO_I8042 || SERIO_I8042 = n
        select INPUT_SPARSEKMAP
        select LEDS_CLASS
        select NEW_LEDS
@@ -279,7 +280,6 @@ config ASUS_WMI
 config ASUS_NB_WMI
        tristate "Asus Notebook WMI Driver"
        depends on ASUS_WMI
-       depends on SERIO_I8042 || SERIO_I8042 = n
        help
          This is a driver for newer Asus notebooks. It adds extra features
          like wireless radio and bluetooth control, leds, hotkeys, backlight...
index 9aa1226e74e6c56d3f19634a836027d4ed508577..fceffe2082ec582d6c432d372de5f05cc298e9cc 100644 (file)
@@ -48,25 +48,43 @@ module_param(tablet_mode_sw, uint, 0444);
 MODULE_PARM_DESC(tablet_mode_sw, "Tablet mode detect: -1:auto 0:disable 1:kbd-dock 2:lid-flip 3:lid-flip-rog");
 
 static struct quirk_entry *quirks;
+static bool atkbd_reports_vol_keys;
 
-static bool asus_q500a_i8042_filter(unsigned char data, unsigned char str,
-                             struct serio *port)
+static bool asus_i8042_filter(unsigned char data, unsigned char str, struct serio *port)
 {
-       static bool extended;
-       bool ret = false;
+       static bool extended_e0;
+       static bool extended_e1;
 
        if (str & I8042_STR_AUXDATA)
                return false;
 
-       if (unlikely(data == 0xe1)) {
-               extended = true;
-               ret = true;
-       } else if (unlikely(extended)) {
-               extended = false;
-               ret = true;
+       if (quirks->filter_i8042_e1_extended_codes) {
+               if (data == 0xe1) {
+                       extended_e1 = true;
+                       return true;
+               }
+
+               if (extended_e1) {
+                       extended_e1 = false;
+                       return true;
+               }
        }
 
-       return ret;
+       if (data == 0xe0) {
+               extended_e0 = true;
+       } else if (extended_e0) {
+               extended_e0 = false;
+
+               switch (data & 0x7f) {
+               case 0x20: /* e0 20 / e0 a0, Volume Mute press / release */
+               case 0x2e: /* e0 2e / e0 ae, Volume Down press / release */
+               case 0x30: /* e0 30 / e0 b0, Volume Up press / release */
+                       atkbd_reports_vol_keys = true;
+                       break;
+               }
+       }
+
+       return false;
 }
 
 static struct quirk_entry quirk_asus_unknown = {
@@ -75,7 +93,7 @@ static struct quirk_entry quirk_asus_unknown = {
 };
 
 static struct quirk_entry quirk_asus_q500a = {
-       .i8042_filter = asus_q500a_i8042_filter,
+       .filter_i8042_e1_extended_codes = true,
        .wmi_backlight_set_devstate = true,
 };
 
@@ -503,8 +521,6 @@ static const struct dmi_system_id asus_quirks[] = {
 
 static void asus_nb_wmi_quirks(struct asus_wmi_driver *driver)
 {
-       int ret;
-
        quirks = &quirk_asus_unknown;
        dmi_check_system(asus_quirks);
 
@@ -519,15 +535,6 @@ static void asus_nb_wmi_quirks(struct asus_wmi_driver *driver)
 
        if (tablet_mode_sw != -1)
                quirks->tablet_switch_mode = tablet_mode_sw;
-
-       if (quirks->i8042_filter) {
-               ret = i8042_install_filter(quirks->i8042_filter);
-               if (ret) {
-                       pr_warn("Unable to install key filter\n");
-                       return;
-               }
-               pr_info("Using i8042 filter function for receiving events\n");
-       }
 }
 
 static const struct key_entry asus_nb_wmi_keymap[] = {
@@ -617,6 +624,13 @@ static void asus_nb_wmi_key_filter(struct asus_wmi_driver *asus_wmi, int *code,
                if (acpi_video_handles_brightness_key_presses())
                        *code = ASUS_WMI_KEY_IGNORE;
 
+               break;
+       case 0x30: /* Volume Up */
+       case 0x31: /* Volume Down */
+       case 0x32: /* Volume Mute */
+               if (atkbd_reports_vol_keys)
+                       *code = ASUS_WMI_KEY_IGNORE;
+
                break;
        }
 }
@@ -630,6 +644,7 @@ static struct asus_wmi_driver asus_nb_wmi_driver = {
        .input_phys = ASUS_NB_WMI_FILE "/input0",
        .detect_quirks = asus_nb_wmi_quirks,
        .key_filter = asus_nb_wmi_key_filter,
+       .i8042_filter = asus_i8042_filter,
 };
 
 
index 6a79f16233abf737d6242bd938af791f007793ac..9f7e23c5c6b4da2c5d58e092c40d4ac716ee3317 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/acpi.h>
 #include <linux/backlight.h>
 #include <linux/debugfs.h>
+#include <linux/delay.h>
 #include <linux/dmi.h>
 #include <linux/fb.h>
 #include <linux/hwmon.h>
@@ -132,6 +133,11 @@ module_param(fnlock_default, bool, 0444);
 #define ASUS_SCREENPAD_BRIGHT_MAX 255
 #define ASUS_SCREENPAD_BRIGHT_DEFAULT 60
 
+/* Controls the power state of the USB0 hub on ROG Ally which input is on */
+#define ASUS_USB0_PWR_EC0_CSEE "\\_SB.PCI0.SBRG.EC0.CSEE"
+/* 300ms so far seems to produce a reliable result on AC and battery */
+#define ASUS_USB0_PWR_EC0_CSEE_WAIT 300
+
 static const char * const ashs_ids[] = { "ATK4001", "ATK4002", NULL };
 
 static int throttle_thermal_policy_write(struct asus_wmi *);
@@ -300,6 +306,9 @@ struct asus_wmi {
 
        bool fnlock_locked;
 
+       /* The ROG Ally device requires the MCU USB device be disconnected before suspend */
+       bool ally_mcu_usb_switch;
+
        struct asus_wmi_debug debug;
 
        struct asus_wmi_driver *driver;
@@ -4488,6 +4497,8 @@ static int asus_wmi_add(struct platform_device *pdev)
        asus->nv_temp_tgt_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_NV_THERM_TARGET);
        asus->panel_overdrive_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_PANEL_OD);
        asus->mini_led_mode_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_MINI_LED_MODE);
+       asus->ally_mcu_usb_switch = acpi_has_method(NULL, ASUS_USB0_PWR_EC0_CSEE)
+                                               && dmi_match(DMI_BOARD_NAME, "RC71L");
 
        err = fan_boost_mode_check_present(asus);
        if (err)
@@ -4567,6 +4578,12 @@ static int asus_wmi_add(struct platform_device *pdev)
                goto fail_wmi_handler;
        }
 
+       if (asus->driver->i8042_filter) {
+               err = i8042_install_filter(asus->driver->i8042_filter);
+               if (err)
+                       pr_warn("Unable to install key filter - %d\n", err);
+       }
+
        asus_wmi_battery_init(asus);
 
        asus_wmi_debugfs_init(asus);
@@ -4603,6 +4620,8 @@ static int asus_wmi_remove(struct platform_device *device)
        struct asus_wmi *asus;
 
        asus = platform_get_drvdata(device);
+       if (asus->driver->i8042_filter)
+               i8042_remove_filter(asus->driver->i8042_filter);
        wmi_remove_notify_handler(asus->driver->event_guid);
        asus_wmi_backlight_exit(asus);
        asus_screenpad_exit(asus);
@@ -4654,6 +4673,43 @@ static int asus_hotk_resume(struct device *device)
                asus_wmi_fnlock_update(asus);
 
        asus_wmi_tablet_mode_get_state(asus);
+
+       return 0;
+}
+
+static int asus_hotk_resume_early(struct device *device)
+{
+       struct asus_wmi *asus = dev_get_drvdata(device);
+
+       if (asus->ally_mcu_usb_switch) {
+               if (ACPI_FAILURE(acpi_execute_simple_method(NULL, ASUS_USB0_PWR_EC0_CSEE, 0xB8)))
+                       dev_err(device, "ROG Ally MCU failed to connect USB dev\n");
+               else
+                       msleep(ASUS_USB0_PWR_EC0_CSEE_WAIT);
+       }
+       return 0;
+}
+
+static int asus_hotk_prepare(struct device *device)
+{
+       struct asus_wmi *asus = dev_get_drvdata(device);
+       int result, err;
+
+       if (asus->ally_mcu_usb_switch) {
+               /* When powersave is enabled it causes many issues with resume of USB hub */
+               result = asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_MCU_POWERSAVE);
+               if (result == 1) {
+                       dev_warn(device, "MCU powersave enabled, disabling to prevent resume issues");
+                       err = asus_wmi_set_devstate(ASUS_WMI_DEVID_MCU_POWERSAVE, 0, &result);
+                       if (err || result != 1)
+                               dev_err(device, "Failed to set MCU powersave mode: %d\n", err);
+               }
+               /* sleep required to ensure USB0 is disabled before sleep continues */
+               if (ACPI_FAILURE(acpi_execute_simple_method(NULL, ASUS_USB0_PWR_EC0_CSEE, 0xB7)))
+                       dev_err(device, "ROG Ally MCU failed to disconnect USB dev\n");
+               else
+                       msleep(ASUS_USB0_PWR_EC0_CSEE_WAIT);
+       }
        return 0;
 }
 
@@ -4701,6 +4757,8 @@ static const struct dev_pm_ops asus_pm_ops = {
        .thaw = asus_hotk_thaw,
        .restore = asus_hotk_restore,
        .resume = asus_hotk_resume,
+       .resume_early = asus_hotk_resume_early,
+       .prepare = asus_hotk_prepare,
 };
 
 /* Registration ***************************************************************/
index adb67c92572487856bd0834b6345513dbbdfe6ae..cc30f185384723f65f383b78b0075128406fc6ae 100644 (file)
@@ -39,6 +39,7 @@ struct quirk_entry {
        bool wmi_backlight_set_devstate;
        bool wmi_force_als_set;
        bool wmi_ignore_fan;
+       bool filter_i8042_e1_extended_codes;
        enum asus_wmi_tablet_switch_mode tablet_switch_mode;
        int wapf;
        /*
@@ -49,9 +50,6 @@ struct quirk_entry {
         */
        int no_display_toggle;
        u32 xusb2pr;
-
-       bool (*i8042_filter)(unsigned char data, unsigned char str,
-                            struct serio *serio);
 };
 
 struct asus_wmi_driver {
@@ -73,6 +71,9 @@ struct asus_wmi_driver {
         * Return ASUS_WMI_KEY_IGNORE in code if event should be ignored. */
        void (*key_filter) (struct asus_wmi_driver *driver, int *code,
                            unsigned int *value, bool *autorelease);
+       /* Optional standard i8042 filter */
+       bool (*i8042_filter)(unsigned char data, unsigned char str,
+                            struct serio *serio);
 
        int (*probe) (struct platform_device *device);
        void (*detect_quirks) (struct asus_wmi_driver *driver);
index 5c27b4aa969049ce5c6c4f97fc2ba08a41dde7b5..5dd22258cb3bc2b350331ce07431b8ecf6c45734 100644 (file)
@@ -1340,6 +1340,11 @@ static int parse_wdg(struct device *wmi_bus_dev, struct platform_device *pdev)
                if (debug_dump_wdg)
                        wmi_dump_wdg(&gblock[i]);
 
+               if (!gblock[i].instance_count) {
+                       dev_info(wmi_bus_dev, FW_INFO "%pUL has zero instances\n", &gblock[i].guid);
+                       continue;
+               }
+
                if (guid_already_parsed_for_legacy(device, &gblock[i].guid))
                        continue;
 
index 9777babd5b95cd9fc3a4388745840ab1a7e2bbdc..ab30667f4f951c0d46ccbeddf365437652c269ba 100644 (file)
@@ -155,6 +155,8 @@ static int bcm2835_pwm_probe(struct platform_device *pdev)
        pc->chip.ops = &bcm2835_pwm_ops;
        pc->chip.npwm = 2;
 
+       platform_set_drvdata(pdev, pc);
+
        ret = devm_pwmchip_add(&pdev->dev, &pc->chip);
        if (ret < 0)
                return dev_err_probe(&pdev->dev, ret,
index 64f0e047c23d2a16d54099f486400eec8c361adf..4b10921276942ed13a43e531b723e746b76dd6fa 100644 (file)
@@ -60,7 +60,16 @@ static void optee_release_device(struct device *dev)
        kfree(optee_device);
 }
 
-static int optee_register_device(const uuid_t *device_uuid)
+static ssize_t need_supplicant_show(struct device *dev,
+                                   struct device_attribute *attr,
+                                   char *buf)
+{
+       return 0;
+}
+
+static DEVICE_ATTR_RO(need_supplicant);
+
+static int optee_register_device(const uuid_t *device_uuid, u32 func)
 {
        struct tee_client_device *optee_device = NULL;
        int rc;
@@ -83,6 +92,10 @@ static int optee_register_device(const uuid_t *device_uuid)
                put_device(&optee_device->dev);
        }
 
+       if (func == PTA_CMD_GET_DEVICES_SUPP)
+               device_create_file(&optee_device->dev,
+                                  &dev_attr_need_supplicant);
+
        return rc;
 }
 
@@ -142,7 +155,7 @@ static int __optee_enumerate_devices(u32 func)
        num_devices = shm_size / sizeof(uuid_t);
 
        for (idx = 0; idx < num_devices; idx++) {
-               rc = optee_register_device(&device_uuid[idx]);
+               rc = optee_register_device(&device_uuid[idx], func);
                if (rc)
                        goto out_shm;
        }
index 12ac3397f39b819aa766e6da8a90e906b4350988..26ba7da6b410621ea72e65d4bb90bd192e06dbda 100644 (file)
@@ -2815,13 +2815,18 @@ static int setup_cvq_vring(struct mlx5_vdpa_dev *mvdev)
        struct mlx5_control_vq *cvq = &mvdev->cvq;
        int err = 0;
 
-       if (mvdev->actual_features & BIT_ULL(VIRTIO_NET_F_CTRL_VQ))
+       if (mvdev->actual_features & BIT_ULL(VIRTIO_NET_F_CTRL_VQ)) {
+               u16 idx = cvq->vring.last_avail_idx;
+
                err = vringh_init_iotlb(&cvq->vring, mvdev->actual_features,
                                        MLX5_CVQ_MAX_ENT, false,
                                        (struct vring_desc *)(uintptr_t)cvq->desc_addr,
                                        (struct vring_avail *)(uintptr_t)cvq->driver_addr,
                                        (struct vring_used *)(uintptr_t)cvq->device_addr);
 
+               if (!err)
+                       cvq->vring.last_avail_idx = cvq->vring.last_used_idx = idx;
+       }
        return err;
 }
 
index 9b04aad6ec35d7499da38d1209fb53a1cdae91a9..c328e694f6e7f0716a9eee53d21e1d6977b64e80 100644 (file)
@@ -261,7 +261,7 @@ void pds_vdpa_debugfs_add_vdpadev(struct pds_vdpa_aux *vdpa_aux)
        debugfs_create_file("config", 0400, vdpa_aux->dentry, vdpa_aux->pdsv, &config_fops);
 
        for (i = 0; i < vdpa_aux->pdsv->num_vqs; i++) {
-               char name[8];
+               char name[16];
 
                snprintf(name, sizeof(name), "vq%02d", i);
                debugfs_create_file(name, 0400, vdpa_aux->dentry,
index 52b2449182ad71976cc68cb58aa8b52a77ff5cea..25c0fe5ec3d5dfacdb53fa31a709851adb118942 100644 (file)
@@ -318,9 +318,8 @@ static int pds_vdpa_set_driver_features(struct vdpa_device *vdpa_dev, u64 featur
                return -EOPNOTSUPP;
        }
 
-       pdsv->negotiated_features = nego_features;
-
        driver_features = pds_vdpa_get_driver_features(vdpa_dev);
+       pdsv->negotiated_features = nego_features;
        dev_dbg(dev, "%s: %#llx => %#llx\n",
                __func__, driver_features, nego_features);
 
@@ -461,8 +460,10 @@ static void pds_vdpa_set_status(struct vdpa_device *vdpa_dev, u8 status)
 
        pds_vdpa_cmd_set_status(pdsv, status);
 
-       /* Note: still working with FW on the need for this reset cmd */
        if (status == 0) {
+               struct vdpa_callback null_cb = { };
+
+               pds_vdpa_set_config_cb(vdpa_dev, &null_cb);
                pds_vdpa_cmd_reset(pdsv);
 
                for (i = 0; i < pdsv->num_vqs; i++) {
index fd1f655b4f1ff38d20df8d939e750e9982d02147..42837617a55b5464b7fe0f63b4fa1326ab3717cc 100644 (file)
@@ -268,6 +268,7 @@ config HUGETLBFS
 
 config HUGETLB_PAGE
        def_bool HUGETLBFS
+       select XARRAY_MULTI
 
 config HUGETLB_PAGE_OPTIMIZE_VMEMMAP
        def_bool HUGETLB_PAGE
index 2c6078a6b8ecb5edd9b1c1b69b192dfef7c47b00..58ca7c936393c4982bb1431e4d75841fd4183553 100644 (file)
@@ -501,15 +501,38 @@ int nilfs_sufile_mark_dirty(struct inode *sufile, __u64 segnum)
 
        down_write(&NILFS_MDT(sufile)->mi_sem);
        ret = nilfs_sufile_get_segment_usage_block(sufile, segnum, 0, &bh);
-       if (!ret) {
-               mark_buffer_dirty(bh);
-               nilfs_mdt_mark_dirty(sufile);
-               kaddr = kmap_atomic(bh->b_page);
-               su = nilfs_sufile_block_get_segment_usage(sufile, segnum, bh, kaddr);
+       if (ret)
+               goto out_sem;
+
+       kaddr = kmap_atomic(bh->b_page);
+       su = nilfs_sufile_block_get_segment_usage(sufile, segnum, bh, kaddr);
+       if (unlikely(nilfs_segment_usage_error(su))) {
+               struct the_nilfs *nilfs = sufile->i_sb->s_fs_info;
+
+               kunmap_atomic(kaddr);
+               brelse(bh);
+               if (nilfs_segment_is_active(nilfs, segnum)) {
+                       nilfs_error(sufile->i_sb,
+                                   "active segment %llu is erroneous",
+                                   (unsigned long long)segnum);
+               } else {
+                       /*
+                        * Segments marked erroneous are never allocated by
+                        * nilfs_sufile_alloc(); only active segments, ie,
+                        * the segments indexed by ns_segnum or ns_nextnum,
+                        * can be erroneous here.
+                        */
+                       WARN_ON_ONCE(1);
+               }
+               ret = -EIO;
+       } else {
                nilfs_segment_usage_set_dirty(su);
                kunmap_atomic(kaddr);
+               mark_buffer_dirty(bh);
+               nilfs_mdt_mark_dirty(sufile);
                brelse(bh);
        }
+out_sem:
        up_write(&NILFS_MDT(sufile)->mi_sem);
        return ret;
 }
@@ -536,9 +559,14 @@ int nilfs_sufile_set_segment_usage(struct inode *sufile, __u64 segnum,
 
        kaddr = kmap_atomic(bh->b_page);
        su = nilfs_sufile_block_get_segment_usage(sufile, segnum, bh, kaddr);
-       WARN_ON(nilfs_segment_usage_error(su));
-       if (modtime)
+       if (modtime) {
+               /*
+                * Check segusage error and set su_lastmod only when updating
+                * this entry with a valid timestamp, not for cancellation.
+                */
+               WARN_ON_ONCE(nilfs_segment_usage_error(su));
                su->su_lastmod = cpu_to_le64(modtime);
+       }
        su->su_nblocks = cpu_to_le32(nblocks);
        kunmap_atomic(kaddr);
 
index 0f0667957c8100d79f1b41f593fb5dc36cebe20a..71400496ed36519d2524ab552efed3e150899a52 100644 (file)
@@ -716,7 +716,11 @@ int init_nilfs(struct the_nilfs *nilfs, struct super_block *sb, char *data)
                        goto failed_sbh;
                }
                nilfs_release_super_block(nilfs);
-               sb_set_blocksize(sb, blocksize);
+               if (!sb_set_blocksize(sb, blocksize)) {
+                       nilfs_err(sb, "bad blocksize %d", blocksize);
+                       err = -EINVAL;
+                       goto out;
+               }
 
                err = nilfs_load_super_block(nilfs, sb, blocksize, &sbp);
                if (err)
index ef2eb12906da88c6fe3a227e82598020f0badc44..435b61054b5b9e768ac34fafd4bf5a7a2c378f89 100644 (file)
@@ -1982,15 +1982,31 @@ static int pagemap_scan_test_walk(unsigned long start, unsigned long end,
        struct pagemap_scan_private *p = walk->private;
        struct vm_area_struct *vma = walk->vma;
        unsigned long vma_category = 0;
+       bool wp_allowed = userfaultfd_wp_async(vma) &&
+           userfaultfd_wp_use_markers(vma);
 
-       if (userfaultfd_wp_async(vma) && userfaultfd_wp_use_markers(vma))
-               vma_category |= PAGE_IS_WPALLOWED;
-       else if (p->arg.flags & PM_SCAN_CHECK_WPASYNC)
-               return -EPERM;
+       if (!wp_allowed) {
+               /* User requested explicit failure over wp-async capability */
+               if (p->arg.flags & PM_SCAN_CHECK_WPASYNC)
+                       return -EPERM;
+               /*
+                * User requires wr-protect, and allows silently skipping
+                * unsupported vmas.
+                */
+               if (p->arg.flags & PM_SCAN_WP_MATCHING)
+                       return 1;
+               /*
+                * Then the request doesn't involve wr-protects at all,
+                * fall through to the rest checks, and allow vma walk.
+                */
+       }
 
        if (vma->vm_flags & VM_PFNMAP)
                return 1;
 
+       if (wp_allowed)
+               vma_category |= PAGE_IS_WPALLOWED;
+
        if (!pagemap_scan_is_interesting_vma(vma_category, p))
                return 1;
 
@@ -2140,7 +2156,7 @@ static int pagemap_scan_pmd_entry(pmd_t *pmd, unsigned long start,
                return 0;
        }
 
-       if (!p->vec_out) {
+       if ((p->arg.flags & PM_SCAN_WP_MATCHING) && !p->vec_out) {
                /* Fast path for performing exclusive WP */
                for (addr = start; addr != end; pte++, addr += PAGE_SIZE) {
                        if (pte_uffd_wp(ptep_get(pte)))
index 581ce9519339018d005137caf72295aaeb16b797..2dc730800f448d8cb44f2d5c4e625e607d1faf2f 100644 (file)
@@ -321,7 +321,7 @@ int squashfs_read_data(struct super_block *sb, u64 index, int length,
                TRACE("Block @ 0x%llx, %scompressed size %d\n", index - 2,
                      compressed ? "" : "un", length);
        }
-       if (length < 0 || length > output->length ||
+       if (length <= 0 || length > output->length ||
                        (index + length) > msblk->bytes_used) {
                res = -EIO;
                goto out;
index 536a0b0091c3a9cf85c4007eac613191c114f75f..006b5c977ad7725f880f35a057bbc7dc9ef22fc6 100644 (file)
@@ -97,6 +97,8 @@ void drm_atomic_helper_commit_modeset_enables(struct drm_device *dev,
 
 int drm_atomic_helper_prepare_planes(struct drm_device *dev,
                                     struct drm_atomic_state *state);
+void drm_atomic_helper_unprepare_planes(struct drm_device *dev,
+                                       struct drm_atomic_state *state);
 
 #define DRM_PLANE_COMMIT_ACTIVE_ONLY                   BIT(0)
 #define DRM_PLANE_COMMIT_NO_DISABLE_AFTER_MODESET      BIT(1)
index 1abedb5b2e48fa298e022a502deb7ea39d38b59a..3d0fde57ba90eb7b6bf6a295181f06ab73cfb03b 100644 (file)
@@ -209,6 +209,8 @@ bool ffa_device_is_valid(struct ffa_device *ffa_dev) { return false; }
 #define module_ffa_driver(__ffa_driver)        \
        module_driver(__ffa_driver, ffa_register, ffa_unregister)
 
+extern struct bus_type ffa_bus_type;
+
 /* FFA transport related */
 struct ffa_partition_info {
        u16 id;
index 6762dac3ef76153fe96bbd05a1050b9a31d1a43d..cff5bb08820ecfc0877f4f5428969c77849554a5 100644 (file)
@@ -3175,6 +3175,9 @@ enum bpf_text_poke_type {
 int bpf_arch_text_poke(void *ip, enum bpf_text_poke_type t,
                       void *addr1, void *addr2);
 
+void bpf_arch_poke_desc_update(struct bpf_jit_poke_descriptor *poke,
+                              struct bpf_prog *new, struct bpf_prog *old);
+
 void *bpf_arch_text_copy(void *dst, void *src, size_t len);
 int bpf_arch_text_invalidate(void *dst, size_t len);
 
index 4cacc0e43b5139863d86c4dbcd85488b8fd9a7a4..be20cff4ba737038692c04cafd2c2abf0381694f 100644 (file)
@@ -454,7 +454,7 @@ static inline void memcpy_from_folio(char *to, struct folio *folio,
                memcpy(to, from, chunk);
                kunmap_local(from);
 
-               from += chunk;
+               to += chunk;
                offset += chunk;
                len -= chunk;
        } while (len > 0);
index d3acecc5db4b33ccdab8c345cab26873ddd3ede7..236ec7b63c5413407ae3dbe06622b8d3463ca7a0 100644 (file)
@@ -1268,10 +1268,7 @@ static inline bool __vma_shareable_lock(struct vm_area_struct *vma)
        return (vma->vm_flags & VM_MAYSHARE) && vma->vm_private_data;
 }
 
-static inline bool __vma_private_lock(struct vm_area_struct *vma)
-{
-       return (!(vma->vm_flags & VM_MAYSHARE)) && vma->vm_private_data;
-}
+bool __vma_private_lock(struct vm_area_struct *vma);
 
 /*
  * Safe version of huge_pte_offset() to check the locks.  See comments
index 63e630276499f88c337c85321d17aed1931aa583..ab1c7deff118f3d988565796bd47ce8b4a5ea7c2 100644 (file)
 /* Charging mode - 1=Barrel, 2=USB */
 #define ASUS_WMI_DEVID_CHARGE_MODE     0x0012006C
 
+/* MCU powersave mode */
+#define ASUS_WMI_DEVID_MCU_POWERSAVE   0x001200E2
+
 /* epu is connected? 1 == true */
 #define ASUS_WMI_DEVID_EGPU_CONNECTED  0x00090018
 /* egpu on/off */
index 0b4658a7eceb622346b5e2f757d8395c825e82a3..dee5ad6e48c5a064c70613948ce1a6f602350cf1 100644 (file)
@@ -175,6 +175,7 @@ struct stmmac_fpe_cfg {
        bool hs_enable;                         /* FPE handshake enable */
        enum stmmac_fpe_state lp_fpe_state;     /* Link Partner FPE state */
        enum stmmac_fpe_state lo_fpe_state;     /* Local station FPE state */
+       u32 fpe_csr;                            /* MAC_FPE_CTRL_STS reg cache */
 };
 
 struct stmmac_safety_feature_cfg {
index 68f3d315d2e18d93a356b0738e4ed855fac94591..b646b574b060d6ca45e545df8edbed032be4189e 100644 (file)
@@ -169,7 +169,7 @@ struct tcp_request_sock {
 #ifdef CONFIG_TCP_AO
        u8                              ao_keyid;
        u8                              ao_rcv_next;
-       u8                              maclen;
+       bool                            used_tcp_ao;
 #endif
 };
 
@@ -180,14 +180,10 @@ static inline struct tcp_request_sock *tcp_rsk(const struct request_sock *req)
 
 static inline bool tcp_rsk_used_ao(const struct request_sock *req)
 {
-       /* The real length of MAC is saved in the request socket,
-        * signing anything with zero-length makes no sense, so here is
-        * a little hack..
-        */
 #ifndef CONFIG_TCP_AO
        return false;
 #else
-       return tcp_rsk(req)->maclen != 0;
+       return tcp_rsk(req)->used_tcp_ao;
 #endif
 }
 
index ff1bd6b5f5b372449102ed50fa7edacc47d60c19..45110daaf8d3260ced995b66ba62669e8b29ddfa 100644 (file)
@@ -2,6 +2,7 @@
 #ifndef _LINUX_UNITS_H
 #define _LINUX_UNITS_H
 
+#include <linux/bits.h>
 #include <linux/math.h>
 
 /* Metric prefixes in accordance with Système international (d'unités) */
index 287e9d83fb8bc38ff6d7aba70c5d7fa44f48c64e..33a4c146dc19c45d5cb343fba0ffdf0a0b7cff36 100644 (file)
@@ -30,6 +30,7 @@
 #define VENDOR_ID_NVIDIA               0x0955
 #define VENDOR_ID_TPLINK               0x2357
 #define VENDOR_ID_DLINK                        0x2001
+#define VENDOR_ID_ASUS                 0x0b05
 
 #if IS_REACHABLE(CONFIG_USB_RTL8152)
 extern u8 rtl8152_get_version(struct usb_interface *intf);
index e18a4c0d69eedcce5c4c246e751f6d5efc8c52c5..c53244f204370442054501e7c9698b6b7224af8b 100644 (file)
  * struct genl_multicast_group - generic netlink multicast group
  * @name: name of the multicast group, names are per-family
  * @flags: GENL_* flags (%GENL_ADMIN_PERM or %GENL_UNS_ADMIN_PERM)
+ * @cap_sys_admin: whether %CAP_SYS_ADMIN is required for binding
  */
 struct genl_multicast_group {
        char                    name[GENL_NAMSIZ];
        u8                      flags;
+       u8                      cap_sys_admin:1;
 };
 
 struct genl_split_ops;
index d2f0736b76b8b299b41e59adb63055bc52dc1f34..144ba48bb07bb9e48de07f7fe7eec60e8997c7f1 100644 (file)
@@ -1514,17 +1514,22 @@ static inline int tcp_full_space(const struct sock *sk)
        return tcp_win_from_space(sk, READ_ONCE(sk->sk_rcvbuf));
 }
 
-static inline void tcp_adjust_rcv_ssthresh(struct sock *sk)
+static inline void __tcp_adjust_rcv_ssthresh(struct sock *sk, u32 new_ssthresh)
 {
        int unused_mem = sk_unused_reserved_mem(sk);
        struct tcp_sock *tp = tcp_sk(sk);
 
-       tp->rcv_ssthresh = min(tp->rcv_ssthresh, 4U * tp->advmss);
+       tp->rcv_ssthresh = min(tp->rcv_ssthresh, new_ssthresh);
        if (unused_mem)
                tp->rcv_ssthresh = max_t(u32, tp->rcv_ssthresh,
                                         tcp_win_from_space(sk, unused_mem));
 }
 
+static inline void tcp_adjust_rcv_ssthresh(struct sock *sk)
+{
+       __tcp_adjust_rcv_ssthresh(sk, 4U * tcp_sk(sk)->advmss);
+}
+
 void tcp_cleanup_rbuf(struct sock *sk, int copied);
 void __tcp_cleanup_rbuf(struct sock *sk, int copied);
 
index b56be10838f09a2cb56ab511242d2b583eb4c33b..6477810806137dbf7f0262ada4a64ebb568c690b 100644 (file)
@@ -62,11 +62,17 @@ static inline int tcp_ao_maclen(const struct tcp_ao_key *key)
        return key->maclen;
 }
 
+/* Use tcp_ao_len_aligned() for TCP header calculations */
 static inline int tcp_ao_len(const struct tcp_ao_key *key)
 {
        return tcp_ao_maclen(key) + sizeof(struct tcp_ao_hdr);
 }
 
+static inline int tcp_ao_len_aligned(const struct tcp_ao_key *key)
+{
+       return round_up(tcp_ao_len(key), 4);
+}
+
 static inline unsigned int tcp_ao_digest_size(struct tcp_ao_key *key)
 {
        return key->digest_size;
index 7aff28ded2f48fbee898ca291f2c29780fb2e9b9..1cc3b1c595d7f9d4c0530335b7a677a0fcc70c29 100644 (file)
@@ -97,7 +97,6 @@ config CRASH_DUMP
        depends on ARCH_SUPPORTS_KEXEC
        select CRASH_CORE
        select KEXEC_CORE
-       select KEXEC
        help
          Generate crash dump after being started by kexec.
          This should be normally only set in special crash dump kernels
index 2058e89b5ddd0091e49032b3982b8d7eaabc6b0d..c85ff9162a5cd44444746f0199e508d0f045b0c4 100644 (file)
@@ -1012,11 +1012,16 @@ static void prog_array_map_poke_untrack(struct bpf_map *map,
        mutex_unlock(&aux->poke_mutex);
 }
 
+void __weak bpf_arch_poke_desc_update(struct bpf_jit_poke_descriptor *poke,
+                                     struct bpf_prog *new, struct bpf_prog *old)
+{
+       WARN_ON_ONCE(1);
+}
+
 static void prog_array_map_poke_run(struct bpf_map *map, u32 key,
                                    struct bpf_prog *old,
                                    struct bpf_prog *new)
 {
-       u8 *old_addr, *new_addr, *old_bypass_addr;
        struct prog_poke_elem *elem;
        struct bpf_array_aux *aux;
 
@@ -1025,7 +1030,7 @@ static void prog_array_map_poke_run(struct bpf_map *map, u32 key,
 
        list_for_each_entry(elem, &aux->poke_progs, list) {
                struct bpf_jit_poke_descriptor *poke;
-               int i, ret;
+               int i;
 
                for (i = 0; i < elem->aux->size_poke_tab; i++) {
                        poke = &elem->aux->poke_tab[i];
@@ -1044,21 +1049,10 @@ static void prog_array_map_poke_run(struct bpf_map *map, u32 key,
                         *    activated, so tail call updates can arrive from here
                         *    while JIT is still finishing its final fixup for
                         *    non-activated poke entries.
-                        * 3) On program teardown, the program's kallsym entry gets
-                        *    removed out of RCU callback, but we can only untrack
-                        *    from sleepable context, therefore bpf_arch_text_poke()
-                        *    might not see that this is in BPF text section and
-                        *    bails out with -EINVAL. As these are unreachable since
-                        *    RCU grace period already passed, we simply skip them.
-                        * 4) Also programs reaching refcount of zero while patching
+                        * 3) Also programs reaching refcount of zero while patching
                         *    is in progress is okay since we're protected under
                         *    poke_mutex and untrack the programs before the JIT
-                        *    buffer is freed. When we're still in the middle of
-                        *    patching and suddenly kallsyms entry of the program
-                        *    gets evicted, we just skip the rest which is fine due
-                        *    to point 3).
-                        * 5) Any other error happening below from bpf_arch_text_poke()
-                        *    is a unexpected bug.
+                        *    buffer is freed.
                         */
                        if (!READ_ONCE(poke->tailcall_target_stable))
                                continue;
@@ -1068,39 +1062,7 @@ static void prog_array_map_poke_run(struct bpf_map *map, u32 key,
                            poke->tail_call.key != key)
                                continue;
 
-                       old_bypass_addr = old ? NULL : poke->bypass_addr;
-                       old_addr = old ? (u8 *)old->bpf_func + poke->adj_off : NULL;
-                       new_addr = new ? (u8 *)new->bpf_func + poke->adj_off : NULL;
-
-                       if (new) {
-                               ret = bpf_arch_text_poke(poke->tailcall_target,
-                                                        BPF_MOD_JUMP,
-                                                        old_addr, new_addr);
-                               BUG_ON(ret < 0 && ret != -EINVAL);
-                               if (!old) {
-                                       ret = bpf_arch_text_poke(poke->tailcall_bypass,
-                                                                BPF_MOD_JUMP,
-                                                                poke->bypass_addr,
-                                                                NULL);
-                                       BUG_ON(ret < 0 && ret != -EINVAL);
-                               }
-                       } else {
-                               ret = bpf_arch_text_poke(poke->tailcall_bypass,
-                                                        BPF_MOD_JUMP,
-                                                        old_bypass_addr,
-                                                        poke->bypass_addr);
-                               BUG_ON(ret < 0 && ret != -EINVAL);
-                               /* let other CPUs finish the execution of program
-                                * so that it will not possible to expose them
-                                * to invalid nop, stack unwind, nop state
-                                */
-                               if (!ret)
-                                       synchronize_rcu();
-                               ret = bpf_arch_text_poke(poke->tailcall_target,
-                                                        BPF_MOD_JUMP,
-                                                        old_addr, NULL);
-                               BUG_ON(ret < 0 && ret != -EINVAL);
-                       }
+                       bpf_arch_poke_desc_update(poke, new, old);
                }
        }
 }
index cd3afe57ece3cc9a5a52c20243bdafd7fa987f4f..fe254ae035fe4956388897af24d38809530f8fb7 100644 (file)
@@ -371,14 +371,18 @@ static int bpf_adj_delta_to_imm(struct bpf_insn *insn, u32 pos, s32 end_old,
 static int bpf_adj_delta_to_off(struct bpf_insn *insn, u32 pos, s32 end_old,
                                s32 end_new, s32 curr, const bool probe_pass)
 {
-       const s32 off_min = S16_MIN, off_max = S16_MAX;
+       s64 off_min, off_max, off;
        s32 delta = end_new - end_old;
-       s32 off;
 
-       if (insn->code == (BPF_JMP32 | BPF_JA))
+       if (insn->code == (BPF_JMP32 | BPF_JA)) {
                off = insn->imm;
-       else
+               off_min = S32_MIN;
+               off_max = S32_MAX;
+       } else {
                off = insn->off;
+               off_min = S16_MIN;
+               off_max = S16_MAX;
+       }
 
        if (curr < pos && curr + off + 1 >= end_old)
                off += delta;
index 122dacb3a44390825054d67530f8f894f2f7fb04..66d1708042a72bf5d25b9ff1d7acb8d91183ffd7 100644 (file)
@@ -66,9 +66,15 @@ static struct freezer *parent_freezer(struct freezer *freezer)
 bool cgroup_freezing(struct task_struct *task)
 {
        bool ret;
+       unsigned int state;
 
        rcu_read_lock();
-       ret = task_freezer(task)->state & CGROUP_FREEZING;
+       /* Check if the cgroup is still FREEZING, but not FROZEN. The extra
+        * !FROZEN check is required, because the FREEZING bit is not cleared
+        * when the state FROZEN is reached.
+        */
+       state = task_freezer(task)->state;
+       ret = (state & CGROUP_FREEZING) && !(state & CGROUP_FROZEN);
        rcu_read_unlock();
 
        return ret;
index 43cc47d7faafc7bd9c80d62fe4ad03f97b4164eb..8d2a4f00eca9f0e3d3c065504f46940902f6a6f0 100644 (file)
@@ -644,8 +644,8 @@ static inline bool __rb_time_read(rb_time_t *t, u64 *ret, unsigned long *cnt)
 
        *cnt = rb_time_cnt(top);
 
-       /* If top and bottom counts don't match, this interrupted a write */
-       if (*cnt != rb_time_cnt(bottom))
+       /* If top and msb counts don't match, this interrupted a write */
+       if (*cnt != rb_time_cnt(msb))
                return false;
 
        /* The shift to msb will lose its cnt bits */
@@ -3030,22 +3030,19 @@ rb_try_to_discard(struct ring_buffer_per_cpu *cpu_buffer,
                        local_read(&bpage->write) & ~RB_WRITE_MASK;
                unsigned long event_length = rb_event_length(event);
 
+               /*
+                * For the before_stamp to be different than the write_stamp
+                * to make sure that the next event adds an absolute
+                * value and does not rely on the saved write stamp, which
+                * is now going to be bogus.
+                */
+               rb_time_set(&cpu_buffer->before_stamp, 0);
+
                /* Something came in, can't discard */
                if (!rb_time_cmpxchg(&cpu_buffer->write_stamp,
                                       write_stamp, write_stamp - delta))
                        return false;
 
-               /*
-                * It's possible that the event time delta is zero
-                * (has the same time stamp as the previous event)
-                * in which case write_stamp and before_stamp could
-                * be the same. In such a case, force before_stamp
-                * to be different than write_stamp. It doesn't
-                * matter what it is, as long as its different.
-                */
-               if (!delta)
-                       rb_time_set(&cpu_buffer->before_stamp, 0);
-
                /*
                 * If an event were to come in now, it would see that the
                 * write_stamp and the before_stamp are different, and assume
index 9aebf904ff9738137a314a78ead0092c009c4d38..fbcd3bafb93e2cc2b93e9716ce58b413f3912233 100644 (file)
@@ -2360,13 +2360,7 @@ int is_tracing_stopped(void)
        return global_trace.stop_count;
 }
 
-/**
- * tracing_start - quick start of the tracer
- *
- * If tracing is enabled but was stopped by tracing_stop,
- * this will start the tracer back up.
- */
-void tracing_start(void)
+static void tracing_start_tr(struct trace_array *tr)
 {
        struct trace_buffer *buffer;
        unsigned long flags;
@@ -2374,119 +2368,83 @@ void tracing_start(void)
        if (tracing_disabled)
                return;
 
-       raw_spin_lock_irqsave(&global_trace.start_lock, flags);
-       if (--global_trace.stop_count) {
-               if (global_trace.stop_count < 0) {
+       raw_spin_lock_irqsave(&tr->start_lock, flags);
+       if (--tr->stop_count) {
+               if (WARN_ON_ONCE(tr->stop_count < 0)) {
                        /* Someone screwed up their debugging */
-                       WARN_ON_ONCE(1);
-                       global_trace.stop_count = 0;
+                       tr->stop_count = 0;
                }
                goto out;
        }
 
        /* Prevent the buffers from switching */
-       arch_spin_lock(&global_trace.max_lock);
+       arch_spin_lock(&tr->max_lock);
 
-       buffer = global_trace.array_buffer.buffer;
+       buffer = tr->array_buffer.buffer;
        if (buffer)
                ring_buffer_record_enable(buffer);
 
 #ifdef CONFIG_TRACER_MAX_TRACE
-       buffer = global_trace.max_buffer.buffer;
+       buffer = tr->max_buffer.buffer;
        if (buffer)
                ring_buffer_record_enable(buffer);
 #endif
 
-       arch_spin_unlock(&global_trace.max_lock);
-
- out:
-       raw_spin_unlock_irqrestore(&global_trace.start_lock, flags);
-}
-
-static void tracing_start_tr(struct trace_array *tr)
-{
-       struct trace_buffer *buffer;
-       unsigned long flags;
-
-       if (tracing_disabled)
-               return;
-
-       /* If global, we need to also start the max tracer */
-       if (tr->flags & TRACE_ARRAY_FL_GLOBAL)
-               return tracing_start();
-
-       raw_spin_lock_irqsave(&tr->start_lock, flags);
-
-       if (--tr->stop_count) {
-               if (tr->stop_count < 0) {
-                       /* Someone screwed up their debugging */
-                       WARN_ON_ONCE(1);
-                       tr->stop_count = 0;
-               }
-               goto out;
-       }
-
-       buffer = tr->array_buffer.buffer;
-       if (buffer)
-               ring_buffer_record_enable(buffer);
+       arch_spin_unlock(&tr->max_lock);
 
  out:
        raw_spin_unlock_irqrestore(&tr->start_lock, flags);
 }
 
 /**
- * tracing_stop - quick stop of the tracer
+ * tracing_start - quick start of the tracer
  *
- * Light weight way to stop tracing. Use in conjunction with
- * tracing_start.
+ * If tracing is enabled but was stopped by tracing_stop,
+ * this will start the tracer back up.
  */
-void tracing_stop(void)
+void tracing_start(void)
+
+{
+       return tracing_start_tr(&global_trace);
+}
+
+static void tracing_stop_tr(struct trace_array *tr)
 {
        struct trace_buffer *buffer;
        unsigned long flags;
 
-       raw_spin_lock_irqsave(&global_trace.start_lock, flags);
-       if (global_trace.stop_count++)
+       raw_spin_lock_irqsave(&tr->start_lock, flags);
+       if (tr->stop_count++)
                goto out;
 
        /* Prevent the buffers from switching */
-       arch_spin_lock(&global_trace.max_lock);
+       arch_spin_lock(&tr->max_lock);
 
-       buffer = global_trace.array_buffer.buffer;
+       buffer = tr->array_buffer.buffer;
        if (buffer)
                ring_buffer_record_disable(buffer);
 
 #ifdef CONFIG_TRACER_MAX_TRACE
-       buffer = global_trace.max_buffer.buffer;
+       buffer = tr->max_buffer.buffer;
        if (buffer)
                ring_buffer_record_disable(buffer);
 #endif
 
-       arch_spin_unlock(&global_trace.max_lock);
+       arch_spin_unlock(&tr->max_lock);
 
  out:
-       raw_spin_unlock_irqrestore(&global_trace.start_lock, flags);
+       raw_spin_unlock_irqrestore(&tr->start_lock, flags);
 }
 
-static void tracing_stop_tr(struct trace_array *tr)
+/**
+ * tracing_stop - quick stop of the tracer
+ *
+ * Light weight way to stop tracing. Use in conjunction with
+ * tracing_start.
+ */
+void tracing_stop(void)
 {
-       struct trace_buffer *buffer;
-       unsigned long flags;
-
-       /* If global, we need to also stop the max tracer */
-       if (tr->flags & TRACE_ARRAY_FL_GLOBAL)
-               return tracing_stop();
-
-       raw_spin_lock_irqsave(&tr->start_lock, flags);
-       if (tr->stop_count++)
-               goto out;
-
-       buffer = tr->array_buffer.buffer;
-       if (buffer)
-               ring_buffer_record_disable(buffer);
-
- out:
-       raw_spin_unlock_irqrestore(&tr->start_lock, flags);
+       return tracing_stop_tr(&global_trace);
 }
 
 static int trace_save_cmdline(struct task_struct *tsk)
@@ -2770,8 +2728,11 @@ void trace_buffered_event_enable(void)
        for_each_tracing_cpu(cpu) {
                page = alloc_pages_node(cpu_to_node(cpu),
                                        GFP_KERNEL | __GFP_NORETRY, 0);
-               if (!page)
-                       goto failed;
+               /* This is just an optimization and can handle failures */
+               if (!page) {
+                       pr_err("Failed to allocate event buffer\n");
+                       break;
+               }
 
                event = page_address(page);
                memset(event, 0, sizeof(*event));
@@ -2785,10 +2746,6 @@ void trace_buffered_event_enable(void)
                        WARN_ON_ONCE(1);
                preempt_enable();
        }
-
-       return;
- failed:
-       trace_buffered_event_disable();
 }
 
 static void enable_trace_buffered_event(void *data)
@@ -2823,11 +2780,9 @@ void trace_buffered_event_disable(void)
        if (--trace_buffered_event_ref)
                return;
 
-       preempt_disable();
        /* For each CPU, set the buffer as used. */
-       smp_call_function_many(tracing_buffer_mask,
-                              disable_trace_buffered_event, NULL, 1);
-       preempt_enable();
+       on_each_cpu_mask(tracing_buffer_mask, disable_trace_buffered_event,
+                        NULL, true);
 
        /* Wait for all current users to finish */
        synchronize_rcu();
@@ -2836,17 +2791,19 @@ void trace_buffered_event_disable(void)
                free_page((unsigned long)per_cpu(trace_buffered_event, cpu));
                per_cpu(trace_buffered_event, cpu) = NULL;
        }
+
        /*
-        * Make sure trace_buffered_event is NULL before clearing
-        * trace_buffered_event_cnt.
+        * Wait for all CPUs that potentially started checking if they can use
+        * their event buffer only after the previous synchronize_rcu() call and
+        * they still read a valid pointer from trace_buffered_event. It must be
+        * ensured they don't see cleared trace_buffered_event_cnt else they
+        * could wrongly decide to use the pointed-to buffer which is now freed.
         */
-       smp_wmb();
+       synchronize_rcu();
 
-       preempt_disable();
-       /* Do the work on each cpu */
-       smp_call_function_many(tracing_buffer_mask,
-                              enable_trace_buffered_event, NULL, 1);
-       preempt_enable();
+       /* For each CPU, relinquish the buffer */
+       on_each_cpu_mask(tracing_buffer_mask, enable_trace_buffered_event, NULL,
+                        true);
 }
 
 static struct trace_buffer *temp_buffer;
@@ -6387,13 +6344,15 @@ static int __tracing_resize_ring_buffer(struct trace_array *tr,
        if (!tr->array_buffer.buffer)
                return 0;
 
+       /* Do not allow tracing while resizng ring buffer */
+       tracing_stop_tr(tr);
+
        ret = ring_buffer_resize(tr->array_buffer.buffer, size, cpu);
        if (ret < 0)
-               return ret;
+               goto out_start;
 
 #ifdef CONFIG_TRACER_MAX_TRACE
-       if (!(tr->flags & TRACE_ARRAY_FL_GLOBAL) ||
-           !tr->current_trace->use_max_tr)
+       if (!tr->current_trace->use_max_tr)
                goto out;
 
        ret = ring_buffer_resize(tr->max_buffer.buffer, size, cpu);
@@ -6418,7 +6377,7 @@ static int __tracing_resize_ring_buffer(struct trace_array *tr,
                        WARN_ON(1);
                        tracing_disabled = 1;
                }
-               return ret;
+               goto out_start;
        }
 
        update_buffer_entries(&tr->max_buffer, cpu);
@@ -6427,7 +6386,8 @@ static int __tracing_resize_ring_buffer(struct trace_array *tr,
 #endif /* CONFIG_TRACER_MAX_TRACE */
 
        update_buffer_entries(&tr->array_buffer, cpu);
-
+ out_start:
+       tracing_start_tr(tr);
        return ret;
 }
 
index 6e578f576a6f2b73b98817b0f5489a79c9d85524..2989b57e154a767dadc6054bed607808086b36d6 100644 (file)
@@ -1684,9 +1684,6 @@ static int wq_select_unbound_cpu(int cpu)
                pr_warn_once("workqueue: round-robin CPU selection forced, expect performance impact\n");
        }
 
-       if (cpumask_empty(wq_unbound_cpumask))
-               return cpu;
-
        new_cpu = __this_cpu_read(wq_rr_cpu_last);
        new_cpu = cpumask_next_and(new_cpu, wq_unbound_cpumask, cpu_online_mask);
        if (unlikely(new_cpu >= nr_cpu_ids)) {
@@ -6515,6 +6512,17 @@ static inline void wq_watchdog_init(void) { }
 
 #endif /* CONFIG_WQ_WATCHDOG */
 
+static void __init restrict_unbound_cpumask(const char *name, const struct cpumask *mask)
+{
+       if (!cpumask_intersects(wq_unbound_cpumask, mask)) {
+               pr_warn("workqueue: Restricting unbound_cpumask (%*pb) with %s (%*pb) leaves no CPU, ignoring\n",
+                       cpumask_pr_args(wq_unbound_cpumask), name, cpumask_pr_args(mask));
+               return;
+       }
+
+       cpumask_and(wq_unbound_cpumask, wq_unbound_cpumask, mask);
+}
+
 /**
  * workqueue_init_early - early init for workqueue subsystem
  *
@@ -6534,11 +6542,11 @@ void __init workqueue_init_early(void)
        BUILD_BUG_ON(__alignof__(struct pool_workqueue) < __alignof__(long long));
 
        BUG_ON(!alloc_cpumask_var(&wq_unbound_cpumask, GFP_KERNEL));
-       cpumask_copy(wq_unbound_cpumask, housekeeping_cpumask(HK_TYPE_WQ));
-       cpumask_and(wq_unbound_cpumask, wq_unbound_cpumask, housekeeping_cpumask(HK_TYPE_DOMAIN));
-
+       cpumask_copy(wq_unbound_cpumask, cpu_possible_mask);
+       restrict_unbound_cpumask("HK_TYPE_WQ", housekeeping_cpumask(HK_TYPE_WQ));
+       restrict_unbound_cpumask("HK_TYPE_DOMAIN", housekeeping_cpumask(HK_TYPE_DOMAIN));
        if (!cpumask_empty(&wq_cmdline_cpumask))
-               cpumask_and(wq_unbound_cpumask, wq_unbound_cpumask, &wq_cmdline_cpumask);
+               restrict_unbound_cpumask("workqueue.unbound_cpus", &wq_cmdline_cpumask);
 
        pwq_cache = KMEM_CACHE(pool_workqueue, SLAB_PANIC);
 
index aa3f6815bb124053e06678fc17c6b6613375e2b9..ee272c4cefcc13907ce9f211f479615d2e3c9154 100644 (file)
@@ -366,13 +366,25 @@ struct cpumask *group_cpus_evenly(unsigned int numgrps)
        if (!masks)
                goto fail_node_to_cpumask;
 
-       /* Stabilize the cpumasks */
-       cpus_read_lock();
        build_node_to_cpumask(node_to_cpumask);
 
+       /*
+        * Make a local cache of 'cpu_present_mask', so the two stages
+        * spread can observe consistent 'cpu_present_mask' without holding
+        * cpu hotplug lock, then we can reduce deadlock risk with cpu
+        * hotplug code.
+        *
+        * Here CPU hotplug may happen when reading `cpu_present_mask`, and
+        * we can live with the case because it only affects that hotplug
+        * CPU is handled in the 1st or 2nd stage, and either way is correct
+        * from API user viewpoint since 2-stage spread is sort of
+        * optimization.
+        */
+       cpumask_copy(npresmsk, data_race(cpu_present_mask));
+
        /* grouping present CPUs first */
        ret = __group_cpus_evenly(curgrp, numgrps, node_to_cpumask,
-                                 cpu_present_mask, nmsk, masks);
+                                 npresmsk, nmsk, masks);
        if (ret < 0)
                goto fail_build_affinity;
        nr_present = ret;
@@ -387,15 +399,13 @@ struct cpumask *group_cpus_evenly(unsigned int numgrps)
                curgrp = 0;
        else
                curgrp = nr_present;
-       cpumask_andnot(npresmsk, cpu_possible_mask, cpu_present_mask);
+       cpumask_andnot(npresmsk, cpu_possible_mask, npresmsk);
        ret = __group_cpus_evenly(curgrp, numgrps, node_to_cpumask,
                                  npresmsk, nmsk, masks);
        if (ret >= 0)
                nr_others = ret;
 
  fail_build_affinity:
-       cpus_read_unlock();
-
        if (ret >= 0)
                WARN_ON(nr_present + nr_others < numgrps);
 
index 89971a894b6058fd7b908c0e8ffa216cbdc887dd..57cd378c73d67fb369d39cfbb90259246531a274 100644 (file)
@@ -1201,13 +1201,6 @@ config ANON_VMA_NAME
          area from being merged with adjacent virtual memory areas due to the
          difference in their name.
 
-config USERFAULTFD
-       bool "Enable userfaultfd() system call"
-       depends on MMU
-       help
-         Enable the userfaultfd() system call that allows to intercept and
-         handle page faults in userland.
-
 config HAVE_ARCH_USERFAULTFD_WP
        bool
        help
@@ -1218,6 +1211,14 @@ config HAVE_ARCH_USERFAULTFD_MINOR
        help
          Arch has userfaultfd minor fault support
 
+menuconfig USERFAULTFD
+       bool "Enable userfaultfd() system call"
+       depends on MMU
+       help
+         Enable the userfaultfd() system call that allows to intercept and
+         handle page faults in userland.
+
+if USERFAULTFD
 config PTE_MARKER_UFFD_WP
        bool "Userfaultfd write protection support for shmem/hugetlbfs"
        default y
@@ -1227,6 +1228,7 @@ config PTE_MARKER_UFFD_WP
          Allows to create marker PTEs for userfaultfd write protection
          purposes.  It is required to enable userfaultfd write protection on
          file-backed memory types like shmem and hugetlbfs.
+endif # USERFAULTFD
 
 # multi-gen LRU {
 config LRU_GEN
index 6262d55904e744a4a41431127266971eb5ee3d8b..ce1562783e7e5df9941cd66e8eaf57db90f176de 100644 (file)
@@ -1225,6 +1225,7 @@ static void damon_split_region_at(struct damon_target *t,
        new->age = r->age;
        new->last_nr_accesses = r->last_nr_accesses;
        new->nr_accesses_bp = r->nr_accesses_bp;
+       new->nr_accesses = r->nr_accesses;
 
        damon_insert_region(new, r, damon_next_region(r), t);
 }
index be667236b8e6e30713a205a4987d50c3b48ab463..fe0fe2562000b3c01d7c5ba01ec884c26fbdb7b8 100644 (file)
@@ -139,6 +139,13 @@ static const struct kobj_type damon_sysfs_scheme_region_ktype = {
  * damon_sysfs_before_damos_apply() understands the situation by showing the
  * 'finished' status and do nothing.
  *
+ * If DAMOS is not applied to any region due to any reasons including the
+ * access pattern, the watermarks, the quotas, and the filters,
+ * ->before_damos_apply() will not be called back.  Until the situation is
+ * changed, the update will not be finished.  To avoid this,
+ * damon_sysfs_after_sampling() set the status as 'finished' if more than two
+ * apply intervals of the scheme is passed while the state is 'idle'.
+ *
  *  Finally, the tried regions request handling finisher function
  *  (damon_sysfs_schemes_update_regions_stop()) unregisters the callbacks.
  */
@@ -154,6 +161,7 @@ struct damon_sysfs_scheme_regions {
        int nr_regions;
        unsigned long total_bytes;
        enum damos_sysfs_regions_upd_status upd_status;
+       unsigned long upd_timeout_jiffies;
 };
 
 static struct damon_sysfs_scheme_regions *
@@ -1854,7 +1862,9 @@ static int damon_sysfs_after_sampling(struct damon_ctx *ctx)
        for (i = 0; i < sysfs_schemes->nr; i++) {
                sysfs_regions = sysfs_schemes->schemes_arr[i]->tried_regions;
                if (sysfs_regions->upd_status ==
-                               DAMOS_TRIED_REGIONS_UPD_STARTED)
+                               DAMOS_TRIED_REGIONS_UPD_STARTED ||
+                               time_after(jiffies,
+                                       sysfs_regions->upd_timeout_jiffies))
                        sysfs_regions->upd_status =
                                DAMOS_TRIED_REGIONS_UPD_FINISHED;
        }
@@ -1885,14 +1895,41 @@ int damon_sysfs_schemes_clear_regions(
        return 0;
 }
 
+static struct damos *damos_sysfs_nth_scheme(int n, struct damon_ctx *ctx)
+{
+       struct damos *scheme;
+       int i = 0;
+
+       damon_for_each_scheme(scheme, ctx) {
+               if (i == n)
+                       return scheme;
+               i++;
+       }
+       return NULL;
+}
+
 static void damos_tried_regions_init_upd_status(
-               struct damon_sysfs_schemes *sysfs_schemes)
+               struct damon_sysfs_schemes *sysfs_schemes,
+               struct damon_ctx *ctx)
 {
        int i;
+       struct damos *scheme;
+       struct damon_sysfs_scheme_regions *sysfs_regions;
 
-       for (i = 0; i < sysfs_schemes->nr; i++)
-               sysfs_schemes->schemes_arr[i]->tried_regions->upd_status =
-                       DAMOS_TRIED_REGIONS_UPD_IDLE;
+       for (i = 0; i < sysfs_schemes->nr; i++) {
+               sysfs_regions = sysfs_schemes->schemes_arr[i]->tried_regions;
+               scheme = damos_sysfs_nth_scheme(i, ctx);
+               if (!scheme) {
+                       sysfs_regions->upd_status =
+                               DAMOS_TRIED_REGIONS_UPD_FINISHED;
+                       continue;
+               }
+               sysfs_regions->upd_status = DAMOS_TRIED_REGIONS_UPD_IDLE;
+               sysfs_regions->upd_timeout_jiffies = jiffies +
+                       2 * usecs_to_jiffies(scheme->apply_interval_us ?
+                                       scheme->apply_interval_us :
+                                       ctx->attrs.sample_interval);
+       }
 }
 
 /* Called from damon_sysfs_cmd_request_callback under damon_sysfs_lock */
@@ -1902,7 +1939,7 @@ int damon_sysfs_schemes_update_regions_start(
 {
        damon_sysfs_schemes_clear_regions(sysfs_schemes, ctx);
        damon_sysfs_schemes_for_damos_callback = sysfs_schemes;
-       damos_tried_regions_init_upd_status(sysfs_schemes);
+       damos_tried_regions_init_upd_status(sysfs_schemes, ctx);
        damos_regions_upd_total_bytes_only = total_bytes_only;
        ctx->callback.before_damos_apply = damon_sysfs_before_damos_apply;
        ctx->callback.after_sampling = damon_sysfs_after_sampling;
index 32eedf3afd45883a7c34920c4a097906b743621e..f1c8c278310fd51384d0e5dcfd309c4aff9541ff 100644 (file)
@@ -3371,7 +3371,7 @@ static bool filemap_map_pmd(struct vm_fault *vmf, struct folio *folio,
                }
        }
 
-       if (pmd_none(*vmf->pmd))
+       if (pmd_none(*vmf->pmd) && vmf->prealloc_pte)
                pmd_install(mm, vmf->pmd, &vmf->prealloc_pte);
 
        return false;
index 1169ef2f2176fa2cd1ca0bce159ce7d31abf0359..6feb3e0630d1865939517a966529c98196083074 100644 (file)
@@ -1182,6 +1182,13 @@ static int is_vma_resv_set(struct vm_area_struct *vma, unsigned long flag)
        return (get_vma_private_data(vma) & flag) != 0;
 }
 
+bool __vma_private_lock(struct vm_area_struct *vma)
+{
+       return !(vma->vm_flags & VM_MAYSHARE) &&
+               get_vma_private_data(vma) & ~HPAGE_RESV_MASK &&
+               is_vma_resv_set(vma, HPAGE_RESV_OWNER);
+}
+
 void hugetlb_dup_vma_private(struct vm_area_struct *vma)
 {
        VM_BUG_ON_VMA(!is_vm_hugetlb_page(vma), vma);
index 1eacca03bedd20cd6ff6cffaa96dcffcde9e5397..5501363d6b3125be1d916c3a29dfd016d2c17233 100644 (file)
@@ -642,32 +642,16 @@ static struct kmemleak_object *__alloc_object(gfp_t gfp)
        if (!object) {
                pr_warn("Cannot allocate a kmemleak_object structure\n");
                kmemleak_disable();
+               return NULL;
        }
 
-       return object;
-}
-
-static int __link_object(struct kmemleak_object *object, unsigned long ptr,
-                        size_t size, int min_count, bool is_phys)
-{
-
-       struct kmemleak_object *parent;
-       struct rb_node **link, *rb_parent;
-       unsigned long untagged_ptr;
-       unsigned long untagged_objp;
-
        INIT_LIST_HEAD(&object->object_list);
        INIT_LIST_HEAD(&object->gray_list);
        INIT_HLIST_HEAD(&object->area_list);
        raw_spin_lock_init(&object->lock);
        atomic_set(&object->use_count, 1);
-       object->flags = OBJECT_ALLOCATED | (is_phys ? OBJECT_PHYS : 0);
-       object->pointer = ptr;
-       object->size = kfence_ksize((void *)ptr) ?: size;
        object->excess_ref = 0;
-       object->min_count = min_count;
        object->count = 0;                      /* white color initially */
-       object->jiffies = jiffies;
        object->checksum = 0;
        object->del_state = 0;
 
@@ -692,6 +676,24 @@ static int __link_object(struct kmemleak_object *object, unsigned long ptr,
        /* kernel backtrace */
        object->trace_handle = set_track_prepare();
 
+       return object;
+}
+
+static int __link_object(struct kmemleak_object *object, unsigned long ptr,
+                        size_t size, int min_count, bool is_phys)
+{
+
+       struct kmemleak_object *parent;
+       struct rb_node **link, *rb_parent;
+       unsigned long untagged_ptr;
+       unsigned long untagged_objp;
+
+       object->flags = OBJECT_ALLOCATED | (is_phys ? OBJECT_PHYS : 0);
+       object->pointer = ptr;
+       object->size = kfence_ksize((void *)ptr) ?: size;
+       object->min_count = min_count;
+       object->jiffies = jiffies;
+
        untagged_ptr = (unsigned long)kasan_reset_tag((void *)ptr);
        /*
         * Only update min_addr and max_addr with object
@@ -1150,6 +1152,7 @@ EXPORT_SYMBOL_GPL(kmemleak_free_percpu);
 void __ref kmemleak_update_trace(const void *ptr)
 {
        struct kmemleak_object *object;
+       depot_stack_handle_t trace_handle;
        unsigned long flags;
 
        pr_debug("%s(0x%px)\n", __func__, ptr);
@@ -1166,8 +1169,9 @@ void __ref kmemleak_update_trace(const void *ptr)
                return;
        }
 
+       trace_handle = set_track_prepare();
        raw_spin_lock_irqsave(&object->lock, flags);
-       object->trace_handle = set_track_prepare();
+       object->trace_handle = trace_handle;
        raw_spin_unlock_irqrestore(&object->lock, flags);
 
        put_object(object);
index cf4d694280e98ae4d65ccd02d2bf1d6c4393a998..6214a1ab5654f442c3ad5ae9c39678f703a303fd 100644 (file)
@@ -335,6 +335,7 @@ static int madvise_cold_or_pageout_pte_range(pmd_t *pmd,
        struct folio *folio = NULL;
        LIST_HEAD(folio_list);
        bool pageout_anon_only_filter;
+       unsigned int batch_count = 0;
 
        if (fatal_signal_pending(current))
                return -EINTR;
@@ -416,6 +417,7 @@ huge_unlock:
 regular_folio:
 #endif
        tlb_change_page_size(tlb, PAGE_SIZE);
+restart:
        start_pte = pte = pte_offset_map_lock(vma->vm_mm, pmd, addr, &ptl);
        if (!start_pte)
                return 0;
@@ -424,6 +426,15 @@ regular_folio:
        for (; addr < end; pte++, addr += PAGE_SIZE) {
                ptent = ptep_get(pte);
 
+               if (++batch_count == SWAP_CLUSTER_MAX) {
+                       batch_count = 0;
+                       if (need_resched()) {
+                               pte_unmap_unlock(start_pte, ptl);
+                               cond_resched();
+                               goto restart;
+                       }
+               }
+
                if (pte_none(ptent))
                        continue;
 
index 1c1061df9cd17cb664d5d6b9faf1ac79db2cef6a..b226090fd9061c6261ace5a09850ebcc0c183060 100644 (file)
@@ -3166,6 +3166,7 @@ __always_inline struct obj_cgroup *current_obj_cgroup(void)
        return NULL;
 
 from_memcg:
+       objcg = NULL;
        for (; !mem_cgroup_is_root(memcg); memcg = parent_mem_cgroup(memcg)) {
                /*
                 * Memcg pointer is protected by scope (see set_active_memcg())
@@ -3176,7 +3177,6 @@ from_memcg:
                objcg = rcu_dereference_check(memcg->objcg, 1);
                if (likely(objcg))
                        break;
-               objcg = NULL;
        }
 
        return objcg;
index 1f18ed4a54971dd8737e7fb108d093bc702d777c..5c757fba8858a592281ea9ad479feee15314e46b 100644 (file)
@@ -1517,6 +1517,7 @@ static unsigned long zap_pte_range(struct mmu_gather *tlb,
                                continue;
                } else {
                        /* We should have covered all the swap entry types */
+                       pr_alert("unrecognized swap entry 0x%lx\n", entry.val);
                        WARN_ON_ONCE(1);
                }
                pte_clear_not_present_full(mm, addr, pte, tlb->fullmm);
index ab41a511e20a8ed054a0e79db37dc1aa25e8ecd3..7a5fc89a865289b76af1df2e4c992a6dbf2ae2df 100644 (file)
@@ -1129,6 +1129,9 @@ void mhp_deinit_memmap_on_memory(unsigned long pfn, unsigned long nr_pages)
        kasan_remove_zero_shadow(__va(PFN_PHYS(pfn)), PFN_PHYS(nr_pages));
 }
 
+/*
+ * Must be called with mem_hotplug_lock in write mode.
+ */
 int __ref online_pages(unsigned long pfn, unsigned long nr_pages,
                       struct zone *zone, struct memory_group *group)
 {
@@ -1149,7 +1152,6 @@ int __ref online_pages(unsigned long pfn, unsigned long nr_pages,
                         !IS_ALIGNED(pfn + nr_pages, PAGES_PER_SECTION)))
                return -EINVAL;
 
-       mem_hotplug_begin();
 
        /* associate pfn range with the zone */
        move_pfn_range_to_zone(zone, pfn, nr_pages, NULL, MIGRATE_ISOLATE);
@@ -1208,7 +1210,6 @@ int __ref online_pages(unsigned long pfn, unsigned long nr_pages,
        writeback_set_ratelimit();
 
        memory_notify(MEM_ONLINE, &arg);
-       mem_hotplug_done();
        return 0;
 
 failed_addition:
@@ -1217,7 +1218,6 @@ failed_addition:
                 (((unsigned long long) pfn + nr_pages) << PAGE_SHIFT) - 1);
        memory_notify(MEM_CANCEL_ONLINE, &arg);
        remove_pfn_range_from_zone(zone, pfn, nr_pages);
-       mem_hotplug_done();
        return ret;
 }
 
@@ -1458,7 +1458,7 @@ int __ref add_memory_resource(int nid, struct resource *res, mhp_t mhp_flags)
        /* create memory block devices after memory was added */
        ret = create_memory_block_devices(start, size, params.altmap, group);
        if (ret) {
-               arch_remove_memory(start, size, NULL);
+               arch_remove_memory(start, size, params.altmap);
                goto error_free;
        }
 
@@ -1863,6 +1863,9 @@ static int count_system_ram_pages_cb(unsigned long start_pfn,
        return 0;
 }
 
+/*
+ * Must be called with mem_hotplug_lock in write mode.
+ */
 int __ref offline_pages(unsigned long start_pfn, unsigned long nr_pages,
                        struct zone *zone, struct memory_group *group)
 {
@@ -1885,8 +1888,6 @@ int __ref offline_pages(unsigned long start_pfn, unsigned long nr_pages,
                         !IS_ALIGNED(start_pfn + nr_pages, PAGES_PER_SECTION)))
                return -EINVAL;
 
-       mem_hotplug_begin();
-
        /*
         * Don't allow to offline memory blocks that contain holes.
         * Consequently, memory blocks with holes can never get onlined
@@ -2031,7 +2032,6 @@ int __ref offline_pages(unsigned long start_pfn, unsigned long nr_pages,
 
        memory_notify(MEM_OFFLINE, &arg);
        remove_pfn_range_from_zone(zone, start_pfn, nr_pages);
-       mem_hotplug_done();
        return 0;
 
 failed_removal_isolated:
@@ -2046,7 +2046,6 @@ failed_removal:
                 (unsigned long long) start_pfn << PAGE_SHIFT,
                 ((unsigned long long) end_pfn << PAGE_SHIFT) - 1,
                 reason);
-       mem_hotplug_done();
        return ret;
 }
 
index aff31cd944c29d60b3634ef9ac098aadb290bb0f..b240d9aae4a6435cdd973f27e54b48f7bd8f9298 100644 (file)
@@ -183,7 +183,7 @@ out:
 }
 
 static const struct genl_multicast_group dropmon_mcgrps[] = {
-       { .name = "events", },
+       { .name = "events", .cap_sys_admin = 1 },
 };
 
 static void send_dm_alert(struct work_struct *work)
@@ -1619,11 +1619,13 @@ static const struct genl_small_ops dropmon_ops[] = {
                .cmd = NET_DM_CMD_START,
                .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
                .doit = net_dm_cmd_trace,
+               .flags = GENL_ADMIN_PERM,
        },
        {
                .cmd = NET_DM_CMD_STOP,
                .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
                .doit = net_dm_cmd_trace,
+               .flags = GENL_ADMIN_PERM,
        },
        {
                .cmd = NET_DM_CMD_CONFIG_GET,
index 7e4d7c3bcc849a9211eca4246cda7fa76af13c36..1737884be52f85ac5818b870ae567ebc3501bfb6 100644 (file)
@@ -2602,6 +2602,22 @@ BPF_CALL_2(bpf_msg_cork_bytes, struct sk_msg *, msg, u32, bytes)
        return 0;
 }
 
+static void sk_msg_reset_curr(struct sk_msg *msg)
+{
+       u32 i = msg->sg.start;
+       u32 len = 0;
+
+       do {
+               len += sk_msg_elem(msg, i)->length;
+               sk_msg_iter_var_next(i);
+               if (len >= msg->sg.size)
+                       break;
+       } while (i != msg->sg.end);
+
+       msg->sg.curr = i;
+       msg->sg.copybreak = 0;
+}
+
 static const struct bpf_func_proto bpf_msg_cork_bytes_proto = {
        .func           = bpf_msg_cork_bytes,
        .gpl_only       = false,
@@ -2721,6 +2737,7 @@ BPF_CALL_4(bpf_msg_pull_data, struct sk_msg *, msg, u32, start,
                      msg->sg.end - shift + NR_MSG_FRAG_IDS :
                      msg->sg.end - shift;
 out:
+       sk_msg_reset_curr(msg);
        msg->data = sg_virt(&msg->sg.data[first_sge]) + start - offset;
        msg->data_end = msg->data + bytes;
        return 0;
@@ -2857,6 +2874,7 @@ BPF_CALL_4(bpf_msg_push_data, struct sk_msg *, msg, u32, start,
                msg->sg.data[new] = rsge;
        }
 
+       sk_msg_reset_curr(msg);
        sk_msg_compute_data_pointers(msg);
        return 0;
 }
@@ -3025,6 +3043,7 @@ BPF_CALL_4(bpf_msg_pop_data, struct sk_msg *, msg, u32, start,
 
        sk_mem_uncharge(msg->sk, len - pop);
        msg->sg.size -= (len - pop);
+       sk_msg_reset_curr(msg);
        sk_msg_compute_data_pointers(msg);
        return 0;
 }
index 22a26d1d29a09d234f18ce3b0f329e5047c0c046..5169c3c72cffe49cef613e69889d139db867ff74 100644 (file)
@@ -635,15 +635,18 @@ static netdev_tx_t ipgre_xmit(struct sk_buff *skb,
        }
 
        if (dev->header_ops) {
+               int pull_len = tunnel->hlen + sizeof(struct iphdr);
+
                if (skb_cow_head(skb, 0))
                        goto free_skb;
 
                tnl_params = (const struct iphdr *)skb->data;
 
-               /* Pull skb since ip_tunnel_xmit() needs skb->data pointing
-                * to gre header.
-                */
-               skb_pull(skb, tunnel->hlen + sizeof(struct iphdr));
+               if (!pskb_network_may_pull(skb, pull_len))
+                       goto free_skb;
+
+               /* ip_tunnel_xmit() needs skb->data pointing to gre header. */
+               skb_pull(skb, pull_len);
                skb_reset_mac_header(skb);
 
                if (skb->ip_summed == CHECKSUM_PARTIAL &&
index 53bcc17c91e4c4fc0799f3f5d51b7ad5c8f32b26..ff6838ca2e58068d6ab435d2bb31babccb728c19 100644 (file)
@@ -3368,9 +3368,25 @@ int tcp_set_window_clamp(struct sock *sk, int val)
                        return -EINVAL;
                tp->window_clamp = 0;
        } else {
-               tp->window_clamp = val < SOCK_MIN_RCVBUF / 2 ?
-                       SOCK_MIN_RCVBUF / 2 : val;
-               tp->rcv_ssthresh = min(tp->rcv_wnd, tp->window_clamp);
+               u32 new_rcv_ssthresh, old_window_clamp = tp->window_clamp;
+               u32 new_window_clamp = val < SOCK_MIN_RCVBUF / 2 ?
+                                               SOCK_MIN_RCVBUF / 2 : val;
+
+               if (new_window_clamp == old_window_clamp)
+                       return 0;
+
+               tp->window_clamp = new_window_clamp;
+               if (new_window_clamp < old_window_clamp) {
+                       /* need to apply the reserved mem provisioning only
+                        * when shrinking the window clamp
+                        */
+                       __tcp_adjust_rcv_ssthresh(sk, tp->window_clamp);
+
+               } else {
+                       new_rcv_ssthresh = min(tp->rcv_wnd, tp->window_clamp);
+                       tp->rcv_ssthresh = max(new_rcv_ssthresh,
+                                              tp->rcv_ssthresh);
+               }
        }
        return 0;
 }
@@ -3594,6 +3610,10 @@ int do_tcp_setsockopt(struct sock *sk, int level, int optname,
                break;
 
        case TCP_AO_REPAIR:
+               if (!tcp_can_repair_sock(sk)) {
+                       err = -EPERM;
+                       break;
+               }
                err = tcp_ao_set_repair(sk, optval, optlen);
                break;
 #ifdef CONFIG_TCP_AO
@@ -4293,6 +4313,8 @@ zerocopy_rcv_out:
        }
 #endif
        case TCP_AO_REPAIR:
+               if (!tcp_can_repair_sock(sk))
+                       return -EPERM;
                return tcp_ao_get_repair(sk, optval, optlen);
        case TCP_AO_GET_KEYS:
        case TCP_AO_INFO: {
index 7696417d064011d3b437c2035b6fe1e5a3a0e6df..f8308d3f565e9d8e46d8fef608de000c2b552b5b 100644 (file)
@@ -851,7 +851,7 @@ void tcp_ao_syncookie(struct sock *sk, const struct sk_buff *skb,
        const struct tcp_ao_hdr *aoh;
        struct tcp_ao_key *key;
 
-       treq->maclen = 0;
+       treq->used_tcp_ao = false;
 
        if (tcp_parse_auth_options(th, NULL, &aoh) || !aoh)
                return;
@@ -863,7 +863,7 @@ void tcp_ao_syncookie(struct sock *sk, const struct sk_buff *skb,
 
        treq->ao_rcv_next = aoh->keyid;
        treq->ao_keyid = aoh->rnext_keyid;
-       treq->maclen = tcp_ao_maclen(key);
+       treq->used_tcp_ao = true;
 }
 
 static enum skb_drop_reason
@@ -1100,7 +1100,7 @@ void tcp_ao_connect_init(struct sock *sk)
                        ao_info->current_key = key;
                if (!ao_info->rnext_key)
                        ao_info->rnext_key = key;
-               tp->tcp_header_len += tcp_ao_len(key);
+               tp->tcp_header_len += tcp_ao_len_aligned(key);
 
                ao_info->lisn = htonl(tp->write_seq);
                ao_info->snd_sne = 0;
@@ -1346,7 +1346,7 @@ static int tcp_ao_parse_crypto(struct tcp_ao_add *cmd, struct tcp_ao_key *key)
        syn_tcp_option_space -= TCPOLEN_MSS_ALIGNED;
        syn_tcp_option_space -= TCPOLEN_TSTAMP_ALIGNED;
        syn_tcp_option_space -= TCPOLEN_WSCALE_ALIGNED;
-       if (tcp_ao_len(key) > syn_tcp_option_space) {
+       if (tcp_ao_len_aligned(key) > syn_tcp_option_space) {
                err = -EMSGSIZE;
                goto err_kfree;
        }
@@ -1608,6 +1608,15 @@ static int tcp_ao_add_cmd(struct sock *sk, unsigned short int family,
                if (!dev || !l3index)
                        return -EINVAL;
 
+               if (!bound_dev_if || bound_dev_if != cmd.ifindex) {
+                       /* tcp_ao_established_key() doesn't expect having
+                        * non peer-matching key on an established TCP-AO
+                        * connection.
+                        */
+                       if (!((1 << sk->sk_state) & (TCPF_LISTEN | TCPF_CLOSE)))
+                               return -EINVAL;
+               }
+
                /* It's still possible to bind after adding keys or even
                 * re-bind to a different dev (with CAP_NET_RAW).
                 * So, no reason to return error here, rather try to be
index bcb55d98004c5213f0095613124d5193b15b2793..90de838a274519110ce0ac84552c4caedb826eb7 100644 (file)
@@ -3871,8 +3871,12 @@ static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag)
         * then we can probably ignore it.
         */
        if (before(ack, prior_snd_una)) {
+               u32 max_window;
+
+               /* do not accept ACK for bytes we never sent. */
+               max_window = min_t(u64, tp->max_window, tp->bytes_acked);
                /* RFC 5961 5.2 [Blind Data Injection Attack].[Mitigation] */
-               if (before(ack, prior_snd_una - tp->max_window)) {
+               if (before(ack, prior_snd_una - max_window)) {
                        if (!(flag & FLAG_NO_CHALLENGE_ACK))
                                tcp_send_challenge_ack(sk);
                        return -SKB_DROP_REASON_TCP_TOO_OLD_ACK;
@@ -7182,11 +7186,12 @@ int tcp_conn_request(struct request_sock_ops *rsk_ops,
        if (tcp_parse_auth_options(tcp_hdr(skb), NULL, &aoh))
                goto drop_and_release; /* Invalid TCP options */
        if (aoh) {
-               tcp_rsk(req)->maclen = aoh->length - sizeof(struct tcp_ao_hdr);
+               tcp_rsk(req)->used_tcp_ao = true;
                tcp_rsk(req)->ao_rcv_next = aoh->keyid;
                tcp_rsk(req)->ao_keyid = aoh->rnext_keyid;
+
        } else {
-               tcp_rsk(req)->maclen = 0;
+               tcp_rsk(req)->used_tcp_ao = false;
        }
 #endif
        tcp_rsk(req)->snt_isn = isn;
index 5f693bbd578d2261b78aa0be6bf69499bbd5117e..0c50c5a32b84a3b601510655ecaa39b46a8f0b34 100644 (file)
@@ -690,7 +690,7 @@ static bool tcp_v4_ao_sign_reset(const struct sock *sk, struct sk_buff *skb,
 
        reply_options[0] = htonl((TCPOPT_AO << 24) | (tcp_ao_len(key) << 16) |
                                 (aoh->rnext_keyid << 8) | keyid);
-       arg->iov[0].iov_len += round_up(tcp_ao_len(key), 4);
+       arg->iov[0].iov_len += tcp_ao_len_aligned(key);
        reply->doff = arg->iov[0].iov_len / 4;
 
        if (tcp_ao_hash_hdr(AF_INET, (char *)&reply_options[1],
@@ -978,7 +978,7 @@ static void tcp_v4_send_ack(const struct sock *sk,
                                          (tcp_ao_len(key->ao_key) << 16) |
                                          (key->ao_key->sndid << 8) |
                                          key->rcv_next);
-               arg.iov[0].iov_len += round_up(tcp_ao_len(key->ao_key), 4);
+               arg.iov[0].iov_len += tcp_ao_len_aligned(key->ao_key);
                rep.th.doff = arg.iov[0].iov_len / 4;
 
                tcp_ao_hash_hdr(AF_INET, (char *)&rep.opt[offset],
index a9807eeb311ca6a276a8ab87ed359819f816cf41..9e85f2a0bddd4978b1bde6add1efc6aad351db8b 100644 (file)
@@ -615,7 +615,7 @@ struct sock *tcp_create_openreq_child(const struct sock *sk,
        ao_key = treq->af_specific->ao_lookup(sk, req,
                                tcp_rsk(req)->ao_keyid, -1);
        if (ao_key)
-               newtp->tcp_header_len += tcp_ao_len(ao_key);
+               newtp->tcp_header_len += tcp_ao_len_aligned(ao_key);
  #endif
        if (skb->len >= TCP_MSS_DEFAULT + newtp->tcp_header_len)
                newicsk->icsk_ack.last_seg_size = skb->len - newtp->tcp_header_len;
index eb13a55d660c2376968f11ee3265280f8cc9e1bd..f5ef15e1d9ac38ff9866d913056b2d0cc5ee685f 100644 (file)
@@ -825,7 +825,7 @@ static unsigned int tcp_syn_options(struct sock *sk, struct sk_buff *skb,
                timestamps = READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_timestamps);
                if (tcp_key_is_ao(key)) {
                        opts->options |= OPTION_AO;
-                       remaining -= tcp_ao_len(key->ao_key);
+                       remaining -= tcp_ao_len_aligned(key->ao_key);
                }
        }
 
@@ -915,7 +915,7 @@ static unsigned int tcp_synack_options(const struct sock *sk,
                        ireq->tstamp_ok &= !ireq->sack_ok;
        } else if (tcp_key_is_ao(key)) {
                opts->options |= OPTION_AO;
-               remaining -= tcp_ao_len(key->ao_key);
+               remaining -= tcp_ao_len_aligned(key->ao_key);
                ireq->tstamp_ok &= !ireq->sack_ok;
        }
 
@@ -982,7 +982,7 @@ static unsigned int tcp_established_options(struct sock *sk, struct sk_buff *skb
                size += TCPOLEN_MD5SIG_ALIGNED;
        } else if (tcp_key_is_ao(key)) {
                opts->options |= OPTION_AO;
-               size += tcp_ao_len(key->ao_key);
+               size += tcp_ao_len_aligned(key->ao_key);
        }
 
        if (likely(tp->rx_opt.tstamp_ok)) {
@@ -3720,7 +3720,6 @@ struct sk_buff *tcp_make_synack(const struct sock *sk, struct dst_entry *dst,
        if (tcp_rsk_used_ao(req)) {
 #ifdef CONFIG_TCP_AO
                struct tcp_ao_key *ao_key = NULL;
-               u8 maclen = tcp_rsk(req)->maclen;
                u8 keyid = tcp_rsk(req)->ao_keyid;
 
                ao_key = tcp_sk(sk)->af_specific->ao_lookup(sk, req_to_sk(req),
@@ -3730,13 +3729,11 @@ struct sk_buff *tcp_make_synack(const struct sock *sk, struct dst_entry *dst,
                 * for another peer-matching key, but the peer has requested
                 * ao_keyid (RFC5925 RNextKeyID), so let's keep it simple here.
                 */
-               if (unlikely(!ao_key || tcp_ao_maclen(ao_key) != maclen)) {
-                       u8 key_maclen = ao_key ? tcp_ao_maclen(ao_key) : 0;
-
+               if (unlikely(!ao_key)) {
                        rcu_read_unlock();
                        kfree_skb(skb);
-                       net_warn_ratelimited("TCP-AO: the keyid %u with maclen %u|%u from SYN packet is not present - not sending SYNACK\n",
-                                            keyid, maclen, key_maclen);
+                       net_warn_ratelimited("TCP-AO: the keyid %u from SYN packet is not present - not sending SYNACK\n",
+                                            keyid);
                        return NULL;
                }
                key.ao_key = ao_key;
index 28b01a068412ab673415bfd9d15b0fd15b3bdb19..7772f42ff2b940da5f53ee1f0ff0dfcdb187cbf0 100644 (file)
@@ -1511,13 +1511,9 @@ out:
                        if (!pn_leaf && !(pn->fn_flags & RTN_RTINFO)) {
                                pn_leaf = fib6_find_prefix(info->nl_net, table,
                                                           pn);
-#if RT6_DEBUG >= 2
-                               if (!pn_leaf) {
-                                       WARN_ON(!pn_leaf);
+                               if (!pn_leaf)
                                        pn_leaf =
                                            info->nl_net->ipv6.fib6_null_entry;
-                               }
-#endif
                                fib6_info_hold(pn_leaf);
                                rcu_assign_pointer(pn->leaf, pn_leaf);
                        }
index 937a02c2e5345390ed592b19faa661cd703a23f0..8c6623496dd7e9daf4cb63528a4817b3c65a334a 100644 (file)
@@ -881,7 +881,7 @@ static void tcp_v6_send_response(const struct sock *sk, struct sk_buff *skb, u32
        if (tcp_key_is_md5(key))
                tot_len += TCPOLEN_MD5SIG_ALIGNED;
        if (tcp_key_is_ao(key))
-               tot_len += tcp_ao_len(key->ao_key);
+               tot_len += tcp_ao_len_aligned(key->ao_key);
 
 #ifdef CONFIG_MPTCP
        if (rst && !tcp_key_is_md5(key)) {
index e502ec00b2fe1e4a806568fe078ef328e4f15ac7..0e4beae421f8302cb0bc6cb798daf36366da0e4b 100644 (file)
@@ -31,7 +31,7 @@ struct bpf_nf_link {
 #if IS_ENABLED(CONFIG_NF_DEFRAG_IPV4) || IS_ENABLED(CONFIG_NF_DEFRAG_IPV6)
 static const struct nf_defrag_hook *
 get_proto_defrag_hook(struct bpf_nf_link *link,
-                     const struct nf_defrag_hook __rcu *global_hook,
+                     const struct nf_defrag_hook __rcu **ptr_global_hook,
                      const char *mod)
 {
        const struct nf_defrag_hook *hook;
@@ -39,7 +39,7 @@ get_proto_defrag_hook(struct bpf_nf_link *link,
 
        /* RCU protects us from races against module unloading */
        rcu_read_lock();
-       hook = rcu_dereference(global_hook);
+       hook = rcu_dereference(*ptr_global_hook);
        if (!hook) {
                rcu_read_unlock();
                err = request_module(mod);
@@ -47,7 +47,7 @@ get_proto_defrag_hook(struct bpf_nf_link *link,
                        return ERR_PTR(err < 0 ? err : -EINVAL);
 
                rcu_read_lock();
-               hook = rcu_dereference(global_hook);
+               hook = rcu_dereference(*ptr_global_hook);
        }
 
        if (hook && try_module_get(hook->owner)) {
@@ -78,7 +78,7 @@ static int bpf_nf_enable_defrag(struct bpf_nf_link *link)
        switch (link->hook_ops.pf) {
 #if IS_ENABLED(CONFIG_NF_DEFRAG_IPV4)
        case NFPROTO_IPV4:
-               hook = get_proto_defrag_hook(link, nf_defrag_v4_hook, "nf_defrag_ipv4");
+               hook = get_proto_defrag_hook(link, &nf_defrag_v4_hook, "nf_defrag_ipv4");
                if (IS_ERR(hook))
                        return PTR_ERR(hook);
 
@@ -87,7 +87,7 @@ static int bpf_nf_enable_defrag(struct bpf_nf_link *link)
 #endif
 #if IS_ENABLED(CONFIG_NF_DEFRAG_IPV6)
        case NFPROTO_IPV6:
-               hook = get_proto_defrag_hook(link, nf_defrag_v6_hook, "nf_defrag_ipv6");
+               hook = get_proto_defrag_hook(link, &nf_defrag_v6_hook, "nf_defrag_ipv6");
                if (IS_ERR(hook))
                        return PTR_ERR(hook);
 
index c0a42989b982266aa7378f06c0a46b5668335d3a..c5c17c6e80eda1f5a33e035a427ee4b2be2f786f 100644 (file)
@@ -803,7 +803,7 @@ static struct nft_table *nft_table_lookup(const struct net *net,
 
 static struct nft_table *nft_table_lookup_byhandle(const struct net *net,
                                                   const struct nlattr *nla,
-                                                  u8 genmask, u32 nlpid)
+                                                  int family, u8 genmask, u32 nlpid)
 {
        struct nftables_pernet *nft_net;
        struct nft_table *table;
@@ -811,6 +811,7 @@ static struct nft_table *nft_table_lookup_byhandle(const struct net *net,
        nft_net = nft_pernet(net);
        list_for_each_entry(table, &nft_net->tables, list) {
                if (be64_to_cpu(nla_get_be64(nla)) == table->handle &&
+                   table->family == family &&
                    nft_active_genmask(table, genmask)) {
                        if (nft_table_has_owner(table) &&
                            nlpid && table->nlpid != nlpid)
@@ -1544,7 +1545,7 @@ static int nf_tables_deltable(struct sk_buff *skb, const struct nfnl_info *info,
 
        if (nla[NFTA_TABLE_HANDLE]) {
                attr = nla[NFTA_TABLE_HANDLE];
-               table = nft_table_lookup_byhandle(net, attr, genmask,
+               table = nft_table_lookup_byhandle(net, attr, family, genmask,
                                                  NETLINK_CB(skb).portid);
        } else {
                attr = nla[NFTA_TABLE_NAME];
index b18a7903912597115c27e2857298c0211cca0fd0..c09dba57354c17e0776e4d5c3b52486719d20163 100644 (file)
@@ -280,10 +280,15 @@ static int nft_dynset_init(const struct nft_ctx *ctx,
                        priv->expr_array[i] = dynset_expr;
                        priv->num_exprs++;
 
-                       if (set->num_exprs &&
-                           dynset_expr->ops != set->exprs[i]->ops) {
-                               err = -EOPNOTSUPP;
-                               goto err_expr_free;
+                       if (set->num_exprs) {
+                               if (i >= set->num_exprs) {
+                                       err = -EINVAL;
+                                       goto err_expr_free;
+                               }
+                               if (dynset_expr->ops != set->exprs[i]->ops) {
+                                       err = -EOPNOTSUPP;
+                                       goto err_expr_free;
+                               }
                        }
                        i++;
                }
index 3fbaa7bf41f9c74956c826ee63797406bff9f297..6eb571d0c3fdfcb4ac6cef4b313f039ecfe2517b 100644 (file)
@@ -214,7 +214,7 @@ static void nft_exthdr_tcp_eval(const struct nft_expr *expr,
 
                offset = i + priv->offset;
                if (priv->flags & NFT_EXTHDR_F_PRESENT) {
-                       *dest = 1;
+                       nft_reg_store8(dest, 1);
                } else {
                        if (priv->len % NFT_REG32_SIZE)
                                dest[priv->len / NFT_REG32_SIZE] = 0;
@@ -461,7 +461,7 @@ static void nft_exthdr_dccp_eval(const struct nft_expr *expr,
                type = bufp[0];
 
                if (type == priv->type) {
-                       *dest = 1;
+                       nft_reg_store8(dest, 1);
                        return;
                }
 
index 1bfe258018da45fb8cf9f95fe0d3b871e5023f31..37cfe6dd712d8b138fc290abe66fd8d9b69963d6 100644 (file)
@@ -145,11 +145,15 @@ void nft_fib_store_result(void *reg, const struct nft_fib *priv,
        switch (priv->result) {
        case NFT_FIB_RESULT_OIF:
                index = dev ? dev->ifindex : 0;
-               *dreg = (priv->flags & NFTA_FIB_F_PRESENT) ? !!index : index;
+               if (priv->flags & NFTA_FIB_F_PRESENT)
+                       nft_reg_store8(dreg, !!index);
+               else
+                       *dreg = index;
+
                break;
        case NFT_FIB_RESULT_OIFNAME:
                if (priv->flags & NFTA_FIB_F_PRESENT)
-                       *dreg = !!dev;
+                       nft_reg_store8(dreg, !!dev);
                else
                        strscpy_pad(reg, dev ? dev->name : "", IFNAMSIZ);
                break;
index 701977af3ee851947dbf3096e729f3161928b9d6..7252fcdae34993835d10d143c02755958ad9a7e2 100644 (file)
@@ -2043,6 +2043,9 @@ static void nft_pipapo_walk(const struct nft_ctx *ctx, struct nft_set *set,
 
                e = f->mt[r].e;
 
+               if (!nft_set_elem_active(&e->ext, iter->genmask))
+                       goto cont;
+
                iter->err = iter->fn(ctx, set, iter, &e->priv);
                if (iter->err < 0)
                        goto out;
index e85ce69924aee95d46ab597b1357ddd0d2c6c2b7..50332888c8d233aab0915a31f2f616f3171da45e 100644 (file)
@@ -76,18 +76,23 @@ owner_mt(const struct sk_buff *skb, struct xt_action_param *par)
                 */
                return false;
 
-       filp = sk->sk_socket->file;
-       if (filp == NULL)
+       read_lock_bh(&sk->sk_callback_lock);
+       filp = sk->sk_socket ? sk->sk_socket->file : NULL;
+       if (filp == NULL) {
+               read_unlock_bh(&sk->sk_callback_lock);
                return ((info->match ^ info->invert) &
                       (XT_OWNER_UID | XT_OWNER_GID)) == 0;
+       }
 
        if (info->match & XT_OWNER_UID) {
                kuid_t uid_min = make_kuid(net->user_ns, info->uid_min);
                kuid_t uid_max = make_kuid(net->user_ns, info->uid_max);
                if ((uid_gte(filp->f_cred->fsuid, uid_min) &&
                     uid_lte(filp->f_cred->fsuid, uid_max)) ^
-                   !(info->invert & XT_OWNER_UID))
+                   !(info->invert & XT_OWNER_UID)) {
+                       read_unlock_bh(&sk->sk_callback_lock);
                        return false;
+               }
        }
 
        if (info->match & XT_OWNER_GID) {
@@ -112,10 +117,13 @@ owner_mt(const struct sk_buff *skb, struct xt_action_param *par)
                        }
                }
 
-               if (match ^ !(info->invert & XT_OWNER_GID))
+               if (match ^ !(info->invert & XT_OWNER_GID)) {
+                       read_unlock_bh(&sk->sk_callback_lock);
                        return false;
+               }
        }
 
+       read_unlock_bh(&sk->sk_callback_lock);
        return true;
 }
 
index 92ef5ed2e7b0422e389d1a9c5696c6e2323a7450..9c7ffd10df2a72c00d626ab40ca95bb739425983 100644 (file)
@@ -1691,6 +1691,9 @@ static int genl_bind(struct net *net, int group)
                if ((grp->flags & GENL_UNS_ADMIN_PERM) &&
                    !ns_capable(net->user_ns, CAP_NET_ADMIN))
                        ret = -EPERM;
+               if (grp->cap_sys_admin &&
+                   !ns_capable(net->user_ns, CAP_SYS_ADMIN))
+                       ret = -EPERM;
 
                break;
        }
index a84e00b5904be0fad471324d1492979403a2fab3..7adf48549a3b7d263ad5cd7dd3b665efebdc32f9 100644 (file)
@@ -4300,7 +4300,7 @@ static void packet_mm_open(struct vm_area_struct *vma)
        struct sock *sk = sock->sk;
 
        if (sk)
-               atomic_inc(&pkt_sk(sk)->mapped);
+               atomic_long_inc(&pkt_sk(sk)->mapped);
 }
 
 static void packet_mm_close(struct vm_area_struct *vma)
@@ -4310,7 +4310,7 @@ static void packet_mm_close(struct vm_area_struct *vma)
        struct sock *sk = sock->sk;
 
        if (sk)
-               atomic_dec(&pkt_sk(sk)->mapped);
+               atomic_long_dec(&pkt_sk(sk)->mapped);
 }
 
 static const struct vm_operations_struct packet_mmap_ops = {
@@ -4405,7 +4405,7 @@ static int packet_set_ring(struct sock *sk, union tpacket_req_u *req_u,
 
        err = -EBUSY;
        if (!closing) {
-               if (atomic_read(&po->mapped))
+               if (atomic_long_read(&po->mapped))
                        goto out;
                if (packet_read_pending(rb))
                        goto out;
@@ -4508,7 +4508,7 @@ static int packet_set_ring(struct sock *sk, union tpacket_req_u *req_u,
 
        err = -EBUSY;
        mutex_lock(&po->pg_vec_lock);
-       if (closing || atomic_read(&po->mapped) == 0) {
+       if (closing || atomic_long_read(&po->mapped) == 0) {
                err = 0;
                spin_lock_bh(&rb_queue->lock);
                swap(rb->pg_vec, pg_vec);
@@ -4526,9 +4526,9 @@ static int packet_set_ring(struct sock *sk, union tpacket_req_u *req_u,
                po->prot_hook.func = (po->rx_ring.pg_vec) ?
                                                tpacket_rcv : packet_rcv;
                skb_queue_purge(rb_queue);
-               if (atomic_read(&po->mapped))
-                       pr_err("packet_mmap: vma is busy: %d\n",
-                              atomic_read(&po->mapped));
+               if (atomic_long_read(&po->mapped))
+                       pr_err("packet_mmap: vma is busy: %ld\n",
+                              atomic_long_read(&po->mapped));
        }
        mutex_unlock(&po->pg_vec_lock);
 
@@ -4606,7 +4606,7 @@ static int packet_mmap(struct file *file, struct socket *sock,
                }
        }
 
-       atomic_inc(&po->mapped);
+       atomic_long_inc(&po->mapped);
        vma->vm_ops = &packet_mmap_ops;
        err = 0;
 
index d29c94c45159dd488530bc6bb6a1b7d847d1d1e2..d5d70712007ad32bf1227ee59dcc12e12bbb77e4 100644 (file)
@@ -122,7 +122,7 @@ struct packet_sock {
        __be16                  num;
        struct packet_rollover  *rollover;
        struct packet_mclist    *mclist;
-       atomic_t                mapped;
+       atomic_long_t           mapped;
        enum tpacket_versions   tp_version;
        unsigned int            tp_hdrlen;
        unsigned int            tp_reserve;
index 81a794e36f535864869812c2003ff65d4c96efd0..c34e902855dbefdd37b86e2f9cb9ef067be87c3d 100644 (file)
@@ -31,7 +31,8 @@ enum psample_nl_multicast_groups {
 
 static const struct genl_multicast_group psample_nl_mcgrps[] = {
        [PSAMPLE_NL_MCGRP_CONFIG] = { .name = PSAMPLE_NL_MCGRP_CONFIG_NAME },
-       [PSAMPLE_NL_MCGRP_SAMPLE] = { .name = PSAMPLE_NL_MCGRP_SAMPLE_NAME },
+       [PSAMPLE_NL_MCGRP_SAMPLE] = { .name = PSAMPLE_NL_MCGRP_SAMPLE_NAME,
+                                     .flags = GENL_UNS_ADMIN_PERM },
 };
 
 static struct genl_family psample_nl_family __ro_after_init;
index 2a1388841951e4b6d447ab1f7b2dff4586ad4218..73eebddbbf41d37a12de450420f41ddcedeb26f3 100644 (file)
@@ -723,7 +723,7 @@ static void smcd_conn_save_peer_info(struct smc_sock *smc,
        int bufsize = smc_uncompress_bufsize(clc->d0.dmbe_size);
 
        smc->conn.peer_rmbe_idx = clc->d0.dmbe_idx;
-       smc->conn.peer_token = clc->d0.token;
+       smc->conn.peer_token = ntohll(clc->d0.token);
        /* msg header takes up space in the buffer */
        smc->conn.peer_rmbe_size = bufsize - sizeof(struct smcd_cdc_msg);
        atomic_set(&smc->conn.peer_rmbe_space, smc->conn.peer_rmbe_size);
@@ -1415,7 +1415,7 @@ static int smc_connect_ism(struct smc_sock *smc,
                if (rc)
                        return rc;
        }
-       ini->ism_peer_gid[ini->ism_selected] = aclc->d0.gid;
+       ini->ism_peer_gid[ini->ism_selected] = ntohll(aclc->d0.gid);
 
        /* there is only one lgr role for SMC-D; use server lock */
        mutex_lock(&smc_server_lgr_pending);
index 8deb46c28f1d55e81e996bd6ae06c1f09e30320b..72f4d81a3f41f27215baa9bacfd05b1e51356cf7 100644 (file)
@@ -1004,6 +1004,7 @@ static int smc_clc_send_confirm_accept(struct smc_sock *smc,
 {
        struct smc_connection *conn = &smc->conn;
        struct smc_clc_first_contact_ext_v2x fce;
+       struct smcd_dev *smcd = conn->lgr->smcd;
        struct smc_clc_msg_accept_confirm *clc;
        struct smc_clc_fce_gid_ext gle;
        struct smc_clc_msg_trail trl;
@@ -1021,17 +1022,15 @@ static int smc_clc_send_confirm_accept(struct smc_sock *smc,
                memcpy(clc->hdr.eyecatcher, SMCD_EYECATCHER,
                       sizeof(SMCD_EYECATCHER));
                clc->hdr.typev1 = SMC_TYPE_D;
-               clc->d0.gid =
-                       conn->lgr->smcd->ops->get_local_gid(conn->lgr->smcd);
-               clc->d0.token = conn->rmb_desc->token;
+               clc->d0.gid = htonll(smcd->ops->get_local_gid(smcd));
+               clc->d0.token = htonll(conn->rmb_desc->token);
                clc->d0.dmbe_size = conn->rmbe_size_comp;
                clc->d0.dmbe_idx = 0;
                memcpy(&clc->d0.linkid, conn->lgr->id, SMC_LGR_ID_SIZE);
                if (version == SMC_V1) {
                        clc->hdr.length = htons(SMCD_CLC_ACCEPT_CONFIRM_LEN);
                } else {
-                       clc_v2->d1.chid =
-                               htons(smc_ism_get_chid(conn->lgr->smcd));
+                       clc_v2->d1.chid = htons(smc_ism_get_chid(smcd));
                        if (eid && eid[0])
                                memcpy(clc_v2->d1.eid, eid, SMC_MAX_EID_LEN);
                        len = SMCD_CLC_ACCEPT_CONFIRM_LEN_V2;
index c5c8e7db775a7680ef7a375692b504bf243b4900..08155a96a02a17864712f5de157244cc0949a24f 100644 (file)
@@ -204,8 +204,8 @@ struct smcr_clc_msg_accept_confirm {        /* SMCR accept/confirm */
 } __packed;
 
 struct smcd_clc_msg_accept_confirm_common {    /* SMCD accept/confirm */
-       u64 gid;                /* Sender GID */
-       u64 token;              /* DMB token */
+       __be64 gid;             /* Sender GID */
+       __be64 token;           /* DMB token */
        u8 dmbe_idx;            /* DMBE index */
 #if defined(__BIG_ENDIAN_BITFIELD)
        u8 dmbe_size : 4,       /* buf size (compressed) */
index 316f761879624d688af85b60527868d5f0d00a49..e37b4d2e2acde25d6879770629b3996d03860c56 100644 (file)
@@ -952,6 +952,8 @@ static int tls_sw_sendmsg_splice(struct sock *sk, struct msghdr *msg,
                }
 
                sk_msg_page_add(msg_pl, page, part, off);
+               msg_pl->sg.copybreak = 0;
+               msg_pl->sg.curr = msg_pl->sg.end;
                sk_mem_charge(sk, part);
                *copied += part;
                try_to_copy -= part;
index f6dc896bf44c6e3b0952d783c9d633cd6596dbee..c8e162c9d1df9265bd6e93586fca9e721fae979e 100644 (file)
@@ -59,8 +59,7 @@ static bool virtio_transport_can_zcopy(const struct virtio_transport *t_ops,
        t_ops = virtio_transport_get_ops(info->vsk);
 
        if (t_ops->can_msgzerocopy) {
-               int pages_in_iov = iov_iter_npages(iov_iter, MAX_SKB_FRAGS);
-               int pages_to_send = min(pages_in_iov, MAX_SKB_FRAGS);
+               int pages_to_send = iov_iter_npages(iov_iter, MAX_SKB_FRAGS);
 
                /* +1 is for packet header. */
                return t_ops->can_msgzerocopy(pages_to_send + 1);
index ae9f8cb611f6ca9b1bd0693fd5771198f7555d8f..3da0b52f308d4a4f4cd946301987fb246e25b76b 100644 (file)
@@ -947,7 +947,7 @@ static __poll_t xsk_poll(struct file *file, struct socket *sock,
 
        rcu_read_lock();
        if (xsk_check_common(xs))
-               goto skip_tx;
+               goto out;
 
        pool = xs->pool;
 
@@ -959,12 +959,11 @@ static __poll_t xsk_poll(struct file *file, struct socket *sock,
                        xsk_generic_xmit(sk);
        }
 
-skip_tx:
        if (xs->rx && !xskq_prod_is_empty(xs->rx))
                mask |= EPOLLIN | EPOLLRDNORM;
        if (xs->tx && xsk_tx_writeable(xs))
                mask |= EPOLLOUT | EPOLLWRNORM;
-
+out:
        rcu_read_unlock();
        return mask;
 }
index d83ba5d8f3f49f6c5e7349fefff382c0264fafb8..f27d552aec43f2b41aacf195069510c3121be03b 100755 (executable)
@@ -138,15 +138,11 @@ $total_size = 0;
 while (my $line = <STDIN>) {
        if ($line =~ m/$funcre/) {
                $func = $1;
-               next if $line !~ m/^($xs*)/;
+               next if $line !~ m/^($x*)/;
                if ($total_size > $min_stack) {
                        push @stack, "$intro$total_size\n";
                }
-
-               $addr = $1;
-               $addr =~ s/ /0/g;
-               $addr = "0x$addr";
-
+               $addr = "0x$1";
                $intro = "$addr $func [$file]:";
                my $padlen = 56 - length($intro);
                while ($padlen > 0) {
index bd07477dd1440fb21137d856b887b62e151d4082..5ffb2364409b1746c5f1b7e8c4c2e3a85ea2c5a4 100755 (executable)
@@ -1,8 +1,8 @@
 #!/usr/bin/env python3
 # SPDX-License-Identifier: GPL-2.0-only
 
+import fnmatch
 import os
-import glob
 import re
 import argparse
 
@@ -81,10 +81,20 @@ def print_compat(filename, compatibles):
        else:
                print(*compatibles, sep='\n')
 
+def glob_without_symlinks(root, glob):
+       for path, dirs, files in os.walk(root):
+               # Ignore hidden directories
+               for d in dirs:
+                       if fnmatch.fnmatch(d, ".*"):
+                               dirs.remove(d)
+               for f in files:
+                       if fnmatch.fnmatch(f, glob):
+                               yield os.path.join(path, f)
+
 def files_to_parse(path_args):
        for f in path_args:
                if os.path.isdir(f):
-                       for filename in glob.iglob(f + "/**/*.c", recursive=True):
+                       for filename in glob_without_symlinks(f, "*.c"):
                                yield filename
                else:
                        yield f
index 16376c5cfec641340d697b2de3cb91f9aef2dc07..0eabc5f4f8ca225f8ac360d7995dab380e20d363 100644 (file)
@@ -36,26 +36,26 @@ def for_each_bus():
     for kobj in kset_for_each_object(gdb.parse_and_eval('bus_kset')):
         subsys = container_of(kobj, kset_type.get_type().pointer(), 'kobj')
         subsys_priv = container_of(subsys, subsys_private_type.get_type().pointer(), 'subsys')
-        yield subsys_priv['bus']
+        yield subsys_priv
 
 
 def for_each_class():
     for kobj in kset_for_each_object(gdb.parse_and_eval('class_kset')):
         subsys = container_of(kobj, kset_type.get_type().pointer(), 'kobj')
         subsys_priv = container_of(subsys, subsys_private_type.get_type().pointer(), 'subsys')
-        yield subsys_priv['class']
+        yield subsys_priv
 
 
 def get_bus_by_name(name):
     for item in for_each_bus():
-        if item['name'].string() == name:
+        if item['bus']['name'].string() == name:
             return item
     raise gdb.GdbError("Can't find bus type {!r}".format(name))
 
 
 def get_class_by_name(name):
     for item in for_each_class():
-        if item['name'].string() == name:
+        if item['class']['name'].string() == name:
             return item
     raise gdb.GdbError("Can't find device class {!r}".format(name))
 
@@ -70,13 +70,13 @@ def klist_for_each(klist):
 
 
 def bus_for_each_device(bus):
-    for kn in klist_for_each(bus['p']['klist_devices']):
+    for kn in klist_for_each(bus['klist_devices']):
         dp = container_of(kn, device_private_type.get_type().pointer(), 'knode_bus')
         yield dp['device']
 
 
 def class_for_each_device(cls):
-    for kn in klist_for_each(cls['p']['klist_devices']):
+    for kn in klist_for_each(cls['klist_devices']):
         dp = container_of(kn, device_private_type.get_type().pointer(), 'knode_class')
         yield dp['device']
 
@@ -103,7 +103,7 @@ class LxDeviceListBus(gdb.Command):
     def invoke(self, arg, from_tty):
         if not arg:
             for bus in for_each_bus():
-                gdb.write('bus {}:\t{}\n'.format(bus['name'].string(), bus))
+                gdb.write('bus {}:\t{}\n'.format(bus['bus']['name'].string(), bus))
                 for dev in bus_for_each_device(bus):
                     _show_device(dev, level=1)
         else:
@@ -123,7 +123,7 @@ class LxDeviceListClass(gdb.Command):
     def invoke(self, arg, from_tty):
         if not arg:
             for cls in for_each_class():
-                gdb.write("class {}:\t{}\n".format(cls['name'].string(), cls))
+                gdb.write("class {}:\t{}\n".format(cls['class']['name'].string(), cls))
                 for dev in class_for_each_device(cls):
                     _show_device(dev, level=1)
         else:
index 17ec19e9b5bf6a93e95e224cc21c88320c5ad4ba..aa5ab6251f763b9860a6128e8582d1ef4af91f6a 100644 (file)
@@ -13,7 +13,7 @@
 
 import gdb
 
-from linux import utils
+from linux import utils, lists
 
 
 task_type = utils.CachedType("struct task_struct")
@@ -22,19 +22,15 @@ task_type = utils.CachedType("struct task_struct")
 def task_lists():
     task_ptr_type = task_type.get_type().pointer()
     init_task = gdb.parse_and_eval("init_task").address
-    t = g = init_task
+    t = init_task
 
     while True:
-        while True:
-            yield t
+        thread_head = t['signal']['thread_head']
+        for thread in lists.list_for_each_entry(thread_head, task_ptr_type, 'thread_node'):
+            yield thread
 
-            t = utils.container_of(t['thread_group']['next'],
-                                   task_ptr_type, "thread_group")
-            if t == g:
-                break
-
-        t = g = utils.container_of(g['tasks']['next'],
-                                   task_ptr_type, "tasks")
+        t = utils.container_of(t['tasks']['next'],
+                               task_ptr_type, "tasks")
         if t == init_task:
             return
 
index 20bb2d7c8d4bf6cde42153cdbb7a16a0cd2bbb75..6d0c9c37796c229e90936c5b42ae9980be69063f 100644 (file)
@@ -253,6 +253,7 @@ static const char * const snd_pcm_state_names[] = {
        STATE(DRAINING),
        STATE(PAUSED),
        STATE(SUSPENDED),
+       STATE(DISCONNECTED),
 };
 
 static const char * const snd_pcm_access_names[] = {
index b59b78a09224090ad04b23940b0c3a2ec4c526da..b8bff5522bce20e601ee363e0edd1bdd7b3261f2 100644 (file)
@@ -397,7 +397,6 @@ static int snd_pcmtst_pcm_close(struct snd_pcm_substream *substream)
        struct pcmtst_buf_iter *v_iter = substream->runtime->private_data;
 
        timer_shutdown_sync(&v_iter->timer_instance);
-       v_iter->substream = NULL;
        playback_capture_test = !v_iter->is_buf_corrupted;
        kfree(v_iter);
        return 0;
@@ -435,6 +434,7 @@ static int snd_pcmtst_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
        case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
                // We can't call timer_shutdown_sync here, as it is forbidden to sleep here
                v_iter->suspend = true;
+               timer_delete(&v_iter->timer_instance);
                break;
        }
 
@@ -512,12 +512,22 @@ static int snd_pcmtst_ioctl(struct snd_pcm_substream *substream, unsigned int cm
        return snd_pcm_lib_ioctl(substream, cmd, arg);
 }
 
+static int snd_pcmtst_sync_stop(struct snd_pcm_substream *substream)
+{
+       struct pcmtst_buf_iter *v_iter = substream->runtime->private_data;
+
+       timer_delete_sync(&v_iter->timer_instance);
+
+       return 0;
+}
+
 static const struct snd_pcm_ops snd_pcmtst_playback_ops = {
        .open =         snd_pcmtst_pcm_open,
        .close =        snd_pcmtst_pcm_close,
        .trigger =      snd_pcmtst_pcm_trigger,
        .hw_params =    snd_pcmtst_pcm_hw_params,
        .ioctl =        snd_pcmtst_ioctl,
+       .sync_stop =    snd_pcmtst_sync_stop,
        .hw_free =      snd_pcmtst_pcm_hw_free,
        .prepare =      snd_pcmtst_pcm_prepare,
        .pointer =      snd_pcmtst_pcm_pointer,
@@ -530,6 +540,7 @@ static const struct snd_pcm_ops snd_pcmtst_capture_ops = {
        .hw_params =    snd_pcmtst_pcm_hw_params,
        .hw_free =      snd_pcmtst_pcm_hw_free,
        .ioctl =        snd_pcmtst_ioctl,
+       .sync_stop =    snd_pcmtst_sync_stop,
        .prepare =      snd_pcmtst_pcm_prepare,
        .pointer =      snd_pcmtst_pcm_pointer,
 };
index f9ddacfd920e20ced7150cecb4a083721e2bd026..0377912e926435d0b69c68d25c926fda85c2cd9f 100644 (file)
@@ -9705,6 +9705,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
        SND_PCI_QUIRK(0x1028, 0x0b1a, "Dell Precision 5570", ALC289_FIXUP_DUAL_SPK),
        SND_PCI_QUIRK(0x1028, 0x0b37, "Dell Inspiron 16 Plus 7620 2-in-1", ALC295_FIXUP_DELL_INSPIRON_TOP_SPEAKERS),
        SND_PCI_QUIRK(0x1028, 0x0b71, "Dell Inspiron 16 Plus 7620", ALC295_FIXUP_DELL_INSPIRON_TOP_SPEAKERS),
+       SND_PCI_QUIRK(0x1028, 0x0beb, "Dell XPS 15 9530 (2023)", ALC289_FIXUP_DELL_CS35L41_SPI_2),
        SND_PCI_QUIRK(0x1028, 0x0c03, "Dell Precision 5340", ALC269_FIXUP_DELL4_MIC_NO_PRESENCE),
        SND_PCI_QUIRK(0x1028, 0x0c19, "Dell Precision 3340", ALC236_FIXUP_DELL_DUAL_CODECS),
        SND_PCI_QUIRK(0x1028, 0x0c1a, "Dell Precision 3340", ALC236_FIXUP_DELL_DUAL_CODECS),
@@ -9963,6 +9964,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
        SND_PCI_QUIRK(0x1043, 0x17f3, "ROG Ally RC71L_RC71L", ALC294_FIXUP_ASUS_ALLY),
        SND_PCI_QUIRK(0x1043, 0x1881, "ASUS Zephyrus S/M", ALC294_FIXUP_ASUS_GX502_PINS),
        SND_PCI_QUIRK(0x1043, 0x18b1, "Asus MJ401TA", ALC256_FIXUP_ASUS_HEADSET_MIC),
+       SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS UM3504DA", ALC294_FIXUP_CS35L41_I2C_2),
        SND_PCI_QUIRK(0x1043, 0x18f1, "Asus FX505DT", ALC256_FIXUP_ASUS_HEADSET_MIC),
        SND_PCI_QUIRK(0x1043, 0x194e, "ASUS UX563FD", ALC294_FIXUP_ASUS_HPE),
        SND_PCI_QUIRK(0x1043, 0x1970, "ASUS UX550VE", ALC289_FIXUP_ASUS_GA401),
@@ -10204,6 +10206,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
        SND_PCI_QUIRK(0x17aa, 0x387d, "Yoga S780-16 pro Quad AAC", ALC287_FIXUP_TAS2781_I2C),
        SND_PCI_QUIRK(0x17aa, 0x387e, "Yoga S780-16 pro Quad YC", ALC287_FIXUP_TAS2781_I2C),
        SND_PCI_QUIRK(0x17aa, 0x3881, "YB9 dual power mode2 YC", ALC287_FIXUP_TAS2781_I2C),
+       SND_PCI_QUIRK(0x17aa, 0x3882, "Lenovo Yoga Pro 7 14APH8", ALC287_FIXUP_YOGA9_14IAP7_BASS_SPK_PIN),
        SND_PCI_QUIRK(0x17aa, 0x3884, "Y780 YG DUAL", ALC287_FIXUP_TAS2781_I2C),
        SND_PCI_QUIRK(0x17aa, 0x3886, "Y780 VECO DUAL", ALC287_FIXUP_TAS2781_I2C),
        SND_PCI_QUIRK(0x17aa, 0x38a7, "Y780P AMD YG dual", ALC287_FIXUP_TAS2781_I2C),
@@ -10271,6 +10274,8 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
        SND_PCI_QUIRK(0x8086, 0x2081, "Intel NUC 10", ALC256_FIXUP_INTEL_NUC10),
        SND_PCI_QUIRK(0x8086, 0x3038, "Intel NUC 13", ALC295_FIXUP_CHROME_BOOK),
        SND_PCI_QUIRK(0xf111, 0x0001, "Framework Laptop", ALC295_FIXUP_FRAMEWORK_LAPTOP_MIC_NO_PRESENCE),
+       SND_PCI_QUIRK(0xf111, 0x0005, "Framework Laptop", ALC295_FIXUP_FRAMEWORK_LAPTOP_MIC_NO_PRESENCE),
+       SND_PCI_QUIRK(0xf111, 0x0006, "Framework Laptop", ALC295_FIXUP_FRAMEWORK_LAPTOP_MIC_NO_PRESENCE),
 
 #if 0
        /* Below is a quirk table taken from the old code.
@@ -12196,6 +12201,7 @@ static const struct snd_pci_quirk alc662_fixup_tbl[] = {
        SND_PCI_QUIRK(0x17aa, 0x32f7, "Lenovo ThinkCentre M90", ALC897_FIXUP_HEADSET_MIC_PIN),
        SND_PCI_QUIRK(0x17aa, 0x3321, "Lenovo ThinkCentre M70 Gen4", ALC897_FIXUP_HEADSET_MIC_PIN),
        SND_PCI_QUIRK(0x17aa, 0x331b, "Lenovo ThinkCentre M90 Gen4", ALC897_FIXUP_HEADSET_MIC_PIN),
+       SND_PCI_QUIRK(0x17aa, 0x3364, "Lenovo ThinkCentre M90 Gen5", ALC897_FIXUP_HEADSET_MIC_PIN),
        SND_PCI_QUIRK(0x17aa, 0x3742, "Lenovo TianYi510Pro-14IOB", ALC897_FIXUP_HEADSET_MIC_PIN2),
        SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD),
        SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Ideapad Y550", ALC662_FIXUP_IDEAPAD),
index 20cee7104c2b3095c1dfb226eec36a526f1490cd..3bc4b2e41650e693c23d7a1972e134beae23194a 100644 (file)
@@ -103,6 +103,20 @@ static const struct config_entry config_table[] = {
                        {}
                },
        },
+       {
+               .flags = FLAG_AMD_LEGACY,
+               .device = ACP_PCI_DEV_ID,
+               .dmi_table = (const struct dmi_system_id []) {
+                       {
+                               .matches = {
+                                       DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "HUAWEI"),
+                                       DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "HVY-WXX9"),
+                                       DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "M1010"),
+                               },
+                       },
+                       {}
+               },
+       },
        {
                .flags = FLAG_AMD_LEGACY,
                .device = ACP_PCI_DEV_ID,
index 15a864dcd7bd3a526ccd5a568c9dc46ad2e394c8..d83cb6e4c62aecc6e54a700e5d22f136253e42fb 100644 (file)
@@ -283,6 +283,13 @@ static const struct dmi_system_id yc_acp_quirk_table[] = {
                        DMI_MATCH(DMI_PRODUCT_NAME, "M6500RC"),
                }
        },
+       {
+               .driver_data = &acp6x_card,
+               .matches = {
+                       DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK COMPUTER INC."),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "E1504FA"),
+               }
+       },
        {
                .driver_data = &acp6x_card,
                .matches = {
@@ -367,6 +374,13 @@ static const struct dmi_system_id yc_acp_quirk_table[] = {
                        DMI_MATCH(DMI_BOARD_NAME, "8A3E"),
                }
        },
+       {
+               .driver_data = &acp6x_card,
+               .matches = {
+                       DMI_MATCH(DMI_BOARD_VENDOR, "HP"),
+                       DMI_MATCH(DMI_BOARD_NAME, "8B2F"),
+               }
+       },
        {
                .driver_data = &acp6x_card,
                .matches = {
@@ -381,6 +395,13 @@ static const struct dmi_system_id yc_acp_quirk_table[] = {
                        DMI_MATCH(DMI_PRODUCT_VERSION, "pang12"),
                }
        },
+       {
+               .driver_data = &acp6x_card,
+               .matches = {
+                       DMI_MATCH(DMI_BOARD_VENDOR, "System76"),
+                       DMI_MATCH(DMI_PRODUCT_VERSION, "pang13"),
+               }
+       },
        {}
 };
 
index 0b40fdfb1825bf48bae092f84c6b6c57da1d91e7..d8ec325b9cc906dfedb9366ec5433ba35390f6f0 100644 (file)
@@ -578,7 +578,7 @@ static int cs43130_set_sp_fmt(int dai_id, unsigned int bitwidth_sclk,
                break;
        case SND_SOC_DAIFMT_LEFT_J:
                hi_size = bitwidth_sclk;
-               frm_delay = 2;
+               frm_delay = 0;
                frm_phase = 1;
                break;
        case SND_SOC_DAIFMT_DSP_A:
@@ -1682,7 +1682,7 @@ static ssize_t hpload_dc_r_show(struct device *dev,
        return cs43130_show_dc(dev, buf, HP_RIGHT);
 }
 
-static u16 const cs43130_ac_freq[CS43130_AC_FREQ] = {
+static const u16 cs43130_ac_freq[CS43130_AC_FREQ] = {
        24,
        43,
        93,
@@ -2362,7 +2362,7 @@ static const struct regmap_config cs43130_regmap = {
        .use_single_write       = true,
 };
 
-static u16 const cs43130_dc_threshold[CS43130_DC_THRESHOLD] = {
+static const u16 cs43130_dc_threshold[CS43130_DC_THRESHOLD] = {
        50,
        120,
 };
index 4c44059427793822d6b8e0836a05d7c1273db42d..6bc068cdcbe2a89e1488530bfa4e6e9c49c0651c 100644 (file)
@@ -696,7 +696,7 @@ static struct da7219_aad_pdata *da7219_aad_fw_to_pdata(struct device *dev)
                aad_pdata->mic_det_thr =
                        da7219_aad_fw_mic_det_thr(dev, fw_val32);
        else
-               aad_pdata->mic_det_thr = DA7219_AAD_MIC_DET_THR_500_OHMS;
+               aad_pdata->mic_det_thr = DA7219_AAD_MIC_DET_THR_200_OHMS;
 
        if (fwnode_property_read_u32(aad_np, "dlg,jack-ins-deb", &fw_val32) >= 0)
                aad_pdata->jack_ins_deb =
index 355f30779a3487efc74d247eeaf63664051b39ff..b075689db2dcaa4afea6566e767ffbe8230c6df1 100644 (file)
@@ -132,6 +132,9 @@ static struct snd_soc_dai_driver hdac_hda_dais[] = {
                .sig_bits = 24,
        },
 },
+};
+
+static struct snd_soc_dai_driver hdac_hda_hdmi_dais[] = {
 {
        .id = HDAC_HDMI_0_DAI_ID,
        .name = "intel-hdmi-hifi1",
@@ -607,8 +610,16 @@ static const struct snd_soc_component_driver hdac_hda_codec = {
        .endianness             = 1,
 };
 
+static const struct snd_soc_component_driver hdac_hda_hdmi_codec = {
+       .probe                  = hdac_hda_codec_probe,
+       .remove                 = hdac_hda_codec_remove,
+       .idle_bias_on           = false,
+       .endianness             = 1,
+};
+
 static int hdac_hda_dev_probe(struct hdac_device *hdev)
 {
+       struct hdac_hda_priv *hda_pvt = dev_get_drvdata(&hdev->dev);
        struct hdac_ext_link *hlink;
        int ret;
 
@@ -621,9 +632,15 @@ static int hdac_hda_dev_probe(struct hdac_device *hdev)
        snd_hdac_ext_bus_link_get(hdev->bus, hlink);
 
        /* ASoC specific initialization */
-       ret = devm_snd_soc_register_component(&hdev->dev,
-                                        &hdac_hda_codec, hdac_hda_dais,
-                                        ARRAY_SIZE(hdac_hda_dais));
+       if (hda_pvt->need_display_power)
+               ret = devm_snd_soc_register_component(&hdev->dev,
+                                               &hdac_hda_hdmi_codec, hdac_hda_hdmi_dais,
+                                               ARRAY_SIZE(hdac_hda_hdmi_dais));
+       else
+               ret = devm_snd_soc_register_component(&hdev->dev,
+                                               &hdac_hda_codec, hdac_hda_dais,
+                                               ARRAY_SIZE(hdac_hda_dais));
+
        if (ret < 0) {
                dev_err(&hdev->dev, "failed to register HDA codec %d\n", ret);
                return ret;
index 82f9873ffada0af35a6729ee5ee530055d82417b..124c2e144f337357af954e1ee4bc9d7b1e3c4b37 100644 (file)
@@ -2021,6 +2021,11 @@ static int tx_macro_probe(struct platform_device *pdev)
 
        tx->dev = dev;
 
+       /* Set active_decimator default value */
+       tx->active_decimator[TX_MACRO_AIF1_CAP] = -1;
+       tx->active_decimator[TX_MACRO_AIF2_CAP] = -1;
+       tx->active_decimator[TX_MACRO_AIF3_CAP] = -1;
+
        /* set MCLK and NPL rates */
        clk_set_rate(tx->mclk, MCLK_FREQ);
        clk_set_rate(tx->npl, MCLK_FREQ);
index ff3024899f456dc8f20ee196215d23017abefd16..7199d734c79f2c4919f38b7db1f950858232dbd9 100644 (file)
@@ -184,6 +184,7 @@ static int nau8822_eq_get(struct snd_kcontrol *kcontrol,
        struct soc_bytes_ext *params = (void *)kcontrol->private_value;
        int i, reg;
        u16 reg_val, *val;
+       __be16 tmp;
 
        val = (u16 *)ucontrol->value.bytes.data;
        reg = NAU8822_REG_EQ1;
@@ -192,8 +193,8 @@ static int nau8822_eq_get(struct snd_kcontrol *kcontrol,
                /* conversion of 16-bit integers between native CPU format
                 * and big endian format
                 */
-               reg_val = cpu_to_be16(reg_val);
-               memcpy(val + i, &reg_val, sizeof(reg_val));
+               tmp = cpu_to_be16(reg_val);
+               memcpy(val + i, &tmp, sizeof(tmp));
        }
 
        return 0;
@@ -216,6 +217,7 @@ static int nau8822_eq_put(struct snd_kcontrol *kcontrol,
        void *data;
        u16 *val, value;
        int i, reg, ret;
+       __be16 *tmp;
 
        data = kmemdup(ucontrol->value.bytes.data,
                params->max, GFP_KERNEL | GFP_DMA);
@@ -228,7 +230,8 @@ static int nau8822_eq_put(struct snd_kcontrol *kcontrol,
                /* conversion of 16-bit integers between native CPU format
                 * and big endian format
                 */
-               value = be16_to_cpu(*(val + i));
+               tmp = (__be16 *)(val + i);
+               value = be16_to_cpup(tmp);
                ret = snd_soc_component_write(component, reg + i, value);
                if (ret) {
                        dev_err(component->dev,
index 7938b52d741d8cd6f354ca61a149db09b41cede2..a0d01d71d8b56f83bc93d04b85681bd1887116ac 100644 (file)
@@ -448,6 +448,7 @@ struct rt5645_priv {
        struct regulator_bulk_data supplies[ARRAY_SIZE(rt5645_supply_names)];
        struct rt5645_eq_param_s *eq_param;
        struct timer_list btn_check_timer;
+       struct mutex jd_mutex;
 
        int codec_type;
        int sysclk;
@@ -3193,6 +3194,8 @@ static int rt5645_jack_detect(struct snd_soc_component *component, int jack_inse
                                rt5645_enable_push_button_irq(component, true);
                        }
                } else {
+                       if (rt5645->en_button_func)
+                               rt5645_enable_push_button_irq(component, false);
                        snd_soc_dapm_disable_pin(dapm, "Mic Det Power");
                        snd_soc_dapm_sync(dapm);
                        rt5645->jack_type = SND_JACK_HEADPHONE;
@@ -3295,6 +3298,8 @@ static void rt5645_jack_detect_work(struct work_struct *work)
        if (!rt5645->component)
                return;
 
+       mutex_lock(&rt5645->jd_mutex);
+
        switch (rt5645->pdata.jd_mode) {
        case 0: /* Not using rt5645 JD */
                if (rt5645->gpiod_hp_det) {
@@ -3321,7 +3326,7 @@ static void rt5645_jack_detect_work(struct work_struct *work)
 
        if (!val && (rt5645->jack_type == 0)) { /* jack in */
                report = rt5645_jack_detect(rt5645->component, 1);
-       } else if (!val && rt5645->jack_type != 0) {
+       } else if (!val && rt5645->jack_type == SND_JACK_HEADSET) {
                /* for push button and jack out */
                btn_type = 0;
                if (snd_soc_component_read(rt5645->component, RT5645_INT_IRQ_ST) & 0x4) {
@@ -3377,6 +3382,8 @@ static void rt5645_jack_detect_work(struct work_struct *work)
                rt5645_jack_detect(rt5645->component, 0);
        }
 
+       mutex_unlock(&rt5645->jd_mutex);
+
        snd_soc_jack_report(rt5645->hp_jack, report, SND_JACK_HEADPHONE);
        snd_soc_jack_report(rt5645->mic_jack, report, SND_JACK_MICROPHONE);
        if (rt5645->en_button_func)
@@ -4150,6 +4157,7 @@ static int rt5645_i2c_probe(struct i2c_client *i2c)
        }
        timer_setup(&rt5645->btn_check_timer, rt5645_btn_check_callback, 0);
 
+       mutex_init(&rt5645->jd_mutex);
        INIT_DELAYED_WORK(&rt5645->jack_detect_work, rt5645_jack_detect_work);
        INIT_DELAYED_WORK(&rt5645->rcclock_work, rt5645_rcclock_work);
 
index 044b6f604c090a69401597a5d2427cad86c46466..260bac695b20ab7f93ed1584f1437fd6f219dc92 100644 (file)
@@ -186,7 +186,7 @@ SOC_DAPM_SINGLE("PCM Playback Switch", WM8974_MONOMIX, 0, 1, 0),
 
 /* Boost mixer */
 static const struct snd_kcontrol_new wm8974_boost_mixer[] = {
-SOC_DAPM_SINGLE("Aux Switch", WM8974_INPPGA, 6, 1, 1),
+SOC_DAPM_SINGLE("PGA Switch", WM8974_INPPGA, 6, 1, 1),
 };
 
 /* Input PGA */
@@ -246,8 +246,8 @@ static const struct snd_soc_dapm_route wm8974_dapm_routes[] = {
 
        /* Boost Mixer */
        {"ADC", NULL, "Boost Mixer"},
-       {"Boost Mixer", "Aux Switch", "Aux Input"},
-       {"Boost Mixer", NULL, "Input PGA"},
+       {"Boost Mixer", NULL, "Aux Input"},
+       {"Boost Mixer", "PGA Switch", "Input PGA"},
        {"Boost Mixer", NULL, "MICP"},
 
        /* Input PGA */
index 236b12b69ae5171374eaa7cf6008e375391b5074..c01e31175015cc2f354175dec019fac591a98b4b 100644 (file)
@@ -1451,12 +1451,12 @@ static int wm_adsp_buffer_populate(struct wm_adsp_compr_buf *buf)
                ret = wm_adsp_buffer_read(buf, caps->region_defs[i].base_offset,
                                          &region->base_addr);
                if (ret < 0)
-                       return ret;
+                       goto err;
 
                ret = wm_adsp_buffer_read(buf, caps->region_defs[i].size_offset,
                                          &offset);
                if (ret < 0)
-                       return ret;
+                       goto err;
 
                region->cumulative_size = offset;
 
@@ -1467,6 +1467,10 @@ static int wm_adsp_buffer_populate(struct wm_adsp_compr_buf *buf)
        }
 
        return 0;
+
+err:
+       kfree(buf->regions);
+       return ret;
 }
 
 static void wm_adsp_buffer_clear(struct wm_adsp_compr_buf *buf)
index 725c530a363607aefd02b6a325ad0859ec9995f7..be342ee03fb9cb6c225ea5bb42eae22d36254542 100644 (file)
@@ -360,6 +360,7 @@ config SND_SOC_IMX_HDMI
 config SND_SOC_IMX_RPMSG
        tristate "SoC Audio support for i.MX boards with rpmsg"
        depends on RPMSG
+       depends on OF && I2C
        select SND_SOC_IMX_PCM_RPMSG
        select SND_SOC_IMX_AUDIO_RPMSG
        help
index 79e7c6b98a754fb9e2f56b1dec0a1e27030f227d..32bbe5056a63520ec953d3a7425129f18234c1a5 100644 (file)
@@ -673,6 +673,20 @@ static int fsl_sai_hw_params(struct snd_pcm_substream *substream,
                           FSL_SAI_CR3_TRCE_MASK,
                           FSL_SAI_CR3_TRCE((dl_cfg[dl_cfg_idx].mask[tx] & trce_mask)));
 
+       /*
+        * When the TERE and FSD_MSTR enabled before configuring the word width
+        * There will be no frame sync clock issue, because word width impact
+        * the generation of frame sync clock.
+        *
+        * TERE enabled earlier only for i.MX8MP case for the hardware limitation,
+        * We need to disable FSD_MSTR before configuring word width, then enable
+        * FSD_MSTR bit for this specific case.
+        */
+       if (sai->soc_data->mclk_with_tere && sai->mclk_direction_output &&
+           !sai->is_consumer_mode)
+               regmap_update_bits(sai->regmap, FSL_SAI_xCR4(tx, ofs),
+                                  FSL_SAI_CR4_FSD_MSTR, 0);
+
        regmap_update_bits(sai->regmap, FSL_SAI_xCR4(tx, ofs),
                           FSL_SAI_CR4_SYWD_MASK | FSL_SAI_CR4_FRSZ_MASK |
                           FSL_SAI_CR4_CHMOD_MASK,
@@ -680,6 +694,13 @@ static int fsl_sai_hw_params(struct snd_pcm_substream *substream,
        regmap_update_bits(sai->regmap, FSL_SAI_xCR5(tx, ofs),
                           FSL_SAI_CR5_WNW_MASK | FSL_SAI_CR5_W0W_MASK |
                           FSL_SAI_CR5_FBT_MASK, val_cr5);
+
+       /* Enable FSD_MSTR after configuring word width */
+       if (sai->soc_data->mclk_with_tere && sai->mclk_direction_output &&
+           !sai->is_consumer_mode)
+               regmap_update_bits(sai->regmap, FSL_SAI_xCR4(tx, ofs),
+                                  FSL_SAI_CR4_FSD_MSTR, FSL_SAI_CR4_FSD_MSTR);
+
        regmap_write(sai->regmap, FSL_SAI_xMR(tx),
                     ~0UL - ((1 << min(channels, slots)) - 1));
 
index fa0a15263c66dc117dcdd7886de6e9e19660ff22..f0fb33d719c25135722014f9763c65df3289ed7e 100644 (file)
@@ -358,7 +358,7 @@ static int fsl_xcvr_en_aud_pll(struct fsl_xcvr *xcvr, u32 freq)
        struct device *dev = &xcvr->pdev->dev;
        int ret;
 
-       freq = xcvr->soc_data->spdif_only ? freq / 10 : freq;
+       freq = xcvr->soc_data->spdif_only ? freq / 5 : freq;
        clk_disable_unprepare(xcvr->phy_clk);
        ret = clk_set_rate(xcvr->phy_clk, freq);
        if (ret < 0) {
@@ -409,11 +409,21 @@ static int fsl_xcvr_prepare(struct snd_pcm_substream *substream,
        bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
        u32 m_ctl = 0, v_ctl = 0;
        u32 r = substream->runtime->rate, ch = substream->runtime->channels;
-       u32 fout = 32 * r * ch * 10 * 2;
+       u32 fout = 32 * r * ch * 10;
        int ret = 0;
 
        switch (xcvr->mode) {
        case FSL_XCVR_MODE_SPDIF:
+               if (xcvr->soc_data->spdif_only && tx) {
+                       ret = regmap_update_bits(xcvr->regmap, FSL_XCVR_TX_DPTH_CTRL_SET,
+                                                FSL_XCVR_TX_DPTH_CTRL_BYPASS_FEM,
+                                                FSL_XCVR_TX_DPTH_CTRL_BYPASS_FEM);
+                       if (ret < 0) {
+                               dev_err(dai->dev, "Failed to set bypass fem: %d\n", ret);
+                               return ret;
+                       }
+               }
+               fallthrough;
        case FSL_XCVR_MODE_ARC:
                if (tx) {
                        ret = fsl_xcvr_en_aud_pll(xcvr, fout);
index 6c6ef63cd5d9ef1ae8a7e306e7f0147d42b45c9e..6e172719c9795b1aa0932f7c7bde8285dbd83c55 100644 (file)
@@ -154,6 +154,8 @@ static int skl_hda_fill_card_info(struct snd_soc_acpi_mach_params *mach_params)
                card->dapm_widgets = skl_hda_widgets;
                card->num_dapm_widgets = ARRAY_SIZE(skl_hda_widgets);
                if (!ctx->idisp_codec) {
+                       card->dapm_routes = &skl_hda_map[IDISP_ROUTE_COUNT];
+                       num_route -= IDISP_ROUTE_COUNT;
                        for (i = 0; i < IDISP_DAI_COUNT; i++) {
                                skl_hda_be_dai_links[i].codecs = &snd_soc_dummy_dlc;
                                skl_hda_be_dai_links[i].num_codecs = 1;
index 3312ad8a563b3fb812ba4070fd0914b9a07848fd..4e428472977326eb883223d580f9364225fbbc7c 100644 (file)
@@ -1546,7 +1546,7 @@ static int sof_card_dai_links_create(struct snd_soc_card *card)
 {
        struct device *dev = card->dev;
        struct snd_soc_acpi_mach *mach = dev_get_platdata(card->dev);
-       int sdw_be_num = 0, ssp_num = 0, dmic_num = 0, hdmi_num = 0, bt_num = 0;
+       int sdw_be_num = 0, ssp_num = 0, dmic_num = 0, bt_num = 0;
        struct mc_private *ctx = snd_soc_card_get_drvdata(card);
        struct snd_soc_acpi_mach_params *mach_params = &mach->mach_params;
        const struct snd_soc_acpi_link_adr *adr_link = mach_params->links;
@@ -1564,6 +1564,7 @@ static int sof_card_dai_links_create(struct snd_soc_card *card)
        char *codec_name, *codec_dai_name;
        int i, j, be_id = 0;
        int codec_index;
+       int hdmi_num;
        int ret;
 
        ret = get_dailink_info(dev, adr_link, &sdw_be_num, &codec_conf_num);
@@ -1584,14 +1585,13 @@ static int sof_card_dai_links_create(struct snd_soc_card *card)
                ssp_num = hweight_long(ssp_mask);
        }
 
-       if (mach_params->codec_mask & IDISP_CODEC_MASK) {
+       if (mach_params->codec_mask & IDISP_CODEC_MASK)
                ctx->hdmi.idisp_codec = true;
 
-               if (sof_sdw_quirk & SOF_SDW_TGL_HDMI)
-                       hdmi_num = SOF_TGL_HDMI_COUNT;
-               else
-                       hdmi_num = SOF_PRE_TGL_HDMI_COUNT;
-       }
+       if (sof_sdw_quirk & SOF_SDW_TGL_HDMI)
+               hdmi_num = SOF_TGL_HDMI_COUNT;
+       else
+               hdmi_num = SOF_PRE_TGL_HDMI_COUNT;
 
        /* enable dmic01 & dmic16k */
        if (sof_sdw_quirk & SOF_SDW_PCH_DMIC || mach_params->dmic_num)
@@ -1601,7 +1601,8 @@ static int sof_card_dai_links_create(struct snd_soc_card *card)
                bt_num = 1;
 
        dev_dbg(dev, "sdw %d, ssp %d, dmic %d, hdmi %d, bt: %d\n",
-               sdw_be_num, ssp_num, dmic_num, hdmi_num, bt_num);
+               sdw_be_num, ssp_num, dmic_num,
+               ctx->hdmi.idisp_codec ? hdmi_num : 0, bt_num);
 
        /* allocate BE dailinks */
        num_links = sdw_be_num + ssp_num + dmic_num + hdmi_num + bt_num;
index d0c02e8a67854c3d6c38102c9bde12238a422ba2..174aae6e0398f2c311f2e53121681fe74e1bd6be 100644 (file)
@@ -240,8 +240,10 @@ static int skl_pcm_open(struct snd_pcm_substream *substream,
        snd_pcm_set_sync(substream);
 
        mconfig = skl_tplg_fe_get_cpr_module(dai, substream->stream);
-       if (!mconfig)
+       if (!mconfig) {
+               kfree(dma_params);
                return -EINVAL;
+       }
 
        skl_tplg_d0i3_get(skl, mconfig->d0i3_caps);
 
@@ -1462,6 +1464,7 @@ int skl_platform_register(struct device *dev)
                dais = krealloc(skl->dais, sizeof(skl_fe_dai) +
                                sizeof(skl_platform_dai), GFP_KERNEL);
                if (!dais) {
+                       kfree(skl->dais);
                        ret = -ENOMEM;
                        goto err;
                }
@@ -1474,8 +1477,10 @@ int skl_platform_register(struct device *dev)
 
        ret = devm_snd_soc_register_component(dev, &skl_component,
                                         skl->dais, num_dais);
-       if (ret)
+       if (ret) {
+               kfree(skl->dais);
                dev_err(dev, "soc component registration failed %d\n", ret);
+       }
 err:
        return ret;
 }
index 7a425271b08b1686fc8310879a47e52be456da30..fd9624ad5f72b07e2a58e5ba220de2893aa7d301 100644 (file)
@@ -1003,8 +1003,10 @@ int skl_ipc_get_large_config(struct sst_generic_ipc *ipc,
 
        reply.size = (reply.header >> 32) & IPC_DATA_OFFSET_SZ_MASK;
        buf = krealloc(reply.data, reply.size, GFP_KERNEL);
-       if (!buf)
+       if (!buf) {
+               kfree(reply.data);
                return -ENOMEM;
+       }
        *payload = buf;
        *bytes = reply.size;
 
index d93b18f07be59a9218281c3f370983e6104d7970..39cb0b889aff91326fccf4e0aea681707f89b17a 100644 (file)
@@ -27,6 +27,23 @@ struct sc8280xp_snd_data {
 static int sc8280xp_snd_init(struct snd_soc_pcm_runtime *rtd)
 {
        struct sc8280xp_snd_data *data = snd_soc_card_get_drvdata(rtd->card);
+       struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
+       struct snd_soc_card *card = rtd->card;
+
+       switch (cpu_dai->id) {
+       case WSA_CODEC_DMA_RX_0:
+       case WSA_CODEC_DMA_RX_1:
+               /*
+                * set limit of 0dB on Digital Volume for Speakers,
+                * this can prevent damage of speakers to some extent without
+                * active speaker protection
+                */
+               snd_soc_limit_volume(card, "WSA_RX0 Digital Volume", 84);
+               snd_soc_limit_volume(card, "WSA_RX1 Digital Volume", 84);
+               break;
+       default:
+               break;
+       }
 
        return qcom_snd_wcd_jack_setup(rtd, &data->jack, &data->jack_setup);
 }
index 55b009d3c6815434c82d0250dd6dae5158d33dde..2d25748ca70662bf771c6896297ccb6a0fb0798f 100644 (file)
@@ -661,7 +661,7 @@ int snd_soc_limit_volume(struct snd_soc_card *card,
        kctl = snd_soc_card_get_kcontrol(card, name);
        if (kctl) {
                struct soc_mixer_control *mc = (struct soc_mixer_control *)kctl->private_value;
-               if (max <= mc->max) {
+               if (max <= mc->max - mc->min) {
                        mc->platform_max = max;
                        ret = 0;
                }
index 323e4d7b6adfe12162a8c1ac43bbb4caa2d5cdd2..f6d1b2e11795fb07d21ef33369c5c95a22a7aa49 100644 (file)
@@ -704,11 +704,6 @@ static int soc_pcm_clean(struct snd_soc_pcm_runtime *rtd,
                        if (snd_soc_dai_active(dai) == 0 &&
                            (dai->rate || dai->channels || dai->sample_bits))
                                soc_pcm_set_dai_params(dai, NULL);
-
-                       if (snd_soc_dai_stream_active(dai, substream->stream) ==  0) {
-                               if (dai->driver->ops && !dai->driver->ops->mute_unmute_on_trigger)
-                                       snd_soc_dai_digital_mute(dai, 1, substream->stream);
-                       }
                }
        }
 
@@ -947,8 +942,10 @@ static int soc_pcm_hw_clean(struct snd_soc_pcm_runtime *rtd,
                if (snd_soc_dai_active(dai) == 1)
                        soc_pcm_set_dai_params(dai, NULL);
 
-               if (snd_soc_dai_stream_active(dai, substream->stream) == 1)
-                       snd_soc_dai_digital_mute(dai, 1, substream->stream);
+               if (snd_soc_dai_stream_active(dai, substream->stream) == 1) {
+                       if (dai->driver->ops && !dai->driver->ops->mute_unmute_on_trigger)
+                               snd_soc_dai_digital_mute(dai, 1, substream->stream);
+               }
        }
 
        /* run the stream event */
index ba4ef290b6343fee3b8267180ffdb352fef6b77a..2c7a5e7a364cf53351e901d907252f258fee2c71 100644 (file)
@@ -493,6 +493,7 @@ static int sof_ipc3_widget_setup_comp_mixer(struct snd_sof_widget *swidget)
 static int sof_ipc3_widget_setup_comp_pipeline(struct snd_sof_widget *swidget)
 {
        struct snd_soc_component *scomp = swidget->scomp;
+       struct snd_sof_pipeline *spipe = swidget->spipe;
        struct sof_ipc_pipe_new *pipeline;
        struct snd_sof_widget *comp_swidget;
        int ret;
@@ -545,6 +546,7 @@ static int sof_ipc3_widget_setup_comp_pipeline(struct snd_sof_widget *swidget)
                swidget->dynamic_pipeline_widget);
 
        swidget->core = pipeline->core;
+       spipe->core_mask |= BIT(pipeline->core);
 
        return 0;
 
index 938efaceb81cf107bdb2fceeaed58727ddd19fbc..b4cdcec33e120944522c572acaf722a2e82a0acb 100644 (file)
@@ -89,7 +89,7 @@ sof_ipc4_set_volume_data(struct snd_sof_dev *sdev, struct snd_sof_widget *swidge
        struct sof_ipc4_control_data *cdata = scontrol->ipc_control_data;
        struct sof_ipc4_gain *gain = swidget->private;
        struct sof_ipc4_msg *msg = &cdata->msg;
-       struct sof_ipc4_gain_data data;
+       struct sof_ipc4_gain_params params;
        bool all_channels_equal = true;
        u32 value;
        int ret, i;
@@ -109,20 +109,20 @@ sof_ipc4_set_volume_data(struct snd_sof_dev *sdev, struct snd_sof_widget *swidge
         */
        for (i = 0; i < scontrol->num_channels; i++) {
                if (all_channels_equal) {
-                       data.channels = SOF_IPC4_GAIN_ALL_CHANNELS_MASK;
-                       data.init_val = cdata->chanv[0].value;
+                       params.channels = SOF_IPC4_GAIN_ALL_CHANNELS_MASK;
+                       params.init_val = cdata->chanv[0].value;
                } else {
-                       data.channels = cdata->chanv[i].channel;
-                       data.init_val = cdata->chanv[i].value;
+                       params.channels = cdata->chanv[i].channel;
+                       params.init_val = cdata->chanv[i].value;
                }
 
                /* set curve type and duration from topology */
-               data.curve_duration_l = gain->data.curve_duration_l;
-               data.curve_duration_h = gain->data.curve_duration_h;
-               data.curve_type = gain->data.curve_type;
+               params.curve_duration_l = gain->data.params.curve_duration_l;
+               params.curve_duration_h = gain->data.params.curve_duration_h;
+               params.curve_type = gain->data.params.curve_type;
 
-               msg->data_ptr = &data;
-               msg->data_size = sizeof(data);
+               msg->data_ptr = &params;
+               msg->data_size = sizeof(params);
 
                ret = sof_ipc4_set_get_kcontrol_data(scontrol, true, lock);
                msg->data_ptr = NULL;
index b24a64377f687463c74da373257759f0cbce1665..e012b6e166accd07e5d46cf99b2938b14e58888e 100644 (file)
@@ -130,18 +130,18 @@ static const struct sof_topology_token comp_ext_tokens[] = {
 
 static const struct sof_topology_token gain_tokens[] = {
        {SOF_TKN_GAIN_RAMP_TYPE, SND_SOC_TPLG_TUPLE_TYPE_WORD,
-               get_token_u32, offsetof(struct sof_ipc4_gain_data, curve_type)},
+               get_token_u32, offsetof(struct sof_ipc4_gain_params, curve_type)},
        {SOF_TKN_GAIN_RAMP_DURATION,
                SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
-               offsetof(struct sof_ipc4_gain_data, curve_duration_l)},
+               offsetof(struct sof_ipc4_gain_params, curve_duration_l)},
        {SOF_TKN_GAIN_VAL, SND_SOC_TPLG_TUPLE_TYPE_WORD,
-               get_token_u32, offsetof(struct sof_ipc4_gain_data, init_val)},
+               get_token_u32, offsetof(struct sof_ipc4_gain_params, init_val)},
 };
 
 /* SRC */
 static const struct sof_topology_token src_tokens[] = {
        {SOF_TKN_SRC_RATE_OUT, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32,
-               offsetof(struct sof_ipc4_src, sink_rate)},
+               offsetof(struct sof_ipc4_src_data, sink_rate)},
 };
 
 static const struct sof_token_info ipc4_token_list[SOF_TOKEN_COUNT] = {
@@ -656,6 +656,7 @@ static int sof_ipc4_widget_setup_comp_pipeline(struct snd_sof_widget *swidget)
 {
        struct snd_soc_component *scomp = swidget->scomp;
        struct sof_ipc4_pipeline *pipeline;
+       struct snd_sof_pipeline *spipe = swidget->spipe;
        int ret;
 
        pipeline = kzalloc(sizeof(*pipeline), GFP_KERNEL);
@@ -670,6 +671,7 @@ static int sof_ipc4_widget_setup_comp_pipeline(struct snd_sof_widget *swidget)
        }
 
        swidget->core = pipeline->core_id;
+       spipe->core_mask |= BIT(pipeline->core_id);
 
        if (pipeline->use_chain_dma) {
                dev_dbg(scomp->dev, "Set up chain DMA for %s\n", swidget->widget->name);
@@ -718,15 +720,15 @@ static int sof_ipc4_widget_setup_comp_pga(struct snd_sof_widget *swidget)
 
        swidget->private = gain;
 
-       gain->data.channels = SOF_IPC4_GAIN_ALL_CHANNELS_MASK;
-       gain->data.init_val = SOF_IPC4_VOL_ZERO_DB;
+       gain->data.params.channels = SOF_IPC4_GAIN_ALL_CHANNELS_MASK;
+       gain->data.params.init_val = SOF_IPC4_VOL_ZERO_DB;
 
-       ret = sof_ipc4_get_audio_fmt(scomp, swidget, &gain->available_fmt, &gain->base_config);
+       ret = sof_ipc4_get_audio_fmt(scomp, swidget, &gain->available_fmt, &gain->data.base_config);
        if (ret)
                goto err;
 
-       ret = sof_update_ipc_object(scomp, &gain->data, SOF_GAIN_TOKENS, swidget->tuples,
-                                   swidget->num_tuples, sizeof(gain->data), 1);
+       ret = sof_update_ipc_object(scomp, &gain->data.params, SOF_GAIN_TOKENS,
+                                   swidget->tuples, swidget->num_tuples, sizeof(gain->data), 1);
        if (ret) {
                dev_err(scomp->dev, "Parsing gain tokens failed\n");
                goto err;
@@ -734,8 +736,8 @@ static int sof_ipc4_widget_setup_comp_pga(struct snd_sof_widget *swidget)
 
        dev_dbg(scomp->dev,
                "pga widget %s: ramp type: %d, ramp duration %d, initial gain value: %#x\n",
-               swidget->widget->name, gain->data.curve_type, gain->data.curve_duration_l,
-               gain->data.init_val);
+               swidget->widget->name, gain->data.params.curve_type,
+               gain->data.params.curve_duration_l, gain->data.params.init_val);
 
        ret = sof_ipc4_widget_setup_msg(swidget, &gain->msg);
        if (ret)
@@ -797,6 +799,7 @@ err:
 static int sof_ipc4_widget_setup_comp_src(struct snd_sof_widget *swidget)
 {
        struct snd_soc_component *scomp = swidget->scomp;
+       struct snd_sof_pipeline *spipe = swidget->spipe;
        struct sof_ipc4_src *src;
        int ret;
 
@@ -808,18 +811,21 @@ static int sof_ipc4_widget_setup_comp_src(struct snd_sof_widget *swidget)
 
        swidget->private = src;
 
-       ret = sof_ipc4_get_audio_fmt(scomp, swidget, &src->available_fmt, &src->base_config);
+       ret = sof_ipc4_get_audio_fmt(scomp, swidget, &src->available_fmt,
+                                    &src->data.base_config);
        if (ret)
                goto err;
 
-       ret = sof_update_ipc_object(scomp, src, SOF_SRC_TOKENS, swidget->tuples,
+       ret = sof_update_ipc_object(scomp, &src->data, SOF_SRC_TOKENS, swidget->tuples,
                                    swidget->num_tuples, sizeof(*src), 1);
        if (ret) {
                dev_err(scomp->dev, "Parsing SRC tokens failed\n");
                goto err;
        }
 
-       dev_dbg(scomp->dev, "SRC sink rate %d\n", src->sink_rate);
+       spipe->core_mask |= BIT(swidget->core);
+
+       dev_dbg(scomp->dev, "SRC sink rate %d\n", src->data.sink_rate);
 
        ret = sof_ipc4_widget_setup_msg(swidget, &src->msg);
        if (ret)
@@ -864,6 +870,7 @@ static int sof_ipc4_widget_setup_comp_process(struct snd_sof_widget *swidget)
 {
        struct snd_soc_component *scomp = swidget->scomp;
        struct sof_ipc4_fw_module *fw_module;
+       struct snd_sof_pipeline *spipe = swidget->spipe;
        struct sof_ipc4_process *process;
        void *cfg;
        int ret;
@@ -920,6 +927,9 @@ static int sof_ipc4_widget_setup_comp_process(struct snd_sof_widget *swidget)
 
        sof_ipc4_widget_update_kcontrol_module_id(swidget);
 
+       /* set pipeline core mask to keep track of the core the module is scheduled to run on */
+       spipe->core_mask |= BIT(swidget->core);
+
        return 0;
 free_base_cfg_ext:
        kfree(process->base_config_ext);
@@ -1816,7 +1826,7 @@ static int sof_ipc4_prepare_gain_module(struct snd_sof_widget *swidget,
        u32 out_ref_rate, out_ref_channels, out_ref_valid_bits;
        int ret;
 
-       ret = sof_ipc4_init_input_audio_fmt(sdev, swidget, &gain->base_config,
+       ret = sof_ipc4_init_input_audio_fmt(sdev, swidget, &gain->data.base_config,
                                            pipeline_params, available_fmt);
        if (ret < 0)
                return ret;
@@ -1826,7 +1836,7 @@ static int sof_ipc4_prepare_gain_module(struct snd_sof_widget *swidget,
        out_ref_channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(in_fmt->fmt_cfg);
        out_ref_valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(in_fmt->fmt_cfg);
 
-       ret = sof_ipc4_init_output_audio_fmt(sdev, &gain->base_config, available_fmt,
+       ret = sof_ipc4_init_output_audio_fmt(sdev, &gain->data.base_config, available_fmt,
                                             out_ref_rate, out_ref_channels, out_ref_valid_bits);
        if (ret < 0) {
                dev_err(sdev->dev, "Failed to initialize output format for %s",
@@ -1835,7 +1845,7 @@ static int sof_ipc4_prepare_gain_module(struct snd_sof_widget *swidget,
        }
 
        /* update pipeline memory usage */
-       sof_ipc4_update_resource_usage(sdev, swidget, &gain->base_config);
+       sof_ipc4_update_resource_usage(sdev, swidget, &gain->data.base_config);
 
        return 0;
 }
@@ -1891,7 +1901,7 @@ static int sof_ipc4_prepare_src_module(struct snd_sof_widget *swidget,
        u32 out_ref_rate, out_ref_channels, out_ref_valid_bits;
        int output_format_index, input_format_index;
 
-       input_format_index = sof_ipc4_init_input_audio_fmt(sdev, swidget, &src->base_config,
+       input_format_index = sof_ipc4_init_input_audio_fmt(sdev, swidget, &src->data.base_config,
                                                           pipeline_params, available_fmt);
        if (input_format_index < 0)
                return input_format_index;
@@ -1921,7 +1931,7 @@ static int sof_ipc4_prepare_src_module(struct snd_sof_widget *swidget,
         */
        out_ref_rate = params_rate(fe_params);
 
-       output_format_index = sof_ipc4_init_output_audio_fmt(sdev, &src->base_config,
+       output_format_index = sof_ipc4_init_output_audio_fmt(sdev, &src->data.base_config,
                                                             available_fmt, out_ref_rate,
                                                             out_ref_channels, out_ref_valid_bits);
        if (output_format_index < 0) {
@@ -1931,10 +1941,10 @@ static int sof_ipc4_prepare_src_module(struct snd_sof_widget *swidget,
        }
 
        /* update pipeline memory usage */
-       sof_ipc4_update_resource_usage(sdev, swidget, &src->base_config);
+       sof_ipc4_update_resource_usage(sdev, swidget, &src->data.base_config);
 
        out_audio_fmt = &available_fmt->output_pin_fmts[output_format_index].audio_fmt;
-       src->sink_rate = out_audio_fmt->sampling_frequency;
+       src->data.sink_rate = out_audio_fmt->sampling_frequency;
 
        /* update pipeline_params for sink widgets */
        return sof_ipc4_update_hw_params(sdev, pipeline_params, out_audio_fmt);
@@ -2314,9 +2324,8 @@ static int sof_ipc4_widget_setup(struct snd_sof_dev *sdev, struct snd_sof_widget
        {
                struct sof_ipc4_gain *gain = swidget->private;
 
-               ipc_size = sizeof(struct sof_ipc4_base_module_cfg) +
-                          sizeof(struct sof_ipc4_gain_data);
-               ipc_data = gain;
+               ipc_size = sizeof(gain->data);
+               ipc_data = &gain->data;
 
                msg = &gain->msg;
                break;
@@ -2335,8 +2344,8 @@ static int sof_ipc4_widget_setup(struct snd_sof_dev *sdev, struct snd_sof_widget
        {
                struct sof_ipc4_src *src = swidget->private;
 
-               ipc_size = sizeof(struct sof_ipc4_base_module_cfg) + sizeof(src->sink_rate);
-               ipc_data = src;
+               ipc_size = sizeof(src->data);
+               ipc_data = &src->data;
 
                msg = &src->msg;
                break;
index 0a57b8ab3e08f09db7020e83946aac45f9969e89..dce174a190ddc630068ee5c6393a83dfb2dd2d05 100644 (file)
@@ -361,7 +361,7 @@ struct sof_ipc4_control_msg_payload {
 } __packed;
 
 /**
- * struct sof_ipc4_gain_data - IPC gain blob
+ * struct sof_ipc4_gain_params - IPC gain parameters
  * @channels: Channels
  * @init_val: Initial value
  * @curve_type: Curve type
@@ -369,24 +369,32 @@ struct sof_ipc4_control_msg_payload {
  * @curve_duration_l: Curve duration low part
  * @curve_duration_h: Curve duration high part
  */
-struct sof_ipc4_gain_data {
+struct sof_ipc4_gain_params {
        uint32_t channels;
        uint32_t init_val;
        uint32_t curve_type;
        uint32_t reserved;
        uint32_t curve_duration_l;
        uint32_t curve_duration_h;
-} __aligned(8);
+} __packed __aligned(4);
 
 /**
- * struct sof_ipc4_gain - gain config data
+ * struct sof_ipc4_gain_data - IPC gain init blob
  * @base_config: IPC base config data
+ * @params: Initial parameters for the gain module
+ */
+struct sof_ipc4_gain_data {
+       struct sof_ipc4_base_module_cfg base_config;
+       struct sof_ipc4_gain_params params;
+} __packed __aligned(4);
+
+/**
+ * struct sof_ipc4_gain - gain config data
  * @data: IPC gain blob
  * @available_fmt: Available audio format
  * @msg: message structure for gain
  */
 struct sof_ipc4_gain {
-       struct sof_ipc4_base_module_cfg base_config;
        struct sof_ipc4_gain_data data;
        struct sof_ipc4_available_audio_format available_fmt;
        struct sof_ipc4_msg msg;
@@ -404,16 +412,24 @@ struct sof_ipc4_mixer {
        struct sof_ipc4_msg msg;
 };
 
-/**
- * struct sof_ipc4_src SRC config data
+/*
+ * struct sof_ipc4_src_data - IPC data for SRC
  * @base_config: IPC base config data
  * @sink_rate: Output rate for sink module
+ */
+struct sof_ipc4_src_data {
+       struct sof_ipc4_base_module_cfg base_config;
+       uint32_t sink_rate;
+} __packed __aligned(4);
+
+/**
+ * struct sof_ipc4_src - SRC config data
+ * @data: IPC base config data
  * @available_fmt: Available audio format
  * @msg: IPC4 message struct containing header and data info
  */
 struct sof_ipc4_src {
-       struct sof_ipc4_base_module_cfg base_config;
-       uint32_t sink_rate;
+       struct sof_ipc4_src_data data;
        struct sof_ipc4_available_audio_format available_fmt;
        struct sof_ipc4_msg msg;
 };
index b69fa788b16f71f951c158e894cd1dceb97f8335..e0d88e7aa8ca0291f2763619f567a667bbda39e6 100644 (file)
@@ -597,6 +597,9 @@ static struct snd_sof_dsp_ops sof_mt8186_ops = {
 
 static struct snd_sof_of_mach sof_mt8186_machs[] = {
        {
+               .compatible = "google,steelix",
+               .sof_tplg_filename = "sof-mt8186-google-steelix.tplg"
+       }, {
                .compatible = "mediatek,mt8186",
                .sof_tplg_filename = "sof-mt8186.tplg",
        },
index 563fe6f7789f735eb68aa1ead4aac6ec9df63297..77cc64ac71131b6ed2eba300714aab90b887984c 100644 (file)
@@ -46,6 +46,7 @@ static int sof_widget_free_unlocked(struct snd_sof_dev *sdev,
                                    struct snd_sof_widget *swidget)
 {
        const struct sof_ipc_tplg_ops *tplg_ops = sof_ipc_get_ops(sdev, tplg);
+       struct snd_sof_pipeline *spipe = swidget->spipe;
        struct snd_sof_widget *pipe_widget;
        int err = 0;
        int ret;
@@ -87,15 +88,22 @@ static int sof_widget_free_unlocked(struct snd_sof_dev *sdev,
        }
 
        /*
-        * disable widget core. continue to route setup status and complete flag
-        * even if this fails and return the appropriate error
+        * decrement ref count for cores associated with all modules in the pipeline and clear
+        * the complete flag
         */
-       ret = snd_sof_dsp_core_put(sdev, swidget->core);
-       if (ret < 0) {
-               dev_err(sdev->dev, "error: failed to disable target core: %d for widget %s\n",
-                       swidget->core, swidget->widget->name);
-               if (!err)
-                       err = ret;
+       if (swidget->id == snd_soc_dapm_scheduler) {
+               int i;
+
+               for_each_set_bit(i, &spipe->core_mask, sdev->num_cores) {
+                       ret = snd_sof_dsp_core_put(sdev, i);
+                       if (ret < 0) {
+                               dev_err(sdev->dev, "failed to disable target core: %d for pipeline %s\n",
+                                       i, swidget->widget->name);
+                               if (!err)
+                                       err = ret;
+                       }
+               }
+               swidget->spipe->complete = 0;
        }
 
        /*
@@ -108,10 +116,6 @@ static int sof_widget_free_unlocked(struct snd_sof_dev *sdev,
                        err = ret;
        }
 
-       /* clear pipeline complete */
-       if (swidget->id == snd_soc_dapm_scheduler)
-               swidget->spipe->complete = 0;
-
        if (!err)
                dev_dbg(sdev->dev, "widget %s freed\n", swidget->widget->name);
 
@@ -134,8 +138,10 @@ static int sof_widget_setup_unlocked(struct snd_sof_dev *sdev,
                                     struct snd_sof_widget *swidget)
 {
        const struct sof_ipc_tplg_ops *tplg_ops = sof_ipc_get_ops(sdev, tplg);
+       struct snd_sof_pipeline *spipe = swidget->spipe;
        bool use_count_decremented = false;
        int ret;
+       int i;
 
        /* skip if there is no private data */
        if (!swidget->private)
@@ -166,19 +172,23 @@ static int sof_widget_setup_unlocked(struct snd_sof_dev *sdev,
                        goto use_count_dec;
        }
 
-       /* enable widget core */
-       ret = snd_sof_dsp_core_get(sdev, swidget->core);
-       if (ret < 0) {
-               dev_err(sdev->dev, "error: failed to enable target core for widget %s\n",
-                       swidget->widget->name);
-               goto pipe_widget_free;
+       /* update ref count for cores associated with all modules in the pipeline */
+       if (swidget->id == snd_soc_dapm_scheduler) {
+               for_each_set_bit(i, &spipe->core_mask, sdev->num_cores) {
+                       ret = snd_sof_dsp_core_get(sdev, i);
+                       if (ret < 0) {
+                               dev_err(sdev->dev, "failed to enable target core %d for pipeline %s\n",
+                                       i, swidget->widget->name);
+                               goto pipe_widget_free;
+                       }
+               }
        }
 
        /* setup widget in the DSP */
        if (tplg_ops && tplg_ops->widget_setup) {
                ret = tplg_ops->widget_setup(sdev, swidget);
                if (ret < 0)
-                       goto core_put;
+                       goto pipe_widget_free;
        }
 
        /* send config for DAI components */
@@ -208,15 +218,22 @@ static int sof_widget_setup_unlocked(struct snd_sof_dev *sdev,
        return 0;
 
 widget_free:
-       /* widget use_count and core ref_count will both be decremented by sof_widget_free() */
+       /* widget use_count will be decremented by sof_widget_free() */
        sof_widget_free_unlocked(sdev, swidget);
        use_count_decremented = true;
-core_put:
-       if (!use_count_decremented)
-               snd_sof_dsp_core_put(sdev, swidget->core);
 pipe_widget_free:
-       if (swidget->id != snd_soc_dapm_scheduler)
+       if (swidget->id != snd_soc_dapm_scheduler) {
                sof_widget_free_unlocked(sdev, swidget->spipe->pipe_widget);
+       } else {
+               int j;
+
+               /* decrement ref count for all cores that were updated previously */
+               for_each_set_bit(j, &spipe->core_mask, sdev->num_cores) {
+                       if (j >= i)
+                               break;
+                       snd_sof_dsp_core_put(sdev, j);
+               }
+       }
 use_count_dec:
        if (!use_count_decremented)
                swidget->use_count--;
index 5d5eeb1a1a6f0d26838004838bcbe8c856fe4579..a6d6bcd00ceeceaca5cc7c6b07bb4045403aca27 100644 (file)
@@ -480,6 +480,7 @@ struct snd_sof_widget {
  * @paused_count: Count of number of PCM's that have started and have currently paused this
                  pipeline
  * @complete: flag used to indicate that pipeline set up is complete.
+ * @core_mask: Mask containing target cores for all modules in the pipeline
  * @list: List item in sdev pipeline_list
  */
 struct snd_sof_pipeline {
@@ -487,6 +488,7 @@ struct snd_sof_pipeline {
        int started_count;
        int paused_count;
        int complete;
+       unsigned long core_mask;
        struct list_head list;
 };
 
index a3a3af252259d9f447da23381bc9cb37d2e22311..37ec671a2d766fb34cc78e08d7a5aeb8f619381b 100644 (file)
@@ -1736,8 +1736,10 @@ static int sof_dai_load(struct snd_soc_component *scomp, int index,
        /* perform pcm set op */
        if (ipc_pcm_ops && ipc_pcm_ops->pcm_setup) {
                ret = ipc_pcm_ops->pcm_setup(sdev, spcm);
-               if (ret < 0)
+               if (ret < 0) {
+                       kfree(spcm);
                        return ret;
+               }
        }
 
        dai_drv->dobj.private = spcm;
index 898bc3baca7b994ef202e80ecbff93288ddc7bba..c8d48566e17598df4e7c390240512ac25c84128d 100644 (file)
@@ -2978,6 +2978,7 @@ static int snd_bbfpro_controls_create(struct usb_mixer_interface *mixer)
 #define SND_DJM_850_IDX                0x2
 #define SND_DJM_900NXS2_IDX    0x3
 #define SND_DJM_750MK2_IDX     0x4
+#define SND_DJM_450_IDX                0x5
 
 
 #define SND_DJM_CTL(_name, suffix, _default_value, _windex) { \
@@ -3108,6 +3109,31 @@ static const struct snd_djm_ctl snd_djm_ctls_250mk2[] = {
 };
 
 
+// DJM-450
+static const u16 snd_djm_opts_450_cap1[] = {
+       0x0103, 0x0100, 0x0106, 0x0107, 0x0108, 0x0109, 0x010d, 0x010a };
+
+static const u16 snd_djm_opts_450_cap2[] = {
+       0x0203, 0x0200, 0x0206, 0x0207, 0x0208, 0x0209, 0x020d, 0x020a };
+
+static const u16 snd_djm_opts_450_cap3[] = {
+       0x030a, 0x0311, 0x0312, 0x0307, 0x0308, 0x0309, 0x030d };
+
+static const u16 snd_djm_opts_450_pb1[] = { 0x0100, 0x0101, 0x0104 };
+static const u16 snd_djm_opts_450_pb2[] = { 0x0200, 0x0201, 0x0204 };
+static const u16 snd_djm_opts_450_pb3[] = { 0x0300, 0x0301, 0x0304 };
+
+static const struct snd_djm_ctl snd_djm_ctls_450[] = {
+       SND_DJM_CTL("Capture Level", cap_level, 0, SND_DJM_WINDEX_CAPLVL),
+       SND_DJM_CTL("Ch1 Input",   450_cap1, 2, SND_DJM_WINDEX_CAP),
+       SND_DJM_CTL("Ch2 Input",   450_cap2, 2, SND_DJM_WINDEX_CAP),
+       SND_DJM_CTL("Ch3 Input",   450_cap3, 0, SND_DJM_WINDEX_CAP),
+       SND_DJM_CTL("Ch1 Output",   450_pb1, 0, SND_DJM_WINDEX_PB),
+       SND_DJM_CTL("Ch2 Output",   450_pb2, 1, SND_DJM_WINDEX_PB),
+       SND_DJM_CTL("Ch3 Output",   450_pb3, 2, SND_DJM_WINDEX_PB)
+};
+
+
 // DJM-750
 static const u16 snd_djm_opts_750_cap1[] = {
        0x0101, 0x0103, 0x0106, 0x0107, 0x0108, 0x0109, 0x010a, 0x010f };
@@ -3203,6 +3229,7 @@ static const struct snd_djm_device snd_djm_devices[] = {
        [SND_DJM_850_IDX] = SND_DJM_DEVICE(850),
        [SND_DJM_900NXS2_IDX] = SND_DJM_DEVICE(900nxs2),
        [SND_DJM_750MK2_IDX] = SND_DJM_DEVICE(750mk2),
+       [SND_DJM_450_IDX] = SND_DJM_DEVICE(450),
 };
 
 
@@ -3454,6 +3481,9 @@ int snd_usb_mixer_apply_create_quirk(struct usb_mixer_interface *mixer)
        case USB_ID(0x2b73, 0x0017): /* Pioneer DJ DJM-250MK2 */
                err = snd_djm_controls_create(mixer, SND_DJM_250MK2_IDX);
                break;
+       case USB_ID(0x2b73, 0x0013): /* Pioneer DJ DJM-450 */
+               err = snd_djm_controls_create(mixer, SND_DJM_450_IDX);
+               break;
        case USB_ID(0x08e4, 0x017f): /* Pioneer DJ DJM-750 */
                err = snd_djm_controls_create(mixer, SND_DJM_750_IDX);
                break;
index fc6b2954e8f50adf1d3ba28da95be0cb5ea9de51..59993fc9c0d7e2b33d9ac6e4fa1caf434398cc04 100644 (file)
@@ -1,6 +1,9 @@
 // SPDX-License-Identifier: GPL-2.0
+#include <unistd.h>
 #include <test_progs.h>
 #include <network_helpers.h>
+#include "tailcall_poke.skel.h"
+
 
 /* test_tailcall_1 checks basic functionality by patching multiple locations
  * in a single program for a single tail call slot with nop->jmp, jmp->nop
@@ -1105,6 +1108,85 @@ out:
        bpf_object__close(tgt_obj);
 }
 
+#define JMP_TABLE "/sys/fs/bpf/jmp_table"
+
+static int poke_thread_exit;
+
+static void *poke_update(void *arg)
+{
+       __u32 zero = 0, prog1_fd, prog2_fd, map_fd;
+       struct tailcall_poke *call = arg;
+
+       map_fd = bpf_map__fd(call->maps.jmp_table);
+       prog1_fd = bpf_program__fd(call->progs.call1);
+       prog2_fd = bpf_program__fd(call->progs.call2);
+
+       while (!poke_thread_exit) {
+               bpf_map_update_elem(map_fd, &zero, &prog1_fd, BPF_ANY);
+               bpf_map_update_elem(map_fd, &zero, &prog2_fd, BPF_ANY);
+       }
+
+       return NULL;
+}
+
+/*
+ * We are trying to hit prog array update during another program load
+ * that shares the same prog array map.
+ *
+ * For that we share the jmp_table map between two skeleton instances
+ * by pinning the jmp_table to same path. Then first skeleton instance
+ * periodically updates jmp_table in 'poke update' thread while we load
+ * the second skeleton instance in the main thread.
+ */
+static void test_tailcall_poke(void)
+{
+       struct tailcall_poke *call, *test;
+       int err, cnt = 10;
+       pthread_t thread;
+
+       unlink(JMP_TABLE);
+
+       call = tailcall_poke__open_and_load();
+       if (!ASSERT_OK_PTR(call, "tailcall_poke__open"))
+               return;
+
+       err = bpf_map__pin(call->maps.jmp_table, JMP_TABLE);
+       if (!ASSERT_OK(err, "bpf_map__pin"))
+               goto out;
+
+       err = pthread_create(&thread, NULL, poke_update, call);
+       if (!ASSERT_OK(err, "new toggler"))
+               goto out;
+
+       while (cnt--) {
+               test = tailcall_poke__open();
+               if (!ASSERT_OK_PTR(test, "tailcall_poke__open"))
+                       break;
+
+               err = bpf_map__set_pin_path(test->maps.jmp_table, JMP_TABLE);
+               if (!ASSERT_OK(err, "bpf_map__pin")) {
+                       tailcall_poke__destroy(test);
+                       break;
+               }
+
+               bpf_program__set_autoload(test->progs.test, true);
+               bpf_program__set_autoload(test->progs.call1, false);
+               bpf_program__set_autoload(test->progs.call2, false);
+
+               err = tailcall_poke__load(test);
+               tailcall_poke__destroy(test);
+               if (!ASSERT_OK(err, "tailcall_poke__load"))
+                       break;
+       }
+
+       poke_thread_exit = 1;
+       ASSERT_OK(pthread_join(thread, NULL), "pthread_join");
+
+out:
+       bpf_map__unpin(call->maps.jmp_table, JMP_TABLE);
+       tailcall_poke__destroy(call);
+}
+
 void test_tailcalls(void)
 {
        if (test__start_subtest("tailcall_1"))
@@ -1139,4 +1221,6 @@ void test_tailcalls(void)
                test_tailcall_bpf2bpf_fentry_fexit();
        if (test__start_subtest("tailcall_bpf2bpf_fentry_entry"))
                test_tailcall_bpf2bpf_fentry_entry();
+       if (test__start_subtest("tailcall_poke"))
+               test_tailcall_poke();
 }
diff --git a/tools/testing/selftests/bpf/progs/tailcall_poke.c b/tools/testing/selftests/bpf/progs/tailcall_poke.c
new file mode 100644 (file)
index 0000000..c78b94b
--- /dev/null
@@ -0,0 +1,32 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <linux/bpf.h>
+#include <bpf/bpf_helpers.h>
+#include <bpf/bpf_tracing.h>
+
+char _license[] SEC("license") = "GPL";
+
+struct {
+       __uint(type, BPF_MAP_TYPE_PROG_ARRAY);
+       __uint(max_entries, 1);
+       __uint(key_size, sizeof(__u32));
+       __uint(value_size, sizeof(__u32));
+} jmp_table SEC(".maps");
+
+SEC("?fentry/bpf_fentry_test1")
+int BPF_PROG(test, int a)
+{
+       bpf_tail_call_static(ctx, &jmp_table, 0);
+       return 0;
+}
+
+SEC("fentry/bpf_fentry_test1")
+int BPF_PROG(call1, int a)
+{
+       return 0;
+}
+
+SEC("fentry/bpf_fentry_test1")
+int BPF_PROG(call2, int a)
+{
+       return 0;
+}
index 050e9751321cff1015474c3023df28c2194d5a52..ad9202335656cc82e8475cf74aba72b6adf7e2b0 100644 (file)
@@ -293,15 +293,13 @@ static int _test_mock_dirty_bitmaps(int fd, __u32 hwpt_id, size_t length,
                                    __u64 bitmap_size, __u32 flags,
                                    struct __test_metadata *_metadata)
 {
-       unsigned long i, count, nbits = bitmap_size * BITS_PER_BYTE;
+       unsigned long i, nbits = bitmap_size * BITS_PER_BYTE;
        unsigned long nr = nbits / 2;
        __u64 out_dirty = 0;
 
        /* Mark all even bits as dirty in the mock domain */
-       for (count = 0, i = 0; i < nbits; count += !(i % 2), i++)
-               if (!(i % 2))
-                       set_bit(i, (unsigned long *)bitmap);
-       ASSERT_EQ(nr, count);
+       for (i = 0; i < nbits; i += 2)
+               set_bit(i, (unsigned long *)bitmap);
 
        test_cmd_mock_domain_set_dirty(fd, hwpt_id, length, iova, page_size,
                                       bitmap, &out_dirty);
@@ -311,9 +309,10 @@ static int _test_mock_dirty_bitmaps(int fd, __u32 hwpt_id, size_t length,
        memset(bitmap, 0, bitmap_size);
        test_cmd_get_dirty_bitmap(fd, hwpt_id, length, iova, page_size, bitmap,
                                  flags);
-       for (count = 0, i = 0; i < nbits; count += !(i % 2), i++)
+       /* Beware ASSERT_EQ() is two statements -- braces are not redundant! */
+       for (i = 0; i < nbits; i++) {
                ASSERT_EQ(!(i % 2), test_bit(i, (unsigned long *)bitmap));
-       ASSERT_EQ(count, out_dirty);
+       }
 
        memset(bitmap, 0, bitmap_size);
        test_cmd_get_dirty_bitmap(fd, hwpt_id, length, iova, page_size, bitmap,
index 78dfec8bc676fa0b72be20f0e3c5c8739b07ea23..dede0bcf97a383f4882761427c0c2e7b7b495ca2 100644 (file)
@@ -60,7 +60,7 @@ TEST_GEN_FILES += mrelease_test
 TEST_GEN_FILES += mremap_dontunmap
 TEST_GEN_FILES += mremap_test
 TEST_GEN_FILES += on-fault-limit
-TEST_GEN_PROGS += pagemap_ioctl
+TEST_GEN_FILES += pagemap_ioctl
 TEST_GEN_FILES += thuge-gen
 TEST_GEN_FILES += transhuge-stress
 TEST_GEN_FILES += uffd-stress
@@ -72,7 +72,7 @@ TEST_GEN_FILES += mdwe_test
 TEST_GEN_FILES += hugetlb_fault_after_madv
 
 ifneq ($(ARCH),arm64)
-TEST_GEN_PROGS += soft-dirty
+TEST_GEN_FILES += soft-dirty
 endif
 
 ifeq ($(ARCH),x86_64)
index befab43719badff842fd771eb52f54fbc98b510c..d59517ed3d48bdb25c94cecbae991fea1acb5108 100644 (file)
@@ -36,6 +36,7 @@ int pagemap_fd;
 int uffd;
 int page_size;
 int hpage_size;
+const char *progname;
 
 #define LEN(region)    ((region.end - region.start)/page_size)
 
@@ -1149,11 +1150,11 @@ int sanity_tests(void)
        munmap(mem, mem_size);
 
        /* 9. Memory mapped file */
-       fd = open(__FILE__, O_RDONLY);
+       fd = open(progname, O_RDONLY);
        if (fd < 0)
                ksft_exit_fail_msg("%s Memory mapped file\n", __func__);
 
-       ret = stat(__FILE__, &sbuf);
+       ret = stat(progname, &sbuf);
        if (ret < 0)
                ksft_exit_fail_msg("error %d %d %s\n", ret, errno, strerror(errno));
 
@@ -1472,12 +1473,14 @@ static void transact_test(int page_size)
                              extra_thread_faults);
 }
 
-int main(void)
+int main(int argc, char *argv[])
 {
        int mem_size, shmid, buf_size, fd, i, ret;
        char *mem, *map, *fmem;
        struct stat sbuf;
 
+       progname = argv[0];
+
        ksft_print_header();
 
        if (init_uffd())