Merge tag 'net-6.4-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 16 Jun 2023 04:11:17 +0000 (21:11 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 16 Jun 2023 04:11:17 +0000 (21:11 -0700)
Pull networking fixes from Jakub Kicinski:
 "Including fixes from wireless, and netfilter.

  Selftests excluded - we have 58 patches and diff of +442/-199, which
  isn't really small but perhaps with the exception of the WiFi locking
  change it's old(ish) bugs.

  We have no known problems with v6.4.

  The selftest changes are rather large as MPTCP folks try to apply
  Greg's guidance that selftest from torvalds/linux should be able to
  run against stable kernels.

  Last thing I should call out is the DCCP/UDP-lite deprecation notices.
  We are fairly sure those are dead, but if we're wrong reverting them
  back in won't be fun.

  Current release - regressions:

   - wifi:
      - cfg80211: fix double lock bug in reg_wdev_chan_valid()
      - iwlwifi: mvm: spin_lock_bh() to fix lockdep regression

  Current release - new code bugs:

   - handshake: remove fput() that causes use-after-free

  Previous releases - regressions:

   - sched: cls_u32: fix reference counter leak leading to overflow

   - sched: cls_api: fix lockup on flushing explicitly created chain

  Previous releases - always broken:

   - nf_tables: integrate pipapo into commit protocol

   - nf_tables: incorrect error path handling with NFT_MSG_NEWRULE, fix
     dangling pointer on failure

   - ping6: fix send to link-local addresses with VRF

   - sched: act_pedit: parse L3 header for L4 offset, the skb may not
     have the offset saved

   - sched: act_ct: fix promotion of offloaded unreplied tuple

   - sched: refuse to destroy an ingress and clsact Qdiscs if there are
     lockless change operations in flight

   - wifi: mac80211: fix handful of bugs in multi-link operation

   - ipvlan: fix bound dev checking for IPv6 l3s mode

   - eth: enetc: correct the indexes of highest and 2nd highest TCs

   - eth: ice: fix XDP memory leak when NIC is brought up and down

  Misc:

   - add deprecation notices for UDP-lite and DCCP

   - selftests: mptcp: skip tests not supported by old kernels

   - sctp: handle invalid error codes without calling BUG()"

* tag 'net-6.4-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net: (91 commits)
  dccp: Print deprecation notice.
  udplite: Print deprecation notice.
  octeon_ep: Add missing check for ioremap
  selftests/ptp: Fix timestamp printf format for PTP_SYS_OFFSET
  net: ethernet: stmicro: stmmac: fix possible memory leak in __stmmac_open
  net: tipc: resize nlattr array to correct size
  sfc: fix XDP queues mode with legacy IRQ
  net: macsec: fix double free of percpu stats
  net: lapbether: only support ethernet devices
  MAINTAINERS: add reviewers for SMC Sockets
  s390/ism: Fix trying to free already-freed IRQ by repeated ism_dev_exit()
  net: dsa: felix: fix taprio guard band overflow at 10Mbps with jumbo frames
  net/sched: cls_api: Fix lockup on flushing explicitly created chain
  ice: Fix ice module unload
  net/handshake: remove fput() that causes use-after-free
  selftests: forwarding: hw_stats_l3: Set addrgenmode in a separate step
  net/sched: qdisc_destroy() old ingress and clsact Qdiscs before grafting
  net/sched: Refactor qdisc_graft() for ingress and clsact Qdiscs
  net/sched: act_ct: Fix promotion of offloaded unreplied tuple
  wifi: iwlwifi: mvm: spin_lock_bh() to fix lockdep regression
  ...

291 files changed:
.mailmap
Documentation/admin-guide/cgroup-v2.rst
Documentation/devicetree/bindings/ata/ahci-common.yaml
Documentation/devicetree/bindings/cache/qcom,llcc.yaml
Documentation/devicetree/bindings/clock/canaan,k210-clk.yaml
Documentation/devicetree/bindings/i3c/silvaco,i3c-master.yaml
Documentation/devicetree/bindings/mfd/canaan,k210-sysctl.yaml
Documentation/devicetree/bindings/net/realtek-bluetooth.yaml
Documentation/devicetree/bindings/pinctrl/canaan,k210-fpioa.yaml
Documentation/devicetree/bindings/pinctrl/qcom,pmic-mpp.yaml
Documentation/devicetree/bindings/power/qcom,rpmpd.yaml
Documentation/devicetree/bindings/reset/canaan,k210-rst.yaml
Documentation/devicetree/bindings/riscv/canaan.yaml
Documentation/devicetree/usage-model.rst
Documentation/translations/zh_CN/devicetree/usage-model.rst
MAINTAINERS
Makefile
arch/arm/boot/dts/am57xx-cl-som-am57x.dts
arch/arm/boot/dts/at91-sama7g5ek.dts
arch/arm/boot/dts/at91sam9261ek.dts
arch/arm/boot/dts/imx7d-pico-hobbit.dts
arch/arm/boot/dts/imx7d-sdb.dts
arch/arm/boot/dts/omap3-cm-t3x.dtsi
arch/arm/boot/dts/omap3-devkit8000-lcd-common.dtsi
arch/arm/boot/dts/omap3-lilly-a83x.dtsi
arch/arm/boot/dts/omap3-overo-common-lcd35.dtsi
arch/arm/boot/dts/omap3-overo-common-lcd43.dtsi
arch/arm/boot/dts/omap3-pandora-common.dtsi
arch/arm/boot/dts/omap5-cm-t54.dts
arch/arm/boot/dts/qcom-apq8026-asus-sparrow.dts
arch/arm/boot/dts/qcom-apq8026-huawei-sturgeon.dts
arch/arm/boot/dts/qcom-apq8026-lg-lenok.dts
arch/arm/boot/dts/qcom-apq8064.dtsi
arch/arm/boot/dts/qcom-apq8084.dtsi
arch/arm/boot/dts/qcom-ipq4019.dtsi
arch/arm/boot/dts/qcom-ipq8064.dtsi
arch/arm/boot/dts/qcom-mdm9615-wp8548-mangoh-green.dts
arch/arm/boot/dts/qcom-msm8660.dtsi
arch/arm/boot/dts/qcom-msm8960.dtsi
arch/arm/boot/dts/qcom-msm8974-lge-nexus5-hammerhead.dts
arch/arm/boot/dts/qcom-msm8974-sony-xperia-rhine.dtsi
arch/arm/boot/dts/qcom-msm8974.dtsi
arch/arm/boot/dts/qcom-msm8974pro-oneplus-bacon.dts
arch/arm/boot/dts/qcom-msm8974pro-samsung-klte.dts
arch/arm/boot/dts/qcom-msm8974pro-sony-xperia-shinano-castor.dts
arch/arm/mach-at91/pm.c
arch/arm64/Kconfig
arch/arm64/boot/dts/freescale/imx8-ss-dma.dtsi
arch/arm64/boot/dts/freescale/imx8mn-beacon-baseboard.dtsi
arch/arm64/boot/dts/freescale/imx8qm-mek.dts
arch/arm64/boot/dts/qcom/ipq5332.dtsi
arch/arm64/boot/dts/qcom/ipq6018.dtsi
arch/arm64/boot/dts/qcom/ipq8074.dtsi
arch/arm64/boot/dts/qcom/ipq9574.dtsi
arch/arm64/boot/dts/qcom/msm8916.dtsi
arch/arm64/boot/dts/qcom/msm8953.dtsi
arch/arm64/boot/dts/qcom/msm8976.dtsi
arch/arm64/boot/dts/qcom/msm8994.dtsi
arch/arm64/boot/dts/qcom/msm8996.dtsi
arch/arm64/boot/dts/qcom/msm8998.dtsi
arch/arm64/boot/dts/qcom/qcm2290.dtsi
arch/arm64/boot/dts/qcom/qcs404.dtsi
arch/arm64/boot/dts/qcom/qdu1000.dtsi
arch/arm64/boot/dts/qcom/sa8155p-adp.dts
arch/arm64/boot/dts/qcom/sa8155p.dtsi [new file with mode: 0644]
arch/arm64/boot/dts/qcom/sa8775p.dtsi
arch/arm64/boot/dts/qcom/sc7180-lite.dtsi
arch/arm64/boot/dts/qcom/sc7180.dtsi
arch/arm64/boot/dts/qcom/sc7280-idp.dtsi
arch/arm64/boot/dts/qcom/sc7280-qcard.dtsi
arch/arm64/boot/dts/qcom/sc7280.dtsi
arch/arm64/boot/dts/qcom/sc8280xp.dtsi
arch/arm64/boot/dts/qcom/sdm630.dtsi
arch/arm64/boot/dts/qcom/sdm670.dtsi
arch/arm64/boot/dts/qcom/sdm845.dtsi
arch/arm64/boot/dts/qcom/sm6115.dtsi
arch/arm64/boot/dts/qcom/sm6125.dtsi
arch/arm64/boot/dts/qcom/sm6350.dtsi
arch/arm64/boot/dts/qcom/sm6375-sony-xperia-murray-pdx225.dts
arch/arm64/boot/dts/qcom/sm6375.dtsi
arch/arm64/boot/dts/qcom/sm8150.dtsi
arch/arm64/boot/dts/qcom/sm8250-xiaomi-elish-boe.dts
arch/arm64/boot/dts/qcom/sm8250-xiaomi-elish-csot.dts
arch/arm64/boot/dts/qcom/sm8350.dtsi
arch/arm64/boot/dts/qcom/sm8450.dtsi
arch/arm64/boot/dts/qcom/sm8550.dtsi
arch/arm64/mm/fault.c
arch/loongarch/include/asm/loongarch.h
arch/loongarch/include/asm/pgtable-bits.h
arch/loongarch/include/asm/pgtable.h
arch/loongarch/kernel/hw_breakpoint.c
arch/loongarch/kernel/perf_event.c
arch/loongarch/kernel/unaligned.c
arch/nios2/boot/dts/10m50_devboard.dts
arch/nios2/boot/dts/3c120_devboard.dts
arch/powerpc/purgatory/Makefile
arch/riscv/Kconfig
arch/riscv/include/asm/kfence.h
arch/riscv/include/asm/pgtable.h
arch/riscv/mm/init.c
arch/riscv/purgatory/Makefile
arch/s390/purgatory/Makefile
arch/x86/kernel/head_64.S
arch/x86/purgatory/Makefile
block/blk-mq.c
drivers/accel/ivpu/Kconfig
drivers/accel/ivpu/ivpu_hw_mtl.c
drivers/accel/ivpu/ivpu_hw_mtl_reg.h
drivers/accel/ivpu/ivpu_ipc.c
drivers/accel/ivpu/ivpu_job.c
drivers/accel/ivpu/ivpu_mmu.c
drivers/base/regmap/regcache.c
drivers/block/null_blk/main.c
drivers/block/rbd.c
drivers/edac/qcom_edac.c
drivers/firmware/arm_ffa/driver.c
drivers/gpio/gpio-sim.c
drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c
drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
drivers/gpu/drm/amd/amdgpu/amdgpu_vm_pt.c
drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c
drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c
drivers/gpu/drm/amd/amdgpu/soc15.c
drivers/gpu/drm/amd/amdgpu/vi.c
drivers/gpu/drm/amd/display/dc/core/dc.c
drivers/gpu/drm/amd/display/dc/core/dc_resource.c
drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c
drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c
drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c
drivers/gpu/drm/ast/ast_dp.c
drivers/gpu/drm/ast/ast_drv.h
drivers/gpu/drm/ast/ast_main.c
drivers/gpu/drm/ast/ast_mode.c
drivers/gpu/drm/ast/ast_post.c
drivers/gpu/drm/drm_fb_helper.c
drivers/gpu/drm/exynos/exynos_drm_g2d.c
drivers/gpu/drm/exynos/exynos_drm_vidi.c
drivers/gpu/drm/i915/display/intel_cdclk.c
drivers/gpu/drm/i915/display/intel_dp_aux.c
drivers/gpu/drm/i915/gem/selftests/i915_gem_context.c
drivers/gpu/drm/i915/gt/selftest_execlists.c
drivers/gpu/drm/lima/lima_sched.c
drivers/gpu/drm/msm/adreno/a6xx_gmu.c
drivers/gpu/drm/msm/adreno/a6xx_gpu.c
drivers/gpu/drm/msm/dp/dp_catalog.c
drivers/gpu/drm/msm/dp/dp_catalog.h
drivers/gpu/drm/msm/dp/dp_display.c
drivers/gpu/drm/msm/msm_drv.c
drivers/gpu/drm/radeon/radeon_gem.c
drivers/i2c/busses/i2c-designware-core.h
drivers/i2c/busses/i2c-designware-slave.c
drivers/i2c/busses/i2c-img-scb.c
drivers/i2c/busses/i2c-mchp-pci1xxxx.c
drivers/i2c/busses/i2c-mv64xxx.c
drivers/i2c/busses/i2c-sprd.c
drivers/infiniband/core/cma.c
drivers/infiniband/core/uverbs_cmd.c
drivers/infiniband/core/uverbs_main.c
drivers/infiniband/hw/bnxt_re/bnxt_re.h
drivers/infiniband/hw/bnxt_re/ib_verbs.c
drivers/infiniband/hw/bnxt_re/main.c
drivers/infiniband/hw/mlx5/counters.c
drivers/infiniband/hw/mlx5/fs.c
drivers/infiniband/hw/mlx5/fs.h
drivers/infiniband/hw/mlx5/main.c
drivers/infiniband/hw/mlx5/mlx5_ib.h
drivers/infiniband/hw/mlx5/qp.c
drivers/infiniband/sw/rxe/rxe_cq.c
drivers/infiniband/sw/rxe/rxe_net.c
drivers/infiniband/sw/rxe/rxe_qp.c
drivers/infiniband/sw/rxe/rxe_resp.c
drivers/infiniband/ulp/isert/ib_isert.c
drivers/infiniband/ulp/rtrs/rtrs-clt.c
drivers/infiniband/ulp/rtrs/rtrs.c
drivers/md/dm-ioctl.c
drivers/md/dm-thin-metadata.c
drivers/md/dm-thin.c
drivers/md/dm.c
drivers/media/dvb-core/dvb_frontend.c
drivers/misc/eeprom/Kconfig
drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h
drivers/of/overlay.c
drivers/pinctrl/meson/pinctrl-meson-axg.c
drivers/regulator/qcom-rpmh-regulator.c
drivers/s390/block/dasd_ioctl.c
drivers/s390/cio/device.c
drivers/soc/qcom/Makefile
drivers/soc/qcom/icc-bwmon.c
drivers/soc/qcom/ramp_controller.c
drivers/soc/qcom/rmtfs_mem.c
drivers/soc/qcom/rpmh-rsc.c
drivers/soc/qcom/rpmhpd.c
drivers/soundwire/dmi-quirks.c
drivers/soundwire/qcom.c
drivers/soundwire/stream.c
drivers/spi/spi-cadence-quadspi.c
drivers/spi/spi-dw-mmio.c
drivers/spi/spi-fsl-dspi.c
drivers/tee/amdtee/amdtee_if.h
drivers/tee/amdtee/call.c
drivers/vdpa/mlx5/net/mlx5_vnet.c
drivers/vdpa/vdpa_user/vduse_dev.c
drivers/vhost/net.c
drivers/vhost/vdpa.c
drivers/vhost/vhost.c
drivers/vhost/vhost.h
fs/btrfs/disk-io.c
fs/btrfs/scrub.c
fs/btrfs/super.c
fs/ceph/caps.c
fs/ceph/snap.c
fs/eventpoll.c
fs/ext4/balloc.c
fs/ext4/super.c
fs/ext4/xattr.c
fs/nilfs2/btnode.c
fs/nilfs2/sufile.c
fs/nilfs2/the_nilfs.c
fs/ocfs2/file.c
fs/ocfs2/super.c
fs/smb/client/cifs_debug.c
fs/smb/client/cifsglob.h
fs/smb/client/cifsproto.h
fs/smb/client/connect.c
fs/smb/client/dfs.c
fs/smb/client/file.c
fs/smb/client/smb2ops.c
fs/smb/client/smb2pdu.c
fs/smb/client/transport.c
fs/smb/server/connection.c
fs/smb/server/oplock.c
fs/smb/server/smb2pdu.c
fs/smb/server/smb_common.c
fs/smb/server/smbacl.c
fs/smb/server/vfs.c
fs/userfaultfd.c
include/dt-bindings/power/qcom-rpmpd.h
include/linux/mlx5/driver.h
include/linux/soc/qcom/llcc-qcom.h
include/media/dvb_frontend.h
include/rdma/ib_addr.h
io_uring/io-wq.c
kernel/cgroup/cgroup-v1.c
kernel/cgroup/cgroup.c
kernel/kexec_file.c
kernel/vhost_task.c
lib/radix-tree.c
lib/radix-tree.h [new file with mode: 0644]
lib/test_vmalloc.c
lib/xarray.c
mm/damon/core.c
mm/filemap.c
mm/gup_test.c
mm/zswap.c
sound/isa/gus/gus_pcm.c
sound/pci/cmipci.c
sound/pci/hda/hda_codec.c
sound/pci/hda/patch_realtek.c
sound/pci/ice1712/aureon.c
sound/pci/ice1712/ice1712.c
sound/pci/ice1712/ice1724.c
sound/pci/ymfpci/ymfpci_main.c
sound/soc/amd/ps/pci-ps.c
sound/soc/amd/ps/ps-pdm-dma.c
sound/soc/amd/yc/acp6x-mach.c
sound/soc/codecs/cs35l56.c
sound/soc/codecs/max98363.c
sound/soc/codecs/nau8824.c
sound/soc/codecs/wcd938x-sdw.c
sound/soc/codecs/wsa881x.c
sound/soc/codecs/wsa883x.c
sound/soc/fsl/fsl_sai.c
sound/soc/fsl/fsl_sai.h
sound/soc/generic/simple-card-utils.c
sound/soc/generic/simple-card.c
sound/soc/mediatek/mt8188/mt8188-afe-clk.c
sound/soc/mediatek/mt8188/mt8188-afe-clk.h
sound/soc/mediatek/mt8188/mt8188-afe-pcm.c
sound/soc/mediatek/mt8188/mt8188-audsys-clk.c
sound/soc/mediatek/mt8188/mt8188-audsys-clk.h
sound/soc/mediatek/mt8195/mt8195-afe-clk.c
sound/soc/mediatek/mt8195/mt8195-afe-clk.h
sound/soc/mediatek/mt8195/mt8195-afe-pcm.c
sound/soc/mediatek/mt8195/mt8195-audsys-clk.c
sound/soc/mediatek/mt8195/mt8195-audsys-clk.h
tools/testing/radix-tree/Makefile
tools/testing/selftests/alsa/pcm-test.c
tools/virtio/ringtest/.gitignore [new file with mode: 0644]
tools/virtio/ringtest/main.h
tools/virtio/virtio-trace/README
tools/virtio/virtio-trace/trace-agent.c

index bf076bb..650689d 100644 (file)
--- a/.mailmap
+++ b/.mailmap
@@ -233,6 +233,7 @@ Jisheng Zhang <jszhang@kernel.org> <Jisheng.Zhang@synaptics.com>
 Johan Hovold <johan@kernel.org> <jhovold@gmail.com>
 Johan Hovold <johan@kernel.org> <johan@hovoldconsulting.com>
 John Crispin <john@phrozen.org> <blogic@openwrt.org>
+John Keeping <john@keeping.me.uk> <john@metanate.com>
 John Paul Adrian Glaubitz <glaubitz@physik.fu-berlin.de>
 John Stultz <johnstul@us.ibm.com>
 <jon.toppins+linux@gmail.com> <jtoppins@cumulusnetworks.com>
index f67c082..e592a93 100644 (file)
@@ -1213,23 +1213,25 @@ PAGE_SIZE multiple when read back.
        A read-write single value file which exists on non-root
        cgroups.  The default is "max".
 
-       Memory usage throttle limit.  This is the main mechanism to
-       control memory usage of a cgroup.  If a cgroup's usage goes
+       Memory usage throttle limit.  If a cgroup's usage goes
        over the high boundary, the processes of the cgroup are
        throttled and put under heavy reclaim pressure.
 
        Going over the high limit never invokes the OOM killer and
-       under extreme conditions the limit may be breached.
+       under extreme conditions the limit may be breached. The high
+       limit should be used in scenarios where an external process
+       monitors the limited cgroup to alleviate heavy reclaim
+       pressure.
 
   memory.max
        A read-write single value file which exists on non-root
        cgroups.  The default is "max".
 
-       Memory usage hard limit.  This is the final protection
-       mechanism.  If a cgroup's memory usage reaches this limit and
-       can't be reduced, the OOM killer is invoked in the cgroup.
-       Under certain circumstances, the usage may go over the limit
-       temporarily.
+       Memory usage hard limit.  This is the main mechanism to limit
+       memory usage of a cgroup.  If a cgroup's memory usage reaches
+       this limit and can't be reduced, the OOM killer is invoked in
+       the cgroup. Under certain circumstances, the usage may go
+       over the limit temporarily.
 
        In default configuration regular 0-order allocations always
        succeed unless OOM killer chooses current task as a victim.
@@ -1238,10 +1240,6 @@ PAGE_SIZE multiple when read back.
        Caller could retry them differently, return into userspace
        as -ENOMEM or silently ignore in cases like disk readahead.
 
-       This is the ultimate protection mechanism.  As long as the
-       high limit is used and monitored properly, this limit's
-       utility is limited to providing the final safety net.
-
   memory.reclaim
        A write-only nested-keyed file which exists for all cgroups.
 
index 7fdf409..38770c4 100644 (file)
@@ -8,7 +8,7 @@ title: Common Properties for Serial ATA AHCI controllers
 
 maintainers:
   - Hans de Goede <hdegoede@redhat.com>
-  - Damien Le Moal <damien.lemoal@opensource.wdc.com>
+  - Damien Le Moal <dlemoal@kernel.org>
 
 description:
   This document defines device tree properties for a common AHCI SATA
index d8b9194..44892aa 100644 (file)
@@ -129,6 +129,7 @@ allOf:
               - qcom,sm8250-llcc
               - qcom,sm8350-llcc
               - qcom,sm8450-llcc
+              - qcom,sm8550-llcc
     then:
       properties:
         reg:
index 998e5cc..380cb6d 100644 (file)
@@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#
 title: Canaan Kendryte K210 Clock
 
 maintainers:
-  - Damien Le Moal <damien.lemoal@wdc.com>
+  - Damien Le Moal <dlemoal@kernel.org>
 
 description: |
   Canaan Kendryte K210 SoC clocks driver bindings. The clock
index 62f3ca6..32c821f 100644 (file)
@@ -44,7 +44,7 @@ required:
   - clock-names
   - clocks
 
-additionalProperties: true
+unevaluatedProperties: false
 
 examples:
   - |
index 8459d36..3b3beab 100644 (file)
@@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#
 title: Canaan Kendryte K210 System Controller
 
 maintainers:
-  - Damien Le Moal <damien.lemoal@wdc.com>
+  - Damien Le Moal <dlemoal@kernel.org>
 
 description:
   Canaan Inc. Kendryte K210 SoC system controller which provides a
index 8cc2b99..043e118 100644 (file)
@@ -11,7 +11,7 @@ maintainers:
   - Alistair Francis <alistair@alistair23.me>
 
 description:
-  RTL8723CS/RTL8723CS/RTL8821CS/RTL8822CS is a WiFi + BT chip. WiFi part
+  RTL8723BS/RTL8723CS/RTL8821CS/RTL8822CS is a WiFi + BT chip. WiFi part
   is connected over SDIO, while BT is connected over serial. It speaks
   H5 protocol with few extra commands to upload firmware and change
   module speed.
@@ -27,7 +27,7 @@ properties:
       - items:
           - enum:
               - realtek,rtl8821cs-bt
-          - const: realtek,rtl8822cs-bt
+          - const: realtek,rtl8723bs-bt
 
   device-wake-gpios:
     maxItems: 1
index 7f4f36a..739a08f 100644 (file)
@@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#
 title: Canaan Kendryte K210 FPIOA
 
 maintainers:
-  - Damien Le Moal <damien.lemoal@wdc.com>
+  - Damien Le Moal <dlemoal@kernel.org>
 
 description:
   The Canaan Kendryte K210 SoC Fully Programmable IO Array (FPIOA)
index c91d3e3..80f9606 100644 (file)
@@ -144,8 +144,9 @@ $defs:
         enum: [0, 1, 2, 3, 4, 5, 6, 7]
 
       qcom,paired:
-        - description:
-            Indicates that the pin should be operating in paired mode.
+        type: boolean
+        description:
+          Indicates that the pin should be operating in paired mode.
 
     required:
       - pins
index afad313..f9c211a 100644 (file)
@@ -29,6 +29,7 @@ properties:
       - qcom,qcm2290-rpmpd
       - qcom,qcs404-rpmpd
       - qcom,qdu1000-rpmhpd
+      - qcom,sa8155p-rpmhpd
       - qcom,sa8540p-rpmhpd
       - qcom,sa8775p-rpmhpd
       - qcom,sdm660-rpmpd
index ee8a2dc..0c01359 100644 (file)
@@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#
 title: Canaan Kendryte K210 Reset Controller
 
 maintainers:
-  - Damien Le Moal <damien.lemoal@wdc.com>
+  - Damien Le Moal <dlemoal@kernel.org>
 
 description: |
   Canaan Kendryte K210 reset controller driver which supports the SoC
index f8f3f28..41fd11f 100644 (file)
@@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#
 title: Canaan SoC-based boards
 
 maintainers:
-  - Damien Le Moal <damien.lemoal@wdc.com>
+  - Damien Le Moal <dlemoal@kernel.org>
 
 description:
   Canaan Kendryte K210 SoC-based boards
index b6a2879..0717426 100644 (file)
@@ -415,6 +415,6 @@ When using the DT, this creates problems for of_platform_populate()
 because it must decide whether to register each node as either a
 platform_device or an amba_device.  This unfortunately complicates the
 device creation model a little bit, but the solution turns out not to
-be too invasive.  If a node is compatible with "arm,amba-primecell", then
+be too invasive.  If a node is compatible with "arm,primecell", then
 of_platform_populate() will register it as an amba_device instead of a
 platform_device.
index c6aee82..19ba4ae 100644 (file)
@@ -325,6 +325,6 @@ Primecell设备。然而,棘手的一点是,AMBA总线上的所有设备并
 
 当使用DT时,这给of_platform_populate()带来了问题,因为它必须决定是否将
 每个节点注册为platform_device或amba_device。不幸的是,这使设备创建模型
-变得有点复杂,但解决方案原来并不是太具有侵略性。如果一个节点与“arm,amba-primecell”
+变得有点复杂,但解决方案原来并不是太具有侵略性。如果一个节点与“arm,primecell”
 兼容,那么of_platform_populate()将把它注册为amba_device而不是
 platform_device。
index c6fa6ed..6992b7c 100644 (file)
@@ -8799,6 +8799,7 @@ F:        include/linux/gpio/regmap.h
 GPIO SUBSYSTEM
 M:     Linus Walleij <linus.walleij@linaro.org>
 M:     Bartosz Golaszewski <brgl@bgdev.pl>
+R:     Andy Shevchenko <andy@kernel.org>
 L:     linux-gpio@vger.kernel.org
 S:     Maintained
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/brgl/linux.git
@@ -9695,8 +9696,9 @@ F:        include/uapi/linux/i2c-*.h
 F:     include/uapi/linux/i2c.h
 
 I2C SUBSYSTEM HOST DRIVERS
+M:     Andi Shyti <andi.shyti@kernel.org>
 L:     linux-i2c@vger.kernel.org
-S:     Odd Fixes
+S:     Maintained
 W:     https://i2c.wiki.kernel.org/
 Q:     https://patchwork.ozlabs.org/project/linux-i2c/list/
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux.git
@@ -18046,6 +18048,14 @@ S:     Maintained
 F:     Documentation/devicetree/bindings/usb/renesas,rzn1-usbf.yaml
 F:     drivers/usb/gadget/udc/renesas_usbf.c
 
+RENESAS RZ/V2M I2C DRIVER
+M:     Fabrizio Castro <fabrizio.castro.jz@renesas.com>
+L:     linux-i2c@vger.kernel.org
+L:     linux-renesas-soc@vger.kernel.org
+S:     Supported
+F:     Documentation/devicetree/bindings/i2c/renesas,rzv2m.yaml
+F:     drivers/i2c/busses/i2c-rzv2m.c
+
 RENESAS USB PHY DRIVER
 M:     Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
 L:     linux-renesas-soc@vger.kernel.org
index 09866a8..0d3a9d3 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -2,7 +2,7 @@
 VERSION = 6
 PATCHLEVEL = 4
 SUBLEVEL = 0
-EXTRAVERSION = -rc5
+EXTRAVERSION = -rc6
 NAME = Hurr durr I'ma ninja sloth
 
 # *DOCUMENTATION*
index 2fc9a5d..625b9b3 100644 (file)
 
                interrupt-parent = <&gpio1>;
                interrupts = <31 0>;
-               pendown-gpio = <&gpio1 31 0>;
+               pendown-gpio = <&gpio1 31 GPIO_ACTIVE_LOW>;
 
 
                ti,x-min = /bits/ 16 <0x0>;
index aa5cc0e..217e9b9 100644 (file)
 };
 
 &shdwc {
-       atmel,shdwc-debouncer = <976>;
+       debounce-delay-us = <976>;
        status = "okay";
 
        input@0 {
index 88869ca..045cb25 100644 (file)
                                        compatible = "ti,ads7843";
                                        interrupts-extended = <&pioC 2 IRQ_TYPE_EDGE_BOTH>;
                                        spi-max-frequency = <3000000>;
-                                       pendown-gpio = <&pioC 2 GPIO_ACTIVE_HIGH>;
+                                       pendown-gpio = <&pioC 2 GPIO_ACTIVE_LOW>;
 
                                        ti,x-min = /bits/ 16 <150>;
                                        ti,x-max = /bits/ 16 <3830>;
index d917dc4..6ad39dc 100644 (file)
@@ -64,7 +64,7 @@
                interrupt-parent = <&gpio2>;
                interrupts = <7 0>;
                spi-max-frequency = <1000000>;
-               pendown-gpio = <&gpio2 7 0>;
+               pendown-gpio = <&gpio2 7 GPIO_ACTIVE_LOW>;
                vcc-supply = <&reg_3p3v>;
                ti,x-min = /bits/ 16 <0>;
                ti,x-max = /bits/ 16 <4095>;
index f483bc0..234e5fc 100644 (file)
                pinctrl-0 = <&pinctrl_tsc2046_pendown>;
                interrupt-parent = <&gpio2>;
                interrupts = <29 0>;
-               pendown-gpio = <&gpio2 29 GPIO_ACTIVE_HIGH>;
+               pendown-gpio = <&gpio2 29 GPIO_ACTIVE_LOW>;
                touchscreen-max-pressure = <255>;
                wakeup-source;
        };
index e61b8a2..51baedf 100644 (file)
 
                interrupt-parent = <&gpio2>;
                interrupts = <25 0>;            /* gpio_57 */
-               pendown-gpio = <&gpio2 25 GPIO_ACTIVE_HIGH>;
+               pendown-gpio = <&gpio2 25 GPIO_ACTIVE_LOW>;
 
                ti,x-min = /bits/ 16 <0x0>;
                ti,x-max = /bits/ 16 <0x0fff>;
index 3decc2d..a7f99ae 100644 (file)
@@ -54,7 +54,7 @@
 
                interrupt-parent = <&gpio1>;
                interrupts = <27 0>;            /* gpio_27 */
-               pendown-gpio = <&gpio1 27 GPIO_ACTIVE_HIGH>;
+               pendown-gpio = <&gpio1 27 GPIO_ACTIVE_LOW>;
 
                ti,x-min = /bits/ 16 <0x0>;
                ti,x-max = /bits/ 16 <0x0fff>;
index c595afe..d310b5c 100644 (file)
                interrupt-parent = <&gpio1>;
                interrupts = <8 0>;   /* boot6 / gpio_8 */
                spi-max-frequency = <1000000>;
-               pendown-gpio = <&gpio1 8 GPIO_ACTIVE_HIGH>;
+               pendown-gpio = <&gpio1 8 GPIO_ACTIVE_LOW>;
                vcc-supply = <&reg_vcc3>;
                pinctrl-names = "default";
                pinctrl-0 = <&tsc2048_pins>;
index 1d6e88f..c3570ac 100644 (file)
 
                interrupt-parent = <&gpio4>;
                interrupts = <18 0>;                    /* gpio_114 */
-               pendown-gpio = <&gpio4 18 GPIO_ACTIVE_HIGH>;
+               pendown-gpio = <&gpio4 18 GPIO_ACTIVE_LOW>;
 
                ti,x-min = /bits/ 16 <0x0>;
                ti,x-max = /bits/ 16 <0x0fff>;
index 7e30f9d..d95a0e1 100644 (file)
 
                interrupt-parent = <&gpio4>;
                interrupts = <18 0>;                    /* gpio_114 */
-               pendown-gpio = <&gpio4 18 GPIO_ACTIVE_HIGH>;
+               pendown-gpio = <&gpio4 18 GPIO_ACTIVE_LOW>;
 
                ti,x-min = /bits/ 16 <0x0>;
                ti,x-max = /bits/ 16 <0x0fff>;
index 5598537..4c3b6ba 100644 (file)
                pinctrl-0 = <&penirq_pins>;
                interrupt-parent = <&gpio3>;
                interrupts = <30 IRQ_TYPE_NONE>;        /* GPIO_94 */
-               pendown-gpio = <&gpio3 30 GPIO_ACTIVE_HIGH>;
+               pendown-gpio = <&gpio3 30 GPIO_ACTIVE_LOW>;
                vcc-supply = <&vaux4>;
 
                ti,x-min = /bits/ 16 <0>;
index 2d87b9f..af288d6 100644 (file)
 
                interrupt-parent = <&gpio1>;
                interrupts = <15 0>;                    /* gpio1_wk15 */
-               pendown-gpio = <&gpio1 15 GPIO_ACTIVE_HIGH>;
+               pendown-gpio = <&gpio1 15 GPIO_ACTIVE_LOW>;
 
 
                ti,x-min = /bits/ 16 <0x0>;
index 7a80e1c..aa0e0e8 100644 (file)
                function = "gpio";
                drive-strength = <8>;
                bias-disable;
-               input-enable;
        };
 
        wlan_hostwake_default_state: wlan-hostwake-default-state {
                function = "gpio";
                drive-strength = <2>;
                bias-disable;
-               input-enable;
        };
 
        wlan_regulator_default_state: wlan-regulator-default-state {
index d640960..5593a3a 100644 (file)
                function = "gpio";
                drive-strength = <2>;
                bias-disable;
-               input-enable;
        };
 
        wlan_regulator_default_state: wlan-regulator-default-state {
index b823812..b887e53 100644 (file)
                function = "gpio";
                drive-strength = <2>;
                bias-disable;
-               input-enable;
        };
 
        touch_pins: touch-state {
 
                        drive-strength = <8>;
                        bias-pull-down;
-                       input-enable;
                };
 
                reset-pins {
                function = "gpio";
                drive-strength = <2>;
                bias-disable;
-               input-enable;
        };
 
        wlan_regulator_default_state: wlan-regulator-default-state {
index 672b246..d228920 100644 (file)
@@ -83,6 +83,7 @@
                L2: l2-cache {
                        compatible = "cache";
                        cache-level = <2>;
+                       cache-unified;
                };
 
                idle-states {
index b653ea4..83839e1 100644 (file)
@@ -74,6 +74,7 @@
                L2: l2-cache {
                        compatible = "cache";
                        cache-level = <2>;
+                       cache-unified;
                        qcom,saw = <&saw_l2>;
                };
 
index dfcfb33..f0ef86f 100644 (file)
                L2: l2-cache {
                        compatible = "cache";
                        cache-level = <2>;
+                       cache-unified;
                        qcom,saw = <&saw_l2>;
                };
        };
index af67647..7581845 100644 (file)
@@ -45,6 +45,7 @@
                L2: l2-cache {
                        compatible = "cache";
                        cache-level = <2>;
+                       cache-unified;
                };
        };
 
index a830476..b269fdc 100644 (file)
@@ -49,7 +49,6 @@
                gpioext1-pins {
                        pins = "gpio2";
                        function = "gpio";
-                       input-enable;
                        bias-disable;
                };
        };
index f601b40..78023ed 100644 (file)
@@ -36,6 +36,7 @@
                L2: l2-cache {
                        compatible = "cache";
                        cache-level = <2>;
+                       cache-unified;
                };
        };
 
index 2a668cd..616fef2 100644 (file)
@@ -42,6 +42,7 @@
                L2: l2-cache {
                        compatible = "cache";
                        cache-level = <2>;
+                       cache-unified;
                };
        };
 
index ab35f2d..861695c 100644 (file)
                pins = "gpio73";
                function = "gpio";
                bias-disable;
-               input-enable;
        };
 
        touch_pin: touch-state {
 
                        drive-strength = <2>;
                        bias-disable;
-                       input-enable;
                };
 
                reset-pins {
index d3bec03..68a2f90 100644 (file)
                function = "gpio";
                drive-strength = <2>;
                bias-disable;
-               input-enable;
        };
 
        sdc1_on: sdc1-on-state {
index 8208012..7ed0d92 100644 (file)
@@ -80,6 +80,7 @@
                L2: l2-cache {
                        compatible = "cache";
                        cache-level = <2>;
+                       cache-unified;
                        qcom,saw = <&saw_l2>;
                };
 
index 8d2a054..8230d0e 100644 (file)
                        function = "gpio";
                        drive-strength = <2>;
                        bias-disable;
-                       input-enable;
                };
 
                reset-pins {
index b9698ff..eb505d6 100644 (file)
                        pins = "gpio75";
                        function = "gpio";
                        drive-strength = <16>;
-                       input-enable;
                };
 
                devwake-pins {
        i2c_touchkey_pins: i2c-touchkey-state {
                pins = "gpio95", "gpio96";
                function = "gpio";
-               input-enable;
                bias-pull-up;
        };
 
        i2c_led_gpioex_pins: i2c-led-gpioex-state {
                pins = "gpio120", "gpio121";
                function = "gpio";
-               input-enable;
                bias-pull-down;
        };
 
        wifi_pin: wifi-state {
                pins = "gpio92";
                function = "gpio";
-               input-enable;
                bias-pull-down;
        };
 
index 04bc58d..0f650ed 100644 (file)
                function = "gpio";
                drive-strength = <2>;
                bias-disable;
-               input-enable;
        };
 
        bt_host_wake_pin: bt-host-wake-state {
index 60dc56d..437dd03 100644 (file)
@@ -334,16 +334,14 @@ static bool at91_pm_eth_quirk_is_valid(struct at91_pm_quirk_eth *eth)
                pdev = of_find_device_by_node(eth->np);
                if (!pdev)
                        return false;
+               /* put_device(eth->dev) is called at the end of suspend. */
                eth->dev = &pdev->dev;
        }
 
        /* No quirks if device isn't a wakeup source. */
-       if (!device_may_wakeup(eth->dev)) {
-               put_device(eth->dev);
+       if (!device_may_wakeup(eth->dev))
                return false;
-       }
 
-       /* put_device(eth->dev) is called at the end of suspend. */
        return true;
 }
 
@@ -439,14 +437,14 @@ clk_unconfigure:
                                pr_err("AT91: PM: failed to enable %s clocks\n",
                                       j == AT91_PM_G_ETH ? "geth" : "eth");
                        }
-               } else {
-                       /*
-                        * Release the reference to eth->dev taken in
-                        * at91_pm_eth_quirk_is_valid().
-                        */
-                       put_device(eth->dev);
-                       eth->dev = NULL;
                }
+
+               /*
+                * Release the reference to eth->dev taken in
+                * at91_pm_eth_quirk_is_valid().
+                */
+               put_device(eth->dev);
+               eth->dev = NULL;
        }
 
        return ret;
index b1201d2..343e1e1 100644 (file)
@@ -1516,7 +1516,7 @@ config XEN
 # 16K |       27          |      14      |       13        |         11         |
 # 64K |       29          |      16      |       13        |         13         |
 config ARCH_FORCE_MAX_ORDER
-       int "Order of maximal physically contiguous allocations" if EXPERT && (ARM64_4K_PAGES || ARM64_16K_PAGES)
+       int
        default "13" if ARM64_64K_PAGES
        default "11" if ARM64_16K_PAGES
        default "10"
index 2dce8f2..adb98a7 100644 (file)
@@ -90,6 +90,8 @@ dma_subsys: bus@5a000000 {
                clocks = <&uart0_lpcg IMX_LPCG_CLK_4>,
                         <&uart0_lpcg IMX_LPCG_CLK_0>;
                clock-names = "ipg", "baud";
+               assigned-clocks = <&clk IMX_SC_R_UART_0 IMX_SC_PM_CLK_PER>;
+               assigned-clock-rates = <80000000>;
                power-domains = <&pd IMX_SC_R_UART_0>;
                status = "disabled";
        };
@@ -100,6 +102,8 @@ dma_subsys: bus@5a000000 {
                clocks = <&uart1_lpcg IMX_LPCG_CLK_4>,
                         <&uart1_lpcg IMX_LPCG_CLK_0>;
                clock-names = "ipg", "baud";
+               assigned-clocks = <&clk IMX_SC_R_UART_1 IMX_SC_PM_CLK_PER>;
+               assigned-clock-rates = <80000000>;
                power-domains = <&pd IMX_SC_R_UART_1>;
                status = "disabled";
        };
@@ -110,6 +114,8 @@ dma_subsys: bus@5a000000 {
                clocks = <&uart2_lpcg IMX_LPCG_CLK_4>,
                         <&uart2_lpcg IMX_LPCG_CLK_0>;
                clock-names = "ipg", "baud";
+               assigned-clocks = <&clk IMX_SC_R_UART_2 IMX_SC_PM_CLK_PER>;
+               assigned-clock-rates = <80000000>;
                power-domains = <&pd IMX_SC_R_UART_2>;
                status = "disabled";
        };
@@ -120,6 +126,8 @@ dma_subsys: bus@5a000000 {
                clocks = <&uart3_lpcg IMX_LPCG_CLK_4>,
                         <&uart3_lpcg IMX_LPCG_CLK_0>;
                clock-names = "ipg", "baud";
+               assigned-clocks = <&clk IMX_SC_R_UART_3 IMX_SC_PM_CLK_PER>;
+               assigned-clock-rates = <80000000>;
                power-domains = <&pd IMX_SC_R_UART_3>;
                status = "disabled";
        };
index 9e82069..5a1f7c3 100644 (file)
@@ -81,7 +81,7 @@
 &ecspi2 {
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_espi2>;
-       cs-gpios = <&gpio5 9 GPIO_ACTIVE_LOW>;
+       cs-gpios = <&gpio5 13 GPIO_ACTIVE_LOW>;
        status = "okay";
 
        eeprom@0 {
                        MX8MN_IOMUXC_ECSPI2_SCLK_ECSPI2_SCLK            0x82
                        MX8MN_IOMUXC_ECSPI2_MOSI_ECSPI2_MOSI            0x82
                        MX8MN_IOMUXC_ECSPI2_MISO_ECSPI2_MISO            0x82
-                       MX8MN_IOMUXC_ECSPI1_SS0_GPIO5_IO9               0x41
+                       MX8MN_IOMUXC_ECSPI2_SS0_GPIO5_IO13              0x41
                >;
        };
 
index ce9d3f0..607cd6b 100644 (file)
@@ -82,8 +82,8 @@
        pinctrl-0 = <&pinctrl_usdhc2>;
        bus-width = <4>;
        vmmc-supply = <&reg_usdhc2_vmmc>;
-       cd-gpios = <&lsio_gpio4 22 GPIO_ACTIVE_LOW>;
-       wp-gpios = <&lsio_gpio4 21 GPIO_ACTIVE_HIGH>;
+       cd-gpios = <&lsio_gpio5 22 GPIO_ACTIVE_LOW>;
+       wp-gpios = <&lsio_gpio5 21 GPIO_ACTIVE_HIGH>;
        status = "okay";
 };
 
index 12e0e17..af4d971 100644 (file)
@@ -73,6 +73,7 @@
                L2_0: l2-cache {
                        compatible = "cache";
                        cache-level = <2>;
+                       cache-unified;
                };
        };
 
index 9ff4e9d..f531797 100644 (file)
@@ -83,7 +83,8 @@
 
                L2_0: l2-cache {
                        compatible = "cache";
-                       cache-level = <0x2>;
+                       cache-level = <2>;
+                       cache-unified;
                };
        };
 
index 84e715a..5b2c198 100644 (file)
@@ -66,7 +66,8 @@
 
                L2_0: l2-cache {
                        compatible = "cache";
-                       cache-level = <0x2>;
+                       cache-level = <2>;
+                       cache-unified;
                };
        };
 
index 3bb7435..0ed19fb 100644 (file)
@@ -72,6 +72,7 @@
                L2_0: l2-cache {
                        compatible = "cache";
                        cache-level = <2>;
+                       cache-unified;
                };
        };
 
index 7e0fa37..834e0b6 100644 (file)
                L2_0: l2-cache {
                        compatible = "cache";
                        cache-level = <2>;
+                       cache-unified;
                };
 
                idle-states {
index 602cb18..d44cfa0 100644 (file)
                L2_0: l2-cache-0 {
                        compatible = "cache";
                        cache-level = <2>;
+                       cache-unified;
                };
 
                L2_1: l2-cache-1 {
                        compatible = "cache";
                        cache-level = <2>;
+                       cache-unified;
                };
        };
 
index 1f0bd24..f47fb8e 100644 (file)
                l2_0: l2-cache0 {
                        compatible = "cache";
                        cache-level = <2>;
+                       cache-unified;
                };
 
                l2_1: l2-cache1 {
                        compatible = "cache";
                        cache-level = <2>;
+                       cache-unified;
                };
        };
 
index 2831966..bdc3f2b 100644 (file)
@@ -52,6 +52,7 @@
                        L2_0: l2-cache {
                                compatible = "cache";
                                cache-level = <2>;
+                               cache-unified;
                        };
                };
 
@@ -88,6 +89,7 @@
                        L2_1: l2-cache {
                                compatible = "cache";
                                cache-level = <2>;
+                               cache-unified;
                        };
                };
 
index 2b35cb3..30257c0 100644 (file)
@@ -53,8 +53,9 @@
                        #cooling-cells = <2>;
                        next-level-cache = <&L2_0>;
                        L2_0: l2-cache {
-                             compatible = "cache";
-                             cache-level = <2>;
+                               compatible = "cache";
+                               cache-level = <2>;
+                               cache-unified;
                        };
                };
 
@@ -83,8 +84,9 @@
                        #cooling-cells = <2>;
                        next-level-cache = <&L2_1>;
                        L2_1: l2-cache {
-                             compatible = "cache";
-                             cache-level = <2>;
+                               compatible = "cache";
+                               cache-level = <2>;
+                               cache-unified;
                        };
                };
 
index b150437..3ec941f 100644 (file)
                        L2_0: l2-cache {
                                compatible = "cache";
                                cache-level = <2>;
+                               cache-unified;
                        };
                };
 
                        L2_1: l2-cache {
                                compatible = "cache";
                                cache-level = <2>;
+                               cache-unified;
                        };
                };
 
index ae5abc7..b29bc4e 100644 (file)
@@ -51,6 +51,7 @@
                        L2_0: l2-cache {
                                compatible = "cache";
                                cache-level = <2>;
+                               cache-unified;
                        };
                };
 
index eefed58..972f753 100644 (file)
@@ -95,6 +95,7 @@
                L2_0: l2-cache {
                        compatible = "cache";
                        cache-level = <2>;
+                       cache-unified;
                };
 
                idle-states {
index 7344381..fb553f0 100644 (file)
                        next-level-cache = <&L2_0>;
                        L2_0: l2-cache {
                                compatible = "cache";
+                               cache-level = <2>;
+                               cache-unified;
                                next-level-cache = <&L3_0>;
                                L3_0: l3-cache {
                                        compatible = "cache";
+                                       cache-level = <3>;
+                                       cache-unified;
                                };
                        };
                };
@@ -54,6 +58,8 @@
                        next-level-cache = <&L2_100>;
                        L2_100: l2-cache {
                                compatible = "cache";
+                               cache-level = <2>;
+                               cache-unified;
                                next-level-cache = <&L3_0>;
                        };
                };
@@ -70,6 +76,8 @@
                        next-level-cache = <&L2_200>;
                        L2_200: l2-cache {
                                compatible = "cache";
+                               cache-level = <2>;
+                               cache-unified;
                                next-level-cache = <&L3_0>;
                        };
                };
@@ -86,6 +94,8 @@
                        next-level-cache = <&L2_300>;
                        L2_300: l2-cache {
                                compatible = "cache";
+                               cache-level = <2>;
+                               cache-unified;
                                next-level-cache = <&L3_0>;
                        };
                };
index 339fea5..15e1ae1 100644 (file)
@@ -7,7 +7,7 @@
 
 #include <dt-bindings/regulator/qcom,rpmh-regulator.h>
 #include <dt-bindings/gpio/gpio.h>
-#include "sm8150.dtsi"
+#include "sa8155p.dtsi"
 #include "pmm8155au_1.dtsi"
 #include "pmm8155au_2.dtsi"
 
diff --git a/arch/arm64/boot/dts/qcom/sa8155p.dtsi b/arch/arm64/boot/dts/qcom/sa8155p.dtsi
new file mode 100644 (file)
index 0000000..ffb7ab6
--- /dev/null
@@ -0,0 +1,40 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2023, Linaro Limited
+ *
+ * SA8155P is an automotive variant of SM8150, with some minor changes.
+ * Most notably, the RPMhPD setup differs: MMCX and LCX/LMX rails are gone,
+ * though the cmd-db doesn't reflect that and access attemps result in a bite.
+ */
+
+#include "sm8150.dtsi"
+
+&dispcc {
+       power-domains = <&rpmhpd SA8155P_CX>;
+};
+
+&mdss_dsi0 {
+       power-domains = <&rpmhpd SA8155P_CX>;
+};
+
+&mdss_dsi1 {
+       power-domains = <&rpmhpd SA8155P_CX>;
+};
+
+&mdss_mdp {
+       power-domains = <&rpmhpd SA8155P_CX>;
+};
+
+&remoteproc_slpi {
+       power-domains = <&rpmhpd SA8155P_CX>,
+                       <&rpmhpd SA8155P_MX>;
+};
+
+&rpmhpd {
+       /*
+        * The bindings were crafted such that SA8155P PDs match their
+        * SM8150 counterparts to make it more maintainable and only
+        * necessitate adjusting entries that actually differ
+        */
+       compatible = "qcom,sa8155p-rpmhpd";
+};
index 2343df7..c3310ca 100644 (file)
                        next-level-cache = <&L2_0>;
                        L2_0: l2-cache {
                                compatible = "cache";
+                               cache-level = <2>;
+                               cache-unified;
                                next-level-cache = <&L3_0>;
                                L3_0: l3-cache {
                                        compatible = "cache";
+                                       cache-level = <3>;
+                                       cache-unified;
                                };
                        };
                };
@@ -58,6 +62,8 @@
                        next-level-cache = <&L2_1>;
                        L2_1: l2-cache {
                                compatible = "cache";
+                               cache-level = <2>;
+                               cache-unified;
                                next-level-cache = <&L3_0>;
                        };
                };
@@ -71,6 +77,8 @@
                        next-level-cache = <&L2_2>;
                        L2_2: l2-cache {
                                compatible = "cache";
+                               cache-level = <2>;
+                               cache-unified;
                                next-level-cache = <&L3_0>;
                        };
                };
@@ -84,6 +92,8 @@
                        next-level-cache = <&L2_3>;
                        L2_3: l2-cache {
                                compatible = "cache";
+                               cache-level = <2>;
+                               cache-unified;
                                next-level-cache = <&L3_0>;
                        };
                };
                        next-level-cache = <&L2_4>;
                        L2_4: l2-cache {
                                compatible = "cache";
+                               cache-level = <2>;
+                               cache-unified;
                                next-level-cache = <&L3_1>;
                                L3_1: l3-cache {
                                        compatible = "cache";
+                                       cache-level = <3>;
+                                       cache-unified;
                                };
 
                        };
                        next-level-cache = <&L2_5>;
                        L2_5: l2-cache {
                                compatible = "cache";
+                               cache-level = <2>;
+                               cache-unified;
                                next-level-cache = <&L3_1>;
                        };
                };
                        next-level-cache = <&L2_6>;
                        L2_6: l2-cache {
                                compatible = "cache";
+                               cache-level = <2>;
+                               cache-unified;
                                next-level-cache = <&L3_1>;
                        };
                };
                        next-level-cache = <&L2_7>;
                        L2_7: l2-cache {
                                compatible = "cache";
+                               cache-level = <2>;
+                               cache-unified;
                                next-level-cache = <&L3_1>;
                        };
                };
index d8ed1d7..4b306a5 100644 (file)
 &cpu6_opp12 {
        opp-peak-kBps = <8532000 23347200>;
 };
+
+&cpu6_opp13 {
+       opp-peak-kBps = <8532000 23347200>;
+};
+
+&cpu6_opp14 {
+       opp-peak-kBps = <8532000 23347200>;
+};
index ea1ffad..f479cab 100644 (file)
                        L2_0: l2-cache {
                                compatible = "cache";
                                cache-level = <2>;
+                               cache-unified;
                                next-level-cache = <&L3_0>;
                                L3_0: l3-cache {
                                        compatible = "cache";
                                        cache-level = <3>;
+                                       cache-unified;
                                };
                        };
                };
                        L2_100: l2-cache {
                                compatible = "cache";
                                cache-level = <2>;
+                               cache-unified;
                                next-level-cache = <&L3_0>;
                        };
                };
                        L2_200: l2-cache {
                                compatible = "cache";
                                cache-level = <2>;
+                               cache-unified;
                                next-level-cache = <&L3_0>;
                        };
                };
                        L2_300: l2-cache {
                                compatible = "cache";
                                cache-level = <2>;
+                               cache-unified;
                                next-level-cache = <&L3_0>;
                        };
                };
                        L2_400: l2-cache {
                                compatible = "cache";
                                cache-level = <2>;
+                               cache-unified;
                                next-level-cache = <&L3_0>;
                        };
                };
                        L2_500: l2-cache {
                                compatible = "cache";
                                cache-level = <2>;
+                               cache-unified;
                                next-level-cache = <&L3_0>;
                        };
                };
                        L2_600: l2-cache {
                                compatible = "cache";
                                cache-level = <2>;
+                               cache-unified;
                                next-level-cache = <&L3_0>;
                        };
                };
                        L2_700: l2-cache {
                                compatible = "cache";
                                cache-level = <2>;
+                               cache-unified;
                                next-level-cache = <&L3_0>;
                        };
                };
index c6dc200..2102704 100644 (file)
        wcd_rx: codec@0,4 {
                compatible = "sdw20217010d00";
                reg = <0 4>;
-               #sound-dai-cells = <1>;
                qcom,rx-port-mapping = <1 2 3 4 5>;
        };
 };
        wcd_tx: codec@0,3 {
                compatible = "sdw20217010d00";
                reg = <0 3>;
-               #sound-dai-cells = <1>;
                qcom,tx-port-mapping = <1 2 3 4>;
        };
 };
index 88b3586..9137db0 100644 (file)
        wcd_rx: codec@0,4 {
                compatible = "sdw20217010d00";
                reg = <0 4>;
-               #sound-dai-cells = <1>;
                qcom,rx-port-mapping = <1 2 3 4 5>;
        };
 };
        wcd_tx: codec@0,3 {
                compatible = "sdw20217010d00";
                reg = <0 3>;
-               #sound-dai-cells = <1>;
                qcom,tx-port-mapping = <1 2 3 4>;
        };
 };
index 31728f4..2fd1d3c 100644 (file)
                        L2_0: l2-cache {
                                compatible = "cache";
                                cache-level = <2>;
+                               cache-unified;
                                next-level-cache = <&L3_0>;
                                L3_0: l3-cache {
                                        compatible = "cache";
                                        cache-level = <3>;
+                                       cache-unified;
                                };
                        };
                };
                        L2_100: l2-cache {
                                compatible = "cache";
                                cache-level = <2>;
+                               cache-unified;
                                next-level-cache = <&L3_0>;
                        };
                };
                        L2_200: l2-cache {
                                compatible = "cache";
                                cache-level = <2>;
+                               cache-unified;
                                next-level-cache = <&L3_0>;
                        };
                };
                        L2_300: l2-cache {
                                compatible = "cache";
                                cache-level = <2>;
+                               cache-unified;
                                next-level-cache = <&L3_0>;
                        };
                };
                        L2_400: l2-cache {
                                compatible = "cache";
                                cache-level = <2>;
+                               cache-unified;
                                next-level-cache = <&L3_0>;
                        };
                };
                        L2_500: l2-cache {
                                compatible = "cache";
                                cache-level = <2>;
+                               cache-unified;
                                next-level-cache = <&L3_0>;
                        };
                };
                        L2_600: l2-cache {
                                compatible = "cache";
                                cache-level = <2>;
+                               cache-unified;
                                next-level-cache = <&L3_0>;
                        };
                };
                        L2_700: l2-cache {
                                compatible = "cache";
                                cache-level = <2>;
+                               cache-unified;
                                next-level-cache = <&L3_0>;
                        };
                };
index 8fa9fbf..cc4aef2 100644 (file)
                        L2_0: l2-cache {
                                compatible = "cache";
                                cache-level = <2>;
+                               cache-unified;
                                next-level-cache = <&L3_0>;
                                L3_0: l3-cache {
-                                     compatible = "cache";
-                                     cache-level = <3>;
+                                       compatible = "cache";
+                                       cache-level = <3>;
+                                       cache-unified;
                                };
                        };
                };
@@ -83,6 +85,7 @@
                        L2_100: l2-cache {
                                compatible = "cache";
                                cache-level = <2>;
+                               cache-unified;
                                next-level-cache = <&L3_0>;
                        };
                };
                        L2_200: l2-cache {
                                compatible = "cache";
                                cache-level = <2>;
+                               cache-unified;
                                next-level-cache = <&L3_0>;
                        };
                };
                        L2_300: l2-cache {
                                compatible = "cache";
                                cache-level = <2>;
+                               cache-unified;
                                next-level-cache = <&L3_0>;
                        };
                };
                        L2_400: l2-cache {
                                compatible = "cache";
                                cache-level = <2>;
+                               cache-unified;
                                next-level-cache = <&L3_0>;
                        };
                };
                        L2_500: l2-cache {
                                compatible = "cache";
                                cache-level = <2>;
+                               cache-unified;
                                next-level-cache = <&L3_0>;
                        };
                };
                        L2_600: l2-cache {
                                compatible = "cache";
                                cache-level = <2>;
+                               cache-unified;
                                next-level-cache = <&L3_0>;
                        };
                };
                        L2_700: l2-cache {
                                compatible = "cache";
                                cache-level = <2>;
+                               cache-unified;
                                next-level-cache = <&L3_0>;
                        };
                };
                                        pins = "gpio7";
                                        function = "dmic1_data";
                                        drive-strength = <8>;
+                                       input-enable;
                                };
                        };
 
                                        function = "dmic1_data";
                                        drive-strength = <2>;
                                        bias-pull-down;
+                                       input-enable;
                                };
                        };
 
                                        pins = "gpio9";
                                        function = "dmic2_data";
                                        drive-strength = <8>;
+                                       input-enable;
                                };
                        };
 
                                        function = "dmic2_data";
                                        drive-strength = <2>;
                                        bias-pull-down;
+                                       input-enable;
                                };
                        };
 
                        qcom,tcs-config = <ACTIVE_TCS  2>, <SLEEP_TCS   3>,
                                          <WAKE_TCS    3>, <CONTROL_TCS 1>;
                        label = "apps_rsc";
+                       power-domains = <&CLUSTER_PD>;
 
                        apps_bcm_voter: bcm-voter {
                                compatible = "qcom,bcm-voter";
index 37e72b1..eaead2f 100644 (file)
@@ -63,6 +63,7 @@
                        L2_1: l2-cache {
                                compatible = "cache";
                                cache-level = <2>;
+                               cache-unified;
                        };
                };
 
                        L2_0: l2-cache {
                                compatible = "cache";
                                cache-level = <2>;
+                               cache-unified;
                        };
                };
 
index c5f839d..b61e13d 100644 (file)
                        L2_0: l2-cache {
                                compatible = "cache";
                                next-level-cache = <&L3_0>;
+                               cache-level = <2>;
+                               cache-unified;
                                L3_0: l3-cache {
-                                     compatible = "cache";
+                                       compatible = "cache";
+                                       cache-level = <3>;
+                                       cache-unified;
                                };
                        };
                };
@@ -57,6 +61,8 @@
                        next-level-cache = <&L2_100>;
                        L2_100: l2-cache {
                                compatible = "cache";
+                               cache-level = <2>;
+                               cache-unified;
                                next-level-cache = <&L3_0>;
                        };
                };
@@ -71,6 +77,8 @@
                        next-level-cache = <&L2_200>;
                        L2_200: l2-cache {
                                compatible = "cache";
+                               cache-level = <2>;
+                               cache-unified;
                                next-level-cache = <&L3_0>;
                        };
                };
@@ -85,6 +93,8 @@
                        next-level-cache = <&L2_300>;
                        L2_300: l2-cache {
                                compatible = "cache";
+                               cache-level = <2>;
+                               cache-unified;
                                next-level-cache = <&L3_0>;
                        };
                };
                        next-level-cache = <&L2_400>;
                        L2_400: l2-cache {
                                compatible = "cache";
+                               cache-level = <2>;
+                               cache-unified;
                                next-level-cache = <&L3_0>;
                        };
                };
                        next-level-cache = <&L2_500>;
                        L2_500: l2-cache {
                                compatible = "cache";
+                               cache-level = <2>;
+                               cache-unified;
                                next-level-cache = <&L3_0>;
                        };
                };
                        next-level-cache = <&L2_600>;
                        L2_600: l2-cache {
                                compatible = "cache";
+                               cache-level = <2>;
+                               cache-unified;
                                next-level-cache = <&L3_0>;
                        };
                };
                        next-level-cache = <&L2_700>;
                        L2_700: l2-cache {
                                compatible = "cache";
+                               cache-level = <2>;
+                               cache-unified;
                                next-level-cache = <&L3_0>;
                        };
                };
index 9042444..cdeb05e 100644 (file)
                        L2_0: l2-cache {
                                compatible = "cache";
                                cache-level = <2>;
+                               cache-unified;
                                next-level-cache = <&L3_0>;
                                L3_0: l3-cache {
-                                     compatible = "cache";
-                                     cache-level = <3>;
+                                       compatible = "cache";
+                                       cache-level = <3>;
+                                       cache-unified;
                                };
                        };
                };
                        L2_100: l2-cache {
                                compatible = "cache";
                                cache-level = <2>;
+                               cache-unified;
                                next-level-cache = <&L3_0>;
                        };
                };
                        L2_200: l2-cache {
                                compatible = "cache";
                                cache-level = <2>;
+                               cache-unified;
                                next-level-cache = <&L3_0>;
                        };
                };
                        L2_300: l2-cache {
                                compatible = "cache";
                                cache-level = <2>;
+                               cache-unified;
                                next-level-cache = <&L3_0>;
                        };
                };
                        L2_400: l2-cache {
                                compatible = "cache";
                                cache-level = <2>;
+                               cache-unified;
                                next-level-cache = <&L3_0>;
                        };
                };
                        L2_500: l2-cache {
                                compatible = "cache";
                                cache-level = <2>;
+                               cache-unified;
                                next-level-cache = <&L3_0>;
                        };
                };
                        L2_600: l2-cache {
                                compatible = "cache";
                                cache-level = <2>;
+                               cache-unified;
                                next-level-cache = <&L3_0>;
                        };
                };
                        L2_700: l2-cache {
                                compatible = "cache";
                                cache-level = <2>;
+                               cache-unified;
                                next-level-cache = <&L3_0>;
                        };
                };
index 631ca32..43f31c1 100644 (file)
@@ -50,6 +50,7 @@
                        L2_0: l2-cache {
                                compatible = "cache";
                                cache-level = <2>;
+                               cache-unified;
                        };
                };
 
                        L2_1: l2-cache {
                                compatible = "cache";
                                cache-level = <2>;
+                               cache-unified;
                        };
                };
 
index 9484752..2aa093d 100644 (file)
@@ -47,6 +47,7 @@
                        L2_0: l2-cache {
                                compatible = "cache";
                                cache-level = <2>;
+                               cache-unified;
                        };
                };
 
@@ -87,6 +88,7 @@
                        L2_1: l2-cache {
                                compatible = "cache";
                                cache-level = <2>;
+                               cache-unified;
                        };
                };
 
index 18c4616..ad34301 100644 (file)
                        L2_0: l2-cache {
                                compatible = "cache";
                                cache-level = <2>;
+                               cache-unified;
                                next-level-cache = <&L3_0>;
                                L3_0: l3-cache {
                                        compatible = "cache";
                                        cache-level = <3>;
+                                       cache-unified;
                                };
                        };
                };
@@ -86,6 +88,7 @@
                        L2_100: l2-cache {
                                compatible = "cache";
                                cache-level = <2>;
+                               cache-unified;
                                next-level-cache = <&L3_0>;
                        };
                };
                        L2_200: l2-cache {
                                compatible = "cache";
                                cache-level = <2>;
+                               cache-unified;
                                next-level-cache = <&L3_0>;
                        };
                };
                        L2_300: l2-cache {
                                compatible = "cache";
                                cache-level = <2>;
+                               cache-unified;
                                next-level-cache = <&L3_0>;
                        };
                };
                        L2_400: l2-cache {
                                compatible = "cache";
                                cache-level = <2>;
+                               cache-unified;
                                next-level-cache = <&L3_0>;
                        };
                };
                        L2_500: l2-cache {
                                compatible = "cache";
                                cache-level = <2>;
+                               cache-unified;
                                next-level-cache = <&L3_0>;
                        };
                };
                        L2_600: l2-cache {
                                compatible = "cache";
                                cache-level = <2>;
+                               cache-unified;
                                next-level-cache = <&L3_0>;
                        };
                };
                        L2_700: l2-cache {
                                compatible = "cache";
                                cache-level = <2>;
+                               cache-unified;
                                next-level-cache = <&L3_0>;
                        };
                };
index 8220e6f..b2f1bb1 100644 (file)
 };
 
 &remoteproc_adsp {
-       firmware-name = "qcom/Sony/murray/adsp.mbn";
+       firmware-name = "qcom/sm6375/Sony/murray/adsp.mbn";
        status = "okay";
 };
 
 &remoteproc_cdsp {
-       firmware-name = "qcom/Sony/murray/cdsp.mbn";
+       firmware-name = "qcom/sm6375/Sony/murray/cdsp.mbn";
        status = "okay";
 };
 
index ae9b6bc..f8d9c34 100644 (file)
                        power-domain-names = "psci";
                        #cooling-cells = <2>;
                        L2_0: l2-cache {
-                             compatible = "cache";
-                             next-level-cache = <&L3_0>;
+                               compatible = "cache";
+                               cache-level = <2>;
+                               cache-unified;
+                               next-level-cache = <&L3_0>;
                                L3_0: l3-cache {
-                                     compatible = "cache";
+                                       compatible = "cache";
+                                       cache-level = <3>;
+                                       cache-unified;
                                };
                        };
                };
                        power-domain-names = "psci";
                        #cooling-cells = <2>;
                        L2_100: l2-cache {
-                             compatible = "cache";
-                             next-level-cache = <&L3_0>;
+                               compatible = "cache";
+                               cache-level = <2>;
+                               cache-unified;
+                               next-level-cache = <&L3_0>;
                        };
                };
 
                        power-domain-names = "psci";
                        #cooling-cells = <2>;
                        L2_200: l2-cache {
-                             compatible = "cache";
-                             next-level-cache = <&L3_0>;
+                               compatible = "cache";
+                               cache-level = <2>;
+                               cache-unified;
+                               next-level-cache = <&L3_0>;
                        };
                };
 
                        power-domain-names = "psci";
                        #cooling-cells = <2>;
                        L2_300: l2-cache {
-                             compatible = "cache";
-                             next-level-cache = <&L3_0>;
+                               compatible = "cache";
+                               cache-level = <2>;
+                               cache-unified;
+                               next-level-cache = <&L3_0>;
                        };
                };
 
                        power-domain-names = "psci";
                        #cooling-cells = <2>;
                        L2_400: l2-cache {
-                             compatible = "cache";
-                             next-level-cache = <&L3_0>;
+                               compatible = "cache";
+                               cache-level = <2>;
+                               cache-unified;
+                               next-level-cache = <&L3_0>;
                        };
                };
 
                        power-domain-names = "psci";
                        #cooling-cells = <2>;
                        L2_500: l2-cache {
-                             compatible = "cache";
-                             next-level-cache = <&L3_0>;
+                               compatible = "cache";
+                               cache-level = <2>;
+                               cache-unified;
+                               next-level-cache = <&L3_0>;
                        };
                };
 
                        power-domain-names = "psci";
                        #cooling-cells = <2>;
                        L2_600: l2-cache {
-                             compatible = "cache";
-                             next-level-cache = <&L3_0>;
+                               compatible = "cache";
+                               cache-level = <2>;
+                               cache-unified;
+                               next-level-cache = <&L3_0>;
                        };
                };
 
                        power-domain-names = "psci";
                        #cooling-cells = <2>;
                        L2_700: l2-cache {
-                             compatible = "cache";
-                             next-level-cache = <&L3_0>;
+                               compatible = "cache";
+                               cache-level = <2>;
+                               cache-unified;
+                               next-level-cache = <&L3_0>;
                        };
                };
 
index 2273fa5..27dcda0 100644 (file)
                        L2_0: l2-cache {
                                compatible = "cache";
                                cache-level = <2>;
+                               cache-unified;
                                next-level-cache = <&L3_0>;
                                L3_0: l3-cache {
-                                     compatible = "cache";
-                                     cache-level = <3>;
+                                       compatible = "cache";
+                                       cache-level = <3>;
+                                       cache-unified;
                                };
                        };
                };
@@ -90,6 +92,7 @@
                        L2_100: l2-cache {
                                compatible = "cache";
                                cache-level = <2>;
+                               cache-unified;
                                next-level-cache = <&L3_0>;
                        };
                };
                        L2_200: l2-cache {
                                compatible = "cache";
                                cache-level = <2>;
+                               cache-unified;
                                next-level-cache = <&L3_0>;
                        };
                };
                        L2_300: l2-cache {
                                compatible = "cache";
                                cache-level = <2>;
+                               cache-unified;
                                next-level-cache = <&L3_0>;
                        };
                };
                        L2_400: l2-cache {
                                compatible = "cache";
                                cache-level = <2>;
+                               cache-unified;
                                next-level-cache = <&L3_0>;
                        };
                };
                        L2_500: l2-cache {
                                compatible = "cache";
                                cache-level = <2>;
+                               cache-unified;
                                next-level-cache = <&L3_0>;
                        };
                };
                        L2_600: l2-cache {
                                compatible = "cache";
                                cache-level = <2>;
+                               cache-unified;
                                next-level-cache = <&L3_0>;
                        };
                };
                        L2_700: l2-cache {
                                compatible = "cache";
                                cache-level = <2>;
+                               cache-unified;
                                next-level-cache = <&L3_0>;
                        };
                };
index 8b2ae39..de6101d 100644 (file)
@@ -13,6 +13,6 @@
 };
 
 &display_panel {
-       compatible = "xiaomi,elish-boe-nt36523";
+       compatible = "xiaomi,elish-boe-nt36523", "novatek,nt36523";
        status = "okay";
 };
index a4d5341..4cffe9c 100644 (file)
@@ -13,6 +13,6 @@
 };
 
 &display_panel {
-       compatible = "xiaomi,elish-csot-nt36523";
+       compatible = "xiaomi,elish-csot-nt36523", "novatek,nt36523";
        status = "okay";
 };
index ebcb481..3efdc03 100644 (file)
                        power-domain-names = "psci";
                        #cooling-cells = <2>;
                        L2_0: l2-cache {
-                             compatible = "cache";
-                             cache-level = <2>;
-                             next-level-cache = <&L3_0>;
+                               compatible = "cache";
+                               cache-level = <2>;
+                               cache-unified;
+                               next-level-cache = <&L3_0>;
                                L3_0: l3-cache {
-                                     compatible = "cache";
-                                     cache-level = <3>;
+                                       compatible = "cache";
+                                       cache-level = <3>;
+                                       cache-unified;
                                };
                        };
                };
                        power-domain-names = "psci";
                        #cooling-cells = <2>;
                        L2_100: l2-cache {
-                             compatible = "cache";
-                             cache-level = <2>;
-                             next-level-cache = <&L3_0>;
+                               compatible = "cache";
+                               cache-level = <2>;
+                               cache-unified;
+                               next-level-cache = <&L3_0>;
                        };
                };
 
                        power-domain-names = "psci";
                        #cooling-cells = <2>;
                        L2_200: l2-cache {
-                             compatible = "cache";
-                             cache-level = <2>;
-                             next-level-cache = <&L3_0>;
+                               compatible = "cache";
+                               cache-level = <2>;
+                               cache-unified;
+                               next-level-cache = <&L3_0>;
                        };
                };
 
                        power-domain-names = "psci";
                        #cooling-cells = <2>;
                        L2_300: l2-cache {
-                             compatible = "cache";
-                             cache-level = <2>;
-                             next-level-cache = <&L3_0>;
+                               compatible = "cache";
+                               cache-level = <2>;
+                               cache-unified;
+                               next-level-cache = <&L3_0>;
                        };
                };
 
                        power-domain-names = "psci";
                        #cooling-cells = <2>;
                        L2_400: l2-cache {
-                             compatible = "cache";
-                             cache-level = <2>;
-                             next-level-cache = <&L3_0>;
+                               compatible = "cache";
+                               cache-level = <2>;
+                               cache-unified;
+                               next-level-cache = <&L3_0>;
                        };
                };
 
                        power-domain-names = "psci";
                        #cooling-cells = <2>;
                        L2_500: l2-cache {
-                             compatible = "cache";
-                             cache-level = <2>;
-                             next-level-cache = <&L3_0>;
+                               compatible = "cache";
+                               cache-level = <2>;
+                               cache-unified;
+                               next-level-cache = <&L3_0>;
                        };
                };
 
                        power-domain-names = "psci";
                        #cooling-cells = <2>;
                        L2_600: l2-cache {
-                             compatible = "cache";
-                             cache-level = <2>;
-                             next-level-cache = <&L3_0>;
+                               compatible = "cache";
+                               cache-level = <2>;
+                               cache-unified;
+                               next-level-cache = <&L3_0>;
                        };
                };
 
                        power-domain-names = "psci";
                        #cooling-cells = <2>;
                        L2_700: l2-cache {
-                             compatible = "cache";
-                             cache-level = <2>;
-                             next-level-cache = <&L3_0>;
+                               compatible = "cache";
+                               cache-level = <2>;
+                               cache-unified;
+                               next-level-cache = <&L3_0>;
                        };
                };
 
index 595533a..d59ea8e 100644 (file)
                        #cooling-cells = <2>;
                        clocks = <&cpufreq_hw 0>;
                        L2_0: l2-cache {
-                             compatible = "cache";
-                             cache-level = <2>;
-                             next-level-cache = <&L3_0>;
+                               compatible = "cache";
+                               cache-level = <2>;
+                               cache-unified;
+                               next-level-cache = <&L3_0>;
                                L3_0: l3-cache {
-                                     compatible = "cache";
-                                     cache-level = <3>;
+                                       compatible = "cache";
+                                       cache-level = <3>;
+                                       cache-unified;
                                };
                        };
                };
                        #cooling-cells = <2>;
                        clocks = <&cpufreq_hw 0>;
                        L2_100: l2-cache {
-                             compatible = "cache";
-                             cache-level = <2>;
-                             next-level-cache = <&L3_0>;
+                               compatible = "cache";
+                               cache-level = <2>;
+                               cache-unified;
+                               next-level-cache = <&L3_0>;
                        };
                };
 
                        #cooling-cells = <2>;
                        clocks = <&cpufreq_hw 0>;
                        L2_200: l2-cache {
-                             compatible = "cache";
-                             cache-level = <2>;
-                             next-level-cache = <&L3_0>;
+                               compatible = "cache";
+                               cache-level = <2>;
+                               cache-unified;
+                               next-level-cache = <&L3_0>;
                        };
                };
 
                        #cooling-cells = <2>;
                        clocks = <&cpufreq_hw 0>;
                        L2_300: l2-cache {
-                             compatible = "cache";
-                             cache-level = <2>;
-                             next-level-cache = <&L3_0>;
+                               compatible = "cache";
+                               cache-level = <2>;
+                               cache-unified;
+                               next-level-cache = <&L3_0>;
                        };
                };
 
                        #cooling-cells = <2>;
                        clocks = <&cpufreq_hw 1>;
                        L2_400: l2-cache {
-                             compatible = "cache";
-                             cache-level = <2>;
-                             next-level-cache = <&L3_0>;
+                               compatible = "cache";
+                               cache-level = <2>;
+                               cache-unified;
+                               next-level-cache = <&L3_0>;
                        };
                };
 
                        #cooling-cells = <2>;
                        clocks = <&cpufreq_hw 1>;
                        L2_500: l2-cache {
-                             compatible = "cache";
-                             cache-level = <2>;
-                             next-level-cache = <&L3_0>;
+                               compatible = "cache";
+                               cache-level = <2>;
+                               cache-unified;
+                               next-level-cache = <&L3_0>;
                        };
                };
 
                        #cooling-cells = <2>;
                        clocks = <&cpufreq_hw 1>;
                        L2_600: l2-cache {
-                             compatible = "cache";
-                             cache-level = <2>;
-                             next-level-cache = <&L3_0>;
+                               compatible = "cache";
+                               cache-level = <2>;
+                               cache-unified;
+                               next-level-cache = <&L3_0>;
                        };
                };
 
                        #cooling-cells = <2>;
                        clocks = <&cpufreq_hw 2>;
                        L2_700: l2-cache {
-                             compatible = "cache";
-                             cache-level = <2>;
-                             next-level-cache = <&L3_0>;
+                               compatible = "cache";
+                               cache-level = <2>;
+                               cache-unified;
+                               next-level-cache = <&L3_0>;
                        };
                };
 
index 6e9bad8..558cbc4 100644 (file)
                        L2_0: l2-cache {
                                compatible = "cache";
                                cache-level = <2>;
+                               cache-unified;
                                next-level-cache = <&L3_0>;
                                L3_0: l3-cache {
                                        compatible = "cache";
                                        cache-level = <3>;
+                                       cache-unified;
                                };
                        };
                };
                        L2_100: l2-cache {
                                compatible = "cache";
                                cache-level = <2>;
+                               cache-unified;
                                next-level-cache = <&L3_0>;
                        };
                };
                        L2_200: l2-cache {
                                compatible = "cache";
                                cache-level = <2>;
+                               cache-unified;
                                next-level-cache = <&L3_0>;
                        };
                };
                        L2_300: l2-cache {
                                compatible = "cache";
                                cache-level = <2>;
+                               cache-unified;
                                next-level-cache = <&L3_0>;
                        };
                };
                        L2_400: l2-cache {
                                compatible = "cache";
                                cache-level = <2>;
+                               cache-unified;
                                next-level-cache = <&L3_0>;
                        };
                };
                        L2_500: l2-cache {
                                compatible = "cache";
                                cache-level = <2>;
+                               cache-unified;
                                next-level-cache = <&L3_0>;
                        };
                };
                        L2_600: l2-cache {
                                compatible = "cache";
                                cache-level = <2>;
+                               cache-unified;
                                next-level-cache = <&L3_0>;
                        };
                };
                        L2_700: l2-cache {
                                compatible = "cache";
                                cache-level = <2>;
+                               cache-unified;
                                next-level-cache = <&L3_0>;
                        };
                };
                        qcom,din-ports = <4>;
                        qcom,dout-ports = <9>;
 
-                       qcom,ports-sinterval =          <0x07 0x1f 0x3f 0x07 0x1f 0x3f 0x18f 0xff 0xff 0x0f 0x0f 0xff 0x31f>;
+                       qcom,ports-sinterval =          /bits/ 16 <0x07 0x1f 0x3f 0x07 0x1f 0x3f 0x18f 0xff 0xff 0x0f 0x0f 0xff 0x31f>;
                        qcom,ports-offset1 =            /bits/ 8 <0x01 0x03 0x05 0x02 0x04 0x15 0x00 0xff 0xff 0x06 0x0d 0xff 0x00>;
                        qcom,ports-offset2 =            /bits/ 8 <0xff 0x07 0x1f 0xff 0x07 0x1f 0xff 0xff 0xff 0xff 0xff 0xff 0xff>;
                        qcom,ports-hstart =             /bits/ 8 <0xff 0xff 0xff 0xff 0xff 0xff 0x08 0xff 0xff 0xff 0xff 0xff 0x0f>;
                        qcom,din-ports = <0>;
                        qcom,dout-ports = <10>;
 
-                       qcom,ports-sinterval =          <0x03 0x3f 0x1f 0x07 0x00 0x18f 0xff 0xff 0xff 0xff>;
+                       qcom,ports-sinterval =          /bits/ 16 <0x03 0x3f 0x1f 0x07 0x00 0x18f 0xff 0xff 0xff 0xff>;
                        qcom,ports-offset1 =            /bits/ 8 <0x00 0x00 0x0b 0x01 0x00 0x00 0xff 0xff 0xff 0xff>;
                        qcom,ports-offset2 =            /bits/ 8 <0x00 0x00 0x0b 0x00 0x00 0x00 0xff 0xff 0xff 0xff>;
                        qcom,ports-hstart =             /bits/ 8 <0xff 0x03 0xff 0xff 0xff 0x08 0xff 0xff 0xff 0xff>;
                        qcom,din-ports = <4>;
                        qcom,dout-ports = <9>;
 
-                       qcom,ports-sinterval =          <0x07 0x1f 0x3f 0x07 0x1f 0x3f 0x18f 0xff 0xff 0x0f 0x0f 0xff 0x31f>;
+                       qcom,ports-sinterval =          /bits/ 16 <0x07 0x1f 0x3f 0x07 0x1f 0x3f 0x18f 0xff 0xff 0x0f 0x0f 0xff 0x31f>;
                        qcom,ports-offset1 =            /bits/ 8 <0x01 0x03 0x05 0x02 0x04 0x15 0x00 0xff 0xff 0x06 0x0d 0xff 0x00>;
                        qcom,ports-offset2 =            /bits/ 8 <0xff 0x07 0x1f 0xff 0x07 0x1f 0xff 0xff 0xff 0xff 0xff 0xff 0xff>;
                        qcom,ports-hstart =             /bits/ 8 <0xff 0xff 0xff 0xff 0xff 0xff 0x08 0xff 0xff 0xff 0xff 0xff 0x0f>;
 
                system-cache-controller@25000000 {
                        compatible = "qcom,sm8550-llcc";
-                       reg = <0 0x25000000 0 0x800000>,
+                       reg = <0 0x25000000 0 0x200000>,
+                             <0 0x25200000 0 0x200000>,
+                             <0 0x25400000 0 0x200000>,
+                             <0 0x25600000 0 0x200000>,
                              <0 0x25800000 0 0x200000>;
-                       reg-names = "llcc_base", "llcc_broadcast_base";
+                       reg-names = "llcc0_base",
+                                   "llcc1_base",
+                                   "llcc2_base",
+                                   "llcc3_base",
+                                   "llcc_broadcast_base";
                        interrupts = <GIC_SPI 266 IRQ_TYPE_LEVEL_HIGH>;
                };
 
index cb21ccd..6045a51 100644 (file)
@@ -600,8 +600,7 @@ static int __kprobes do_page_fault(unsigned long far, unsigned long esr,
                vma_end_read(vma);
                goto lock_mmap;
        }
-       fault = handle_mm_fault(vma, addr & PAGE_MASK,
-                               mm_flags | FAULT_FLAG_VMA_LOCK, regs);
+       fault = handle_mm_fault(vma, addr, mm_flags | FAULT_FLAG_VMA_LOCK, regs);
        vma_end_read(vma);
 
        if (!(fault & VM_FAULT_RETRY)) {
index b3323ab..35e8a52 100644 (file)
@@ -1496,7 +1496,7 @@ __BUILD_CSR_OP(tlbidx)
 #define write_fcsr(dest, val) \
 do {   \
        __asm__ __volatile__(   \
-       "       movgr2fcsr      %0, "__stringify(dest)" \n"     \
+       "       movgr2fcsr      "__stringify(dest)", %0 \n"     \
        : : "r" (val)); \
 } while (0)
 
index 8b98d22..de46a6b 100644 (file)
 #define        _PAGE_PFN_SHIFT         12
 #define        _PAGE_SWP_EXCLUSIVE_SHIFT 23
 #define        _PAGE_PFN_END_SHIFT     48
+#define        _PAGE_PRESENT_INVALID_SHIFT 60
 #define        _PAGE_NO_READ_SHIFT     61
 #define        _PAGE_NO_EXEC_SHIFT     62
 #define        _PAGE_RPLV_SHIFT        63
 
 /* Used by software */
 #define _PAGE_PRESENT          (_ULCAST_(1) << _PAGE_PRESENT_SHIFT)
+#define _PAGE_PRESENT_INVALID  (_ULCAST_(1) << _PAGE_PRESENT_INVALID_SHIFT)
 #define _PAGE_WRITE            (_ULCAST_(1) << _PAGE_WRITE_SHIFT)
 #define _PAGE_ACCESSED         (_ULCAST_(1) << _PAGE_ACCESSED_SHIFT)
 #define _PAGE_MODIFIED         (_ULCAST_(1) << _PAGE_MODIFIED_SHIFT)
index d28fb9d..9a9f9ff 100644 (file)
@@ -213,7 +213,7 @@ static inline int pmd_bad(pmd_t pmd)
 static inline int pmd_present(pmd_t pmd)
 {
        if (unlikely(pmd_val(pmd) & _PAGE_HUGE))
-               return !!(pmd_val(pmd) & (_PAGE_PRESENT | _PAGE_PROTNONE));
+               return !!(pmd_val(pmd) & (_PAGE_PRESENT | _PAGE_PROTNONE | _PAGE_PRESENT_INVALID));
 
        return pmd_val(pmd) != (unsigned long)invalid_pte_table;
 }
@@ -558,6 +558,7 @@ static inline pmd_t pmd_modify(pmd_t pmd, pgprot_t newprot)
 
 static inline pmd_t pmd_mkinvalid(pmd_t pmd)
 {
+       pmd_val(pmd) |= _PAGE_PRESENT_INVALID;
        pmd_val(pmd) &= ~(_PAGE_PRESENT | _PAGE_VALID | _PAGE_DIRTY | _PAGE_PROTNONE);
 
        return pmd;
index 2406c95..021b59c 100644 (file)
@@ -396,6 +396,8 @@ int hw_breakpoint_arch_parse(struct perf_event *bp,
 
        if (hw->ctrl.type != LOONGARCH_BREAKPOINT_EXECUTE)
                alignment_mask = 0x7;
+       else
+               alignment_mask = 0x3;
        offset = hw->address & alignment_mask;
 
        hw->address &= ~alignment_mask;
index ff28f99..0491bf4 100644 (file)
@@ -271,7 +271,7 @@ static void loongarch_pmu_enable_event(struct hw_perf_event *evt, int idx)
        WARN_ON(idx < 0 || idx >= loongarch_pmu.num_counters);
 
        /* Make sure interrupt enabled. */
-       cpuc->saved_ctrl[idx] = M_PERFCTL_EVENT(evt->event_base & 0xff) |
+       cpuc->saved_ctrl[idx] = M_PERFCTL_EVENT(evt->event_base) |
                (evt->config_base & M_PERFCTL_CONFIG_MASK) | CSR_PERFCTRL_IE;
 
        cpu = (event->cpu >= 0) ? event->cpu : smp_processor_id();
@@ -594,7 +594,7 @@ static struct pmu pmu = {
 
 static unsigned int loongarch_pmu_perf_event_encode(const struct loongarch_perf_event *pev)
 {
-       return (pev->event_id & 0xff);
+       return M_PERFCTL_EVENT(pev->event_id);
 }
 
 static const struct loongarch_perf_event *loongarch_pmu_map_general_event(int idx)
@@ -849,7 +849,7 @@ static void resume_local_counters(void)
 
 static const struct loongarch_perf_event *loongarch_pmu_map_raw_event(u64 config)
 {
-       raw_event.event_id = config & 0xff;
+       raw_event.event_id = M_PERFCTL_EVENT(config);
 
        return &raw_event;
 }
index bdff825..85fae3d 100644 (file)
@@ -485,7 +485,7 @@ static int __init debugfs_unaligned(void)
        struct dentry *d;
 
        d = debugfs_create_dir("loongarch", NULL);
-       if (!d)
+       if (IS_ERR_OR_NULL(d))
                return -ENOMEM;
 
        debugfs_create_u32("unaligned_instructions_user",
index 56339be..0e7e5b0 100644 (file)
@@ -97,7 +97,7 @@
                        rx-fifo-depth = <8192>;
                        tx-fifo-depth = <8192>;
                        address-bits = <48>;
-                       max-frame-size = <1518>;
+                       max-frame-size = <1500>;
                        local-mac-address = [00 00 00 00 00 00];
                        altr,has-supplementary-unicast;
                        altr,enable-sup-addr = <1>;
index d10fb81..3ee3169 100644 (file)
                                interrupt-names = "rx_irq", "tx_irq";
                                rx-fifo-depth = <8192>;
                                tx-fifo-depth = <8192>;
-                               max-frame-size = <1518>;
+                               max-frame-size = <1500>;
                                local-mac-address = [ 00 00 00 00 00 00 ];
                                phy-mode = "rgmii-id";
                                phy-handle = <&phy0>;
index 6f5e272..78473d6 100644 (file)
@@ -5,6 +5,11 @@ KCSAN_SANITIZE := n
 
 targets += trampoline_$(BITS).o purgatory.ro
 
+# When profile-guided optimization is enabled, llvm emits two different
+# overlapping text sections, which is not supported by kexec. Remove profile
+# optimization flags.
+KBUILD_CFLAGS := $(filter-out -fprofile-sample-use=% -fprofile-use=%,$(KBUILD_CFLAGS))
+
 LDFLAGS_purgatory.ro := -e purgatory_start -r --no-undefined
 
 $(obj)/purgatory.ro: $(obj)/trampoline_$(BITS).o FORCE
index 2bb0c38..5966ad9 100644 (file)
@@ -26,6 +26,7 @@ config RISCV
        select ARCH_HAS_GIGANTIC_PAGE
        select ARCH_HAS_KCOV
        select ARCH_HAS_MMIOWB
+       select ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE
        select ARCH_HAS_PMEM_API
        select ARCH_HAS_PTE_SPECIAL
        select ARCH_HAS_SET_DIRECT_MAP if MMU
index d887a54..0bbffd5 100644 (file)
@@ -8,41 +8,8 @@
 #include <asm-generic/pgalloc.h>
 #include <asm/pgtable.h>
 
-static inline int split_pmd_page(unsigned long addr)
-{
-       int i;
-       unsigned long pfn = PFN_DOWN(__pa((addr & PMD_MASK)));
-       pmd_t *pmd = pmd_off_k(addr);
-       pte_t *pte = pte_alloc_one_kernel(&init_mm);
-
-       if (!pte)
-               return -ENOMEM;
-
-       for (i = 0; i < PTRS_PER_PTE; i++)
-               set_pte(pte + i, pfn_pte(pfn + i, PAGE_KERNEL));
-       set_pmd(pmd, pfn_pmd(PFN_DOWN(__pa(pte)), PAGE_TABLE));
-
-       flush_tlb_kernel_range(addr, addr + PMD_SIZE);
-       return 0;
-}
-
 static inline bool arch_kfence_init_pool(void)
 {
-       int ret;
-       unsigned long addr;
-       pmd_t *pmd;
-
-       for (addr = (unsigned long)__kfence_pool; is_kfence_address((void *)addr);
-            addr += PAGE_SIZE) {
-               pmd = pmd_off_k(addr);
-
-               if (pmd_leaf(*pmd)) {
-                       ret = split_pmd_page(addr);
-                       if (ret)
-                               return false;
-               }
-       }
-
        return true;
 }
 
index 2258b27..75970ee 100644 (file)
@@ -165,8 +165,7 @@ extern struct pt_alloc_ops pt_ops __initdata;
                                         _PAGE_EXEC | _PAGE_WRITE)
 
 #define PAGE_COPY              PAGE_READ
-#define PAGE_COPY_EXEC         PAGE_EXEC
-#define PAGE_COPY_READ_EXEC    PAGE_READ_EXEC
+#define PAGE_COPY_EXEC         PAGE_READ_EXEC
 #define PAGE_SHARED            PAGE_WRITE
 #define PAGE_SHARED_EXEC       PAGE_WRITE_EXEC
 
index c6bb966..4fa420f 100644 (file)
@@ -23,6 +23,7 @@
 #ifdef CONFIG_RELOCATABLE
 #include <linux/elf.h>
 #endif
+#include <linux/kfence.h>
 
 #include <asm/fixmap.h>
 #include <asm/tlbflush.h>
@@ -293,7 +294,7 @@ static const pgprot_t protection_map[16] = {
        [VM_EXEC]                                       = PAGE_EXEC,
        [VM_EXEC | VM_READ]                             = PAGE_READ_EXEC,
        [VM_EXEC | VM_WRITE]                            = PAGE_COPY_EXEC,
-       [VM_EXEC | VM_WRITE | VM_READ]                  = PAGE_COPY_READ_EXEC,
+       [VM_EXEC | VM_WRITE | VM_READ]                  = PAGE_COPY_EXEC,
        [VM_SHARED]                                     = PAGE_NONE,
        [VM_SHARED | VM_READ]                           = PAGE_READ,
        [VM_SHARED | VM_WRITE]                          = PAGE_SHARED,
@@ -659,18 +660,19 @@ void __init create_pgd_mapping(pgd_t *pgdp,
        create_pgd_next_mapping(nextp, va, pa, sz, prot);
 }
 
-static uintptr_t __init best_map_size(phys_addr_t base, phys_addr_t size)
+static uintptr_t __init best_map_size(phys_addr_t pa, uintptr_t va,
+                                     phys_addr_t size)
 {
-       if (!(base & (PGDIR_SIZE - 1)) && size >= PGDIR_SIZE)
+       if (!(pa & (PGDIR_SIZE - 1)) && !(va & (PGDIR_SIZE - 1)) && size >= PGDIR_SIZE)
                return PGDIR_SIZE;
 
-       if (!(base & (P4D_SIZE - 1)) && size >= P4D_SIZE)
+       if (!(pa & (P4D_SIZE - 1)) && !(va & (P4D_SIZE - 1)) && size >= P4D_SIZE)
                return P4D_SIZE;
 
-       if (!(base & (PUD_SIZE - 1)) && size >= PUD_SIZE)
+       if (!(pa & (PUD_SIZE - 1)) && !(va & (PUD_SIZE - 1)) && size >= PUD_SIZE)
                return PUD_SIZE;
 
-       if (!(base & (PMD_SIZE - 1)) && size >= PMD_SIZE)
+       if (!(pa & (PMD_SIZE - 1)) && !(va & (PMD_SIZE - 1)) && size >= PMD_SIZE)
                return PMD_SIZE;
 
        return PAGE_SIZE;
@@ -1167,14 +1169,16 @@ asmlinkage void __init setup_vm(uintptr_t dtb_pa)
 }
 
 static void __init create_linear_mapping_range(phys_addr_t start,
-                                              phys_addr_t end)
+                                              phys_addr_t end,
+                                              uintptr_t fixed_map_size)
 {
        phys_addr_t pa;
        uintptr_t va, map_size;
 
        for (pa = start; pa < end; pa += map_size) {
                va = (uintptr_t)__va(pa);
-               map_size = best_map_size(pa, end - pa);
+               map_size = fixed_map_size ? fixed_map_size :
+                                           best_map_size(pa, va, end - pa);
 
                create_pgd_mapping(swapper_pg_dir, va, pa, map_size,
                                   pgprot_from_va(va));
@@ -1184,6 +1188,7 @@ static void __init create_linear_mapping_range(phys_addr_t start,
 static void __init create_linear_mapping_page_table(void)
 {
        phys_addr_t start, end;
+       phys_addr_t kfence_pool __maybe_unused;
        u64 i;
 
 #ifdef CONFIG_STRICT_KERNEL_RWX
@@ -1197,6 +1202,19 @@ static void __init create_linear_mapping_page_table(void)
        memblock_mark_nomap(krodata_start, krodata_size);
 #endif
 
+#ifdef CONFIG_KFENCE
+       /*
+        *  kfence pool must be backed by PAGE_SIZE mappings, so allocate it
+        *  before we setup the linear mapping so that we avoid using hugepages
+        *  for this region.
+        */
+       kfence_pool = memblock_phys_alloc(KFENCE_POOL_SIZE, PAGE_SIZE);
+       BUG_ON(!kfence_pool);
+
+       memblock_mark_nomap(kfence_pool, KFENCE_POOL_SIZE);
+       __kfence_pool = __va(kfence_pool);
+#endif
+
        /* Map all memory banks in the linear mapping */
        for_each_mem_range(i, &start, &end) {
                if (start >= end)
@@ -1207,17 +1225,25 @@ static void __init create_linear_mapping_page_table(void)
                if (end >= __pa(PAGE_OFFSET) + memory_limit)
                        end = __pa(PAGE_OFFSET) + memory_limit;
 
-               create_linear_mapping_range(start, end);
+               create_linear_mapping_range(start, end, 0);
        }
 
 #ifdef CONFIG_STRICT_KERNEL_RWX
-       create_linear_mapping_range(ktext_start, ktext_start + ktext_size);
+       create_linear_mapping_range(ktext_start, ktext_start + ktext_size, 0);
        create_linear_mapping_range(krodata_start,
-                                   krodata_start + krodata_size);
+                                   krodata_start + krodata_size, 0);
 
        memblock_clear_nomap(ktext_start,  ktext_size);
        memblock_clear_nomap(krodata_start, krodata_size);
 #endif
+
+#ifdef CONFIG_KFENCE
+       create_linear_mapping_range(kfence_pool,
+                                   kfence_pool + KFENCE_POOL_SIZE,
+                                   PAGE_SIZE);
+
+       memblock_clear_nomap(kfence_pool, KFENCE_POOL_SIZE);
+#endif
 }
 
 static void __init setup_vm_final(void)
index 5730797..bd2e27f 100644 (file)
@@ -35,6 +35,11 @@ CFLAGS_sha256.o := -D__DISABLE_EXPORTS
 CFLAGS_string.o := -D__DISABLE_EXPORTS
 CFLAGS_ctype.o := -D__DISABLE_EXPORTS
 
+# When profile-guided optimization is enabled, llvm emits two different
+# overlapping text sections, which is not supported by kexec. Remove profile
+# optimization flags.
+KBUILD_CFLAGS := $(filter-out -fprofile-sample-use=% -fprofile-use=%,$(KBUILD_CFLAGS))
+
 # When linking purgatory.ro with -r unresolved symbols are not checked,
 # also link a purgatory.chk binary without -r to check for unresolved symbols.
 PURGATORY_LDFLAGS := -e purgatory_start -z nodefaultlib
index 32573b4..cc8cf5a 100644 (file)
@@ -26,6 +26,7 @@ KBUILD_CFLAGS += -Wno-pointer-sign -Wno-sign-compare
 KBUILD_CFLAGS += -fno-zero-initialized-in-bss -fno-builtin -ffreestanding
 KBUILD_CFLAGS += -Os -m64 -msoft-float -fno-common
 KBUILD_CFLAGS += -fno-stack-protector
+KBUILD_CFLAGS += -DDISABLE_BRANCH_PROFILING
 KBUILD_CFLAGS += $(CLANG_FLAGS)
 KBUILD_CFLAGS += $(call cc-option,-fno-PIE)
 KBUILD_AFLAGS := $(filter-out -DCC_USING_EXPOLINE,$(KBUILD_AFLAGS))
index a5df3e9..113c133 100644 (file)
@@ -77,6 +77,15 @@ SYM_CODE_START_NOALIGN(startup_64)
        call    startup_64_setup_env
        popq    %rsi
 
+       /* Now switch to __KERNEL_CS so IRET works reliably */
+       pushq   $__KERNEL_CS
+       leaq    .Lon_kernel_cs(%rip), %rax
+       pushq   %rax
+       lretq
+
+.Lon_kernel_cs:
+       UNWIND_HINT_END_OF_STACK
+
 #ifdef CONFIG_AMD_MEM_ENCRYPT
        /*
         * Activate SEV/SME memory encryption if supported/enabled. This needs to
@@ -90,15 +99,6 @@ SYM_CODE_START_NOALIGN(startup_64)
        popq    %rsi
 #endif
 
-       /* Now switch to __KERNEL_CS so IRET works reliably */
-       pushq   $__KERNEL_CS
-       leaq    .Lon_kernel_cs(%rip), %rax
-       pushq   %rax
-       lretq
-
-.Lon_kernel_cs:
-       UNWIND_HINT_END_OF_STACK
-
        /* Sanitize CPU configuration */
        call verify_cpu
 
index 82fec66..42abd6a 100644 (file)
@@ -14,6 +14,11 @@ $(obj)/sha256.o: $(srctree)/lib/crypto/sha256.c FORCE
 
 CFLAGS_sha256.o := -D__DISABLE_EXPORTS
 
+# When profile-guided optimization is enabled, llvm emits two different
+# overlapping text sections, which is not supported by kexec. Remove profile
+# optimization flags.
+KBUILD_CFLAGS := $(filter-out -fprofile-sample-use=% -fprofile-use=%,$(KBUILD_CFLAGS))
+
 # When linking purgatory.ro with -r unresolved symbols are not checked,
 # also link a purgatory.chk binary without -r to check for unresolved symbols.
 PURGATORY_LDFLAGS := -e purgatory_start -z nodefaultlib
index f6dad08..850bfb8 100644 (file)
@@ -683,6 +683,10 @@ static void __blk_mq_free_request(struct request *rq)
        blk_crypto_free_request(rq);
        blk_pm_mark_last_busy(rq);
        rq->mq_hctx = NULL;
+
+       if (rq->rq_flags & RQF_MQ_INFLIGHT)
+               __blk_mq_dec_active_requests(hctx);
+
        if (rq->tag != BLK_MQ_NO_TAG)
                blk_mq_put_tag(hctx->tags, ctx, rq->tag);
        if (sched_tag != BLK_MQ_NO_TAG)
@@ -694,15 +698,11 @@ static void __blk_mq_free_request(struct request *rq)
 void blk_mq_free_request(struct request *rq)
 {
        struct request_queue *q = rq->q;
-       struct blk_mq_hw_ctx *hctx = rq->mq_hctx;
 
        if ((rq->rq_flags & RQF_ELVPRIV) &&
            q->elevator->type->ops.finish_request)
                q->elevator->type->ops.finish_request(rq);
 
-       if (rq->rq_flags & RQF_MQ_INFLIGHT)
-               __blk_mq_dec_active_requests(hctx);
-
        if (unlikely(laptop_mode && !blk_rq_is_passthrough(rq)))
                laptop_io_completion(q->disk->bdi);
 
index 9bdf168..1a4c4ed 100644 (file)
@@ -7,6 +7,7 @@ config DRM_ACCEL_IVPU
        depends on PCI && PCI_MSI
        select FW_LOADER
        select SHMEM
+       select GENERIC_ALLOCATOR
        help
          Choose this option if you have a system that has an 14th generation Intel CPU
          or newer. VPU stands for Versatile Processing Unit and it's a CPU-integrated
index 382ec12..fef3542 100644 (file)
@@ -197,6 +197,11 @@ static void ivpu_pll_init_frequency_ratios(struct ivpu_device *vdev)
        hw->pll.pn_ratio = clamp_t(u8, fuse_pn_ratio, hw->pll.min_ratio, hw->pll.max_ratio);
 }
 
+static int ivpu_hw_mtl_wait_for_vpuip_bar(struct ivpu_device *vdev)
+{
+       return REGV_POLL_FLD(MTL_VPU_HOST_SS_CPR_RST_CLR, AON, 0, 100);
+}
+
 static int ivpu_pll_drive(struct ivpu_device *vdev, bool enable)
 {
        struct ivpu_hw_info *hw = vdev->hw;
@@ -239,6 +244,12 @@ static int ivpu_pll_drive(struct ivpu_device *vdev, bool enable)
                        ivpu_err(vdev, "Timed out waiting for PLL ready status\n");
                        return ret;
                }
+
+               ret = ivpu_hw_mtl_wait_for_vpuip_bar(vdev);
+               if (ret) {
+                       ivpu_err(vdev, "Timed out waiting for VPUIP bar\n");
+                       return ret;
+               }
        }
 
        return 0;
@@ -256,7 +267,7 @@ static int ivpu_pll_disable(struct ivpu_device *vdev)
 
 static void ivpu_boot_host_ss_rst_clr_assert(struct ivpu_device *vdev)
 {
-       u32 val = REGV_RD32(MTL_VPU_HOST_SS_CPR_RST_CLR);
+       u32 val = 0;
 
        val = REG_SET_FLD(MTL_VPU_HOST_SS_CPR_RST_CLR, TOP_NOC, val);
        val = REG_SET_FLD(MTL_VPU_HOST_SS_CPR_RST_CLR, DSS_MAS, val);
@@ -754,9 +765,8 @@ static int ivpu_hw_mtl_power_down(struct ivpu_device *vdev)
 {
        int ret = 0;
 
-       if (ivpu_hw_mtl_reset(vdev)) {
+       if (!ivpu_hw_mtl_is_idle(vdev) && ivpu_hw_mtl_reset(vdev)) {
                ivpu_err(vdev, "Failed to reset the VPU\n");
-               ret = -EIO;
        }
 
        if (ivpu_pll_disable(vdev)) {
@@ -764,8 +774,10 @@ static int ivpu_hw_mtl_power_down(struct ivpu_device *vdev)
                ret = -EIO;
        }
 
-       if (ivpu_hw_mtl_d0i3_enable(vdev))
-               ivpu_warn(vdev, "Failed to enable D0I3\n");
+       if (ivpu_hw_mtl_d0i3_enable(vdev)) {
+               ivpu_err(vdev, "Failed to enter D0I3\n");
+               ret = -EIO;
+       }
 
        return ret;
 }
index d83ccfd..593b8ff 100644 (file)
@@ -91,6 +91,7 @@
 #define MTL_VPU_HOST_SS_CPR_RST_SET_MSS_MAS_MASK                       BIT_MASK(11)
 
 #define MTL_VPU_HOST_SS_CPR_RST_CLR                                    0x00000098u
+#define MTL_VPU_HOST_SS_CPR_RST_CLR_AON_MASK                           BIT_MASK(0)
 #define MTL_VPU_HOST_SS_CPR_RST_CLR_TOP_NOC_MASK                       BIT_MASK(1)
 #define MTL_VPU_HOST_SS_CPR_RST_CLR_DSS_MAS_MASK                       BIT_MASK(10)
 #define MTL_VPU_HOST_SS_CPR_RST_CLR_MSS_MAS_MASK                       BIT_MASK(11)
index 3adcfa8..fa0af59 100644 (file)
@@ -183,9 +183,7 @@ ivpu_ipc_send(struct ivpu_device *vdev, struct ivpu_ipc_consumer *cons, struct v
        struct ivpu_ipc_info *ipc = vdev->ipc;
        int ret;
 
-       ret = mutex_lock_interruptible(&ipc->lock);
-       if (ret)
-               return ret;
+       mutex_lock(&ipc->lock);
 
        if (!ipc->on) {
                ret = -EAGAIN;
index 3c6f1e1..d45be06 100644 (file)
@@ -431,6 +431,7 @@ ivpu_job_prepare_bos_for_submit(struct drm_file *file, struct ivpu_job *job, u32
        struct ivpu_file_priv *file_priv = file->driver_priv;
        struct ivpu_device *vdev = file_priv->vdev;
        struct ww_acquire_ctx acquire_ctx;
+       enum dma_resv_usage usage;
        struct ivpu_bo *bo;
        int ret;
        u32 i;
@@ -461,22 +462,28 @@ ivpu_job_prepare_bos_for_submit(struct drm_file *file, struct ivpu_job *job, u32
 
        job->cmd_buf_vpu_addr = bo->vpu_addr + commands_offset;
 
-       ret = drm_gem_lock_reservations((struct drm_gem_object **)job->bos, 1, &acquire_ctx);
+       ret = drm_gem_lock_reservations((struct drm_gem_object **)job->bos, buf_count,
+                                       &acquire_ctx);
        if (ret) {
                ivpu_warn(vdev, "Failed to lock reservations: %d\n", ret);
                return ret;
        }
 
-       ret = dma_resv_reserve_fences(bo->base.resv, 1);
-       if (ret) {
-               ivpu_warn(vdev, "Failed to reserve fences: %d\n", ret);
-               goto unlock_reservations;
+       for (i = 0; i < buf_count; i++) {
+               ret = dma_resv_reserve_fences(job->bos[i]->base.resv, 1);
+               if (ret) {
+                       ivpu_warn(vdev, "Failed to reserve fences: %d\n", ret);
+                       goto unlock_reservations;
+               }
        }
 
-       dma_resv_add_fence(bo->base.resv, job->done_fence, DMA_RESV_USAGE_WRITE);
+       for (i = 0; i < buf_count; i++) {
+               usage = (i == CMD_BUF_IDX) ? DMA_RESV_USAGE_WRITE : DMA_RESV_USAGE_BOOKKEEP;
+               dma_resv_add_fence(job->bos[i]->base.resv, job->done_fence, usage);
+       }
 
 unlock_reservations:
-       drm_gem_unlock_reservations((struct drm_gem_object **)job->bos, 1, &acquire_ctx);
+       drm_gem_unlock_reservations((struct drm_gem_object **)job->bos, buf_count, &acquire_ctx);
 
        wmb(); /* Flush write combining buffers */
 
index 694e978..b8b259b 100644 (file)
@@ -587,16 +587,11 @@ static int ivpu_mmu_strtab_init(struct ivpu_device *vdev)
 int ivpu_mmu_invalidate_tlb(struct ivpu_device *vdev, u16 ssid)
 {
        struct ivpu_mmu_info *mmu = vdev->mmu;
-       int ret;
-
-       ret = mutex_lock_interruptible(&mmu->lock);
-       if (ret)
-               return ret;
+       int ret = 0;
 
-       if (!mmu->on) {
-               ret = 0;
+       mutex_lock(&mmu->lock);
+       if (!mmu->on)
                goto unlock;
-       }
 
        ret = ivpu_mmu_cmdq_write_tlbi_nh_asid(vdev, ssid);
        if (ret)
@@ -614,7 +609,7 @@ static int ivpu_mmu_cd_add(struct ivpu_device *vdev, u32 ssid, u64 cd_dma)
        struct ivpu_mmu_cdtab *cdtab = &mmu->cdtab;
        u64 *entry;
        u64 cd[4];
-       int ret;
+       int ret = 0;
 
        if (ssid > IVPU_MMU_CDTAB_ENT_COUNT)
                return -EINVAL;
@@ -655,14 +650,9 @@ static int ivpu_mmu_cd_add(struct ivpu_device *vdev, u32 ssid, u64 cd_dma)
        ivpu_dbg(vdev, MMU, "CDTAB %s entry (SSID=%u, dma=%pad): 0x%llx, 0x%llx, 0x%llx, 0x%llx\n",
                 cd_dma ? "write" : "clear", ssid, &cd_dma, cd[0], cd[1], cd[2], cd[3]);
 
-       ret = mutex_lock_interruptible(&mmu->lock);
-       if (ret)
-               return ret;
-
-       if (!mmu->on) {
-               ret = 0;
+       mutex_lock(&mmu->lock);
+       if (!mmu->on)
                goto unlock;
-       }
 
        ret = ivpu_mmu_cmdq_write_cfgi_all(vdev);
        if (ret)
index 0295646..97c681f 100644 (file)
@@ -284,6 +284,9 @@ static bool regcache_reg_needs_sync(struct regmap *map, unsigned int reg,
 {
        int ret;
 
+       if (!regmap_writeable(map, reg))
+               return false;
+
        /* If we don't know the chip just got reset, then sync everything. */
        if (!map->no_sync_defaults)
                return true;
index b3fedaf..8640130 100644 (file)
@@ -2244,6 +2244,7 @@ static void null_destroy_dev(struct nullb *nullb)
        struct nullb_device *dev = nullb->dev;
 
        null_del_dev(nullb);
+       null_free_device_storage(dev, false);
        null_free_dev(dev);
 }
 
index 84ad3b1..632751d 100644 (file)
@@ -1334,14 +1334,30 @@ static bool rbd_obj_is_tail(struct rbd_obj_request *obj_req)
 /*
  * Must be called after rbd_obj_calc_img_extents().
  */
-static bool rbd_obj_copyup_enabled(struct rbd_obj_request *obj_req)
+static void rbd_obj_set_copyup_enabled(struct rbd_obj_request *obj_req)
 {
-       if (!obj_req->num_img_extents ||
-           (rbd_obj_is_entire(obj_req) &&
-            !obj_req->img_request->snapc->num_snaps))
-               return false;
+       rbd_assert(obj_req->img_request->snapc);
 
-       return true;
+       if (obj_req->img_request->op_type == OBJ_OP_DISCARD) {
+               dout("%s %p objno %llu discard\n", __func__, obj_req,
+                    obj_req->ex.oe_objno);
+               return;
+       }
+
+       if (!obj_req->num_img_extents) {
+               dout("%s %p objno %llu not overlapping\n", __func__, obj_req,
+                    obj_req->ex.oe_objno);
+               return;
+       }
+
+       if (rbd_obj_is_entire(obj_req) &&
+           !obj_req->img_request->snapc->num_snaps) {
+               dout("%s %p objno %llu entire\n", __func__, obj_req,
+                    obj_req->ex.oe_objno);
+               return;
+       }
+
+       obj_req->flags |= RBD_OBJ_FLAG_COPYUP_ENABLED;
 }
 
 static u64 rbd_obj_img_extents_bytes(struct rbd_obj_request *obj_req)
@@ -1442,6 +1458,7 @@ __rbd_obj_add_osd_request(struct rbd_obj_request *obj_req,
 static struct ceph_osd_request *
 rbd_obj_add_osd_request(struct rbd_obj_request *obj_req, int num_ops)
 {
+       rbd_assert(obj_req->img_request->snapc);
        return __rbd_obj_add_osd_request(obj_req, obj_req->img_request->snapc,
                                         num_ops);
 }
@@ -1578,15 +1595,18 @@ static void rbd_img_request_init(struct rbd_img_request *img_request,
        mutex_init(&img_request->state_mutex);
 }
 
+/*
+ * Only snap_id is captured here, for reads.  For writes, snapshot
+ * context is captured in rbd_img_object_requests() after exclusive
+ * lock is ensured to be held.
+ */
 static void rbd_img_capture_header(struct rbd_img_request *img_req)
 {
        struct rbd_device *rbd_dev = img_req->rbd_dev;
 
        lockdep_assert_held(&rbd_dev->header_rwsem);
 
-       if (rbd_img_is_write(img_req))
-               img_req->snapc = ceph_get_snap_context(rbd_dev->header.snapc);
-       else
+       if (!rbd_img_is_write(img_req))
                img_req->snap_id = rbd_dev->spec->snap_id;
 
        if (rbd_dev_parent_get(rbd_dev))
@@ -2233,9 +2253,6 @@ static int rbd_obj_init_write(struct rbd_obj_request *obj_req)
        if (ret)
                return ret;
 
-       if (rbd_obj_copyup_enabled(obj_req))
-               obj_req->flags |= RBD_OBJ_FLAG_COPYUP_ENABLED;
-
        obj_req->write_state = RBD_OBJ_WRITE_START;
        return 0;
 }
@@ -2341,8 +2358,6 @@ static int rbd_obj_init_zeroout(struct rbd_obj_request *obj_req)
        if (ret)
                return ret;
 
-       if (rbd_obj_copyup_enabled(obj_req))
-               obj_req->flags |= RBD_OBJ_FLAG_COPYUP_ENABLED;
        if (!obj_req->num_img_extents) {
                obj_req->flags |= RBD_OBJ_FLAG_NOOP_FOR_NONEXISTENT;
                if (rbd_obj_is_entire(obj_req))
@@ -3286,6 +3301,7 @@ again:
        case RBD_OBJ_WRITE_START:
                rbd_assert(!*result);
 
+               rbd_obj_set_copyup_enabled(obj_req);
                if (rbd_obj_write_is_noop(obj_req))
                        return true;
 
@@ -3472,9 +3488,19 @@ static int rbd_img_exclusive_lock(struct rbd_img_request *img_req)
 
 static void rbd_img_object_requests(struct rbd_img_request *img_req)
 {
+       struct rbd_device *rbd_dev = img_req->rbd_dev;
        struct rbd_obj_request *obj_req;
 
        rbd_assert(!img_req->pending.result && !img_req->pending.num_pending);
+       rbd_assert(!need_exclusive_lock(img_req) ||
+                  __rbd_is_lock_owner(rbd_dev));
+
+       if (rbd_img_is_write(img_req)) {
+               rbd_assert(!img_req->snapc);
+               down_read(&rbd_dev->header_rwsem);
+               img_req->snapc = ceph_get_snap_context(rbd_dev->header.snapc);
+               up_read(&rbd_dev->header_rwsem);
+       }
 
        for_each_obj_request(img_req, obj_req) {
                int result = 0;
@@ -3492,7 +3518,6 @@ static void rbd_img_object_requests(struct rbd_img_request *img_req)
 
 static bool rbd_img_advance(struct rbd_img_request *img_req, int *result)
 {
-       struct rbd_device *rbd_dev = img_req->rbd_dev;
        int ret;
 
 again:
@@ -3513,9 +3538,6 @@ again:
                if (*result)
                        return true;
 
-               rbd_assert(!need_exclusive_lock(img_req) ||
-                          __rbd_is_lock_owner(rbd_dev));
-
                rbd_img_object_requests(img_req);
                if (!img_req->pending.num_pending) {
                        *result = img_req->pending.result;
@@ -3977,6 +3999,10 @@ static int rbd_post_acquire_action(struct rbd_device *rbd_dev)
 {
        int ret;
 
+       ret = rbd_dev_refresh(rbd_dev);
+       if (ret)
+               return ret;
+
        if (rbd_dev->header.features & RBD_FEATURE_OBJECT_MAP) {
                ret = rbd_object_map_open(rbd_dev);
                if (ret)
index 265e0fb..b2db545 100644 (file)
 #define TRP_SYN_REG_CNT                 6
 #define DRP_SYN_REG_CNT                 8
 
-#define LLCC_COMMON_STATUS0             0x0003000c
 #define LLCC_LB_CNT_MASK                GENMASK(31, 28)
 #define LLCC_LB_CNT_SHIFT               28
 
-/* Single & double bit syndrome register offsets */
-#define TRP_ECC_SB_ERR_SYN0             0x0002304c
-#define TRP_ECC_DB_ERR_SYN0             0x00020370
-#define DRP_ECC_SB_ERR_SYN0             0x0004204c
-#define DRP_ECC_DB_ERR_SYN0             0x00042070
-
-/* Error register offsets */
-#define TRP_ECC_ERROR_STATUS1           0x00020348
-#define TRP_ECC_ERROR_STATUS0           0x00020344
-#define DRP_ECC_ERROR_STATUS1           0x00042048
-#define DRP_ECC_ERROR_STATUS0           0x00042044
-
-/* TRP, DRP interrupt register offsets */
-#define DRP_INTERRUPT_STATUS            0x00041000
-#define TRP_INTERRUPT_0_STATUS          0x00020480
-#define DRP_INTERRUPT_CLEAR             0x00041008
-#define DRP_ECC_ERROR_CNTR_CLEAR        0x00040004
-#define TRP_INTERRUPT_0_CLEAR           0x00020484
-#define TRP_ECC_ERROR_CNTR_CLEAR        0x00020440
-
 /* Mask and shift macros */
 #define ECC_DB_ERR_COUNT_MASK           GENMASK(4, 0)
 #define ECC_DB_ERR_WAYS_MASK            GENMASK(31, 16)
 #define DRP_TRP_INT_CLEAR               GENMASK(1, 0)
 #define DRP_TRP_CNT_CLEAR               GENMASK(1, 0)
 
-/* Config registers offsets*/
-#define DRP_ECC_ERROR_CFG               0x00040000
-
-/* Tag RAM, Data RAM interrupt register offsets */
-#define CMN_INTERRUPT_0_ENABLE          0x0003001c
-#define CMN_INTERRUPT_2_ENABLE          0x0003003c
-#define TRP_INTERRUPT_0_ENABLE          0x00020488
-#define DRP_INTERRUPT_ENABLE            0x0004100c
-
 #define SB_ERROR_THRESHOLD              0x1
 #define SB_ERROR_THRESHOLD_SHIFT        24
 #define SB_DB_TRP_INTERRUPT_ENABLE      0x3
@@ -88,9 +58,6 @@ enum {
 static const struct llcc_edac_reg_data edac_reg_data[] = {
        [LLCC_DRAM_CE] = {
                .name = "DRAM Single-bit",
-               .synd_reg = DRP_ECC_SB_ERR_SYN0,
-               .count_status_reg = DRP_ECC_ERROR_STATUS1,
-               .ways_status_reg = DRP_ECC_ERROR_STATUS0,
                .reg_cnt = DRP_SYN_REG_CNT,
                .count_mask = ECC_SB_ERR_COUNT_MASK,
                .ways_mask = ECC_SB_ERR_WAYS_MASK,
@@ -98,9 +65,6 @@ static const struct llcc_edac_reg_data edac_reg_data[] = {
        },
        [LLCC_DRAM_UE] = {
                .name = "DRAM Double-bit",
-               .synd_reg = DRP_ECC_DB_ERR_SYN0,
-               .count_status_reg = DRP_ECC_ERROR_STATUS1,
-               .ways_status_reg = DRP_ECC_ERROR_STATUS0,
                .reg_cnt = DRP_SYN_REG_CNT,
                .count_mask = ECC_DB_ERR_COUNT_MASK,
                .ways_mask = ECC_DB_ERR_WAYS_MASK,
@@ -108,9 +72,6 @@ static const struct llcc_edac_reg_data edac_reg_data[] = {
        },
        [LLCC_TRAM_CE] = {
                .name = "TRAM Single-bit",
-               .synd_reg = TRP_ECC_SB_ERR_SYN0,
-               .count_status_reg = TRP_ECC_ERROR_STATUS1,
-               .ways_status_reg = TRP_ECC_ERROR_STATUS0,
                .reg_cnt = TRP_SYN_REG_CNT,
                .count_mask = ECC_SB_ERR_COUNT_MASK,
                .ways_mask = ECC_SB_ERR_WAYS_MASK,
@@ -118,9 +79,6 @@ static const struct llcc_edac_reg_data edac_reg_data[] = {
        },
        [LLCC_TRAM_UE] = {
                .name = "TRAM Double-bit",
-               .synd_reg = TRP_ECC_DB_ERR_SYN0,
-               .count_status_reg = TRP_ECC_ERROR_STATUS1,
-               .ways_status_reg = TRP_ECC_ERROR_STATUS0,
                .reg_cnt = TRP_SYN_REG_CNT,
                .count_mask = ECC_DB_ERR_COUNT_MASK,
                .ways_mask = ECC_DB_ERR_WAYS_MASK,
@@ -128,7 +86,7 @@ static const struct llcc_edac_reg_data edac_reg_data[] = {
        },
 };
 
-static int qcom_llcc_core_setup(struct regmap *llcc_bcast_regmap)
+static int qcom_llcc_core_setup(struct llcc_drv_data *drv, struct regmap *llcc_bcast_regmap)
 {
        u32 sb_err_threshold;
        int ret;
@@ -137,31 +95,31 @@ static int qcom_llcc_core_setup(struct regmap *llcc_bcast_regmap)
         * Configure interrupt enable registers such that Tag, Data RAM related
         * interrupts are propagated to interrupt controller for servicing
         */
-       ret = regmap_update_bits(llcc_bcast_regmap, CMN_INTERRUPT_2_ENABLE,
+       ret = regmap_update_bits(llcc_bcast_regmap, drv->edac_reg_offset->cmn_interrupt_2_enable,
                                 TRP0_INTERRUPT_ENABLE,
                                 TRP0_INTERRUPT_ENABLE);
        if (ret)
                return ret;
 
-       ret = regmap_update_bits(llcc_bcast_regmap, TRP_INTERRUPT_0_ENABLE,
+       ret = regmap_update_bits(llcc_bcast_regmap, drv->edac_reg_offset->trp_interrupt_0_enable,
                                 SB_DB_TRP_INTERRUPT_ENABLE,
                                 SB_DB_TRP_INTERRUPT_ENABLE);
        if (ret)
                return ret;
 
        sb_err_threshold = (SB_ERROR_THRESHOLD << SB_ERROR_THRESHOLD_SHIFT);
-       ret = regmap_write(llcc_bcast_regmap, DRP_ECC_ERROR_CFG,
+       ret = regmap_write(llcc_bcast_regmap, drv->edac_reg_offset->drp_ecc_error_cfg,
                           sb_err_threshold);
        if (ret)
                return ret;
 
-       ret = regmap_update_bits(llcc_bcast_regmap, CMN_INTERRUPT_2_ENABLE,
+       ret = regmap_update_bits(llcc_bcast_regmap, drv->edac_reg_offset->cmn_interrupt_2_enable,
                                 DRP0_INTERRUPT_ENABLE,
                                 DRP0_INTERRUPT_ENABLE);
        if (ret)
                return ret;
 
-       ret = regmap_write(llcc_bcast_regmap, DRP_INTERRUPT_ENABLE,
+       ret = regmap_write(llcc_bcast_regmap, drv->edac_reg_offset->drp_interrupt_enable,
                           SB_DB_DRP_INTERRUPT_ENABLE);
        return ret;
 }
@@ -170,29 +128,33 @@ static int qcom_llcc_core_setup(struct regmap *llcc_bcast_regmap)
 static int
 qcom_llcc_clear_error_status(int err_type, struct llcc_drv_data *drv)
 {
-       int ret = 0;
+       int ret;
 
        switch (err_type) {
        case LLCC_DRAM_CE:
        case LLCC_DRAM_UE:
-               ret = regmap_write(drv->bcast_regmap, DRP_INTERRUPT_CLEAR,
+               ret = regmap_write(drv->bcast_regmap,
+                                  drv->edac_reg_offset->drp_interrupt_clear,
                                   DRP_TRP_INT_CLEAR);
                if (ret)
                        return ret;
 
-               ret = regmap_write(drv->bcast_regmap, DRP_ECC_ERROR_CNTR_CLEAR,
+               ret = regmap_write(drv->bcast_regmap,
+                                  drv->edac_reg_offset->drp_ecc_error_cntr_clear,
                                   DRP_TRP_CNT_CLEAR);
                if (ret)
                        return ret;
                break;
        case LLCC_TRAM_CE:
        case LLCC_TRAM_UE:
-               ret = regmap_write(drv->bcast_regmap, TRP_INTERRUPT_0_CLEAR,
+               ret = regmap_write(drv->bcast_regmap,
+                                  drv->edac_reg_offset->trp_interrupt_0_clear,
                                   DRP_TRP_INT_CLEAR);
                if (ret)
                        return ret;
 
-               ret = regmap_write(drv->bcast_regmap, TRP_ECC_ERROR_CNTR_CLEAR,
+               ret = regmap_write(drv->bcast_regmap,
+                                  drv->edac_reg_offset->trp_ecc_error_cntr_clear,
                                   DRP_TRP_CNT_CLEAR);
                if (ret)
                        return ret;
@@ -205,16 +167,54 @@ qcom_llcc_clear_error_status(int err_type, struct llcc_drv_data *drv)
        return ret;
 }
 
+struct qcom_llcc_syn_regs {
+       u32 synd_reg;
+       u32 count_status_reg;
+       u32 ways_status_reg;
+};
+
+static void get_reg_offsets(struct llcc_drv_data *drv, int err_type,
+                           struct qcom_llcc_syn_regs *syn_regs)
+{
+       const struct llcc_edac_reg_offset *edac_reg_offset = drv->edac_reg_offset;
+
+       switch (err_type) {
+       case LLCC_DRAM_CE:
+               syn_regs->synd_reg = edac_reg_offset->drp_ecc_sb_err_syn0;
+               syn_regs->count_status_reg = edac_reg_offset->drp_ecc_error_status1;
+               syn_regs->ways_status_reg = edac_reg_offset->drp_ecc_error_status0;
+               break;
+       case LLCC_DRAM_UE:
+               syn_regs->synd_reg = edac_reg_offset->drp_ecc_db_err_syn0;
+               syn_regs->count_status_reg = edac_reg_offset->drp_ecc_error_status1;
+               syn_regs->ways_status_reg = edac_reg_offset->drp_ecc_error_status0;
+               break;
+       case LLCC_TRAM_CE:
+               syn_regs->synd_reg = edac_reg_offset->trp_ecc_sb_err_syn0;
+               syn_regs->count_status_reg = edac_reg_offset->trp_ecc_error_status1;
+               syn_regs->ways_status_reg = edac_reg_offset->trp_ecc_error_status0;
+               break;
+       case LLCC_TRAM_UE:
+               syn_regs->synd_reg = edac_reg_offset->trp_ecc_db_err_syn0;
+               syn_regs->count_status_reg = edac_reg_offset->trp_ecc_error_status1;
+               syn_regs->ways_status_reg = edac_reg_offset->trp_ecc_error_status0;
+               break;
+       }
+}
+
 /* Dump Syndrome registers data for Tag RAM, Data RAM bit errors*/
 static int
 dump_syn_reg_values(struct llcc_drv_data *drv, u32 bank, int err_type)
 {
        struct llcc_edac_reg_data reg_data = edac_reg_data[err_type];
+       struct qcom_llcc_syn_regs regs = { };
        int err_cnt, err_ways, ret, i;
        u32 synd_reg, synd_val;
 
+       get_reg_offsets(drv, err_type, &regs);
+
        for (i = 0; i < reg_data.reg_cnt; i++) {
-               synd_reg = reg_data.synd_reg + (i * 4);
+               synd_reg = regs.synd_reg + (i * 4);
                ret = regmap_read(drv->regmaps[bank], synd_reg,
                                  &synd_val);
                if (ret)
@@ -224,7 +224,7 @@ dump_syn_reg_values(struct llcc_drv_data *drv, u32 bank, int err_type)
                            reg_data.name, i, synd_val);
        }
 
-       ret = regmap_read(drv->regmaps[bank], reg_data.count_status_reg,
+       ret = regmap_read(drv->regmaps[bank], regs.count_status_reg,
                          &err_cnt);
        if (ret)
                goto clear;
@@ -234,7 +234,7 @@ dump_syn_reg_values(struct llcc_drv_data *drv, u32 bank, int err_type)
        edac_printk(KERN_CRIT, EDAC_LLCC, "%s: Error count: 0x%4x\n",
                    reg_data.name, err_cnt);
 
-       ret = regmap_read(drv->regmaps[bank], reg_data.ways_status_reg,
+       ret = regmap_read(drv->regmaps[bank], regs.ways_status_reg,
                          &err_ways);
        if (ret)
                goto clear;
@@ -295,7 +295,7 @@ static irqreturn_t llcc_ecc_irq_handler(int irq, void *edev_ctl)
 
        /* Iterate over the banks and look for Tag RAM or Data RAM errors */
        for (i = 0; i < drv->num_banks; i++) {
-               ret = regmap_read(drv->regmaps[i], DRP_INTERRUPT_STATUS,
+               ret = regmap_read(drv->regmaps[i], drv->edac_reg_offset->drp_interrupt_status,
                                  &drp_error);
 
                if (!ret && (drp_error & SB_ECC_ERROR)) {
@@ -310,7 +310,7 @@ static irqreturn_t llcc_ecc_irq_handler(int irq, void *edev_ctl)
                if (!ret)
                        irq_rc = IRQ_HANDLED;
 
-               ret = regmap_read(drv->regmaps[i], TRP_INTERRUPT_0_STATUS,
+               ret = regmap_read(drv->regmaps[i], drv->edac_reg_offset->trp_interrupt_0_status,
                                  &trp_error);
 
                if (!ret && (trp_error & SB_ECC_ERROR)) {
@@ -342,7 +342,7 @@ static int qcom_llcc_edac_probe(struct platform_device *pdev)
        int ecc_irq;
        int rc;
 
-       rc = qcom_llcc_core_setup(llcc_driv_data->bcast_regmap);
+       rc = qcom_llcc_core_setup(llcc_driv_data, llcc_driv_data->bcast_regmap);
        if (rc)
                return rc;
 
index e234091..2109cd1 100644 (file)
@@ -424,6 +424,7 @@ ffa_setup_and_transmit(u32 func_id, void *buffer, u32 max_fragsize,
                ep_mem_access->flag = 0;
                ep_mem_access->reserved = 0;
        }
+       mem_region->handle = 0;
        mem_region->reserved_0 = 0;
        mem_region->reserved_1 = 0;
        mem_region->ep_count = args->nattrs;
index a1c8702..8b49b0a 100644 (file)
@@ -696,6 +696,9 @@ static char **gpio_sim_make_line_names(struct gpio_sim_bank *bank,
        char **line_names;
 
        list_for_each_entry(line, &bank->line_list, siblings) {
+               if (line->offset >= bank->num_lines)
+                       continue;
+
                if (line->name) {
                        if (line->offset > max_offset)
                                max_offset = line->offset;
@@ -721,8 +724,13 @@ static char **gpio_sim_make_line_names(struct gpio_sim_bank *bank,
        if (!line_names)
                return ERR_PTR(-ENOMEM);
 
-       list_for_each_entry(line, &bank->line_list, siblings)
-               line_names[line->offset] = line->name;
+       list_for_each_entry(line, &bank->line_list, siblings) {
+               if (line->offset >= bank->num_lines)
+                       continue;
+
+               if (line->name && (line->offset <= max_offset))
+                       line_names[line->offset] = line->name;
+       }
 
        return line_names;
 }
@@ -754,6 +762,9 @@ static int gpio_sim_add_hogs(struct gpio_sim_device *dev)
 
        list_for_each_entry(bank, &dev->bank_list, siblings) {
                list_for_each_entry(line, &bank->line_list, siblings) {
+                       if (line->offset >= bank->num_lines)
+                               continue;
+
                        if (line->hog)
                                num_hogs++;
                }
@@ -769,6 +780,9 @@ static int gpio_sim_add_hogs(struct gpio_sim_device *dev)
 
        list_for_each_entry(bank, &dev->bank_list, siblings) {
                list_for_each_entry(line, &bank->line_list, siblings) {
+                       if (line->offset >= bank->num_lines)
+                               continue;
+
                        if (!line->hog)
                                continue;
 
index aeeec21..fd6e837 100644 (file)
@@ -1092,16 +1092,20 @@ bool amdgpu_acpi_is_s0ix_active(struct amdgpu_device *adev)
         * S0ix even though the system is suspending to idle, so return false
         * in that case.
         */
-       if (!(acpi_gbl_FADT.flags & ACPI_FADT_LOW_POWER_S0))
-               dev_warn_once(adev->dev,
+       if (!(acpi_gbl_FADT.flags & ACPI_FADT_LOW_POWER_S0)) {
+               dev_err_once(adev->dev,
                              "Power consumption will be higher as BIOS has not been configured for suspend-to-idle.\n"
                              "To use suspend-to-idle change the sleep mode in BIOS setup.\n");
+               return false;
+       }
 
 #if !IS_ENABLED(CONFIG_AMD_PMC)
-       dev_warn_once(adev->dev,
+       dev_err_once(adev->dev,
                      "Power consumption will be higher as the kernel has not been compiled with CONFIG_AMD_PMC.\n");
-#endif /* CONFIG_AMD_PMC */
+       return false;
+#else
        return true;
+#endif /* CONFIG_AMD_PMC */
 }
 
 #endif /* CONFIG_SUSPEND */
index 2bd1a54..3b225be 100644 (file)
@@ -79,9 +79,10 @@ static void amdgpu_bo_user_destroy(struct ttm_buffer_object *tbo)
 static void amdgpu_bo_vm_destroy(struct ttm_buffer_object *tbo)
 {
        struct amdgpu_device *adev = amdgpu_ttm_adev(tbo->bdev);
-       struct amdgpu_bo *bo = ttm_to_amdgpu_bo(tbo);
+       struct amdgpu_bo *shadow_bo = ttm_to_amdgpu_bo(tbo), *bo;
        struct amdgpu_bo_vm *vmbo;
 
+       bo = shadow_bo->parent;
        vmbo = to_amdgpu_bo_vm(bo);
        /* in case amdgpu_device_recover_vram got NULL of bo->parent */
        if (!list_empty(&vmbo->shadow_list)) {
@@ -694,11 +695,6 @@ int amdgpu_bo_create_vm(struct amdgpu_device *adev,
                return r;
 
        *vmbo_ptr = to_amdgpu_bo_vm(bo_ptr);
-       INIT_LIST_HEAD(&(*vmbo_ptr)->shadow_list);
-       /* Set destroy callback to amdgpu_bo_vm_destroy after vmbo->shadow_list
-        * is initialized.
-        */
-       bo_ptr->tbo.destroy = &amdgpu_bo_vm_destroy;
        return r;
 }
 
@@ -715,6 +711,8 @@ void amdgpu_bo_add_to_shadow_list(struct amdgpu_bo_vm *vmbo)
 
        mutex_lock(&adev->shadow_list_lock);
        list_add_tail(&vmbo->shadow_list, &adev->shadow_list);
+       vmbo->shadow->parent = amdgpu_bo_ref(&vmbo->bo);
+       vmbo->shadow->tbo.destroy = &amdgpu_bo_vm_destroy;
        mutex_unlock(&adev->shadow_list_lock);
 }
 
index df63dc3..051c719 100644 (file)
@@ -564,7 +564,6 @@ int amdgpu_vm_pt_create(struct amdgpu_device *adev, struct amdgpu_vm *vm,
                return r;
        }
 
-       (*vmbo)->shadow->parent = amdgpu_bo_ref(bo);
        amdgpu_bo_add_to_shadow_list(*vmbo);
 
        return 0;
index 43d6a9d..afacfb9 100644 (file)
@@ -800,7 +800,7 @@ static void amdgpu_vram_mgr_debug(struct ttm_resource_manager *man,
 {
        struct amdgpu_vram_mgr *mgr = to_vram_mgr(man);
        struct drm_buddy *mm = &mgr->mm;
-       struct drm_buddy_block *block;
+       struct amdgpu_vram_reservation *rsv;
 
        drm_printf(printer, "  vis usage:%llu\n",
                   amdgpu_vram_mgr_vis_usage(mgr));
@@ -812,8 +812,9 @@ static void amdgpu_vram_mgr_debug(struct ttm_resource_manager *man,
        drm_buddy_print(mm, printer);
 
        drm_printf(printer, "reserved:\n");
-       list_for_each_entry(block, &mgr->reserved_pages, link)
-               drm_buddy_block_print(mm, block, printer);
+       list_for_each_entry(rsv, &mgr->reserved_pages, blocks)
+               drm_printf(printer, "%#018llx-%#018llx: %llu\n",
+                       rsv->start, rsv->start + rsv->size, rsv->size);
        mutex_unlock(&mgr->lock);
 }
 
index ce22f7b..e7f2b7b 100644 (file)
@@ -149,16 +149,6 @@ MODULE_FIRMWARE("amdgpu/aldebaran_sjt_mec2.bin");
 #define mmGOLDEN_TSC_COUNT_LOWER_Renoir                0x0026
 #define mmGOLDEN_TSC_COUNT_LOWER_Renoir_BASE_IDX       1
 
-#define mmGOLDEN_TSC_COUNT_UPPER_Raven   0x007a
-#define mmGOLDEN_TSC_COUNT_UPPER_Raven_BASE_IDX 0
-#define mmGOLDEN_TSC_COUNT_LOWER_Raven   0x007b
-#define mmGOLDEN_TSC_COUNT_LOWER_Raven_BASE_IDX 0
-
-#define mmGOLDEN_TSC_COUNT_UPPER_Raven2   0x0068
-#define mmGOLDEN_TSC_COUNT_UPPER_Raven2_BASE_IDX 0
-#define mmGOLDEN_TSC_COUNT_LOWER_Raven2   0x0069
-#define mmGOLDEN_TSC_COUNT_LOWER_Raven2_BASE_IDX 0
-
 enum ta_ras_gfx_subblock {
        /*CPC*/
        TA_RAS_BLOCK__GFX_CPC_INDEX_START = 0,
@@ -4004,31 +3994,6 @@ static uint64_t gfx_v9_0_get_gpu_clock_counter(struct amdgpu_device *adev)
                preempt_enable();
                clock = clock_lo | (clock_hi << 32ULL);
                break;
-       case IP_VERSION(9, 1, 0):
-       case IP_VERSION(9, 2, 2):
-               preempt_disable();
-               if (adev->rev_id >= 0x8) {
-                       clock_hi = RREG32_SOC15_NO_KIQ(PWR, 0, mmGOLDEN_TSC_COUNT_UPPER_Raven2);
-                       clock_lo = RREG32_SOC15_NO_KIQ(PWR, 0, mmGOLDEN_TSC_COUNT_LOWER_Raven2);
-                       hi_check = RREG32_SOC15_NO_KIQ(PWR, 0, mmGOLDEN_TSC_COUNT_UPPER_Raven2);
-               } else {
-                       clock_hi = RREG32_SOC15_NO_KIQ(PWR, 0, mmGOLDEN_TSC_COUNT_UPPER_Raven);
-                       clock_lo = RREG32_SOC15_NO_KIQ(PWR, 0, mmGOLDEN_TSC_COUNT_LOWER_Raven);
-                       hi_check = RREG32_SOC15_NO_KIQ(PWR, 0, mmGOLDEN_TSC_COUNT_UPPER_Raven);
-               }
-               /* The PWR TSC clock frequency is 100MHz, which sets 32-bit carry over
-               * roughly every 42 seconds.
-               */
-               if (hi_check != clock_hi) {
-                       if (adev->rev_id >= 0x8)
-                               clock_lo = RREG32_SOC15_NO_KIQ(PWR, 0, mmGOLDEN_TSC_COUNT_LOWER_Raven2);
-                       else
-                               clock_lo = RREG32_SOC15_NO_KIQ(PWR, 0, mmGOLDEN_TSC_COUNT_LOWER_Raven);
-                       clock_hi = hi_check;
-               }
-               preempt_enable();
-               clock = clock_lo | (clock_hi << 32ULL);
-               break;
        default:
                amdgpu_gfx_off_ctrl(adev, false);
                mutex_lock(&adev->gfx.gpu_clock_mutex);
index 6d15d5c..a2fd1ff 100644 (file)
@@ -301,10 +301,11 @@ static u32 soc15_get_xclk(struct amdgpu_device *adev)
        u32 reference_clock = adev->clock.spll.reference_freq;
 
        if (adev->ip_versions[MP1_HWIP][0] == IP_VERSION(12, 0, 0) ||
-           adev->ip_versions[MP1_HWIP][0] == IP_VERSION(12, 0, 1) ||
-           adev->ip_versions[MP1_HWIP][0] == IP_VERSION(10, 0, 0) ||
-           adev->ip_versions[MP1_HWIP][0] == IP_VERSION(10, 0, 1))
+           adev->ip_versions[MP1_HWIP][0] == IP_VERSION(12, 0, 1))
                return 10000;
+       if (adev->ip_versions[MP1_HWIP][0] == IP_VERSION(10, 0, 0) ||
+           adev->ip_versions[MP1_HWIP][0] == IP_VERSION(10, 0, 1))
+               return reference_clock / 4;
 
        return reference_clock;
 }
index 531f173..c0360db 100644 (file)
@@ -542,8 +542,15 @@ static u32 vi_get_xclk(struct amdgpu_device *adev)
        u32 reference_clock = adev->clock.spll.reference_freq;
        u32 tmp;
 
-       if (adev->flags & AMD_IS_APU)
-               return reference_clock;
+       if (adev->flags & AMD_IS_APU) {
+               switch (adev->asic_type) {
+               case CHIP_STONEY:
+                       /* vbios says 48Mhz, but the actual freq is 100Mhz */
+                       return 10000;
+               default:
+                       return reference_clock;
+               }
+       }
 
        tmp = RREG32_SMC(ixCG_CLKPIN_CNTL_2);
        if (REG_GET_FIELD(tmp, CG_CLKPIN_CNTL_2, MUX_TCLK_TO_XCLK))
index 52564b9..7cde67b 100644 (file)
@@ -1981,6 +1981,9 @@ static enum dc_status dc_commit_state_no_check(struct dc *dc, struct dc_state *c
        return result;
 }
 
+static bool commit_minimal_transition_state(struct dc *dc,
+               struct dc_state *transition_base_context);
+
 /**
  * dc_commit_streams - Commit current stream state
  *
@@ -2002,6 +2005,8 @@ enum dc_status dc_commit_streams(struct dc *dc,
        struct dc_state *context;
        enum dc_status res = DC_OK;
        struct dc_validation_set set[MAX_STREAMS] = {0};
+       struct pipe_ctx *pipe;
+       bool handle_exit_odm2to1 = false;
 
        if (dc->ctx->dce_environment == DCE_ENV_VIRTUAL_HW)
                return res;
@@ -2026,6 +2031,22 @@ enum dc_status dc_commit_streams(struct dc *dc,
                }
        }
 
+       /* Check for case where we are going from odm 2:1 to max
+        *  pipe scenario.  For these cases, we will call
+        *  commit_minimal_transition_state() to exit out of odm 2:1
+        *  first before processing new streams
+        */
+       if (stream_count == dc->res_pool->pipe_count) {
+               for (i = 0; i < dc->res_pool->pipe_count; i++) {
+                       pipe = &dc->current_state->res_ctx.pipe_ctx[i];
+                       if (pipe->next_odm_pipe)
+                               handle_exit_odm2to1 = true;
+               }
+       }
+
+       if (handle_exit_odm2to1)
+               res = commit_minimal_transition_state(dc, dc->current_state);
+
        context = dc_create_state(dc);
        if (!context)
                goto context_alloc_fail;
@@ -3872,6 +3893,7 @@ static bool commit_minimal_transition_state(struct dc *dc,
        unsigned int i, j;
        unsigned int pipe_in_use = 0;
        bool subvp_in_use = false;
+       bool odm_in_use = false;
 
        if (!transition_context)
                return false;
@@ -3900,6 +3922,18 @@ static bool commit_minimal_transition_state(struct dc *dc,
                }
        }
 
+       /* If ODM is enabled and we are adding or removing planes from any ODM
+        * pipe, we must use the minimal transition.
+        */
+       for (i = 0; i < dc->res_pool->pipe_count; i++) {
+               struct pipe_ctx *pipe = &dc->current_state->res_ctx.pipe_ctx[i];
+
+               if (pipe->stream && pipe->next_odm_pipe) {
+                       odm_in_use = true;
+                       break;
+               }
+       }
+
        /* When the OS add a new surface if we have been used all of pipes with odm combine
         * and mpc split feature, it need use commit_minimal_transition_state to transition safely.
         * After OS exit MPO, it will back to use odm and mpc split with all of pipes, we need
@@ -3908,7 +3942,7 @@ static bool commit_minimal_transition_state(struct dc *dc,
         * Reduce the scenarios to use dc_commit_state_no_check in the stage of flip. Especially
         * enter/exit MPO when DCN still have enough resources.
         */
-       if (pipe_in_use != dc->res_pool->pipe_count && !subvp_in_use) {
+       if (pipe_in_use != dc->res_pool->pipe_count && !subvp_in_use && !odm_in_use) {
                dc_release_state(transition_context);
                return true;
        }
index 117d80c..fe15513 100644 (file)
@@ -1446,6 +1446,26 @@ static int acquire_first_split_pipe(
 
                        split_pipe->stream = stream;
                        return i;
+               } else if (split_pipe->prev_odm_pipe &&
+                               split_pipe->prev_odm_pipe->plane_state == split_pipe->plane_state) {
+                       split_pipe->prev_odm_pipe->next_odm_pipe = split_pipe->next_odm_pipe;
+                       if (split_pipe->next_odm_pipe)
+                               split_pipe->next_odm_pipe->prev_odm_pipe = split_pipe->prev_odm_pipe;
+
+                       if (split_pipe->prev_odm_pipe->plane_state)
+                               resource_build_scaling_params(split_pipe->prev_odm_pipe);
+
+                       memset(split_pipe, 0, sizeof(*split_pipe));
+                       split_pipe->stream_res.tg = pool->timing_generators[i];
+                       split_pipe->plane_res.hubp = pool->hubps[i];
+                       split_pipe->plane_res.ipp = pool->ipps[i];
+                       split_pipe->plane_res.dpp = pool->dpps[i];
+                       split_pipe->stream_res.opp = pool->opps[i];
+                       split_pipe->plane_res.mpcc_inst = pool->dpps[i]->inst;
+                       split_pipe->pipe_idx = i;
+
+                       split_pipe->stream = stream;
+                       return i;
                }
        }
        return -1;
index 47beb4e..0c4c320 100644 (file)
@@ -138,7 +138,7 @@ struct _vcs_dpi_soc_bounding_box_st dcn3_2_soc = {
        .urgent_out_of_order_return_per_channel_pixel_only_bytes = 4096,
        .urgent_out_of_order_return_per_channel_pixel_and_vm_bytes = 4096,
        .urgent_out_of_order_return_per_channel_vm_only_bytes = 4096,
-       .pct_ideal_sdp_bw_after_urgent = 100.0,
+       .pct_ideal_sdp_bw_after_urgent = 90.0,
        .pct_ideal_fabric_bw_after_urgent = 67.0,
        .pct_ideal_dram_sdp_bw_after_urgent_pixel_only = 20.0,
        .pct_ideal_dram_sdp_bw_after_urgent_pixel_and_vm = 60.0, // N/A, for now keep as is until DML implemented
index 75f1868..85d5359 100644 (file)
@@ -2067,33 +2067,94 @@ static int sienna_cichlid_display_disable_memory_clock_switch(struct smu_context
        return ret;
 }
 
+static void sienna_cichlid_get_override_pcie_settings(struct smu_context *smu,
+                                                     uint32_t *gen_speed_override,
+                                                     uint32_t *lane_width_override)
+{
+       struct amdgpu_device *adev = smu->adev;
+
+       *gen_speed_override = 0xff;
+       *lane_width_override = 0xff;
+
+       switch (adev->pdev->device) {
+       case 0x73A0:
+       case 0x73A1:
+       case 0x73A2:
+       case 0x73A3:
+       case 0x73AB:
+       case 0x73AE:
+               /* Bit 7:0: PCIE lane width, 1 to 7 corresponds is x1 to x32 */
+               *lane_width_override = 6;
+               break;
+       case 0x73E0:
+       case 0x73E1:
+       case 0x73E3:
+               *lane_width_override = 4;
+               break;
+       case 0x7420:
+       case 0x7421:
+       case 0x7422:
+       case 0x7423:
+       case 0x7424:
+               *lane_width_override = 3;
+               break;
+       default:
+               break;
+       }
+}
+
+#define MAX(a, b)      ((a) > (b) ? (a) : (b))
+
 static int sienna_cichlid_update_pcie_parameters(struct smu_context *smu,
                                         uint32_t pcie_gen_cap,
                                         uint32_t pcie_width_cap)
 {
        struct smu_11_0_dpm_context *dpm_context = smu->smu_dpm.dpm_context;
-
-       uint32_t smu_pcie_arg;
+       struct smu_11_0_pcie_table *pcie_table = &dpm_context->dpm_tables.pcie_table;
+       uint32_t gen_speed_override, lane_width_override;
        uint8_t *table_member1, *table_member2;
+       uint32_t min_gen_speed, max_gen_speed;
+       uint32_t min_lane_width, max_lane_width;
+       uint32_t smu_pcie_arg;
        int ret, i;
 
        GET_PPTABLE_MEMBER(PcieGenSpeed, &table_member1);
        GET_PPTABLE_MEMBER(PcieLaneCount, &table_member2);
 
-       /* lclk dpm table setup */
-       for (i = 0; i < MAX_PCIE_CONF; i++) {
-               dpm_context->dpm_tables.pcie_table.pcie_gen[i] = table_member1[i];
-               dpm_context->dpm_tables.pcie_table.pcie_lane[i] = table_member2[i];
+       sienna_cichlid_get_override_pcie_settings(smu,
+                                                 &gen_speed_override,
+                                                 &lane_width_override);
+
+       /* PCIE gen speed override */
+       if (gen_speed_override != 0xff) {
+               min_gen_speed = MIN(pcie_gen_cap, gen_speed_override);
+               max_gen_speed = MIN(pcie_gen_cap, gen_speed_override);
+       } else {
+               min_gen_speed = MAX(0, table_member1[0]);
+               max_gen_speed = MIN(pcie_gen_cap, table_member1[1]);
+               min_gen_speed = min_gen_speed > max_gen_speed ?
+                               max_gen_speed : min_gen_speed;
        }
+       pcie_table->pcie_gen[0] = min_gen_speed;
+       pcie_table->pcie_gen[1] = max_gen_speed;
+
+       /* PCIE lane width override */
+       if (lane_width_override != 0xff) {
+               min_lane_width = MIN(pcie_width_cap, lane_width_override);
+               max_lane_width = MIN(pcie_width_cap, lane_width_override);
+       } else {
+               min_lane_width = MAX(1, table_member2[0]);
+               max_lane_width = MIN(pcie_width_cap, table_member2[1]);
+               min_lane_width = min_lane_width > max_lane_width ?
+                                max_lane_width : min_lane_width;
+       }
+       pcie_table->pcie_lane[0] = min_lane_width;
+       pcie_table->pcie_lane[1] = max_lane_width;
 
        for (i = 0; i < NUM_LINK_LEVELS; i++) {
-               smu_pcie_arg = (i << 16) |
-                       ((table_member1[i] <= pcie_gen_cap) ?
-                        (table_member1[i] << 8) :
-                        (pcie_gen_cap << 8)) |
-                       ((table_member2[i] <= pcie_width_cap) ?
-                        table_member2[i] :
-                        pcie_width_cap);
+               smu_pcie_arg = (i << 16 |
+                               pcie_table->pcie_gen[i] << 8 |
+                               pcie_table->pcie_lane[i]);
 
                ret = smu_cmn_send_smc_msg_with_param(smu,
                                SMU_MSG_OverridePcieParameters,
@@ -2101,11 +2162,6 @@ static int sienna_cichlid_update_pcie_parameters(struct smu_context *smu,
                                NULL);
                if (ret)
                        return ret;
-
-               if (table_member1[i] > pcie_gen_cap)
-                       dpm_context->dpm_tables.pcie_table.pcie_gen[i] = pcie_gen_cap;
-               if (table_member2[i] > pcie_width_cap)
-                       dpm_context->dpm_tables.pcie_table.pcie_lane[i] = pcie_width_cap;
        }
 
        return 0;
index 393c6a7..ca37918 100644 (file)
@@ -573,11 +573,11 @@ int smu_v13_0_init_power(struct smu_context *smu)
        if (smu_power->power_context || smu_power->power_context_size != 0)
                return -EINVAL;
 
-       smu_power->power_context = kzalloc(sizeof(struct smu_13_0_dpm_context),
+       smu_power->power_context = kzalloc(sizeof(struct smu_13_0_power_context),
                                           GFP_KERNEL);
        if (!smu_power->power_context)
                return -ENOMEM;
-       smu_power->power_context_size = sizeof(struct smu_13_0_dpm_context);
+       smu_power->power_context_size = sizeof(struct smu_13_0_power_context);
 
        return 0;
 }
index fbb070f..6dc1a09 100644 (file)
@@ -119,53 +119,32 @@ err_astdp_edid_not_ready:
 /*
  * Launch Aspeed DP
  */
-void ast_dp_launch(struct drm_device *dev, u8 bPower)
+void ast_dp_launch(struct drm_device *dev)
 {
-       u32 i = 0, j = 0, WaitCount = 1;
-       u8 bDPTX = 0;
+       u32 i = 0;
        u8 bDPExecute = 1;
-
        struct ast_device *ast = to_ast_device(dev);
-       // S3 come back, need more time to wait BMC ready.
-       if (bPower)
-               WaitCount = 300;
-
-
-       // Wait total count by different condition.
-       for (j = 0; j < WaitCount; j++) {
-               bDPTX = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xD1, TX_TYPE_MASK);
-
-               if (bDPTX)
-                       break;
 
+       // Wait one second then timeout.
+       while (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xD1, ASTDP_MCU_FW_EXECUTING) !=
+               ASTDP_MCU_FW_EXECUTING) {
+               i++;
+               // wait 100 ms
                msleep(100);
-       }
 
-       // 0xE : ASTDP with DPMCU FW handling
-       if (bDPTX == ASTDP_DPMCU_TX) {
-               // Wait one second then timeout.
-               i = 0;
-
-               while (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xD1, COPROCESSOR_LAUNCH) !=
-                       COPROCESSOR_LAUNCH) {
-                       i++;
-                       // wait 100 ms
-                       msleep(100);
-
-                       if (i >= 10) {
-                               // DP would not be ready.
-                               bDPExecute = 0;
-                               break;
-                       }
+               if (i >= 10) {
+                       // DP would not be ready.
+                       bDPExecute = 0;
+                       break;
                }
+       }
 
-               if (bDPExecute)
-                       ast->tx_chip_types |= BIT(AST_TX_ASTDP);
+       if (!bDPExecute)
+               drm_err(dev, "Wait DPMCU executing timeout\n");
 
-               ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xE5,
-                                                       (u8) ~ASTDP_HOST_EDID_READ_DONE_MASK,
-                                                       ASTDP_HOST_EDID_READ_DONE);
-       }
+       ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xE5,
+                              (u8) ~ASTDP_HOST_EDID_READ_DONE_MASK,
+                              ASTDP_HOST_EDID_READ_DONE);
 }
 
 
index a501169..5498a66 100644 (file)
@@ -350,9 +350,6 @@ int ast_mode_config_init(struct ast_device *ast);
 #define AST_DP501_LINKRATE     0xf014
 #define AST_DP501_EDID_DATA    0xf020
 
-/* Define for Soc scratched reg */
-#define COPROCESSOR_LAUNCH                     BIT(5)
-
 /*
  * Display Transmitter Type:
  */
@@ -480,7 +477,7 @@ struct ast_i2c_chan *ast_i2c_create(struct drm_device *dev);
 
 /* aspeed DP */
 int ast_astdp_read_edid(struct drm_device *dev, u8 *ediddata);
-void ast_dp_launch(struct drm_device *dev, u8 bPower);
+void ast_dp_launch(struct drm_device *dev);
 void ast_dp_power_on_off(struct drm_device *dev, bool no);
 void ast_dp_set_on_off(struct drm_device *dev, bool no);
 void ast_dp_set_mode(struct drm_crtc *crtc, struct ast_vbios_mode_info *vbios_mode);
index f32ce29..1f35438 100644 (file)
@@ -254,8 +254,13 @@ static int ast_detect_chip(struct drm_device *dev, bool *need_post)
                case 0x0c:
                        ast->tx_chip_types = AST_TX_DP501_BIT;
                }
-       } else if (ast->chip == AST2600)
-               ast_dp_launch(&ast->base, 0);
+       } else if (ast->chip == AST2600) {
+               if (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xD1, TX_TYPE_MASK) ==
+                   ASTDP_DPMCU_TX) {
+                       ast->tx_chip_types = AST_TX_ASTDP_BIT;
+                       ast_dp_launch(&ast->base);
+               }
+       }
 
        /* Print stuff for diagnostic purposes */
        if (ast->tx_chip_types & AST_TX_NONE_BIT)
@@ -264,6 +269,8 @@ static int ast_detect_chip(struct drm_device *dev, bool *need_post)
                drm_info(dev, "Using Sil164 TMDS transmitter\n");
        if (ast->tx_chip_types & AST_TX_DP501_BIT)
                drm_info(dev, "Using DP501 DisplayPort transmitter\n");
+       if (ast->tx_chip_types & AST_TX_ASTDP_BIT)
+               drm_info(dev, "Using ASPEED DisplayPort transmitter\n");
 
        return 0;
 }
index 3637482..b3c670a 100644 (file)
@@ -1647,6 +1647,8 @@ static int ast_dp501_output_init(struct ast_device *ast)
 static int ast_astdp_connector_helper_get_modes(struct drm_connector *connector)
 {
        void *edid;
+       struct drm_device *dev = connector->dev;
+       struct ast_device *ast = to_ast_device(dev);
 
        int succ;
        int count;
@@ -1655,9 +1657,17 @@ static int ast_astdp_connector_helper_get_modes(struct drm_connector *connector)
        if (!edid)
                goto err_drm_connector_update_edid_property;
 
+       /*
+        * Protect access to I/O registers from concurrent modesetting
+        * by acquiring the I/O-register lock.
+        */
+       mutex_lock(&ast->ioregs_lock);
+
        succ = ast_astdp_read_edid(connector->dev, edid);
        if (succ < 0)
-               goto err_kfree;
+               goto err_mutex_unlock;
+
+       mutex_unlock(&ast->ioregs_lock);
 
        drm_connector_update_edid_property(connector, edid);
        count = drm_add_edid_modes(connector, edid);
@@ -1665,7 +1675,8 @@ static int ast_astdp_connector_helper_get_modes(struct drm_connector *connector)
 
        return count;
 
-err_kfree:
+err_mutex_unlock:
+       mutex_unlock(&ast->ioregs_lock);
        kfree(edid);
 err_drm_connector_update_edid_property:
        drm_connector_update_edid_property(connector, NULL);
index 71bb36b..a005aec 100644 (file)
@@ -380,7 +380,8 @@ void ast_post_gpu(struct drm_device *dev)
        ast_set_def_ext_reg(dev);
 
        if (ast->chip == AST2600) {
-               ast_dp_launch(dev, 1);
+               if (ast->tx_chip_types & AST_TX_ASTDP_BIT)
+                       ast_dp_launch(dev);
        } else if (ast->config_mode == ast_use_p2a) {
                if (ast->chip == AST2500)
                        ast_post_chip_2500(dev);
index 6bb1b8b..fd27f19 100644 (file)
@@ -1545,17 +1545,19 @@ static void drm_fb_helper_fill_pixel_fmt(struct fb_var_screeninfo *var,
        }
 }
 
-static void __fill_var(struct fb_var_screeninfo *var,
+static void __fill_var(struct fb_var_screeninfo *var, struct fb_info *info,
                       struct drm_framebuffer *fb)
 {
        int i;
 
        var->xres_virtual = fb->width;
        var->yres_virtual = fb->height;
-       var->accel_flags = FB_ACCELF_TEXT;
+       var->accel_flags = 0;
        var->bits_per_pixel = drm_format_info_bpp(fb->format, 0);
 
-       var->height = var->width = 0;
+       var->height = info->var.height;
+       var->width = info->var.width;
+
        var->left_margin = var->right_margin = 0;
        var->upper_margin = var->lower_margin = 0;
        var->hsync_len = var->vsync_len = 0;
@@ -1618,7 +1620,7 @@ int drm_fb_helper_check_var(struct fb_var_screeninfo *var,
                return -EINVAL;
        }
 
-       __fill_var(var, fb);
+       __fill_var(var, info, fb);
 
        /*
         * fb_pan_display() validates this, but fb_set_par() doesn't and just
@@ -2074,7 +2076,7 @@ static void drm_fb_helper_fill_var(struct fb_info *info,
        info->pseudo_palette = fb_helper->pseudo_palette;
        info->var.xoffset = 0;
        info->var.yoffset = 0;
-       __fill_var(&info->var, fb);
+       __fill_var(&info->var, info, fb);
        info->var.activate = FB_ACTIVATE_NOW;
 
        drm_fb_helper_fill_pixel_fmt(&info->var, format);
index ec784e5..414e585 100644 (file)
@@ -1335,7 +1335,7 @@ int exynos_g2d_exec_ioctl(struct drm_device *drm_dev, void *data,
        /* Let the runqueue know that there is work to do. */
        queue_work(g2d->g2d_workq, &g2d->runqueue_work);
 
-       if (runqueue_node->async)
+       if (req->async)
                goto out;
 
        wait_for_completion(&runqueue_node->complete);
index 4d56c8c..f5e1adf 100644 (file)
@@ -469,8 +469,6 @@ static int vidi_remove(struct platform_device *pdev)
        if (ctx->raw_edid != (struct edid *)fake_edid_info) {
                kfree(ctx->raw_edid);
                ctx->raw_edid = NULL;
-
-               return -EINVAL;
        }
 
        component_del(&pdev->dev, &vidi_component_ops);
index 084a483..2aaaba0 100644 (file)
@@ -1453,6 +1453,18 @@ static u8 tgl_calc_voltage_level(int cdclk)
                return 0;
 }
 
+static u8 rplu_calc_voltage_level(int cdclk)
+{
+       if (cdclk > 556800)
+               return 3;
+       else if (cdclk > 480000)
+               return 2;
+       else if (cdclk > 312000)
+               return 1;
+       else
+               return 0;
+}
+
 static void icl_readout_refclk(struct drm_i915_private *dev_priv,
                               struct intel_cdclk_config *cdclk_config)
 {
@@ -3242,6 +3254,13 @@ static const struct intel_cdclk_funcs mtl_cdclk_funcs = {
        .calc_voltage_level = tgl_calc_voltage_level,
 };
 
+static const struct intel_cdclk_funcs rplu_cdclk_funcs = {
+       .get_cdclk = bxt_get_cdclk,
+       .set_cdclk = bxt_set_cdclk,
+       .modeset_calc_cdclk = bxt_modeset_calc_cdclk,
+       .calc_voltage_level = rplu_calc_voltage_level,
+};
+
 static const struct intel_cdclk_funcs tgl_cdclk_funcs = {
        .get_cdclk = bxt_get_cdclk,
        .set_cdclk = bxt_set_cdclk,
@@ -3384,14 +3403,17 @@ void intel_init_cdclk_hooks(struct drm_i915_private *dev_priv)
                dev_priv->display.funcs.cdclk = &tgl_cdclk_funcs;
                dev_priv->display.cdclk.table = dg2_cdclk_table;
        } else if (IS_ALDERLAKE_P(dev_priv)) {
-               dev_priv->display.funcs.cdclk = &tgl_cdclk_funcs;
                /* Wa_22011320316:adl-p[a0] */
-               if (IS_ADLP_DISPLAY_STEP(dev_priv, STEP_A0, STEP_B0))
+               if (IS_ADLP_DISPLAY_STEP(dev_priv, STEP_A0, STEP_B0)) {
                        dev_priv->display.cdclk.table = adlp_a_step_cdclk_table;
-               else if (IS_ADLP_RPLU(dev_priv))
+                       dev_priv->display.funcs.cdclk = &tgl_cdclk_funcs;
+               } else if (IS_ADLP_RPLU(dev_priv)) {
                        dev_priv->display.cdclk.table = rplu_cdclk_table;
-               else
+                       dev_priv->display.funcs.cdclk = &rplu_cdclk_funcs;
+               } else {
                        dev_priv->display.cdclk.table = adlp_cdclk_table;
+                       dev_priv->display.funcs.cdclk = &tgl_cdclk_funcs;
+               }
        } else if (IS_ROCKETLAKE(dev_priv)) {
                dev_priv->display.funcs.cdclk = &tgl_cdclk_funcs;
                dev_priv->display.cdclk.table = rkl_cdclk_table;
index 705915d..524bd6d 100644 (file)
@@ -129,7 +129,7 @@ static int intel_dp_aux_sync_len(void)
 
 static int intel_dp_aux_fw_sync_len(void)
 {
-       int precharge = 16; /* 10-16 */
+       int precharge = 10; /* 10-16 */
        int preamble = 8;
 
        return precharge + preamble;
index a81fa6a..7b516b1 100644 (file)
@@ -346,8 +346,10 @@ static int live_parallel_switch(void *arg)
                                continue;
 
                        ce = intel_context_create(data[m].ce[0]->engine);
-                       if (IS_ERR(ce))
+                       if (IS_ERR(ce)) {
+                               err = PTR_ERR(ce);
                                goto out;
+                       }
 
                        err = intel_context_pin(ce);
                        if (err) {
@@ -367,8 +369,10 @@ static int live_parallel_switch(void *arg)
 
                worker = kthread_create_worker(0, "igt/parallel:%s",
                                               data[n].ce[0]->engine->name);
-               if (IS_ERR(worker))
+               if (IS_ERR(worker)) {
+                       err = PTR_ERR(worker);
                        goto out;
+               }
 
                data[n].worker = worker;
        }
@@ -397,8 +401,10 @@ static int live_parallel_switch(void *arg)
                        }
                }
 
-               if (igt_live_test_end(&t))
-                       err = -EIO;
+               if (igt_live_test_end(&t)) {
+                       err = err ?: -EIO;
+                       break;
+               }
        }
 
 out:
index 736b89a..4202df5 100644 (file)
@@ -1530,8 +1530,8 @@ static int live_busywait_preempt(void *arg)
        struct drm_i915_gem_object *obj;
        struct i915_vma *vma;
        enum intel_engine_id id;
-       int err = -ENOMEM;
        u32 *map;
+       int err;
 
        /*
         * Verify that even without HAS_LOGICAL_RING_PREEMPTION, we can
@@ -1539,13 +1539,17 @@ static int live_busywait_preempt(void *arg)
         */
 
        ctx_hi = kernel_context(gt->i915, NULL);
-       if (!ctx_hi)
-               return -ENOMEM;
+       if (IS_ERR(ctx_hi))
+               return PTR_ERR(ctx_hi);
+
        ctx_hi->sched.priority = I915_CONTEXT_MAX_USER_PRIORITY;
 
        ctx_lo = kernel_context(gt->i915, NULL);
-       if (!ctx_lo)
+       if (IS_ERR(ctx_lo)) {
+               err = PTR_ERR(ctx_lo);
                goto err_ctx_hi;
+       }
+
        ctx_lo->sched.priority = I915_CONTEXT_MIN_USER_PRIORITY;
 
        obj = i915_gem_object_create_internal(gt->i915, PAGE_SIZE);
index ff00340..ffd91a5 100644 (file)
@@ -165,7 +165,7 @@ int lima_sched_context_init(struct lima_sched_pipe *pipe,
 void lima_sched_context_fini(struct lima_sched_pipe *pipe,
                             struct lima_sched_context *context)
 {
-       drm_sched_entity_fini(&context->base);
+       drm_sched_entity_destroy(&context->base);
 }
 
 struct dma_fence *lima_sched_context_queue_task(struct lima_sched_task *task)
index e16b4b3..8914992 100644 (file)
@@ -1526,8 +1526,6 @@ int a6xx_gmu_init(struct a6xx_gpu *a6xx_gpu, struct device_node *node)
        if (!pdev)
                return -ENODEV;
 
-       mutex_init(&gmu->lock);
-
        gmu->dev = &pdev->dev;
 
        of_dma_configure(gmu->dev, node, true);
index 9fb214f..52da379 100644 (file)
@@ -1981,6 +1981,8 @@ struct msm_gpu *a6xx_gpu_init(struct drm_device *dev)
        adreno_gpu = &a6xx_gpu->base;
        gpu = &adreno_gpu->base;
 
+       mutex_init(&a6xx_gpu->gmu.lock);
+
        adreno_gpu->registers = NULL;
 
        /*
index 7a8cf1c..5142aeb 100644 (file)
@@ -620,7 +620,7 @@ void dp_catalog_hpd_config_intr(struct dp_catalog *dp_catalog,
                                config & DP_DP_HPD_INT_MASK);
 }
 
-void dp_catalog_ctrl_hpd_config(struct dp_catalog *dp_catalog)
+void dp_catalog_ctrl_hpd_enable(struct dp_catalog *dp_catalog)
 {
        struct dp_catalog_private *catalog = container_of(dp_catalog,
                                struct dp_catalog_private, dp_catalog);
@@ -635,6 +635,19 @@ void dp_catalog_ctrl_hpd_config(struct dp_catalog *dp_catalog)
        dp_write_aux(catalog, REG_DP_DP_HPD_CTRL, DP_DP_HPD_CTRL_HPD_EN);
 }
 
+void dp_catalog_ctrl_hpd_disable(struct dp_catalog *dp_catalog)
+{
+       struct dp_catalog_private *catalog = container_of(dp_catalog,
+                               struct dp_catalog_private, dp_catalog);
+
+       u32 reftimer = dp_read_aux(catalog, REG_DP_DP_HPD_REFTIMER);
+
+       reftimer &= ~DP_DP_HPD_REFTIMER_ENABLE;
+       dp_write_aux(catalog, REG_DP_DP_HPD_REFTIMER, reftimer);
+
+       dp_write_aux(catalog, REG_DP_DP_HPD_CTRL, 0);
+}
+
 static void dp_catalog_enable_sdp(struct dp_catalog_private *catalog)
 {
        /* trigger sdp */
index 82376a2..38786e8 100644 (file)
@@ -104,7 +104,8 @@ bool dp_catalog_ctrl_mainlink_ready(struct dp_catalog *dp_catalog);
 void dp_catalog_ctrl_enable_irq(struct dp_catalog *dp_catalog, bool enable);
 void dp_catalog_hpd_config_intr(struct dp_catalog *dp_catalog,
                        u32 intr_mask, bool en);
-void dp_catalog_ctrl_hpd_config(struct dp_catalog *dp_catalog);
+void dp_catalog_ctrl_hpd_enable(struct dp_catalog *dp_catalog);
+void dp_catalog_ctrl_hpd_disable(struct dp_catalog *dp_catalog);
 void dp_catalog_ctrl_config_psr(struct dp_catalog *dp_catalog);
 void dp_catalog_ctrl_set_psr(struct dp_catalog *dp_catalog, bool enter);
 u32 dp_catalog_link_is_connected(struct dp_catalog *dp_catalog);
index 99a38db..03b0eda 100644 (file)
 #include "dp_audio.h"
 #include "dp_debug.h"
 
+static bool psr_enabled = false;
+module_param(psr_enabled, bool, 0);
+MODULE_PARM_DESC(psr_enabled, "enable PSR for eDP and DP displays");
+
 #define HPD_STRING_SIZE 30
 
 enum {
@@ -407,7 +411,7 @@ static int dp_display_process_hpd_high(struct dp_display_private *dp)
 
        edid = dp->panel->edid;
 
-       dp->dp_display.psr_supported = dp->panel->psr_cap.version;
+       dp->dp_display.psr_supported = dp->panel->psr_cap.version && psr_enabled;
 
        dp->audio_supported = drm_detect_monitor_audio(edid);
        dp_panel_handle_sink_request(dp->panel);
@@ -616,12 +620,6 @@ static int dp_hpd_plug_handle(struct dp_display_private *dp, u32 data)
                dp->hpd_state = ST_MAINLINK_READY;
        }
 
-       /* enable HDP irq_hpd/replug interrupt */
-       if (dp->dp_display.internal_hpd)
-               dp_catalog_hpd_config_intr(dp->catalog,
-                                          DP_DP_IRQ_HPD_INT_MASK | DP_DP_HPD_REPLUG_INT_MASK,
-                                          true);
-
        drm_dbg_dp(dp->drm_dev, "After, type=%d hpd_state=%d\n",
                        dp->dp_display.connector_type, state);
        mutex_unlock(&dp->event_mutex);
@@ -659,12 +657,6 @@ static int dp_hpd_unplug_handle(struct dp_display_private *dp, u32 data)
        drm_dbg_dp(dp->drm_dev, "Before, type=%d hpd_state=%d\n",
                        dp->dp_display.connector_type, state);
 
-       /* disable irq_hpd/replug interrupts */
-       if (dp->dp_display.internal_hpd)
-               dp_catalog_hpd_config_intr(dp->catalog,
-                                          DP_DP_IRQ_HPD_INT_MASK | DP_DP_HPD_REPLUG_INT_MASK,
-                                          false);
-
        /* unplugged, no more irq_hpd handle */
        dp_del_event(dp, EV_IRQ_HPD_INT);
 
@@ -688,10 +680,6 @@ static int dp_hpd_unplug_handle(struct dp_display_private *dp, u32 data)
                return 0;
        }
 
-       /* disable HPD plug interrupts */
-       if (dp->dp_display.internal_hpd)
-               dp_catalog_hpd_config_intr(dp->catalog, DP_DP_HPD_PLUG_INT_MASK, false);
-
        /*
         * We don't need separate work for disconnect as
         * connect/attention interrupts are disabled
@@ -707,10 +695,6 @@ static int dp_hpd_unplug_handle(struct dp_display_private *dp, u32 data)
        /* signal the disconnect event early to ensure proper teardown */
        dp_display_handle_plugged_change(&dp->dp_display, false);
 
-       /* enable HDP plug interrupt to prepare for next plugin */
-       if (dp->dp_display.internal_hpd)
-               dp_catalog_hpd_config_intr(dp->catalog, DP_DP_HPD_PLUG_INT_MASK, true);
-
        drm_dbg_dp(dp->drm_dev, "After, type=%d hpd_state=%d\n",
                        dp->dp_display.connector_type, state);
 
@@ -1083,26 +1067,6 @@ void msm_dp_snapshot(struct msm_disp_state *disp_state, struct msm_dp *dp)
        mutex_unlock(&dp_display->event_mutex);
 }
 
-static void dp_display_config_hpd(struct dp_display_private *dp)
-{
-
-       dp_display_host_init(dp);
-       dp_catalog_ctrl_hpd_config(dp->catalog);
-
-       /* Enable plug and unplug interrupts only if requested */
-       if (dp->dp_display.internal_hpd)
-               dp_catalog_hpd_config_intr(dp->catalog,
-                               DP_DP_HPD_PLUG_INT_MASK |
-                               DP_DP_HPD_UNPLUG_INT_MASK,
-                               true);
-
-       /* Enable interrupt first time
-        * we are leaving dp clocks on during disconnect
-        * and never disable interrupt
-        */
-       enable_irq(dp->irq);
-}
-
 void dp_display_set_psr(struct msm_dp *dp_display, bool enter)
 {
        struct dp_display_private *dp;
@@ -1177,7 +1141,7 @@ static int hpd_event_thread(void *data)
 
                switch (todo->event_id) {
                case EV_HPD_INIT_SETUP:
-                       dp_display_config_hpd(dp_priv);
+                       dp_display_host_init(dp_priv);
                        break;
                case EV_HPD_PLUG_INT:
                        dp_hpd_plug_handle(dp_priv, todo->data);
@@ -1283,7 +1247,6 @@ int dp_display_request_irq(struct msm_dp *dp_display)
                                dp->irq, rc);
                return rc;
        }
-       disable_irq(dp->irq);
 
        return 0;
 }
@@ -1395,13 +1358,8 @@ static int dp_pm_resume(struct device *dev)
        /* turn on dp ctrl/phy */
        dp_display_host_init(dp);
 
-       dp_catalog_ctrl_hpd_config(dp->catalog);
-
-       if (dp->dp_display.internal_hpd)
-               dp_catalog_hpd_config_intr(dp->catalog,
-                               DP_DP_HPD_PLUG_INT_MASK |
-                               DP_DP_HPD_UNPLUG_INT_MASK,
-                               true);
+       if (dp_display->is_edp)
+               dp_catalog_ctrl_hpd_enable(dp->catalog);
 
        if (dp_catalog_link_is_connected(dp->catalog)) {
                /*
@@ -1569,9 +1527,8 @@ static int dp_display_get_next_bridge(struct msm_dp *dp)
 
        if (aux_bus && dp->is_edp) {
                dp_display_host_init(dp_priv);
-               dp_catalog_ctrl_hpd_config(dp_priv->catalog);
+               dp_catalog_ctrl_hpd_enable(dp_priv->catalog);
                dp_display_host_phy_init(dp_priv);
-               enable_irq(dp_priv->irq);
 
                /*
                 * The code below assumes that the panel will finish probing
@@ -1613,7 +1570,6 @@ static int dp_display_get_next_bridge(struct msm_dp *dp)
 
 error:
        if (dp->is_edp) {
-               disable_irq(dp_priv->irq);
                dp_display_host_phy_exit(dp_priv);
                dp_display_host_deinit(dp_priv);
        }
@@ -1802,16 +1758,31 @@ void dp_bridge_hpd_enable(struct drm_bridge *bridge)
 {
        struct msm_dp_bridge *dp_bridge = to_dp_bridge(bridge);
        struct msm_dp *dp_display = dp_bridge->dp_display;
+       struct dp_display_private *dp = container_of(dp_display, struct dp_display_private, dp_display);
+
+       mutex_lock(&dp->event_mutex);
+       dp_catalog_ctrl_hpd_enable(dp->catalog);
+
+       /* enable HDP interrupts */
+       dp_catalog_hpd_config_intr(dp->catalog, DP_DP_HPD_INT_MASK, true);
 
        dp_display->internal_hpd = true;
+       mutex_unlock(&dp->event_mutex);
 }
 
 void dp_bridge_hpd_disable(struct drm_bridge *bridge)
 {
        struct msm_dp_bridge *dp_bridge = to_dp_bridge(bridge);
        struct msm_dp *dp_display = dp_bridge->dp_display;
+       struct dp_display_private *dp = container_of(dp_display, struct dp_display_private, dp_display);
+
+       mutex_lock(&dp->event_mutex);
+       /* disable HDP interrupts */
+       dp_catalog_hpd_config_intr(dp->catalog, DP_DP_HPD_INT_MASK, false);
+       dp_catalog_ctrl_hpd_disable(dp->catalog);
 
        dp_display->internal_hpd = false;
+       mutex_unlock(&dp->event_mutex);
 }
 
 void dp_bridge_hpd_notify(struct drm_bridge *bridge,
index b4cfa44..463ca41 100644 (file)
@@ -449,6 +449,8 @@ static int msm_drm_init(struct device *dev, const struct drm_driver *drv)
        if (ret)
                goto err_cleanup_mode_config;
 
+       dma_set_max_seg_size(dev, UINT_MAX);
+
        /* Bind all our sub-components: */
        ret = component_bind_all(dev, ddev);
        if (ret)
@@ -459,8 +461,6 @@ static int msm_drm_init(struct device *dev, const struct drm_driver *drv)
        if (ret)
                goto err_msm_uninit;
 
-       dma_set_max_seg_size(dev, UINT_MAX);
-
        msm_gem_shrinker_init(ddev);
 
        if (priv->kms_init) {
index bdc5af2..d3f5ddb 100644 (file)
@@ -459,7 +459,6 @@ int radeon_gem_set_domain_ioctl(struct drm_device *dev, void *data,
        struct radeon_device *rdev = dev->dev_private;
        struct drm_radeon_gem_set_domain *args = data;
        struct drm_gem_object *gobj;
-       struct radeon_bo *robj;
        int r;
 
        /* for now if someone requests domain CPU -
@@ -472,13 +471,12 @@ int radeon_gem_set_domain_ioctl(struct drm_device *dev, void *data,
                up_read(&rdev->exclusive_lock);
                return -ENOENT;
        }
-       robj = gem_to_radeon_bo(gobj);
 
        r = radeon_gem_set_domain(gobj, args->read_domains, args->write_domain);
 
        drm_gem_object_put(gobj);
        up_read(&rdev->exclusive_lock);
-       r = radeon_gem_handle_lockup(robj->rdev, r);
+       r = radeon_gem_handle_lockup(rdev, r);
        return r;
 }
 
index c5d87aa..bf23bfb 100644 (file)
@@ -40,6 +40,7 @@
 #define DW_IC_CON_BUS_CLEAR_CTRL               BIT(11)
 
 #define DW_IC_DATA_CMD_DAT                     GENMASK(7, 0)
+#define DW_IC_DATA_CMD_FIRST_DATA_BYTE         BIT(11)
 
 /*
  * Registers offset
index cec2505..2e079cf 100644 (file)
@@ -176,6 +176,10 @@ static irqreturn_t i2c_dw_isr_slave(int this_irq, void *dev_id)
 
                do {
                        regmap_read(dev->map, DW_IC_DATA_CMD, &tmp);
+                       if (tmp & DW_IC_DATA_CMD_FIRST_DATA_BYTE)
+                               i2c_slave_event(dev->slave,
+                                               I2C_SLAVE_WRITE_REQUESTED,
+                                               &val);
                        val = tmp;
                        i2c_slave_event(dev->slave, I2C_SLAVE_WRITE_RECEIVED,
                                        &val);
index 8e98794..39c479f 100644 (file)
 #define IMG_I2C_TIMEOUT                        (msecs_to_jiffies(1000))
 
 /*
- * Worst incs are 1 (innacurate) and 16*256 (irregular).
+ * Worst incs are 1 (inaccurate) and 16*256 (irregular).
  * So a sensible inc is the logarithmic mean: 64 (2^6), which is
  * in the middle of the valid range (0-127).
  */
index b21ffd6..5ef136c 100644 (file)
@@ -1118,8 +1118,10 @@ static int pci1xxxx_i2c_resume(struct device *dev)
 static DEFINE_SIMPLE_DEV_PM_OPS(pci1xxxx_i2c_pm_ops, pci1xxxx_i2c_suspend,
                         pci1xxxx_i2c_resume);
 
-static void pci1xxxx_i2c_shutdown(struct pci1xxxx_i2c *i2c)
+static void pci1xxxx_i2c_shutdown(void *data)
 {
+       struct pci1xxxx_i2c *i2c = data;
+
        pci1xxxx_i2c_config_padctrl(i2c, false);
        pci1xxxx_i2c_configure_core_reg(i2c, false);
 }
@@ -1156,7 +1158,7 @@ static int pci1xxxx_i2c_probe_pci(struct pci_dev *pdev,
        init_completion(&i2c->i2c_xfer_done);
        pci1xxxx_i2c_init(i2c);
 
-       ret = devm_add_action(dev, (void (*)(void *))pci1xxxx_i2c_shutdown, i2c);
+       ret = devm_add_action(dev, pci1xxxx_i2c_shutdown, i2c);
        if (ret)
                return ret;
 
index 047dfef..878c076 100644 (file)
@@ -520,6 +520,17 @@ mv64xxx_i2c_intr(int irq, void *dev_id)
 
        while (readl(drv_data->reg_base + drv_data->reg_offsets.control) &
                                                MV64XXX_I2C_REG_CONTROL_IFLG) {
+               /*
+                * It seems that sometime the controller updates the status
+                * register only after it asserts IFLG in control register.
+                * This may result in weird bugs when in atomic mode. A delay
+                * of 100 ns before reading the status register solves this
+                * issue. This bug does not seem to appear when using
+                * interrupts.
+                */
+               if (drv_data->atomic)
+                       ndelay(100);
+
                status = readl(drv_data->reg_base + drv_data->reg_offsets.status);
                mv64xxx_i2c_fsm(drv_data, status);
                mv64xxx_i2c_do_action(drv_data);
index 4fe15cd..ffc54fb 100644 (file)
@@ -576,12 +576,14 @@ static int sprd_i2c_remove(struct platform_device *pdev)
        struct sprd_i2c *i2c_dev = platform_get_drvdata(pdev);
        int ret;
 
-       ret = pm_runtime_resume_and_get(i2c_dev->dev);
+       ret = pm_runtime_get_sync(i2c_dev->dev);
        if (ret < 0)
-               return ret;
+               dev_err(&pdev->dev, "Failed to resume device (%pe)\n", ERR_PTR(ret));
 
        i2c_del_adapter(&i2c_dev->adap);
-       clk_disable_unprepare(i2c_dev->clk);
+
+       if (ret >= 0)
+               clk_disable_unprepare(i2c_dev->clk);
 
        pm_runtime_put_noidle(i2c_dev->dev);
        pm_runtime_disable(i2c_dev->dev);
index 93a1c48..6b3f438 100644 (file)
@@ -3295,7 +3295,7 @@ static int cma_resolve_iboe_route(struct rdma_id_private *id_priv)
        route->path_rec->traffic_class = tos;
        route->path_rec->mtu = iboe_get_mtu(ndev->mtu);
        route->path_rec->rate_selector = IB_SA_EQ;
-       route->path_rec->rate = iboe_get_rate(ndev);
+       route->path_rec->rate = IB_RATE_PORT_CURRENT;
        dev_put(ndev);
        route->path_rec->packet_life_time_selector = IB_SA_EQ;
        /* In case ACK timeout is set, use this value to calculate
@@ -4964,7 +4964,7 @@ static int cma_iboe_join_multicast(struct rdma_id_private *id_priv,
        if (!ndev)
                return -ENODEV;
 
-       ib.rec.rate = iboe_get_rate(ndev);
+       ib.rec.rate = IB_RATE_PORT_CURRENT;
        ib.rec.hop_limit = 1;
        ib.rec.mtu = iboe_get_mtu(ndev->mtu);
 
index 4796f6a..e836c9c 100644 (file)
@@ -1850,8 +1850,13 @@ static int modify_qp(struct uverbs_attr_bundle *attrs,
                attr->path_mtu = cmd->base.path_mtu;
        if (cmd->base.attr_mask & IB_QP_PATH_MIG_STATE)
                attr->path_mig_state = cmd->base.path_mig_state;
-       if (cmd->base.attr_mask & IB_QP_QKEY)
+       if (cmd->base.attr_mask & IB_QP_QKEY) {
+               if (cmd->base.qkey & IB_QP_SET_QKEY && !capable(CAP_NET_RAW)) {
+                       ret = -EPERM;
+                       goto release_qp;
+               }
                attr->qkey = cmd->base.qkey;
+       }
        if (cmd->base.attr_mask & IB_QP_RQ_PSN)
                attr->rq_psn = cmd->base.rq_psn;
        if (cmd->base.attr_mask & IB_QP_SQ_PSN)
index fbace69..7c9c79c 100644 (file)
@@ -222,8 +222,12 @@ static ssize_t ib_uverbs_event_read(struct ib_uverbs_event_queue *ev_queue,
        spin_lock_irq(&ev_queue->lock);
 
        while (list_empty(&ev_queue->event_list)) {
-               spin_unlock_irq(&ev_queue->lock);
+               if (ev_queue->is_closed) {
+                       spin_unlock_irq(&ev_queue->lock);
+                       return -EIO;
+               }
 
+               spin_unlock_irq(&ev_queue->lock);
                if (filp->f_flags & O_NONBLOCK)
                        return -EAGAIN;
 
@@ -233,12 +237,6 @@ static ssize_t ib_uverbs_event_read(struct ib_uverbs_event_queue *ev_queue,
                        return -ERESTARTSYS;
 
                spin_lock_irq(&ev_queue->lock);
-
-               /* If device was disassociated and no event exists set an error */
-               if (list_empty(&ev_queue->event_list) && ev_queue->is_closed) {
-                       spin_unlock_irq(&ev_queue->lock);
-                       return -EIO;
-               }
        }
 
        event = list_entry(ev_queue->event_list.next, struct ib_uverbs_event, list);
index 5a2baf4..2c95e6f 100644 (file)
@@ -135,8 +135,6 @@ struct bnxt_re_dev {
 
        struct delayed_work             worker;
        u8                              cur_prio_map;
-       u16                             active_speed;
-       u8                              active_width;
 
        /* FP Notification Queue (CQ & SRQ) */
        struct tasklet_struct           nq_task;
index b1c3641..952811c 100644 (file)
@@ -199,6 +199,7 @@ int bnxt_re_query_port(struct ib_device *ibdev, u32 port_num,
 {
        struct bnxt_re_dev *rdev = to_bnxt_re_dev(ibdev, ibdev);
        struct bnxt_qplib_dev_attr *dev_attr = &rdev->dev_attr;
+       int rc;
 
        memset(port_attr, 0, sizeof(*port_attr));
 
@@ -228,10 +229,10 @@ int bnxt_re_query_port(struct ib_device *ibdev, u32 port_num,
        port_attr->sm_sl = 0;
        port_attr->subnet_timeout = 0;
        port_attr->init_type_reply = 0;
-       port_attr->active_speed = rdev->active_speed;
-       port_attr->active_width = rdev->active_width;
+       rc = ib_get_eth_speed(&rdev->ibdev, port_num, &port_attr->active_speed,
+                             &port_attr->active_width);
 
-       return 0;
+       return rc;
 }
 
 int bnxt_re_get_port_immutable(struct ib_device *ibdev, u32 port_num,
index e34eccd..3073398 100644 (file)
@@ -1077,8 +1077,6 @@ static int bnxt_re_ib_init(struct bnxt_re_dev *rdev)
                return rc;
        }
        dev_info(rdev_to_dev(rdev), "Device registered with IB successfully");
-       ib_get_eth_speed(&rdev->ibdev, 1, &rdev->active_speed,
-                        &rdev->active_width);
        set_bit(BNXT_RE_FLAG_ISSUE_ROCE_STATS, &rdev->flags);
 
        event = netif_running(rdev->netdev) && netif_carrier_ok(rdev->netdev) ?
index 1c06920..93257fa 100644 (file)
@@ -209,7 +209,8 @@ static const struct mlx5_ib_counters *get_counters(struct mlx5_ib_dev *dev,
             !vport_qcounters_supported(dev)) || !port_num)
                return &dev->port[0].cnts;
 
-       return &dev->port[port_num - 1].cnts;
+       return is_mdev_switchdev_mode(dev->mdev) ?
+              &dev->port[1].cnts : &dev->port[port_num - 1].cnts;
 }
 
 /**
@@ -262,7 +263,7 @@ static struct rdma_hw_stats *
 mlx5_ib_alloc_hw_port_stats(struct ib_device *ibdev, u32 port_num)
 {
        struct mlx5_ib_dev *dev = to_mdev(ibdev);
-       const struct mlx5_ib_counters *cnts = &dev->port[port_num - 1].cnts;
+       const struct mlx5_ib_counters *cnts = get_counters(dev, port_num);
 
        return do_alloc_stats(cnts);
 }
@@ -329,6 +330,7 @@ static int mlx5_ib_query_q_counters_vport(struct mlx5_ib_dev *dev,
 {
        u32 out[MLX5_ST_SZ_DW(query_q_counter_out)] = {};
        u32 in[MLX5_ST_SZ_DW(query_q_counter_in)] = {};
+       struct mlx5_core_dev *mdev;
        __be32 val;
        int ret, i;
 
@@ -336,12 +338,16 @@ static int mlx5_ib_query_q_counters_vport(struct mlx5_ib_dev *dev,
            dev->port[port_num].rep->vport == MLX5_VPORT_UPLINK)
                return 0;
 
+       mdev = mlx5_eswitch_get_core_dev(dev->port[port_num].rep->esw);
+       if (!mdev)
+               return -EOPNOTSUPP;
+
        MLX5_SET(query_q_counter_in, in, opcode, MLX5_CMD_OP_QUERY_Q_COUNTER);
        MLX5_SET(query_q_counter_in, in, other_vport, 1);
        MLX5_SET(query_q_counter_in, in, vport_number,
                 dev->port[port_num].rep->vport);
        MLX5_SET(query_q_counter_in, in, aggregate, 1);
-       ret = mlx5_cmd_exec_inout(dev->mdev, query_q_counter, in, out);
+       ret = mlx5_cmd_exec_inout(mdev, query_q_counter, in, out);
        if (ret)
                return ret;
 
@@ -575,43 +581,53 @@ static void mlx5_ib_fill_counters(struct mlx5_ib_dev *dev,
        bool is_vport = is_mdev_switchdev_mode(dev->mdev) &&
                        port_num != MLX5_VPORT_PF;
        const struct mlx5_ib_counter *names;
-       int j = 0, i;
+       int j = 0, i, size;
 
        names = is_vport ? vport_basic_q_cnts : basic_q_cnts;
-       for (i = 0; i < ARRAY_SIZE(basic_q_cnts); i++, j++) {
+       size = is_vport ? ARRAY_SIZE(vport_basic_q_cnts) :
+                         ARRAY_SIZE(basic_q_cnts);
+       for (i = 0; i < size; i++, j++) {
                descs[j].name = names[i].name;
-               offsets[j] = basic_q_cnts[i].offset;
+               offsets[j] = names[i].offset;
        }
 
        names = is_vport ? vport_out_of_seq_q_cnts : out_of_seq_q_cnts;
+       size = is_vport ? ARRAY_SIZE(vport_out_of_seq_q_cnts) :
+                         ARRAY_SIZE(out_of_seq_q_cnts);
        if (MLX5_CAP_GEN(dev->mdev, out_of_seq_cnt)) {
-               for (i = 0; i < ARRAY_SIZE(out_of_seq_q_cnts); i++, j++) {
+               for (i = 0; i < size; i++, j++) {
                        descs[j].name = names[i].name;
-                       offsets[j] = out_of_seq_q_cnts[i].offset;
+                       offsets[j] = names[i].offset;
                }
        }
 
        names = is_vport ? vport_retrans_q_cnts : retrans_q_cnts;
+       size = is_vport ? ARRAY_SIZE(vport_retrans_q_cnts) :
+                         ARRAY_SIZE(retrans_q_cnts);
        if (MLX5_CAP_GEN(dev->mdev, retransmission_q_counters)) {
-               for (i = 0; i < ARRAY_SIZE(retrans_q_cnts); i++, j++) {
+               for (i = 0; i < size; i++, j++) {
                        descs[j].name = names[i].name;
-                       offsets[j] = retrans_q_cnts[i].offset;
+                       offsets[j] = names[i].offset;
                }
        }
 
        names = is_vport ? vport_extended_err_cnts : extended_err_cnts;
+       size = is_vport ? ARRAY_SIZE(vport_extended_err_cnts) :
+                         ARRAY_SIZE(extended_err_cnts);
        if (MLX5_CAP_GEN(dev->mdev, enhanced_error_q_counters)) {
-               for (i = 0; i < ARRAY_SIZE(extended_err_cnts); i++, j++) {
+               for (i = 0; i < size; i++, j++) {
                        descs[j].name = names[i].name;
-                       offsets[j] = extended_err_cnts[i].offset;
+                       offsets[j] = names[i].offset;
                }
        }
 
        names = is_vport ? vport_roce_accl_cnts : roce_accl_cnts;
+       size = is_vport ? ARRAY_SIZE(vport_roce_accl_cnts) :
+                         ARRAY_SIZE(roce_accl_cnts);
        if (MLX5_CAP_GEN(dev->mdev, roce_accl)) {
-               for (i = 0; i < ARRAY_SIZE(roce_accl_cnts); i++, j++) {
+               for (i = 0; i < size; i++, j++) {
                        descs[j].name = names[i].name;
-                       offsets[j] = roce_accl_cnts[i].offset;
+                       offsets[j] = names[i].offset;
                }
        }
 
@@ -661,25 +677,37 @@ static void mlx5_ib_fill_counters(struct mlx5_ib_dev *dev,
 static int __mlx5_ib_alloc_counters(struct mlx5_ib_dev *dev,
                                    struct mlx5_ib_counters *cnts, u32 port_num)
 {
-       u32 num_counters, num_op_counters = 0;
+       bool is_vport = is_mdev_switchdev_mode(dev->mdev) &&
+                       port_num != MLX5_VPORT_PF;
+       u32 num_counters, num_op_counters = 0, size;
 
-       num_counters = ARRAY_SIZE(basic_q_cnts);
+       size = is_vport ? ARRAY_SIZE(vport_basic_q_cnts) :
+                         ARRAY_SIZE(basic_q_cnts);
+       num_counters = size;
 
+       size = is_vport ? ARRAY_SIZE(vport_out_of_seq_q_cnts) :
+                         ARRAY_SIZE(out_of_seq_q_cnts);
        if (MLX5_CAP_GEN(dev->mdev, out_of_seq_cnt))
-               num_counters += ARRAY_SIZE(out_of_seq_q_cnts);
+               num_counters += size;
 
+       size = is_vport ? ARRAY_SIZE(vport_retrans_q_cnts) :
+                         ARRAY_SIZE(retrans_q_cnts);
        if (MLX5_CAP_GEN(dev->mdev, retransmission_q_counters))
-               num_counters += ARRAY_SIZE(retrans_q_cnts);
+               num_counters += size;
 
+       size = is_vport ? ARRAY_SIZE(vport_extended_err_cnts) :
+                         ARRAY_SIZE(extended_err_cnts);
        if (MLX5_CAP_GEN(dev->mdev, enhanced_error_q_counters))
-               num_counters += ARRAY_SIZE(extended_err_cnts);
+               num_counters += size;
 
+       size = is_vport ? ARRAY_SIZE(vport_roce_accl_cnts) :
+                         ARRAY_SIZE(roce_accl_cnts);
        if (MLX5_CAP_GEN(dev->mdev, roce_accl))
-               num_counters += ARRAY_SIZE(roce_accl_cnts);
+               num_counters += size;
 
        cnts->num_q_counters = num_counters;
 
-       if (is_mdev_switchdev_mode(dev->mdev) && port_num != MLX5_VPORT_PF)
+       if (is_vport)
                goto skip_non_qcounters;
 
        if (MLX5_CAP_GEN(dev->mdev, cc_query_allowed)) {
@@ -725,11 +753,11 @@ err:
 static void mlx5_ib_dealloc_counters(struct mlx5_ib_dev *dev)
 {
        u32 in[MLX5_ST_SZ_DW(dealloc_q_counter_in)] = {};
-       int num_cnt_ports;
+       int num_cnt_ports = dev->num_ports;
        int i, j;
 
-       num_cnt_ports = (!is_mdev_switchdev_mode(dev->mdev) ||
-                        vport_qcounters_supported(dev)) ? dev->num_ports : 1;
+       if (is_mdev_switchdev_mode(dev->mdev))
+               num_cnt_ports = min(2, num_cnt_ports);
 
        MLX5_SET(dealloc_q_counter_in, in, opcode,
                 MLX5_CMD_OP_DEALLOC_Q_COUNTER);
@@ -761,15 +789,22 @@ static int mlx5_ib_alloc_counters(struct mlx5_ib_dev *dev)
 {
        u32 out[MLX5_ST_SZ_DW(alloc_q_counter_out)] = {};
        u32 in[MLX5_ST_SZ_DW(alloc_q_counter_in)] = {};
-       int num_cnt_ports;
+       int num_cnt_ports = dev->num_ports;
        int err = 0;
        int i;
        bool is_shared;
 
        MLX5_SET(alloc_q_counter_in, in, opcode, MLX5_CMD_OP_ALLOC_Q_COUNTER);
        is_shared = MLX5_CAP_GEN(dev->mdev, log_max_uctx) != 0;
-       num_cnt_ports = (!is_mdev_switchdev_mode(dev->mdev) ||
-                        vport_qcounters_supported(dev)) ? dev->num_ports : 1;
+
+       /*
+        * In switchdev we need to allocate two ports, one that is used for
+        * the device Q_counters and it is essentially the real Q_counters of
+        * this device, while the other is used as a helper for PF to be able to
+        * query all other vports.
+        */
+       if (is_mdev_switchdev_mode(dev->mdev))
+               num_cnt_ports = min(2, num_cnt_ports);
 
        for (i = 0; i < num_cnt_ports; i++) {
                err = __mlx5_ib_alloc_counters(dev, &dev->port[i].cnts, i);
index 3008632..1e419e0 100644 (file)
@@ -695,8 +695,6 @@ static struct mlx5_ib_flow_prio *_get_prio(struct mlx5_ib_dev *dev,
        struct mlx5_flow_table_attr ft_attr = {};
        struct mlx5_flow_table *ft;
 
-       if (mlx5_ib_shared_ft_allowed(&dev->ib_dev))
-               ft_attr.uid = MLX5_SHARED_RESOURCE_UID;
        ft_attr.prio = priority;
        ft_attr.max_fte = num_entries;
        ft_attr.flags = flags;
@@ -2025,6 +2023,237 @@ static int flow_matcher_cleanup(struct ib_uobject *uobject,
        return 0;
 }
 
+static int steering_anchor_create_ft(struct mlx5_ib_dev *dev,
+                                    struct mlx5_ib_flow_prio *ft_prio,
+                                    enum mlx5_flow_namespace_type ns_type)
+{
+       struct mlx5_flow_table_attr ft_attr = {};
+       struct mlx5_flow_namespace *ns;
+       struct mlx5_flow_table *ft;
+
+       if (ft_prio->anchor.ft)
+               return 0;
+
+       ns = mlx5_get_flow_namespace(dev->mdev, ns_type);
+       if (!ns)
+               return -EOPNOTSUPP;
+
+       ft_attr.flags = MLX5_FLOW_TABLE_UNMANAGED;
+       ft_attr.uid = MLX5_SHARED_RESOURCE_UID;
+       ft_attr.prio = 0;
+       ft_attr.max_fte = 2;
+       ft_attr.level = 1;
+
+       ft = mlx5_create_flow_table(ns, &ft_attr);
+       if (IS_ERR(ft))
+               return PTR_ERR(ft);
+
+       ft_prio->anchor.ft = ft;
+
+       return 0;
+}
+
+static void steering_anchor_destroy_ft(struct mlx5_ib_flow_prio *ft_prio)
+{
+       if (ft_prio->anchor.ft) {
+               mlx5_destroy_flow_table(ft_prio->anchor.ft);
+               ft_prio->anchor.ft = NULL;
+       }
+}
+
+static int
+steering_anchor_create_fg_drop(struct mlx5_ib_flow_prio *ft_prio)
+{
+       int inlen = MLX5_ST_SZ_BYTES(create_flow_group_in);
+       struct mlx5_flow_group *fg;
+       void *flow_group_in;
+       int err = 0;
+
+       if (ft_prio->anchor.fg_drop)
+               return 0;
+
+       flow_group_in = kvzalloc(inlen, GFP_KERNEL);
+       if (!flow_group_in)
+               return -ENOMEM;
+
+       MLX5_SET(create_flow_group_in, flow_group_in, start_flow_index, 1);
+       MLX5_SET(create_flow_group_in, flow_group_in, end_flow_index, 1);
+
+       fg = mlx5_create_flow_group(ft_prio->anchor.ft, flow_group_in);
+       if (IS_ERR(fg)) {
+               err = PTR_ERR(fg);
+               goto out;
+       }
+
+       ft_prio->anchor.fg_drop = fg;
+
+out:
+       kvfree(flow_group_in);
+
+       return err;
+}
+
+static void
+steering_anchor_destroy_fg_drop(struct mlx5_ib_flow_prio *ft_prio)
+{
+       if (ft_prio->anchor.fg_drop) {
+               mlx5_destroy_flow_group(ft_prio->anchor.fg_drop);
+               ft_prio->anchor.fg_drop = NULL;
+       }
+}
+
+static int
+steering_anchor_create_fg_goto_table(struct mlx5_ib_flow_prio *ft_prio)
+{
+       int inlen = MLX5_ST_SZ_BYTES(create_flow_group_in);
+       struct mlx5_flow_group *fg;
+       void *flow_group_in;
+       int err = 0;
+
+       if (ft_prio->anchor.fg_goto_table)
+               return 0;
+
+       flow_group_in = kvzalloc(inlen, GFP_KERNEL);
+       if (!flow_group_in)
+               return -ENOMEM;
+
+       fg = mlx5_create_flow_group(ft_prio->anchor.ft, flow_group_in);
+       if (IS_ERR(fg)) {
+               err = PTR_ERR(fg);
+               goto out;
+       }
+       ft_prio->anchor.fg_goto_table = fg;
+
+out:
+       kvfree(flow_group_in);
+
+       return err;
+}
+
+static void
+steering_anchor_destroy_fg_goto_table(struct mlx5_ib_flow_prio *ft_prio)
+{
+       if (ft_prio->anchor.fg_goto_table) {
+               mlx5_destroy_flow_group(ft_prio->anchor.fg_goto_table);
+               ft_prio->anchor.fg_goto_table = NULL;
+       }
+}
+
+static int
+steering_anchor_create_rule_drop(struct mlx5_ib_flow_prio *ft_prio)
+{
+       struct mlx5_flow_act flow_act = {};
+       struct mlx5_flow_handle *handle;
+
+       if (ft_prio->anchor.rule_drop)
+               return 0;
+
+       flow_act.fg = ft_prio->anchor.fg_drop;
+       flow_act.action = MLX5_FLOW_CONTEXT_ACTION_DROP;
+
+       handle = mlx5_add_flow_rules(ft_prio->anchor.ft, NULL, &flow_act,
+                                    NULL, 0);
+       if (IS_ERR(handle))
+               return PTR_ERR(handle);
+
+       ft_prio->anchor.rule_drop = handle;
+
+       return 0;
+}
+
+static void steering_anchor_destroy_rule_drop(struct mlx5_ib_flow_prio *ft_prio)
+{
+       if (ft_prio->anchor.rule_drop) {
+               mlx5_del_flow_rules(ft_prio->anchor.rule_drop);
+               ft_prio->anchor.rule_drop = NULL;
+       }
+}
+
+static int
+steering_anchor_create_rule_goto_table(struct mlx5_ib_flow_prio *ft_prio)
+{
+       struct mlx5_flow_destination dest = {};
+       struct mlx5_flow_act flow_act = {};
+       struct mlx5_flow_handle *handle;
+
+       if (ft_prio->anchor.rule_goto_table)
+               return 0;
+
+       flow_act.action = MLX5_FLOW_CONTEXT_ACTION_FWD_DEST;
+       flow_act.flags |= FLOW_ACT_IGNORE_FLOW_LEVEL;
+       flow_act.fg = ft_prio->anchor.fg_goto_table;
+
+       dest.type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE;
+       dest.ft = ft_prio->flow_table;
+
+       handle = mlx5_add_flow_rules(ft_prio->anchor.ft, NULL, &flow_act,
+                                    &dest, 1);
+       if (IS_ERR(handle))
+               return PTR_ERR(handle);
+
+       ft_prio->anchor.rule_goto_table = handle;
+
+       return 0;
+}
+
+static void
+steering_anchor_destroy_rule_goto_table(struct mlx5_ib_flow_prio *ft_prio)
+{
+       if (ft_prio->anchor.rule_goto_table) {
+               mlx5_del_flow_rules(ft_prio->anchor.rule_goto_table);
+               ft_prio->anchor.rule_goto_table = NULL;
+       }
+}
+
+static int steering_anchor_create_res(struct mlx5_ib_dev *dev,
+                                     struct mlx5_ib_flow_prio *ft_prio,
+                                     enum mlx5_flow_namespace_type ns_type)
+{
+       int err;
+
+       err = steering_anchor_create_ft(dev, ft_prio, ns_type);
+       if (err)
+               return err;
+
+       err = steering_anchor_create_fg_drop(ft_prio);
+       if (err)
+               goto destroy_ft;
+
+       err = steering_anchor_create_fg_goto_table(ft_prio);
+       if (err)
+               goto destroy_fg_drop;
+
+       err = steering_anchor_create_rule_drop(ft_prio);
+       if (err)
+               goto destroy_fg_goto_table;
+
+       err = steering_anchor_create_rule_goto_table(ft_prio);
+       if (err)
+               goto destroy_rule_drop;
+
+       return 0;
+
+destroy_rule_drop:
+       steering_anchor_destroy_rule_drop(ft_prio);
+destroy_fg_goto_table:
+       steering_anchor_destroy_fg_goto_table(ft_prio);
+destroy_fg_drop:
+       steering_anchor_destroy_fg_drop(ft_prio);
+destroy_ft:
+       steering_anchor_destroy_ft(ft_prio);
+
+       return err;
+}
+
+static void mlx5_steering_anchor_destroy_res(struct mlx5_ib_flow_prio *ft_prio)
+{
+       steering_anchor_destroy_rule_goto_table(ft_prio);
+       steering_anchor_destroy_rule_drop(ft_prio);
+       steering_anchor_destroy_fg_goto_table(ft_prio);
+       steering_anchor_destroy_fg_drop(ft_prio);
+       steering_anchor_destroy_ft(ft_prio);
+}
+
 static int steering_anchor_cleanup(struct ib_uobject *uobject,
                                   enum rdma_remove_reason why,
                                   struct uverbs_attr_bundle *attrs)
@@ -2035,6 +2264,9 @@ static int steering_anchor_cleanup(struct ib_uobject *uobject,
                return -EBUSY;
 
        mutex_lock(&obj->dev->flow_db->lock);
+       if (!--obj->ft_prio->anchor.rule_goto_table_ref)
+               steering_anchor_destroy_rule_goto_table(obj->ft_prio);
+
        put_flow_table(obj->dev, obj->ft_prio, true);
        mutex_unlock(&obj->dev->flow_db->lock);
 
@@ -2042,6 +2274,24 @@ static int steering_anchor_cleanup(struct ib_uobject *uobject,
        return 0;
 }
 
+static void fs_cleanup_anchor(struct mlx5_ib_flow_prio *prio,
+                             int count)
+{
+       while (count--)
+               mlx5_steering_anchor_destroy_res(&prio[count]);
+}
+
+void mlx5_ib_fs_cleanup_anchor(struct mlx5_ib_dev *dev)
+{
+       fs_cleanup_anchor(dev->flow_db->prios, MLX5_IB_NUM_FLOW_FT);
+       fs_cleanup_anchor(dev->flow_db->egress_prios, MLX5_IB_NUM_FLOW_FT);
+       fs_cleanup_anchor(dev->flow_db->sniffer, MLX5_IB_NUM_SNIFFER_FTS);
+       fs_cleanup_anchor(dev->flow_db->egress, MLX5_IB_NUM_EGRESS_FTS);
+       fs_cleanup_anchor(dev->flow_db->fdb, MLX5_IB_NUM_FDB_FTS);
+       fs_cleanup_anchor(dev->flow_db->rdma_rx, MLX5_IB_NUM_FLOW_FT);
+       fs_cleanup_anchor(dev->flow_db->rdma_tx, MLX5_IB_NUM_FLOW_FT);
+}
+
 static int mlx5_ib_matcher_ns(struct uverbs_attr_bundle *attrs,
                              struct mlx5_ib_flow_matcher *obj)
 {
@@ -2182,21 +2432,31 @@ static int UVERBS_HANDLER(MLX5_IB_METHOD_STEERING_ANCHOR_CREATE)(
                return -ENOMEM;
 
        mutex_lock(&dev->flow_db->lock);
+
        ft_prio = _get_flow_table(dev, priority, ns_type, 0);
        if (IS_ERR(ft_prio)) {
-               mutex_unlock(&dev->flow_db->lock);
                err = PTR_ERR(ft_prio);
                goto free_obj;
        }
 
        ft_prio->refcount++;
-       ft_id = mlx5_flow_table_id(ft_prio->flow_table);
-       mutex_unlock(&dev->flow_db->lock);
+
+       if (!ft_prio->anchor.rule_goto_table_ref) {
+               err = steering_anchor_create_res(dev, ft_prio, ns_type);
+               if (err)
+                       goto put_flow_table;
+       }
+
+       ft_prio->anchor.rule_goto_table_ref++;
+
+       ft_id = mlx5_flow_table_id(ft_prio->anchor.ft);
 
        err = uverbs_copy_to(attrs, MLX5_IB_ATTR_STEERING_ANCHOR_FT_ID,
                             &ft_id, sizeof(ft_id));
        if (err)
-               goto put_flow_table;
+               goto destroy_res;
+
+       mutex_unlock(&dev->flow_db->lock);
 
        uobj->object = obj;
        obj->dev = dev;
@@ -2205,8 +2465,10 @@ static int UVERBS_HANDLER(MLX5_IB_METHOD_STEERING_ANCHOR_CREATE)(
 
        return 0;
 
+destroy_res:
+       --ft_prio->anchor.rule_goto_table_ref;
+       mlx5_steering_anchor_destroy_res(ft_prio);
 put_flow_table:
-       mutex_lock(&dev->flow_db->lock);
        put_flow_table(dev, ft_prio, true);
        mutex_unlock(&dev->flow_db->lock);
 free_obj:
index ad320ad..b973490 100644 (file)
@@ -10,6 +10,7 @@
 
 #if IS_ENABLED(CONFIG_INFINIBAND_USER_ACCESS)
 int mlx5_ib_fs_init(struct mlx5_ib_dev *dev);
+void mlx5_ib_fs_cleanup_anchor(struct mlx5_ib_dev *dev);
 #else
 static inline int mlx5_ib_fs_init(struct mlx5_ib_dev *dev)
 {
@@ -21,9 +22,24 @@ static inline int mlx5_ib_fs_init(struct mlx5_ib_dev *dev)
        mutex_init(&dev->flow_db->lock);
        return 0;
 }
+
+inline void mlx5_ib_fs_cleanup_anchor(struct mlx5_ib_dev *dev) {}
 #endif
+
 static inline void mlx5_ib_fs_cleanup(struct mlx5_ib_dev *dev)
 {
+       /* When a steering anchor is created, a special flow table is also
+        * created for the user to reference. Since the user can reference it,
+        * the kernel cannot trust that when the user destroys the steering
+        * anchor, they no longer reference the flow table.
+        *
+        * To address this issue, when a user destroys a steering anchor, only
+        * the flow steering rule in the table is destroyed, but the table
+        * itself is kept to deal with the above scenario. The remaining
+        * resources are only removed when the RDMA device is destroyed, which
+        * is a safe assumption that all references are gone.
+        */
+       mlx5_ib_fs_cleanup_anchor(dev);
        kfree(dev->flow_db);
 }
 #endif /* _MLX5_IB_FS_H */
index 5d45de2..f0b394e 100644 (file)
@@ -4275,6 +4275,9 @@ const struct mlx5_ib_profile raw_eth_profile = {
        STAGE_CREATE(MLX5_IB_STAGE_POST_IB_REG_UMR,
                     mlx5_ib_stage_post_ib_reg_umr_init,
                     NULL),
+       STAGE_CREATE(MLX5_IB_STAGE_DELAY_DROP,
+                    mlx5_ib_stage_delay_drop_init,
+                    mlx5_ib_stage_delay_drop_cleanup),
        STAGE_CREATE(MLX5_IB_STAGE_RESTRACK,
                     mlx5_ib_restrack_init,
                     NULL),
index efa4dc6..2dfa6f4 100644 (file)
@@ -237,8 +237,19 @@ enum {
 #define MLX5_IB_NUM_SNIFFER_FTS                2
 #define MLX5_IB_NUM_EGRESS_FTS         1
 #define MLX5_IB_NUM_FDB_FTS            MLX5_BY_PASS_NUM_REGULAR_PRIOS
+
+struct mlx5_ib_anchor {
+       struct mlx5_flow_table *ft;
+       struct mlx5_flow_group *fg_goto_table;
+       struct mlx5_flow_group *fg_drop;
+       struct mlx5_flow_handle *rule_goto_table;
+       struct mlx5_flow_handle *rule_drop;
+       unsigned int rule_goto_table_ref;
+};
+
 struct mlx5_ib_flow_prio {
        struct mlx5_flow_table          *flow_table;
+       struct mlx5_ib_anchor           anchor;
        unsigned int                    refcount;
 };
 
@@ -1587,6 +1598,9 @@ static inline bool mlx5_ib_lag_should_assign_affinity(struct mlx5_ib_dev *dev)
            MLX5_CAP_PORT_SELECTION(dev->mdev, port_select_flow_table_bypass))
                return 0;
 
+       if (mlx5_lag_is_lacp_owner(dev->mdev) && !dev->lag_active)
+               return 0;
+
        return dev->lag_active ||
                (MLX5_CAP_GEN(dev->mdev, num_lag_ports) > 1 &&
                 MLX5_CAP_GEN(dev->mdev, lag_tx_port_affinity));
index 70ca8ff..78b96bf 100644 (file)
@@ -1237,6 +1237,9 @@ static int create_raw_packet_qp_tis(struct mlx5_ib_dev *dev,
 
        MLX5_SET(create_tis_in, in, uid, to_mpd(pd)->uid);
        MLX5_SET(tisc, tisc, transport_domain, tdn);
+       if (!mlx5_ib_lag_should_assign_affinity(dev) &&
+           mlx5_lag_is_lacp_owner(dev->mdev))
+               MLX5_SET(tisc, tisc, strict_lag_tx_port_affinity, 1);
        if (qp->flags & IB_QP_CREATE_SOURCE_QPN)
                MLX5_SET(tisc, tisc, underlay_qpn, qp->underlay_qpn);
 
index 20ff0c0..6ca2a05 100644 (file)
@@ -113,8 +113,6 @@ int rxe_cq_post(struct rxe_cq *cq, struct rxe_cqe *cqe, int solicited)
 
        queue_advance_producer(cq->queue, QUEUE_TYPE_TO_CLIENT);
 
-       spin_unlock_irqrestore(&cq->cq_lock, flags);
-
        if ((cq->notify == IB_CQ_NEXT_COMP) ||
            (cq->notify == IB_CQ_SOLICITED && solicited)) {
                cq->notify = 0;
@@ -122,6 +120,8 @@ int rxe_cq_post(struct rxe_cq *cq, struct rxe_cqe *cqe, int solicited)
                cq->ibcq.comp_handler(&cq->ibcq, cq->ibcq.cq_context);
        }
 
+       spin_unlock_irqrestore(&cq->cq_lock, flags);
+
        return 0;
 }
 
index a38fab1..cd59666 100644 (file)
@@ -159,6 +159,9 @@ static int rxe_udp_encap_recv(struct sock *sk, struct sk_buff *skb)
        pkt->mask = RXE_GRH_MASK;
        pkt->paylen = be16_to_cpu(udph->len) - sizeof(*udph);
 
+       /* remove udp header */
+       skb_pull(skb, sizeof(struct udphdr));
+
        rxe_rcv(skb);
 
        return 0;
@@ -401,6 +404,9 @@ static int rxe_loopback(struct sk_buff *skb, struct rxe_pkt_info *pkt)
                return -EIO;
        }
 
+       /* remove udp header */
+       skb_pull(skb, sizeof(struct udphdr));
+
        rxe_rcv(skb);
 
        return 0;
index 61a2eb7..a0f2064 100644 (file)
@@ -176,6 +176,9 @@ static void rxe_qp_init_misc(struct rxe_dev *rxe, struct rxe_qp *qp,
        spin_lock_init(&qp->rq.producer_lock);
        spin_lock_init(&qp->rq.consumer_lock);
 
+       skb_queue_head_init(&qp->req_pkts);
+       skb_queue_head_init(&qp->resp_pkts);
+
        atomic_set(&qp->ssn, 0);
        atomic_set(&qp->skb_out, 0);
 }
@@ -234,8 +237,6 @@ static int rxe_qp_init_req(struct rxe_dev *rxe, struct rxe_qp *qp,
        qp->req.opcode          = -1;
        qp->comp.opcode         = -1;
 
-       skb_queue_head_init(&qp->req_pkts);
-
        rxe_init_task(&qp->req.task, qp, rxe_requester);
        rxe_init_task(&qp->comp.task, qp, rxe_completer);
 
@@ -279,8 +280,6 @@ static int rxe_qp_init_resp(struct rxe_dev *rxe, struct rxe_qp *qp,
                }
        }
 
-       skb_queue_head_init(&qp->resp_pkts);
-
        rxe_init_task(&qp->resp.task, qp, rxe_responder);
 
        qp->resp.opcode         = OPCODE_NONE;
index 1da044f..ee68306 100644 (file)
@@ -489,8 +489,9 @@ static enum resp_states check_rkey(struct rxe_qp *qp,
                if (mw->access & IB_ZERO_BASED)
                        qp->resp.offset = mw->addr;
 
-               rxe_put(mw);
                rxe_get(mr);
+               rxe_put(mw);
+               mw = NULL;
        } else {
                mr = lookup_mr(qp->pd, access, rkey, RXE_LOOKUP_REMOTE);
                if (!mr) {
index f290cd4..92e1e75 100644 (file)
@@ -657,9 +657,13 @@ static int
 isert_connect_error(struct rdma_cm_id *cma_id)
 {
        struct isert_conn *isert_conn = cma_id->qp->qp_context;
+       struct isert_np *isert_np = cma_id->context;
 
        ib_drain_qp(isert_conn->qp);
+
+       mutex_lock(&isert_np->mutex);
        list_del_init(&isert_conn->node);
+       mutex_unlock(&isert_np->mutex);
        isert_conn->cm_id = NULL;
        isert_put_conn(isert_conn);
 
@@ -2431,6 +2435,7 @@ isert_free_np(struct iscsi_np *np)
 {
        struct isert_np *isert_np = np->np_context;
        struct isert_conn *isert_conn, *n;
+       LIST_HEAD(drop_conn_list);
 
        if (isert_np->cm_id)
                rdma_destroy_id(isert_np->cm_id);
@@ -2450,7 +2455,7 @@ isert_free_np(struct iscsi_np *np)
                                         node) {
                        isert_info("cleaning isert_conn %p state (%d)\n",
                                   isert_conn, isert_conn->state);
-                       isert_connect_release(isert_conn);
+                       list_move_tail(&isert_conn->node, &drop_conn_list);
                }
        }
 
@@ -2461,11 +2466,16 @@ isert_free_np(struct iscsi_np *np)
                                         node) {
                        isert_info("cleaning isert_conn %p state (%d)\n",
                                   isert_conn, isert_conn->state);
-                       isert_connect_release(isert_conn);
+                       list_move_tail(&isert_conn->node, &drop_conn_list);
                }
        }
        mutex_unlock(&isert_np->mutex);
 
+       list_for_each_entry_safe(isert_conn, n, &drop_conn_list, node) {
+               list_del_init(&isert_conn->node);
+               isert_connect_release(isert_conn);
+       }
+
        np->np_context = NULL;
        kfree(isert_np);
 }
@@ -2560,8 +2570,6 @@ static void isert_wait_conn(struct iscsit_conn *conn)
        isert_put_unsol_pending_cmds(conn);
        isert_wait4cmds(conn);
        isert_wait4logout(isert_conn);
-
-       queue_work(isert_release_wq, &isert_conn->release_work);
 }
 
 static void isert_free_conn(struct iscsit_conn *conn)
index edb2e3a..cfb50bf 100644 (file)
@@ -2040,6 +2040,7 @@ static int rtrs_clt_rdma_cm_handler(struct rdma_cm_id *cm_id,
        return 0;
 }
 
+/* The caller should do the cleanup in case of error */
 static int create_cm(struct rtrs_clt_con *con)
 {
        struct rtrs_path *s = con->c.path;
@@ -2062,14 +2063,14 @@ static int create_cm(struct rtrs_clt_con *con)
        err = rdma_set_reuseaddr(cm_id, 1);
        if (err != 0) {
                rtrs_err(s, "Set address reuse failed, err: %d\n", err);
-               goto destroy_cm;
+               return err;
        }
        err = rdma_resolve_addr(cm_id, (struct sockaddr *)&clt_path->s.src_addr,
                                (struct sockaddr *)&clt_path->s.dst_addr,
                                RTRS_CONNECT_TIMEOUT_MS);
        if (err) {
                rtrs_err(s, "Failed to resolve address, err: %d\n", err);
-               goto destroy_cm;
+               return err;
        }
        /*
         * Combine connection status and session events. This is needed
@@ -2084,29 +2085,15 @@ static int create_cm(struct rtrs_clt_con *con)
                if (err == 0)
                        err = -ETIMEDOUT;
                /* Timedout or interrupted */
-               goto errr;
-       }
-       if (con->cm_err < 0) {
-               err = con->cm_err;
-               goto errr;
+               return err;
        }
-       if (READ_ONCE(clt_path->state) != RTRS_CLT_CONNECTING) {
+       if (con->cm_err < 0)
+               return con->cm_err;
+       if (READ_ONCE(clt_path->state) != RTRS_CLT_CONNECTING)
                /* Device removal */
-               err = -ECONNABORTED;
-               goto errr;
-       }
+               return -ECONNABORTED;
 
        return 0;
-
-errr:
-       stop_cm(con);
-       mutex_lock(&con->con_mutex);
-       destroy_con_cq_qp(con);
-       mutex_unlock(&con->con_mutex);
-destroy_cm:
-       destroy_cm(con);
-
-       return err;
 }
 
 static void rtrs_clt_path_up(struct rtrs_clt_path *clt_path)
@@ -2334,7 +2321,7 @@ static void rtrs_clt_close_work(struct work_struct *work)
 static int init_conns(struct rtrs_clt_path *clt_path)
 {
        unsigned int cid;
-       int err;
+       int err, i;
 
        /*
         * On every new session connections increase reconnect counter
@@ -2350,10 +2337,8 @@ static int init_conns(struct rtrs_clt_path *clt_path)
                        goto destroy;
 
                err = create_cm(to_clt_con(clt_path->s.con[cid]));
-               if (err) {
-                       destroy_con(to_clt_con(clt_path->s.con[cid]));
+               if (err)
                        goto destroy;
-               }
        }
        err = alloc_path_reqs(clt_path);
        if (err)
@@ -2364,15 +2349,21 @@ static int init_conns(struct rtrs_clt_path *clt_path)
        return 0;
 
 destroy:
-       while (cid--) {
-               struct rtrs_clt_con *con = to_clt_con(clt_path->s.con[cid]);
+       /* Make sure we do the cleanup in the order they are created */
+       for (i = 0; i <= cid; i++) {
+               struct rtrs_clt_con *con;
 
-               stop_cm(con);
+               if (!clt_path->s.con[i])
+                       break;
 
-               mutex_lock(&con->con_mutex);
-               destroy_con_cq_qp(con);
-               mutex_unlock(&con->con_mutex);
-               destroy_cm(con);
+               con = to_clt_con(clt_path->s.con[i]);
+               if (con->c.cm_id) {
+                       stop_cm(con);
+                       mutex_lock(&con->con_mutex);
+                       destroy_con_cq_qp(con);
+                       mutex_unlock(&con->con_mutex);
+                       destroy_cm(con);
+               }
                destroy_con(con);
        }
        /*
index 4bf9d86..3696f36 100644 (file)
@@ -37,8 +37,10 @@ struct rtrs_iu *rtrs_iu_alloc(u32 iu_num, size_t size, gfp_t gfp_mask,
                        goto err;
 
                iu->dma_addr = ib_dma_map_single(dma_dev, iu->buf, size, dir);
-               if (ib_dma_mapping_error(dma_dev, iu->dma_addr))
+               if (ib_dma_mapping_error(dma_dev, iu->dma_addr)) {
+                       kfree(iu->buf);
                        goto err;
+               }
 
                iu->cqe.done  = done;
                iu->size      = size;
index cc77cf3..7d5c9c5 100644 (file)
@@ -1168,13 +1168,10 @@ static int do_resume(struct dm_ioctl *param)
        /* Do we need to load a new map ? */
        if (new_map) {
                sector_t old_size, new_size;
-               int srcu_idx;
 
                /* Suspend if it isn't already suspended */
-               old_map = dm_get_live_table(md, &srcu_idx);
-               if ((param->flags & DM_SKIP_LOCKFS_FLAG) || !old_map)
+               if (param->flags & DM_SKIP_LOCKFS_FLAG)
                        suspend_flags &= ~DM_SUSPEND_LOCKFS_FLAG;
-               dm_put_live_table(md, srcu_idx);
                if (param->flags & DM_NOFLUSH_FLAG)
                        suspend_flags |= DM_SUSPEND_NOFLUSH_FLAG;
                if (!dm_suspended_md(md))
index 9f5cb52..b9461fa 100644 (file)
@@ -1756,13 +1756,15 @@ int dm_thin_remove_range(struct dm_thin_device *td,
 
 int dm_pool_block_is_shared(struct dm_pool_metadata *pmd, dm_block_t b, bool *result)
 {
-       int r;
+       int r = -EINVAL;
        uint32_t ref_count;
 
        down_read(&pmd->root_lock);
-       r = dm_sm_get_count(pmd->data_sm, b, &ref_count);
-       if (!r)
-               *result = (ref_count > 1);
+       if (!pmd->fail_io) {
+               r = dm_sm_get_count(pmd->data_sm, b, &ref_count);
+               if (!r)
+                       *result = (ref_count > 1);
+       }
        up_read(&pmd->root_lock);
 
        return r;
@@ -1770,10 +1772,11 @@ int dm_pool_block_is_shared(struct dm_pool_metadata *pmd, dm_block_t b, bool *re
 
 int dm_pool_inc_data_range(struct dm_pool_metadata *pmd, dm_block_t b, dm_block_t e)
 {
-       int r = 0;
+       int r = -EINVAL;
 
        pmd_write_lock(pmd);
-       r = dm_sm_inc_blocks(pmd->data_sm, b, e);
+       if (!pmd->fail_io)
+               r = dm_sm_inc_blocks(pmd->data_sm, b, e);
        pmd_write_unlock(pmd);
 
        return r;
@@ -1781,10 +1784,11 @@ int dm_pool_inc_data_range(struct dm_pool_metadata *pmd, dm_block_t b, dm_block_
 
 int dm_pool_dec_data_range(struct dm_pool_metadata *pmd, dm_block_t b, dm_block_t e)
 {
-       int r = 0;
+       int r = -EINVAL;
 
        pmd_write_lock(pmd);
-       r = dm_sm_dec_blocks(pmd->data_sm, b, e);
+       if (!pmd->fail_io)
+               r = dm_sm_dec_blocks(pmd->data_sm, b, e);
        pmd_write_unlock(pmd);
 
        return r;
index 2b13c94..39410bf 100644 (file)
@@ -401,8 +401,7 @@ static int issue_discard(struct discard_op *op, dm_block_t data_b, dm_block_t da
        sector_t s = block_to_sectors(tc->pool, data_b);
        sector_t len = block_to_sectors(tc->pool, data_e - data_b);
 
-       return __blkdev_issue_discard(tc->pool_dev->bdev, s, len, GFP_NOWAIT,
-                                     &op->bio);
+       return __blkdev_issue_discard(tc->pool_dev->bdev, s, len, GFP_NOIO, &op->bio);
 }
 
 static void end_discard(struct discard_op *op, int r)
index 3b694ba..fffb0cb 100644 (file)
@@ -1172,7 +1172,8 @@ static inline sector_t max_io_len_target_boundary(struct dm_target *ti,
 }
 
 static sector_t __max_io_len(struct dm_target *ti, sector_t sector,
-                            unsigned int max_granularity)
+                            unsigned int max_granularity,
+                            unsigned int max_sectors)
 {
        sector_t target_offset = dm_target_offset(ti, sector);
        sector_t len = max_io_len_target_boundary(ti, target_offset);
@@ -1186,13 +1187,13 @@ static sector_t __max_io_len(struct dm_target *ti, sector_t sector,
        if (!max_granularity)
                return len;
        return min_t(sector_t, len,
-               min(queue_max_sectors(ti->table->md->queue),
+               min(max_sectors ? : queue_max_sectors(ti->table->md->queue),
                    blk_chunk_sectors_left(target_offset, max_granularity)));
 }
 
 static inline sector_t max_io_len(struct dm_target *ti, sector_t sector)
 {
-       return __max_io_len(ti, sector, ti->max_io_len);
+       return __max_io_len(ti, sector, ti->max_io_len, 0);
 }
 
 int dm_set_target_max_io_len(struct dm_target *ti, sector_t len)
@@ -1581,12 +1582,13 @@ static void __send_empty_flush(struct clone_info *ci)
 
 static void __send_changing_extent_only(struct clone_info *ci, struct dm_target *ti,
                                        unsigned int num_bios,
-                                       unsigned int max_granularity)
+                                       unsigned int max_granularity,
+                                       unsigned int max_sectors)
 {
        unsigned int len, bios;
 
        len = min_t(sector_t, ci->sector_count,
-                   __max_io_len(ti, ci->sector, max_granularity));
+                   __max_io_len(ti, ci->sector, max_granularity, max_sectors));
 
        atomic_add(num_bios, &ci->io->io_count);
        bios = __send_duplicate_bios(ci, ti, num_bios, &len);
@@ -1623,23 +1625,27 @@ static blk_status_t __process_abnormal_io(struct clone_info *ci,
 {
        unsigned int num_bios = 0;
        unsigned int max_granularity = 0;
+       unsigned int max_sectors = 0;
        struct queue_limits *limits = dm_get_queue_limits(ti->table->md);
 
        switch (bio_op(ci->bio)) {
        case REQ_OP_DISCARD:
                num_bios = ti->num_discard_bios;
+               max_sectors = limits->max_discard_sectors;
                if (ti->max_discard_granularity)
-                       max_granularity = limits->max_discard_sectors;
+                       max_granularity = max_sectors;
                break;
        case REQ_OP_SECURE_ERASE:
                num_bios = ti->num_secure_erase_bios;
+               max_sectors = limits->max_secure_erase_sectors;
                if (ti->max_secure_erase_granularity)
-                       max_granularity = limits->max_secure_erase_sectors;
+                       max_granularity = max_sectors;
                break;
        case REQ_OP_WRITE_ZEROES:
                num_bios = ti->num_write_zeroes_bios;
+               max_sectors = limits->max_write_zeroes_sectors;
                if (ti->max_write_zeroes_granularity)
-                       max_granularity = limits->max_write_zeroes_sectors;
+                       max_granularity = max_sectors;
                break;
        default:
                break;
@@ -1654,7 +1660,8 @@ static blk_status_t __process_abnormal_io(struct clone_info *ci,
        if (unlikely(!num_bios))
                return BLK_STS_NOTSUPP;
 
-       __send_changing_extent_only(ci, ti, num_bios, max_granularity);
+       __send_changing_extent_only(ci, ti, num_bios,
+                                   max_granularity, max_sectors);
        return BLK_STS_OK;
 }
 
@@ -2808,6 +2815,10 @@ retry:
        }
 
        map = rcu_dereference_protected(md->map, lockdep_is_held(&md->suspend_lock));
+       if (!map) {
+               /* avoid deadlock with fs/namespace.c:do_mount() */
+               suspend_flags &= ~DM_SUSPEND_LOCKFS_FLAG;
+       }
 
        r = __dm_suspend(md, map, suspend_flags, TASK_INTERRUPTIBLE, DMF_SUSPENDED);
        if (r)
index bc6950a..9293b05 100644 (file)
@@ -817,26 +817,15 @@ static void dvb_frontend_stop(struct dvb_frontend *fe)
 
        dev_dbg(fe->dvb->device, "%s:\n", __func__);
 
-       mutex_lock(&fe->remove_mutex);
-
        if (fe->exit != DVB_FE_DEVICE_REMOVED)
                fe->exit = DVB_FE_NORMAL_EXIT;
        mb();
 
-       if (!fepriv->thread) {
-               mutex_unlock(&fe->remove_mutex);
+       if (!fepriv->thread)
                return;
-       }
 
        kthread_stop(fepriv->thread);
 
-       mutex_unlock(&fe->remove_mutex);
-
-       if (fepriv->dvbdev->users < -1) {
-               wait_event(fepriv->dvbdev->wait_queue,
-                          fepriv->dvbdev->users == -1);
-       }
-
        sema_init(&fepriv->sem, 1);
        fepriv->state = FESTATE_IDLE;
 
@@ -2780,13 +2769,9 @@ static int dvb_frontend_open(struct inode *inode, struct file *file)
        struct dvb_adapter *adapter = fe->dvb;
        int ret;
 
-       mutex_lock(&fe->remove_mutex);
-
        dev_dbg(fe->dvb->device, "%s:\n", __func__);
-       if (fe->exit == DVB_FE_DEVICE_REMOVED) {
-               ret = -ENODEV;
-               goto err_remove_mutex;
-       }
+       if (fe->exit == DVB_FE_DEVICE_REMOVED)
+               return -ENODEV;
 
        if (adapter->mfe_shared == 2) {
                mutex_lock(&adapter->mfe_lock);
@@ -2794,8 +2779,7 @@ static int dvb_frontend_open(struct inode *inode, struct file *file)
                        if (adapter->mfe_dvbdev &&
                            !adapter->mfe_dvbdev->writers) {
                                mutex_unlock(&adapter->mfe_lock);
-                               ret = -EBUSY;
-                               goto err_remove_mutex;
+                               return -EBUSY;
                        }
                        adapter->mfe_dvbdev = dvbdev;
                }
@@ -2818,10 +2802,8 @@ static int dvb_frontend_open(struct inode *inode, struct file *file)
                        while (mferetry-- && (mfedev->users != -1 ||
                                              mfepriv->thread)) {
                                if (msleep_interruptible(500)) {
-                                       if (signal_pending(current)) {
-                                               ret = -EINTR;
-                                               goto err_remove_mutex;
-                                       }
+                                       if (signal_pending(current))
+                                               return -EINTR;
                                }
                        }
 
@@ -2833,8 +2815,7 @@ static int dvb_frontend_open(struct inode *inode, struct file *file)
                                if (mfedev->users != -1 ||
                                    mfepriv->thread) {
                                        mutex_unlock(&adapter->mfe_lock);
-                                       ret = -EBUSY;
-                                       goto err_remove_mutex;
+                                       return -EBUSY;
                                }
                                adapter->mfe_dvbdev = dvbdev;
                        }
@@ -2893,8 +2874,6 @@ static int dvb_frontend_open(struct inode *inode, struct file *file)
 
        if (adapter->mfe_shared)
                mutex_unlock(&adapter->mfe_lock);
-
-       mutex_unlock(&fe->remove_mutex);
        return ret;
 
 err3:
@@ -2916,9 +2895,6 @@ err1:
 err0:
        if (adapter->mfe_shared)
                mutex_unlock(&adapter->mfe_lock);
-
-err_remove_mutex:
-       mutex_unlock(&fe->remove_mutex);
        return ret;
 }
 
@@ -2929,8 +2905,6 @@ static int dvb_frontend_release(struct inode *inode, struct file *file)
        struct dvb_frontend_private *fepriv = fe->frontend_priv;
        int ret;
 
-       mutex_lock(&fe->remove_mutex);
-
        dev_dbg(fe->dvb->device, "%s:\n", __func__);
 
        if ((file->f_flags & O_ACCMODE) != O_RDONLY) {
@@ -2952,18 +2926,10 @@ static int dvb_frontend_release(struct inode *inode, struct file *file)
                }
                mutex_unlock(&fe->dvb->mdev_lock);
 #endif
+               if (fe->exit != DVB_FE_NO_EXIT)
+                       wake_up(&dvbdev->wait_queue);
                if (fe->ops.ts_bus_ctrl)
                        fe->ops.ts_bus_ctrl(fe, 0);
-
-               if (fe->exit != DVB_FE_NO_EXIT) {
-                       mutex_unlock(&fe->remove_mutex);
-                       wake_up(&dvbdev->wait_queue);
-               } else {
-                       mutex_unlock(&fe->remove_mutex);
-               }
-
-       } else {
-               mutex_unlock(&fe->remove_mutex);
        }
 
        dvb_frontend_put(fe);
@@ -3064,7 +3030,6 @@ int dvb_register_frontend(struct dvb_adapter *dvb,
        fepriv = fe->frontend_priv;
 
        kref_init(&fe->refcount);
-       mutex_init(&fe->remove_mutex);
 
        /*
         * After initialization, there need to be two references: one
index f0a7531..2d240bf 100644 (file)
@@ -6,6 +6,7 @@ config EEPROM_AT24
        depends on I2C && SYSFS
        select NVMEM
        select NVMEM_SYSFS
+       select REGMAP
        select REGMAP_I2C
        help
          Enable this driver to get read/write support to most I2C EEPROMs
index 1d87937..2295204 100644 (file)
@@ -276,18 +276,6 @@ static inline bool mlx5_sriov_is_enabled(struct mlx5_core_dev *dev)
        return pci_num_vf(dev->pdev) ? true : false;
 }
 
-static inline int mlx5_lag_is_lacp_owner(struct mlx5_core_dev *dev)
-{
-       /* LACP owner conditions:
-        * 1) Function is physical.
-        * 2) LAG is supported by FW.
-        * 3) LAG is managed by driver (currently the only option).
-        */
-       return  MLX5_CAP_GEN(dev, vport_group_manager) &&
-                  (MLX5_CAP_GEN(dev, num_lag_ports) > 1) &&
-                   MLX5_CAP_GEN(dev, lag_master);
-}
-
 int mlx5_rescan_drivers_locked(struct mlx5_core_dev *dev);
 static inline int mlx5_rescan_drivers(struct mlx5_core_dev *dev)
 {
index 2e01960..7feb643 100644 (file)
@@ -811,6 +811,7 @@ static int init_overlay_changeset(struct overlay_changeset *ovcs)
                if (!fragment->target) {
                        pr_err("symbols in overlay, but not in live tree\n");
                        ret = -EINVAL;
+                       of_node_put(node);
                        goto err_out;
                }
 
index 7bfecdf..d249a03 100644 (file)
@@ -400,6 +400,7 @@ static struct meson_pmx_group meson_axg_periphs_groups[] = {
        GPIO_GROUP(GPIOA_15),
        GPIO_GROUP(GPIOA_16),
        GPIO_GROUP(GPIOA_17),
+       GPIO_GROUP(GPIOA_18),
        GPIO_GROUP(GPIOA_19),
        GPIO_GROUP(GPIOA_20),
 
index b0a58c6..f3b280a 100644 (file)
@@ -1057,21 +1057,21 @@ static const struct rpmh_vreg_init_data pm8450_vreg_data[] = {
 };
 
 static const struct rpmh_vreg_init_data pm8550_vreg_data[] = {
-       RPMH_VREG("ldo1",   "ldo%s1",  &pmic5_pldo,    "vdd-l1-l4-l10"),
+       RPMH_VREG("ldo1",   "ldo%s1",  &pmic5_nldo515,    "vdd-l1-l4-l10"),
        RPMH_VREG("ldo2",   "ldo%s2",  &pmic5_pldo,    "vdd-l2-l13-l14"),
-       RPMH_VREG("ldo3",   "ldo%s3",  &pmic5_nldo,    "vdd-l3"),
-       RPMH_VREG("ldo4",   "ldo%s4",  &pmic5_nldo,    "vdd-l1-l4-l10"),
+       RPMH_VREG("ldo3",   "ldo%s3",  &pmic5_nldo515,    "vdd-l3"),
+       RPMH_VREG("ldo4",   "ldo%s4",  &pmic5_nldo515,    "vdd-l1-l4-l10"),
        RPMH_VREG("ldo5",   "ldo%s5",  &pmic5_pldo,    "vdd-l5-l16"),
-       RPMH_VREG("ldo6",   "ldo%s6",  &pmic5_pldo_lv, "vdd-l6-l7"),
-       RPMH_VREG("ldo7",   "ldo%s7",  &pmic5_pldo_lv, "vdd-l6-l7"),
-       RPMH_VREG("ldo8",   "ldo%s8",  &pmic5_pldo_lv, "vdd-l8-l9"),
+       RPMH_VREG("ldo6",   "ldo%s6",  &pmic5_pldo, "vdd-l6-l7"),
+       RPMH_VREG("ldo7",   "ldo%s7",  &pmic5_pldo, "vdd-l6-l7"),
+       RPMH_VREG("ldo8",   "ldo%s8",  &pmic5_pldo, "vdd-l8-l9"),
        RPMH_VREG("ldo9",   "ldo%s9",  &pmic5_pldo,    "vdd-l8-l9"),
-       RPMH_VREG("ldo10",  "ldo%s10", &pmic5_nldo,    "vdd-l1-l4-l10"),
-       RPMH_VREG("ldo11",  "ldo%s11", &pmic5_nldo,    "vdd-l11"),
+       RPMH_VREG("ldo10",  "ldo%s10", &pmic5_nldo515,    "vdd-l1-l4-l10"),
+       RPMH_VREG("ldo11",  "ldo%s11", &pmic5_nldo515,    "vdd-l11"),
        RPMH_VREG("ldo12",  "ldo%s12", &pmic5_pldo,    "vdd-l12"),
        RPMH_VREG("ldo13",  "ldo%s13", &pmic5_pldo,    "vdd-l2-l13-l14"),
        RPMH_VREG("ldo14",  "ldo%s14", &pmic5_pldo,    "vdd-l2-l13-l14"),
-       RPMH_VREG("ldo15",  "ldo%s15", &pmic5_pldo,    "vdd-l15"),
+       RPMH_VREG("ldo15",  "ldo%s15", &pmic5_nldo515,    "vdd-l15"),
        RPMH_VREG("ldo16",  "ldo%s16", &pmic5_pldo,    "vdd-l5-l16"),
        RPMH_VREG("ldo17",  "ldo%s17", &pmic5_pldo,    "vdd-l17"),
        RPMH_VREG("bob1",   "bob%s1",  &pmic5_bob,     "vdd-bob1"),
@@ -1086,9 +1086,9 @@ static const struct rpmh_vreg_init_data pm8550vs_vreg_data[] = {
        RPMH_VREG("smps4",  "smp%s4",  &pmic5_ftsmps525_lv, "vdd-s4"),
        RPMH_VREG("smps5",  "smp%s5",  &pmic5_ftsmps525_lv, "vdd-s5"),
        RPMH_VREG("smps6",  "smp%s6",  &pmic5_ftsmps525_mv, "vdd-s6"),
-       RPMH_VREG("ldo1",   "ldo%s1",  &pmic5_nldo,   "vdd-l1"),
-       RPMH_VREG("ldo2",   "ldo%s2",  &pmic5_nldo,   "vdd-l2"),
-       RPMH_VREG("ldo3",   "ldo%s3",  &pmic5_nldo,   "vdd-l3"),
+       RPMH_VREG("ldo1",   "ldo%s1",  &pmic5_nldo515,   "vdd-l1"),
+       RPMH_VREG("ldo2",   "ldo%s2",  &pmic5_nldo515,   "vdd-l2"),
+       RPMH_VREG("ldo3",   "ldo%s3",  &pmic5_nldo515,   "vdd-l3"),
        {}
 };
 
@@ -1101,9 +1101,9 @@ static const struct rpmh_vreg_init_data pm8550ve_vreg_data[] = {
        RPMH_VREG("smps6", "smp%s6", &pmic5_ftsmps525_lv, "vdd-s6"),
        RPMH_VREG("smps7", "smp%s7", &pmic5_ftsmps525_lv, "vdd-s7"),
        RPMH_VREG("smps8", "smp%s8", &pmic5_ftsmps525_lv, "vdd-s8"),
-       RPMH_VREG("ldo1",  "ldo%s1", &pmic5_nldo,   "vdd-l1"),
-       RPMH_VREG("ldo2",  "ldo%s2", &pmic5_nldo,   "vdd-l2"),
-       RPMH_VREG("ldo3",  "ldo%s3", &pmic5_nldo,   "vdd-l3"),
+       RPMH_VREG("ldo1",  "ldo%s1", &pmic5_nldo515,   "vdd-l1"),
+       RPMH_VREG("ldo2",  "ldo%s2", &pmic5_nldo515,   "vdd-l2"),
+       RPMH_VREG("ldo3",  "ldo%s3", &pmic5_nldo515,   "vdd-l3"),
        {}
 };
 
index 9327dcd..8fca725 100644 (file)
@@ -552,10 +552,10 @@ static int __dasd_ioctl_information(struct dasd_block *block,
 
        memcpy(dasd_info->type, base->discipline->name, 4);
 
-       spin_lock_irqsave(&block->queue_lock, flags);
+       spin_lock_irqsave(get_ccwdev_lock(base->cdev), flags);
        list_for_each(l, &base->ccw_queue)
                dasd_info->chanq_len++;
-       spin_unlock_irqrestore(&block->queue_lock, flags);
+       spin_unlock_irqrestore(get_ccwdev_lock(base->cdev), flags);
        return 0;
 }
 
index d5c43e9..c0d620f 100644 (file)
@@ -1376,6 +1376,7 @@ void ccw_device_set_notoper(struct ccw_device *cdev)
 enum io_sch_action {
        IO_SCH_UNREG,
        IO_SCH_ORPH_UNREG,
+       IO_SCH_UNREG_CDEV,
        IO_SCH_ATTACH,
        IO_SCH_UNREG_ATTACH,
        IO_SCH_ORPH_ATTACH,
@@ -1408,7 +1409,7 @@ static enum io_sch_action sch_get_action(struct subchannel *sch)
        }
        if ((sch->schib.pmcw.pam & sch->opm) == 0) {
                if (ccw_device_notify(cdev, CIO_NO_PATH) != NOTIFY_OK)
-                       return IO_SCH_UNREG;
+                       return IO_SCH_UNREG_CDEV;
                return IO_SCH_DISC;
        }
        if (device_is_disconnected(cdev))
@@ -1470,6 +1471,7 @@ static int io_subchannel_sch_event(struct subchannel *sch, int process)
        case IO_SCH_ORPH_ATTACH:
                ccw_device_set_disconnected(cdev);
                break;
+       case IO_SCH_UNREG_CDEV:
        case IO_SCH_UNREG_ATTACH:
        case IO_SCH_UNREG:
                if (!cdev)
@@ -1503,6 +1505,7 @@ static int io_subchannel_sch_event(struct subchannel *sch, int process)
                if (rc)
                        goto out;
                break;
+       case IO_SCH_UNREG_CDEV:
        case IO_SCH_UNREG_ATTACH:
                spin_lock_irqsave(sch->lock, flags);
                sch_set_cdev(sch, NULL);
index 0f43a88..89b7755 100644 (file)
@@ -32,4 +32,5 @@ obj-$(CONFIG_QCOM_RPMHPD) += rpmhpd.o
 obj-$(CONFIG_QCOM_RPMPD) += rpmpd.o
 obj-$(CONFIG_QCOM_KRYO_L2_ACCESSORS) +=        kryo-l2-accessors.o
 obj-$(CONFIG_QCOM_ICC_BWMON)   += icc-bwmon.o
-obj-$(CONFIG_QCOM_INLINE_CRYPTO_ENGINE)        += ice.o
+qcom_ice-objs                  += ice.o
+obj-$(CONFIG_QCOM_INLINE_CRYPTO_ENGINE)        += qcom_ice.o
index fd58c5b..f65bfec 100644 (file)
@@ -773,12 +773,12 @@ static int bwmon_probe(struct platform_device *pdev)
        bwmon->max_bw_kbps = UINT_MAX;
        opp = dev_pm_opp_find_bw_floor(dev, &bwmon->max_bw_kbps, 0);
        if (IS_ERR(opp))
-               return dev_err_probe(dev, ret, "failed to find max peak bandwidth\n");
+               return dev_err_probe(dev, PTR_ERR(opp), "failed to find max peak bandwidth\n");
 
        bwmon->min_bw_kbps = 0;
        opp = dev_pm_opp_find_bw_ceil(dev, &bwmon->min_bw_kbps, 0);
        if (IS_ERR(opp))
-               return dev_err_probe(dev, ret, "failed to find min peak bandwidth\n");
+               return dev_err_probe(dev, PTR_ERR(opp), "failed to find min peak bandwidth\n");
 
        bwmon->dev = dev;
 
index dc74d2a..5e3ba0b 100644 (file)
@@ -296,7 +296,7 @@ static int qcom_ramp_controller_probe(struct platform_device *pdev)
                return -ENOMEM;
 
        qrc->desc = device_get_match_data(&pdev->dev);
-       if (!qrc)
+       if (!qrc->desc)
                return -EINVAL;
 
        qrc->regmap = devm_regmap_init_mmio(&pdev->dev, base, &qrc_regmap_config);
index ce48a9f..f83811f 100644 (file)
@@ -233,6 +233,7 @@ static int qcom_rmtfs_mem_probe(struct platform_device *pdev)
                num_vmids = 0;
        } else if (num_vmids < 0) {
                dev_err(&pdev->dev, "failed to count qcom,vmid elements: %d\n", num_vmids);
+               ret = num_vmids;
                goto remove_cdev;
        } else if (num_vmids > NUM_MAX_VMIDS) {
                dev_warn(&pdev->dev,
index f93544f..0dd4363 100644 (file)
@@ -1073,7 +1073,7 @@ static int rpmh_rsc_probe(struct platform_device *pdev)
        drv->ver.minor = rsc_id & (MINOR_VER_MASK << MINOR_VER_SHIFT);
        drv->ver.minor >>= MINOR_VER_SHIFT;
 
-       if (drv->ver.major == 3 && drv->ver.minor >= 0)
+       if (drv->ver.major == 3)
                drv->regs = rpmh_rsc_reg_offset_ver_3_0;
        else
                drv->regs = rpmh_rsc_reg_offset_ver_2_7;
index f20e2a4..63c35a3 100644 (file)
@@ -342,6 +342,21 @@ static const struct rpmhpd_desc sm8150_desc = {
        .num_pds = ARRAY_SIZE(sm8150_rpmhpds),
 };
 
+static struct rpmhpd *sa8155p_rpmhpds[] = {
+       [SA8155P_CX] = &cx_w_mx_parent,
+       [SA8155P_CX_AO] = &cx_ao_w_mx_parent,
+       [SA8155P_EBI] = &ebi,
+       [SA8155P_GFX] = &gfx,
+       [SA8155P_MSS] = &mss,
+       [SA8155P_MX] = &mx,
+       [SA8155P_MX_AO] = &mx_ao,
+};
+
+static const struct rpmhpd_desc sa8155p_desc = {
+       .rpmhpds = sa8155p_rpmhpds,
+       .num_pds = ARRAY_SIZE(sa8155p_rpmhpds),
+};
+
 /* SM8250 RPMH powerdomains */
 static struct rpmhpd *sm8250_rpmhpds[] = {
        [SM8250_CX] = &cx_w_mx_parent,
@@ -519,6 +534,7 @@ static const struct rpmhpd_desc sc8280xp_desc = {
 
 static const struct of_device_id rpmhpd_match_table[] = {
        { .compatible = "qcom,qdu1000-rpmhpd", .data = &qdu1000_desc },
+       { .compatible = "qcom,sa8155p-rpmhpd", .data = &sa8155p_desc },
        { .compatible = "qcom,sa8540p-rpmhpd", .data = &sa8540p_desc },
        { .compatible = "qcom,sa8775p-rpmhpd", .data = &sa8775p_desc },
        { .compatible = "qcom,sc7180-rpmhpd", .data = &sc7180_desc },
index 58ea013..2a1096d 100644 (file)
@@ -100,6 +100,13 @@ static const struct dmi_system_id adr_remap_quirk_table[] = {
                .driver_data = (void *)intel_tgl_bios,
        },
        {
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "HP"),
+                       DMI_MATCH(DMI_BOARD_NAME, "8709"),
+               },
+               .driver_data = (void *)intel_tgl_bios,
+       },
+       {
                /* quirk used for NUC15 'Bishop County' LAPBC510 and LAPBC710 skews */
                .matches = {
                        DMI_MATCH(DMI_SYS_VENDOR, "Intel(R) Client Systems"),
index c296e0b..280455f 100644 (file)
@@ -1099,8 +1099,10 @@ static int qcom_swrm_startup(struct snd_pcm_substream *substream,
        }
 
        sruntime = sdw_alloc_stream(dai->name);
-       if (!sruntime)
-               return -ENOMEM;
+       if (!sruntime) {
+               ret = -ENOMEM;
+               goto err_alloc;
+       }
 
        ctrl->sruntime[dai->id] = sruntime;
 
@@ -1110,12 +1112,19 @@ static int qcom_swrm_startup(struct snd_pcm_substream *substream,
                if (ret < 0 && ret != -ENOTSUPP) {
                        dev_err(dai->dev, "Failed to set sdw stream on %s\n",
                                codec_dai->name);
-                       sdw_release_stream(sruntime);
-                       return ret;
+                       goto err_set_stream;
                }
        }
 
        return 0;
+
+err_set_stream:
+       sdw_release_stream(sruntime);
+err_alloc:
+       pm_runtime_mark_last_busy(ctrl->dev);
+       pm_runtime_put_autosuspend(ctrl->dev);
+
+       return ret;
 }
 
 static void qcom_swrm_shutdown(struct snd_pcm_substream *substream,
index c2191c0..379228f 100644 (file)
@@ -2021,8 +2021,10 @@ int sdw_stream_add_slave(struct sdw_slave *slave,
 
 skip_alloc_master_rt:
        s_rt = sdw_slave_rt_find(slave, stream);
-       if (s_rt)
+       if (s_rt) {
+               alloc_slave_rt = false;
                goto skip_alloc_slave_rt;
+       }
 
        s_rt = sdw_slave_rt_alloc(slave, m_rt);
        if (!s_rt) {
index 6ddb2df..32449be 100644 (file)
@@ -1756,8 +1756,11 @@ static int cqspi_probe(struct platform_device *pdev)
                        cqspi->slow_sram = true;
 
                if (of_device_is_compatible(pdev->dev.of_node,
-                                           "xlnx,versal-ospi-1.0"))
-                       dma_set_mask(&pdev->dev, DMA_BIT_MASK(64));
+                                           "xlnx,versal-ospi-1.0")) {
+                       ret = dma_set_mask(&pdev->dev, DMA_BIT_MASK(64));
+                       if (ret)
+                               goto probe_reset_failed;
+               }
        }
 
        ret = devm_request_irq(dev, irq, cqspi_irq_handler, 0,
index 5f2aee6..15f5e9c 100644 (file)
@@ -274,7 +274,7 @@ static void dw_spi_elba_set_cs(struct spi_device *spi, bool enable)
         */
        spi_set_chipselect(spi, 0, 0);
        dw_spi_set_cs(spi, enable);
-       spi_get_chipselect(spi, cs);
+       spi_set_chipselect(spi, 0, cs);
 }
 
 static int dw_spi_elba_init(struct platform_device *pdev,
index 4339485..674cfe0 100644 (file)
@@ -1002,7 +1002,9 @@ static int dspi_transfer_one_message(struct spi_controller *ctlr,
 static int dspi_setup(struct spi_device *spi)
 {
        struct fsl_dspi *dspi = spi_controller_get_devdata(spi->controller);
+       u32 period_ns = DIV_ROUND_UP(NSEC_PER_SEC, spi->max_speed_hz);
        unsigned char br = 0, pbr = 0, pcssck = 0, cssck = 0;
+       u32 quarter_period_ns = DIV_ROUND_UP(period_ns, 4);
        u32 cs_sck_delay = 0, sck_cs_delay = 0;
        struct fsl_dspi_platform_data *pdata;
        unsigned char pasc = 0, asc = 0;
@@ -1031,6 +1033,19 @@ static int dspi_setup(struct spi_device *spi)
                sck_cs_delay = pdata->sck_cs_delay;
        }
 
+       /* Since tCSC and tASC apply to continuous transfers too, avoid SCK
+        * glitches of half a cycle by never allowing tCSC + tASC to go below
+        * half a SCK period.
+        */
+       if (cs_sck_delay < quarter_period_ns)
+               cs_sck_delay = quarter_period_ns;
+       if (sck_cs_delay < quarter_period_ns)
+               sck_cs_delay = quarter_period_ns;
+
+       dev_dbg(&spi->dev,
+               "DSPI controller timing params: CS-to-SCK delay %u ns, SCK-to-CS delay %u ns\n",
+               cs_sck_delay, sck_cs_delay);
+
        clkrate = clk_get_rate(dspi->clk);
        hz_to_spi_baud(&pbr, &br, spi->max_speed_hz, clkrate);
 
index ff48c3e..e2014e2 100644 (file)
@@ -118,16 +118,18 @@ struct tee_cmd_unmap_shared_mem {
 
 /**
  * struct tee_cmd_load_ta - load Trusted Application (TA) binary into TEE
- * @low_addr:    [in] bits [31:0] of the physical address of the TA binary
- * @hi_addr:     [in] bits [63:32] of the physical address of the TA binary
- * @size:        [in] size of TA binary in bytes
- * @ta_handle:   [out] return handle of the loaded TA
+ * @low_addr:       [in] bits [31:0] of the physical address of the TA binary
+ * @hi_addr:        [in] bits [63:32] of the physical address of the TA binary
+ * @size:           [in] size of TA binary in bytes
+ * @ta_handle:      [out] return handle of the loaded TA
+ * @return_origin:  [out] origin of return code after TEE processing
  */
 struct tee_cmd_load_ta {
        u32 low_addr;
        u32 hi_addr;
        u32 size;
        u32 ta_handle;
+       u32 return_origin;
 };
 
 /**
index e8cd9aa..e9b63dc 100644 (file)
@@ -423,19 +423,23 @@ int handle_load_ta(void *data, u32 size, struct tee_ioctl_open_session_arg *arg)
        if (ret) {
                arg->ret_origin = TEEC_ORIGIN_COMMS;
                arg->ret = TEEC_ERROR_COMMUNICATION;
-       } else if (arg->ret == TEEC_SUCCESS) {
-               ret = get_ta_refcount(load_cmd.ta_handle);
-               if (!ret) {
-                       arg->ret_origin = TEEC_ORIGIN_COMMS;
-                       arg->ret = TEEC_ERROR_OUT_OF_MEMORY;
-
-                       /* Unload the TA on error */
-                       unload_cmd.ta_handle = load_cmd.ta_handle;
-                       psp_tee_process_cmd(TEE_CMD_ID_UNLOAD_TA,
-                                           (void *)&unload_cmd,
-                                           sizeof(unload_cmd), &ret);
-               } else {
-                       set_session_id(load_cmd.ta_handle, 0, &arg->session);
+       } else {
+               arg->ret_origin = load_cmd.return_origin;
+
+               if (arg->ret == TEEC_SUCCESS) {
+                       ret = get_ta_refcount(load_cmd.ta_handle);
+                       if (!ret) {
+                               arg->ret_origin = TEEC_ORIGIN_COMMS;
+                               arg->ret = TEEC_ERROR_OUT_OF_MEMORY;
+
+                               /* Unload the TA on error */
+                               unload_cmd.ta_handle = load_cmd.ta_handle;
+                               psp_tee_process_cmd(TEE_CMD_ID_UNLOAD_TA,
+                                                   (void *)&unload_cmd,
+                                                   sizeof(unload_cmd), &ret);
+                       } else {
+                               set_session_id(load_cmd.ta_handle, 0, &arg->session);
+                       }
                }
        }
        mutex_unlock(&ta_refcount_mutex);
index e29e32b..279ac6a 100644 (file)
@@ -3349,10 +3349,10 @@ static void mlx5_vdpa_dev_del(struct vdpa_mgmt_dev *v_mdev, struct vdpa_device *
        mlx5_vdpa_remove_debugfs(ndev->debugfs);
        ndev->debugfs = NULL;
        unregister_link_notifier(ndev);
+       _vdpa_unregister_device(dev);
        wq = mvdev->wq;
        mvdev->wq = NULL;
        destroy_workqueue(wq);
-       _vdpa_unregister_device(dev);
        mgtdev->ndev = NULL;
 }
 
index de97e38..5f5c216 100644 (file)
@@ -1685,6 +1685,9 @@ static bool vduse_validate_config(struct vduse_dev_config *config)
        if (config->vq_num > 0xffff)
                return false;
 
+       if (!config->name[0])
+               return false;
+
        if (!device_is_allowed(config->device_id))
                return false;
 
index 07181cd..ae22731 100644 (file)
@@ -935,13 +935,18 @@ static void handle_tx_zerocopy(struct vhost_net *net, struct socket *sock)
 
                err = sock->ops->sendmsg(sock, &msg, len);
                if (unlikely(err < 0)) {
+                       bool retry = err == -EAGAIN || err == -ENOMEM || err == -ENOBUFS;
+
                        if (zcopy_used) {
                                if (vq->heads[ubuf->desc].len == VHOST_DMA_IN_PROGRESS)
                                        vhost_net_ubuf_put(ubufs);
-                               nvq->upend_idx = ((unsigned)nvq->upend_idx - 1)
-                                       % UIO_MAXIOV;
+                               if (retry)
+                                       nvq->upend_idx = ((unsigned)nvq->upend_idx - 1)
+                                               % UIO_MAXIOV;
+                               else
+                                       vq->heads[ubuf->desc].len = VHOST_DMA_DONE_LEN;
                        }
-                       if (err == -EAGAIN || err == -ENOMEM || err == -ENOBUFS) {
+                       if (retry) {
                                vhost_discard_vq_desc(vq, 1);
                                vhost_net_enable_vq(net, vq);
                                break;
index 8c1aefc..bf77924 100644 (file)
@@ -407,7 +407,10 @@ static long vhost_vdpa_set_features(struct vhost_vdpa *v, u64 __user *featurep)
 {
        struct vdpa_device *vdpa = v->vdpa;
        const struct vdpa_config_ops *ops = vdpa->config;
+       struct vhost_dev *d = &v->vdev;
+       u64 actual_features;
        u64 features;
+       int i;
 
        /*
         * It's not allowed to change the features after they have
@@ -422,6 +425,16 @@ static long vhost_vdpa_set_features(struct vhost_vdpa *v, u64 __user *featurep)
        if (vdpa_set_features(vdpa, features))
                return -EINVAL;
 
+       /* let the vqs know what has been configured */
+       actual_features = ops->get_driver_features(vdpa);
+       for (i = 0; i < d->nvqs; ++i) {
+               struct vhost_virtqueue *vq = d->vqs[i];
+
+               mutex_lock(&vq->mutex);
+               vq->acked_features = actual_features;
+               mutex_unlock(&vq->mutex);
+       }
+
        return 0;
 }
 
@@ -594,7 +607,14 @@ static long vhost_vdpa_vring_ioctl(struct vhost_vdpa *v, unsigned int cmd,
                if (r)
                        return r;
 
-               vq->last_avail_idx = vq_state.split.avail_index;
+               if (vhost_has_feature(vq, VIRTIO_F_RING_PACKED)) {
+                       vq->last_avail_idx = vq_state.packed.last_avail_idx |
+                                            (vq_state.packed.last_avail_counter << 15);
+                       vq->last_used_idx = vq_state.packed.last_used_idx |
+                                           (vq_state.packed.last_used_counter << 15);
+               } else {
+                       vq->last_avail_idx = vq_state.split.avail_index;
+               }
                break;
        }
 
@@ -612,9 +632,15 @@ static long vhost_vdpa_vring_ioctl(struct vhost_vdpa *v, unsigned int cmd,
                break;
 
        case VHOST_SET_VRING_BASE:
-               vq_state.split.avail_index = vq->last_avail_idx;
-               if (ops->set_vq_state(vdpa, idx, &vq_state))
-                       r = -EINVAL;
+               if (vhost_has_feature(vq, VIRTIO_F_RING_PACKED)) {
+                       vq_state.packed.last_avail_idx = vq->last_avail_idx & 0x7fff;
+                       vq_state.packed.last_avail_counter = !!(vq->last_avail_idx & 0x8000);
+                       vq_state.packed.last_used_idx = vq->last_used_idx & 0x7fff;
+                       vq_state.packed.last_used_counter = !!(vq->last_used_idx & 0x8000);
+               } else {
+                       vq_state.split.avail_index = vq->last_avail_idx;
+               }
+               r = ops->set_vq_state(vdpa, idx, &vq_state);
                break;
 
        case VHOST_SET_VRING_CALL:
index 0742730..60c9ebd 100644 (file)
@@ -235,7 +235,7 @@ void vhost_dev_flush(struct vhost_dev *dev)
 {
        struct vhost_flush_struct flush;
 
-       if (dev->worker) {
+       if (dev->worker.vtsk) {
                init_completion(&flush.wait_event);
                vhost_work_init(&flush.work, vhost_flush_work);
 
@@ -247,7 +247,7 @@ EXPORT_SYMBOL_GPL(vhost_dev_flush);
 
 void vhost_work_queue(struct vhost_dev *dev, struct vhost_work *work)
 {
-       if (!dev->worker)
+       if (!dev->worker.vtsk)
                return;
 
        if (!test_and_set_bit(VHOST_WORK_QUEUED, &work->flags)) {
@@ -255,8 +255,8 @@ void vhost_work_queue(struct vhost_dev *dev, struct vhost_work *work)
                 * sure it was not in the list.
                 * test_and_set_bit() implies a memory barrier.
                 */
-               llist_add(&work->node, &dev->worker->work_list);
-               vhost_task_wake(dev->worker->vtsk);
+               llist_add(&work->node, &dev->worker.work_list);
+               vhost_task_wake(dev->worker.vtsk);
        }
 }
 EXPORT_SYMBOL_GPL(vhost_work_queue);
@@ -264,7 +264,7 @@ EXPORT_SYMBOL_GPL(vhost_work_queue);
 /* A lockless hint for busy polling code to exit the loop */
 bool vhost_has_work(struct vhost_dev *dev)
 {
-       return dev->worker && !llist_empty(&dev->worker->work_list);
+       return !llist_empty(&dev->worker.work_list);
 }
 EXPORT_SYMBOL_GPL(vhost_has_work);
 
@@ -341,6 +341,8 @@ static bool vhost_worker(void *data)
 
        node = llist_del_all(&worker->work_list);
        if (node) {
+               __set_current_state(TASK_RUNNING);
+
                node = llist_reverse_order(node);
                /* make sure flag is seen after deletion */
                smp_wmb();
@@ -456,7 +458,8 @@ void vhost_dev_init(struct vhost_dev *dev,
        dev->umem = NULL;
        dev->iotlb = NULL;
        dev->mm = NULL;
-       dev->worker = NULL;
+       memset(&dev->worker, 0, sizeof(dev->worker));
+       init_llist_head(&dev->worker.work_list);
        dev->iov_limit = iov_limit;
        dev->weight = weight;
        dev->byte_weight = byte_weight;
@@ -530,47 +533,30 @@ static void vhost_detach_mm(struct vhost_dev *dev)
 
 static void vhost_worker_free(struct vhost_dev *dev)
 {
-       struct vhost_worker *worker = dev->worker;
-
-       if (!worker)
+       if (!dev->worker.vtsk)
                return;
 
-       dev->worker = NULL;
-       WARN_ON(!llist_empty(&worker->work_list));
-       vhost_task_stop(worker->vtsk);
-       kfree(worker);
+       WARN_ON(!llist_empty(&dev->worker.work_list));
+       vhost_task_stop(dev->worker.vtsk);
+       dev->worker.kcov_handle = 0;
+       dev->worker.vtsk = NULL;
 }
 
 static int vhost_worker_create(struct vhost_dev *dev)
 {
-       struct vhost_worker *worker;
        struct vhost_task *vtsk;
        char name[TASK_COMM_LEN];
-       int ret;
-
-       worker = kzalloc(sizeof(*worker), GFP_KERNEL_ACCOUNT);
-       if (!worker)
-               return -ENOMEM;
 
-       dev->worker = worker;
-       worker->kcov_handle = kcov_common_handle();
-       init_llist_head(&worker->work_list);
        snprintf(name, sizeof(name), "vhost-%d", current->pid);
 
-       vtsk = vhost_task_create(vhost_worker, worker, name);
-       if (!vtsk) {
-               ret = -ENOMEM;
-               goto free_worker;
-       }
+       vtsk = vhost_task_create(vhost_worker, &dev->worker, name);
+       if (!vtsk)
+               return -ENOMEM;
 
-       worker->vtsk = vtsk;
+       dev->worker.kcov_handle = kcov_common_handle();
+       dev->worker.vtsk = vtsk;
        vhost_task_start(vtsk);
        return 0;
-
-free_worker:
-       kfree(worker);
-       dev->worker = NULL;
-       return ret;
 }
 
 /* Caller should have device mutex */
@@ -1614,17 +1600,25 @@ long vhost_vring_ioctl(struct vhost_dev *d, unsigned int ioctl, void __user *arg
                        r = -EFAULT;
                        break;
                }
-               if (s.num > 0xffff) {
-                       r = -EINVAL;
-                       break;
+               if (vhost_has_feature(vq, VIRTIO_F_RING_PACKED)) {
+                       vq->last_avail_idx = s.num & 0xffff;
+                       vq->last_used_idx = (s.num >> 16) & 0xffff;
+               } else {
+                       if (s.num > 0xffff) {
+                               r = -EINVAL;
+                               break;
+                       }
+                       vq->last_avail_idx = s.num;
                }
-               vq->last_avail_idx = s.num;
                /* Forget the cached index value. */
                vq->avail_idx = vq->last_avail_idx;
                break;
        case VHOST_GET_VRING_BASE:
                s.index = idx;
-               s.num = vq->last_avail_idx;
+               if (vhost_has_feature(vq, VIRTIO_F_RING_PACKED))
+                       s.num = (u32)vq->last_avail_idx | ((u32)vq->last_used_idx << 16);
+               else
+                       s.num = vq->last_avail_idx;
                if (copy_to_user(argp, &s, sizeof s))
                        r = -EFAULT;
                break;
@@ -2563,12 +2557,11 @@ EXPORT_SYMBOL_GPL(vhost_disable_notify);
 /* Create a new message. */
 struct vhost_msg_node *vhost_new_msg(struct vhost_virtqueue *vq, int type)
 {
-       struct vhost_msg_node *node = kmalloc(sizeof *node, GFP_KERNEL);
+       /* Make sure all padding within the structure is initialized. */
+       struct vhost_msg_node *node = kzalloc(sizeof(*node), GFP_KERNEL);
        if (!node)
                return NULL;
 
-       /* Make sure all padding within the structure is initialized. */
-       memset(&node->msg, 0, sizeof node->msg);
        node->vq = vq;
        node->msg.type = type;
        return node;
index 0308638..fc900be 100644 (file)
@@ -92,13 +92,17 @@ struct vhost_virtqueue {
        /* The routine to call when the Guest pings us, or timeout. */
        vhost_work_fn_t handle_kick;
 
-       /* Last available index we saw. */
+       /* Last available index we saw.
+        * Values are limited to 0x7fff, and the high bit is used as
+        * a wrap counter when using VIRTIO_F_RING_PACKED. */
        u16 last_avail_idx;
 
        /* Caches available index value from user. */
        u16 avail_idx;
 
-       /* Last index we used. */
+       /* Last index we used.
+        * Values are limited to 0x7fff, and the high bit is used as
+        * a wrap counter when using VIRTIO_F_RING_PACKED. */
        u16 last_used_idx;
 
        /* Used flags */
@@ -154,7 +158,7 @@ struct vhost_dev {
        struct vhost_virtqueue **vqs;
        int nvqs;
        struct eventfd_ctx *log_ctx;
-       struct vhost_worker *worker;
+       struct vhost_worker worker;
        struct vhost_iotlb *umem;
        struct vhost_iotlb *iotlb;
        spinlock_t iotlb_lock;
index 2b1b227..88e6d10 100644 (file)
@@ -242,7 +242,6 @@ static int btrfs_repair_eb_io_failure(const struct extent_buffer *eb,
                                      int mirror_num)
 {
        struct btrfs_fs_info *fs_info = eb->fs_info;
-       u64 start = eb->start;
        int i, num_pages = num_extent_pages(eb);
        int ret = 0;
 
@@ -251,12 +250,14 @@ static int btrfs_repair_eb_io_failure(const struct extent_buffer *eb,
 
        for (i = 0; i < num_pages; i++) {
                struct page *p = eb->pages[i];
+               u64 start = max_t(u64, eb->start, page_offset(p));
+               u64 end = min_t(u64, eb->start + eb->len, page_offset(p) + PAGE_SIZE);
+               u32 len = end - start;
 
-               ret = btrfs_repair_io_failure(fs_info, 0, start, PAGE_SIZE,
-                               start, p, start - page_offset(p), mirror_num);
+               ret = btrfs_repair_io_failure(fs_info, 0, start, len,
+                               start, p, offset_in_page(start), mirror_num);
                if (ret)
                        break;
-               start += PAGE_SIZE;
        }
 
        return ret;
index 7c66651..50c241a 100644 (file)
@@ -134,8 +134,14 @@ struct scrub_stripe {
         * The errors hit during the initial read of the stripe.
         *
         * Would be utilized for error reporting and repair.
+        *
+        * The remaining init_nr_* records the number of errors hit, only used
+        * by error reporting.
         */
        unsigned long init_error_bitmap;
+       unsigned int init_nr_io_errors;
+       unsigned int init_nr_csum_errors;
+       unsigned int init_nr_meta_errors;
 
        /*
         * The following error bitmaps are all for the current status.
@@ -1003,12 +1009,9 @@ skip:
        sctx->stat.data_bytes_scrubbed += nr_data_sectors << fs_info->sectorsize_bits;
        sctx->stat.tree_bytes_scrubbed += nr_meta_sectors << fs_info->sectorsize_bits;
        sctx->stat.no_csum += nr_nodatacsum_sectors;
-       sctx->stat.read_errors +=
-               bitmap_weight(&stripe->io_error_bitmap, stripe->nr_sectors);
-       sctx->stat.csum_errors +=
-               bitmap_weight(&stripe->csum_error_bitmap, stripe->nr_sectors);
-       sctx->stat.verify_errors +=
-               bitmap_weight(&stripe->meta_error_bitmap, stripe->nr_sectors);
+       sctx->stat.read_errors += stripe->init_nr_io_errors;
+       sctx->stat.csum_errors += stripe->init_nr_csum_errors;
+       sctx->stat.verify_errors += stripe->init_nr_meta_errors;
        sctx->stat.uncorrectable_errors +=
                bitmap_weight(&stripe->error_bitmap, stripe->nr_sectors);
        sctx->stat.corrected_errors += nr_repaired_sectors;
@@ -1041,6 +1044,12 @@ static void scrub_stripe_read_repair_worker(struct work_struct *work)
        scrub_verify_one_stripe(stripe, stripe->extent_sector_bitmap);
        /* Save the initial failed bitmap for later repair and report usage. */
        stripe->init_error_bitmap = stripe->error_bitmap;
+       stripe->init_nr_io_errors = bitmap_weight(&stripe->io_error_bitmap,
+                                                 stripe->nr_sectors);
+       stripe->init_nr_csum_errors = bitmap_weight(&stripe->csum_error_bitmap,
+                                                   stripe->nr_sectors);
+       stripe->init_nr_meta_errors = bitmap_weight(&stripe->meta_error_bitmap,
+                                                   stripe->nr_sectors);
 
        if (bitmap_empty(&stripe->init_error_bitmap, stripe->nr_sectors))
                goto out;
@@ -1490,6 +1499,9 @@ static void scrub_stripe_reset_bitmaps(struct scrub_stripe *stripe)
 {
        stripe->extent_sector_bitmap = 0;
        stripe->init_error_bitmap = 0;
+       stripe->init_nr_io_errors = 0;
+       stripe->init_nr_csum_errors = 0;
+       stripe->init_nr_meta_errors = 0;
        stripe->error_bitmap = 0;
        stripe->io_error_bitmap = 0;
        stripe->csum_error_bitmap = 0;
@@ -1730,7 +1742,7 @@ static int flush_scrub_stripes(struct scrub_ctx *sctx)
                                break;
                        }
                }
-       } else {
+       } else if (!sctx->readonly) {
                for (int i = 0; i < nr_stripes; i++) {
                        unsigned long repaired;
 
index ec18e22..efeb1a9 100644 (file)
@@ -1841,6 +1841,12 @@ static int btrfs_remount(struct super_block *sb, int *flags, char *data)
                btrfs_clear_sb_rdonly(sb);
 
                set_bit(BTRFS_FS_OPEN, &fs_info->flags);
+
+               /*
+                * If we've gone from readonly -> read/write, we need to get
+                * our sync/async discard lists in the right state.
+                */
+               btrfs_discard_resume(fs_info);
        }
 out:
        /*
index 789be30..2321e5d 100644 (file)
@@ -1627,6 +1627,7 @@ void ceph_flush_snaps(struct ceph_inode_info *ci,
        struct inode *inode = &ci->netfs.inode;
        struct ceph_mds_client *mdsc = ceph_inode_to_client(inode)->mdsc;
        struct ceph_mds_session *session = NULL;
+       bool need_put = false;
        int mds;
 
        dout("ceph_flush_snaps %p\n", inode);
@@ -1671,8 +1672,13 @@ out:
                ceph_put_mds_session(session);
        /* we flushed them all; remove this inode from the queue */
        spin_lock(&mdsc->snap_flush_lock);
+       if (!list_empty(&ci->i_snap_flush_item))
+               need_put = true;
        list_del_init(&ci->i_snap_flush_item);
        spin_unlock(&mdsc->snap_flush_lock);
+
+       if (need_put)
+               iput(inode);
 }
 
 /*
index 0b236eb..2e73ba6 100644 (file)
@@ -693,8 +693,10 @@ int __ceph_finish_cap_snap(struct ceph_inode_info *ci,
             capsnap->size);
 
        spin_lock(&mdsc->snap_flush_lock);
-       if (list_empty(&ci->i_snap_flush_item))
+       if (list_empty(&ci->i_snap_flush_item)) {
+               ihold(inode);
                list_add_tail(&ci->i_snap_flush_item, &mdsc->snap_flush_list);
+       }
        spin_unlock(&mdsc->snap_flush_lock);
        return 1;  /* caller may want to ceph_flush_snaps */
 }
index 9804834..266d45c 100644 (file)
@@ -1805,7 +1805,11 @@ static int ep_autoremove_wake_function(struct wait_queue_entry *wq_entry,
 {
        int ret = default_wake_function(wq_entry, mode, sync, key);
 
-       list_del_init(&wq_entry->entry);
+       /*
+        * Pairs with list_empty_careful in ep_poll, and ensures future loop
+        * iterations see the cause of this wakeup.
+        */
+       list_del_init_careful(&wq_entry->entry);
        return ret;
 }
 
index c1edde8..1f72f97 100644 (file)
@@ -324,17 +324,15 @@ static ext4_fsblk_t ext4_valid_block_bitmap_padding(struct super_block *sb,
 struct ext4_group_info *ext4_get_group_info(struct super_block *sb,
                                            ext4_group_t group)
 {
-        struct ext4_group_info **grp_info;
-        long indexv, indexh;
-
-        if (unlikely(group >= EXT4_SB(sb)->s_groups_count)) {
-                ext4_error(sb, "invalid group %u", group);
-                return NULL;
-        }
-        indexv = group >> (EXT4_DESC_PER_BLOCK_BITS(sb));
-        indexh = group & ((EXT4_DESC_PER_BLOCK(sb)) - 1);
-        grp_info = sbi_array_rcu_deref(EXT4_SB(sb), s_group_info, indexv);
-        return grp_info[indexh];
+       struct ext4_group_info **grp_info;
+       long indexv, indexh;
+
+       if (unlikely(group >= EXT4_SB(sb)->s_groups_count))
+               return NULL;
+       indexv = group >> (EXT4_DESC_PER_BLOCK_BITS(sb));
+       indexh = group & ((EXT4_DESC_PER_BLOCK(sb)) - 1);
+       grp_info = sbi_array_rcu_deref(EXT4_SB(sb), s_group_info, indexv);
+       return grp_info[indexh];
 }
 
 /*
@@ -886,7 +884,10 @@ static unsigned long ext4_bg_num_gdb_nometa(struct super_block *sb,
        if (!ext4_bg_has_super(sb, group))
                return 0;
 
-       return EXT4_SB(sb)->s_gdb_count;
+       if (ext4_has_feature_meta_bg(sb))
+               return le32_to_cpu(EXT4_SB(sb)->s_es->s_first_meta_bg);
+       else
+               return EXT4_SB(sb)->s_gdb_count;
 }
 
 /**
index 56a5d1c..05fcecc 100644 (file)
@@ -6388,7 +6388,6 @@ static int __ext4_remount(struct fs_context *fc, struct super_block *sb)
        struct ext4_mount_options old_opts;
        ext4_group_t g;
        int err = 0;
-       int enable_rw = 0;
 #ifdef CONFIG_QUOTA
        int enable_quota = 0;
        int i, j;
@@ -6575,7 +6574,7 @@ static int __ext4_remount(struct fs_context *fc, struct super_block *sb)
                        if (err)
                                goto restore_opts;
 
-                       enable_rw = 1;
+                       sb->s_flags &= ~SB_RDONLY;
                        if (ext4_has_feature_mmp(sb)) {
                                err = ext4_multi_mount_protect(sb,
                                                le64_to_cpu(es->s_mmp_block));
@@ -6622,9 +6621,6 @@ static int __ext4_remount(struct fs_context *fc, struct super_block *sb)
        if (!test_opt(sb, BLOCK_VALIDITY) && sbi->s_system_blks)
                ext4_release_system_zone(sb);
 
-       if (enable_rw)
-               sb->s_flags &= ~SB_RDONLY;
-
        /*
         * Reinitialize lazy itable initialization thread based on
         * current settings
index 13d7f17..321e3a8 100644 (file)
@@ -2056,8 +2056,9 @@ inserted:
                        else {
                                u32 ref;
 
+#ifdef EXT4_XATTR_DEBUG
                                WARN_ON_ONCE(dquot_initialize_needed(inode));
-
+#endif
                                /* The old block is released after updating
                                   the inode. */
                                error = dquot_alloc_block(inode,
@@ -2120,8 +2121,9 @@ inserted:
                        /* We need to allocate a new block */
                        ext4_fsblk_t goal, block;
 
+#ifdef EXT4_XATTR_DEBUG
                        WARN_ON_ONCE(dquot_initialize_needed(inode));
-
+#endif
                        goal = ext4_group_first_block_no(sb,
                                                EXT4_I(inode)->i_block_group);
                        block = ext4_new_meta_blocks(handle, inode, goal, 0,
index e956f88..5710833 100644 (file)
@@ -285,6 +285,14 @@ void nilfs_btnode_abort_change_key(struct address_space *btnc,
        if (nbh == NULL) {      /* blocksize == pagesize */
                xa_erase_irq(&btnc->i_pages, newkey);
                unlock_page(ctxt->bh->b_page);
-       } else
-               brelse(nbh);
+       } else {
+               /*
+                * When canceling a buffer that a prepare operation has
+                * allocated to copy a node block to another location, use
+                * nilfs_btnode_delete() to initialize and release the buffer
+                * so that the buffer flags will not be in an inconsistent
+                * state when it is reallocated.
+                */
+               nilfs_btnode_delete(nbh);
+       }
 }
index dc359b5..2c6078a 100644 (file)
@@ -779,6 +779,15 @@ int nilfs_sufile_resize(struct inode *sufile, __u64 newnsegs)
                        goto out_header;
 
                sui->ncleansegs -= nsegs - newnsegs;
+
+               /*
+                * If the sufile is successfully truncated, immediately adjust
+                * the segment allocation space while locking the semaphore
+                * "mi_sem" so that nilfs_sufile_alloc() never allocates
+                * segments in the truncated space.
+                */
+               sui->allocmax = newnsegs - 1;
+               sui->allocmin = 0;
        }
 
        kaddr = kmap_atomic(header_bh->b_page);
index 2894152..0f06679 100644 (file)
@@ -405,6 +405,18 @@ unsigned long nilfs_nrsvsegs(struct the_nilfs *nilfs, unsigned long nsegs)
                                  100));
 }
 
+/**
+ * nilfs_max_segment_count - calculate the maximum number of segments
+ * @nilfs: nilfs object
+ */
+static u64 nilfs_max_segment_count(struct the_nilfs *nilfs)
+{
+       u64 max_count = U64_MAX;
+
+       do_div(max_count, nilfs->ns_blocks_per_segment);
+       return min_t(u64, max_count, ULONG_MAX);
+}
+
 void nilfs_set_nsegments(struct the_nilfs *nilfs, unsigned long nsegs)
 {
        nilfs->ns_nsegments = nsegs;
@@ -414,6 +426,8 @@ void nilfs_set_nsegments(struct the_nilfs *nilfs, unsigned long nsegs)
 static int nilfs_store_disk_layout(struct the_nilfs *nilfs,
                                   struct nilfs_super_block *sbp)
 {
+       u64 nsegments, nblocks;
+
        if (le32_to_cpu(sbp->s_rev_level) < NILFS_MIN_SUPP_REV) {
                nilfs_err(nilfs->ns_sb,
                          "unsupported revision (superblock rev.=%d.%d, current rev.=%d.%d). Please check the version of mkfs.nilfs(2).",
@@ -457,7 +471,34 @@ static int nilfs_store_disk_layout(struct the_nilfs *nilfs,
                return -EINVAL;
        }
 
-       nilfs_set_nsegments(nilfs, le64_to_cpu(sbp->s_nsegments));
+       nsegments = le64_to_cpu(sbp->s_nsegments);
+       if (nsegments > nilfs_max_segment_count(nilfs)) {
+               nilfs_err(nilfs->ns_sb,
+                         "segment count %llu exceeds upper limit (%llu segments)",
+                         (unsigned long long)nsegments,
+                         (unsigned long long)nilfs_max_segment_count(nilfs));
+               return -EINVAL;
+       }
+
+       nblocks = sb_bdev_nr_blocks(nilfs->ns_sb);
+       if (nblocks) {
+               u64 min_block_count = nsegments * nilfs->ns_blocks_per_segment;
+               /*
+                * To avoid failing to mount early device images without a
+                * second superblock, exclude that block count from the
+                * "min_block_count" calculation.
+                */
+
+               if (nblocks < min_block_count) {
+                       nilfs_err(nilfs->ns_sb,
+                                 "total number of segment blocks %llu exceeds device size (%llu blocks)",
+                                 (unsigned long long)min_block_count,
+                                 (unsigned long long)nblocks);
+                       return -EINVAL;
+               }
+       }
+
+       nilfs_set_nsegments(nilfs, nsegments);
        nilfs->ns_crc_seed = le32_to_cpu(sbp->s_crc_seed);
        return 0;
 }
index efb09de..b173c36 100644 (file)
@@ -2100,14 +2100,20 @@ static long ocfs2_fallocate(struct file *file, int mode, loff_t offset,
        struct ocfs2_space_resv sr;
        int change_size = 1;
        int cmd = OCFS2_IOC_RESVSP64;
+       int ret = 0;
 
        if (mode & ~(FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE))
                return -EOPNOTSUPP;
        if (!ocfs2_writes_unwritten_extents(osb))
                return -EOPNOTSUPP;
 
-       if (mode & FALLOC_FL_KEEP_SIZE)
+       if (mode & FALLOC_FL_KEEP_SIZE) {
                change_size = 0;
+       } else {
+               ret = inode_newsize_ok(inode, offset + len);
+               if (ret)
+                       return ret;
+       }
 
        if (mode & FALLOC_FL_PUNCH_HOLE)
                cmd = OCFS2_IOC_UNRESVSP64;
index 0b0e6a1..988d1c0 100644 (file)
@@ -952,8 +952,10 @@ static void ocfs2_disable_quotas(struct ocfs2_super *osb)
        for (type = 0; type < OCFS2_MAXQUOTAS; type++) {
                if (!sb_has_quota_loaded(sb, type))
                        continue;
-               oinfo = sb_dqinfo(sb, type)->dqi_priv;
-               cancel_delayed_work_sync(&oinfo->dqi_sync_work);
+               if (!sb_has_quota_suspended(sb, type)) {
+                       oinfo = sb_dqinfo(sb, type)->dqi_priv;
+                       cancel_delayed_work_sync(&oinfo->dqi_sync_work);
+               }
                inode = igrab(sb->s_dquot.files[type]);
                /* Turn off quotas. This will remove all dquot structures from
                 * memory and so they will be automatically synced to global
index 5034b86..b279f74 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/module.h>
 #include <linux/proc_fs.h>
 #include <linux/uaccess.h>
+#include <uapi/linux/ethtool.h>
 #include "cifspdu.h"
 #include "cifsglob.h"
 #include "cifsproto.h"
@@ -130,12 +131,14 @@ cifs_dump_channel(struct seq_file *m, int i, struct cifs_chan *chan)
        struct TCP_Server_Info *server = chan->server;
 
        seq_printf(m, "\n\n\t\tChannel: %d ConnectionId: 0x%llx"
-                  "\n\t\tNumber of credits: %d Dialect 0x%x"
+                  "\n\t\tNumber of credits: %d,%d,%d Dialect 0x%x"
                   "\n\t\tTCP status: %d Instance: %d"
                   "\n\t\tLocal Users To Server: %d SecMode: 0x%x Req On Wire: %d"
                   "\n\t\tIn Send: %d In MaxReq Wait: %d",
                   i+1, server->conn_id,
                   server->credits,
+                  server->echo_credits,
+                  server->oplock_credits,
                   server->dialect,
                   server->tcpStatus,
                   server->reconnect_instance,
@@ -146,18 +149,62 @@ cifs_dump_channel(struct seq_file *m, int i, struct cifs_chan *chan)
                   atomic_read(&server->num_waiters));
 }
 
+static inline const char *smb_speed_to_str(size_t bps)
+{
+       size_t mbps = bps / 1000 / 1000;
+
+       switch (mbps) {
+       case SPEED_10:
+               return "10Mbps";
+       case SPEED_100:
+               return "100Mbps";
+       case SPEED_1000:
+               return "1Gbps";
+       case SPEED_2500:
+               return "2.5Gbps";
+       case SPEED_5000:
+               return "5Gbps";
+       case SPEED_10000:
+               return "10Gbps";
+       case SPEED_14000:
+               return "14Gbps";
+       case SPEED_20000:
+               return "20Gbps";
+       case SPEED_25000:
+               return "25Gbps";
+       case SPEED_40000:
+               return "40Gbps";
+       case SPEED_50000:
+               return "50Gbps";
+       case SPEED_56000:
+               return "56Gbps";
+       case SPEED_100000:
+               return "100Gbps";
+       case SPEED_200000:
+               return "200Gbps";
+       case SPEED_400000:
+               return "400Gbps";
+       case SPEED_800000:
+               return "800Gbps";
+       default:
+               return "Unknown";
+       }
+}
+
 static void
 cifs_dump_iface(struct seq_file *m, struct cifs_server_iface *iface)
 {
        struct sockaddr_in *ipv4 = (struct sockaddr_in *)&iface->sockaddr;
        struct sockaddr_in6 *ipv6 = (struct sockaddr_in6 *)&iface->sockaddr;
 
-       seq_printf(m, "\tSpeed: %zu bps\n", iface->speed);
+       seq_printf(m, "\tSpeed: %s\n", smb_speed_to_str(iface->speed));
        seq_puts(m, "\t\tCapabilities: ");
        if (iface->rdma_capable)
                seq_puts(m, "rdma ");
        if (iface->rss_capable)
                seq_puts(m, "rss ");
+       if (!iface->rdma_capable && !iface->rss_capable)
+               seq_puts(m, "None");
        seq_putc(m, '\n');
        if (iface->sockaddr.ss_family == AF_INET)
                seq_printf(m, "\t\tIPv4: %pI4\n", &ipv4->sin_addr);
@@ -350,8 +397,11 @@ static int cifs_debug_data_proc_show(struct seq_file *m, void *v)
                        atomic_read(&server->smbd_conn->mr_used_count));
 skip_rdma:
 #endif
-               seq_printf(m, "\nNumber of credits: %d Dialect 0x%x",
-                       server->credits,  server->dialect);
+               seq_printf(m, "\nNumber of credits: %d,%d,%d Dialect 0x%x",
+                       server->credits,
+                       server->echo_credits,
+                       server->oplock_credits,
+                       server->dialect);
                if (server->compress_algorithm == SMB3_COMPRESS_LZNT1)
                        seq_printf(m, " COMPRESS_LZNT1");
                else if (server->compress_algorithm == SMB3_COMPRESS_LZ77)
index 0d84bb1..b212a4e 100644 (file)
@@ -970,43 +970,6 @@ release_iface(struct kref *ref)
        kfree(iface);
 }
 
-/*
- * compare two interfaces a and b
- * return 0 if everything matches.
- * return 1 if a has higher link speed, or rdma capable, or rss capable
- * return -1 otherwise.
- */
-static inline int
-iface_cmp(struct cifs_server_iface *a, struct cifs_server_iface *b)
-{
-       int cmp_ret = 0;
-
-       WARN_ON(!a || !b);
-       if (a->speed == b->speed) {
-               if (a->rdma_capable == b->rdma_capable) {
-                       if (a->rss_capable == b->rss_capable) {
-                               cmp_ret = memcmp(&a->sockaddr, &b->sockaddr,
-                                                sizeof(a->sockaddr));
-                               if (!cmp_ret)
-                                       return 0;
-                               else if (cmp_ret > 0)
-                                       return 1;
-                               else
-                                       return -1;
-                       } else if (a->rss_capable > b->rss_capable)
-                               return 1;
-                       else
-                               return -1;
-               } else if (a->rdma_capable > b->rdma_capable)
-                       return 1;
-               else
-                       return -1;
-       } else if (a->speed > b->speed)
-               return 1;
-       else
-               return -1;
-}
-
 struct cifs_chan {
        unsigned int in_reconnect : 1; /* if session setup in progress for this channel */
        struct TCP_Server_Info *server;
index c1c7049..d127ade 100644 (file)
@@ -87,6 +87,7 @@ extern int cifs_handle_standard(struct TCP_Server_Info *server,
                                struct mid_q_entry *mid);
 extern int smb3_parse_devname(const char *devname, struct smb3_fs_context *ctx);
 extern int smb3_parse_opt(const char *options, const char *key, char **val);
+extern int cifs_ipaddr_cmp(struct sockaddr *srcaddr, struct sockaddr *rhs);
 extern bool cifs_match_ipaddr(struct sockaddr *srcaddr, struct sockaddr *rhs);
 extern int cifs_discard_remaining_data(struct TCP_Server_Info *server);
 extern int cifs_call_async(struct TCP_Server_Info *server,
index 8e9a672..9d16626 100644 (file)
@@ -1288,6 +1288,56 @@ next_pdu:
        module_put_and_kthread_exit(0);
 }
 
+int
+cifs_ipaddr_cmp(struct sockaddr *srcaddr, struct sockaddr *rhs)
+{
+       struct sockaddr_in *saddr4 = (struct sockaddr_in *)srcaddr;
+       struct sockaddr_in *vaddr4 = (struct sockaddr_in *)rhs;
+       struct sockaddr_in6 *saddr6 = (struct sockaddr_in6 *)srcaddr;
+       struct sockaddr_in6 *vaddr6 = (struct sockaddr_in6 *)rhs;
+
+       switch (srcaddr->sa_family) {
+       case AF_UNSPEC:
+               switch (rhs->sa_family) {
+               case AF_UNSPEC:
+                       return 0;
+               case AF_INET:
+               case AF_INET6:
+                       return 1;
+               default:
+                       return -1;
+               }
+       case AF_INET: {
+               switch (rhs->sa_family) {
+               case AF_UNSPEC:
+                       return -1;
+               case AF_INET:
+                       return memcmp(saddr4, vaddr4,
+                                     sizeof(struct sockaddr_in));
+               case AF_INET6:
+                       return 1;
+               default:
+                       return -1;
+               }
+       }
+       case AF_INET6: {
+               switch (rhs->sa_family) {
+               case AF_UNSPEC:
+               case AF_INET:
+                       return -1;
+               case AF_INET6:
+                       return memcmp(saddr6,
+                                     vaddr6,
+                                     sizeof(struct sockaddr_in6));
+               default:
+                       return -1;
+               }
+       }
+       default:
+               return -1; /* don't expect to be here */
+       }
+}
+
 /*
  * Returns true if srcaddr isn't specified and rhs isn't specified, or
  * if srcaddr is specified and matches the IP address of the rhs argument
@@ -4086,16 +4136,17 @@ int cifs_tree_connect(const unsigned int xid, struct cifs_tcon *tcon, const stru
 
        /* only send once per connect */
        spin_lock(&tcon->tc_lock);
+       if (tcon->status == TID_GOOD) {
+               spin_unlock(&tcon->tc_lock);
+               return 0;
+       }
+
        if (tcon->status != TID_NEW &&
            tcon->status != TID_NEED_TCON) {
                spin_unlock(&tcon->tc_lock);
                return -EHOSTDOWN;
        }
 
-       if (tcon->status == TID_GOOD) {
-               spin_unlock(&tcon->tc_lock);
-               return 0;
-       }
        tcon->status = TID_IN_TCON;
        spin_unlock(&tcon->tc_lock);
 
index 2f93bf8..2390b2f 100644 (file)
@@ -575,16 +575,17 @@ int cifs_tree_connect(const unsigned int xid, struct cifs_tcon *tcon, const stru
 
        /* only send once per connect */
        spin_lock(&tcon->tc_lock);
+       if (tcon->status == TID_GOOD) {
+               spin_unlock(&tcon->tc_lock);
+               return 0;
+       }
+
        if (tcon->status != TID_NEW &&
            tcon->status != TID_NEED_TCON) {
                spin_unlock(&tcon->tc_lock);
                return -EHOSTDOWN;
        }
 
-       if (tcon->status == TID_GOOD) {
-               spin_unlock(&tcon->tc_lock);
-               return 0;
-       }
        tcon->status = TID_IN_TCON;
        spin_unlock(&tcon->tc_lock);
 
index df88b8c..0512833 100644 (file)
@@ -4942,9 +4942,13 @@ oplock_break_ack:
         * disconnected since oplock already released by the server
         */
        if (!oplock_break_cancelled) {
-               rc = tcon->ses->server->ops->oplock_response(tcon, persistent_fid,
+               /* check for server null since can race with kill_sb calling tree disconnect */
+               if (tcon->ses && tcon->ses->server) {
+                       rc = tcon->ses->server->ops->oplock_response(tcon, persistent_fid,
                                volatile_fid, net_fid, cinode);
-               cifs_dbg(FYI, "Oplock release rc = %d\n", rc);
+                       cifs_dbg(FYI, "Oplock release rc = %d\n", rc);
+               } else
+                       pr_warn_once("lease break not sent for unmounted share\n");
        }
 
        cifs_done_oplock_break(cinode);
index 6e3be58..a8bb9d0 100644 (file)
@@ -34,6 +34,8 @@ static int
 change_conf(struct TCP_Server_Info *server)
 {
        server->credits += server->echo_credits + server->oplock_credits;
+       if (server->credits > server->max_credits)
+               server->credits = server->max_credits;
        server->oplock_credits = server->echo_credits = 0;
        switch (server->credits) {
        case 0:
@@ -91,6 +93,7 @@ smb2_add_credits(struct TCP_Server_Info *server,
                                            server->conn_id, server->hostname, *val,
                                            add, server->in_flight);
        }
+       WARN_ON_ONCE(server->in_flight == 0);
        server->in_flight--;
        if (server->in_flight == 0 &&
           ((optype & CIFS_OP_MASK) != CIFS_NEG_OP) &&
@@ -510,6 +513,43 @@ smb3_negotiate_rsize(struct cifs_tcon *tcon, struct smb3_fs_context *ctx)
        return rsize;
 }
 
+/*
+ * compare two interfaces a and b
+ * return 0 if everything matches.
+ * return 1 if a is rdma capable, or rss capable, or has higher link speed
+ * return -1 otherwise.
+ */
+static int
+iface_cmp(struct cifs_server_iface *a, struct cifs_server_iface *b)
+{
+       int cmp_ret = 0;
+
+       WARN_ON(!a || !b);
+       if (a->rdma_capable == b->rdma_capable) {
+               if (a->rss_capable == b->rss_capable) {
+                       if (a->speed == b->speed) {
+                               cmp_ret = cifs_ipaddr_cmp((struct sockaddr *) &a->sockaddr,
+                                                         (struct sockaddr *) &b->sockaddr);
+                               if (!cmp_ret)
+                                       return 0;
+                               else if (cmp_ret > 0)
+                                       return 1;
+                               else
+                                       return -1;
+                       } else if (a->speed > b->speed)
+                               return 1;
+                       else
+                               return -1;
+               } else if (a->rss_capable > b->rss_capable)
+                       return 1;
+               else
+                       return -1;
+       } else if (a->rdma_capable > b->rdma_capable)
+               return 1;
+       else
+               return -1;
+}
+
 static int
 parse_server_interfaces(struct network_interface_info_ioctl_rsp *buf,
                        size_t buf_len, struct cifs_ses *ses, bool in_mount)
index 7063b39..17fe212 100644 (file)
@@ -1305,7 +1305,12 @@ SMB2_sess_alloc_buffer(struct SMB2_sess_data *sess_data)
        }
 
        /* enough to enable echos and oplocks and one max size write */
-       req->hdr.CreditRequest = cpu_to_le16(130);
+       if (server->credits >= server->max_credits)
+               req->hdr.CreditRequest = cpu_to_le16(0);
+       else
+               req->hdr.CreditRequest = cpu_to_le16(
+                       min_t(int, server->max_credits -
+                             server->credits, 130));
 
        /* only one of SMB2 signing flags may be set in SMB2 request */
        if (server->sign)
@@ -1899,7 +1904,12 @@ SMB2_tcon(const unsigned int xid, struct cifs_ses *ses, const char *tree,
        rqst.rq_nvec = 2;
 
        /* Need 64 for max size write so ask for more in case not there yet */
-       req->hdr.CreditRequest = cpu_to_le16(64);
+       if (server->credits >= server->max_credits)
+               req->hdr.CreditRequest = cpu_to_le16(0);
+       else
+               req->hdr.CreditRequest = cpu_to_le16(
+                       min_t(int, server->max_credits -
+                             server->credits, 64));
 
        rc = cifs_send_recv(xid, ses, server,
                            &rqst, &resp_buftype, flags, &rsp_iov);
@@ -4227,6 +4237,7 @@ smb2_async_readv(struct cifs_readdata *rdata)
        struct TCP_Server_Info *server;
        struct cifs_tcon *tcon = tlink_tcon(rdata->cfile->tlink);
        unsigned int total_len;
+       int credit_request;
 
        cifs_dbg(FYI, "%s: offset=%llu bytes=%u\n",
                 __func__, rdata->offset, rdata->bytes);
@@ -4258,7 +4269,13 @@ smb2_async_readv(struct cifs_readdata *rdata)
        if (rdata->credits.value > 0) {
                shdr->CreditCharge = cpu_to_le16(DIV_ROUND_UP(rdata->bytes,
                                                SMB2_MAX_BUFFER_SIZE));
-               shdr->CreditRequest = cpu_to_le16(le16_to_cpu(shdr->CreditCharge) + 8);
+               credit_request = le16_to_cpu(shdr->CreditCharge) + 8;
+               if (server->credits >= server->max_credits)
+                       shdr->CreditRequest = cpu_to_le16(0);
+               else
+                       shdr->CreditRequest = cpu_to_le16(
+                               min_t(int, server->max_credits -
+                                               server->credits, credit_request));
 
                rc = adjust_credits(server, &rdata->credits, rdata->bytes);
                if (rc)
@@ -4468,6 +4485,7 @@ smb2_async_writev(struct cifs_writedata *wdata,
        unsigned int total_len;
        struct cifs_io_parms _io_parms;
        struct cifs_io_parms *io_parms = NULL;
+       int credit_request;
 
        if (!wdata->server)
                server = wdata->server = cifs_pick_channel(tcon->ses);
@@ -4572,7 +4590,13 @@ smb2_async_writev(struct cifs_writedata *wdata,
        if (wdata->credits.value > 0) {
                shdr->CreditCharge = cpu_to_le16(DIV_ROUND_UP(wdata->bytes,
                                                    SMB2_MAX_BUFFER_SIZE));
-               shdr->CreditRequest = cpu_to_le16(le16_to_cpu(shdr->CreditCharge) + 8);
+               credit_request = le16_to_cpu(shdr->CreditCharge) + 8;
+               if (server->credits >= server->max_credits)
+                       shdr->CreditRequest = cpu_to_le16(0);
+               else
+                       shdr->CreditRequest = cpu_to_le16(
+                               min_t(int, server->max_credits -
+                                               server->credits, credit_request));
 
                rc = adjust_credits(server, &wdata->credits, io_parms->length);
                if (rc)
index 24bdd5f..0474d0b 100644 (file)
@@ -55,7 +55,7 @@ alloc_mid(const struct smb_hdr *smb_buffer, struct TCP_Server_Info *server)
        temp->pid = current->pid;
        temp->command = cpu_to_le16(smb_buffer->Command);
        cifs_dbg(FYI, "For smb_command %d\n", smb_buffer->Command);
-       /*      do_gettimeofday(&temp->when_sent);*/ /* easier to use jiffies */
+       /* easier to use jiffies */
        /* when mid allocated can be before when sent */
        temp->when_alloc = jiffies;
        temp->server = server;
index 4882a81..2a717d1 100644 (file)
@@ -294,6 +294,9 @@ bool ksmbd_conn_alive(struct ksmbd_conn *conn)
        return true;
 }
 
+#define SMB1_MIN_SUPPORTED_HEADER_SIZE (sizeof(struct smb_hdr))
+#define SMB2_MIN_SUPPORTED_HEADER_SIZE (sizeof(struct smb2_hdr) + 4)
+
 /**
  * ksmbd_conn_handler_loop() - session thread to listen on new smb requests
  * @p:         connection instance
@@ -350,6 +353,9 @@ int ksmbd_conn_handler_loop(void *p)
                if (pdu_size > MAX_STREAM_PROT_LEN)
                        break;
 
+               if (pdu_size < SMB1_MIN_SUPPORTED_HEADER_SIZE)
+                       break;
+
                /* 4 for rfc1002 length field */
                /* 1 for implied bcc[0] */
                size = pdu_size + 4 + 1;
@@ -358,8 +364,6 @@ int ksmbd_conn_handler_loop(void *p)
                        break;
 
                memcpy(conn->request_buf, hdr_buf, sizeof(hdr_buf));
-               if (!ksmbd_smb_request(conn))
-                       break;
 
                /*
                 * We already read 4 bytes to find out PDU size, now
@@ -377,6 +381,15 @@ int ksmbd_conn_handler_loop(void *p)
                        continue;
                }
 
+               if (!ksmbd_smb_request(conn))
+                       break;
+
+               if (((struct smb2_hdr *)smb2_get_msg(conn->request_buf))->ProtocolId ==
+                   SMB2_PROTO_NUMBER) {
+                       if (pdu_size < SMB2_MIN_SUPPORTED_HEADER_SIZE)
+                               break;
+               }
+
                if (!default_conn_ops.process_fn) {
                        pr_err("No connection request callback\n");
                        break;
index db181bd..844b303 100644 (file)
@@ -1415,56 +1415,38 @@ void create_lease_buf(u8 *rbuf, struct lease *lease)
  */
 struct lease_ctx_info *parse_lease_state(void *open_req)
 {
-       char *data_offset;
        struct create_context *cc;
-       unsigned int next = 0;
-       char *name;
-       bool found = false;
        struct smb2_create_req *req = (struct smb2_create_req *)open_req;
-       struct lease_ctx_info *lreq = kzalloc(sizeof(struct lease_ctx_info),
-               GFP_KERNEL);
+       struct lease_ctx_info *lreq;
+
+       cc = smb2_find_context_vals(req, SMB2_CREATE_REQUEST_LEASE, 4);
+       if (IS_ERR_OR_NULL(cc))
+               return NULL;
+
+       lreq = kzalloc(sizeof(struct lease_ctx_info), GFP_KERNEL);
        if (!lreq)
                return NULL;
 
-       data_offset = (char *)req + le32_to_cpu(req->CreateContextsOffset);
-       cc = (struct create_context *)data_offset;
-       do {
-               cc = (struct create_context *)((char *)cc + next);
-               name = le16_to_cpu(cc->NameOffset) + (char *)cc;
-               if (le16_to_cpu(cc->NameLength) != 4 ||
-                   strncmp(name, SMB2_CREATE_REQUEST_LEASE, 4)) {
-                       next = le32_to_cpu(cc->Next);
-                       continue;
-               }
-               found = true;
-               break;
-       } while (next != 0);
+       if (sizeof(struct lease_context_v2) == le32_to_cpu(cc->DataLength)) {
+               struct create_lease_v2 *lc = (struct create_lease_v2 *)cc;
 
-       if (found) {
-               if (sizeof(struct lease_context_v2) == le32_to_cpu(cc->DataLength)) {
-                       struct create_lease_v2 *lc = (struct create_lease_v2 *)cc;
-
-                       memcpy(lreq->lease_key, lc->lcontext.LeaseKey, SMB2_LEASE_KEY_SIZE);
-                       lreq->req_state = lc->lcontext.LeaseState;
-                       lreq->flags = lc->lcontext.LeaseFlags;
-                       lreq->duration = lc->lcontext.LeaseDuration;
-                       memcpy(lreq->parent_lease_key, lc->lcontext.ParentLeaseKey,
-                              SMB2_LEASE_KEY_SIZE);
-                       lreq->version = 2;
-               } else {
-                       struct create_lease *lc = (struct create_lease *)cc;
+               memcpy(lreq->lease_key, lc->lcontext.LeaseKey, SMB2_LEASE_KEY_SIZE);
+               lreq->req_state = lc->lcontext.LeaseState;
+               lreq->flags = lc->lcontext.LeaseFlags;
+               lreq->duration = lc->lcontext.LeaseDuration;
+               memcpy(lreq->parent_lease_key, lc->lcontext.ParentLeaseKey,
+                               SMB2_LEASE_KEY_SIZE);
+               lreq->version = 2;
+       } else {
+               struct create_lease *lc = (struct create_lease *)cc;
 
-                       memcpy(lreq->lease_key, lc->lcontext.LeaseKey, SMB2_LEASE_KEY_SIZE);
-                       lreq->req_state = lc->lcontext.LeaseState;
-                       lreq->flags = lc->lcontext.LeaseFlags;
-                       lreq->duration = lc->lcontext.LeaseDuration;
-                       lreq->version = 1;
-               }
-               return lreq;
+               memcpy(lreq->lease_key, lc->lcontext.LeaseKey, SMB2_LEASE_KEY_SIZE);
+               lreq->req_state = lc->lcontext.LeaseState;
+               lreq->flags = lc->lcontext.LeaseFlags;
+               lreq->duration = lc->lcontext.LeaseDuration;
+               lreq->version = 1;
        }
-
-       kfree(lreq);
-       return NULL;
+       return lreq;
 }
 
 /**
index 7a81541..25c0ba0 100644 (file)
@@ -963,13 +963,13 @@ static void decode_sign_cap_ctxt(struct ksmbd_conn *conn,
 
 static __le32 deassemble_neg_contexts(struct ksmbd_conn *conn,
                                      struct smb2_negotiate_req *req,
-                                     int len_of_smb)
+                                     unsigned int len_of_smb)
 {
        /* +4 is to account for the RFC1001 len field */
        struct smb2_neg_context *pctx = (struct smb2_neg_context *)req;
        int i = 0, len_of_ctxts;
-       int offset = le32_to_cpu(req->NegotiateContextOffset);
-       int neg_ctxt_cnt = le16_to_cpu(req->NegotiateContextCount);
+       unsigned int offset = le32_to_cpu(req->NegotiateContextOffset);
+       unsigned int neg_ctxt_cnt = le16_to_cpu(req->NegotiateContextCount);
        __le32 status = STATUS_INVALID_PARAMETER;
 
        ksmbd_debug(SMB, "decoding %d negotiate contexts\n", neg_ctxt_cnt);
@@ -983,7 +983,7 @@ static __le32 deassemble_neg_contexts(struct ksmbd_conn *conn,
        while (i++ < neg_ctxt_cnt) {
                int clen, ctxt_len;
 
-               if (len_of_ctxts < sizeof(struct smb2_neg_context))
+               if (len_of_ctxts < (int)sizeof(struct smb2_neg_context))
                        break;
 
                pctx = (struct smb2_neg_context *)((char *)pctx + offset);
@@ -1038,9 +1038,8 @@ static __le32 deassemble_neg_contexts(struct ksmbd_conn *conn,
                }
 
                /* offsets must be 8 byte aligned */
-               clen = (clen + 7) & ~0x7;
-               offset = clen + sizeof(struct smb2_neg_context);
-               len_of_ctxts -= clen + sizeof(struct smb2_neg_context);
+               offset = (ctxt_len + 7) & ~0x7;
+               len_of_ctxts -= offset;
        }
        return status;
 }
index af0c2a9..569e5ee 100644 (file)
@@ -158,7 +158,19 @@ int ksmbd_verify_smb_message(struct ksmbd_work *work)
  */
 bool ksmbd_smb_request(struct ksmbd_conn *conn)
 {
-       return conn->request_buf[0] == 0;
+       __le32 *proto = (__le32 *)smb2_get_msg(conn->request_buf);
+
+       if (*proto == SMB2_COMPRESSION_TRANSFORM_ID) {
+               pr_err_ratelimited("smb2 compression not support yet");
+               return false;
+       }
+
+       if (*proto != SMB1_PROTO_NUMBER &&
+           *proto != SMB2_PROTO_NUMBER &&
+           *proto != SMB2_TRANSFORM_PROTO_NUM)
+               return false;
+
+       return true;
 }
 
 static bool supported_protocol(int idx)
index 6d6cfb6..0a5862a 100644 (file)
@@ -1290,7 +1290,7 @@ int smb_check_perm_dacl(struct ksmbd_conn *conn, const struct path *path,
 
        if (IS_ENABLED(CONFIG_FS_POSIX_ACL)) {
                posix_acls = get_inode_acl(d_inode(path->dentry), ACL_TYPE_ACCESS);
-               if (posix_acls && !found) {
+               if (!IS_ERR_OR_NULL(posix_acls) && !found) {
                        unsigned int id = -1;
 
                        pa_entry = posix_acls->a_entries;
@@ -1314,7 +1314,7 @@ int smb_check_perm_dacl(struct ksmbd_conn *conn, const struct path *path,
                                }
                        }
                }
-               if (posix_acls)
+               if (!IS_ERR_OR_NULL(posix_acls))
                        posix_acl_release(posix_acls);
        }
 
index 6f30291..f9fb778 100644 (file)
@@ -1321,7 +1321,7 @@ static struct xattr_smb_acl *ksmbd_vfs_make_xattr_posix_acl(struct mnt_idmap *id
                return NULL;
 
        posix_acls = get_inode_acl(inode, acl_type);
-       if (!posix_acls)
+       if (IS_ERR_OR_NULL(posix_acls))
                return NULL;
 
        smb_acl = kzalloc(sizeof(struct xattr_smb_acl) +
@@ -1830,7 +1830,7 @@ int ksmbd_vfs_inherit_posix_acl(struct mnt_idmap *idmap,
                return -EOPNOTSUPP;
 
        acls = get_inode_acl(parent_inode, ACL_TYPE_DEFAULT);
-       if (!acls)
+       if (IS_ERR_OR_NULL(acls))
                return -ENOENT;
        pace = acls->a_entries;
 
index 0fd96d6..4e800bb 100644 (file)
@@ -1332,6 +1332,7 @@ static int userfaultfd_register(struct userfaultfd_ctx *ctx,
        bool basic_ioctls;
        unsigned long start, end, vma_end;
        struct vma_iterator vmi;
+       pgoff_t pgoff;
 
        user_uffdio_register = (struct uffdio_register __user *) arg;
 
@@ -1459,6 +1460,8 @@ static int userfaultfd_register(struct userfaultfd_ctx *ctx,
 
        vma_iter_set(&vmi, start);
        prev = vma_prev(&vmi);
+       if (vma->vm_start < start)
+               prev = vma;
 
        ret = 0;
        for_each_vma_range(vmi, vma, end) {
@@ -1482,8 +1485,9 @@ static int userfaultfd_register(struct userfaultfd_ctx *ctx,
                vma_end = min(end, vma->vm_end);
 
                new_flags = (vma->vm_flags & ~__VM_UFFD_FLAGS) | vm_flags;
+               pgoff = vma->vm_pgoff + ((start - vma->vm_start) >> PAGE_SHIFT);
                prev = vma_merge(&vmi, mm, prev, start, vma_end, new_flags,
-                                vma->anon_vma, vma->vm_file, vma->vm_pgoff,
+                                vma->anon_vma, vma->vm_file, pgoff,
                                 vma_policy(vma),
                                 ((struct vm_userfaultfd_ctx){ ctx }),
                                 anon_vma_name(vma));
@@ -1563,6 +1567,7 @@ static int userfaultfd_unregister(struct userfaultfd_ctx *ctx,
        unsigned long start, end, vma_end;
        const void __user *buf = (void __user *)arg;
        struct vma_iterator vmi;
+       pgoff_t pgoff;
 
        ret = -EFAULT;
        if (copy_from_user(&uffdio_unregister, buf, sizeof(uffdio_unregister)))
@@ -1625,6 +1630,9 @@ static int userfaultfd_unregister(struct userfaultfd_ctx *ctx,
 
        vma_iter_set(&vmi, start);
        prev = vma_prev(&vmi);
+       if (vma->vm_start < start)
+               prev = vma;
+
        ret = 0;
        for_each_vma_range(vmi, vma, end) {
                cond_resched();
@@ -1662,8 +1670,9 @@ static int userfaultfd_unregister(struct userfaultfd_ctx *ctx,
                        uffd_wp_range(vma, start, vma_end - start, false);
 
                new_flags = vma->vm_flags & ~__VM_UFFD_FLAGS;
+               pgoff = vma->vm_pgoff + ((start - vma->vm_start) >> PAGE_SHIFT);
                prev = vma_merge(&vmi, mm, prev, start, vma_end, new_flags,
-                                vma->anon_vma, vma->vm_file, vma->vm_pgoff,
+                                vma->anon_vma, vma->vm_file, pgoff,
                                 vma_policy(vma),
                                 NULL_VM_UFFD_CTX, anon_vma_name(vma));
                if (prev) {
index 1bf8e87..867b18e 100644 (file)
 #define SM8150_MMCX    9
 #define SM8150_MMCX_AO 10
 
+/* SA8155P is a special case, kept for backwards compatibility */
+#define SA8155P_CX     SM8150_CX
+#define SA8155P_CX_AO  SM8150_CX_AO
+#define SA8155P_EBI    SM8150_EBI
+#define SA8155P_GFX    SM8150_GFX
+#define SA8155P_MSS    SM8150_MSS
+#define SA8155P_MX     SM8150_MX
+#define SA8155P_MX_AO  SM8150_MX_AO
+
 /* SM8250 Power Domain Indexes */
 #define SM8250_CX      0
 #define SM8250_CX_AO   1
index 94d2be5..4b9626c 100644 (file)
@@ -1238,6 +1238,18 @@ static inline u16 mlx5_core_max_vfs(const struct mlx5_core_dev *dev)
        return dev->priv.sriov.max_vfs;
 }
 
+static inline int mlx5_lag_is_lacp_owner(struct mlx5_core_dev *dev)
+{
+       /* LACP owner conditions:
+        * 1) Function is physical.
+        * 2) LAG is supported by FW.
+        * 3) LAG is managed by driver (currently the only option).
+        */
+       return  MLX5_CAP_GEN(dev, vport_group_manager) &&
+                  (MLX5_CAP_GEN(dev, num_lag_ports) > 1) &&
+                   MLX5_CAP_GEN(dev, lag_master);
+}
+
 static inline int mlx5_get_gid_table_len(u16 param)
 {
        if (param > 4) {
index 423220e..93417ba 100644 (file)
@@ -69,9 +69,6 @@ struct llcc_slice_desc {
 /**
  * struct llcc_edac_reg_data - llcc edac registers data for each error type
  * @name: Name of the error
- * @synd_reg: Syndrome register address
- * @count_status_reg: Status register address to read the error count
- * @ways_status_reg: Status register address to read the error ways
  * @reg_cnt: Number of registers
  * @count_mask: Mask value to get the error count
  * @ways_mask: Mask value to get the error ways
@@ -80,9 +77,6 @@ struct llcc_slice_desc {
  */
 struct llcc_edac_reg_data {
        char *name;
-       u64 synd_reg;
-       u64 count_status_reg;
-       u64 ways_status_reg;
        u32 reg_cnt;
        u32 count_mask;
        u32 ways_mask;
index 367d538..e7c4487 100644 (file)
@@ -686,10 +686,7 @@ struct dtv_frontend_properties {
  * @id:                        Frontend ID
  * @exit:              Used to inform the DVB core that the frontend
  *                     thread should exit (usually, means that the hardware
- *                     got disconnected).
- * @remove_mutex:      mutex that avoids a race condition between a callback
- *                     called when the hardware is disconnected and the
- *                     file_operations of dvb_frontend.
+ *                     got disconnected.
  */
 
 struct dvb_frontend {
@@ -707,7 +704,6 @@ struct dvb_frontend {
        int (*callback)(void *adapter_priv, int component, int cmd, int arg);
        int id;
        unsigned int exit;
-       struct mutex remove_mutex;
 };
 
 /**
index d808dc3..811a0f1 100644 (file)
@@ -194,29 +194,6 @@ static inline enum ib_mtu iboe_get_mtu(int mtu)
                return 0;
 }
 
-static inline int iboe_get_rate(struct net_device *dev)
-{
-       struct ethtool_link_ksettings cmd;
-       int err;
-
-       rtnl_lock();
-       err = __ethtool_get_link_ksettings(dev, &cmd);
-       rtnl_unlock();
-       if (err)
-               return IB_RATE_PORT_CURRENT;
-
-       if (cmd.base.speed >= 40000)
-               return IB_RATE_40_GBPS;
-       else if (cmd.base.speed >= 30000)
-               return IB_RATE_30_GBPS;
-       else if (cmd.base.speed >= 20000)
-               return IB_RATE_20_GBPS;
-       else if (cmd.base.speed >= 10000)
-               return IB_RATE_10_GBPS;
-       else
-               return IB_RATE_PORT_CURRENT;
-}
-
 static inline int rdma_link_local_addr(struct in6_addr *addr)
 {
        if (addr->s6_addr32[0] == htonl(0xfe800000) &&
index b271598..fe38eb0 100644 (file)
@@ -221,9 +221,6 @@ static void io_worker_exit(struct io_worker *worker)
        raw_spin_unlock(&wq->lock);
        io_wq_dec_running(worker);
        worker->flags = 0;
-       preempt_disable();
-       current->flags &= ~PF_IO_WORKER;
-       preempt_enable();
 
        kfree_rcu(worker, rcu);
        io_worker_ref_put(wq);
index aeef06c..5407241 100644 (file)
@@ -108,7 +108,7 @@ int cgroup_transfer_tasks(struct cgroup *to, struct cgroup *from)
 
        cgroup_lock();
 
-       percpu_down_write(&cgroup_threadgroup_rwsem);
+       cgroup_attach_lock(true);
 
        /* all tasks in @from are being moved, all csets are source */
        spin_lock_irq(&css_set_lock);
@@ -144,7 +144,7 @@ int cgroup_transfer_tasks(struct cgroup *to, struct cgroup *from)
        } while (task && !ret);
 out_err:
        cgroup_migrate_finish(&mgctx);
-       percpu_up_write(&cgroup_threadgroup_rwsem);
+       cgroup_attach_unlock(true);
        cgroup_unlock();
        return ret;
 }
index 625d748..245cf62 100644 (file)
@@ -6486,19 +6486,18 @@ err:
 static void cgroup_css_set_put_fork(struct kernel_clone_args *kargs)
        __releases(&cgroup_threadgroup_rwsem) __releases(&cgroup_mutex)
 {
+       struct cgroup *cgrp = kargs->cgrp;
+       struct css_set *cset = kargs->cset;
+
        cgroup_threadgroup_change_end(current);
 
-       if (kargs->flags & CLONE_INTO_CGROUP) {
-               struct cgroup *cgrp = kargs->cgrp;
-               struct css_set *cset = kargs->cset;
+       if (cset) {
+               put_css_set(cset);
+               kargs->cset = NULL;
+       }
 
+       if (kargs->flags & CLONE_INTO_CGROUP) {
                cgroup_unlock();
-
-               if (cset) {
-                       put_css_set(cset);
-                       kargs->cset = NULL;
-               }
-
                if (cgrp) {
                        cgroup_put(cgrp);
                        kargs->cgrp = NULL;
index f989f5f..69ee4a2 100644 (file)
@@ -901,10 +901,22 @@ static int kexec_purgatory_setup_sechdrs(struct purgatory_info *pi,
                }
 
                offset = ALIGN(offset, align);
+
+               /*
+                * Check if the segment contains the entry point, if so,
+                * calculate the value of image->start based on it.
+                * If the compiler has produced more than one .text section
+                * (Eg: .text.hot), they are generally after the main .text
+                * section, and they shall not be used to calculate
+                * image->start. So do not re-calculate image->start if it
+                * is not set to the initial value, and warn the user so they
+                * have a chance to fix their purgatory's linker script.
+                */
                if (sechdrs[i].sh_flags & SHF_EXECINSTR &&
                    pi->ehdr->e_entry >= sechdrs[i].sh_addr &&
                    pi->ehdr->e_entry < (sechdrs[i].sh_addr
-                                        + sechdrs[i].sh_size)) {
+                                        + sechdrs[i].sh_size) &&
+                   !WARN_ON(kbuf->image->start != pi->ehdr->e_entry)) {
                        kbuf->image->start -= sechdrs[i].sh_addr;
                        kbuf->image->start += kbuf->mem + offset;
                }
index f80d5c5..da35e5b 100644 (file)
@@ -28,10 +28,6 @@ static int vhost_task_fn(void *data)
        for (;;) {
                bool did_work;
 
-               /* mb paired w/ vhost_task_stop */
-               if (test_bit(VHOST_TASK_FLAGS_STOP, &vtsk->flags))
-                       break;
-
                if (!dead && signal_pending(current)) {
                        struct ksignal ksig;
                        /*
@@ -48,11 +44,17 @@ static int vhost_task_fn(void *data)
                                clear_thread_flag(TIF_SIGPENDING);
                }
 
+               /* mb paired w/ vhost_task_stop */
+               set_current_state(TASK_INTERRUPTIBLE);
+
+               if (test_bit(VHOST_TASK_FLAGS_STOP, &vtsk->flags)) {
+                       __set_current_state(TASK_RUNNING);
+                       break;
+               }
+
                did_work = vtsk->fn(vtsk->data);
-               if (!did_work) {
-                       set_current_state(TASK_INTERRUPTIBLE);
+               if (!did_work)
                        schedule();
-               }
        }
 
        complete(&vtsk->exited);
index 049ba13..1a31065 100644 (file)
@@ -27,6 +27,8 @@
 #include <linux/string.h>
 #include <linux/xarray.h>
 
+#include "radix-tree.h"
+
 /*
  * Radix tree node cache.
  */
diff --git a/lib/radix-tree.h b/lib/radix-tree.h
new file mode 100644 (file)
index 0000000..40d5c03
--- /dev/null
@@ -0,0 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0+
+/* radix-tree helpers that are only shared with xarray */
+
+struct kmem_cache;
+struct rcu_head;
+
+extern struct kmem_cache *radix_tree_node_cachep;
+extern void radix_tree_node_rcu_free(struct rcu_head *head);
index 9dd9745..3718d98 100644 (file)
@@ -369,7 +369,7 @@ vm_map_ram_test(void)
        int i;
 
        map_nr_pages = nr_pages > 0 ? nr_pages:1;
-       pages = kmalloc(map_nr_pages * sizeof(struct page), GFP_KERNEL);
+       pages = kcalloc(map_nr_pages, sizeof(struct page *), GFP_KERNEL);
        if (!pages)
                return -1;
 
index ea9ce1f..2071a37 100644 (file)
@@ -12,6 +12,8 @@
 #include <linux/slab.h>
 #include <linux/xarray.h>
 
+#include "radix-tree.h"
+
 /*
  * Coding conventions in this file:
  *
@@ -247,10 +249,6 @@ void *xas_load(struct xa_state *xas)
 }
 EXPORT_SYMBOL_GPL(xas_load);
 
-/* Move the radix tree node cache here */
-extern struct kmem_cache *radix_tree_node_cachep;
-extern void radix_tree_node_rcu_free(struct rcu_head *head);
-
 #define XA_RCU_FREE    ((struct xarray *)1)
 
 static void xa_node_free(struct xa_node *node)
index d9ef620..91cff7f 100644 (file)
@@ -551,6 +551,8 @@ int damon_set_attrs(struct damon_ctx *ctx, struct damon_attrs *attrs)
                return -EINVAL;
        if (attrs->min_nr_regions > attrs->max_nr_regions)
                return -EINVAL;
+       if (attrs->sample_interval > attrs->aggr_interval)
+               return -EINVAL;
 
        damon_update_monitoring_results(ctx, attrs);
        ctx->attrs = *attrs;
index b4c9bd3..83dda76 100644 (file)
@@ -1760,7 +1760,9 @@ bool __folio_lock_or_retry(struct folio *folio, struct mm_struct *mm,
  *
  * Return: The index of the gap if found, otherwise an index outside the
  * range specified (in which case 'return - index >= max_scan' will be true).
- * In the rare case of index wrap-around, 0 will be returned.
+ * In the rare case of index wrap-around, 0 will be returned.  0 will also
+ * be returned if index == 0 and there is a gap at the index.  We can not
+ * wrap-around if passed index == 0.
  */
 pgoff_t page_cache_next_miss(struct address_space *mapping,
                             pgoff_t index, unsigned long max_scan)
@@ -1770,12 +1772,13 @@ pgoff_t page_cache_next_miss(struct address_space *mapping,
        while (max_scan--) {
                void *entry = xas_next(&xas);
                if (!entry || xa_is_value(entry))
-                       break;
-               if (xas.xa_index == 0)
-                       break;
+                       return xas.xa_index;
+               if (xas.xa_index == 0 && index != 0)
+                       return xas.xa_index;
        }
 
-       return xas.xa_index;
+       /* No gaps in range and no wrap-around, return index beyond range */
+       return xas.xa_index + 1;
 }
 EXPORT_SYMBOL(page_cache_next_miss);
 
@@ -1796,7 +1799,9 @@ EXPORT_SYMBOL(page_cache_next_miss);
  *
  * Return: The index of the gap if found, otherwise an index outside the
  * range specified (in which case 'index - return >= max_scan' will be true).
- * In the rare case of wrap-around, ULONG_MAX will be returned.
+ * In the rare case of wrap-around, ULONG_MAX will be returned.  ULONG_MAX
+ * will also be returned if index == ULONG_MAX and there is a gap at the
+ * index.  We can not wrap-around if passed index == ULONG_MAX.
  */
 pgoff_t page_cache_prev_miss(struct address_space *mapping,
                             pgoff_t index, unsigned long max_scan)
@@ -1806,12 +1811,13 @@ pgoff_t page_cache_prev_miss(struct address_space *mapping,
        while (max_scan--) {
                void *entry = xas_prev(&xas);
                if (!entry || xa_is_value(entry))
-                       break;
-               if (xas.xa_index == ULONG_MAX)
-                       break;
+                       return xas.xa_index;
+               if (xas.xa_index == ULONG_MAX && index != ULONG_MAX)
+                       return xas.xa_index;
        }
 
-       return xas.xa_index;
+       /* No gaps in range and no wrap-around, return index beyond range */
+       return xas.xa_index - 1;
 }
 EXPORT_SYMBOL(page_cache_prev_miss);
 
index 8ae7307..c0421b7 100644 (file)
@@ -381,6 +381,7 @@ static int gup_test_release(struct inode *inode, struct file *file)
 static const struct file_operations gup_test_fops = {
        .open = nonseekable_open,
        .unlocked_ioctl = gup_test_ioctl,
+       .compat_ioctl = compat_ptr_ioctl,
        .release = gup_test_release,
 };
 
index 59da2a4..30092d9 100644 (file)
@@ -1174,9 +1174,16 @@ static int zswap_frontswap_store(unsigned type, pgoff_t offset,
                goto reject;
        }
 
+       /*
+        * XXX: zswap reclaim does not work with cgroups yet. Without a
+        * cgroup-aware entry LRU, we will push out entries system-wide based on
+        * local cgroup limits.
+        */
        objcg = get_obj_cgroup_from_page(page);
-       if (objcg && !obj_cgroup_may_zswap(objcg))
-               goto shrink;
+       if (objcg && !obj_cgroup_may_zswap(objcg)) {
+               ret = -ENOMEM;
+               goto reject;
+       }
 
        /* reclaim space if needed */
        if (zswap_is_full()) {
index 230f65a..388db5f 100644 (file)
@@ -892,10 +892,10 @@ int snd_gf1_pcm_new(struct snd_gus_card *gus, int pcm_dev, int control_index)
                kctl = snd_ctl_new1(&snd_gf1_pcm_volume_control1, gus);
        else
                kctl = snd_ctl_new1(&snd_gf1_pcm_volume_control, gus);
+       kctl->id.index = control_index;
        err = snd_ctl_add(card, kctl);
        if (err < 0)
                return err;
-       kctl->id.index = control_index;
 
        return 0;
 }
index 727db6d..6d25c12 100644 (file)
@@ -2688,20 +2688,20 @@ static int snd_cmipci_mixer_new(struct cmipci *cm, int pcm_spdif_device)
                }
                if (cm->can_ac3_hw) {
                        kctl = snd_ctl_new1(&snd_cmipci_spdif_default, cm);
+                       kctl->id.device = pcm_spdif_device;
                        err = snd_ctl_add(card, kctl);
                        if (err < 0)
                                return err;
-                       kctl->id.device = pcm_spdif_device;
                        kctl = snd_ctl_new1(&snd_cmipci_spdif_mask, cm);
+                       kctl->id.device = pcm_spdif_device;
                        err = snd_ctl_add(card, kctl);
                        if (err < 0)
                                return err;
-                       kctl->id.device = pcm_spdif_device;
                        kctl = snd_ctl_new1(&snd_cmipci_spdif_stream, cm);
+                       kctl->id.device = pcm_spdif_device;
                        err = snd_ctl_add(card, kctl);
                        if (err < 0)
                                return err;
-                       kctl->id.device = pcm_spdif_device;
                }
                if (cm->chip_version <= 37) {
                        sw = snd_cmipci_old_mixer_switches;
index 9f79c0a..bd19f92 100644 (file)
@@ -2458,10 +2458,14 @@ int snd_hda_create_dig_out_ctls(struct hda_codec *codec,
                   type == HDA_PCM_TYPE_HDMI) {
                /* suppose a single SPDIF device */
                for (dig_mix = dig_mixes; dig_mix->name; dig_mix++) {
+                       struct snd_ctl_elem_id id;
+
                        kctl = find_mixer_ctl(codec, dig_mix->name, 0, 0);
                        if (!kctl)
                                break;
-                       kctl->id.index = spdif_index;
+                       id = kctl->id;
+                       id.index = spdif_index;
+                       snd_ctl_rename_id(codec->card, &kctl->id, &id);
                }
                bus->primary_dig_out_type = HDA_PCM_TYPE_HDMI;
        }
index 7b5f194..a5d55a7 100644 (file)
@@ -9500,7 +9500,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
        SND_PCI_QUIRK(0x103c, 0x8b8a, "HP", ALC236_FIXUP_HP_GPIO_LED),
        SND_PCI_QUIRK(0x103c, 0x8b8b, "HP", ALC236_FIXUP_HP_GPIO_LED),
        SND_PCI_QUIRK(0x103c, 0x8b8d, "HP", ALC236_FIXUP_HP_GPIO_LED),
-       SND_PCI_QUIRK(0x103c, 0x8b8f, "HP", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED),
+       SND_PCI_QUIRK(0x103c, 0x8b8f, "HP", ALC245_FIXUP_CS35L41_SPI_4_HP_GPIO_LED),
        SND_PCI_QUIRK(0x103c, 0x8b92, "HP", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED),
        SND_PCI_QUIRK(0x103c, 0x8b96, "HP", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF),
        SND_PCI_QUIRK(0x103c, 0x8b97, "HP", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF),
@@ -9547,6 +9547,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
        SND_PCI_QUIRK(0x1043, 0x1a8f, "ASUS UX582ZS", ALC245_FIXUP_CS35L41_SPI_2),
        SND_PCI_QUIRK(0x1043, 0x1b11, "ASUS UX431DA", ALC294_FIXUP_ASUS_COEF_1B),
        SND_PCI_QUIRK(0x1043, 0x1b13, "Asus U41SV", ALC269_FIXUP_INV_DMIC),
+       SND_PCI_QUIRK(0x1043, 0x1b93, "ASUS G614JVR/JIR", ALC245_FIXUP_CS35L41_SPI_2),
        SND_PCI_QUIRK(0x1043, 0x1bbd, "ASUS Z550MA", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE),
        SND_PCI_QUIRK(0x1043, 0x1c23, "Asus X55U", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
        SND_PCI_QUIRK(0x1043, 0x1c62, "ASUS GU603", ALC289_FIXUP_ASUS_GA401),
@@ -9565,6 +9566,11 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
        SND_PCI_QUIRK(0x1043, 0x1f12, "ASUS UM5302", ALC287_FIXUP_CS35L41_I2C_2),
        SND_PCI_QUIRK(0x1043, 0x1f92, "ASUS ROG Flow X16", ALC289_FIXUP_ASUS_GA401),
        SND_PCI_QUIRK(0x1043, 0x3030, "ASUS ZN270IE", ALC256_FIXUP_ASUS_AIO_GPIO2),
+       SND_PCI_QUIRK(0x1043, 0x3a20, "ASUS G614JZR", ALC245_FIXUP_CS35L41_SPI_2),
+       SND_PCI_QUIRK(0x1043, 0x3a30, "ASUS G814JVR/JIR", ALC245_FIXUP_CS35L41_SPI_2),
+       SND_PCI_QUIRK(0x1043, 0x3a40, "ASUS G814JZR", ALC245_FIXUP_CS35L41_SPI_2),
+       SND_PCI_QUIRK(0x1043, 0x3a50, "ASUS G834JYR/JZR", ALC245_FIXUP_CS35L41_SPI_2),
+       SND_PCI_QUIRK(0x1043, 0x3a60, "ASUS G634JYR/JZR", ALC245_FIXUP_CS35L41_SPI_2),
        SND_PCI_QUIRK(0x1043, 0x831a, "ASUS P901", ALC269_FIXUP_STEREO_DMIC),
        SND_PCI_QUIRK(0x1043, 0x834a, "ASUS S101", ALC269_FIXUP_STEREO_DMIC),
        SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005", ALC269_FIXUP_STEREO_DMIC),
@@ -9588,6 +9594,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
        SND_PCI_QUIRK(0x10ec, 0x124c, "Intel Reference board", ALC295_FIXUP_CHROME_BOOK),
        SND_PCI_QUIRK(0x10ec, 0x1252, "Intel Reference board", ALC295_FIXUP_CHROME_BOOK),
        SND_PCI_QUIRK(0x10ec, 0x1254, "Intel Reference board", ALC295_FIXUP_CHROME_BOOK),
+       SND_PCI_QUIRK(0x10ec, 0x12cc, "Intel Reference board", ALC225_FIXUP_HEADSET_JACK),
        SND_PCI_QUIRK(0x10f7, 0x8338, "Panasonic CF-SZ6", ALC269_FIXUP_HEADSET_MODE),
        SND_PCI_QUIRK(0x144d, 0xc109, "Samsung Ativ book 9 (NP900X3G)", ALC269_FIXUP_INV_DMIC),
        SND_PCI_QUIRK(0x144d, 0xc169, "Samsung Notebook 9 Pen (NP930SBE-K01US)", ALC298_FIXUP_SAMSUNG_AMP),
@@ -9636,6 +9643,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
        SND_PCI_QUIRK(0x1558, 0x5101, "Clevo S510WU", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
        SND_PCI_QUIRK(0x1558, 0x5157, "Clevo W517GU1", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
        SND_PCI_QUIRK(0x1558, 0x51a1, "Clevo NS50MU", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
+       SND_PCI_QUIRK(0x1558, 0x51b1, "Clevo NS50AU", ALC256_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
        SND_PCI_QUIRK(0x1558, 0x5630, "Clevo NP50RNJS", ALC256_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
        SND_PCI_QUIRK(0x1558, 0x70a1, "Clevo NB70T[HJK]", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
        SND_PCI_QUIRK(0x1558, 0x70b3, "Clevo NK70SB", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
@@ -9807,6 +9815,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
        SND_PCI_QUIRK(0x8086, 0x2074, "Intel NUC 8", ALC233_FIXUP_INTEL_NUC8_DMIC),
        SND_PCI_QUIRK(0x8086, 0x2080, "Intel NUC 8 Rugged", ALC256_FIXUP_INTEL_NUC8_RUGGED),
        SND_PCI_QUIRK(0x8086, 0x2081, "Intel NUC 10", ALC256_FIXUP_INTEL_NUC10),
+       SND_PCI_QUIRK(0x8086, 0x3038, "Intel NUC 13", ALC225_FIXUP_HEADSET_JACK),
        SND_PCI_QUIRK(0xf111, 0x0001, "Framework Laptop", ALC295_FIXUP_FRAMEWORK_LAPTOP_MIC_NO_PRESENCE),
 
 #if 0
@@ -11694,6 +11703,7 @@ static const struct snd_pci_quirk alc662_fixup_tbl[] = {
        SND_PCI_QUIRK(0x103c, 0x8719, "HP", ALC897_FIXUP_HP_HSMIC_VERB),
        SND_PCI_QUIRK(0x103c, 0x872b, "HP", ALC897_FIXUP_HP_HSMIC_VERB),
        SND_PCI_QUIRK(0x103c, 0x873e, "HP", ALC671_FIXUP_HP_HEADSET_MIC2),
+       SND_PCI_QUIRK(0x103c, 0x8768, "HP Slim Desktop S01", ALC671_FIXUP_HP_HEADSET_MIC2),
        SND_PCI_QUIRK(0x103c, 0x877e, "HP 288 Pro G6", ALC671_FIXUP_HP_HEADSET_MIC2),
        SND_PCI_QUIRK(0x103c, 0x885f, "HP 288 Pro G8", ALC671_FIXUP_HP_HEADSET_MIC2),
        SND_PCI_QUIRK(0x1043, 0x1080, "Asus UX501VW", ALC668_FIXUP_HEADSET_MODE),
@@ -11715,6 +11725,7 @@ static const struct snd_pci_quirk alc662_fixup_tbl[] = {
        SND_PCI_QUIRK(0x14cd, 0x5003, "USI", ALC662_FIXUP_USI_HEADSET_MODE),
        SND_PCI_QUIRK(0x17aa, 0x1036, "Lenovo P520", ALC662_FIXUP_LENOVO_MULTI_CODECS),
        SND_PCI_QUIRK(0x17aa, 0x1057, "Lenovo P360", ALC897_FIXUP_HEADSET_MIC_PIN),
+       SND_PCI_QUIRK(0x17aa, 0x1064, "Lenovo P3 Tower", ALC897_FIXUP_HEADSET_MIC_PIN),
        SND_PCI_QUIRK(0x17aa, 0x32ca, "Lenovo ThinkCentre M80", ALC897_FIXUP_HEADSET_MIC_PIN),
        SND_PCI_QUIRK(0x17aa, 0x32cb, "Lenovo ThinkCentre M70", ALC897_FIXUP_HEADSET_MIC_PIN),
        SND_PCI_QUIRK(0x17aa, 0x32cf, "Lenovo ThinkCentre M950", ALC897_FIXUP_HEADSET_MIC_PIN),
index 24b9782..0278493 100644 (file)
@@ -1899,11 +1899,12 @@ static int aureon_add_controls(struct snd_ice1712 *ice)
                else {
                        for (i = 0; i < ARRAY_SIZE(cs8415_controls); i++) {
                                struct snd_kcontrol *kctl;
-                               err = snd_ctl_add(ice->card, (kctl = snd_ctl_new1(&cs8415_controls[i], ice)));
-                               if (err < 0)
-                                       return err;
+                               kctl = snd_ctl_new1(&cs8415_controls[i], ice);
                                if (i > 1)
                                        kctl->id.device = ice->pcm->device;
+                               err = snd_ctl_add(ice->card, kctl);
+                               if (err < 0)
+                                       return err;
                        }
                }
        }
index a5241a2..3b0c3e7 100644 (file)
@@ -2371,22 +2371,26 @@ int snd_ice1712_spdif_build_controls(struct snd_ice1712 *ice)
 
        if (snd_BUG_ON(!ice->pcm_pro))
                return -EIO;
-       err = snd_ctl_add(ice->card, kctl = snd_ctl_new1(&snd_ice1712_spdif_default, ice));
+       kctl = snd_ctl_new1(&snd_ice1712_spdif_default, ice);
+       kctl->id.device = ice->pcm_pro->device;
+       err = snd_ctl_add(ice->card, kctl);
        if (err < 0)
                return err;
+       kctl = snd_ctl_new1(&snd_ice1712_spdif_maskc, ice);
        kctl->id.device = ice->pcm_pro->device;
-       err = snd_ctl_add(ice->card, kctl = snd_ctl_new1(&snd_ice1712_spdif_maskc, ice));
+       err = snd_ctl_add(ice->card, kctl);
        if (err < 0)
                return err;
+       kctl = snd_ctl_new1(&snd_ice1712_spdif_maskp, ice);
        kctl->id.device = ice->pcm_pro->device;
-       err = snd_ctl_add(ice->card, kctl = snd_ctl_new1(&snd_ice1712_spdif_maskp, ice));
+       err = snd_ctl_add(ice->card, kctl);
        if (err < 0)
                return err;
+       kctl = snd_ctl_new1(&snd_ice1712_spdif_stream, ice);
        kctl->id.device = ice->pcm_pro->device;
-       err = snd_ctl_add(ice->card, kctl = snd_ctl_new1(&snd_ice1712_spdif_stream, ice));
+       err = snd_ctl_add(ice->card, kctl);
        if (err < 0)
                return err;
-       kctl->id.device = ice->pcm_pro->device;
        ice->spdif.stream_ctl = kctl;
        return 0;
 }
index 6fab2ad..1dc776a 100644 (file)
@@ -2392,23 +2392,27 @@ static int snd_vt1724_spdif_build_controls(struct snd_ice1712 *ice)
        if (err < 0)
                return err;
 
-       err = snd_ctl_add(ice->card, kctl = snd_ctl_new1(&snd_vt1724_spdif_default, ice));
+       kctl = snd_ctl_new1(&snd_vt1724_spdif_default, ice);
+       kctl->id.device = ice->pcm->device;
+       err = snd_ctl_add(ice->card, kctl);
        if (err < 0)
                return err;
+       kctl = snd_ctl_new1(&snd_vt1724_spdif_maskc, ice);
        kctl->id.device = ice->pcm->device;
-       err = snd_ctl_add(ice->card, kctl = snd_ctl_new1(&snd_vt1724_spdif_maskc, ice));
+       err = snd_ctl_add(ice->card, kctl);
        if (err < 0)
                return err;
+       kctl = snd_ctl_new1(&snd_vt1724_spdif_maskp, ice);
        kctl->id.device = ice->pcm->device;
-       err = snd_ctl_add(ice->card, kctl = snd_ctl_new1(&snd_vt1724_spdif_maskp, ice));
+       err = snd_ctl_add(ice->card, kctl);
        if (err < 0)
                return err;
-       kctl->id.device = ice->pcm->device;
 #if 0 /* use default only */
-       err = snd_ctl_add(ice->card, kctl = snd_ctl_new1(&snd_vt1724_spdif_stream, ice));
+       kctl = snd_ctl_new1(&snd_vt1724_spdif_stream, ice);
+       kctl->id.device = ice->pcm->device;
+       err = snd_ctl_add(ice->card, kctl);
        if (err < 0)
                return err;
-       kctl->id.device = ice->pcm->device;
        ice->spdif.stream_ctl = kctl;
 #endif
        return 0;
index 6971eec..6b8d869 100644 (file)
@@ -1822,20 +1822,20 @@ int snd_ymfpci_mixer(struct snd_ymfpci *chip, int rear_switch)
        if (snd_BUG_ON(!chip->pcm_spdif))
                return -ENXIO;
        kctl = snd_ctl_new1(&snd_ymfpci_spdif_default, chip);
+       kctl->id.device = chip->pcm_spdif->device;
        err = snd_ctl_add(chip->card, kctl);
        if (err < 0)
                return err;
-       kctl->id.device = chip->pcm_spdif->device;
        kctl = snd_ctl_new1(&snd_ymfpci_spdif_mask, chip);
+       kctl->id.device = chip->pcm_spdif->device;
        err = snd_ctl_add(chip->card, kctl);
        if (err < 0)
                return err;
-       kctl->id.device = chip->pcm_spdif->device;
        kctl = snd_ctl_new1(&snd_ymfpci_spdif_stream, chip);
+       kctl->id.device = chip->pcm_spdif->device;
        err = snd_ctl_add(chip->card, kctl);
        if (err < 0)
                return err;
-       kctl->id.device = chip->pcm_spdif->device;
        chip->spdif_pcm_ctl = kctl;
 
        /* direct recording source */
index afddb9a..b1337b9 100644 (file)
@@ -211,8 +211,7 @@ static int create_acp63_platform_devs(struct pci_dev *pci, struct acp63_dev_data
        case ACP63_PDM_DEV_MASK:
                adata->pdm_dev_index  = 0;
                acp63_fill_platform_dev_info(&pdevinfo[0], parent, NULL, "acp_ps_pdm_dma",
-                                            0, adata->res, 1, &adata->acp_lock,
-                                            sizeof(adata->acp_lock));
+                                            0, adata->res, 1, NULL, 0);
                acp63_fill_platform_dev_info(&pdevinfo[1], parent, NULL, "dmic-codec",
                                             0, NULL, 0, NULL, 0);
                acp63_fill_platform_dev_info(&pdevinfo[2], parent, NULL, "acp_ps_mach",
index 46b9132..3a83dc1 100644 (file)
@@ -361,12 +361,12 @@ static int acp63_pdm_audio_probe(struct platform_device *pdev)
 {
        struct resource *res;
        struct pdm_dev_data *adata;
+       struct acp63_dev_data *acp_data;
+       struct device *parent;
        int status;
 
-       if (!pdev->dev.platform_data) {
-               dev_err(&pdev->dev, "platform_data not retrieved\n");
-               return -ENODEV;
-       }
+       parent = pdev->dev.parent;
+       acp_data = dev_get_drvdata(parent);
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        if (!res) {
                dev_err(&pdev->dev, "IORESOURCE_MEM FAILED\n");
@@ -382,7 +382,7 @@ static int acp63_pdm_audio_probe(struct platform_device *pdev)
                return -ENOMEM;
 
        adata->capture_stream = NULL;
-       adata->acp_lock = pdev->dev.platform_data;
+       adata->acp_lock = &acp_data->acp_lock;
        dev_set_drvdata(&pdev->dev, adata);
        status = devm_snd_soc_register_component(&pdev->dev,
                                                 &acp63_pdm_component,
index 4406a5d..246299a 100644 (file)
@@ -175,6 +175,13 @@ static const struct dmi_system_id yc_acp_quirk_table[] = {
                .driver_data = &acp6x_card,
                .matches = {
                        DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "21EF"),
+               }
+       },
+       {
+               .driver_data = &acp6x_card,
+               .matches = {
+                       DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
                        DMI_MATCH(DMI_PRODUCT_NAME, "21EM"),
                }
        },
index d1677d7..e0d2b9b 100644 (file)
@@ -704,9 +704,6 @@ static int cs35l56_sdw_dai_hw_free(struct snd_pcm_substream *substream,
 static int cs35l56_sdw_dai_set_stream(struct snd_soc_dai *dai,
                                      void *sdw_stream, int direction)
 {
-       if (!sdw_stream)
-               return 0;
-
        snd_soc_dai_dma_data_set(dai, direction, sdw_stream);
 
        return 0;
index dcce06b..e6b84e2 100644 (file)
@@ -211,7 +211,7 @@ static int max98363_io_init(struct sdw_slave *slave)
 }
 
 #define MAX98363_RATES SNDRV_PCM_RATE_8000_192000
-#define MAX98363_FORMATS (SNDRV_PCM_FMTBIT_S32_LE)
+#define MAX98363_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE)
 
 static int max98363_sdw_dai_hw_params(struct snd_pcm_substream *substream,
                                      struct snd_pcm_hw_params *params,
@@ -246,7 +246,7 @@ static int max98363_sdw_dai_hw_params(struct snd_pcm_substream *substream,
        stream_config.frame_rate = params_rate(params);
        stream_config.bps = snd_pcm_format_width(params_format(params));
        stream_config.direction = direction;
-       stream_config.ch_count = params_channels(params);
+       stream_config.ch_count = 1;
 
        if (stream_config.ch_count > runtime->hw.channels_max) {
                stream_config.ch_count = runtime->hw.channels_max;
index 4f19fd9..5a4db89 100644 (file)
@@ -1903,6 +1903,30 @@ static const struct dmi_system_id nau8824_quirk_table[] = {
                },
                .driver_data = (void *)(NAU8824_MONO_SPEAKER),
        },
+       {
+               /* Positivo CW14Q01P */
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Positivo Tecnologia SA"),
+                       DMI_MATCH(DMI_BOARD_NAME, "CW14Q01P"),
+               },
+               .driver_data = (void *)(NAU8824_JD_ACTIVE_HIGH),
+       },
+       {
+               /* Positivo K1424G */
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Positivo Tecnologia SA"),
+                       DMI_MATCH(DMI_BOARD_NAME, "K1424G"),
+               },
+               .driver_data = (void *)(NAU8824_JD_ACTIVE_HIGH),
+       },
+       {
+               /* Positivo N14ZP74G */
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Positivo Tecnologia SA"),
+                       DMI_MATCH(DMI_BOARD_NAME, "N14ZP74G"),
+               },
+               .driver_data = (void *)(NAU8824_JD_ACTIVE_HIGH),
+       },
        {}
 };
 
index 402286d..9c10200 100644 (file)
@@ -1190,7 +1190,6 @@ static const struct regmap_config wcd938x_regmap_config = {
        .readable_reg = wcd938x_readable_register,
        .writeable_reg = wcd938x_writeable_register,
        .volatile_reg = wcd938x_volatile_register,
-       .can_multi_write = true,
 };
 
 static const struct sdw_slave_ops wcd9380_slave_ops = {
index f709231..97f6873 100644 (file)
@@ -645,7 +645,6 @@ static struct regmap_config wsa881x_regmap_config = {
        .readable_reg = wsa881x_readable_register,
        .reg_format_endian = REGMAP_ENDIAN_NATIVE,
        .val_format_endian = REGMAP_ENDIAN_NATIVE,
-       .can_multi_write = true,
 };
 
 enum {
index c609cb6..e80b531 100644 (file)
@@ -946,7 +946,6 @@ static struct regmap_config wsa883x_regmap_config = {
        .writeable_reg = wsa883x_writeable_register,
        .reg_format_endian = REGMAP_ENDIAN_NATIVE,
        .val_format_endian = REGMAP_ENDIAN_NATIVE,
-       .can_multi_write = true,
        .use_single_read = true,
 };
 
index abdaffb..e3105d4 100644 (file)
@@ -491,14 +491,21 @@ static int fsl_sai_set_bclk(struct snd_soc_dai *dai, bool tx, u32 freq)
        regmap_update_bits(sai->regmap, reg, FSL_SAI_CR2_MSEL_MASK,
                           FSL_SAI_CR2_MSEL(sai->mclk_id[tx]));
 
-       if (savediv == 1)
+       if (savediv == 1) {
                regmap_update_bits(sai->regmap, reg,
                                   FSL_SAI_CR2_DIV_MASK | FSL_SAI_CR2_BYP,
                                   FSL_SAI_CR2_BYP);
-       else
+               if (fsl_sai_dir_is_synced(sai, adir))
+                       regmap_update_bits(sai->regmap, FSL_SAI_xCR2(tx, ofs),
+                                          FSL_SAI_CR2_BCI, FSL_SAI_CR2_BCI);
+               else
+                       regmap_update_bits(sai->regmap, FSL_SAI_xCR2(tx, ofs),
+                                          FSL_SAI_CR2_BCI, 0);
+       } else {
                regmap_update_bits(sai->regmap, reg,
                                   FSL_SAI_CR2_DIV_MASK | FSL_SAI_CR2_BYP,
                                   savediv / 2 - 1);
+       }
 
        if (sai->soc_data->max_register >= FSL_SAI_MCTL) {
                /* SAI is in master mode at this point, so enable MCLK */
index 197748a..a53c4f0 100644 (file)
 
 /* SAI Transmit and Receive Configuration 2 Register */
 #define FSL_SAI_CR2_SYNC       BIT(30)
+#define FSL_SAI_CR2_BCI                BIT(28)
 #define FSL_SAI_CR2_MSEL_MASK  (0x3 << 26)
 #define FSL_SAI_CR2_MSEL_BUS   0
 #define FSL_SAI_CR2_MSEL_MCLK1 BIT(26)
index 467edd9..e5ff61c 100644 (file)
@@ -314,7 +314,7 @@ int asoc_simple_startup(struct snd_pcm_substream *substream)
                }
                ret = snd_pcm_hw_constraint_minmax(substream->runtime, SNDRV_PCM_HW_PARAM_RATE,
                        fixed_rate, fixed_rate);
-               if (ret)
+               if (ret < 0)
                        goto codec_err;
        }
 
index 6f044cc..5a5e4ec 100644 (file)
@@ -416,6 +416,7 @@ static int __simple_for_each_link(struct asoc_simple_priv *priv,
 
                        if (ret < 0) {
                                of_node_put(codec);
+                               of_node_put(plat);
                                of_node_put(np);
                                goto error;
                        }
index 743d6a1..0fb9751 100644 (file)
@@ -418,13 +418,6 @@ int mt8188_afe_init_clock(struct mtk_base_afe *afe)
        return 0;
 }
 
-void mt8188_afe_deinit_clock(void *priv)
-{
-       struct mtk_base_afe *afe = priv;
-
-       mt8188_audsys_clk_unregister(afe);
-}
-
 int mt8188_afe_enable_clk(struct mtk_base_afe *afe, struct clk *clk)
 {
        int ret;
index 084fdfb..a4203a8 100644 (file)
@@ -100,7 +100,6 @@ int mt8188_afe_get_mclk_source_clk_id(int sel);
 int mt8188_afe_get_mclk_source_rate(struct mtk_base_afe *afe, int apll);
 int mt8188_afe_get_default_mclk_source_by_rate(int rate);
 int mt8188_afe_init_clock(struct mtk_base_afe *afe);
-void mt8188_afe_deinit_clock(void *priv);
 int mt8188_afe_enable_clk(struct mtk_base_afe *afe, struct clk *clk);
 void mt8188_afe_disable_clk(struct mtk_base_afe *afe, struct clk *clk);
 int mt8188_afe_set_clk_rate(struct mtk_base_afe *afe, struct clk *clk,
index e5f9373..bcf7025 100644 (file)
@@ -3185,10 +3185,6 @@ static int mt8188_afe_pcm_dev_probe(struct platform_device *pdev)
        if (ret)
                return dev_err_probe(dev, ret, "init clock error");
 
-       ret = devm_add_action_or_reset(dev, mt8188_afe_deinit_clock, (void *)afe);
-       if (ret)
-               return ret;
-
        spin_lock_init(&afe_priv->afe_ctrl_lock);
 
        mutex_init(&afe->irq_alloc_lock);
index be1c53b..c796ad8 100644 (file)
@@ -138,6 +138,29 @@ static const struct afe_gate aud_clks[CLK_AUD_NR_CLK] = {
        GATE_AUD6(CLK_AUD_GASRC11, "aud_gasrc11", "top_asm_h", 11),
 };
 
+static void mt8188_audsys_clk_unregister(void *data)
+{
+       struct mtk_base_afe *afe = data;
+       struct mt8188_afe_private *afe_priv = afe->platform_priv;
+       struct clk *clk;
+       struct clk_lookup *cl;
+       int i;
+
+       if (!afe_priv)
+               return;
+
+       for (i = 0; i < CLK_AUD_NR_CLK; i++) {
+               cl = afe_priv->lookup[i];
+               if (!cl)
+                       continue;
+
+               clk = cl->clk;
+               clk_unregister_gate(clk);
+
+               clkdev_drop(cl);
+       }
+}
+
 int mt8188_audsys_clk_register(struct mtk_base_afe *afe)
 {
        struct mt8188_afe_private *afe_priv = afe->platform_priv;
@@ -179,27 +202,5 @@ int mt8188_audsys_clk_register(struct mtk_base_afe *afe)
                afe_priv->lookup[i] = cl;
        }
 
-       return 0;
-}
-
-void mt8188_audsys_clk_unregister(struct mtk_base_afe *afe)
-{
-       struct mt8188_afe_private *afe_priv = afe->platform_priv;
-       struct clk *clk;
-       struct clk_lookup *cl;
-       int i;
-
-       if (!afe_priv)
-               return;
-
-       for (i = 0; i < CLK_AUD_NR_CLK; i++) {
-               cl = afe_priv->lookup[i];
-               if (!cl)
-                       continue;
-
-               clk = cl->clk;
-               clk_unregister_gate(clk);
-
-               clkdev_drop(cl);
-       }
+       return devm_add_action_or_reset(afe->dev, mt8188_audsys_clk_unregister, afe);
 }
index 6c5f463..45b0948 100644 (file)
@@ -10,6 +10,5 @@
 #define _MT8188_AUDSYS_CLK_H_
 
 int mt8188_audsys_clk_register(struct mtk_base_afe *afe);
-void mt8188_audsys_clk_unregister(struct mtk_base_afe *afe);
 
 #endif
index 9ca2cb8..f35318a 100644 (file)
@@ -410,11 +410,6 @@ int mt8195_afe_init_clock(struct mtk_base_afe *afe)
        return 0;
 }
 
-void mt8195_afe_deinit_clock(struct mtk_base_afe *afe)
-{
-       mt8195_audsys_clk_unregister(afe);
-}
-
 int mt8195_afe_enable_clk(struct mtk_base_afe *afe, struct clk *clk)
 {
        int ret;
index 40663e3..a08c0ee 100644 (file)
@@ -101,7 +101,6 @@ int mt8195_afe_get_mclk_source_clk_id(int sel);
 int mt8195_afe_get_mclk_source_rate(struct mtk_base_afe *afe, int apll);
 int mt8195_afe_get_default_mclk_source_by_rate(int rate);
 int mt8195_afe_init_clock(struct mtk_base_afe *afe);
-void mt8195_afe_deinit_clock(struct mtk_base_afe *afe);
 int mt8195_afe_enable_clk(struct mtk_base_afe *afe, struct clk *clk);
 void mt8195_afe_disable_clk(struct mtk_base_afe *afe, struct clk *clk);
 int mt8195_afe_prepare_clk(struct mtk_base_afe *afe, struct clk *clk);
index 9e45efe..03dabc0 100644 (file)
@@ -3255,15 +3255,11 @@ err_pm_put:
 
 static void mt8195_afe_pcm_dev_remove(struct platform_device *pdev)
 {
-       struct mtk_base_afe *afe = platform_get_drvdata(pdev);
-
        snd_soc_unregister_component(&pdev->dev);
 
        pm_runtime_disable(&pdev->dev);
        if (!pm_runtime_status_suspended(&pdev->dev))
                mt8195_afe_runtime_suspend(&pdev->dev);
-
-       mt8195_afe_deinit_clock(afe);
 }
 
 static const struct of_device_id mt8195_afe_pcm_dt_match[] = {
index e0670e0..38594bc 100644 (file)
@@ -148,6 +148,29 @@ static const struct afe_gate aud_clks[CLK_AUD_NR_CLK] = {
        GATE_AUD6(CLK_AUD_GASRC19, "aud_gasrc19", "top_asm_h", 19),
 };
 
+static void mt8195_audsys_clk_unregister(void *data)
+{
+       struct mtk_base_afe *afe = data;
+       struct mt8195_afe_private *afe_priv = afe->platform_priv;
+       struct clk *clk;
+       struct clk_lookup *cl;
+       int i;
+
+       if (!afe_priv)
+               return;
+
+       for (i = 0; i < CLK_AUD_NR_CLK; i++) {
+               cl = afe_priv->lookup[i];
+               if (!cl)
+                       continue;
+
+               clk = cl->clk;
+               clk_unregister_gate(clk);
+
+               clkdev_drop(cl);
+       }
+}
+
 int mt8195_audsys_clk_register(struct mtk_base_afe *afe)
 {
        struct mt8195_afe_private *afe_priv = afe->platform_priv;
@@ -188,27 +211,5 @@ int mt8195_audsys_clk_register(struct mtk_base_afe *afe)
                afe_priv->lookup[i] = cl;
        }
 
-       return 0;
-}
-
-void mt8195_audsys_clk_unregister(struct mtk_base_afe *afe)
-{
-       struct mt8195_afe_private *afe_priv = afe->platform_priv;
-       struct clk *clk;
-       struct clk_lookup *cl;
-       int i;
-
-       if (!afe_priv)
-               return;
-
-       for (i = 0; i < CLK_AUD_NR_CLK; i++) {
-               cl = afe_priv->lookup[i];
-               if (!cl)
-                       continue;
-
-               clk = cl->clk;
-               clk_unregister_gate(clk);
-
-               clkdev_drop(cl);
-       }
+       return devm_add_action_or_reset(afe->dev, mt8195_audsys_clk_unregister, afe);
 }
index 239d310..69db2dd 100644 (file)
@@ -10,6 +10,5 @@
 #define _MT8195_AUDSYS_CLK_H_
 
 int mt8195_audsys_clk_register(struct mtk_base_afe *afe);
-void mt8195_audsys_clk_unregister(struct mtk_base_afe *afe);
 
 #endif
index caf32a9..7527f73 100644 (file)
@@ -1,7 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0
 
-CFLAGS += -I. -I../../include -g -Og -Wall -D_LGPL_SOURCE -fsanitize=address \
-         -fsanitize=undefined
+CFLAGS += -I. -I../../include -I../../../lib -g -Og -Wall \
+         -D_LGPL_SOURCE -fsanitize=address -fsanitize=undefined
 LDFLAGS += -fsanitize=address -fsanitize=undefined
 LDLIBS+= -lpthread -lurcu
 TARGETS = main idr-test multiorder xarray maple
@@ -49,6 +49,7 @@ $(OFILES): Makefile *.h */*.h generated/map-shift.h generated/bit-length.h \
        ../../../include/linux/xarray.h \
        ../../../include/linux/maple_tree.h \
        ../../../include/linux/radix-tree.h \
+       ../../../lib/radix-tree.h \
        ../../../include/linux/idr.h
 
 radix-tree.c: ../../../lib/radix-tree.c
index 3e390fe..b7eef32 100644 (file)
@@ -381,7 +381,7 @@ __format:
                goto __close;
        }
        if (rrate != rate) {
-               snprintf(msg, sizeof(msg), "rate mismatch %ld != %ld", rate, rrate);
+               snprintf(msg, sizeof(msg), "rate mismatch %ld != %d", rate, rrate);
                goto __close;
        }
        rperiod_size = period_size;
@@ -447,24 +447,24 @@ __format:
                        frames = snd_pcm_writei(handle, samples, rate);
                        if (frames < 0) {
                                snprintf(msg, sizeof(msg),
-                                        "Write failed: expected %d, wrote %li", rate, frames);
+                                        "Write failed: expected %ld, wrote %li", rate, frames);
                                goto __close;
                        }
                        if (frames < rate) {
                                snprintf(msg, sizeof(msg),
-                                        "expected %d, wrote %li", rate, frames);
+                                        "expected %ld, wrote %li", rate, frames);
                                goto __close;
                        }
                } else {
                        frames = snd_pcm_readi(handle, samples, rate);
                        if (frames < 0) {
                                snprintf(msg, sizeof(msg),
-                                        "expected %d, wrote %li", rate, frames);
+                                        "expected %ld, wrote %li", rate, frames);
                                goto __close;
                        }
                        if (frames < rate) {
                                snprintf(msg, sizeof(msg),
-                                        "expected %d, wrote %li", rate, frames);
+                                        "expected %ld, wrote %li", rate, frames);
                                goto __close;
                        }
                }
diff --git a/tools/virtio/ringtest/.gitignore b/tools/virtio/ringtest/.gitignore
new file mode 100644 (file)
index 0000000..100b9e3
--- /dev/null
@@ -0,0 +1,7 @@
+# SPDX-License-Identifier: GPL-2.0-only
+/noring
+/ptr_ring
+/ring
+/virtio_ring_0_9
+/virtio_ring_inorder
+/virtio_ring_poll
index b68920d..d18dd31 100644 (file)
@@ -8,6 +8,7 @@
 #ifndef MAIN_H
 #define MAIN_H
 
+#include <assert.h>
 #include <stdbool.h>
 
 extern int param;
@@ -95,6 +96,8 @@ extern unsigned ring_size;
 #define cpu_relax() asm ("rep; nop" ::: "memory")
 #elif defined(__s390x__)
 #define cpu_relax() barrier()
+#elif defined(__aarch64__)
+#define cpu_relax() asm ("yield" ::: "memory")
 #else
 #define cpu_relax() assert(0)
 #endif
@@ -112,6 +115,8 @@ static inline void busy_wait(void)
 
 #if defined(__x86_64__) || defined(__i386__)
 #define smp_mb()     asm volatile("lock; addl $0,-132(%%rsp)" ::: "memory", "cc")
+#elif defined(__aarch64__)
+#define smp_mb()     asm volatile("dmb ish" ::: "memory")
 #else
 /*
  * Not using __ATOMIC_SEQ_CST since gcc docs say they are only synchronized
@@ -136,10 +141,16 @@ static inline void busy_wait(void)
 
 #if defined(__i386__) || defined(__x86_64__) || defined(__s390x__)
 #define smp_wmb() barrier()
+#elif defined(__aarch64__)
+#define smp_wmb() asm volatile("dmb ishst" ::: "memory")
 #else
 #define smp_wmb() smp_release()
 #endif
 
+#ifndef __always_inline
+#define __always_inline inline __attribute__((always_inline))
+#endif
+
 static __always_inline
 void __read_once_size(const volatile void *p, void *res, int size)
 {
index 4fb9368..0127ff0 100644 (file)
@@ -95,7 +95,7 @@ Run
 
 1) Enable ftrace in the guest
  <Example>
-       # echo 1 > /sys/kernel/debug/tracing/events/sched/enable
+       # echo 1 > /sys/kernel/tracing/events/sched/enable
 
 2) Run trace agent in the guest
  This agent must be operated as root.
index cdfe77c..7e2d9bb 100644 (file)
@@ -18,8 +18,9 @@
 #define PIPE_DEF_BUFS          16
 #define PIPE_MIN_SIZE          (PAGE_SIZE*PIPE_DEF_BUFS)
 #define PIPE_MAX_SIZE          (1024*1024)
-#define READ_PATH_FMT  \
-               "/sys/kernel/debug/tracing/per_cpu/cpu%d/trace_pipe_raw"
+#define TRACEFS                "/sys/kernel/tracing"
+#define DEBUGFS                "/sys/kernel/debug/tracing"
+#define READ_PATH_FMT          "%s/per_cpu/cpu%d/trace_pipe_raw"
 #define WRITE_PATH_FMT         "/dev/virtio-ports/trace-path-cpu%d"
 #define CTL_PATH               "/dev/virtio-ports/agent-ctl-path"
 
@@ -120,9 +121,12 @@ static const char *make_path(int cpu_num, bool this_is_write_path)
        if (this_is_write_path)
                /* write(output) path */
                ret = snprintf(buf, PATH_MAX, WRITE_PATH_FMT, cpu_num);
-       else
+       else {
                /* read(input) path */
-               ret = snprintf(buf, PATH_MAX, READ_PATH_FMT, cpu_num);
+               ret = snprintf(buf, PATH_MAX, READ_PATH_FMT, TRACEFS, cpu_num);
+               if (ret > 0 && access(buf, F_OK) != 0)
+                       ret = snprintf(buf, PATH_MAX, READ_PATH_FMT, DEBUGFS, cpu_num);
+       }
 
        if (ret <= 0) {
                pr_err("Failed to generate %s path(CPU#%d):%d\n",