]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
Merge tag 'riscv-for-linus-5.7-rc4' of git://git.kernel.org/pub/scm/linux/kernel...
authorLinus Torvalds <torvalds@linux-foundation.org>
Wed, 29 Apr 2020 16:25:32 +0000 (09:25 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Wed, 29 Apr 2020 16:25:32 +0000 (09:25 -0700)
Pull RISC-V fixes from Palmer Dabbelt:
 "A handful of fixes.

  Specifically:

   - fix linker argument to allow linking with lld

   - build fix for configurations without a frame pointer

   - a handful of build fixes related the SBI 0.1 vs 0.2 split

   - remove STRICT_KERNEL_RWX for !MMU, which isn't useful"

* tag 'riscv-for-linus-5.7-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/riscv/linux:
  riscv: select ARCH_HAS_STRICT_KERNEL_RWX only if MMU
  riscv: sbi: Fix undefined reference to sbi_shutdown
  tty: riscv: Using RISCV_SBI_V01 instead of RISCV_SBI
  riscv: sbi: Correct sbi_shutdown() and sbi_clear_ipi() export
  riscv: fix vdso build with lld
  RISC-V: stacktrace: Declare sp_in_global outside ifdef

491 files changed:
.clang-format
Documentation/admin-guide/kernel-parameters.txt
Documentation/arm64/amu.rst
Documentation/devicetree/bindings/Makefile
Documentation/devicetree/bindings/display/panel/leadtek,ltk500hd1829.yaml
Documentation/devicetree/bindings/display/panel/lvds.yaml
Documentation/devicetree/bindings/display/panel/xinpeng,xpp055c272.yaml
Documentation/devicetree/bindings/iio/adc/st,stm32-adc.yaml
Documentation/devicetree/bindings/mfd/st,stpmic1.yaml
Documentation/devicetree/bindings/phy/qcom,qusb2-phy.yaml
Documentation/devicetree/bindings/regulator/mps,mp5416.yaml
Documentation/devicetree/bindings/regulator/mps,mpq7920.yaml
Documentation/devicetree/bindings/regulator/rohm,bd71828-regulator.yaml
Documentation/devicetree/bindings/regulator/rohm,bd71837-regulator.yaml
Documentation/devicetree/bindings/regulator/rohm,bd71847-regulator.yaml
Documentation/devicetree/bindings/sound/rockchip-i2s.yaml
Documentation/devicetree/bindings/sound/rockchip-spdif.txt [deleted file]
Documentation/devicetree/bindings/sound/rockchip-spdif.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/usb/renesas,usb3-peri.yaml
Documentation/devicetree/bindings/usb/renesas,usbhs.yaml
Documentation/devicetree/bindings/usb/usb-xhci.txt
Documentation/filesystems/debugfs.rst
Documentation/kbuild/makefiles.rst
Documentation/networking/ip-sysctl.txt
MAINTAINERS
Makefile
arch/arc/include/asm/module.h
arch/arc/include/asm/vermagic.h [new file with mode: 0644]
arch/arm/boot/dts/bcm2835-rpi.dtsi
arch/arm/boot/dts/bcm283x.dtsi
arch/arm/boot/dts/omap3-n950-n9.dtsi
arch/arm/include/asm/module.h
arch/arm/include/asm/vermagic.h [new file with mode: 0644]
arch/arm/mach-imx/Makefile
arch/arm64/include/asm/module.h
arch/arm64/include/asm/pointer_auth.h
arch/arm64/include/asm/vermagic.h [new file with mode: 0644]
arch/h8300/kernel/.gitignore [new file with mode: 0644]
arch/hexagon/include/asm/vermagic.h [moved from arch/hexagon/include/asm/module.h with 64% similarity]
arch/ia64/include/asm/module.h
arch/ia64/include/asm/vermagic.h [new file with mode: 0644]
arch/mips/include/asm/module.h
arch/mips/include/asm/vermagic.h [new file with mode: 0644]
arch/nds32/include/asm/vermagic.h [moved from arch/nds32/include/asm/module.h with 52% similarity]
arch/powerpc/include/asm/module.h
arch/powerpc/include/asm/vermagic.h [new file with mode: 0644]
arch/powerpc/kernel/entry_32.S
arch/powerpc/kernel/setup_64.c
arch/powerpc/kvm/book3s_64_mmu_hv.c
arch/powerpc/kvm/book3s_64_mmu_radix.c
arch/powerpc/mm/nohash/8xx.c
arch/powerpc/platforms/Kconfig.cputype
arch/riscv/include/asm/module.h
arch/riscv/include/asm/vermagic.h [new file with mode: 0644]
arch/s390/boot/uv.c
arch/s390/kernel/diag.c
arch/s390/kernel/smp.c
arch/s390/kernel/trace.c
arch/s390/kernel/uv.c
arch/s390/kvm/interrupt.c
arch/s390/kvm/kvm-s390.c
arch/s390/lib/uaccess.c
arch/s390/mm/pgalloc.c
arch/s390/pci/pci_irq.c
arch/sh/include/asm/module.h
arch/sh/include/asm/vermagic.h [new file with mode: 0644]
arch/sh/mm/init.c
arch/um/Makefile
arch/x86/Kconfig
arch/x86/events/intel/cstate.c
arch/x86/hyperv/hv_init.c
arch/x86/include/asm/module.h
arch/x86/include/asm/mshyperv.h
arch/x86/include/asm/nospec-branch.h
arch/x86/include/asm/vermagic.h [new file with mode: 0644]
arch/x86/kernel/smpboot.c
arch/x86/kvm/Makefile
arch/x86/kvm/svm/sev.c
arch/x86/kvm/svm/svm.c
arch/x86/kvm/svm/vmenter.S
arch/x86/kvm/vmx/nested.c
arch/x86/kvm/vmx/vmx.c
arch/x86/kvm/x86.c
arch/x86/net/bpf_jit_comp.c
arch/x86/net/bpf_jit_comp32.c
arch/xtensa/include/asm/vermagic.h [moved from arch/xtensa/include/asm/module.h with 57% similarity]
block/blk-iocost.c
drivers/acpi/button.c
drivers/acpi/pci_link.c
drivers/ata/sata_inic162x.c
drivers/base/firmware_loader/fallback_table.c
drivers/base/power/main.c
drivers/block/null_blk.h
drivers/block/null_blk_main.c
drivers/block/null_blk_zoned.c
drivers/block/virtio_blk.c
drivers/char/hw_random/virtio-rng.c
drivers/char/tpm/tpm-interface.c
drivers/char/tpm/tpm2-cmd.c
drivers/char/tpm/tpm_ibmvtpm.c
drivers/char/tpm/tpm_tis_core.c
drivers/counter/104-quad-8.c
drivers/crypto/caam/caamalg.c
drivers/crypto/caam/caamhash.c
drivers/crypto/caam/caampkc.c
drivers/crypto/chelsio/chcr_ktls.c
drivers/firmware/imx/Kconfig
drivers/firmware/xilinx/zynqmp-debug.c
drivers/fpga/dfl-pci.c
drivers/fpga/zynq-fpga.c
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.h
drivers/gpu/drm/amd/powerplay/hwmgr/processpptables.c
drivers/gpu/drm/amd/powerplay/renoir_ppt.c
drivers/gpu/drm/bridge/analogix/analogix-anx6345.c
drivers/gpu/drm/drm_dp_mst_topology.c
drivers/gpu/drm/i915/display/intel_ddi.c
drivers/gpu/drm/i915/display/intel_display_power.c
drivers/gpu/drm/i915/display/intel_dp.c
drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c
drivers/gpu/drm/i915/display/intel_hdmi.c
drivers/gpu/drm/i915/display/intel_sprite.c
drivers/gpu/drm/i915/gt/intel_rps.c
drivers/gpu/drm/i915/i915_drv.h
drivers/gpu/drm/i915/i915_reg.h
drivers/gpu/drm/meson/meson_dw_hdmi.c
drivers/gpu/drm/scheduler/sched_main.c
drivers/gpu/drm/tidss/tidss_crtc.c
drivers/gpu/drm/tidss/tidss_encoder.c
drivers/gpu/drm/tidss/tidss_plane.c
drivers/gpu/drm/virtio/virtgpu_ioctl.c
drivers/gpu/drm/virtio/virtgpu_kms.c
drivers/hv/hv.c
drivers/hv/hv_trace.h
drivers/hv/vmbus_drv.c
drivers/iio/adc/ad7192.c
drivers/iio/adc/ad7793.c
drivers/iio/adc/stm32-adc.c
drivers/iio/adc/ti-ads8344.c
drivers/iio/adc/xilinx-xadc-core.c
drivers/iio/common/st_sensors/st_sensors_core.c
drivers/iio/dac/ad5770r.c
drivers/iio/imu/inv_mpu6050/inv_mpu_core.c
drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h
drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c
drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c
drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_shub.c
drivers/iio/industrialio-core.c
drivers/infiniband/core/cm.c
drivers/infiniband/core/rdma_core.c
drivers/infiniband/core/uverbs_main.c
drivers/infiniband/hw/i40iw/i40iw_ctrl.c
drivers/infiniband/hw/mlx4/main.c
drivers/infiniband/hw/mlx5/qp.c
drivers/infiniband/sw/rdmavt/cq.c
drivers/infiniband/sw/rdmavt/mmap.c
drivers/infiniband/sw/rdmavt/qp.c
drivers/infiniband/sw/rdmavt/srq.c
drivers/infiniband/sw/siw/siw_qp_tx.c
drivers/interconnect/qcom/bcm-voter.c
drivers/misc/mei/pci-me.c
drivers/misc/mic/Kconfig
drivers/net/caif/Kconfig
drivers/net/dsa/b53/b53_common.c
drivers/net/dsa/b53/b53_regs.h
drivers/net/ethernet/broadcom/bcmsysport.c
drivers/net/ethernet/broadcom/bgmac-platform.c
drivers/net/ethernet/broadcom/genet/bcmgenet.c
drivers/net/ethernet/chelsio/cxgb4/cudbg_lib.c
drivers/net/ethernet/chelsio/cxgb4/cxgb4_ptp.c
drivers/net/ethernet/chelsio/cxgb4/t4_regs.h
drivers/net/ethernet/intel/e1000/e1000_main.c
drivers/net/ethernet/intel/i40e/i40e_main.c
drivers/net/ethernet/mellanox/mlx4/en_tx.c
drivers/net/ethernet/mellanox/mlx5/core/Kconfig
drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c
drivers/net/ethernet/mellanox/mlx5/core/en.h
drivers/net/ethernet/mellanox/mlx5/core/en/tc_ct.c
drivers/net/ethernet/mellanox/mlx5/core/en/xsk/tx.c
drivers/net/ethernet/mellanox/mlx5/core/en_main.c
drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
drivers/net/ethernet/mellanox/mlx5/core/en_txrx.c
drivers/net/ethernet/mellanox/mlxsw/core_acl_flex_actions.c
drivers/net/ethernet/mellanox/mlxsw/spectrum2_acl_tcam.c
drivers/net/ethernet/mellanox/mlxsw/spectrum_acl.c
drivers/net/ethernet/mellanox/mlxsw/spectrum_mr_tcam.c
drivers/net/ethernet/sgi/meth.h
drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c
drivers/net/ethernet/stmicro/stmmac/dwmac-intel.h [new file with mode: 0644]
drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c
drivers/net/ethernet/stmicro/stmmac/stmmac_hwtstamp.c
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
drivers/net/ethernet/xscale/ixp4xx_eth.c
drivers/net/geneve.c
drivers/net/macsec.c
drivers/net/macvlan.c
drivers/net/phy/bcm84881.c
drivers/net/phy/marvell10g.c
drivers/net/phy/microchip_t1.c
drivers/net/team/team.c
drivers/net/vrf.c
drivers/net/vxlan.c
drivers/net/wimax/i2400m/usb-fw.c
drivers/net/wireless/intel/iwlegacy/3945-rs.c
drivers/net/wireless/intel/iwlegacy/4965-rs.c
drivers/net/wireless/intel/iwlwifi/dvm/rs.c
drivers/net/wireless/intel/iwlwifi/fw/acpi.c
drivers/net/wireless/intel/iwlwifi/fw/api/txq.h
drivers/net/wireless/intel/iwlwifi/iwl-drv.c
drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c
drivers/net/wireless/intel/iwlwifi/mvm/fw.c
drivers/net/wireless/intel/iwlwifi/mvm/rs.c
drivers/net/wireless/intel/iwlwifi/mvm/rx.c
drivers/net/wireless/intel/iwlwifi/mvm/sta.c
drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info-gen3.c
drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c
drivers/net/wireless/mac80211_hwsim.c
drivers/net/wireless/realtek/rtlwifi/rc.c
drivers/pci/quirks.c
drivers/phy/tegra/Kconfig
drivers/ptp/ptp_ines.c
drivers/remoteproc/mtk_common.h
drivers/remoteproc/mtk_scp.c
drivers/remoteproc/qcom_q6v5_mss.c
drivers/remoteproc/remoteproc_sysfs.c
drivers/remoteproc/stm32_rproc.c
drivers/rpmsg/mtk_rpmsg.c
drivers/scsi/Kconfig
drivers/scsi/sg.c
drivers/soc/fsl/dpio/dpio-service.c
drivers/soc/fsl/dpio/qbman-portal.c
drivers/soc/imx/Kconfig
drivers/soc/xilinx/Kconfig
drivers/staging/comedi/comedi_fops.c
drivers/staging/comedi/drivers/dt2815.c
drivers/staging/gasket/apex_driver.c
drivers/staging/gasket/gasket_sysfs.c
drivers/staging/gasket/gasket_sysfs.h
drivers/staging/vt6656/key.c
drivers/staging/vt6656/main_usb.c
drivers/staging/vt6656/usbpipe.c
drivers/tty/hvc/hvc_console.c
drivers/tty/rocket.c
drivers/tty/serial/bcm63xx_uart.c
drivers/tty/serial/owl-uart.c
drivers/tty/serial/sh-sci.c
drivers/tty/serial/sunhv.c
drivers/tty/serial/xilinx_uartps.c
drivers/tty/sysrq.c
drivers/tty/vt/vt.c
drivers/usb/class/cdc-acm.c
drivers/usb/class/cdc-acm.h
drivers/usb/core/hub.c
drivers/usb/core/message.c
drivers/usb/core/quirks.c
drivers/usb/dwc3/core.h
drivers/usb/dwc3/gadget.c
drivers/usb/early/xhci-dbc.c
drivers/usb/early/xhci-dbc.h
drivers/usb/gadget/function/f_fs.c
drivers/usb/gadget/legacy/raw_gadget.c
drivers/usb/gadget/udc/atmel_usba_udc.c
drivers/usb/gadget/udc/bdc/bdc_ep.c
drivers/usb/host/xhci-hub.c
drivers/usb/host/xhci-ring.c
drivers/usb/host/xhci.c
drivers/usb/host/xhci.h
drivers/usb/misc/sisusbvga/sisusb.c
drivers/usb/misc/sisusbvga/sisusb_init.h
drivers/usb/storage/uas.c
drivers/usb/storage/unusual_devs.h
drivers/usb/typec/bus.c
drivers/usb/typec/mux/pi3usb30532.c
drivers/usb/typec/tcpm/tcpm.c
drivers/vdpa/Kconfig
drivers/vdpa/ifcvf/ifcvf_base.c
drivers/vdpa/ifcvf/ifcvf_main.c
drivers/vdpa/vdpa.c
drivers/vdpa/vdpa_sim/vdpa_sim.c
drivers/vhost/Kconfig
drivers/vhost/net.c
drivers/vhost/scsi.c
drivers/vhost/test.c
drivers/vhost/vdpa.c
drivers/vhost/vhost.h
drivers/vhost/vringh.c
drivers/vhost/vsock.c
drivers/virtio/Kconfig
drivers/virtio/virtio_balloon.c
drivers/virtio/virtio_input.c
fs/afs/cmservice.c
fs/afs/fs_probe.c
fs/afs/internal.h
fs/afs/rotate.c
fs/afs/server.c
fs/afs/vl_rotate.c
fs/afs/volume.c
fs/block_dev.c
fs/btrfs/block-group.c
fs/btrfs/discard.h
fs/btrfs/disk-io.c
fs/btrfs/relocation.c
fs/buffer.c
fs/cifs/cifsglob.h
fs/cifs/connect.c
fs/cifs/misc.c
fs/cifs/smb2ops.c
fs/coredump.c
fs/debugfs/file.c
fs/exfat/balloc.c
fs/exfat/exfat_fs.h
fs/exfat/file.c
fs/exfat/misc.c
fs/exfat/namei.c
fs/exfat/super.c
fs/io_uring.c
fs/nfsd/nfs4callback.c
fs/nfsd/nfs4state.c
fs/ocfs2/dlmfs/dlmfs.c
fs/pnode.c
fs/proc/base.c
fs/proc/vmcore.c
fs/super.c
include/asm-generic/Kbuild
include/asm-generic/vermagic.h [new file with mode: 0644]
include/linux/backing-dev-defs.h
include/linux/debugfs.h
include/linux/iio/iio.h
include/linux/kvm_host.h
include/linux/pnp.h
include/linux/stmmac.h
include/linux/sunrpc/svc_rdma.h
include/linux/tracepoint.h
include/linux/vdpa.h
include/linux/vermagic.h
include/linux/virtio.h
include/linux/vmalloc.h
include/linux/vringh.h
include/net/mac80211.h
include/net/ndisc.h
include/net/tcp.h
include/soc/tegra/pmc.h
include/sound/soc-dai.h
include/sound/soc.h
include/trace/events/iocost.h
include/trace/events/rpcrdma.h
include/trace/events/writeback.h
include/uapi/linux/bpf.h
include/uapi/linux/hyperv.h
include/uapi/linux/virtio_balloon.h
include/vdso/datapage.h
kernel/audit.c
kernel/bpf/cpumap.c
kernel/bpf/syscall.c
kernel/bpf/verifier.c
kernel/events/core.c
kernel/exit.c
kernel/sched/core.c
kernel/signal.c
kernel/trace/ftrace.c
kernel/trace/trace_events_hist.c
kernel/trace/tracing_map.c
lib/mpi/longlong.h
mm/gup.c
mm/hugetlb.c
mm/ksm.c
mm/madvise.c
mm/shmem.c
mm/slub.c
mm/vmalloc.c
net/core/netclassid_cgroup.c
net/dsa/slave.c
net/ipv4/fib_semantics.c
net/ipv4/xfrm4_output.c
net/ipv6/ipv6_sockglue.c
net/ipv6/rpl.c
net/ipv6/xfrm6_output.c
net/mac80211/main.c
net/mac80211/rate.c
net/mac80211/rate.h
net/mac80211/rc80211_minstrel_ht.c
net/mac80211/sta_info.c
net/mptcp/options.c
net/mptcp/pm_netlink.c
net/mptcp/protocol.c
net/mptcp/protocol.h
net/mptcp/subflow.c
net/netfilter/nf_flow_table_core.c
net/netfilter/nf_nat_proto.c
net/netlabel/Kconfig
net/netrom/nr_route.c
net/openvswitch/conntrack.c
net/openvswitch/datapath.c
net/sched/sch_etf.c
net/sctp/sm_make_chunk.c
net/sctp/sm_statefuns.c
net/sunrpc/cache.c
net/sunrpc/svc_xprt.c
net/sunrpc/svcsock.c
net/sunrpc/xprtrdma/svc_rdma_backchannel.c
net/sunrpc/xprtrdma/svc_rdma_recvfrom.c
net/sunrpc/xprtrdma/svc_rdma_rw.c
net/sunrpc/xprtrdma/svc_rdma_sendto.c
net/sunrpc/xprtrdma/svc_rdma_transport.c
net/sunrpc/xprtsock.c
net/tipc/crypto.c
net/tipc/node.c
net/x25/x25_dev.c
samples/vfio-mdev/mdpy.c
scripts/Makefile.lib
scripts/checkpatch.pl
scripts/config
sound/pci/hda/hda_codec.c
sound/pci/hda/hda_intel.c
sound/pci/hda/patch_hdmi.c
sound/pci/hda/patch_realtek.c
sound/soc/amd/acp3x-rt5682-max9836.c
sound/soc/codecs/Kconfig
sound/soc/codecs/hdac_hdmi.c
sound/soc/codecs/madera.c
sound/soc/codecs/sgtl5000.c
sound/soc/codecs/sgtl5000.h
sound/soc/codecs/tas571x.c
sound/soc/codecs/wm8960.c
sound/soc/codecs/wsa881x.c
sound/soc/intel/common/soc-acpi-intel-cml-match.c
sound/soc/intel/common/soc-acpi-intel-icl-match.c
sound/soc/meson/axg-card.c
sound/soc/meson/gx-card.c
sound/soc/qcom/apq8096.c
sound/soc/qcom/qdsp6/q6afe-dai.c
sound/soc/qcom/sdm845.c
sound/soc/samsung/s3c-i2s-v2.c
sound/soc/samsung/s3c2412-i2s.c
sound/soc/sh/rcar/ssi.c
sound/soc/sh/rcar/ssiu.c
sound/soc/soc-dai.c
sound/soc/soc-dapm.c
sound/soc/soc-pcm.c
sound/soc/soc-topology.c
sound/soc/sof/intel/bdw.c
sound/soc/sof/intel/byt.c
sound/soc/stm/stm32_sai_sub.c
sound/usb/format.c
sound/usb/mixer.c
sound/usb/mixer.h
sound/usb/mixer_maps.c
sound/usb/mixer_quirks.c
sound/usb/quirks-table.h
sound/usb/quirks.c
sound/usb/usx2y/usbusx2yaudio.c
tools/bpf/bpftool/struct_ops.c
tools/bpf/runqslower/Makefile
tools/build/feature/test-sync-compare-and-swap.c
tools/include/uapi/linux/bpf.h
tools/lib/bpf/netlink.c
tools/objtool/elf.c
tools/objtool/elf.h
tools/power/pm-graph/Makefile
tools/power/pm-graph/README
tools/power/pm-graph/bootgraph.py
tools/power/pm-graph/sleepgraph.8
tools/power/pm-graph/sleepgraph.py
tools/testing/selftests/bpf/prog_tests/fexit_bpf2bpf.c
tools/testing/selftests/bpf/progs/connect4_prog.c
tools/testing/selftests/bpf/progs/freplace_connect4.c [new file with mode: 0644]
tools/testing/selftests/bpf/progs/test_btf_haskv.c
tools/testing/selftests/bpf/progs/test_btf_newkv.c
tools/testing/selftests/bpf/progs/test_btf_nokv.c
tools/testing/selftests/bpf/test_btf.c
tools/testing/selftests/bpf/verifier/stack_ptr.c
tools/testing/selftests/bpf/verifier/value_illegal_alu.c
tools/testing/selftests/ftrace/config
tools/testing/selftests/ipc/msgque.c
tools/testing/selftests/kselftest/runner.sh
tools/testing/selftests/kselftest_harness.h
tools/testing/selftests/memfd/Makefile
tools/testing/selftests/net/fib_nexthops.sh
tools/testing/selftests/net/fib_tests.sh
tools/testing/selftests/seccomp/seccomp_bpf.c
tools/testing/selftests/tpm2/test_smoke.sh
tools/testing/selftests/tpm2/test_space.sh
tools/testing/selftests/vm/Makefile
tools/testing/selftests/vm/run_vmtests
tools/virtio/Makefile
tools/virtio/asm/barrier.h
tools/virtio/generated/autoconf.h [new file with mode: 0644]
tools/virtio/linux/compiler.h
tools/vm/Makefile

index 6ec5558b516bd909e2bb266208e08fdffee4364e..e92e6dd1780d0b2eeebf34d8cbac5bc18bbc8204 100644 (file)
@@ -142,10 +142,13 @@ ForEachMacros:
   - 'for_each_card_auxs'
   - 'for_each_card_auxs_safe'
   - 'for_each_card_components'
+  - 'for_each_card_dapms'
   - 'for_each_card_pre_auxs'
   - 'for_each_card_prelinks'
   - 'for_each_card_rtds'
   - 'for_each_card_rtds_safe'
+  - 'for_each_card_widgets'
+  - 'for_each_card_widgets_safe'
   - 'for_each_cgroup_storage_type'
   - 'for_each_child_of_node'
   - 'for_each_clear_bit'
@@ -160,6 +163,7 @@ ForEachMacros:
   - 'for_each_cpu_and'
   - 'for_each_cpu_not'
   - 'for_each_cpu_wrap'
+  - 'for_each_dapm_widgets'
   - 'for_each_dev_addr'
   - 'for_each_dev_scope'
   - 'for_each_displayid_db'
@@ -170,7 +174,6 @@ ForEachMacros:
   - 'for_each_dpcm_fe'
   - 'for_each_drhd_unit'
   - 'for_each_dss_dev'
-  - 'for_each_efi_handle'
   - 'for_each_efi_memory_desc'
   - 'for_each_efi_memory_desc_in_map'
   - 'for_each_element'
@@ -191,6 +194,7 @@ ForEachMacros:
   - 'for_each_ip_tunnel_rcu'
   - 'for_each_irq_nr'
   - 'for_each_link_codecs'
+  - 'for_each_link_cpus'
   - 'for_each_link_platforms'
   - 'for_each_lru'
   - 'for_each_matching_node'
@@ -250,6 +254,7 @@ ForEachMacros:
   - 'for_each_pci_bridge'
   - 'for_each_pci_dev'
   - 'for_each_pci_msi_entry'
+  - 'for_each_pcm_streams'
   - 'for_each_populated_zone'
   - 'for_each_possible_cpu'
   - 'for_each_present_cpu'
@@ -260,9 +265,12 @@ ForEachMacros:
   - 'for_each_property_of_node'
   - 'for_each_registered_fb'
   - 'for_each_reserved_mem_region'
-  - 'for_each_rtd_codec_dai'
-  - 'for_each_rtd_codec_dai_rollback'
+  - 'for_each_rtd_codec_dais'
+  - 'for_each_rtd_codec_dais_rollback'
   - 'for_each_rtd_components'
+  - 'for_each_rtd_cpu_dais'
+  - 'for_each_rtd_cpu_dais_rollback'
+  - 'for_each_rtd_dais'
   - 'for_each_set_bit'
   - 'for_each_set_bit_from'
   - 'for_each_set_clump8'
@@ -334,6 +342,7 @@ ForEachMacros:
   - 'klp_for_each_object'
   - 'klp_for_each_object_safe'
   - 'klp_for_each_object_static'
+  - 'kunit_suite_for_each_test_case'
   - 'kvm_for_each_memslot'
   - 'kvm_for_each_vcpu'
   - 'list_for_each'
@@ -387,6 +396,7 @@ ForEachMacros:
   - 'of_property_for_each_string'
   - 'of_property_for_each_u32'
   - 'pci_bus_for_each_resource'
+  - 'pcm_for_each_format'
   - 'ping_portaddr_for_each_entry'
   - 'plist_for_each'
   - 'plist_for_each_continue'
@@ -482,7 +492,7 @@ KeepEmptyLinesAtTheStartOfBlocks: false
 MacroBlockBegin: ''
 MacroBlockEnd: ''
 MaxEmptyLinesToKeep: 1
-NamespaceIndentation: Inner
+NamespaceIndentation: None
 #ObjCBinPackProtocolList: Auto # Unknown to clang-format-5.0
 ObjCBlockIndentWidth: 8
 ObjCSpaceAfterProperty: true
index f2a93c8679e889151aea5261262d1c7dc13635e6..7bc83f3d9bdfe376762ede68db1d2982eb4d586e 100644 (file)
 
        usbcore.old_scheme_first=
                        [USB] Start with the old device initialization
-                       scheme,  applies only to low and full-speed devices
-                        (default 0 = off).
+                       scheme (default 0 = off).
 
        usbcore.usbfs_memory_mb=
                        [USB] Memory limit (in MB) for buffers allocated by
index 5057b11100ed28656893e69c28dd9759092d18f4..036783ee327f252726f645d4684b6673f8a4aad9 100644 (file)
@@ -23,13 +23,14 @@ optional external memory-mapped interface.
 
 Version 1 of the Activity Monitors architecture implements a counter group
 of four fixed and architecturally defined 64-bit event counters.
-  - CPU cycle counter: increments at the frequency of the CPU.
-  - Constant counter: increments at the fixed frequency of the system
-    clock.
-  - Instructions retired: increments with every architecturally executed
-    instruction.
-  - Memory stall cycles: counts instruction dispatch stall cycles caused by
-    misses in the last level cache within the clock domain.
+
+- CPU cycle counter: increments at the frequency of the CPU.
+- Constant counter: increments at the fixed frequency of the system
+  clock.
+- Instructions retired: increments with every architecturally executed
+  instruction.
+- Memory stall cycles: counts instruction dispatch stall cycles caused by
+  misses in the last level cache within the clock domain.
 
 When in WFI or WFE these counters do not increment.
 
@@ -57,11 +58,12 @@ counters, only the presence of the extension.
 
 Firmware (code running at higher exception levels, e.g. arm-tf) support is
 needed to:
- - Enable access for lower exception levels (EL2 and EL1) to the AMU
-   registers.
- - Enable the counters. If not enabled these will read as 0.
- - Save/restore the counters before/after the CPU is being put/brought up
-   from the 'off' power state.
+
+- Enable access for lower exception levels (EL2 and EL1) to the AMU
+  registers.
+- Enable the counters. If not enabled these will read as 0.
+- Save/restore the counters before/after the CPU is being put/brought up
+  from the 'off' power state.
 
 When using kernels that have this feature enabled but boot with broken
 firmware the user may experience panics or lockups when accessing the
@@ -78,10 +80,11 @@ are not trapped in EL2/EL3.
 
 The fixed counters of AMUv1 are accessible though the following system
 register definitions:
- - SYS_AMEVCNTR0_CORE_EL0
- - SYS_AMEVCNTR0_CONST_EL0
- - SYS_AMEVCNTR0_INST_RET_EL0
- - SYS_AMEVCNTR0_MEM_STALL_EL0
+
+- SYS_AMEVCNTR0_CORE_EL0
+- SYS_AMEVCNTR0_CONST_EL0
+- SYS_AMEVCNTR0_INST_RET_EL0
+- SYS_AMEVCNTR0_MEM_STALL_EL0
 
 Auxiliary platform specific counters can be accessed using
 SYS_AMEVCNTR1_EL0(n), where n is a value between 0 and 15.
@@ -93,9 +96,10 @@ Userspace access
 ----------------
 
 Currently, access from userspace to the AMU registers is disabled due to:
- - Security reasons: they might expose information about code executed in
-   secure mode.
- - Purpose: AMU counters are intended for system management use.
+
+- Security reasons: they might expose information about code executed in
+  secure mode.
+- Purpose: AMU counters are intended for system management use.
 
 Also, the presence of the feature is not visible to userspace.
 
@@ -105,8 +109,9 @@ Virtualization
 
 Currently, access from userspace (EL0) and kernelspace (EL1) on the KVM
 guest side is disabled due to:
- - Security reasons: they might expose information about code executed
-   by other guests or the host.
+
+- Security reasons: they might expose information about code executed
+  by other guests or the host.
 
 Any attempt to access the AMU registers will result in an UNDEFINED
 exception being injected into the guest.
index 1df680d0746108b177a566bbd1060f1bc161a544..7782d99850823f9c8e70a494b0aab659f8d88d32 100644 (file)
@@ -2,6 +2,7 @@
 DT_DOC_CHECKER ?= dt-doc-validate
 DT_EXTRACT_EX ?= dt-extract-example
 DT_MK_SCHEMA ?= dt-mk-schema
+DT_MK_SCHEMA_USERONLY_FLAG := $(if $(DT_SCHEMA_FILES), -u)
 
 quiet_cmd_chk_binding = CHKDT   $(patsubst $(srctree)/%,%,$<)
       cmd_chk_binding = $(DT_DOC_CHECKER) -u $(srctree)/$(src) $< ; \
@@ -13,16 +14,18 @@ $(obj)/%.example.dts: $(src)/%.yaml FORCE
 # Use full schemas when checking %.example.dts
 DT_TMP_SCHEMA := $(obj)/processed-schema-examples.yaml
 
+find_cmd = find $(srctree)/$(src) \( -name '*.yaml' ! \
+               -name 'processed-schema*' ! \
+               -name '*.example.dt.yaml' \)
+
 quiet_cmd_mk_schema = SCHEMA  $@
-      cmd_mk_schema = $(DT_MK_SCHEMA) $(DT_MK_SCHEMA_FLAGS) -o $@ $(real-prereqs)
+      cmd_mk_schema = rm -f $@ ; \
+                      $(if $(DT_MK_SCHEMA_FLAGS), \
+                           echo $(real-prereqs), \
+                           $(find_cmd)) | \
+                      xargs $(DT_MK_SCHEMA) $(DT_MK_SCHEMA_FLAGS) >> $@
 
-DT_DOCS = $(addprefix $(src)/, \
-       $(shell \
-       cd $(srctree)/$(src) && \
-       find * \( -name '*.yaml' ! \
-               -name 'processed-schema*' ! \
-               -name '*.example.dt.yaml' \) \
-       ))
+DT_DOCS = $(shell $(find_cmd) | sed -e 's|^$(srctree)/||')
 
 DT_SCHEMA_FILES ?= $(DT_DOCS)
 
@@ -37,7 +40,7 @@ override DTC_FLAGS := \
 $(obj)/processed-schema-examples.yaml: $(DT_DOCS) FORCE
        $(call if_changed,mk_schema)
 
-$(obj)/processed-schema.yaml: DT_MK_SCHEMA_FLAGS := -u
+$(obj)/processed-schema.yaml: DT_MK_SCHEMA_FLAGS := $(DT_MK_SCHEMA_USERONLY_FLAG)
 $(obj)/processed-schema.yaml: $(DT_SCHEMA_FILES) FORCE
        $(call if_changed,mk_schema)
 
index fd931b29381670bcf271f926b9543522f06d260c..b900973b5f7b7622fba9ccd3f4b5720a61e159cf 100644 (file)
@@ -37,7 +37,6 @@ examples:
     dsi {
         #address-cells = <1>;
         #size-cells = <0>;
-        reg = <0xff450000 0x1000>;
 
         panel@0 {
             compatible = "leadtek,ltk500hd1829";
index d0083301acbefbe78a1d528a413ae2f2a24f73a2..946dd354256c11d2e461f4810e8b094ef08117f3 100644 (file)
@@ -96,12 +96,20 @@ properties:
       If set, reverse the bit order described in the data mappings below on all
       data lanes, transmitting bits for slots 6 to 0 instead of 0 to 6.
 
+  port: true
+  ports: true
+
 required:
   - compatible
   - data-mapping
   - width-mm
   - height-mm
   - panel-timing
-  - port
+
+oneOf:
+  - required:
+      - port
+  - required:
+      - ports
 
 ...
index d9fdb58e06b4218bc1db4d2b9b8534085903f336..6913923df5695ccd453a7597ebf532f18c509c78 100644 (file)
@@ -37,7 +37,6 @@ examples:
     dsi {
         #address-cells = <1>;
         #size-cells = <0>;
-        reg = <0xff450000 0x1000>;
 
         panel@0 {
             compatible = "xinpeng,xpp055c272";
index 933ba37944d7175a12fc5bde0cef17aa7139a265..dd8eb15aeb6395b68b1583f03a5f8a0621315f08 100644 (file)
@@ -1,7 +1,7 @@
 # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
 %YAML 1.2
 ---
-$id: "http://devicetree.org/schemas/bindings/iio/adc/st,stm32-adc.yaml#"
+$id: "http://devicetree.org/schemas/iio/adc/st,stm32-adc.yaml#"
 $schema: "http://devicetree.org/meta-schemas/core.yaml#"
 
 title: STMicroelectronics STM32 ADC bindings
index f88d13d7044137e09c382caea88fb5e503a2b73a..be7faa6dc055e3fcc494458033f42bd8a99de138 100644 (file)
@@ -259,8 +259,6 @@ properties:
 
     additionalProperties: false
 
-  additionalProperties: false
-
 additionalProperties: false
 
 required:
index 144ae29e7141930221bddbda99d1631df07b79a3..f8bd28ff31c1fafd03468fa5bb4e3bdc712ca65a 100644 (file)
@@ -97,7 +97,7 @@ then:
         - $ref: /schemas/types.yaml#/definitions/uint32
         - minimum: 0
           maximum: 63
-          default: 0
+          default: 32
 
     qcom,charge-ctrl-value:
      description:
@@ -130,7 +130,7 @@ then:
         - $ref: /schemas/types.yaml#/definitions/uint32
         - minimum: 0
           maximum: 3
-          default: 2
+          default: 0
 
     qcom,preemphasis-width:
       description:
@@ -152,7 +152,7 @@ then:
         - $ref: /schemas/types.yaml#/definitions/uint32
         - minimum: 0
           maximum: 3
-          default: 0
+          default: 1
 
 required:
   - compatible
index f0acce2029fde0e9f10e6335ab563fb1d88ee544..3b019fa6db31788380d9122a643e602a8b03ac69 100644 (file)
@@ -37,7 +37,6 @@ properties:
         type: object
 
     additionalProperties: false
-  additionalProperties: false
 
 required:
   - compatible
index a682af0dc67ed129a394ca61e08f119a9fc0df3a..ae6e7ab36c58658c47a8cf82cc217e34bb2beb5b 100644 (file)
@@ -75,7 +75,8 @@ properties:
             description: |
               disables over voltage protection of this buck
 
-      additionalProperties: false
+        unevaluatedProperties: false
+
     additionalProperties: false
 
 required:
index 71ce032b8cf8b87659fe035a7e30a3061a4df858..1e52dafcb5c9a4e8080450bb64daeb08cc0d2f83 100644 (file)
@@ -35,6 +35,8 @@ patternProperties:
         description:
           should be "ldo1", ..., "ldo7"
 
+    unevaluatedProperties: false
+
   "^BUCK[1-7]$":
     type: object
     allOf:
@@ -103,5 +105,7 @@ patternProperties:
 
     required:
       - regulator-name
-  additionalProperties: false
+
+    unevaluatedProperties: false
+
 additionalProperties: false
index a323b1696eee8597c37a792ad0e36c818f3a8e96..543d4b52397e2572db019c3660b95a4b0e59b866 100644 (file)
@@ -41,6 +41,8 @@ patternProperties:
         description:
           should be "ldo1", ..., "ldo7"
 
+    unevaluatedProperties: false
+
   "^BUCK[1-8]$":
     type: object
     allOf:
@@ -99,5 +101,7 @@ patternProperties:
 
     required:
       - regulator-name
-  additionalProperties: false
+
+    unevaluatedProperties: false
+
 additionalProperties: false
index 526fd00bcb162b2642dc962313502b5717a4e6b8..d797cc23406f897b3ff1bb40989b278b34ca28e0 100644 (file)
@@ -40,6 +40,8 @@ patternProperties:
         description:
           should be "ldo1", ..., "ldo6"
 
+    unevaluatedProperties: false
+
   "^BUCK[1-6]$":
     type: object
     allOf:
@@ -93,5 +95,7 @@ patternProperties:
 
     required:
       - regulator-name
-  additionalProperties: false
+
+    unevaluatedProperties: false
+
 additionalProperties: false
index 7cd0e278ed85a1a09e9bd290ab0a0ae00ef5cfa0..a3ba2186d6a184ee3f98f9199623305b3f851211 100644 (file)
@@ -56,6 +56,9 @@ properties:
       - const: tx
       - const: rx
 
+  power-domains:
+    maxItems: 1
+
   rockchip,capture-channels:
     allOf:
       - $ref: /schemas/types.yaml#/definitions/uint32
diff --git a/Documentation/devicetree/bindings/sound/rockchip-spdif.txt b/Documentation/devicetree/bindings/sound/rockchip-spdif.txt
deleted file mode 100644 (file)
index ec20c12..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-* Rockchip SPDIF transceiver
-
-The S/PDIF audio block is a stereo transceiver that allows the
-processor to receive and transmit digital audio via an coaxial cable or
-a fibre cable.
-
-Required properties:
-
-- compatible: should be one of the following:
-   - "rockchip,rk3066-spdif"
-   - "rockchip,rk3188-spdif"
-   - "rockchip,rk3228-spdif"
-   - "rockchip,rk3288-spdif"
-   - "rockchip,rk3328-spdif"
-   - "rockchip,rk3366-spdif"
-   - "rockchip,rk3368-spdif"
-   - "rockchip,rk3399-spdif"
-- reg: physical base address of the controller and length of memory mapped
-  region.
-- interrupts: should contain the SPDIF interrupt.
-- dmas: DMA specifiers for tx dma. See the DMA client binding,
-  Documentation/devicetree/bindings/dma/dma.txt
-- dma-names: should be "tx"
-- clocks: a list of phandle + clock-specifier pairs, one for each entry
-  in clock-names.
-- clock-names: should contain following:
-   - "hclk": clock for SPDIF controller
-   - "mclk" : clock for SPDIF bus
-
-Required properties on RK3288:
-  - rockchip,grf: the phandle of the syscon node for the general register
-                   file (GRF)
-
-Example for the rk3188 SPDIF controller:
-
-spdif: spdif@1011e000 {
-       compatible = "rockchip,rk3188-spdif", "rockchip,rk3066-spdif";
-       reg = <0x1011e000 0x2000>;
-       interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
-       dmas = <&dmac1_s 8>;
-       dma-names = "tx";
-       clock-names = "hclk", "mclk";
-       clocks = <&cru HCLK_SPDIF>, <&cru SCLK_SPDIF>;
-       #sound-dai-cells = <0>;
-};
diff --git a/Documentation/devicetree/bindings/sound/rockchip-spdif.yaml b/Documentation/devicetree/bindings/sound/rockchip-spdif.yaml
new file mode 100644 (file)
index 0000000..c467152
--- /dev/null
@@ -0,0 +1,101 @@
+# SPDX-License-Identifier: GPL-2.0
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/sound/rockchip-spdif.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Rockchip SPDIF transceiver
+
+description:
+  The S/PDIF audio block is a stereo transceiver that allows the
+  processor to receive and transmit digital audio via a coaxial or
+  fibre cable.
+
+maintainers:
+  - Heiko Stuebner <heiko@sntech.de>
+
+properties:
+  compatible:
+    oneOf:
+      - const: rockchip,rk3066-spdif
+      - const: rockchip,rk3228-spdif
+      - const: rockchip,rk3328-spdif
+      - const: rockchip,rk3366-spdif
+      - const: rockchip,rk3368-spdif
+      - const: rockchip,rk3399-spdif
+      - items:
+          - enum:
+            - rockchip,rk3188-spdif
+            - rockchip,rk3288-spdif
+          - const: rockchip,rk3066-spdif
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  clocks:
+    items:
+      - description: clock for SPDIF bus
+      - description: clock for SPDIF controller
+
+  clock-names:
+    items:
+      - const: mclk
+      - const: hclk
+
+  dmas:
+    maxItems: 1
+
+  dma-names:
+    const: tx
+
+  power-domains:
+    maxItems: 1
+
+  rockchip,grf:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description:
+      The phandle of the syscon node for the GRF register.
+      Required property on RK3288.
+
+  "#sound-dai-cells":
+    const: 0
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - clocks
+  - clock-names
+  - dmas
+  - dma-names
+  - "#sound-dai-cells"
+
+if:
+  properties:
+    compatible:
+      contains:
+        const: rockchip,rk3288-spdif
+
+then:
+  required:
+    - rockchip,grf
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/rk3188-cru.h>
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    spdif: spdif@1011e000 {
+      compatible = "rockchip,rk3188-spdif", "rockchip,rk3066-spdif";
+      reg = <0x1011e000 0x2000>;
+      interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
+      clocks = <&cru SCLK_SPDIF>, <&cru HCLK_SPDIF>;
+      clock-names = "mclk", "hclk";
+      dmas = <&dmac1_s 8>;
+      dma-names = "tx";
+      #sound-dai-cells = <0>;
+    };
index 92d8631b9aa60c6968d074100d4a98b62e310ce7..031452aa25bc2a94c24cab8281e8762be76947e9 100644 (file)
@@ -18,6 +18,7 @@ properties:
           - renesas,r8a774c0-usb3-peri # RZ/G2E
           - renesas,r8a7795-usb3-peri  # R-Car H3
           - renesas,r8a7796-usb3-peri  # R-Car M3-W
+          - renesas,r8a77961-usb3-peri # R-Car M3-W+
           - renesas,r8a77965-usb3-peri # R-Car M3-N
           - renesas,r8a77990-usb3-peri # R-Car E3
       - const: renesas,rcar-gen3-usb3-peri
index 469affa872d34ba7662dde2f1778b1d70136923d..a7ae95598ccb1056182b471d627610e64d68904c 100644 (file)
@@ -40,6 +40,7 @@ properties:
               - renesas,usbhs-r8a774c0 # RZ/G2E
               - renesas,usbhs-r8a7795  # R-Car H3
               - renesas,usbhs-r8a7796  # R-Car M3-W
+              - renesas,usbhs-r8a77961 # R-Car M3-W+
               - renesas,usbhs-r8a77965 # R-Car M3-N
               - renesas,usbhs-r8a77990 # R-Car E3
               - renesas,usbhs-r8a77995 # R-Car D3
index 3f378951d624bfc6b45035a23e77dc0c42a33b62..dc025f126d717b4b8471080ee03f09278a1b9a3d 100644 (file)
@@ -16,7 +16,8 @@ Required properties:
     - "renesas,xhci-r8a7791" for r8a7791 SoC
     - "renesas,xhci-r8a7793" for r8a7793 SoC
     - "renesas,xhci-r8a7795" for r8a7795 SoC
-    - "renesas,xhci-r8a7796" for r8a7796 SoC
+    - "renesas,xhci-r8a7796" for r8a77960 SoC
+    - "renesas,xhci-r8a77961" for r8a77961 SoC
     - "renesas,xhci-r8a77965" for r8a77965 SoC
     - "renesas,xhci-r8a77990" for r8a77990 SoC
     - "renesas,rcar-gen2-xhci" for a generic R-Car Gen2 or RZ/G1 compatible
index db9ea085404033d7723ccd2ba02c4abdab8b0712..6c032db235a5efa2e4745485d4a22cdb3ffe503a 100644 (file)
@@ -79,8 +79,8 @@ created with any of::
                           struct dentry *parent, u8 *value);
     void debugfs_create_u16(const char *name, umode_t mode,
                            struct dentry *parent, u16 *value);
-    struct dentry *debugfs_create_u32(const char *name, umode_t mode,
-                                     struct dentry *parent, u32 *value);
+    void debugfs_create_u32(const char *name, umode_t mode,
+                           struct dentry *parent, u32 *value);
     void debugfs_create_u64(const char *name, umode_t mode,
                            struct dentry *parent, u64 *value);
 
index 04d5c01a2e998db16fa8ca7846a5d8e0034c41a0..b80257a0383030fc7f5383f3a37cc37ee8df2179 100644 (file)
@@ -1241,7 +1241,8 @@ When kbuild executes, the following steps are followed (roughly):
        will be displayed with "make KBUILD_VERBOSE=0".
 
 
---- 6.9 Preprocessing linker scripts
+6.9 Preprocessing linker scripts
+--------------------------------
 
        When the vmlinux image is built, the linker script
        arch/$(ARCH)/kernel/vmlinux.lds is used.
index 6fcfd313dbe417ee7ee1098870ccb72a42a797a6..9375324aa8e1630c373098842c05f8d3b38715d9 100644 (file)
@@ -983,6 +983,13 @@ ip_early_demux - BOOLEAN
        reduces overall throughput, in such case you should disable it.
        Default: 1
 
+ping_group_range - 2 INTEGERS
+       Restrict ICMP_PROTO datagram sockets to users in the group range.
+       The default is "1 0", meaning, that nobody (not even root) may
+       create ping sockets.  Setting it to "100 100" would grant permissions
+       to the single group. "0 4294967295" would enable it for the world, "100
+       4294967295" would enable it for the users, but not daemons.
+
 tcp_early_demux - BOOLEAN
        Enable early demux for established TCP sockets.
        Default: 1
index b816a453b10eba4288be034f340dd135a32742a9..26f281d9f32a4ad35d744a90353c93177b309287 100644 (file)
@@ -189,7 +189,7 @@ F:  drivers/net/hamradio/6pack.c
 M:     Johannes Berg <johannes@sipsolutions.net>
 L:     linux-wireless@vger.kernel.org
 S:     Maintained
-W:     http://wireless.kernel.org/
+W:     https://wireless.wiki.kernel.org/
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211.git
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next.git
 F:     Documentation/driver-api/80211/cfg80211.rst
@@ -505,7 +505,7 @@ F:  drivers/hwmon/adm1029.c
 ADM8211 WIRELESS DRIVER
 L:     linux-wireless@vger.kernel.org
 S:     Orphan
-W:     http://wireless.kernel.org/
+W:     https://wireless.wiki.kernel.org/
 F:     drivers/net/wireless/admtek/adm8211.*
 
 ADP1653 FLASH CONTROLLER DRIVER
@@ -570,7 +570,7 @@ F:  Documentation/devicetree/bindings/iio/accel/adi,adxl345.yaml
 F:     drivers/input/misc/adxl34x.c
 
 ADXL372 THREE-AXIS DIGITAL ACCELEROMETER DRIVER
-M:     Stefan Popa <stefan.popa@analog.com>
+M:     Michael Hennerich <michael.hennerich@analog.com>
 S:     Supported
 W:     http://ez.analog.com/community/linux-device-drivers
 F:     Documentation/devicetree/bindings/iio/accel/adi,adxl372.yaml
@@ -922,7 +922,7 @@ F:  arch/arm64/boot/dts/amd/amd-seattle-xgbe*.dtsi
 F:     drivers/net/ethernet/amd/xgbe/
 
 ANALOG DEVICES INC AD5686 DRIVER
-M:     Stefan Popa <stefan.popa@analog.com>
+M:     Michael Hennerich <Michael.Hennerich@analog.com>
 L:     linux-pm@vger.kernel.org
 S:     Supported
 W:     http://ez.analog.com/community/linux-device-drivers
@@ -930,7 +930,7 @@ F:  drivers/iio/dac/ad5686*
 F:     drivers/iio/dac/ad5696*
 
 ANALOG DEVICES INC AD5758 DRIVER
-M:     Stefan Popa <stefan.popa@analog.com>
+M:     Michael Hennerich <Michael.Hennerich@analog.com>
 L:     linux-iio@vger.kernel.org
 S:     Supported
 W:     http://ez.analog.com/community/linux-device-drivers
@@ -946,7 +946,7 @@ F:  Documentation/devicetree/bindings/iio/adc/adi,ad7091r5.yaml
 F:     drivers/iio/adc/ad7091r5.c
 
 ANALOG DEVICES INC AD7124 DRIVER
-M:     Stefan Popa <stefan.popa@analog.com>
+M:     Michael Hennerich <Michael.Hennerich@analog.com>
 L:     linux-iio@vger.kernel.org
 S:     Supported
 W:     http://ez.analog.com/community/linux-device-drivers
@@ -970,7 +970,7 @@ F:  Documentation/devicetree/bindings/iio/adc/adi,ad7292.yaml
 F:     drivers/iio/adc/ad7292.c
 
 ANALOG DEVICES INC AD7606 DRIVER
-M:     Stefan Popa <stefan.popa@analog.com>
+M:     Michael Hennerich <Michael.Hennerich@analog.com>
 M:     Beniamin Bia <beniamin.bia@analog.com>
 L:     linux-iio@vger.kernel.org
 S:     Supported
@@ -979,7 +979,7 @@ F:  Documentation/devicetree/bindings/iio/adc/adi,ad7606.yaml
 F:     drivers/iio/adc/ad7606.c
 
 ANALOG DEVICES INC AD7768-1 DRIVER
-M:     Stefan Popa <stefan.popa@analog.com>
+M:     Michael Hennerich <Michael.Hennerich@analog.com>
 L:     linux-iio@vger.kernel.org
 S:     Supported
 W:     http://ez.analog.com/community/linux-device-drivers
@@ -1040,7 +1040,7 @@ F:        Documentation/devicetree/bindings/hwmon/adi,adm1177.yaml
 F:     drivers/hwmon/adm1177.c
 
 ANALOG DEVICES INC ADP5061 DRIVER
-M:     Stefan Popa <stefan.popa@analog.com>
+M:     Michael Hennerich <Michael.Hennerich@analog.com>
 L:     linux-pm@vger.kernel.org
 S:     Supported
 W:     http://ez.analog.com/community/linux-device-drivers
@@ -1109,7 +1109,6 @@ F:        drivers/iio/amplifiers/hmc425a.c
 ANALOG DEVICES INC IIO DRIVERS
 M:     Lars-Peter Clausen <lars@metafoo.de>
 M:     Michael Hennerich <Michael.Hennerich@analog.com>
-M:     Stefan Popa <stefan.popa@analog.com>
 S:     Supported
 W:     http://wiki.analog.com/
 W:     http://ez.analog.com/community/linux-device-drivers
@@ -2850,14 +2849,14 @@ M:      Nick Kossifidis <mickflemm@gmail.com>
 M:     Luis Chamberlain <mcgrof@kernel.org>
 L:     linux-wireless@vger.kernel.org
 S:     Maintained
-W:     http://wireless.kernel.org/en/users/Drivers/ath5k
+W:     https://wireless.wiki.kernel.org/en/users/Drivers/ath5k
 F:     drivers/net/wireless/ath/ath5k/
 
 ATHEROS ATH6KL WIRELESS DRIVER
 M:     Kalle Valo <kvalo@codeaurora.org>
 L:     linux-wireless@vger.kernel.org
 S:     Supported
-W:     http://wireless.kernel.org/en/users/Drivers/ath6kl
+W:     https://wireless.wiki.kernel.org/en/users/Drivers/ath6kl
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/ath.git
 F:     drivers/net/wireless/ath/ath6kl/
 
@@ -3020,7 +3019,7 @@ B43 WIRELESS DRIVER
 L:     linux-wireless@vger.kernel.org
 L:     b43-dev@lists.infradead.org
 S:     Odd Fixes
-W:     http://wireless.kernel.org/en/users/Drivers/b43
+W:     https://wireless.wiki.kernel.org/en/users/Drivers/b43
 F:     drivers/net/wireless/broadcom/b43/
 
 B43LEGACY WIRELESS DRIVER
@@ -3028,7 +3027,7 @@ M:        Larry Finger <Larry.Finger@lwfinger.net>
 L:     linux-wireless@vger.kernel.org
 L:     b43-dev@lists.infradead.org
 S:     Maintained
-W:     http://wireless.kernel.org/en/users/Drivers/b43
+W:     https://wireless.wiki.kernel.org/en/users/Drivers/b43
 F:     drivers/net/wireless/broadcom/b43legacy/
 
 BACKLIGHT CLASS/SUBSYSTEM
@@ -3843,7 +3842,7 @@ CARL9170 LINUX COMMUNITY WIRELESS DRIVER
 M:     Christian Lamparter <chunkeey@googlemail.com>
 L:     linux-wireless@vger.kernel.org
 S:     Maintained
-W:     http://wireless.kernel.org/en/users/Drivers/carl9170
+W:     https://wireless.wiki.kernel.org/en/users/Drivers/carl9170
 F:     drivers/net/wireless/ath/carl9170/
 
 CAVIUM I2C DRIVER
@@ -5176,6 +5175,7 @@ S:        Maintained
 F:     drivers/soc/fsl/dpio
 
 DPAA2 ETHERNET DRIVER
+M:     Ioana Ciornei <ioana.ciornei@nxp.com>
 M:     Ioana Radulescu <ruxandra.radulescu@nxp.com>
 L:     netdev@vger.kernel.org
 S:     Maintained
@@ -9329,6 +9329,7 @@ M:        Christian Borntraeger <borntraeger@de.ibm.com>
 M:     Janosch Frank <frankja@linux.ibm.com>
 R:     David Hildenbrand <david@redhat.com>
 R:     Cornelia Huck <cohuck@redhat.com>
+R:     Claudio Imbrenda <imbrenda@linux.ibm.com>
 L:     kvm@vger.kernel.org
 S:     Supported
 W:     http://www.ibm.com/developerworks/linux/linux390/
@@ -9416,6 +9417,13 @@ F:       include/linux/keyctl.h
 F:     include/uapi/linux/keyctl.h
 F:     security/keys/
 
+KFIFO
+M:     Stefani Seibold <stefani@seibold.net>
+S:     Maintained
+F:     include/linux/kfifo.h
+F:     lib/kfifo.c
+F:     samples/kfifo/
+
 KGDB / KDB /debug_core
 M:     Jason Wessel <jason.wessel@windriver.com>
 M:     Daniel Thompson <daniel.thompson@linaro.org>
@@ -10067,7 +10075,7 @@ MAC80211
 M:     Johannes Berg <johannes@sipsolutions.net>
 L:     linux-wireless@vger.kernel.org
 S:     Maintained
-W:     http://wireless.kernel.org/
+W:     https://wireless.wiki.kernel.org/
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211.git
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next.git
 F:     Documentation/networking/mac80211-injection.txt
@@ -10697,7 +10705,6 @@ MEDIATEK MT76 WIRELESS LAN DRIVER
 M:     Felix Fietkau <nbd@nbd.name>
 M:     Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
 R:     Ryder Lee <ryder.lee@mediatek.com>
-R:     Roy Luo <royluo@google.com>
 L:     linux-wireless@vger.kernel.org
 S:     Maintained
 F:     drivers/net/wireless/mediatek/mt76/
@@ -12648,7 +12655,7 @@ F:      fs/orangefs/
 ORINOCO DRIVER
 L:     linux-wireless@vger.kernel.org
 S:     Orphan
-W:     http://wireless.kernel.org/en/users/Drivers/orinoco
+W:     https://wireless.wiki.kernel.org/en/users/Drivers/orinoco
 W:     http://www.nongnu.org/orinoco/
 F:     drivers/net/wireless/intersil/orinoco/
 
@@ -12674,7 +12681,7 @@ P54 WIRELESS DRIVER
 M:     Christian Lamparter <chunkeey@googlemail.com>
 L:     linux-wireless@vger.kernel.org
 S:     Maintained
-W:     http://wireless.kernel.org/en/users/Drivers/p54
+W:     https://wireless.wiki.kernel.org/en/users/Drivers/p54
 F:     drivers/net/wireless/intersil/p54/
 
 PACKING
@@ -13042,7 +13049,7 @@ F:      drivers/pci/controller/pci-xgene-msi.c
 
 PCI NATIVE HOST BRIDGE AND ENDPOINT DRIVERS
 M:     Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
-R:     Andrew Murray <amurray@thegoodpenguin.co.uk>
+R:     Rob Herring <robh@kernel.org>
 L:     linux-pci@vger.kernel.org
 S:     Supported
 Q:     http://patchwork.ozlabs.org/project/linux-pci/list/
@@ -13595,7 +13602,7 @@ PRISM54 WIRELESS DRIVER
 M:     Luis Chamberlain <mcgrof@kernel.org>
 L:     linux-wireless@vger.kernel.org
 S:     Obsolete
-W:     http://wireless.kernel.org/en/users/Drivers/p54
+W:     https://wireless.wiki.kernel.org/en/users/Drivers/p54
 F:     drivers/net/wireless/intersil/prism54/
 
 PROC FILESYSTEM
@@ -13936,7 +13943,7 @@ QUALCOMM ATHEROS ATH10K WIRELESS DRIVER
 M:     Kalle Valo <kvalo@codeaurora.org>
 L:     ath10k@lists.infradead.org
 S:     Supported
-W:     http://wireless.kernel.org/en/users/Drivers/ath10k
+W:     https://wireless.wiki.kernel.org/en/users/Drivers/ath10k
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/ath.git
 F:     drivers/net/wireless/ath/ath10k/
 
@@ -13951,7 +13958,7 @@ QUALCOMM ATHEROS ATH9K WIRELESS DRIVER
 M:     QCA ath9k Development <ath9k-devel@qca.qualcomm.com>
 L:     linux-wireless@vger.kernel.org
 S:     Supported
-W:     http://wireless.kernel.org/en/users/Drivers/ath9k
+W:     https://wireless.wiki.kernel.org/en/users/Drivers/ath9k
 F:     drivers/net/wireless/ath/ath9k/
 
 QUALCOMM CAMERA SUBSYSTEM DRIVER
@@ -14048,13 +14055,12 @@ QUALCOMM WCN36XX WIRELESS DRIVER
 M:     Kalle Valo <kvalo@codeaurora.org>
 L:     wcn36xx@lists.infradead.org
 S:     Supported
-W:     http://wireless.kernel.org/en/users/Drivers/wcn36xx
+W:     https://wireless.wiki.kernel.org/en/users/Drivers/wcn36xx
 T:     git git://github.com/KrasnikovEugene/wcn36xx.git
 F:     drivers/net/wireless/ath/wcn36xx/
 
 QUANTENNA QTNFMAC WIRELESS DRIVER
 M:     Igor Mitsyanko <imitsyanko@quantenna.com>
-M:     Avinash Patil <avinashp@quantenna.com>
 M:     Sergey Matyukevich <smatyukevich@quantenna.com>
 L:     linux-wireless@vger.kernel.org
 S:     Maintained
@@ -14276,7 +14282,7 @@ REALTEK WIRELESS DRIVER (rtlwifi family)
 M:     Ping-Ke Shih <pkshih@realtek.com>
 L:     linux-wireless@vger.kernel.org
 S:     Maintained
-W:     http://wireless.kernel.org/
+W:     https://wireless.wiki.kernel.org/
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-testing.git
 F:     drivers/net/wireless/realtek/rtlwifi/
 
@@ -14411,7 +14417,7 @@ RFKILL
 M:     Johannes Berg <johannes@sipsolutions.net>
 L:     linux-wireless@vger.kernel.org
 S:     Maintained
-W:     http://wireless.kernel.org/
+W:     https://wireless.wiki.kernel.org/
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211.git
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next.git
 F:     Documentation/ABI/stable/sysfs-class-rfkill
@@ -14560,7 +14566,7 @@ F:      drivers/media/dvb-frontends/rtl2832_sdr*
 RTL8180 WIRELESS DRIVER
 L:     linux-wireless@vger.kernel.org
 S:     Orphan
-W:     http://wireless.kernel.org/
+W:     https://wireless.wiki.kernel.org/
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-testing.git
 F:     drivers/net/wireless/realtek/rtl818x/rtl8180/
 
@@ -14570,7 +14576,7 @@ M:      Hin-Tak Leung <htl10@users.sourceforge.net>
 M:     Larry Finger <Larry.Finger@lwfinger.net>
 L:     linux-wireless@vger.kernel.org
 S:     Maintained
-W:     http://wireless.kernel.org/
+W:     https://wireless.wiki.kernel.org/
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-testing.git
 F:     drivers/net/wireless/realtek/rtl818x/rtl8187/
 
@@ -16925,8 +16931,8 @@ F:      drivers/media/platform/ti-vpe/
 TI WILINK WIRELESS DRIVERS
 L:     linux-wireless@vger.kernel.org
 S:     Orphan
-W:     http://wireless.kernel.org/en/users/Drivers/wl12xx
-W:     http://wireless.kernel.org/en/users/Drivers/wl1251
+W:     https://wireless.wiki.kernel.org/en/users/Drivers/wl12xx
+W:     https://wireless.wiki.kernel.org/en/users/Drivers/wl1251
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/luca/wl12xx.git
 F:     drivers/net/wireless/ti/
 F:     include/linux/wl12xx.h
@@ -18208,7 +18214,7 @@ M:      Maya Erez <merez@codeaurora.org>
 L:     linux-wireless@vger.kernel.org
 L:     wil6210@qti.qualcomm.com
 S:     Supported
-W:     http://wireless.kernel.org/en/users/Drivers/wil6210
+W:     https://wireless.wiki.kernel.org/en/users/Drivers/wil6210
 F:     drivers/net/wireless/ath/wil6210/
 
 WIMAX STACK
index 49b2709ff44e3fc204ca21777bec4ed93956b707..679f302a8b8bd47288753e065af1273bbf149bfa 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -2,7 +2,7 @@
 VERSION = 5
 PATCHLEVEL = 7
 SUBLEVEL = 0
-EXTRAVERSION = -rc2
+EXTRAVERSION = -rc3
 NAME = Kleptomaniac Octopus
 
 # *DOCUMENTATION*
index 48f13a4ace4b3fcb07d5cbaf5e64e72ac359fcfa..f534a1fef070fb13ed0e94ebf2768d51158759ae 100644 (file)
@@ -3,7 +3,6 @@
  * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com)
  *
  * Amit Bhor, Sameer Dhavale: Codito Technologies 2004
-
  */
 
 #ifndef _ASM_ARC_MODULE_H
@@ -19,8 +18,4 @@ struct mod_arch_specific {
        const char *secstr;
 };
 
-#define MODULE_PROC_FAMILY "ARC700"
-
-#define MODULE_ARCH_VERMAGIC MODULE_PROC_FAMILY
-
 #endif /* _ASM_ARC_MODULE_H */
diff --git a/arch/arc/include/asm/vermagic.h b/arch/arc/include/asm/vermagic.h
new file mode 100644 (file)
index 0000000..a10257d
--- /dev/null
@@ -0,0 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#ifndef _ASM_VERMAGIC_H
+#define _ASM_VERMAGIC_H
+
+#define MODULE_ARCH_VERMAGIC "ARC700"
+
+#endif /* _ASM_VERMAGIC_H */
index fd2c766e0f7108973b771660e368d66cef3a5bc4..f7ae5a4530b8807e4ad3f6b90c7c8205bcd9b2c2 100644 (file)
@@ -14,6 +14,9 @@
        soc {
                firmware: firmware {
                        compatible = "raspberrypi,bcm2835-firmware", "simple-bus";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+
                        mboxes = <&mailbox>;
                        dma-ranges;
                };
index e1abe8c730cefca16e942eb5f89a16d4f8cad45d..b83a864e2e8ba1a8326cadce40bfd6cac15830a2 100644 (file)
                                             "dsi0_ddr2",
                                             "dsi0_ddr";
 
+                       status = "disabled";
                };
 
                aux: aux@7e215000 {
index a075b63f3087d110a709d3dbfbe3186e513dfb4e..11d41e86f814d26e42249d9ff96ea4c0745d3955 100644 (file)
        status = "disabled";
 };
 
+/* RNG not directly accessible on N950/N9. */
+&rng_target {
+       status = "disabled";
+};
+
 &usb_otg_hs {
        interface-type = <0>;
        usb-phy = <&usb2_phy>;
index 182163b55546c973767ad8687b6ee4e362465b70..4b0df09cbe678dc5aa33e97a46972c9de40fef72 100644 (file)
@@ -37,30 +37,6 @@ struct mod_arch_specific {
 struct module;
 u32 get_module_plt(struct module *mod, unsigned long loc, Elf32_Addr val);
 
-/*
- * Add the ARM architecture version to the version magic string
- */
-#define MODULE_ARCH_VERMAGIC_ARMVSN "ARMv" __stringify(__LINUX_ARM_ARCH__) " "
-
-/* Add __virt_to_phys patching state as well */
-#ifdef CONFIG_ARM_PATCH_PHYS_VIRT
-#define MODULE_ARCH_VERMAGIC_P2V "p2v8 "
-#else
-#define MODULE_ARCH_VERMAGIC_P2V ""
-#endif
-
-/* Add instruction set architecture tag to distinguish ARM/Thumb kernels */
-#ifdef CONFIG_THUMB2_KERNEL
-#define MODULE_ARCH_VERMAGIC_ARMTHUMB "thumb2 "
-#else
-#define MODULE_ARCH_VERMAGIC_ARMTHUMB ""
-#endif
-
-#define MODULE_ARCH_VERMAGIC \
-       MODULE_ARCH_VERMAGIC_ARMVSN \
-       MODULE_ARCH_VERMAGIC_ARMTHUMB \
-       MODULE_ARCH_VERMAGIC_P2V
-
 #ifdef CONFIG_THUMB2_KERNEL
 #define HAVE_ARCH_KALLSYMS_SYMBOL_VALUE
 static inline unsigned long kallsyms_symbol_value(const Elf_Sym *sym)
diff --git a/arch/arm/include/asm/vermagic.h b/arch/arm/include/asm/vermagic.h
new file mode 100644 (file)
index 0000000..62ce94e
--- /dev/null
@@ -0,0 +1,31 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_VERMAGIC_H
+#define _ASM_VERMAGIC_H
+
+#include <linux/stringify.h>
+
+/*
+ * Add the ARM architecture version to the version magic string
+ */
+#define MODULE_ARCH_VERMAGIC_ARMVSN "ARMv" __stringify(__LINUX_ARM_ARCH__) " "
+
+/* Add __virt_to_phys patching state as well */
+#ifdef CONFIG_ARM_PATCH_PHYS_VIRT
+#define MODULE_ARCH_VERMAGIC_P2V "p2v8 "
+#else
+#define MODULE_ARCH_VERMAGIC_P2V ""
+#endif
+
+/* Add instruction set architecture tag to distinguish ARM/Thumb kernels */
+#ifdef CONFIG_THUMB2_KERNEL
+#define MODULE_ARCH_VERMAGIC_ARMTHUMB "thumb2 "
+#else
+#define MODULE_ARCH_VERMAGIC_ARMTHUMB ""
+#endif
+
+#define MODULE_ARCH_VERMAGIC \
+       MODULE_ARCH_VERMAGIC_ARMVSN \
+       MODULE_ARCH_VERMAGIC_ARMTHUMB \
+       MODULE_ARCH_VERMAGIC_P2V
+
+#endif /* _ASM_VERMAGIC_H */
index 03506ce4614934675e772cce4a74386ead086fae..e7364e6c8c6b0229186c434ef78cba884ddb251b 100644 (file)
@@ -91,8 +91,10 @@ AFLAGS_suspend-imx6.o :=-Wa,-march=armv7-a
 obj-$(CONFIG_SOC_IMX6) += suspend-imx6.o
 obj-$(CONFIG_SOC_IMX53) += suspend-imx53.o
 endif
+ifeq ($(CONFIG_ARM_CPU_SUSPEND),y)
 AFLAGS_resume-imx6.o :=-Wa,-march=armv7-a
 obj-$(CONFIG_SOC_IMX6) += resume-imx6.o
+endif
 obj-$(CONFIG_SOC_IMX6) += pm-imx6.o
 
 obj-$(CONFIG_SOC_IMX1) += mach-imx1.o
index 1e93de68c04418851dd0ab33d5406a9e759b565c..4e7fa2623896b008afb775c2cd4d41f7a72491c5 100644 (file)
@@ -7,8 +7,6 @@
 
 #include <asm-generic/module.h>
 
-#define MODULE_ARCH_VERMAGIC   "aarch64"
-
 #ifdef CONFIG_ARM64_MODULE_PLTS
 struct mod_plt_sec {
        int                     plt_shndx;
index 70c47156e54b1791b268fc768166e574ce01625b..c6b4f0603024332948677b9ec9606d201ac32b28 100644 (file)
@@ -47,7 +47,7 @@ static inline void ptrauth_keys_init_user(struct ptrauth_keys_user *keys)
                get_random_bytes(&keys->apga, sizeof(keys->apga));
 }
 
-#define __ptrauth_key_install(k, v)                            \
+#define __ptrauth_key_install_nosync(k, v)                     \
 do {                                                           \
        struct ptrauth_key __pki_v = (v);                       \
        write_sysreg_s(__pki_v.lo, SYS_ ## k ## KEYLO_EL1);     \
@@ -62,8 +62,11 @@ static __always_inline void ptrauth_keys_init_kernel(struct ptrauth_keys_kernel
 
 static __always_inline void ptrauth_keys_switch_kernel(struct ptrauth_keys_kernel *keys)
 {
-       if (system_supports_address_auth())
-               __ptrauth_key_install(APIA, keys->apia);
+       if (!system_supports_address_auth())
+               return;
+
+       __ptrauth_key_install_nosync(APIA, keys->apia);
+       isb();
 }
 
 extern int ptrauth_prctl_reset_keys(struct task_struct *tsk, unsigned long arg);
diff --git a/arch/arm64/include/asm/vermagic.h b/arch/arm64/include/asm/vermagic.h
new file mode 100644 (file)
index 0000000..a1eec6a
--- /dev/null
@@ -0,0 +1,10 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2012 ARM Ltd.
+ */
+#ifndef _ASM_VERMAGIC_H
+#define _ASM_VERMAGIC_H
+
+#define MODULE_ARCH_VERMAGIC   "aarch64"
+
+#endif /* _ASM_VERMAGIC_H */
diff --git a/arch/h8300/kernel/.gitignore b/arch/h8300/kernel/.gitignore
new file mode 100644 (file)
index 0000000..bbb90f9
--- /dev/null
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0-only
+vmlinux.lds
similarity index 64%
rename from arch/hexagon/include/asm/module.h
rename to arch/hexagon/include/asm/vermagic.h
index e8de4fe035438ed9ed20c6b01588175b6fd75cce..0e8dedc8c486dec4f7cd9255c0e0232960b65dca 100644 (file)
@@ -3,11 +3,11 @@
  * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved.
  */
 
-#ifndef _ASM_MODULE_H
-#define _ASM_MODULE_H
+#ifndef _ASM_VERMAGIC_H
+#define _ASM_VERMAGIC_H
 
-#include <asm-generic/module.h>
+#include <linux/stringify.h>
 
 #define MODULE_ARCH_VERMAGIC __stringify(PROCESSOR_MODEL_NAME) " "
 
-#endif
+#endif /* _ASM_VERMAGIC_H */
index f319144260ce13fcb316e1d0b40715f9a6f427b2..5a29652e6defcb2885591b00c72086cee28d8372 100644 (file)
@@ -26,10 +26,6 @@ struct mod_arch_specific {
        unsigned int next_got_entry;    /* index of next available got entry */
 };
 
-#define MODULE_PROC_FAMILY     "ia64"
-#define MODULE_ARCH_VERMAGIC   MODULE_PROC_FAMILY \
-       "gcc-" __stringify(__GNUC__) "." __stringify(__GNUC_MINOR__)
-
 #define ARCH_SHF_SMALL SHF_IA_64_SHORT
 
 #endif /* _ASM_IA64_MODULE_H */
diff --git a/arch/ia64/include/asm/vermagic.h b/arch/ia64/include/asm/vermagic.h
new file mode 100644 (file)
index 0000000..29c7424
--- /dev/null
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2003 Hewlett-Packard Co
+ *     David Mosberger-Tang <davidm@hpl.hp.com>
+ */
+
+#ifndef _ASM_VERMAGIC_H
+#define _ASM_VERMAGIC_H
+
+#include <linux/stringify.h>
+
+#define MODULE_ARCH_VERMAGIC   "ia64" \
+       "gcc-" __stringify(__GNUC__) "." __stringify(__GNUC_MINOR__)
+
+#endif /* _ASM_VERMAGIC_H */
index 9846047b3d3d31e303d2927e7c2b275ac562a945..724a0882576b3cf1760ff8811be45ae69778b84e 100644 (file)
@@ -83,65 +83,4 @@ search_module_dbetables(unsigned long addr)
 }
 #endif
 
-#ifdef CONFIG_CPU_BMIPS
-#define MODULE_PROC_FAMILY "BMIPS "
-#elif defined CONFIG_CPU_MIPS32_R1
-#define MODULE_PROC_FAMILY "MIPS32_R1 "
-#elif defined CONFIG_CPU_MIPS32_R2
-#define MODULE_PROC_FAMILY "MIPS32_R2 "
-#elif defined CONFIG_CPU_MIPS32_R6
-#define MODULE_PROC_FAMILY "MIPS32_R6 "
-#elif defined CONFIG_CPU_MIPS64_R1
-#define MODULE_PROC_FAMILY "MIPS64_R1 "
-#elif defined CONFIG_CPU_MIPS64_R2
-#define MODULE_PROC_FAMILY "MIPS64_R2 "
-#elif defined CONFIG_CPU_MIPS64_R6
-#define MODULE_PROC_FAMILY "MIPS64_R6 "
-#elif defined CONFIG_CPU_R3000
-#define MODULE_PROC_FAMILY "R3000 "
-#elif defined CONFIG_CPU_TX39XX
-#define MODULE_PROC_FAMILY "TX39XX "
-#elif defined CONFIG_CPU_VR41XX
-#define MODULE_PROC_FAMILY "VR41XX "
-#elif defined CONFIG_CPU_R4X00
-#define MODULE_PROC_FAMILY "R4X00 "
-#elif defined CONFIG_CPU_TX49XX
-#define MODULE_PROC_FAMILY "TX49XX "
-#elif defined CONFIG_CPU_R5000
-#define MODULE_PROC_FAMILY "R5000 "
-#elif defined CONFIG_CPU_R5500
-#define MODULE_PROC_FAMILY "R5500 "
-#elif defined CONFIG_CPU_NEVADA
-#define MODULE_PROC_FAMILY "NEVADA "
-#elif defined CONFIG_CPU_R10000
-#define MODULE_PROC_FAMILY "R10000 "
-#elif defined CONFIG_CPU_RM7000
-#define MODULE_PROC_FAMILY "RM7000 "
-#elif defined CONFIG_CPU_SB1
-#define MODULE_PROC_FAMILY "SB1 "
-#elif defined CONFIG_CPU_LOONGSON32
-#define MODULE_PROC_FAMILY "LOONGSON32 "
-#elif defined CONFIG_CPU_LOONGSON2EF
-#define MODULE_PROC_FAMILY "LOONGSON2EF "
-#elif defined CONFIG_CPU_LOONGSON64
-#define MODULE_PROC_FAMILY "LOONGSON64 "
-#elif defined CONFIG_CPU_CAVIUM_OCTEON
-#define MODULE_PROC_FAMILY "OCTEON "
-#elif defined CONFIG_CPU_XLR
-#define MODULE_PROC_FAMILY "XLR "
-#elif defined CONFIG_CPU_XLP
-#define MODULE_PROC_FAMILY "XLP "
-#else
-#error MODULE_PROC_FAMILY undefined for your processor configuration
-#endif
-
-#ifdef CONFIG_32BIT
-#define MODULE_KERNEL_TYPE "32BIT "
-#elif defined CONFIG_64BIT
-#define MODULE_KERNEL_TYPE "64BIT "
-#endif
-
-#define MODULE_ARCH_VERMAGIC \
-       MODULE_PROC_FAMILY MODULE_KERNEL_TYPE
-
 #endif /* _ASM_MODULE_H */
diff --git a/arch/mips/include/asm/vermagic.h b/arch/mips/include/asm/vermagic.h
new file mode 100644 (file)
index 0000000..24dc3d3
--- /dev/null
@@ -0,0 +1,66 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_VERMAGIC_H
+#define _ASM_VERMAGIC_H
+
+#ifdef CONFIG_CPU_BMIPS
+#define MODULE_PROC_FAMILY "BMIPS "
+#elif defined CONFIG_CPU_MIPS32_R1
+#define MODULE_PROC_FAMILY "MIPS32_R1 "
+#elif defined CONFIG_CPU_MIPS32_R2
+#define MODULE_PROC_FAMILY "MIPS32_R2 "
+#elif defined CONFIG_CPU_MIPS32_R6
+#define MODULE_PROC_FAMILY "MIPS32_R6 "
+#elif defined CONFIG_CPU_MIPS64_R1
+#define MODULE_PROC_FAMILY "MIPS64_R1 "
+#elif defined CONFIG_CPU_MIPS64_R2
+#define MODULE_PROC_FAMILY "MIPS64_R2 "
+#elif defined CONFIG_CPU_MIPS64_R6
+#define MODULE_PROC_FAMILY "MIPS64_R6 "
+#elif defined CONFIG_CPU_R3000
+#define MODULE_PROC_FAMILY "R3000 "
+#elif defined CONFIG_CPU_TX39XX
+#define MODULE_PROC_FAMILY "TX39XX "
+#elif defined CONFIG_CPU_VR41XX
+#define MODULE_PROC_FAMILY "VR41XX "
+#elif defined CONFIG_CPU_R4X00
+#define MODULE_PROC_FAMILY "R4X00 "
+#elif defined CONFIG_CPU_TX49XX
+#define MODULE_PROC_FAMILY "TX49XX "
+#elif defined CONFIG_CPU_R5000
+#define MODULE_PROC_FAMILY "R5000 "
+#elif defined CONFIG_CPU_R5500
+#define MODULE_PROC_FAMILY "R5500 "
+#elif defined CONFIG_CPU_NEVADA
+#define MODULE_PROC_FAMILY "NEVADA "
+#elif defined CONFIG_CPU_R10000
+#define MODULE_PROC_FAMILY "R10000 "
+#elif defined CONFIG_CPU_RM7000
+#define MODULE_PROC_FAMILY "RM7000 "
+#elif defined CONFIG_CPU_SB1
+#define MODULE_PROC_FAMILY "SB1 "
+#elif defined CONFIG_CPU_LOONGSON32
+#define MODULE_PROC_FAMILY "LOONGSON32 "
+#elif defined CONFIG_CPU_LOONGSON2EF
+#define MODULE_PROC_FAMILY "LOONGSON2EF "
+#elif defined CONFIG_CPU_LOONGSON64
+#define MODULE_PROC_FAMILY "LOONGSON64 "
+#elif defined CONFIG_CPU_CAVIUM_OCTEON
+#define MODULE_PROC_FAMILY "OCTEON "
+#elif defined CONFIG_CPU_XLR
+#define MODULE_PROC_FAMILY "XLR "
+#elif defined CONFIG_CPU_XLP
+#define MODULE_PROC_FAMILY "XLP "
+#else
+#error MODULE_PROC_FAMILY undefined for your processor configuration
+#endif
+
+#ifdef CONFIG_32BIT
+#define MODULE_KERNEL_TYPE "32BIT "
+#elif defined CONFIG_64BIT
+#define MODULE_KERNEL_TYPE "64BIT "
+#endif
+
+#define MODULE_ARCH_VERMAGIC \
+       MODULE_PROC_FAMILY MODULE_KERNEL_TYPE
+
+#endif /* _ASM_VERMAGIC_H */
similarity index 52%
rename from arch/nds32/include/asm/module.h
rename to arch/nds32/include/asm/vermagic.h
index a3a08e993c65924cb3537bb3848701a15e4b33b7..f772e7ba33f1fa71674c9c5584ed532843f9f8a9 100644 (file)
@@ -1,11 +1,9 @@
 /* SPDX-License-Identifier: GPL-2.0 */
 // Copyright (C) 2005-2017 Andes Technology Corporation
 
-#ifndef _ASM_NDS32_MODULE_H
-#define _ASM_NDS32_MODULE_H
-
-#include <asm-generic/module.h>
+#ifndef _ASM_VERMAGIC_H
+#define _ASM_VERMAGIC_H
 
 #define MODULE_ARCH_VERMAGIC   "NDS32v3"
 
-#endif /* _ASM_NDS32_MODULE_H */
+#endif /* _ASM_VERMAGIC_H */
index 356658711a864e0587aead0ebd7c5f9e030cda02..5398bfc465b4859e2641569272daa72b758a74ed 100644 (file)
@@ -3,28 +3,10 @@
 #define _ASM_POWERPC_MODULE_H
 #ifdef __KERNEL__
 
-/*
- */
-
 #include <linux/list.h>
 #include <asm/bug.h>
 #include <asm-generic/module.h>
 
-
-#ifdef CONFIG_MPROFILE_KERNEL
-#define MODULE_ARCH_VERMAGIC_FTRACE    "mprofile-kernel "
-#else
-#define MODULE_ARCH_VERMAGIC_FTRACE    ""
-#endif
-
-#ifdef CONFIG_RELOCATABLE
-#define MODULE_ARCH_VERMAGIC_RELOCATABLE       "relocatable "
-#else
-#define MODULE_ARCH_VERMAGIC_RELOCATABLE       ""
-#endif
-
-#define MODULE_ARCH_VERMAGIC MODULE_ARCH_VERMAGIC_FTRACE MODULE_ARCH_VERMAGIC_RELOCATABLE
-
 #ifndef __powerpc64__
 /*
  * Thanks to Paul M for explaining this.
diff --git a/arch/powerpc/include/asm/vermagic.h b/arch/powerpc/include/asm/vermagic.h
new file mode 100644 (file)
index 0000000..b054a85
--- /dev/null
@@ -0,0 +1,20 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_VERMAGIC_H
+#define _ASM_VERMAGIC_H
+
+#ifdef CONFIG_MPROFILE_KERNEL
+#define MODULE_ARCH_VERMAGIC_FTRACE    "mprofile-kernel "
+#else
+#define MODULE_ARCH_VERMAGIC_FTRACE    ""
+#endif
+
+#ifdef CONFIG_RELOCATABLE
+#define MODULE_ARCH_VERMAGIC_RELOCATABLE       "relocatable "
+#else
+#define MODULE_ARCH_VERMAGIC_RELOCATABLE       ""
+#endif
+
+#define MODULE_ARCH_VERMAGIC \
+               MODULE_ARCH_VERMAGIC_FTRACE MODULE_ARCH_VERMAGIC_RELOCATABLE
+
+#endif /* _ASM_VERMAGIC_H */
index a6371fb8f7612caec0111171bbf23d90b7efee39..8420abd4ea1ce8bf7400bf3b68389bc85ff562ea 100644 (file)
@@ -732,7 +732,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_SPE)
        stw     r10,_CCR(r1)
        stw     r1,KSP(r3)      /* Set old stack pointer */
 
-       kuap_check r2, r4
+       kuap_check r2, r0
 #ifdef CONFIG_SMP
        /* We need a sync somewhere here to make sure that if the
         * previous task gets rescheduled on another CPU, it sees all
index 438a9befce4159e53f27de6c136d7ccdd3533dba..8105010b0e76fb179f7939a5d41ce534f4b9c87d 100644 (file)
@@ -534,6 +534,8 @@ static bool __init parse_cache_info(struct device_node *np,
        lsizep = of_get_property(np, propnames[3], NULL);
        if (bsizep == NULL)
                bsizep = lsizep;
+       if (lsizep == NULL)
+               lsizep = bsizep;
        if (lsizep != NULL)
                lsize = be32_to_cpu(*lsizep);
        if (bsizep != NULL)
index 6404df613ea36a0783609b45df72fde12cf9c7ed..2b35f9bcf8928f8404d4b9781bcbb2d6c2503b62 100644 (file)
@@ -604,18 +604,19 @@ int kvmppc_book3s_hv_page_fault(struct kvm_run *run, struct kvm_vcpu *vcpu,
         */
        local_irq_disable();
        ptep = __find_linux_pte(vcpu->arch.pgdir, hva, NULL, &shift);
+       pte = __pte(0);
+       if (ptep)
+               pte = *ptep;
+       local_irq_enable();
        /*
         * If the PTE disappeared temporarily due to a THP
         * collapse, just return and let the guest try again.
         */
-       if (!ptep) {
-               local_irq_enable();
+       if (!pte_present(pte)) {
                if (page)
                        put_page(page);
                return RESUME_GUEST;
        }
-       pte = *ptep;
-       local_irq_enable();
        hpa = pte_pfn(pte) << PAGE_SHIFT;
        pte_size = PAGE_SIZE;
        if (shift)
index 9f050064d2a2d7523ff0d89222d7bc6e8f3f2bc3..aa12cd4078b3205e85d4cdf2d8746229377bd937 100644 (file)
@@ -815,18 +815,19 @@ int kvmppc_book3s_instantiate_page(struct kvm_vcpu *vcpu,
         */
        local_irq_disable();
        ptep = __find_linux_pte(vcpu->arch.pgdir, hva, NULL, &shift);
+       pte = __pte(0);
+       if (ptep)
+               pte = *ptep;
+       local_irq_enable();
        /*
         * If the PTE disappeared temporarily due to a THP
         * collapse, just return and let the guest try again.
         */
-       if (!ptep) {
-               local_irq_enable();
+       if (!pte_present(pte)) {
                if (page)
                        put_page(page);
                return RESUME_GUEST;
        }
-       pte = *ptep;
-       local_irq_enable();
 
        /* If we're logging dirty pages, always map single pages */
        large_enable = !(memslot->flags & KVM_MEM_LOG_DIRTY_PAGES);
index 3189308dece4c9a09b5f32d332a307945679ce62..d83a12c5bc7f4343d154f60dabb73c8cfa519442 100644 (file)
@@ -185,6 +185,7 @@ void mmu_mark_initmem_nx(void)
                        mmu_mapin_ram_chunk(etext8, einittext8, PAGE_KERNEL);
                }
        }
+       _tlbil_all();
 }
 
 #ifdef CONFIG_STRICT_KERNEL_RWX
@@ -199,6 +200,8 @@ void mmu_mark_rodata_ro(void)
                                      ~(LARGE_PAGE_SIZE_8M - 1)));
        mmu_patch_addis(&patch__dtlbmiss_romem_top, -__pa(_sinittext));
 
+       _tlbil_all();
+
        /* Update page tables for PTDUMP and BDI */
        mmu_mapin_ram_chunk(0, sinittext, __pgprot(0));
        mmu_mapin_ram_chunk(0, etext, PAGE_KERNEL_ROX);
index 0c3c1902135c4f430e076e50213e6eefc9552521..27a81c291be8403e3b3c8f851e168fb9b96a648e 100644 (file)
@@ -397,7 +397,7 @@ config PPC_KUAP
 
 config PPC_KUAP_DEBUG
        bool "Extra debugging for Kernel Userspace Access Protection"
-       depends on PPC_KUAP && (PPC_RADIX_MMU || PPC_32)
+       depends on PPC_KUAP && (PPC_RADIX_MMU || PPC32)
        help
          Add extra debugging for Kernel Userspace Access Protection (KUAP)
          If you're unsure, say N.
index 46202dad365d0631175998eec030194354cd4d57..76aa96a9fc08165783566100155776862b780ad9 100644 (file)
@@ -6,8 +6,6 @@
 
 #include <asm-generic/module.h>
 
-#define MODULE_ARCH_VERMAGIC    "riscv"
-
 struct module;
 unsigned long module_emit_got_entry(struct module *mod, unsigned long val);
 unsigned long module_emit_plt_entry(struct module *mod, unsigned long val);
diff --git a/arch/riscv/include/asm/vermagic.h b/arch/riscv/include/asm/vermagic.h
new file mode 100644 (file)
index 0000000..7b9441a
--- /dev/null
@@ -0,0 +1,9 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright (C) 2017 Andes Technology Corporation */
+
+#ifndef _ASM_VERMAGIC_H
+#define _ASM_VERMAGIC_H
+
+#define MODULE_ARCH_VERMAGIC    "riscv"
+
+#endif /* _ASM_VERMAGIC_H */
index 8fde561f1d07e3e905446c8f9b25d38f79f0b7b8..f887a479cdc7ec13b8058481011ad3a7b7781fdb 100644 (file)
@@ -7,9 +7,7 @@
 #ifdef CONFIG_PROTECTED_VIRTUALIZATION_GUEST
 int __bootdata_preserved(prot_virt_guest);
 #endif
-#if IS_ENABLED(CONFIG_KVM)
 struct uv_info __bootdata_preserved(uv_info);
-#endif
 
 void uv_query_info(void)
 {
index 61f2b0412345afc7c42e22361fa41e0054cbf24b..ccba63aaeb470ba64c073dd6f0d71ff8d3b4a784 100644 (file)
@@ -133,7 +133,7 @@ void diag_stat_inc(enum diag_stat_enum nr)
 }
 EXPORT_SYMBOL(diag_stat_inc);
 
-void diag_stat_inc_norecursion(enum diag_stat_enum nr)
+void notrace diag_stat_inc_norecursion(enum diag_stat_enum nr)
 {
        this_cpu_inc(diag_stat.counter[nr]);
        trace_s390_diagnose_norecursion(diag_map[nr].code);
index 7eaabbab22134aa4be336e8461997569b90e84c9..10dbb12eb14d2677b964037d0e99fe1ccfd3ecd1 100644 (file)
@@ -403,7 +403,7 @@ int smp_find_processor_id(u16 address)
        return -1;
 }
 
-bool arch_vcpu_is_preempted(int cpu)
+bool notrace arch_vcpu_is_preempted(int cpu)
 {
        if (test_cpu_flag_of(CIF_ENABLED_WAIT, cpu))
                return false;
@@ -413,7 +413,7 @@ bool arch_vcpu_is_preempted(int cpu)
 }
 EXPORT_SYMBOL(arch_vcpu_is_preempted);
 
-void smp_yield_cpu(int cpu)
+void notrace smp_yield_cpu(int cpu)
 {
        if (!MACHINE_HAS_DIAG9C)
                return;
index 490b52e85014538937d0c67e73a8bf6bf11c7cf9..11a669f3cc93c17d5f69f281296e04c2a39cc2bb 100644 (file)
@@ -14,7 +14,7 @@ EXPORT_TRACEPOINT_SYMBOL(s390_diagnose);
 
 static DEFINE_PER_CPU(unsigned int, diagnose_trace_depth);
 
-void trace_s390_diagnose_norecursion(int diag_nr)
+void notrace trace_s390_diagnose_norecursion(int diag_nr)
 {
        unsigned long flags;
        unsigned int *depth;
index c86d654351d1615f18f62caf4a501e5322513e8a..4c0677fc8904ba6a2925a4d0f983c3aea1afa6d0 100644 (file)
 int __bootdata_preserved(prot_virt_guest);
 #endif
 
+struct uv_info __bootdata_preserved(uv_info);
+
 #if IS_ENABLED(CONFIG_KVM)
 int prot_virt_host;
 EXPORT_SYMBOL(prot_virt_host);
-struct uv_info __bootdata_preserved(uv_info);
 EXPORT_SYMBOL(uv_info);
 
 static int __init prot_virt_setup(char *val)
index 8191106bf7b92dcf99caec72516b18b8c9212691..bfb4811349944d5662138b3f7f4889505ed85899 100644 (file)
@@ -393,7 +393,7 @@ static unsigned long deliverable_irqs(struct kvm_vcpu *vcpu)
        if (psw_mchk_disabled(vcpu))
                active_mask &= ~IRQ_PEND_MCHK_MASK;
        /* PV guest cpus can have a single interruption injected at a time. */
-       if (kvm_s390_pv_cpu_is_protected(vcpu) &&
+       if (kvm_s390_pv_cpu_get_handle(vcpu) &&
            vcpu->arch.sie_block->iictl != IICTL_CODE_NONE)
                active_mask &= ~(IRQ_PEND_EXT_II_MASK |
                                 IRQ_PEND_IO_MASK |
index 19a81024fe16b0cedf8d78a4d7d6410cedff5ba7..5dcf9ff1282868bb9bb945a4d0f99117ad2c7fdb 100644 (file)
@@ -1939,6 +1939,9 @@ static int gfn_to_memslot_approx(struct kvm_memslots *slots, gfn_t gfn)
                        start = slot + 1;
        }
 
+       if (start >= slots->used_slots)
+               return slots->used_slots - 1;
+
        if (gfn >= memslots[start].base_gfn &&
            gfn < memslots[start].base_gfn + memslots[start].npages) {
                atomic_set(&slots->lru_slot, start);
index c4f8039a35e8dda0bc20999b7db089e3ab09b613..0267405ab7c69fec93f73df3ed35f381b03c7f38 100644 (file)
@@ -64,10 +64,13 @@ mm_segment_t enable_sacf_uaccess(void)
 {
        mm_segment_t old_fs;
        unsigned long asce, cr;
+       unsigned long flags;
 
        old_fs = current->thread.mm_segment;
        if (old_fs & 1)
                return old_fs;
+       /* protect against a concurrent page table upgrade */
+       local_irq_save(flags);
        current->thread.mm_segment |= 1;
        asce = S390_lowcore.kernel_asce;
        if (likely(old_fs == USER_DS)) {
@@ -83,6 +86,7 @@ mm_segment_t enable_sacf_uaccess(void)
                __ctl_load(asce, 7, 7);
                set_cpu_flag(CIF_ASCE_SECONDARY);
        }
+       local_irq_restore(flags);
        return old_fs;
 }
 EXPORT_SYMBOL(enable_sacf_uaccess);
index 498c98a312f44c0318d3a0ee051b0a65fd5078f6..fff169d6471188cd8f58669316848e34969d12cd 100644 (file)
@@ -70,8 +70,20 @@ static void __crst_table_upgrade(void *arg)
 {
        struct mm_struct *mm = arg;
 
-       if (current->active_mm == mm)
-               set_user_asce(mm);
+       /* we must change all active ASCEs to avoid the creation of new TLBs */
+       if (current->active_mm == mm) {
+               S390_lowcore.user_asce = mm->context.asce;
+               if (current->thread.mm_segment == USER_DS) {
+                       __ctl_load(S390_lowcore.user_asce, 1, 1);
+                       /* Mark user-ASCE present in CR1 */
+                       clear_cpu_flag(CIF_ASCE_PRIMARY);
+               }
+               if (current->thread.mm_segment == USER_DS_SACF) {
+                       __ctl_load(S390_lowcore.user_asce, 7, 7);
+                       /* enable_sacf_uaccess does all or nothing */
+                       WARN_ON(!test_cpu_flag(CIF_ASCE_SECONDARY));
+               }
+       }
        __tlb_flush_local();
 }
 
index fbe97ab2e22869a2e80c94ad6729363ba3d217ec..743f257cf2cbdd0cfa0aed3a935edded9ce0d513 100644 (file)
@@ -115,7 +115,6 @@ static struct irq_chip zpci_irq_chip = {
        .name = "PCI-MSI",
        .irq_unmask = pci_msi_unmask_irq,
        .irq_mask = pci_msi_mask_irq,
-       .irq_set_affinity = zpci_set_irq_affinity,
 };
 
 static void zpci_handle_cpu_local_irq(bool rescan)
@@ -276,7 +275,9 @@ int arch_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
                rc = -EIO;
                if (hwirq - bit >= msi_vecs)
                        break;
-               irq = __irq_alloc_descs(-1, 0, 1, 0, THIS_MODULE, msi->affinity);
+               irq = __irq_alloc_descs(-1, 0, 1, 0, THIS_MODULE,
+                               (irq_delivery == DIRECTED) ?
+                               msi->affinity : NULL);
                if (irq < 0)
                        return -ENOMEM;
                rc = irq_set_msi_desc(irq, msi);
index 9f38fb35fe96cae9672fb2bf0e579431403722c2..337663a028dbc01a100de90909496108d94dd0f2 100644 (file)
@@ -11,32 +11,4 @@ struct mod_arch_specific {
 };
 #endif
 
-#ifdef CONFIG_CPU_LITTLE_ENDIAN
-# ifdef CONFIG_CPU_SH2
-#  define MODULE_PROC_FAMILY "SH2LE "
-# elif defined  CONFIG_CPU_SH3
-#  define MODULE_PROC_FAMILY "SH3LE "
-# elif defined  CONFIG_CPU_SH4
-#  define MODULE_PROC_FAMILY "SH4LE "
-# elif defined  CONFIG_CPU_SH5
-#  define MODULE_PROC_FAMILY "SH5LE "
-# else
-#  error unknown processor family
-# endif
-#else
-# ifdef CONFIG_CPU_SH2
-#  define MODULE_PROC_FAMILY "SH2BE "
-# elif defined  CONFIG_CPU_SH3
-#  define MODULE_PROC_FAMILY "SH3BE "
-# elif defined  CONFIG_CPU_SH4
-#  define MODULE_PROC_FAMILY "SH4BE "
-# elif defined  CONFIG_CPU_SH5
-#  define MODULE_PROC_FAMILY "SH5BE "
-# else
-#  error unknown processor family
-# endif
-#endif
-
-#define MODULE_ARCH_VERMAGIC MODULE_PROC_FAMILY
-
 #endif /* _ASM_SH_MODULE_H */
diff --git a/arch/sh/include/asm/vermagic.h b/arch/sh/include/asm/vermagic.h
new file mode 100644 (file)
index 0000000..13d8eaa
--- /dev/null
@@ -0,0 +1,34 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#ifndef _ASM_VERMAGIC_H
+#define _ASM_VERMAGIC_H
+
+#ifdef CONFIG_CPU_LITTLE_ENDIAN
+# ifdef CONFIG_CPU_SH2
+#  define MODULE_PROC_FAMILY "SH2LE "
+# elif defined  CONFIG_CPU_SH3
+#  define MODULE_PROC_FAMILY "SH3LE "
+# elif defined  CONFIG_CPU_SH4
+#  define MODULE_PROC_FAMILY "SH4LE "
+# elif defined  CONFIG_CPU_SH5
+#  define MODULE_PROC_FAMILY "SH5LE "
+# else
+#  error unknown processor family
+# endif
+#else
+# ifdef CONFIG_CPU_SH2
+#  define MODULE_PROC_FAMILY "SH2BE "
+# elif defined  CONFIG_CPU_SH3
+#  define MODULE_PROC_FAMILY "SH3BE "
+# elif defined  CONFIG_CPU_SH4
+#  define MODULE_PROC_FAMILY "SH4BE "
+# elif defined  CONFIG_CPU_SH5
+#  define MODULE_PROC_FAMILY "SH5BE "
+# else
+#  error unknown processor family
+# endif
+#endif
+
+#define MODULE_ARCH_VERMAGIC MODULE_PROC_FAMILY
+
+#endif /* _ASM_VERMAGIC_H */
index b9de2d4fa57e347a172c17c40435c9c5417f8333..8d2a68aea1fcbff018d074062868ea2d9fbff3f6 100644 (file)
@@ -412,7 +412,7 @@ int arch_add_memory(int nid, u64 start, u64 size,
        unsigned long nr_pages = size >> PAGE_SHIFT;
        int ret;
 
-       if (WARN_ON_ONCE(params->pgprot.pgprot != PAGE_KERNEL.pgprot)
+       if (WARN_ON_ONCE(params->pgprot.pgprot != PAGE_KERNEL.pgprot))
                return -EINVAL;
 
        /* We only have ZONE_NORMAL, so this is easy.. */
index d2daa206872da406408a2685f6659c312b9aa18b..275f5ffdf6f0ada4e1f5499d77bda066a99b1f83 100644 (file)
@@ -140,6 +140,7 @@ export CFLAGS_vmlinux := $(LINK-y) $(LINK_WRAPS) $(LD_FLAGS_CMDLINE)
 # When cleaning we don't include .config, so we don't include
 # TT or skas makefiles and don't clean skas_ptregs.h.
 CLEAN_FILES += linux x.i gmon.out
+MRPROPER_DIRS += arch/$(SUBARCH)/include/generated
 
 archclean:
        @find . \( -name '*.bb' -o -name '*.bbg' -o -name '*.da' \
index 1d6104ea8af0309d437766a72657989f88b2d4d9..1197b5596d5ad8959d242bd5f1666690e368de7d 100644 (file)
@@ -149,7 +149,7 @@ config X86
        select HAVE_ARCH_TRACEHOOK
        select HAVE_ARCH_TRANSPARENT_HUGEPAGE
        select HAVE_ARCH_TRANSPARENT_HUGEPAGE_PUD if X86_64
-       select HAVE_ARCH_USERFAULTFD_WP         if USERFAULTFD
+       select HAVE_ARCH_USERFAULTFD_WP         if X86_64 && USERFAULTFD
        select HAVE_ARCH_VMAP_STACK             if X86_64
        select HAVE_ARCH_WITHIN_STACK_FRAMES
        select HAVE_ASM_MODVERSIONS
index e4aa20c0426fcc31a87b8486ad5a2dfa8182dabb..442e1ed4acd49d62235dc1e42a2604ac669693dd 100644 (file)
@@ -643,6 +643,7 @@ static const struct x86_cpu_id intel_cstates_match[] __initconst = {
        X86_MATCH_INTEL_FAM6_MODEL(ATOM_GOLDMONT_PLUS,  &glm_cstates),
        X86_MATCH_INTEL_FAM6_MODEL(ATOM_TREMONT_D,      &glm_cstates),
        X86_MATCH_INTEL_FAM6_MODEL(ATOM_TREMONT,        &glm_cstates),
+       X86_MATCH_INTEL_FAM6_MODEL(ATOM_TREMONT_L,      &glm_cstates),
 
        X86_MATCH_INTEL_FAM6_MODEL(ICELAKE_L,           &icl_cstates),
        X86_MATCH_INTEL_FAM6_MODEL(ICELAKE,             &icl_cstates),
index 624f5d9b0f79f9c37e2b6e9fad21a6ee31ea7e3f..fd51bac11b467d83e02d6156c310359ff70ac19e 100644 (file)
@@ -73,7 +73,8 @@ static int hv_cpu_init(unsigned int cpu)
        struct page *pg;
 
        input_arg = (void **)this_cpu_ptr(hyperv_pcpu_input_arg);
-       pg = alloc_page(GFP_KERNEL);
+       /* hv_cpu_init() can be called with IRQs disabled from hv_resume() */
+       pg = alloc_page(irqs_disabled() ? GFP_ATOMIC : GFP_KERNEL);
        if (unlikely(!pg))
                return -ENOMEM;
        *input_arg = page_address(pg);
@@ -254,6 +255,7 @@ static int __init hv_pci_init(void)
 static int hv_suspend(void)
 {
        union hv_x64_msr_hypercall_contents hypercall_msr;
+       int ret;
 
        /*
         * Reset the hypercall page as it is going to be invalidated
@@ -270,12 +272,17 @@ static int hv_suspend(void)
        hypercall_msr.enable = 0;
        wrmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64);
 
-       return 0;
+       ret = hv_cpu_die(0);
+       return ret;
 }
 
 static void hv_resume(void)
 {
        union hv_x64_msr_hypercall_contents hypercall_msr;
+       int ret;
+
+       ret = hv_cpu_init(0);
+       WARN_ON(ret);
 
        /* Re-enable the hypercall page */
        rdmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64);
@@ -288,6 +295,7 @@ static void hv_resume(void)
        hv_hypercall_pg_saved = NULL;
 }
 
+/* Note: when the ops are called, only CPU0 is online and IRQs are disabled. */
 static struct syscore_ops hv_syscore_ops = {
        .suspend        = hv_suspend,
        .resume         = hv_resume,
index c215d276248844e0608ba0c880f1ddb15e7ba839..e988bac0a4a1c316fffac9525b2a094cde9b2a51 100644 (file)
@@ -13,64 +13,4 @@ struct mod_arch_specific {
 #endif
 };
 
-#ifdef CONFIG_X86_64
-/* X86_64 does not define MODULE_PROC_FAMILY */
-#elif defined CONFIG_M486SX
-#define MODULE_PROC_FAMILY "486SX "
-#elif defined CONFIG_M486
-#define MODULE_PROC_FAMILY "486 "
-#elif defined CONFIG_M586
-#define MODULE_PROC_FAMILY "586 "
-#elif defined CONFIG_M586TSC
-#define MODULE_PROC_FAMILY "586TSC "
-#elif defined CONFIG_M586MMX
-#define MODULE_PROC_FAMILY "586MMX "
-#elif defined CONFIG_MCORE2
-#define MODULE_PROC_FAMILY "CORE2 "
-#elif defined CONFIG_MATOM
-#define MODULE_PROC_FAMILY "ATOM "
-#elif defined CONFIG_M686
-#define MODULE_PROC_FAMILY "686 "
-#elif defined CONFIG_MPENTIUMII
-#define MODULE_PROC_FAMILY "PENTIUMII "
-#elif defined CONFIG_MPENTIUMIII
-#define MODULE_PROC_FAMILY "PENTIUMIII "
-#elif defined CONFIG_MPENTIUMM
-#define MODULE_PROC_FAMILY "PENTIUMM "
-#elif defined CONFIG_MPENTIUM4
-#define MODULE_PROC_FAMILY "PENTIUM4 "
-#elif defined CONFIG_MK6
-#define MODULE_PROC_FAMILY "K6 "
-#elif defined CONFIG_MK7
-#define MODULE_PROC_FAMILY "K7 "
-#elif defined CONFIG_MK8
-#define MODULE_PROC_FAMILY "K8 "
-#elif defined CONFIG_MELAN
-#define MODULE_PROC_FAMILY "ELAN "
-#elif defined CONFIG_MCRUSOE
-#define MODULE_PROC_FAMILY "CRUSOE "
-#elif defined CONFIG_MEFFICEON
-#define MODULE_PROC_FAMILY "EFFICEON "
-#elif defined CONFIG_MWINCHIPC6
-#define MODULE_PROC_FAMILY "WINCHIPC6 "
-#elif defined CONFIG_MWINCHIP3D
-#define MODULE_PROC_FAMILY "WINCHIP3D "
-#elif defined CONFIG_MCYRIXIII
-#define MODULE_PROC_FAMILY "CYRIXIII "
-#elif defined CONFIG_MVIAC3_2
-#define MODULE_PROC_FAMILY "VIAC3-2 "
-#elif defined CONFIG_MVIAC7
-#define MODULE_PROC_FAMILY "VIAC7 "
-#elif defined CONFIG_MGEODEGX1
-#define MODULE_PROC_FAMILY "GEODEGX1 "
-#elif defined CONFIG_MGEODE_LX
-#define MODULE_PROC_FAMILY "GEODE "
-#else
-#error unknown processor family
-#endif
-
-#ifdef CONFIG_X86_32
-# define MODULE_ARCH_VERMAGIC MODULE_PROC_FAMILY
-#endif
-
 #endif /* _ASM_X86_MODULE_H */
index 1c42ecbe75cb4d2b430f12e4dfa6a95c7128739f..d30805ed323ef9d682fec37bdd9fc5a8e2f30cf6 100644 (file)
@@ -35,6 +35,8 @@ typedef int (*hyperv_fill_flush_list_func)(
        rdmsrl(HV_X64_MSR_SINT0 + int_num, val)
 #define hv_set_synint_state(int_num, val) \
        wrmsrl(HV_X64_MSR_SINT0 + int_num, val)
+#define hv_recommend_using_aeoi() \
+       (!(ms_hyperv.hints & HV_DEPRECATING_AEOI_RECOMMENDED))
 
 #define hv_get_crash_ctl(val) \
        rdmsrl(HV_X64_MSR_CRASH_CTL, val)
index 07e95dcb40ad5463b6e642c386e45cb6c5090cbe..7e9a281e266049b06668ec6f659f37f03f1052e9 100644 (file)
@@ -237,27 +237,6 @@ enum ssb_mitigation {
 extern char __indirect_thunk_start[];
 extern char __indirect_thunk_end[];
 
-/*
- * On VMEXIT we must ensure that no RSB predictions learned in the guest
- * can be followed in the host, by overwriting the RSB completely. Both
- * retpoline and IBRS mitigations for Spectre v2 need this; only on future
- * CPUs with IBRS_ALL *might* it be avoided.
- */
-static inline void vmexit_fill_RSB(void)
-{
-#ifdef CONFIG_RETPOLINE
-       unsigned long loops;
-
-       asm volatile (ANNOTATE_NOSPEC_ALTERNATIVE
-                     ALTERNATIVE("jmp 910f",
-                                 __stringify(__FILL_RETURN_BUFFER(%0, RSB_CLEAR_LOOPS, %1)),
-                                 X86_FEATURE_RETPOLINE)
-                     "910:"
-                     : "=r" (loops), ASM_CALL_CONSTRAINT
-                     : : "memory" );
-#endif
-}
-
 static __always_inline
 void alternative_msr_write(unsigned int msr, u64 val, unsigned int feature)
 {
diff --git a/arch/x86/include/asm/vermagic.h b/arch/x86/include/asm/vermagic.h
new file mode 100644 (file)
index 0000000..75884d2
--- /dev/null
@@ -0,0 +1,68 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#ifndef _ASM_VERMAGIC_H
+#define _ASM_VERMAGIC_H
+
+#ifdef CONFIG_X86_64
+/* X86_64 does not define MODULE_PROC_FAMILY */
+#elif defined CONFIG_M486SX
+#define MODULE_PROC_FAMILY "486SX "
+#elif defined CONFIG_M486
+#define MODULE_PROC_FAMILY "486 "
+#elif defined CONFIG_M586
+#define MODULE_PROC_FAMILY "586 "
+#elif defined CONFIG_M586TSC
+#define MODULE_PROC_FAMILY "586TSC "
+#elif defined CONFIG_M586MMX
+#define MODULE_PROC_FAMILY "586MMX "
+#elif defined CONFIG_MCORE2
+#define MODULE_PROC_FAMILY "CORE2 "
+#elif defined CONFIG_MATOM
+#define MODULE_PROC_FAMILY "ATOM "
+#elif defined CONFIG_M686
+#define MODULE_PROC_FAMILY "686 "
+#elif defined CONFIG_MPENTIUMII
+#define MODULE_PROC_FAMILY "PENTIUMII "
+#elif defined CONFIG_MPENTIUMIII
+#define MODULE_PROC_FAMILY "PENTIUMIII "
+#elif defined CONFIG_MPENTIUMM
+#define MODULE_PROC_FAMILY "PENTIUMM "
+#elif defined CONFIG_MPENTIUM4
+#define MODULE_PROC_FAMILY "PENTIUM4 "
+#elif defined CONFIG_MK6
+#define MODULE_PROC_FAMILY "K6 "
+#elif defined CONFIG_MK7
+#define MODULE_PROC_FAMILY "K7 "
+#elif defined CONFIG_MK8
+#define MODULE_PROC_FAMILY "K8 "
+#elif defined CONFIG_MELAN
+#define MODULE_PROC_FAMILY "ELAN "
+#elif defined CONFIG_MCRUSOE
+#define MODULE_PROC_FAMILY "CRUSOE "
+#elif defined CONFIG_MEFFICEON
+#define MODULE_PROC_FAMILY "EFFICEON "
+#elif defined CONFIG_MWINCHIPC6
+#define MODULE_PROC_FAMILY "WINCHIPC6 "
+#elif defined CONFIG_MWINCHIP3D
+#define MODULE_PROC_FAMILY "WINCHIP3D "
+#elif defined CONFIG_MCYRIXIII
+#define MODULE_PROC_FAMILY "CYRIXIII "
+#elif defined CONFIG_MVIAC3_2
+#define MODULE_PROC_FAMILY "VIAC3-2 "
+#elif defined CONFIG_MVIAC7
+#define MODULE_PROC_FAMILY "VIAC7 "
+#elif defined CONFIG_MGEODEGX1
+#define MODULE_PROC_FAMILY "GEODEGX1 "
+#elif defined CONFIG_MGEODE_LX
+#define MODULE_PROC_FAMILY "GEODE "
+#else
+#error unknown processor family
+#endif
+
+#ifdef CONFIG_X86_32
+# define MODULE_ARCH_VERMAGIC MODULE_PROC_FAMILY
+#else
+# define MODULE_ARCH_VERMAGIC ""
+#endif
+
+#endif /* _ASM_VERMAGIC_H */
index fe3ab9632f3bc3d23df2261098bda1b1fdb780c0..8c89e4d9ad28da008a4bb5c5d8abb95993edd4b2 100644 (file)
@@ -147,7 +147,7 @@ static inline void smpboot_restore_warm_reset_vector(void)
        *((volatile u32 *)phys_to_virt(TRAMPOLINE_PHYS_LOW)) = 0;
 }
 
-static void init_freq_invariance(void);
+static void init_freq_invariance(bool secondary);
 
 /*
  * Report back to the Boot Processor during boot time or to the caller processor
@@ -185,7 +185,7 @@ static void smp_callin(void)
         */
        set_cpu_sibling_map(raw_smp_processor_id());
 
-       init_freq_invariance();
+       init_freq_invariance(true);
 
        /*
         * Get our bogomips.
@@ -1341,7 +1341,7 @@ void __init native_smp_prepare_cpus(unsigned int max_cpus)
        set_sched_topology(x86_topology);
 
        set_cpu_sibling_map(0);
-       init_freq_invariance();
+       init_freq_invariance(false);
        smp_sanity_check();
 
        switch (apic_intr_mode) {
@@ -1877,9 +1877,6 @@ static bool knl_set_max_freq_ratio(u64 *base_freq, u64 *turbo_freq,
        int err, i;
        u64 msr;
 
-       if (!x86_match_cpu(has_knl_turbo_ratio_limits))
-               return false;
-
        err = rdmsrl_safe(MSR_PLATFORM_INFO, base_freq);
        if (err)
                return false;
@@ -1945,18 +1942,23 @@ static bool skx_set_max_freq_ratio(u64 *base_freq, u64 *turbo_freq, int size)
 
 static bool core_set_max_freq_ratio(u64 *base_freq, u64 *turbo_freq)
 {
+       u64 msr;
        int err;
 
        err = rdmsrl_safe(MSR_PLATFORM_INFO, base_freq);
        if (err)
                return false;
 
-       err = rdmsrl_safe(MSR_TURBO_RATIO_LIMIT, turbo_freq);
+       err = rdmsrl_safe(MSR_TURBO_RATIO_LIMIT, &msr);
        if (err)
                return false;
 
-       *base_freq = (*base_freq >> 8) & 0xFF;      /* max P state */
-       *turbo_freq = (*turbo_freq >> 24) & 0xFF;   /* 4C turbo    */
+       *base_freq = (*base_freq >> 8) & 0xFF;    /* max P state */
+       *turbo_freq = (msr >> 24) & 0xFF;         /* 4C turbo    */
+
+       /* The CPU may have less than 4 cores */
+       if (!*turbo_freq)
+               *turbo_freq = msr & 0xFF;         /* 1C turbo    */
 
        return true;
 }
@@ -1972,7 +1974,8 @@ static bool intel_set_max_freq_ratio(void)
            skx_set_max_freq_ratio(&base_freq, &turbo_freq, 1))
                goto out;
 
-       if (knl_set_max_freq_ratio(&base_freq, &turbo_freq, 1))
+       if (x86_match_cpu(has_knl_turbo_ratio_limits) &&
+           knl_set_max_freq_ratio(&base_freq, &turbo_freq, 1))
                goto out;
 
        if (x86_match_cpu(has_skx_turbo_ratio_limits) &&
@@ -1985,13 +1988,22 @@ static bool intel_set_max_freq_ratio(void)
        return false;
 
 out:
+       /*
+        * Some hypervisors advertise X86_FEATURE_APERFMPERF
+        * but then fill all MSR's with zeroes.
+        */
+       if (!base_freq) {
+               pr_debug("Couldn't determine cpu base frequency, necessary for scale-invariant accounting.\n");
+               return false;
+       }
+
        arch_turbo_freq_ratio = div_u64(turbo_freq * SCHED_CAPACITY_SCALE,
                                        base_freq);
        arch_set_max_freq_ratio(turbo_disabled());
        return true;
 }
 
-static void init_counter_refs(void *arg)
+static void init_counter_refs(void)
 {
        u64 aperf, mperf;
 
@@ -2002,18 +2014,25 @@ static void init_counter_refs(void *arg)
        this_cpu_write(arch_prev_mperf, mperf);
 }
 
-static void init_freq_invariance(void)
+static void init_freq_invariance(bool secondary)
 {
        bool ret = false;
 
-       if (smp_processor_id() != 0 || !boot_cpu_has(X86_FEATURE_APERFMPERF))
+       if (!boot_cpu_has(X86_FEATURE_APERFMPERF))
                return;
 
+       if (secondary) {
+               if (static_branch_likely(&arch_scale_freq_key)) {
+                       init_counter_refs();
+               }
+               return;
+       }
+
        if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL)
                ret = intel_set_max_freq_ratio();
 
        if (ret) {
-               on_each_cpu(init_counter_refs, NULL, 1);
+               init_counter_refs();
                static_branch_enable(&arch_scale_freq_key);
        } else {
                pr_debug("Couldn't determine max cpu frequency, necessary for scale-invariant accounting.\n");
index a789759b7261339312e9074320ff5c72dcd02820..4a3081e9f4b5de97c4b90c1858284731088778ce 100644 (file)
@@ -3,6 +3,10 @@
 ccflags-y += -Iarch/x86/kvm
 ccflags-$(CONFIG_KVM_WERROR) += -Werror
 
+ifeq ($(CONFIG_FRAME_POINTER),y)
+OBJECT_FILES_NON_STANDARD_vmenter.o := y
+endif
+
 KVM := ../../../virt/kvm
 
 kvm-y                  += $(KVM)/kvm_main.o $(KVM)/coalesced_mmio.o \
index 0e3fc311d7da69aac911762d3fd6c93ffc790444..cf912b4aaba8e419f73c00ee26a760e7752ec1f1 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/kernel.h>
 #include <linux/highmem.h>
 #include <linux/psp-sev.h>
+#include <linux/pagemap.h>
 #include <linux/swap.h>
 
 #include "x86.h"
@@ -1117,7 +1118,7 @@ int __init sev_hardware_setup(void)
        /* Maximum number of encrypted guests supported simultaneously */
        max_sev_asid = cpuid_ecx(0x8000001F);
 
-       if (!max_sev_asid)
+       if (!svm_sev_enabled())
                return 1;
 
        /* Minimum ASID value that should be used for SEV guest */
@@ -1156,6 +1157,9 @@ err:
 
 void sev_hardware_teardown(void)
 {
+       if (!svm_sev_enabled())
+               return;
+
        bitmap_free(sev_asid_bitmap);
        bitmap_free(sev_reclaim_asid_bitmap);
 
index 2be5bbae3a40f2b0abb809c3be5284327e48a036..2f379bacbb26a3750157f80456a8d6321fa53ad2 100644 (file)
@@ -3276,7 +3276,7 @@ static void svm_cancel_injection(struct kvm_vcpu *vcpu)
        svm_complete_interrupts(svm);
 }
 
-bool __svm_vcpu_run(unsigned long vmcb_pa, unsigned long *regs);
+void __svm_vcpu_run(unsigned long vmcb_pa, unsigned long *regs);
 
 static void svm_vcpu_run(struct kvm_vcpu *vcpu)
 {
@@ -3330,13 +3330,8 @@ static void svm_vcpu_run(struct kvm_vcpu *vcpu)
         */
        x86_spec_ctrl_set_guest(svm->spec_ctrl, svm->virt_spec_ctrl);
 
-       local_irq_enable();
-
        __svm_vcpu_run(svm->vmcb_pa, (unsigned long *)&svm->vcpu.arch.regs);
 
-       /* Eliminate branch target predictions from guest mode */
-       vmexit_fill_RSB();
-
 #ifdef CONFIG_X86_64
        wrmsrl(MSR_GS_BASE, svm->host.gs_base);
 #else
@@ -3366,8 +3361,6 @@ static void svm_vcpu_run(struct kvm_vcpu *vcpu)
 
        reload_tss(vcpu);
 
-       local_irq_disable();
-
        x86_spec_ctrl_restore_host(svm->spec_ctrl, svm->virt_spec_ctrl);
 
        vcpu->arch.cr2 = svm->vmcb->save.cr2;
@@ -3411,7 +3404,6 @@ static void svm_vcpu_run(struct kvm_vcpu *vcpu)
 
        mark_all_clean(svm->vmcb);
 }
-STACK_FRAME_NON_STANDARD(svm_vcpu_run);
 
 static void svm_load_mmu_pgd(struct kvm_vcpu *vcpu, unsigned long root)
 {
index fa1af90067e97534227196bc70f7e5dc0e358bda..bf944334003aefa2cc5f1ffe3de34e61a1e6ceb3 100644 (file)
@@ -3,6 +3,7 @@
 #include <asm/asm.h>
 #include <asm/bitsperlong.h>
 #include <asm/kvm_vcpu_regs.h>
+#include <asm/nospec-branch.h>
 
 #define WORD_SIZE (BITS_PER_LONG / 8)
 
@@ -35,7 +36,6 @@
  */
 SYM_FUNC_START(__svm_vcpu_run)
        push %_ASM_BP
-       mov  %_ASM_SP, %_ASM_BP
 #ifdef CONFIG_X86_64
        push %r15
        push %r14
@@ -78,6 +78,7 @@ SYM_FUNC_START(__svm_vcpu_run)
        pop %_ASM_AX
 
        /* Enter guest mode */
+       sti
 1:     vmload %_ASM_AX
        jmp 3f
 2:     cmpb $0, kvm_rebooting
@@ -99,6 +100,13 @@ SYM_FUNC_START(__svm_vcpu_run)
        ud2
        _ASM_EXTABLE(5b, 6b)
 7:
+       cli
+
+#ifdef CONFIG_RETPOLINE
+       /* IMPORTANT: Stuff the RSB immediately after VM-Exit, before RET! */
+       FILL_RETURN_BUFFER %_ASM_AX, RSB_CLEAR_LOOPS, X86_FEATURE_RETPOLINE
+#endif
+
        /* "POP" @regs to RAX. */
        pop %_ASM_AX
 
index cbc9ea2de28f967dbdc77f33fd83d70464568d23..fd78ffbde644479348510b25c8fbf8433291509a 100644 (file)
@@ -5533,8 +5533,25 @@ static bool nested_vmx_exit_handled_vmcs_access(struct kvm_vcpu *vcpu,
        return 1 & (b >> (field & 7));
 }
 
+static bool nested_vmx_exit_handled_mtf(struct vmcs12 *vmcs12)
+{
+       u32 entry_intr_info = vmcs12->vm_entry_intr_info_field;
+
+       if (nested_cpu_has_mtf(vmcs12))
+               return true;
+
+       /*
+        * An MTF VM-exit may be injected into the guest by setting the
+        * interruption-type to 7 (other event) and the vector field to 0. Such
+        * is the case regardless of the 'monitor trap flag' VM-execution
+        * control.
+        */
+       return entry_intr_info == (INTR_INFO_VALID_MASK
+                                  | INTR_TYPE_OTHER_EVENT);
+}
+
 /*
- * Return 1 if we should exit from L2 to L1 to handle an exit, or 0 if we
+ * Return true if we should exit from L2 to L1 to handle an exit, or false if we
  * should handle it ourselves in L0 (and then continue L2). Only call this
  * when in is_guest_mode (L2).
  */
@@ -5633,7 +5650,7 @@ bool nested_vmx_exit_reflected(struct kvm_vcpu *vcpu, u32 exit_reason)
        case EXIT_REASON_MWAIT_INSTRUCTION:
                return nested_cpu_has(vmcs12, CPU_BASED_MWAIT_EXITING);
        case EXIT_REASON_MONITOR_TRAP_FLAG:
-               return nested_cpu_has_mtf(vmcs12);
+               return nested_vmx_exit_handled_mtf(vmcs12);
        case EXIT_REASON_MONITOR_INSTRUCTION:
                return nested_cpu_has(vmcs12, CPU_BASED_MONITOR_EXITING);
        case EXIT_REASON_PAUSE_INSTRUCTION:
index 83050977490c6bfc86a299e5456ff025831a085b..c2c6335a998c2f09f7f608b38e52403765c65e22 100644 (file)
@@ -4572,7 +4572,7 @@ static int handle_rmode_exception(struct kvm_vcpu *vcpu,
  */
 static void kvm_machine_check(void)
 {
-#if defined(CONFIG_X86_MCE) && defined(CONFIG_X86_64)
+#if defined(CONFIG_X86_MCE)
        struct pt_regs regs = {
                .cs = 3, /* Fake ring 3 no matter what the guest ran on */
                .flags = X86_EFLAGS_IF,
index 3bf2ecafd0270f9ab484ecb2b503d5afea2fd616..c5835f9cb9ad327aba58c1cab2a47934f5807d53 100644 (file)
@@ -3060,6 +3060,17 @@ int kvm_get_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
        case MSR_IA32_PERF_CTL:
        case MSR_AMD64_DC_CFG:
        case MSR_F15H_EX_CFG:
+       /*
+        * Intel Sandy Bridge CPUs must support the RAPL (running average power
+        * limit) MSRs. Just return 0, as we do not want to expose the host
+        * data here. Do not conditionalize this on CPUID, as KVM does not do
+        * so for existing CPU-specific MSRs.
+        */
+       case MSR_RAPL_POWER_UNIT:
+       case MSR_PP0_ENERGY_STATUS:     /* Power plane 0 (core) */
+       case MSR_PP1_ENERGY_STATUS:     /* Power plane 1 (graphics uncore) */
+       case MSR_PKG_ENERGY_STATUS:     /* Total package */
+       case MSR_DRAM_ENERGY_STATUS:    /* DRAM controller */
                msr_info->data = 0;
                break;
        case MSR_F15H_PERF_CTL0 ... MSR_F15H_PERF_CTR5:
@@ -5049,10 +5060,13 @@ set_identity_unlock:
                r = -EFAULT;
                if (copy_from_user(&u.ps, argp, sizeof(u.ps)))
                        goto out;
+               mutex_lock(&kvm->lock);
                r = -ENXIO;
                if (!kvm->arch.vpit)
-                       goto out;
+                       goto set_pit_out;
                r = kvm_vm_ioctl_set_pit(kvm, &u.ps);
+set_pit_out:
+               mutex_unlock(&kvm->lock);
                break;
        }
        case KVM_GET_PIT2: {
@@ -5072,10 +5086,13 @@ set_identity_unlock:
                r = -EFAULT;
                if (copy_from_user(&u.ps2, argp, sizeof(u.ps2)))
                        goto out;
+               mutex_lock(&kvm->lock);
                r = -ENXIO;
                if (!kvm->arch.vpit)
-                       goto out;
+                       goto set_pit2_out;
                r = kvm_vm_ioctl_set_pit2(kvm, &u.ps2);
+set_pit2_out:
+               mutex_unlock(&kvm->lock);
                break;
        }
        case KVM_REINJECT_CONTROL: {
index 5ea7c2cf7ab4eea153625e38dc4820fcf69a1030..42b6709e6dc7ca002cc8653446bdba62ff83f182 100644 (file)
@@ -158,6 +158,19 @@ static bool is_ereg(u32 reg)
                             BIT(BPF_REG_AX));
 }
 
+/*
+ * is_ereg_8l() == true if BPF register 'reg' is mapped to access x86-64
+ * lower 8-bit registers dil,sil,bpl,spl,r8b..r15b, which need extra byte
+ * of encoding. al,cl,dl,bl have simpler encoding.
+ */
+static bool is_ereg_8l(u32 reg)
+{
+       return is_ereg(reg) ||
+           (1 << reg) & (BIT(BPF_REG_1) |
+                         BIT(BPF_REG_2) |
+                         BIT(BPF_REG_FP));
+}
+
 static bool is_axreg(u32 reg)
 {
        return reg == BPF_REG_0;
@@ -598,9 +611,8 @@ static void emit_stx(u8 **pprog, u32 size, u32 dst_reg, u32 src_reg, int off)
        switch (size) {
        case BPF_B:
                /* Emit 'mov byte ptr [rax + off], al' */
-               if (is_ereg(dst_reg) || is_ereg(src_reg) ||
-                   /* We have to add extra byte for x86 SIL, DIL regs */
-                   src_reg == BPF_REG_1 || src_reg == BPF_REG_2)
+               if (is_ereg(dst_reg) || is_ereg_8l(src_reg))
+                       /* Add extra byte for eregs or SIL,DIL,BPL in src_reg */
                        EMIT2(add_2mod(0x40, dst_reg, src_reg), 0x88);
                else
                        EMIT1(0x88);
index 4d2a7a76460262a537bc242c4f3468ea1d0ee15b..66cd150b7e541d77302819298284ec3b81c54b12 100644 (file)
@@ -1847,14 +1847,16 @@ static int do_jit(struct bpf_prog *bpf_prog, int *addrs, u8 *image,
                        case BPF_B:
                        case BPF_H:
                        case BPF_W:
-                               if (!bpf_prog->aux->verifier_zext)
+                               if (bpf_prog->aux->verifier_zext)
                                        break;
                                if (dstk) {
                                        EMIT3(0xC7, add_1reg(0x40, IA32_EBP),
                                              STACK_VAR(dst_hi));
                                        EMIT(0x0, 4);
                                } else {
-                                       EMIT3(0xC7, add_1reg(0xC0, dst_hi), 0);
+                                       /* xor dst_hi,dst_hi */
+                                       EMIT2(0x33,
+                                             add_2reg(0xC0, dst_hi, dst_hi));
                                }
                                break;
                        case BPF_DW:
@@ -2013,8 +2015,8 @@ static int do_jit(struct bpf_prog *bpf_prog, int *addrs, u8 *image,
                case BPF_JMP | BPF_JSET | BPF_X:
                case BPF_JMP32 | BPF_JSET | BPF_X: {
                        bool is_jmp64 = BPF_CLASS(insn->code) == BPF_JMP;
-                       u8 dreg_lo = dstk ? IA32_EAX : dst_lo;
-                       u8 dreg_hi = dstk ? IA32_EDX : dst_hi;
+                       u8 dreg_lo = IA32_EAX;
+                       u8 dreg_hi = IA32_EDX;
                        u8 sreg_lo = sstk ? IA32_ECX : src_lo;
                        u8 sreg_hi = sstk ? IA32_EBX : src_hi;
 
@@ -2026,6 +2028,13 @@ static int do_jit(struct bpf_prog *bpf_prog, int *addrs, u8 *image,
                                              add_2reg(0x40, IA32_EBP,
                                                       IA32_EDX),
                                              STACK_VAR(dst_hi));
+                       } else {
+                               /* mov dreg_lo,dst_lo */
+                               EMIT2(0x89, add_2reg(0xC0, dreg_lo, dst_lo));
+                               if (is_jmp64)
+                                       /* mov dreg_hi,dst_hi */
+                                       EMIT2(0x89,
+                                             add_2reg(0xC0, dreg_hi, dst_hi));
                        }
 
                        if (sstk) {
@@ -2050,8 +2059,8 @@ static int do_jit(struct bpf_prog *bpf_prog, int *addrs, u8 *image,
                case BPF_JMP | BPF_JSET | BPF_K:
                case BPF_JMP32 | BPF_JSET | BPF_K: {
                        bool is_jmp64 = BPF_CLASS(insn->code) == BPF_JMP;
-                       u8 dreg_lo = dstk ? IA32_EAX : dst_lo;
-                       u8 dreg_hi = dstk ? IA32_EDX : dst_hi;
+                       u8 dreg_lo = IA32_EAX;
+                       u8 dreg_hi = IA32_EDX;
                        u8 sreg_lo = IA32_ECX;
                        u8 sreg_hi = IA32_EBX;
                        u32 hi;
@@ -2064,6 +2073,13 @@ static int do_jit(struct bpf_prog *bpf_prog, int *addrs, u8 *image,
                                              add_2reg(0x40, IA32_EBP,
                                                       IA32_EDX),
                                              STACK_VAR(dst_hi));
+                       } else {
+                               /* mov dreg_lo,dst_lo */
+                               EMIT2(0x89, add_2reg(0xC0, dreg_lo, dst_lo));
+                               if (is_jmp64)
+                                       /* mov dreg_hi,dst_hi */
+                                       EMIT2(0x89,
+                                             add_2reg(0xC0, dreg_hi, dst_hi));
                        }
 
                        /* mov ecx,imm32 */
similarity index 57%
rename from arch/xtensa/include/asm/module.h
rename to arch/xtensa/include/asm/vermagic.h
index 488b40c6f9b9aa89fcf0cce02d33e9bd6bfa6274..6d9c670e4ba98843029effc73e20738e344ad376 100644 (file)
@@ -1,8 +1,4 @@
 /*
- * include/asm-xtensa/module.h
- *
- * This file contains the module code specific to the Xtensa architecture.
- *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  * Copyright (C) 2001 - 2005 Tensilica Inc.
  */
 
-#ifndef _XTENSA_MODULE_H
-#define _XTENSA_MODULE_H
+#ifndef _ASM_VERMAGIC_H
+#define _ASM_VERMAGIC_H
 
-#define MODULE_ARCH_VERMAGIC "xtensa-" __stringify(XCHAL_CORE_ID) " "
+#include <linux/stringify.h>
+#include <variant/core.h>
 
-#include <asm-generic/module.h>
+#define MODULE_ARCH_VERMAGIC "xtensa-" __stringify(XCHAL_CORE_ID) " "
 
-#endif /* _XTENSA_MODULE_H */
+#endif /* _ASM_VERMAGIC_H */
index db35ee682294c138ec78a048a34bd80aeb860a7d..3ab0c1c704b68f0a9d5574d2a76ea252f3cc950d 100644 (file)
@@ -1591,7 +1591,7 @@ skip_surplus_transfers:
                                      vrate_min, vrate_max);
                }
 
-               trace_iocost_ioc_vrate_adj(ioc, vrate, &missed_ppm, rq_wait_pct,
+               trace_iocost_ioc_vrate_adj(ioc, vrate, missed_ppm, rq_wait_pct,
                                           nr_lagging, nr_shortages,
                                           nr_surpluses);
 
@@ -1600,7 +1600,7 @@ skip_surplus_transfers:
                        ioc->period_us * vrate * INUSE_MARGIN_PCT, 100);
        } else if (ioc->busy_level != prev_busy_level || nr_lagging) {
                trace_iocost_ioc_vrate_adj(ioc, atomic64_read(&ioc->vtime_rate),
-                                          &missed_ppm, rq_wait_pct, nr_lagging,
+                                          missed_ppm, rq_wait_pct, nr_lagging,
                                           nr_shortages, nr_surpluses);
        }
 
index 00112cf1532203da1b04144975b4069779b128e0..78cfc70cb3209c8997d297cf9274815163bbd477 100644 (file)
@@ -87,18 +87,6 @@ static const struct dmi_system_id dmi_lid_quirks[] = {
                },
                .driver_data = (void *)(long)ACPI_BUTTON_LID_INIT_DISABLED,
        },
-       {
-               /*
-                * Asus T200TA, _LID keeps reporting closed after every second
-                * openening of the lid. Causing immediate re-suspend after
-                * opening every other open. Using LID_INIT_OPEN fixes this.
-                */
-               .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "T200TA"),
-               },
-               .driver_data = (void *)(long)ACPI_BUTTON_LID_INIT_OPEN,
-       },
        {
                /* GP-electronic T701, _LID method points to a floating GPIO */
                .matches = {
index 00a6da2121be30bd08de4bcbe2f9a6e9a12c4488..ed3d2182cf2c0a0eb80624876ce66ef6cba02566 100644 (file)
@@ -322,10 +322,10 @@ static int acpi_pci_link_set(struct acpi_pci_link *link, int irq)
                resource->res.data.extended_irq.polarity =
                    link->irq.polarity;
                if (link->irq.triggering == ACPI_EDGE_SENSITIVE)
-                       resource->res.data.irq.shareable =
+                       resource->res.data.extended_irq.shareable =
                            ACPI_EXCLUSIVE;
                else
-                       resource->res.data.irq.shareable = ACPI_SHARED;
+                       resource->res.data.extended_irq.shareable = ACPI_SHARED;
                resource->res.data.extended_irq.interrupt_count = 1;
                resource->res.data.extended_irq.interrupts[0] = irq;
                /* ignore resource_source, it's optional */
index a6b76cc12a66192aa21ad20aae68e2e8175944a9..e517bd8822a5faaeef2039a356518ed5a4e970da 100644 (file)
@@ -145,7 +145,7 @@ enum {
 
        /* PORT_IDMA_CTL bits */
        IDMA_CTL_RST_ATA        = (1 << 2),  /* hardreset ATA bus */
-       IDMA_CTL_RST_IDMA       = (1 << 5),  /* reset IDMA machinary */
+       IDMA_CTL_RST_IDMA       = (1 << 5),  /* reset IDMA machinery */
        IDMA_CTL_GO             = (1 << 7),  /* IDMA mode go */
        IDMA_CTL_ATA_NIEN       = (1 << 8),  /* ATA IRQ disable */
 
index ba9d30b28edc5a9d8a439f0a6a07610a5590cbb4..a182e318bd0969d9391d99f7c84ca97af59ef568 100644 (file)
@@ -45,5 +45,4 @@ struct ctl_table firmware_config_table[] = {
        },
        { }
 };
-EXPORT_SYMBOL_GPL(firmware_config_table);
 #endif
index fdd508a78ffd66044a4ffd89f5e44fd16f74e05f..0e07e17c2def339448a2a6ae41d496f703b81472 100644 (file)
@@ -730,7 +730,7 @@ static bool dpm_async_fn(struct device *dev, async_func_t func)
 
        if (is_async(dev)) {
                get_device(dev);
-               async_schedule(func, dev);
+               async_schedule_dev(func, dev);
                return true;
        }
 
index 62b660821dbcc19b390712b4088fc7141a4b27c2..81b311c9d781ef5d61108093db0d8a79518e4245 100644 (file)
@@ -85,26 +85,35 @@ struct nullb {
        char disk_name[DISK_NAME_LEN];
 };
 
+blk_status_t null_process_cmd(struct nullb_cmd *cmd,
+                             enum req_opf op, sector_t sector,
+                             unsigned int nr_sectors);
+
 #ifdef CONFIG_BLK_DEV_ZONED
-int null_zone_init(struct nullb_device *dev);
-void null_zone_exit(struct nullb_device *dev);
+int null_init_zoned_dev(struct nullb_device *dev, struct request_queue *q);
+int null_register_zoned_dev(struct nullb *nullb);
+void null_free_zoned_dev(struct nullb_device *dev);
 int null_report_zones(struct gendisk *disk, sector_t sector,
                      unsigned int nr_zones, report_zones_cb cb, void *data);
-blk_status_t null_handle_zoned(struct nullb_cmd *cmd,
-                               enum req_opf op, sector_t sector,
-                               sector_t nr_sectors);
+blk_status_t null_process_zoned_cmd(struct nullb_cmd *cmd,
+                                   enum req_opf op, sector_t sector,
+                                   sector_t nr_sectors);
 size_t null_zone_valid_read_len(struct nullb *nullb,
                                sector_t sector, unsigned int len);
 #else
-static inline int null_zone_init(struct nullb_device *dev)
+static inline int null_init_zoned_dev(struct nullb_device *dev,
+                                     struct request_queue *q)
 {
        pr_err("CONFIG_BLK_DEV_ZONED not enabled\n");
        return -EINVAL;
 }
-static inline void null_zone_exit(struct nullb_device *dev) {}
-static inline blk_status_t null_handle_zoned(struct nullb_cmd *cmd,
-                                            enum req_opf op, sector_t sector,
-                                            sector_t nr_sectors)
+static inline int null_register_zoned_dev(struct nullb *nullb)
+{
+       return -ENODEV;
+}
+static inline void null_free_zoned_dev(struct nullb_device *dev) {}
+static inline blk_status_t null_process_zoned_cmd(struct nullb_cmd *cmd,
+                       enum req_opf op, sector_t sector, sector_t nr_sectors)
 {
        return BLK_STS_NOTSUPP;
 }
index 4e1c0712278eaf89e1cedb897db54f73fe13ae94..8efd8778e2095e4a4ce6606f36effb5882339cd4 100644 (file)
@@ -580,7 +580,7 @@ static void null_free_dev(struct nullb_device *dev)
        if (!dev)
                return;
 
-       null_zone_exit(dev);
+       null_free_zoned_dev(dev);
        badblocks_exit(&dev->badblocks);
        kfree(dev);
 }
@@ -1276,6 +1276,25 @@ static inline void nullb_complete_cmd(struct nullb_cmd *cmd)
        }
 }
 
+blk_status_t null_process_cmd(struct nullb_cmd *cmd,
+                             enum req_opf op, sector_t sector,
+                             unsigned int nr_sectors)
+{
+       struct nullb_device *dev = cmd->nq->dev;
+       blk_status_t ret;
+
+       if (dev->badblocks.shift != -1) {
+               ret = null_handle_badblocks(cmd, sector, nr_sectors);
+               if (ret != BLK_STS_OK)
+                       return ret;
+       }
+
+       if (dev->memory_backed)
+               return null_handle_memory_backed(cmd, op);
+
+       return BLK_STS_OK;
+}
+
 static blk_status_t null_handle_cmd(struct nullb_cmd *cmd, sector_t sector,
                                    sector_t nr_sectors, enum req_opf op)
 {
@@ -1294,17 +1313,11 @@ static blk_status_t null_handle_cmd(struct nullb_cmd *cmd, sector_t sector,
                goto out;
        }
 
-       if (nullb->dev->badblocks.shift != -1) {
-               cmd->error = null_handle_badblocks(cmd, sector, nr_sectors);
-               if (cmd->error != BLK_STS_OK)
-                       goto out;
-       }
-
-       if (dev->memory_backed)
-               cmd->error = null_handle_memory_backed(cmd, op);
-
-       if (!cmd->error && dev->zoned)
-               cmd->error = null_handle_zoned(cmd, op, sector, nr_sectors);
+       if (dev->zoned)
+               cmd->error = null_process_zoned_cmd(cmd, op,
+                                                   sector, nr_sectors);
+       else
+               cmd->error = null_process_cmd(cmd, op, sector, nr_sectors);
 
 out:
        nullb_complete_cmd(cmd);
@@ -1605,19 +1618,12 @@ static int null_gendisk_register(struct nullb *nullb)
        disk->queue             = nullb->q;
        strncpy(disk->disk_name, nullb->disk_name, DISK_NAME_LEN);
 
-#ifdef CONFIG_BLK_DEV_ZONED
        if (nullb->dev->zoned) {
-               if (queue_is_mq(nullb->q)) {
-                       int ret = blk_revalidate_disk_zones(disk);
-                       if (ret)
-                               return ret;
-               } else {
-                       blk_queue_chunk_sectors(nullb->q,
-                                       nullb->dev->zone_size_sects);
-                       nullb->q->nr_zones = blkdev_nr_zones(disk);
-               }
+               int ret = null_register_zoned_dev(nullb);
+
+               if (ret)
+                       return ret;
        }
-#endif
 
        add_disk(disk);
        return 0;
@@ -1773,14 +1779,9 @@ static int null_add_dev(struct nullb_device *dev)
        }
 
        if (dev->zoned) {
-               rv = null_zone_init(dev);
+               rv = null_init_zoned_dev(dev, nullb->q);
                if (rv)
                        goto out_cleanup_blk_queue;
-
-               nullb->q->limits.zoned = BLK_ZONED_HM;
-               blk_queue_flag_set(QUEUE_FLAG_ZONE_RESETALL, nullb->q);
-               blk_queue_required_elevator_features(nullb->q,
-                                               ELEVATOR_F_ZBD_SEQ_WRITE);
        }
 
        nullb->q->queuedata = nullb;
@@ -1809,8 +1810,7 @@ static int null_add_dev(struct nullb_device *dev)
 
        return 0;
 out_cleanup_zone:
-       if (dev->zoned)
-               null_zone_exit(dev);
+       null_free_zoned_dev(dev);
 out_cleanup_blk_queue:
        blk_cleanup_queue(nullb->q);
 out_cleanup_tags:
index 673618d8222a6e6acc48ddb95fb56a85d73506bd..9e4bcdad1a80f700562a447cca6c533b828369d0 100644 (file)
@@ -13,7 +13,7 @@ static inline unsigned int null_zone_no(struct nullb_device *dev, sector_t sect)
        return sect >> ilog2(dev->zone_size_sects);
 }
 
-int null_zone_init(struct nullb_device *dev)
+int null_init_zoned_dev(struct nullb_device *dev, struct request_queue *q)
 {
        sector_t dev_size = (sector_t)dev->size * 1024 * 1024;
        sector_t sector = 0;
@@ -61,10 +61,27 @@ int null_zone_init(struct nullb_device *dev)
                sector += dev->zone_size_sects;
        }
 
+       q->limits.zoned = BLK_ZONED_HM;
+       blk_queue_flag_set(QUEUE_FLAG_ZONE_RESETALL, q);
+       blk_queue_required_elevator_features(q, ELEVATOR_F_ZBD_SEQ_WRITE);
+
+       return 0;
+}
+
+int null_register_zoned_dev(struct nullb *nullb)
+{
+       struct request_queue *q = nullb->q;
+
+       if (queue_is_mq(q))
+               return blk_revalidate_disk_zones(nullb->disk);
+
+       blk_queue_chunk_sectors(q, nullb->dev->zone_size_sects);
+       q->nr_zones = blkdev_nr_zones(nullb->disk);
+
        return 0;
 }
 
-void null_zone_exit(struct nullb_device *dev)
+void null_free_zoned_dev(struct nullb_device *dev)
 {
        kvfree(dev->zones);
 }
@@ -126,11 +143,16 @@ static blk_status_t null_zone_write(struct nullb_cmd *cmd, sector_t sector,
        struct nullb_device *dev = cmd->nq->dev;
        unsigned int zno = null_zone_no(dev, sector);
        struct blk_zone *zone = &dev->zones[zno];
+       blk_status_t ret;
+
+       trace_nullb_zone_op(cmd, zno, zone->cond);
+
+       if (zone->type == BLK_ZONE_TYPE_CONVENTIONAL)
+               return null_process_cmd(cmd, REQ_OP_WRITE, sector, nr_sectors);
 
        switch (zone->cond) {
        case BLK_ZONE_COND_FULL:
                /* Cannot write to a full zone */
-               cmd->error = BLK_STS_IOERR;
                return BLK_STS_IOERR;
        case BLK_ZONE_COND_EMPTY:
        case BLK_ZONE_COND_IMP_OPEN:
@@ -143,19 +165,18 @@ static blk_status_t null_zone_write(struct nullb_cmd *cmd, sector_t sector,
                if (zone->cond != BLK_ZONE_COND_EXP_OPEN)
                        zone->cond = BLK_ZONE_COND_IMP_OPEN;
 
+               ret = null_process_cmd(cmd, REQ_OP_WRITE, sector, nr_sectors);
+               if (ret != BLK_STS_OK)
+                       return ret;
+
                zone->wp += nr_sectors;
                if (zone->wp == zone->start + zone->len)
                        zone->cond = BLK_ZONE_COND_FULL;
-               break;
-       case BLK_ZONE_COND_NOT_WP:
-               break;
+               return BLK_STS_OK;
        default:
                /* Invalid zone condition */
                return BLK_STS_IOERR;
        }
-
-       trace_nullb_zone_op(cmd, zno, zone->cond);
-       return BLK_STS_OK;
 }
 
 static blk_status_t null_zone_mgmt(struct nullb_cmd *cmd, enum req_opf op,
@@ -216,8 +237,8 @@ static blk_status_t null_zone_mgmt(struct nullb_cmd *cmd, enum req_opf op,
        return BLK_STS_OK;
 }
 
-blk_status_t null_handle_zoned(struct nullb_cmd *cmd, enum req_opf op,
-                              sector_t sector, sector_t nr_sectors)
+blk_status_t null_process_zoned_cmd(struct nullb_cmd *cmd, enum req_opf op,
+                                   sector_t sector, sector_t nr_sectors)
 {
        switch (op) {
        case REQ_OP_WRITE:
@@ -229,6 +250,6 @@ blk_status_t null_handle_zoned(struct nullb_cmd *cmd, enum req_opf op,
        case REQ_OP_ZONE_FINISH:
                return null_zone_mgmt(cmd, op, sector);
        default:
-               return BLK_STS_OK;
+               return null_process_cmd(cmd, op, sector, nr_sectors);
        }
 }
index f9b1e70f1b3149b4da7a4c1b9f324821b1d0b7ab..93468b7c67019b3af6dd16cf639f11bb8dd77337 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/blk-mq.h>
 #include <linux/blk-mq-virtio.h>
 #include <linux/numa.h>
+#include <uapi/linux/virtio_ring.h>
 
 #define PART_BITS 4
 #define VQ_NAME_LEN 16
index 718d8c0876506c59e4d05b7ccc5ef950e431ed19..79a6e47b5fbc9f20a5529620eee384b42842283a 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/virtio.h>
 #include <linux/virtio_rng.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 
 static DEFINE_IDA(rng_index_ida);
 
index a438b1206fcbe7c4355e9a04281bfbb55f83dc2c..1621ce8187052cf332cab95d0dffed87ec2f074e 100644 (file)
@@ -323,7 +323,7 @@ int tpm_pcr_extend(struct tpm_chip *chip, u32 pcr_idx,
 
        for (i = 0; i < chip->nr_allocated_banks; i++) {
                if (digests[i].alg_id != chip->allocated_banks[i].alg_id) {
-                       rc = EINVAL;
+                       rc = -EINVAL;
                        goto out;
                }
        }
index 76f67b155bd5420981e7baea3f530745748cbed2..eff1f12d981ab275e07387864a876e1cfc35e2d9 100644 (file)
@@ -681,6 +681,7 @@ out:
                rc = -ENODEV;
        return rc;
 }
+EXPORT_SYMBOL_GPL(tpm2_get_cc_attrs_tbl);
 
 /**
  * tpm2_startup - turn on the TPM
index 1a49db9e108e5d3e09ad678d66f10a3908d14ba0..09fe45246b8cc0d65760eecff54af9bdbd2997ef 100644 (file)
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
- * Copyright (C) 2012 IBM Corporation
+ * Copyright (C) 2012-2020 IBM Corporation
  *
  * Author: Ashley Lai <ashleydlai@gmail.com>
  *
@@ -134,6 +134,64 @@ static int tpm_ibmvtpm_recv(struct tpm_chip *chip, u8 *buf, size_t count)
        return len;
 }
 
+/**
+ * ibmvtpm_crq_send_init - Send a CRQ initialize message
+ * @ibmvtpm:   vtpm device struct
+ *
+ * Return:
+ *     0 on success.
+ *     Non-zero on failure.
+ */
+static int ibmvtpm_crq_send_init(struct ibmvtpm_dev *ibmvtpm)
+{
+       int rc;
+
+       rc = ibmvtpm_send_crq_word(ibmvtpm->vdev, INIT_CRQ_CMD);
+       if (rc != H_SUCCESS)
+               dev_err(ibmvtpm->dev,
+                       "%s failed rc=%d\n", __func__, rc);
+
+       return rc;
+}
+
+/**
+ * tpm_ibmvtpm_resume - Resume from suspend
+ *
+ * @dev:       device struct
+ *
+ * Return: Always 0.
+ */
+static int tpm_ibmvtpm_resume(struct device *dev)
+{
+       struct tpm_chip *chip = dev_get_drvdata(dev);
+       struct ibmvtpm_dev *ibmvtpm = dev_get_drvdata(&chip->dev);
+       int rc = 0;
+
+       do {
+               if (rc)
+                       msleep(100);
+               rc = plpar_hcall_norets(H_ENABLE_CRQ,
+                                       ibmvtpm->vdev->unit_address);
+       } while (rc == H_IN_PROGRESS || rc == H_BUSY || H_IS_LONG_BUSY(rc));
+
+       if (rc) {
+               dev_err(dev, "Error enabling ibmvtpm rc=%d\n", rc);
+               return rc;
+       }
+
+       rc = vio_enable_interrupts(ibmvtpm->vdev);
+       if (rc) {
+               dev_err(dev, "Error vio_enable_interrupts rc=%d\n", rc);
+               return rc;
+       }
+
+       rc = ibmvtpm_crq_send_init(ibmvtpm);
+       if (rc)
+               dev_err(dev, "Error send_init rc=%d\n", rc);
+
+       return rc;
+}
+
 /**
  * tpm_ibmvtpm_send() - Send a TPM command
  * @chip:      tpm chip struct
@@ -147,6 +205,7 @@ static int tpm_ibmvtpm_recv(struct tpm_chip *chip, u8 *buf, size_t count)
 static int tpm_ibmvtpm_send(struct tpm_chip *chip, u8 *buf, size_t count)
 {
        struct ibmvtpm_dev *ibmvtpm = dev_get_drvdata(&chip->dev);
+       bool retry = true;
        int rc, sig;
 
        if (!ibmvtpm->rtce_buf) {
@@ -180,18 +239,27 @@ static int tpm_ibmvtpm_send(struct tpm_chip *chip, u8 *buf, size_t count)
         */
        ibmvtpm->tpm_processing_cmd = true;
 
+again:
        rc = ibmvtpm_send_crq(ibmvtpm->vdev,
                        IBMVTPM_VALID_CMD, VTPM_TPM_COMMAND,
                        count, ibmvtpm->rtce_dma_handle);
        if (rc != H_SUCCESS) {
+               /*
+                * H_CLOSED can be returned after LPM resume.  Call
+                * tpm_ibmvtpm_resume() to re-enable the CRQ then retry
+                * ibmvtpm_send_crq() once before failing.
+                */
+               if (rc == H_CLOSED && retry) {
+                       tpm_ibmvtpm_resume(ibmvtpm->dev);
+                       retry = false;
+                       goto again;
+               }
                dev_err(ibmvtpm->dev, "tpm_ibmvtpm_send failed rc=%d\n", rc);
-               rc = 0;
                ibmvtpm->tpm_processing_cmd = false;
-       } else
-               rc = 0;
+       }
 
        spin_unlock(&ibmvtpm->rtce_lock);
-       return rc;
+       return 0;
 }
 
 static void tpm_ibmvtpm_cancel(struct tpm_chip *chip)
@@ -269,26 +337,6 @@ static int ibmvtpm_crq_send_init_complete(struct ibmvtpm_dev *ibmvtpm)
        return rc;
 }
 
-/**
- * ibmvtpm_crq_send_init - Send a CRQ initialize message
- * @ibmvtpm:   vtpm device struct
- *
- * Return:
- *     0 on success.
- *     Non-zero on failure.
- */
-static int ibmvtpm_crq_send_init(struct ibmvtpm_dev *ibmvtpm)
-{
-       int rc;
-
-       rc = ibmvtpm_send_crq_word(ibmvtpm->vdev, INIT_CRQ_CMD);
-       if (rc != H_SUCCESS)
-               dev_err(ibmvtpm->dev,
-                       "ibmvtpm_crq_send_init failed rc=%d\n", rc);
-
-       return rc;
-}
-
 /**
  * tpm_ibmvtpm_remove - ibm vtpm remove entry point
  * @vdev:      vio device struct
@@ -401,44 +449,6 @@ static int ibmvtpm_reset_crq(struct ibmvtpm_dev *ibmvtpm)
                                  ibmvtpm->crq_dma_handle, CRQ_RES_BUF_SIZE);
 }
 
-/**
- * tpm_ibmvtpm_resume - Resume from suspend
- *
- * @dev:       device struct
- *
- * Return: Always 0.
- */
-static int tpm_ibmvtpm_resume(struct device *dev)
-{
-       struct tpm_chip *chip = dev_get_drvdata(dev);
-       struct ibmvtpm_dev *ibmvtpm = dev_get_drvdata(&chip->dev);
-       int rc = 0;
-
-       do {
-               if (rc)
-                       msleep(100);
-               rc = plpar_hcall_norets(H_ENABLE_CRQ,
-                                       ibmvtpm->vdev->unit_address);
-       } while (rc == H_IN_PROGRESS || rc == H_BUSY || H_IS_LONG_BUSY(rc));
-
-       if (rc) {
-               dev_err(dev, "Error enabling ibmvtpm rc=%d\n", rc);
-               return rc;
-       }
-
-       rc = vio_enable_interrupts(ibmvtpm->vdev);
-       if (rc) {
-               dev_err(dev, "Error vio_enable_interrupts rc=%d\n", rc);
-               return rc;
-       }
-
-       rc = ibmvtpm_crq_send_init(ibmvtpm);
-       if (rc)
-               dev_err(dev, "Error send_init rc=%d\n", rc);
-
-       return rc;
-}
-
 static bool tpm_ibmvtpm_req_canceled(struct tpm_chip *chip, u8 status)
 {
        return (status == 0);
index 27c6ca031e23ec8a26401dc281271404e8e3a008..2435216bd10aaac1856f48a30c507a532bf19deb 100644 (file)
@@ -433,6 +433,9 @@ static void disable_interrupts(struct tpm_chip *chip)
        u32 intmask;
        int rc;
 
+       if (priv->irq == 0)
+               return;
+
        rc = tpm_tis_read32(priv, TPM_INT_ENABLE(priv->locality), &intmask);
        if (rc < 0)
                intmask = 0;
@@ -1062,9 +1065,12 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq,
                if (irq) {
                        tpm_tis_probe_irq_single(chip, intmask, IRQF_SHARED,
                                                 irq);
-                       if (!(chip->flags & TPM_CHIP_FLAG_IRQ))
+                       if (!(chip->flags & TPM_CHIP_FLAG_IRQ)) {
                                dev_err(&chip->dev, FW_BUG
                                        "TPM interrupt not working, polling instead\n");
+
+                               disable_interrupts(chip);
+                       }
                } else {
                        tpm_tis_probe_irq(chip, intmask);
                }
index 9dab190c49b062821442ef7852e026fe7ad48d04..aa13708c2bc30653ba8426b99f2b4ddc82cf0c5e 100644 (file)
@@ -44,6 +44,7 @@ MODULE_PARM_DESC(base, "ACCES 104-QUAD-8 base addresses");
  * @base:              base port address of the IIO device
  */
 struct quad8_iio {
+       struct mutex lock;
        struct counter_device counter;
        unsigned int fck_prescaler[QUAD8_NUM_COUNTERS];
        unsigned int preset[QUAD8_NUM_COUNTERS];
@@ -123,6 +124,8 @@ static int quad8_read_raw(struct iio_dev *indio_dev,
                /* Borrow XOR Carry effectively doubles count range */
                *val = (borrow ^ carry) << 24;
 
+               mutex_lock(&priv->lock);
+
                /* Reset Byte Pointer; transfer Counter to Output Latch */
                outb(QUAD8_CTR_RLD | QUAD8_RLD_RESET_BP | QUAD8_RLD_CNTR_OUT,
                     base_offset + 1);
@@ -130,6 +133,8 @@ static int quad8_read_raw(struct iio_dev *indio_dev,
                for (i = 0; i < 3; i++)
                        *val |= (unsigned int)inb(base_offset) << (8 * i);
 
+               mutex_unlock(&priv->lock);
+
                return IIO_VAL_INT;
        case IIO_CHAN_INFO_ENABLE:
                *val = priv->ab_enable[chan->channel];
@@ -160,6 +165,8 @@ static int quad8_write_raw(struct iio_dev *indio_dev,
                if ((unsigned int)val > 0xFFFFFF)
                        return -EINVAL;
 
+               mutex_lock(&priv->lock);
+
                /* Reset Byte Pointer */
                outb(QUAD8_CTR_RLD | QUAD8_RLD_RESET_BP, base_offset + 1);
 
@@ -183,12 +190,16 @@ static int quad8_write_raw(struct iio_dev *indio_dev,
                /* Reset Error flag */
                outb(QUAD8_CTR_RLD | QUAD8_RLD_RESET_E, base_offset + 1);
 
+               mutex_unlock(&priv->lock);
+
                return 0;
        case IIO_CHAN_INFO_ENABLE:
                /* only boolean values accepted */
                if (val < 0 || val > 1)
                        return -EINVAL;
 
+               mutex_lock(&priv->lock);
+
                priv->ab_enable[chan->channel] = val;
 
                ior_cfg = val | priv->preset_enable[chan->channel] << 1;
@@ -196,11 +207,18 @@ static int quad8_write_raw(struct iio_dev *indio_dev,
                /* Load I/O control configuration */
                outb(QUAD8_CTR_IOR | ior_cfg, base_offset + 1);
 
+               mutex_unlock(&priv->lock);
+
                return 0;
        case IIO_CHAN_INFO_SCALE:
+               mutex_lock(&priv->lock);
+
                /* Quadrature scaling only available in quadrature mode */
-               if (!priv->quadrature_mode[chan->channel] && (val2 || val != 1))
+               if (!priv->quadrature_mode[chan->channel] &&
+                               (val2 || val != 1)) {
+                       mutex_unlock(&priv->lock);
                        return -EINVAL;
+               }
 
                /* Only three gain states (1, 0.5, 0.25) */
                if (val == 1 && !val2)
@@ -214,11 +232,15 @@ static int quad8_write_raw(struct iio_dev *indio_dev,
                                priv->quadrature_scale[chan->channel] = 2;
                                break;
                        default:
+                               mutex_unlock(&priv->lock);
                                return -EINVAL;
                        }
-               else
+               else {
+                       mutex_unlock(&priv->lock);
                        return -EINVAL;
+               }
 
+               mutex_unlock(&priv->lock);
                return 0;
        }
 
@@ -255,6 +277,8 @@ static ssize_t quad8_write_preset(struct iio_dev *indio_dev, uintptr_t private,
        if (preset > 0xFFFFFF)
                return -EINVAL;
 
+       mutex_lock(&priv->lock);
+
        priv->preset[chan->channel] = preset;
 
        /* Reset Byte Pointer */
@@ -264,6 +288,8 @@ static ssize_t quad8_write_preset(struct iio_dev *indio_dev, uintptr_t private,
        for (i = 0; i < 3; i++)
                outb(preset >> (8 * i), base_offset);
 
+       mutex_unlock(&priv->lock);
+
        return len;
 }
 
@@ -293,6 +319,8 @@ static ssize_t quad8_write_set_to_preset_on_index(struct iio_dev *indio_dev,
        /* Preset enable is active low in Input/Output Control register */
        preset_enable = !preset_enable;
 
+       mutex_lock(&priv->lock);
+
        priv->preset_enable[chan->channel] = preset_enable;
 
        ior_cfg = priv->ab_enable[chan->channel] |
@@ -301,6 +329,8 @@ static ssize_t quad8_write_set_to_preset_on_index(struct iio_dev *indio_dev,
        /* Load I/O control configuration to Input / Output Control Register */
        outb(QUAD8_CTR_IOR | ior_cfg, base_offset);
 
+       mutex_unlock(&priv->lock);
+
        return len;
 }
 
@@ -358,6 +388,8 @@ static int quad8_set_count_mode(struct iio_dev *indio_dev,
        unsigned int mode_cfg = cnt_mode << 1;
        const int base_offset = priv->base + 2 * chan->channel + 1;
 
+       mutex_lock(&priv->lock);
+
        priv->count_mode[chan->channel] = cnt_mode;
 
        /* Add quadrature mode configuration */
@@ -367,6 +399,8 @@ static int quad8_set_count_mode(struct iio_dev *indio_dev,
        /* Load mode configuration to Counter Mode Register */
        outb(QUAD8_CTR_CMR | mode_cfg, base_offset);
 
+       mutex_unlock(&priv->lock);
+
        return 0;
 }
 
@@ -394,19 +428,26 @@ static int quad8_set_synchronous_mode(struct iio_dev *indio_dev,
        const struct iio_chan_spec *chan, unsigned int synchronous_mode)
 {
        struct quad8_iio *const priv = iio_priv(indio_dev);
-       const unsigned int idr_cfg = synchronous_mode |
-               priv->index_polarity[chan->channel] << 1;
        const int base_offset = priv->base + 2 * chan->channel + 1;
+       unsigned int idr_cfg = synchronous_mode;
+
+       mutex_lock(&priv->lock);
+
+       idr_cfg |= priv->index_polarity[chan->channel] << 1;
 
        /* Index function must be non-synchronous in non-quadrature mode */
-       if (synchronous_mode && !priv->quadrature_mode[chan->channel])
+       if (synchronous_mode && !priv->quadrature_mode[chan->channel]) {
+               mutex_unlock(&priv->lock);
                return -EINVAL;
+       }
 
        priv->synchronous_mode[chan->channel] = synchronous_mode;
 
        /* Load Index Control configuration to Index Control Register */
        outb(QUAD8_CTR_IDR | idr_cfg, base_offset);
 
+       mutex_unlock(&priv->lock);
+
        return 0;
 }
 
@@ -434,8 +475,12 @@ static int quad8_set_quadrature_mode(struct iio_dev *indio_dev,
        const struct iio_chan_spec *chan, unsigned int quadrature_mode)
 {
        struct quad8_iio *const priv = iio_priv(indio_dev);
-       unsigned int mode_cfg = priv->count_mode[chan->channel] << 1;
        const int base_offset = priv->base + 2 * chan->channel + 1;
+       unsigned int mode_cfg;
+
+       mutex_lock(&priv->lock);
+
+       mode_cfg = priv->count_mode[chan->channel] << 1;
 
        if (quadrature_mode)
                mode_cfg |= (priv->quadrature_scale[chan->channel] + 1) << 3;
@@ -453,6 +498,8 @@ static int quad8_set_quadrature_mode(struct iio_dev *indio_dev,
        /* Load mode configuration to Counter Mode Register */
        outb(QUAD8_CTR_CMR | mode_cfg, base_offset);
 
+       mutex_unlock(&priv->lock);
+
        return 0;
 }
 
@@ -480,15 +527,20 @@ static int quad8_set_index_polarity(struct iio_dev *indio_dev,
        const struct iio_chan_spec *chan, unsigned int index_polarity)
 {
        struct quad8_iio *const priv = iio_priv(indio_dev);
-       const unsigned int idr_cfg = priv->synchronous_mode[chan->channel] |
-               index_polarity << 1;
        const int base_offset = priv->base + 2 * chan->channel + 1;
+       unsigned int idr_cfg = index_polarity << 1;
+
+       mutex_lock(&priv->lock);
+
+       idr_cfg |= priv->synchronous_mode[chan->channel];
 
        priv->index_polarity[chan->channel] = index_polarity;
 
        /* Load Index Control configuration to Index Control Register */
        outb(QUAD8_CTR_IDR | idr_cfg, base_offset);
 
+       mutex_unlock(&priv->lock);
+
        return 0;
 }
 
@@ -589,7 +641,7 @@ static int quad8_signal_read(struct counter_device *counter,
 static int quad8_count_read(struct counter_device *counter,
        struct counter_count *count, unsigned long *val)
 {
-       const struct quad8_iio *const priv = counter->priv;
+       struct quad8_iio *const priv = counter->priv;
        const int base_offset = priv->base + 2 * count->id;
        unsigned int flags;
        unsigned int borrow;
@@ -603,6 +655,8 @@ static int quad8_count_read(struct counter_device *counter,
        /* Borrow XOR Carry effectively doubles count range */
        *val = (unsigned long)(borrow ^ carry) << 24;
 
+       mutex_lock(&priv->lock);
+
        /* Reset Byte Pointer; transfer Counter to Output Latch */
        outb(QUAD8_CTR_RLD | QUAD8_RLD_RESET_BP | QUAD8_RLD_CNTR_OUT,
             base_offset + 1);
@@ -610,13 +664,15 @@ static int quad8_count_read(struct counter_device *counter,
        for (i = 0; i < 3; i++)
                *val |= (unsigned long)inb(base_offset) << (8 * i);
 
+       mutex_unlock(&priv->lock);
+
        return 0;
 }
 
 static int quad8_count_write(struct counter_device *counter,
        struct counter_count *count, unsigned long val)
 {
-       const struct quad8_iio *const priv = counter->priv;
+       struct quad8_iio *const priv = counter->priv;
        const int base_offset = priv->base + 2 * count->id;
        int i;
 
@@ -624,6 +680,8 @@ static int quad8_count_write(struct counter_device *counter,
        if (val > 0xFFFFFF)
                return -EINVAL;
 
+       mutex_lock(&priv->lock);
+
        /* Reset Byte Pointer */
        outb(QUAD8_CTR_RLD | QUAD8_RLD_RESET_BP, base_offset + 1);
 
@@ -647,6 +705,8 @@ static int quad8_count_write(struct counter_device *counter,
        /* Reset Error flag */
        outb(QUAD8_CTR_RLD | QUAD8_RLD_RESET_E, base_offset + 1);
 
+       mutex_unlock(&priv->lock);
+
        return 0;
 }
 
@@ -667,13 +727,13 @@ static enum counter_count_function quad8_count_functions_list[] = {
 static int quad8_function_get(struct counter_device *counter,
        struct counter_count *count, size_t *function)
 {
-       const struct quad8_iio *const priv = counter->priv;
+       struct quad8_iio *const priv = counter->priv;
        const int id = count->id;
-       const unsigned int quadrature_mode = priv->quadrature_mode[id];
-       const unsigned int scale = priv->quadrature_scale[id];
 
-       if (quadrature_mode)
-               switch (scale) {
+       mutex_lock(&priv->lock);
+
+       if (priv->quadrature_mode[id])
+               switch (priv->quadrature_scale[id]) {
                case 0:
                        *function = QUAD8_COUNT_FUNCTION_QUADRATURE_X1;
                        break;
@@ -687,6 +747,8 @@ static int quad8_function_get(struct counter_device *counter,
        else
                *function = QUAD8_COUNT_FUNCTION_PULSE_DIRECTION;
 
+       mutex_unlock(&priv->lock);
+
        return 0;
 }
 
@@ -697,10 +759,15 @@ static int quad8_function_set(struct counter_device *counter,
        const int id = count->id;
        unsigned int *const quadrature_mode = priv->quadrature_mode + id;
        unsigned int *const scale = priv->quadrature_scale + id;
-       unsigned int mode_cfg = priv->count_mode[id] << 1;
        unsigned int *const synchronous_mode = priv->synchronous_mode + id;
-       const unsigned int idr_cfg = priv->index_polarity[id] << 1;
        const int base_offset = priv->base + 2 * id + 1;
+       unsigned int mode_cfg;
+       unsigned int idr_cfg;
+
+       mutex_lock(&priv->lock);
+
+       mode_cfg = priv->count_mode[id] << 1;
+       idr_cfg = priv->index_polarity[id] << 1;
 
        if (function == QUAD8_COUNT_FUNCTION_PULSE_DIRECTION) {
                *quadrature_mode = 0;
@@ -736,6 +803,8 @@ static int quad8_function_set(struct counter_device *counter,
        /* Load mode configuration to Counter Mode Register */
        outb(QUAD8_CTR_CMR | mode_cfg, base_offset);
 
+       mutex_unlock(&priv->lock);
+
        return 0;
 }
 
@@ -852,15 +921,20 @@ static int quad8_index_polarity_set(struct counter_device *counter,
 {
        struct quad8_iio *const priv = counter->priv;
        const size_t channel_id = signal->id - 16;
-       const unsigned int idr_cfg = priv->synchronous_mode[channel_id] |
-               index_polarity << 1;
        const int base_offset = priv->base + 2 * channel_id + 1;
+       unsigned int idr_cfg = index_polarity << 1;
+
+       mutex_lock(&priv->lock);
+
+       idr_cfg |= priv->synchronous_mode[channel_id];
 
        priv->index_polarity[channel_id] = index_polarity;
 
        /* Load Index Control configuration to Index Control Register */
        outb(QUAD8_CTR_IDR | idr_cfg, base_offset);
 
+       mutex_unlock(&priv->lock);
+
        return 0;
 }
 
@@ -887,19 +961,26 @@ static int quad8_synchronous_mode_set(struct counter_device *counter,
 {
        struct quad8_iio *const priv = counter->priv;
        const size_t channel_id = signal->id - 16;
-       const unsigned int idr_cfg = synchronous_mode |
-               priv->index_polarity[channel_id] << 1;
        const int base_offset = priv->base + 2 * channel_id + 1;
+       unsigned int idr_cfg = synchronous_mode;
+
+       mutex_lock(&priv->lock);
+
+       idr_cfg |= priv->index_polarity[channel_id] << 1;
 
        /* Index function must be non-synchronous in non-quadrature mode */
-       if (synchronous_mode && !priv->quadrature_mode[channel_id])
+       if (synchronous_mode && !priv->quadrature_mode[channel_id]) {
+               mutex_unlock(&priv->lock);
                return -EINVAL;
+       }
 
        priv->synchronous_mode[channel_id] = synchronous_mode;
 
        /* Load Index Control configuration to Index Control Register */
        outb(QUAD8_CTR_IDR | idr_cfg, base_offset);
 
+       mutex_unlock(&priv->lock);
+
        return 0;
 }
 
@@ -964,6 +1045,8 @@ static int quad8_count_mode_set(struct counter_device *counter,
                break;
        }
 
+       mutex_lock(&priv->lock);
+
        priv->count_mode[count->id] = cnt_mode;
 
        /* Set count mode configuration value */
@@ -976,6 +1059,8 @@ static int quad8_count_mode_set(struct counter_device *counter,
        /* Load mode configuration to Counter Mode Register */
        outb(QUAD8_CTR_CMR | mode_cfg, base_offset);
 
+       mutex_unlock(&priv->lock);
+
        return 0;
 }
 
@@ -1017,6 +1102,8 @@ static ssize_t quad8_count_enable_write(struct counter_device *counter,
        if (err)
                return err;
 
+       mutex_lock(&priv->lock);
+
        priv->ab_enable[count->id] = ab_enable;
 
        ior_cfg = ab_enable | priv->preset_enable[count->id] << 1;
@@ -1024,6 +1111,8 @@ static ssize_t quad8_count_enable_write(struct counter_device *counter,
        /* Load I/O control configuration */
        outb(QUAD8_CTR_IOR | ior_cfg, base_offset + 1);
 
+       mutex_unlock(&priv->lock);
+
        return len;
 }
 
@@ -1052,14 +1141,28 @@ static ssize_t quad8_count_preset_read(struct counter_device *counter,
        return sprintf(buf, "%u\n", priv->preset[count->id]);
 }
 
+static void quad8_preset_register_set(struct quad8_iio *quad8iio, int id,
+               unsigned int preset)
+{
+       const unsigned int base_offset = quad8iio->base + 2 * id;
+       int i;
+
+       quad8iio->preset[id] = preset;
+
+       /* Reset Byte Pointer */
+       outb(QUAD8_CTR_RLD | QUAD8_RLD_RESET_BP, base_offset + 1);
+
+       /* Set Preset Register */
+       for (i = 0; i < 3; i++)
+               outb(preset >> (8 * i), base_offset);
+}
+
 static ssize_t quad8_count_preset_write(struct counter_device *counter,
        struct counter_count *count, void *private, const char *buf, size_t len)
 {
        struct quad8_iio *const priv = counter->priv;
-       const int base_offset = priv->base + 2 * count->id;
        unsigned int preset;
        int ret;
-       int i;
 
        ret = kstrtouint(buf, 0, &preset);
        if (ret)
@@ -1069,14 +1172,11 @@ static ssize_t quad8_count_preset_write(struct counter_device *counter,
        if (preset > 0xFFFFFF)
                return -EINVAL;
 
-       priv->preset[count->id] = preset;
+       mutex_lock(&priv->lock);
 
-       /* Reset Byte Pointer */
-       outb(QUAD8_CTR_RLD | QUAD8_RLD_RESET_BP, base_offset + 1);
+       quad8_preset_register_set(priv, count->id, preset);
 
-       /* Set Preset Register */
-       for (i = 0; i < 3; i++)
-               outb(preset >> (8 * i), base_offset);
+       mutex_unlock(&priv->lock);
 
        return len;
 }
@@ -1084,15 +1184,20 @@ static ssize_t quad8_count_preset_write(struct counter_device *counter,
 static ssize_t quad8_count_ceiling_read(struct counter_device *counter,
        struct counter_count *count, void *private, char *buf)
 {
-       const struct quad8_iio *const priv = counter->priv;
+       struct quad8_iio *const priv = counter->priv;
+
+       mutex_lock(&priv->lock);
 
        /* Range Limit and Modulo-N count modes use preset value as ceiling */
        switch (priv->count_mode[count->id]) {
        case 1:
        case 3:
-               return quad8_count_preset_read(counter, count, private, buf);
+               mutex_unlock(&priv->lock);
+               return sprintf(buf, "%u\n", priv->preset[count->id]);
        }
 
+       mutex_unlock(&priv->lock);
+
        /* By default 0x1FFFFFF (25 bits unsigned) is maximum count */
        return sprintf(buf, "33554431\n");
 }
@@ -1101,15 +1206,29 @@ static ssize_t quad8_count_ceiling_write(struct counter_device *counter,
        struct counter_count *count, void *private, const char *buf, size_t len)
 {
        struct quad8_iio *const priv = counter->priv;
+       unsigned int ceiling;
+       int ret;
+
+       ret = kstrtouint(buf, 0, &ceiling);
+       if (ret)
+               return ret;
+
+       /* Only 24-bit values are supported */
+       if (ceiling > 0xFFFFFF)
+               return -EINVAL;
+
+       mutex_lock(&priv->lock);
 
        /* Range Limit and Modulo-N count modes use preset value as ceiling */
        switch (priv->count_mode[count->id]) {
        case 1:
        case 3:
-               return quad8_count_preset_write(counter, count, private, buf,
-                                               len);
+               quad8_preset_register_set(priv, count->id, ceiling);
+               break;
        }
 
+       mutex_unlock(&priv->lock);
+
        return len;
 }
 
@@ -1137,6 +1256,8 @@ static ssize_t quad8_count_preset_enable_write(struct counter_device *counter,
        /* Preset enable is active low in Input/Output Control register */
        preset_enable = !preset_enable;
 
+       mutex_lock(&priv->lock);
+
        priv->preset_enable[count->id] = preset_enable;
 
        ior_cfg = priv->ab_enable[count->id] | (unsigned int)preset_enable << 1;
@@ -1144,6 +1265,8 @@ static ssize_t quad8_count_preset_enable_write(struct counter_device *counter,
        /* Load I/O control configuration to Input / Output Control Register */
        outb(QUAD8_CTR_IOR | ior_cfg, base_offset);
 
+       mutex_unlock(&priv->lock);
+
        return len;
 }
 
@@ -1429,6 +1552,9 @@ static int quad8_probe(struct device *dev, unsigned int id)
        quad8iio->counter.priv = quad8iio;
        quad8iio->base = base[id];
 
+       /* Initialize mutex */
+       mutex_init(&quad8iio->lock);
+
        /* Reset all counters and disable interrupt function */
        outb(QUAD8_CHAN_OP_RESET_COUNTERS, base[id] + QUAD8_REG_CHAN_OP);
        /* Set initial configuration for all counters */
index b7bb7c30adeb823d92fd5f233d40e0ba644f0afa..b2f9882bc010f1619b0e17eb2204caaecf41895c 100644 (file)
@@ -963,10 +963,12 @@ static void aead_crypt_done(struct device *jrdev, u32 *desc, u32 err,
        struct caam_drv_private_jr *jrp = dev_get_drvdata(jrdev);
        struct aead_edesc *edesc;
        int ecode = 0;
+       bool has_bklog;
 
        dev_dbg(jrdev, "%s %d: err 0x%x\n", __func__, __LINE__, err);
 
        edesc = rctx->edesc;
+       has_bklog = edesc->bklog;
 
        if (err)
                ecode = caam_jr_strstatus(jrdev, err);
@@ -979,7 +981,7 @@ static void aead_crypt_done(struct device *jrdev, u32 *desc, u32 err,
         * If no backlog flag, the completion of the request is done
         * by CAAM, not crypto engine.
         */
-       if (!edesc->bklog)
+       if (!has_bklog)
                aead_request_complete(req, ecode);
        else
                crypto_finalize_aead_request(jrp->engine, req, ecode);
@@ -995,10 +997,12 @@ static void skcipher_crypt_done(struct device *jrdev, u32 *desc, u32 err,
        struct caam_drv_private_jr *jrp = dev_get_drvdata(jrdev);
        int ivsize = crypto_skcipher_ivsize(skcipher);
        int ecode = 0;
+       bool has_bklog;
 
        dev_dbg(jrdev, "%s %d: err 0x%x\n", __func__, __LINE__, err);
 
        edesc = rctx->edesc;
+       has_bklog = edesc->bklog;
        if (err)
                ecode = caam_jr_strstatus(jrdev, err);
 
@@ -1028,7 +1032,7 @@ static void skcipher_crypt_done(struct device *jrdev, u32 *desc, u32 err,
         * If no backlog flag, the completion of the request is done
         * by CAAM, not crypto engine.
         */
-       if (!edesc->bklog)
+       if (!has_bklog)
                skcipher_request_complete(req, ecode);
        else
                crypto_finalize_skcipher_request(jrp->engine, req, ecode);
@@ -1711,7 +1715,7 @@ static struct skcipher_edesc *skcipher_edesc_alloc(struct skcipher_request *req,
 
        if (ivsize || mapped_dst_nents > 1)
                sg_to_sec4_set_last(edesc->sec4_sg + dst_sg_idx +
-                                   mapped_dst_nents);
+                                   mapped_dst_nents - 1 + !!ivsize);
 
        if (sec4_sg_bytes) {
                edesc->sec4_sg_dma = dma_map_single(jrdev, edesc->sec4_sg,
index 943bc0296267d3a751c5493358a2a291ff3b5af2..27ff4a3d037ee6927f5a44c1072bdb7f266c933b 100644 (file)
@@ -583,10 +583,12 @@ static inline void ahash_done_cpy(struct device *jrdev, u32 *desc, u32 err,
        struct caam_hash_state *state = ahash_request_ctx(req);
        struct caam_hash_ctx *ctx = crypto_ahash_ctx(ahash);
        int ecode = 0;
+       bool has_bklog;
 
        dev_dbg(jrdev, "%s %d: err 0x%x\n", __func__, __LINE__, err);
 
        edesc = state->edesc;
+       has_bklog = edesc->bklog;
 
        if (err)
                ecode = caam_jr_strstatus(jrdev, err);
@@ -603,7 +605,7 @@ static inline void ahash_done_cpy(struct device *jrdev, u32 *desc, u32 err,
         * If no backlog flag, the completion of the request is done
         * by CAAM, not crypto engine.
         */
-       if (!edesc->bklog)
+       if (!has_bklog)
                req->base.complete(&req->base, ecode);
        else
                crypto_finalize_hash_request(jrp->engine, req, ecode);
@@ -632,10 +634,12 @@ static inline void ahash_done_switch(struct device *jrdev, u32 *desc, u32 err,
        struct caam_hash_state *state = ahash_request_ctx(req);
        int digestsize = crypto_ahash_digestsize(ahash);
        int ecode = 0;
+       bool has_bklog;
 
        dev_dbg(jrdev, "%s %d: err 0x%x\n", __func__, __LINE__, err);
 
        edesc = state->edesc;
+       has_bklog = edesc->bklog;
        if (err)
                ecode = caam_jr_strstatus(jrdev, err);
 
@@ -663,7 +667,7 @@ static inline void ahash_done_switch(struct device *jrdev, u32 *desc, u32 err,
         * If no backlog flag, the completion of the request is done
         * by CAAM, not crypto engine.
         */
-       if (!edesc->bklog)
+       if (!has_bklog)
                req->base.complete(&req->base, ecode);
        else
                crypto_finalize_hash_request(jrp->engine, req, ecode);
index 4fcae37a2e33c1943c99b2945ea7703233d155c2..2e44d685618fded647b016c6a4e250ae40971032 100644 (file)
@@ -121,11 +121,13 @@ static void rsa_pub_done(struct device *dev, u32 *desc, u32 err, void *context)
        struct caam_drv_private_jr *jrp = dev_get_drvdata(dev);
        struct rsa_edesc *edesc;
        int ecode = 0;
+       bool has_bklog;
 
        if (err)
                ecode = caam_jr_strstatus(dev, err);
 
        edesc = req_ctx->edesc;
+       has_bklog = edesc->bklog;
 
        rsa_pub_unmap(dev, edesc, req);
        rsa_io_unmap(dev, edesc, req);
@@ -135,7 +137,7 @@ static void rsa_pub_done(struct device *dev, u32 *desc, u32 err, void *context)
         * If no backlog flag, the completion of the request is done
         * by CAAM, not crypto engine.
         */
-       if (!edesc->bklog)
+       if (!has_bklog)
                akcipher_request_complete(req, ecode);
        else
                crypto_finalize_akcipher_request(jrp->engine, req, ecode);
@@ -152,11 +154,13 @@ static void rsa_priv_f_done(struct device *dev, u32 *desc, u32 err,
        struct caam_rsa_req_ctx *req_ctx = akcipher_request_ctx(req);
        struct rsa_edesc *edesc;
        int ecode = 0;
+       bool has_bklog;
 
        if (err)
                ecode = caam_jr_strstatus(dev, err);
 
        edesc = req_ctx->edesc;
+       has_bklog = edesc->bklog;
 
        switch (key->priv_form) {
        case FORM1:
@@ -176,7 +180,7 @@ static void rsa_priv_f_done(struct device *dev, u32 *desc, u32 err,
         * If no backlog flag, the completion of the request is done
         * by CAAM, not crypto engine.
         */
-       if (!edesc->bklog)
+       if (!has_bklog)
                akcipher_request_complete(req, ecode);
        else
                crypto_finalize_akcipher_request(jrp->engine, req, ecode);
index cd1769ecdc1cc99b68fa9b50bd329621d6be320e..e92b352fb0ad6885f75b900e0d36e46e33c9b4dd 100644 (file)
@@ -120,12 +120,10 @@ out:
 static int chcr_ktls_update_connection_state(struct chcr_ktls_info *tx_info,
                                             int new_state)
 {
-       unsigned long flags;
-
        /* This function can be called from both rx (interrupt context) and tx
         * queue contexts.
         */
-       spin_lock_irqsave(&tx_info->lock, flags);
+       spin_lock_bh(&tx_info->lock);
        switch (tx_info->connection_state) {
        case KTLS_CONN_CLOSED:
                tx_info->connection_state = new_state;
@@ -169,7 +167,7 @@ static int chcr_ktls_update_connection_state(struct chcr_ktls_info *tx_info,
                pr_err("unknown KTLS connection state\n");
                break;
        }
-       spin_unlock_irqrestore(&tx_info->lock, flags);
+       spin_unlock_bh(&tx_info->lock);
 
        return tx_info->connection_state;
 }
index 116707a075f35b234076f5f7798a6b281f27e4ae..1d2e5b85d7ca8458f3d67bac38b964f4f9100ef6 100644 (file)
@@ -12,7 +12,7 @@ config IMX_DSP
 
 config IMX_SCU
        bool "IMX SCU Protocol driver"
-       depends on IMX_MBOX || COMPILE_TEST
+       depends on IMX_MBOX
        help
          The System Controller Firmware (SCFW) is a low-level system function
          which runs on a dedicated Cortex-M core to provide power, clock, and
@@ -24,6 +24,6 @@ config IMX_SCU
 
 config IMX_SCU_PD
        bool "IMX SCU Power Domain driver"
-       depends on IMX_SCU || COMPILE_TEST
+       depends on IMX_SCU
        help
          The System Controller Firmware (SCFW) based power domain driver.
index c6d0724da4dbca771174984efa414170fdd426c3..43bc6cfdab45ea3a8803870c183c5e8264652a0c 100644 (file)
@@ -35,7 +35,7 @@ static struct pm_api_info pm_api_list[] = {
        PM_API(PM_QUERY_DATA),
 };
 
-struct dentry *firmware_debugfs_root;
+static struct dentry *firmware_debugfs_root;
 
 /**
  * zynqmp_pm_argument_value() - Extract argument value from a PM-API request
index 89ca292236ad8655ea582b72d264e4bf1bde8aa5..538755062ab7ca7d8fee6911ca2af02a8afc7a37 100644 (file)
@@ -248,11 +248,13 @@ static int cci_pci_sriov_configure(struct pci_dev *pcidev, int num_vfs)
                        return ret;
 
                ret = pci_enable_sriov(pcidev, num_vfs);
-               if (ret)
+               if (ret) {
                        dfl_fpga_cdev_config_ports_pf(cdev);
+                       return ret;
+               }
        }
 
-       return ret;
+       return num_vfs;
 }
 
 static void cci_pci_remove(struct pci_dev *pcidev)
index ee7765049607453933c5e4541ba3751a3bc02b03..07fa8d9ec67500586878267c2cd7ee541ceeeefd 100644 (file)
@@ -583,7 +583,8 @@ static int zynq_fpga_probe(struct platform_device *pdev)
 
        priv->clk = devm_clk_get(dev, "ref_clk");
        if (IS_ERR(priv->clk)) {
-               dev_err(dev, "input clock not found\n");
+               if (PTR_ERR(priv->clk) != -EPROBE_DEFER)
+                       dev_err(dev, "input clock not found\n");
                return PTR_ERR(priv->clk);
        }
 
index f7c5cdc10a705b1b78cfb074596649f55d831639..c5ba5d46a1485b4bee4eb7cf3b5b87f141c9dff4 100644 (file)
@@ -4664,6 +4664,7 @@ static void amdgpu_dm_connector_destroy(struct drm_connector *connector)
                i2c_del_adapter(&aconnector->i2c->base);
                kfree(aconnector->i2c);
        }
+       kfree(aconnector->dm_dp_aux.aux.name);
 
        kfree(connector);
 }
@@ -4723,10 +4724,19 @@ amdgpu_dm_connector_atomic_duplicate_state(struct drm_connector *connector)
 static int
 amdgpu_dm_connector_late_register(struct drm_connector *connector)
 {
-#if defined(CONFIG_DEBUG_FS)
        struct amdgpu_dm_connector *amdgpu_dm_connector =
                to_amdgpu_dm_connector(connector);
+       int r;
 
+       if ((connector->connector_type == DRM_MODE_CONNECTOR_DisplayPort) ||
+           (connector->connector_type == DRM_MODE_CONNECTOR_eDP)) {
+               amdgpu_dm_connector->dm_dp_aux.aux.dev = connector->kdev;
+               r = drm_dp_aux_register(&amdgpu_dm_connector->dm_dp_aux.aux);
+               if (r)
+                       return r;
+       }
+
+#if defined(CONFIG_DEBUG_FS)
        connector_debugfs_init(amdgpu_dm_connector);
 #endif
 
@@ -6092,7 +6102,7 @@ static int amdgpu_dm_connector_init(struct amdgpu_display_manager *dm,
 
        if (connector_type == DRM_MODE_CONNECTOR_DisplayPort
                || connector_type == DRM_MODE_CONNECTOR_eDP)
-               amdgpu_dm_initialize_dp_connector(dm, aconnector);
+               amdgpu_dm_initialize_dp_connector(dm, aconnector, link->link_index);
 
 out_free:
        if (res) {
index fabbe78d5aefeefc6f933aef4deadc4f486b1157..d2917759b7ab1b70abdea458e5c8d97c16e0a344 100644 (file)
@@ -156,16 +156,16 @@ amdgpu_dm_mst_connector_late_register(struct drm_connector *connector)
                to_amdgpu_dm_connector(connector);
        int r;
 
-       amdgpu_dm_connector->dm_dp_aux.aux.dev = connector->kdev;
-       r = drm_dp_aux_register(&amdgpu_dm_connector->dm_dp_aux.aux);
-       if (r)
+       r = drm_dp_mst_connector_late_register(connector,
+                                              amdgpu_dm_connector->port);
+       if (r < 0)
                return r;
 
 #if defined(CONFIG_DEBUG_FS)
        connector_debugfs_init(amdgpu_dm_connector);
 #endif
 
-       return r;
+       return 0;
 }
 
 static void
@@ -472,9 +472,12 @@ static const struct drm_dp_mst_topology_cbs dm_mst_cbs = {
 };
 
 void amdgpu_dm_initialize_dp_connector(struct amdgpu_display_manager *dm,
-                                      struct amdgpu_dm_connector *aconnector)
+                                      struct amdgpu_dm_connector *aconnector,
+                                      int link_index)
 {
-       aconnector->dm_dp_aux.aux.name = "dmdc";
+       aconnector->dm_dp_aux.aux.name =
+               kasprintf(GFP_KERNEL, "AMDGPU DM aux hw bus %d",
+                         link_index);
        aconnector->dm_dp_aux.aux.transfer = dm_dp_aux_transfer;
        aconnector->dm_dp_aux.ddc_service = aconnector->dc_link->ddc;
 
index d6813ce67bbd36844b5af0ac235b7190e8164a44..d2c56579a2cc412a3074ba0a089f29b891492c77 100644 (file)
@@ -32,7 +32,8 @@ struct amdgpu_dm_connector;
 int dm_mst_get_pbn_divider(struct dc_link *link);
 
 void amdgpu_dm_initialize_dp_connector(struct amdgpu_display_manager *dm,
-                                      struct amdgpu_dm_connector *aconnector);
+                                      struct amdgpu_dm_connector *aconnector,
+                                      int link_index);
 
 #if defined(CONFIG_DRM_AMD_DC_DCN)
 bool compute_mst_dsc_configs_for_state(struct drm_atomic_state *state,
index 77c14671866c07f159729b82e31ec1779b7d4f45..719597c5d27d98e070b202fffd31d4413b994fa9 100644 (file)
@@ -984,6 +984,32 @@ static int init_thermal_controller(
                        struct pp_hwmgr *hwmgr,
                        const ATOM_PPLIB_POWERPLAYTABLE *powerplay_table)
 {
+       hwmgr->thermal_controller.ucType =
+                       powerplay_table->sThermalController.ucType;
+       hwmgr->thermal_controller.ucI2cLine =
+                       powerplay_table->sThermalController.ucI2cLine;
+       hwmgr->thermal_controller.ucI2cAddress =
+                       powerplay_table->sThermalController.ucI2cAddress;
+
+       hwmgr->thermal_controller.fanInfo.bNoFan =
+               (0 != (powerplay_table->sThermalController.ucFanParameters &
+                       ATOM_PP_FANPARAMETERS_NOFAN));
+
+       hwmgr->thermal_controller.fanInfo.ucTachometerPulsesPerRevolution =
+               powerplay_table->sThermalController.ucFanParameters &
+               ATOM_PP_FANPARAMETERS_TACHOMETER_PULSES_PER_REVOLUTION_MASK;
+
+       hwmgr->thermal_controller.fanInfo.ulMinRPM
+               = powerplay_table->sThermalController.ucFanMinRPM * 100UL;
+       hwmgr->thermal_controller.fanInfo.ulMaxRPM
+               = powerplay_table->sThermalController.ucFanMaxRPM * 100UL;
+
+       set_hw_cap(hwmgr,
+                  ATOM_PP_THERMALCONTROLLER_NONE != hwmgr->thermal_controller.ucType,
+                  PHM_PlatformCaps_ThermalController);
+
+       hwmgr->thermal_controller.use_hw_fan_control = 1;
+
        return 0;
 }
 
index ff73a735b8882a4844ac87dda3ca75588e6fe453..b0ed1b3fe79a351a82ab984aac7ccee57aff89fd 100644 (file)
@@ -895,12 +895,17 @@ static int renoir_read_sensor(struct smu_context *smu,
 
 static bool renoir_is_dpm_running(struct smu_context *smu)
 {
+       struct amdgpu_device *adev = smu->adev;
+
        /*
         * Util now, the pmfw hasn't exported the interface of SMU
         * feature mask to APU SKU so just force on all the feature
         * at early initial stage.
         */
-       return true;
+       if (adev->in_suspend)
+               return false;
+       else
+               return true;
 
 }
 
index 2bc6e4f85171697a9fb7ff29831eb5316bba05af..9af39ec958db5eade1a8bdb786381753b6fd7d3b 100644 (file)
@@ -485,6 +485,9 @@ static int anx6345_get_modes(struct drm_connector *connector)
 
        num_modes += drm_add_edid_modes(connector, anx6345->edid);
 
+       /* Driver currently supports only 6bpc */
+       connector->display_info.bpc = 6;
+
 unlock:
        if (power_off)
                anx6345_poweroff(anx6345);
index 70c4b7afed12494951da8fdaa0132733e87ad8bf..283615e448386606183f75983b14a49ca3cc86ae 100644 (file)
@@ -4295,6 +4295,7 @@ int drm_dp_atomic_release_vcpi_slots(struct drm_atomic_state *state,
        if (pos->vcpi) {
                drm_dp_mst_put_port_malloc(port);
                pos->vcpi = 0;
+               pos->pbn = 0;
        }
 
        return 0;
index 2c617c98db3a4b12bcf96721f6032b76d9bc3f6f..52db7852827bfddc8c2b732fd00c8e5aedb09ee8 100644 (file)
@@ -3141,9 +3141,6 @@ static void hsw_ddi_pre_enable_dp(struct intel_encoder *encoder,
        intel_dp_set_link_params(intel_dp, crtc_state->port_clock,
                                 crtc_state->lane_count, is_mst);
 
-       intel_dp->regs.dp_tp_ctl = DP_TP_CTL(port);
-       intel_dp->regs.dp_tp_status = DP_TP_STATUS(port);
-
        intel_edp_panel_on(intel_dp);
 
        intel_ddi_clk_select(encoder, crtc_state);
@@ -3848,12 +3845,18 @@ void intel_ddi_get_config(struct intel_encoder *encoder,
        struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
        struct intel_crtc *intel_crtc = to_intel_crtc(pipe_config->uapi.crtc);
        enum transcoder cpu_transcoder = pipe_config->cpu_transcoder;
+       struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
        u32 temp, flags = 0;
 
        /* XXX: DSI transcoder paranoia */
        if (drm_WARN_ON(&dev_priv->drm, transcoder_is_dsi(cpu_transcoder)))
                return;
 
+       if (INTEL_GEN(dev_priv) >= 12) {
+               intel_dp->regs.dp_tp_ctl = TGL_DP_TP_CTL(cpu_transcoder);
+               intel_dp->regs.dp_tp_status = TGL_DP_TP_STATUS(cpu_transcoder);
+       }
+
        intel_dsc_get_config(encoder, pipe_config);
 
        temp = intel_de_read(dev_priv, TRANS_DDI_FUNC_CTL(cpu_transcoder));
@@ -4173,6 +4176,7 @@ static const struct drm_encoder_funcs intel_ddi_funcs = {
 static struct intel_connector *
 intel_ddi_init_dp_connector(struct intel_digital_port *intel_dig_port)
 {
+       struct drm_i915_private *dev_priv = to_i915(intel_dig_port->base.base.dev);
        struct intel_connector *connector;
        enum port port = intel_dig_port->base.port;
 
@@ -4183,6 +4187,10 @@ intel_ddi_init_dp_connector(struct intel_digital_port *intel_dig_port)
        intel_dig_port->dp.output_reg = DDI_BUF_CTL(port);
        intel_dig_port->dp.prepare_link_retrain =
                intel_ddi_prepare_link_retrain;
+       if (INTEL_GEN(dev_priv) < 12) {
+               intel_dig_port->dp.regs.dp_tp_ctl = DP_TP_CTL(port);
+               intel_dig_port->dp.regs.dp_tp_status = DP_TP_STATUS(port);
+       }
 
        if (!intel_dp_init_connector(intel_dig_port, connector)) {
                kfree(connector);
index 246e406bb385edbcf0d44d1c970c037136eff2b5..84ecf8e58523d4e9a60bcd03c834e1d39b968e54 100644 (file)
@@ -4140,7 +4140,7 @@ static const struct i915_power_well_desc tgl_power_wells[] = {
        {
                .name = "AUX D TBT1",
                .domains = TGL_AUX_D_TBT1_IO_POWER_DOMAINS,
-               .ops = &hsw_power_well_ops,
+               .ops = &icl_tc_phy_aux_power_well_ops,
                .id = DISP_PW_ID_NONE,
                {
                        .hsw.regs = &icl_aux_power_well_regs,
@@ -4151,7 +4151,7 @@ static const struct i915_power_well_desc tgl_power_wells[] = {
        {
                .name = "AUX E TBT2",
                .domains = TGL_AUX_E_TBT2_IO_POWER_DOMAINS,
-               .ops = &hsw_power_well_ops,
+               .ops = &icl_tc_phy_aux_power_well_ops,
                .id = DISP_PW_ID_NONE,
                {
                        .hsw.regs = &icl_aux_power_well_regs,
@@ -4162,7 +4162,7 @@ static const struct i915_power_well_desc tgl_power_wells[] = {
        {
                .name = "AUX F TBT3",
                .domains = TGL_AUX_F_TBT3_IO_POWER_DOMAINS,
-               .ops = &hsw_power_well_ops,
+               .ops = &icl_tc_phy_aux_power_well_ops,
                .id = DISP_PW_ID_NONE,
                {
                        .hsw.regs = &icl_aux_power_well_regs,
@@ -4173,7 +4173,7 @@ static const struct i915_power_well_desc tgl_power_wells[] = {
        {
                .name = "AUX G TBT4",
                .domains = TGL_AUX_G_TBT4_IO_POWER_DOMAINS,
-               .ops = &hsw_power_well_ops,
+               .ops = &icl_tc_phy_aux_power_well_ops,
                .id = DISP_PW_ID_NONE,
                {
                        .hsw.regs = &icl_aux_power_well_regs,
@@ -4184,7 +4184,7 @@ static const struct i915_power_well_desc tgl_power_wells[] = {
        {
                .name = "AUX H TBT5",
                .domains = TGL_AUX_H_TBT5_IO_POWER_DOMAINS,
-               .ops = &hsw_power_well_ops,
+               .ops = &icl_tc_phy_aux_power_well_ops,
                .id = DISP_PW_ID_NONE,
                {
                        .hsw.regs = &icl_aux_power_well_regs,
@@ -4195,7 +4195,7 @@ static const struct i915_power_well_desc tgl_power_wells[] = {
        {
                .name = "AUX I TBT6",
                .domains = TGL_AUX_I_TBT6_IO_POWER_DOMAINS,
-               .ops = &hsw_power_well_ops,
+               .ops = &icl_tc_phy_aux_power_well_ops,
                .id = DISP_PW_ID_NONE,
                {
                        .hsw.regs = &icl_aux_power_well_regs,
index 804b1d966f66424ebd5fa5601bbb357feec1c0cb..a2fafd4499f2a67d1b2ae2dfd2748d3f38013268 100644 (file)
@@ -2517,9 +2517,6 @@ static void intel_dp_prepare(struct intel_encoder *encoder,
                                 intel_crtc_has_type(pipe_config,
                                                     INTEL_OUTPUT_DP_MST));
 
-       intel_dp->regs.dp_tp_ctl = DP_TP_CTL(port);
-       intel_dp->regs.dp_tp_status = DP_TP_STATUS(port);
-
        /*
         * There are four kinds of DP registers:
         *
@@ -7836,6 +7833,8 @@ bool intel_dp_init(struct drm_i915_private *dev_priv,
 
        intel_dig_port->dp.output_reg = output_reg;
        intel_dig_port->max_lanes = 4;
+       intel_dig_port->dp.regs.dp_tp_ctl = DP_TP_CTL(port);
+       intel_dig_port->dp.regs.dp_tp_status = DP_TP_STATUS(port);
 
        intel_encoder->type = INTEL_OUTPUT_DP;
        intel_encoder->power_domain = intel_port_to_power_domain(port);
index 3e706bb850a8714a91ca8af57ec56a9aeff31190..dbfa6895795b2e067a08ccae65b355bceab21422 100644 (file)
@@ -342,6 +342,7 @@ int intel_dp_aux_init_backlight_funcs(struct intel_connector *intel_connector)
         */
        if (dev_priv->vbt.backlight.type !=
            INTEL_BACKLIGHT_VESA_EDP_AUX_INTERFACE &&
+           i915_modparams.enable_dpcd_backlight != 1 &&
            !drm_dp_has_quirk(&intel_dp->desc, intel_dp->edid_quirks,
                              DP_QUIRK_FORCE_DPCD_BACKLIGHT)) {
                DRM_DEV_INFO(dev->dev,
index 39930232b25323acdd80fa0136ee585da09c80d2..821411b93dacc4a2f36af15667850f735d5426dd 100644 (file)
@@ -1536,7 +1536,8 @@ bool intel_hdmi_hdcp_check_link(struct intel_digital_port *intel_dig_port)
        intel_de_write(i915, HDCP_RPRIME(i915, cpu_transcoder, port), ri.reg);
 
        /* Wait for Ri prime match */
-       if (wait_for(intel_de_read(i915, HDCP_STATUS(i915, cpu_transcoder, port)) &
+       if (wait_for((intel_de_read(i915, HDCP_STATUS(i915, cpu_transcoder, port)) &
+                     (HDCP_STATUS_RI_MATCH | HDCP_STATUS_ENC)) ==
                     (HDCP_STATUS_RI_MATCH | HDCP_STATUS_ENC), 1)) {
                DRM_ERROR("Ri' mismatch detected, link check failed (%x)\n",
                          intel_de_read(i915, HDCP_STATUS(i915, cpu_transcoder, port)));
index deda351719db801551ad000cbe164c0774ae834b..33d8861411382e2b38ebdb30e1c2d6fe0bd0ebce 100644 (file)
@@ -2817,19 +2817,25 @@ static bool skl_plane_format_mod_supported(struct drm_plane *_plane,
        }
 }
 
-static bool gen12_plane_supports_mc_ccs(enum plane_id plane_id)
+static bool gen12_plane_supports_mc_ccs(struct drm_i915_private *dev_priv,
+                                       enum plane_id plane_id)
 {
+       /* Wa_14010477008:tgl[a0..c0] */
+       if (IS_TGL_REVID(dev_priv, TGL_REVID_A0, TGL_REVID_C0))
+               return false;
+
        return plane_id < PLANE_SPRITE4;
 }
 
 static bool gen12_plane_format_mod_supported(struct drm_plane *_plane,
                                             u32 format, u64 modifier)
 {
+       struct drm_i915_private *dev_priv = to_i915(_plane->dev);
        struct intel_plane *plane = to_intel_plane(_plane);
 
        switch (modifier) {
        case I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS:
-               if (!gen12_plane_supports_mc_ccs(plane->id))
+               if (!gen12_plane_supports_mc_ccs(dev_priv, plane->id))
                        return false;
                /* fall through */
        case DRM_FORMAT_MOD_LINEAR:
@@ -2998,9 +3004,10 @@ static const u32 *icl_get_plane_formats(struct drm_i915_private *dev_priv,
        }
 }
 
-static const u64 *gen12_get_plane_modifiers(enum plane_id plane_id)
+static const u64 *gen12_get_plane_modifiers(struct drm_i915_private *dev_priv,
+                                           enum plane_id plane_id)
 {
-       if (gen12_plane_supports_mc_ccs(plane_id))
+       if (gen12_plane_supports_mc_ccs(dev_priv, plane_id))
                return gen12_plane_format_modifiers_mc_ccs;
        else
                return gen12_plane_format_modifiers_rc_ccs;
@@ -3070,7 +3077,7 @@ skl_universal_plane_create(struct drm_i915_private *dev_priv,
 
        plane->has_ccs = skl_plane_has_ccs(dev_priv, pipe, plane_id);
        if (INTEL_GEN(dev_priv) >= 12) {
-               modifiers = gen12_get_plane_modifiers(plane_id);
+               modifiers = gen12_get_plane_modifiers(dev_priv, plane_id);
                plane_funcs = &gen12_plane_funcs;
        } else {
                if (plane->has_ccs)
index cfaf141bac4d86e1f2e8cea1642120ed55f0829d..19542fd9e207e94325e9ea99a70972a0285d9182 100644 (file)
@@ -81,13 +81,14 @@ static void rps_enable_interrupts(struct intel_rps *rps)
                events = (GEN6_PM_RP_UP_THRESHOLD |
                          GEN6_PM_RP_DOWN_THRESHOLD |
                          GEN6_PM_RP_DOWN_TIMEOUT);
-
        WRITE_ONCE(rps->pm_events, events);
+
        spin_lock_irq(&gt->irq_lock);
        gen6_gt_pm_enable_irq(gt, rps->pm_events);
        spin_unlock_irq(&gt->irq_lock);
 
-       set(gt->uncore, GEN6_PMINTRMSK, rps_pm_mask(rps, rps->cur_freq));
+       intel_uncore_write(gt->uncore,
+                          GEN6_PMINTRMSK, rps_pm_mask(rps, rps->last_freq));
 }
 
 static void gen6_rps_reset_interrupts(struct intel_rps *rps)
@@ -120,7 +121,9 @@ static void rps_disable_interrupts(struct intel_rps *rps)
        struct intel_gt *gt = rps_to_gt(rps);
 
        WRITE_ONCE(rps->pm_events, 0);
-       set(gt->uncore, GEN6_PMINTRMSK, rps_pm_sanitize_mask(rps, ~0u));
+
+       intel_uncore_write(gt->uncore,
+                          GEN6_PMINTRMSK, rps_pm_sanitize_mask(rps, ~0u));
 
        spin_lock_irq(&gt->irq_lock);
        gen6_gt_pm_disable_irq(gt, GEN6_PM_RPS_EVENTS);
index 1f5b9a584f71795ea6cb9869e96338ab6e39d808..62b901ffabf9bd8087b3fe666072e4bc6271b253 100644 (file)
@@ -1507,6 +1507,8 @@ IS_SUBPLATFORM(const struct drm_i915_private *i915,
        (IS_ICELAKE(p) && IS_REVID(p, since, until))
 
 #define TGL_REVID_A0           0x0
+#define TGL_REVID_B0           0x1
+#define TGL_REVID_C0           0x2
 
 #define IS_TGL_REVID(p, since, until) \
        (IS_TIGERLAKE(p) && IS_REVID(p, since, until))
index 59e64acc2c5680afd514b860a258c321728ea2d9..e0c6021fdaf989c96e207ec5c946a9115d144b5b 100644 (file)
@@ -34,8 +34,8 @@
  * Follow the style described here for new macros, and while changing existing
  * macros. Do **not** mass change existing definitions just to update the style.
  *
- * Layout
- * ~~~~~~
+ * File Layout
+ * ~~~~~~~~~~~
  *
  * Keep helper macros near the top. For example, _PIPE() and friends.
  *
index e8c94915a4fcf3936f7a18c7fc9bdabcaa8e6016..64cb6ba4bc42d9ebb19f6dedb1272a36e094185d 100644 (file)
@@ -1034,10 +1034,8 @@ static int meson_dw_hdmi_bind(struct device *dev, struct device *master,
                return PTR_ERR(dw_plat_data->regm);
 
        irq = platform_get_irq(pdev, 0);
-       if (irq < 0) {
-               dev_err(dev, "Failed to get hdmi top irq\n");
+       if (irq < 0)
                return irq;
-       }
 
        ret = devm_request_threaded_irq(dev, irq, dw_hdmi_top_irq,
                                        dw_hdmi_top_thread_irq, IRQF_SHARED,
index 8e731ed0d9d9f81d4b04bfe5ecd4e139c13bfd51..2f319102ae9f7f39366f54a6ccfe52812af8e9b9 100644 (file)
@@ -676,7 +676,7 @@ drm_sched_get_cleanup_job(struct drm_gpu_scheduler *sched)
         */
        if ((sched->timeout != MAX_SCHEDULE_TIMEOUT &&
            !cancel_delayed_work(&sched->work_tdr)) ||
-           __kthread_should_park(sched->thread))
+           kthread_should_park())
                return NULL;
 
        spin_lock(&sched->job_list_lock);
index d4ce9bab8c7e61369ab52bc6617d3a6fddeb3610..3221a707e07366c68c03e2945a72b7ddd5298c20 100644 (file)
@@ -379,9 +379,17 @@ static struct drm_crtc_state *tidss_crtc_duplicate_state(struct drm_crtc *crtc)
        return &state->base;
 }
 
+static void tidss_crtc_destroy(struct drm_crtc *crtc)
+{
+       struct tidss_crtc *tcrtc = to_tidss_crtc(crtc);
+
+       drm_crtc_cleanup(crtc);
+       kfree(tcrtc);
+}
+
 static const struct drm_crtc_funcs tidss_crtc_funcs = {
        .reset = tidss_crtc_reset,
-       .destroy = drm_crtc_cleanup,
+       .destroy = tidss_crtc_destroy,
        .set_config = drm_atomic_helper_set_config,
        .page_flip = drm_atomic_helper_page_flip,
        .atomic_duplicate_state = tidss_crtc_duplicate_state,
@@ -400,7 +408,7 @@ struct tidss_crtc *tidss_crtc_create(struct tidss_device *tidss,
        bool has_ctm = tidss->feat->vp_feat.color.has_ctm;
        int ret;
 
-       tcrtc = devm_kzalloc(tidss->dev, sizeof(*tcrtc), GFP_KERNEL);
+       tcrtc = kzalloc(sizeof(*tcrtc), GFP_KERNEL);
        if (!tcrtc)
                return ERR_PTR(-ENOMEM);
 
@@ -411,8 +419,10 @@ struct tidss_crtc *tidss_crtc_create(struct tidss_device *tidss,
 
        ret = drm_crtc_init_with_planes(&tidss->ddev, crtc, primary,
                                        NULL, &tidss_crtc_funcs, NULL);
-       if (ret < 0)
+       if (ret < 0) {
+               kfree(tcrtc);
                return ERR_PTR(ret);
+       }
 
        drm_crtc_helper_add(crtc, &tidss_crtc_helper_funcs);
 
index 83785b0a66a9d28740fed7848b6559bbb99dce0f..30bf2a65949cff34f14f5efb6abdf63d71ca71cc 100644 (file)
@@ -55,12 +55,18 @@ static int tidss_encoder_atomic_check(struct drm_encoder *encoder,
        return 0;
 }
 
+static void tidss_encoder_destroy(struct drm_encoder *encoder)
+{
+       drm_encoder_cleanup(encoder);
+       kfree(encoder);
+}
+
 static const struct drm_encoder_helper_funcs encoder_helper_funcs = {
        .atomic_check = tidss_encoder_atomic_check,
 };
 
 static const struct drm_encoder_funcs encoder_funcs = {
-       .destroy = drm_encoder_cleanup,
+       .destroy = tidss_encoder_destroy,
 };
 
 struct drm_encoder *tidss_encoder_create(struct tidss_device *tidss,
@@ -69,7 +75,7 @@ struct drm_encoder *tidss_encoder_create(struct tidss_device *tidss,
        struct drm_encoder *enc;
        int ret;
 
-       enc = devm_kzalloc(tidss->dev, sizeof(*enc), GFP_KERNEL);
+       enc = kzalloc(sizeof(*enc), GFP_KERNEL);
        if (!enc)
                return ERR_PTR(-ENOMEM);
 
@@ -77,8 +83,10 @@ struct drm_encoder *tidss_encoder_create(struct tidss_device *tidss,
 
        ret = drm_encoder_init(&tidss->ddev, enc, &encoder_funcs,
                               encoder_type, NULL);
-       if (ret < 0)
+       if (ret < 0) {
+               kfree(enc);
                return ERR_PTR(ret);
+       }
 
        drm_encoder_helper_add(enc, &encoder_helper_funcs);
 
index ff99b2dd4a17f8681ee0c9f7aa6ecfa2b6837803..798488948fc539716bfe53a5316583b1360ee5ee 100644 (file)
@@ -141,6 +141,14 @@ static void tidss_plane_atomic_disable(struct drm_plane *plane,
        dispc_plane_enable(tidss->dispc, tplane->hw_plane_id, false);
 }
 
+static void drm_plane_destroy(struct drm_plane *plane)
+{
+       struct tidss_plane *tplane = to_tidss_plane(plane);
+
+       drm_plane_cleanup(plane);
+       kfree(tplane);
+}
+
 static const struct drm_plane_helper_funcs tidss_plane_helper_funcs = {
        .atomic_check = tidss_plane_atomic_check,
        .atomic_update = tidss_plane_atomic_update,
@@ -151,7 +159,7 @@ static const struct drm_plane_funcs tidss_plane_funcs = {
        .update_plane = drm_atomic_helper_update_plane,
        .disable_plane = drm_atomic_helper_disable_plane,
        .reset = drm_atomic_helper_plane_reset,
-       .destroy = drm_plane_cleanup,
+       .destroy = drm_plane_destroy,
        .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
        .atomic_destroy_state = drm_atomic_helper_plane_destroy_state,
 };
@@ -175,7 +183,7 @@ struct tidss_plane *tidss_plane_create(struct tidss_device *tidss,
                           BIT(DRM_MODE_BLEND_COVERAGE));
        int ret;
 
-       tplane = devm_kzalloc(tidss->dev, sizeof(*tplane), GFP_KERNEL);
+       tplane = kzalloc(sizeof(*tplane), GFP_KERNEL);
        if (!tplane)
                return ERR_PTR(-ENOMEM);
 
@@ -190,7 +198,7 @@ struct tidss_plane *tidss_plane_create(struct tidss_device *tidss,
                                       formats, num_formats,
                                       NULL, type, NULL);
        if (ret < 0)
-               return ERR_PTR(ret);
+               goto err;
 
        drm_plane_helper_add(&tplane->plane, &tidss_plane_helper_funcs);
 
@@ -203,15 +211,19 @@ struct tidss_plane *tidss_plane_create(struct tidss_device *tidss,
                                                default_encoding,
                                                default_range);
        if (ret)
-               return ERR_PTR(ret);
+               goto err;
 
        ret = drm_plane_create_alpha_property(&tplane->plane);
        if (ret)
-               return ERR_PTR(ret);
+               goto err;
 
        ret = drm_plane_create_blend_mode_property(&tplane->plane, blend_modes);
        if (ret)
-               return ERR_PTR(ret);
+               goto err;
 
        return tplane;
+
+err:
+       kfree(tplane);
+       return ERR_PTR(ret);
 }
index 336cc9143205de921c4307f076903530abe58e97..3f60bf2fe05aba4922717453a1bd674b18dfa4f3 100644 (file)
@@ -27,6 +27,7 @@
 
 #include <linux/file.h>
 #include <linux/sync_file.h>
+#include <linux/uaccess.h>
 
 #include <drm/drm_file.h>
 #include <drm/virtgpu_drm.h>
index 023a030ca7b99e7cba5d2fea111df0d434df852f..f4ea4cef5e23f7d2c1092853d47388c9e2668779 100644 (file)
@@ -25,6 +25,7 @@
 
 #include <linux/virtio.h>
 #include <linux/virtio_config.h>
+#include <linux/virtio_ring.h>
 
 #include <drm/drm_file.h>
 
index 6098e0cbdb4b0ad36f22fd214d2f0f59d08fec31..533c8b82b344d1b035a2cc78ff80476beab87701 100644 (file)
@@ -184,11 +184,7 @@ void hv_synic_enable_regs(unsigned int cpu)
 
        shared_sint.vector = HYPERVISOR_CALLBACK_VECTOR;
        shared_sint.masked = false;
-       if (ms_hyperv.hints & HV_DEPRECATING_AEOI_RECOMMENDED)
-               shared_sint.auto_eoi = false;
-       else
-               shared_sint.auto_eoi = true;
-
+       shared_sint.auto_eoi = hv_recommend_using_aeoi();
        hv_set_synint_state(VMBUS_MESSAGE_SINT, shared_sint.as_uint64);
 
        /* Enable the global synic bit */
index e70783e33680f1ec2ffa6b2bf46b266093907e57..f9d14db980cb4d2b65158bdd6ece3c2f5e02516e 100644 (file)
@@ -286,8 +286,8 @@ TRACE_EVENT(vmbus_send_tl_connect_request,
                    __field(int, ret)
                    ),
            TP_fast_assign(
-                   memcpy(__entry->guest_id, &msg->guest_endpoint_id.b, 16);
-                   memcpy(__entry->host_id, &msg->host_service_id.b, 16);
+                   export_guid(__entry->guest_id, &msg->guest_endpoint_id);
+                   export_guid(__entry->host_id, &msg->host_service_id);
                    __entry->ret = ret;
                    ),
            TP_printk("sending guest_endpoint_id %pUl, host_service_id %pUl, "
index a68bce4d0ddbe925beabc2ca6a3499c6e25ea202..e06c6b9555cfb6800bf67910730b79f5870359ed 100644 (file)
@@ -978,6 +978,9 @@ static int vmbus_resume(struct device *child_device)
 
        return drv->resume(dev);
 }
+#else
+#define vmbus_suspend NULL
+#define vmbus_resume NULL
 #endif /* CONFIG_PM_SLEEP */
 
 /*
@@ -997,11 +1000,22 @@ static void vmbus_device_release(struct device *device)
 }
 
 /*
- * Note: we must use SET_NOIRQ_SYSTEM_SLEEP_PM_OPS rather than
- * SET_SYSTEM_SLEEP_PM_OPS: see the comment before vmbus_bus_pm.
+ * Note: we must use the "noirq" ops: see the comment before vmbus_bus_pm.
+ *
+ * suspend_noirq/resume_noirq are set to NULL to support Suspend-to-Idle: we
+ * shouldn't suspend the vmbus devices upon Suspend-to-Idle, otherwise there
+ * is no way to wake up a Generation-2 VM.
+ *
+ * The other 4 ops are for hibernation.
  */
+
 static const struct dev_pm_ops vmbus_pm = {
-       SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(vmbus_suspend, vmbus_resume)
+       .suspend_noirq  = NULL,
+       .resume_noirq   = NULL,
+       .freeze_noirq   = vmbus_suspend,
+       .thaw_noirq     = vmbus_resume,
+       .poweroff_noirq = vmbus_suspend,
+       .restore_noirq  = vmbus_resume,
 };
 
 /* The one and only one */
@@ -2281,6 +2295,9 @@ static int vmbus_bus_resume(struct device *dev)
 
        return 0;
 }
+#else
+#define vmbus_bus_suspend NULL
+#define vmbus_bus_resume NULL
 #endif /* CONFIG_PM_SLEEP */
 
 static const struct acpi_device_id vmbus_acpi_device_ids[] = {
@@ -2291,16 +2308,24 @@ static const struct acpi_device_id vmbus_acpi_device_ids[] = {
 MODULE_DEVICE_TABLE(acpi, vmbus_acpi_device_ids);
 
 /*
- * Note: we must use SET_NOIRQ_SYSTEM_SLEEP_PM_OPS rather than
- * SET_SYSTEM_SLEEP_PM_OPS, otherwise NIC SR-IOV can not work, because the
- * "pci_dev_pm_ops" uses the "noirq" callbacks: in the resume path, the
- * pci "noirq" restore callback runs before "non-noirq" callbacks (see
+ * Note: we must use the "no_irq" ops, otherwise hibernation can not work with
+ * PCI device assignment, because "pci_dev_pm_ops" uses the "noirq" ops: in
+ * the resume path, the pci "noirq" restore op runs before "non-noirq" op (see
  * resume_target_kernel() -> dpm_resume_start(), and hibernation_restore() ->
  * dpm_resume_end()). This means vmbus_bus_resume() and the pci-hyperv's
- * resume callback must also run via the "noirq" callbacks.
+ * resume callback must also run via the "noirq" ops.
+ *
+ * Set suspend_noirq/resume_noirq to NULL for Suspend-to-Idle: see the comment
+ * earlier in this file before vmbus_pm.
  */
+
 static const struct dev_pm_ops vmbus_bus_pm = {
-       SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(vmbus_bus_suspend, vmbus_bus_resume)
+       .suspend_noirq  = NULL,
+       .resume_noirq   = NULL,
+       .freeze_noirq   = vmbus_bus_suspend,
+       .thaw_noirq     = vmbus_bus_resume,
+       .poweroff_noirq = vmbus_bus_suspend,
+       .restore_noirq  = vmbus_bus_resume
 };
 
 static struct acpi_driver vmbus_acpi_driver = {
index 02981f3d179410c34a188344e4ad34a242014d6d..08ba1a8f05eb347f1614c78006f84a7015888470 100644 (file)
 #define AD7193_CH_AINCOM       0x600 /* AINCOM - AINCOM */
 
 /* ID Register Bit Designations (AD7192_REG_ID) */
-#define ID_AD7190              0x4
-#define ID_AD7192              0x0
-#define ID_AD7193              0x2
-#define ID_AD7195              0x6
+#define CHIPID_AD7190          0x4
+#define CHIPID_AD7192          0x0
+#define CHIPID_AD7193          0x2
+#define CHIPID_AD7195          0x6
 #define AD7192_ID_MASK         0x0F
 
 /* GPOCON Register Bit Designations (AD7192_REG_GPOCON) */
@@ -161,7 +161,20 @@ enum {
        AD7192_SYSCALIB_FULL_SCALE,
 };
 
+enum {
+       ID_AD7190,
+       ID_AD7192,
+       ID_AD7193,
+       ID_AD7195,
+};
+
+struct ad7192_chip_info {
+       unsigned int                    chip_id;
+       const char                      *name;
+};
+
 struct ad7192_state {
+       const struct ad7192_chip_info   *chip_info;
        struct regulator                *avdd;
        struct regulator                *dvdd;
        struct clk                      *mclk;
@@ -172,7 +185,6 @@ struct ad7192_state {
        u32                             conf;
        u32                             scale_avail[8][2];
        u8                              gpocon;
-       u8                              devid;
        u8                              clock_sel;
        struct mutex                    lock;   /* protect sensor state */
        u8                              syscalib_mode[8];
@@ -348,7 +360,7 @@ static int ad7192_setup(struct ad7192_state *st, struct device_node *np)
 
        id &= AD7192_ID_MASK;
 
-       if (id != st->devid)
+       if (id != st->chip_info->chip_id)
                dev_warn(&st->sd.spi->dev, "device ID query failed (0x%X)\n",
                         id);
 
@@ -363,7 +375,7 @@ static int ad7192_setup(struct ad7192_state *st, struct device_node *np)
                st->mode |= AD7192_MODE_REJ60;
 
        refin2_en = of_property_read_bool(np, "adi,refin2-pins-enable");
-       if (refin2_en && st->devid != ID_AD7195)
+       if (refin2_en && st->chip_info->chip_id != CHIPID_AD7195)
                st->conf |= AD7192_CONF_REFSEL;
 
        st->conf &= ~AD7192_CONF_CHOP;
@@ -859,12 +871,31 @@ static const struct iio_chan_spec ad7193_channels[] = {
        IIO_CHAN_SOFT_TIMESTAMP(14),
 };
 
+static const struct ad7192_chip_info ad7192_chip_info_tbl[] = {
+       [ID_AD7190] = {
+               .chip_id = CHIPID_AD7190,
+               .name = "ad7190",
+       },
+       [ID_AD7192] = {
+               .chip_id = CHIPID_AD7192,
+               .name = "ad7192",
+       },
+       [ID_AD7193] = {
+               .chip_id = CHIPID_AD7193,
+               .name = "ad7193",
+       },
+       [ID_AD7195] = {
+               .chip_id = CHIPID_AD7195,
+               .name = "ad7195",
+       },
+};
+
 static int ad7192_channels_config(struct iio_dev *indio_dev)
 {
        struct ad7192_state *st = iio_priv(indio_dev);
 
-       switch (st->devid) {
-       case ID_AD7193:
+       switch (st->chip_info->chip_id) {
+       case CHIPID_AD7193:
                indio_dev->channels = ad7193_channels;
                indio_dev->num_channels = ARRAY_SIZE(ad7193_channels);
                break;
@@ -878,10 +909,10 @@ static int ad7192_channels_config(struct iio_dev *indio_dev)
 }
 
 static const struct of_device_id ad7192_of_match[] = {
-       { .compatible = "adi,ad7190", .data = (void *)ID_AD7190 },
-       { .compatible = "adi,ad7192", .data = (void *)ID_AD7192 },
-       { .compatible = "adi,ad7193", .data = (void *)ID_AD7193 },
-       { .compatible = "adi,ad7195", .data = (void *)ID_AD7195 },
+       { .compatible = "adi,ad7190", .data = &ad7192_chip_info_tbl[ID_AD7190] },
+       { .compatible = "adi,ad7192", .data = &ad7192_chip_info_tbl[ID_AD7192] },
+       { .compatible = "adi,ad7193", .data = &ad7192_chip_info_tbl[ID_AD7193] },
+       { .compatible = "adi,ad7195", .data = &ad7192_chip_info_tbl[ID_AD7195] },
        {}
 };
 MODULE_DEVICE_TABLE(of, ad7192_of_match);
@@ -938,16 +969,16 @@ static int ad7192_probe(struct spi_device *spi)
        }
 
        spi_set_drvdata(spi, indio_dev);
-       st->devid = (unsigned long)of_device_get_match_data(&spi->dev);
+       st->chip_info = of_device_get_match_data(&spi->dev);
        indio_dev->dev.parent = &spi->dev;
-       indio_dev->name = spi_get_device_id(spi)->name;
+       indio_dev->name = st->chip_info->name;
        indio_dev->modes = INDIO_DIRECT_MODE;
 
        ret = ad7192_channels_config(indio_dev);
        if (ret < 0)
                goto error_disable_dvdd;
 
-       if (st->devid == ID_AD7195)
+       if (st->chip_info->chip_id == CHIPID_AD7195)
                indio_dev->info = &ad7195_info;
        else
                indio_dev->info = &ad7192_info;
index b747db97f78ad5f60a9ea52c8643d29a21de480c..e5691e33032361df9abd0e1638a6c649a8784af4 100644 (file)
@@ -542,7 +542,7 @@ static const struct iio_info ad7797_info = {
        .read_raw = &ad7793_read_raw,
        .write_raw = &ad7793_write_raw,
        .write_raw_get_fmt = &ad7793_write_raw_get_fmt,
-       .attrs = &ad7793_attribute_group,
+       .attrs = &ad7797_attribute_group,
        .validate_trigger = ad_sd_validate_trigger,
 };
 
index 80c3f963527b5cf8997d880aed6a4c0e4676638e..ae622ee6d08cbb7d77ec68b9f01d077de6ddee8a 100644 (file)
@@ -1418,8 +1418,30 @@ static unsigned int stm32_adc_dma_residue(struct stm32_adc *adc)
 static void stm32_adc_dma_buffer_done(void *data)
 {
        struct iio_dev *indio_dev = data;
+       struct stm32_adc *adc = iio_priv(indio_dev);
+       int residue = stm32_adc_dma_residue(adc);
+
+       /*
+        * In DMA mode the trigger services of IIO are not used
+        * (e.g. no call to iio_trigger_poll).
+        * Calling irq handler associated to the hardware trigger is not
+        * relevant as the conversions have already been done. Data
+        * transfers are performed directly in DMA callback instead.
+        * This implementation avoids to call trigger irq handler that
+        * may sleep, in an atomic context (DMA irq handler context).
+        */
+       dev_dbg(&indio_dev->dev, "%s bufi=%d\n", __func__, adc->bufi);
 
-       iio_trigger_poll_chained(indio_dev->trig);
+       while (residue >= indio_dev->scan_bytes) {
+               u16 *buffer = (u16 *)&adc->rx_buf[adc->bufi];
+
+               iio_push_to_buffers(indio_dev, buffer);
+
+               residue -= indio_dev->scan_bytes;
+               adc->bufi += indio_dev->scan_bytes;
+               if (adc->bufi >= adc->rx_buf_sz)
+                       adc->bufi = 0;
+       }
 }
 
 static int stm32_adc_dma_start(struct iio_dev *indio_dev)
@@ -1845,6 +1867,7 @@ static int stm32_adc_probe(struct platform_device *pdev)
 {
        struct iio_dev *indio_dev;
        struct device *dev = &pdev->dev;
+       irqreturn_t (*handler)(int irq, void *p) = NULL;
        struct stm32_adc *adc;
        int ret;
 
@@ -1911,9 +1934,11 @@ static int stm32_adc_probe(struct platform_device *pdev)
        if (ret < 0)
                return ret;
 
+       if (!adc->dma_chan)
+               handler = &stm32_adc_trigger_handler;
+
        ret = iio_triggered_buffer_setup(indio_dev,
-                                        &iio_pollfunc_store_time,
-                                        &stm32_adc_trigger_handler,
+                                        &iio_pollfunc_store_time, handler,
                                         &stm32_adc_buffer_setup_ops);
        if (ret) {
                dev_err(&pdev->dev, "buffer setup failed\n");
index 9a460807d46d13975bac3578300c72fcf75cd05c..abe4b56c847c7db3c362f0c1d5fea0159dacf74b 100644 (file)
@@ -29,7 +29,7 @@ struct ads8344 {
        struct mutex lock;
 
        u8 tx_buf ____cacheline_aligned;
-       u16 rx_buf;
+       u8 rx_buf[3];
 };
 
 #define ADS8344_VOLTAGE_CHANNEL(chan, si)                              \
@@ -89,11 +89,11 @@ static int ads8344_adc_conversion(struct ads8344 *adc, int channel,
 
        udelay(9);
 
-       ret = spi_read(spi, &adc->rx_buf, 2);
+       ret = spi_read(spi, adc->rx_buf, sizeof(adc->rx_buf));
        if (ret)
                return ret;
 
-       return adc->rx_buf;
+       return adc->rx_buf[0] << 9 | adc->rx_buf[1] << 1 | adc->rx_buf[2] >> 7;
 }
 
 static int ads8344_read_raw(struct iio_dev *iio,
index ec227b358cd6f868dbb7d00f4a9e57fabe0ea65f..6fd06e4eff73eb2cb5b0a2729b2f784403fdcb43 100644 (file)
@@ -102,6 +102,16 @@ static const unsigned int XADC_ZYNQ_UNMASK_TIMEOUT = 500;
 
 #define XADC_FLAGS_BUFFERED BIT(0)
 
+/*
+ * The XADC hardware supports a samplerate of up to 1MSPS. Unfortunately it does
+ * not have a hardware FIFO. Which means an interrupt is generated for each
+ * conversion sequence. At 1MSPS sample rate the CPU in ZYNQ7000 is completely
+ * overloaded by the interrupts that it soft-lockups. For this reason the driver
+ * limits the maximum samplerate 150kSPS. At this rate the CPU is fairly busy,
+ * but still responsive.
+ */
+#define XADC_MAX_SAMPLERATE 150000
+
 static void xadc_write_reg(struct xadc *xadc, unsigned int reg,
        uint32_t val)
 {
@@ -674,7 +684,7 @@ static int xadc_trigger_set_state(struct iio_trigger *trigger, bool state)
 
        spin_lock_irqsave(&xadc->lock, flags);
        xadc_read_reg(xadc, XADC_AXI_REG_IPIER, &val);
-       xadc_write_reg(xadc, XADC_AXI_REG_IPISR, val & XADC_AXI_INT_EOS);
+       xadc_write_reg(xadc, XADC_AXI_REG_IPISR, XADC_AXI_INT_EOS);
        if (state)
                val |= XADC_AXI_INT_EOS;
        else
@@ -722,13 +732,14 @@ static int xadc_power_adc_b(struct xadc *xadc, unsigned int seq_mode)
 {
        uint16_t val;
 
+       /* Powerdown the ADC-B when it is not needed. */
        switch (seq_mode) {
        case XADC_CONF1_SEQ_SIMULTANEOUS:
        case XADC_CONF1_SEQ_INDEPENDENT:
-               val = XADC_CONF2_PD_ADC_B;
+               val = 0;
                break;
        default:
-               val = 0;
+               val = XADC_CONF2_PD_ADC_B;
                break;
        }
 
@@ -797,6 +808,16 @@ static int xadc_preenable(struct iio_dev *indio_dev)
        if (ret)
                goto err;
 
+       /*
+        * In simultaneous mode the upper and lower aux channels are samples at
+        * the same time. In this mode the upper 8 bits in the sequencer
+        * register are don't care and the lower 8 bits control two channels
+        * each. As such we must set the bit if either the channel in the lower
+        * group or the upper group is enabled.
+        */
+       if (seq_mode == XADC_CONF1_SEQ_SIMULTANEOUS)
+               scan_mask = ((scan_mask >> 8) | scan_mask) & 0xff0000;
+
        ret = xadc_write_adc_reg(xadc, XADC_REG_SEQ(1), scan_mask >> 16);
        if (ret)
                goto err;
@@ -823,11 +844,27 @@ static const struct iio_buffer_setup_ops xadc_buffer_ops = {
        .postdisable = &xadc_postdisable,
 };
 
+static int xadc_read_samplerate(struct xadc *xadc)
+{
+       unsigned int div;
+       uint16_t val16;
+       int ret;
+
+       ret = xadc_read_adc_reg(xadc, XADC_REG_CONF2, &val16);
+       if (ret)
+               return ret;
+
+       div = (val16 & XADC_CONF2_DIV_MASK) >> XADC_CONF2_DIV_OFFSET;
+       if (div < 2)
+               div = 2;
+
+       return xadc_get_dclk_rate(xadc) / div / 26;
+}
+
 static int xadc_read_raw(struct iio_dev *indio_dev,
        struct iio_chan_spec const *chan, int *val, int *val2, long info)
 {
        struct xadc *xadc = iio_priv(indio_dev);
-       unsigned int div;
        uint16_t val16;
        int ret;
 
@@ -880,41 +917,31 @@ static int xadc_read_raw(struct iio_dev *indio_dev,
                *val = -((273150 << 12) / 503975);
                return IIO_VAL_INT;
        case IIO_CHAN_INFO_SAMP_FREQ:
-               ret = xadc_read_adc_reg(xadc, XADC_REG_CONF2, &val16);
-               if (ret)
+               ret = xadc_read_samplerate(xadc);
+               if (ret < 0)
                        return ret;
 
-               div = (val16 & XADC_CONF2_DIV_MASK) >> XADC_CONF2_DIV_OFFSET;
-               if (div < 2)
-                       div = 2;
-
-               *val = xadc_get_dclk_rate(xadc) / div / 26;
-
+               *val = ret;
                return IIO_VAL_INT;
        default:
                return -EINVAL;
        }
 }
 
-static int xadc_write_raw(struct iio_dev *indio_dev,
-       struct iio_chan_spec const *chan, int val, int val2, long info)
+static int xadc_write_samplerate(struct xadc *xadc, int val)
 {
-       struct xadc *xadc = iio_priv(indio_dev);
        unsigned long clk_rate = xadc_get_dclk_rate(xadc);
        unsigned int div;
 
        if (!clk_rate)
                return -EINVAL;
 
-       if (info != IIO_CHAN_INFO_SAMP_FREQ)
-               return -EINVAL;
-
        if (val <= 0)
                return -EINVAL;
 
        /* Max. 150 kSPS */
-       if (val > 150000)
-               val = 150000;
+       if (val > XADC_MAX_SAMPLERATE)
+               val = XADC_MAX_SAMPLERATE;
 
        val *= 26;
 
@@ -927,7 +954,7 @@ static int xadc_write_raw(struct iio_dev *indio_dev,
         * limit.
         */
        div = clk_rate / val;
-       if (clk_rate / div / 26 > 150000)
+       if (clk_rate / div / 26 > XADC_MAX_SAMPLERATE)
                div++;
        if (div < 2)
                div = 2;
@@ -938,6 +965,17 @@ static int xadc_write_raw(struct iio_dev *indio_dev,
                div << XADC_CONF2_DIV_OFFSET);
 }
 
+static int xadc_write_raw(struct iio_dev *indio_dev,
+       struct iio_chan_spec const *chan, int val, int val2, long info)
+{
+       struct xadc *xadc = iio_priv(indio_dev);
+
+       if (info != IIO_CHAN_INFO_SAMP_FREQ)
+               return -EINVAL;
+
+       return xadc_write_samplerate(xadc, val);
+}
+
 static const struct iio_event_spec xadc_temp_events[] = {
        {
                .type = IIO_EV_TYPE_THRESH,
@@ -1223,6 +1261,21 @@ static int xadc_probe(struct platform_device *pdev)
        if (ret)
                goto err_free_samplerate_trigger;
 
+       /*
+        * Make sure not to exceed the maximum samplerate since otherwise the
+        * resulting interrupt storm will soft-lock the system.
+        */
+       if (xadc->ops->flags & XADC_FLAGS_BUFFERED) {
+               ret = xadc_read_samplerate(xadc);
+               if (ret < 0)
+                       goto err_free_samplerate_trigger;
+               if (ret > XADC_MAX_SAMPLERATE) {
+                       ret = xadc_write_samplerate(xadc, XADC_MAX_SAMPLERATE);
+                       if (ret < 0)
+                               goto err_free_samplerate_trigger;
+               }
+       }
+
        ret = request_irq(xadc->irq, xadc->ops->interrupt_handler, 0,
                        dev_name(&pdev->dev), indio_dev);
        if (ret)
index 0e35ff06f9af9d1d821411a679b2da9d497c0f85..13bdfbbf5f71f0eb38b55324c422837474a3ea7a 100644 (file)
@@ -79,7 +79,7 @@ int st_sensors_set_odr(struct iio_dev *indio_dev, unsigned int odr)
        struct st_sensor_odr_avl odr_out = {0, 0};
        struct st_sensor_data *sdata = iio_priv(indio_dev);
 
-       if (!sdata->sensor_settings->odr.addr)
+       if (!sdata->sensor_settings->odr.mask)
                return 0;
 
        err = st_sensors_match_odr(sdata->sensor_settings, odr, &odr_out);
index a98ea76732e72cf07881fcbbda0dd0224fb2aebe..2d7623b9b2c0ec8b88e46676a40086660c7d0cb7 100644 (file)
@@ -525,7 +525,7 @@ static int ad5770r_channel_config(struct ad5770r_state *st)
                ret = fwnode_property_read_u32(child, "num", &num);
                if (ret)
                        return ret;
-               if (num > AD5770R_MAX_CHANNELS)
+               if (num >= AD5770R_MAX_CHANNELS)
                        return -EINVAL;
 
                ret = fwnode_property_read_u32_array(child,
index 7cb9ff3d3e940018134b08badc9d3f50ab4cf545..0b8d2f7a0165bb6b8e2be85c2af8e18f55a8ec1d 100644 (file)
@@ -1617,6 +1617,10 @@ static int __maybe_unused inv_mpu_resume(struct device *dev)
        if (result)
                goto out_unlock;
 
+       pm_runtime_disable(dev);
+       pm_runtime_set_active(dev);
+       pm_runtime_enable(dev);
+
        result = inv_mpu6050_switch_engine(st, true, st->suspended_sensors);
        if (result)
                goto out_unlock;
@@ -1638,13 +1642,18 @@ static int __maybe_unused inv_mpu_suspend(struct device *dev)
 
        mutex_lock(&st->lock);
 
+       st->suspended_sensors = 0;
+       if (pm_runtime_suspended(dev)) {
+               result = 0;
+               goto out_unlock;
+       }
+
        if (iio_buffer_enabled(indio_dev)) {
                result = inv_mpu6050_prepare_fifo(st, false);
                if (result)
                        goto out_unlock;
        }
 
-       st->suspended_sensors = 0;
        if (st->chip_config.accl_en)
                st->suspended_sensors |= INV_MPU6050_SENSOR_ACCL;
        if (st->chip_config.gyro_en)
index f2113a63721a8619e57ab685cd28864d3b7f8054..41cb20cb3809aa1e02ee8ccd6e1683290050d816 100644 (file)
@@ -337,6 +337,7 @@ enum st_lsm6dsx_fifo_mode {
  * @gain: Configured sensor sensitivity.
  * @odr: Output data rate of the sensor [Hz].
  * @watermark: Sensor watermark level.
+ * @decimator: Sensor decimation factor.
  * @sip: Number of samples in a given pattern.
  * @ts_ref: Sensor timestamp reference for hw one.
  * @ext_info: Sensor settings if it is connected to i2c controller
@@ -350,11 +351,13 @@ struct st_lsm6dsx_sensor {
        u32 odr;
 
        u16 watermark;
+       u8 decimator;
        u8 sip;
        s64 ts_ref;
 
        struct {
                const struct st_lsm6dsx_ext_dev_settings *settings;
+               u32 slv_odr;
                u8 addr;
        } ext_info;
 };
index bb899345f2bbace1ff7655d246af9fc573de5e62..afd00daeefb2d4ae6fb57659cd3085c83193fefe 100644 (file)
@@ -93,6 +93,7 @@ st_lsm6dsx_get_decimator_val(struct st_lsm6dsx_sensor *sensor, u32 max_odr)
                        break;
        }
 
+       sensor->decimator = decimator;
        return i == max_size ? 0 : st_lsm6dsx_decimator_table[i].val;
 }
 
@@ -337,7 +338,7 @@ static inline int st_lsm6dsx_read_block(struct st_lsm6dsx_hw *hw, u8 addr,
 int st_lsm6dsx_read_fifo(struct st_lsm6dsx_hw *hw)
 {
        struct st_lsm6dsx_sensor *acc_sensor, *gyro_sensor, *ext_sensor = NULL;
-       int err, acc_sip, gyro_sip, ts_sip, ext_sip, read_len, offset;
+       int err, sip, acc_sip, gyro_sip, ts_sip, ext_sip, read_len, offset;
        u16 fifo_len, pattern_len = hw->sip * ST_LSM6DSX_SAMPLE_SIZE;
        u16 fifo_diff_mask = hw->settings->fifo_ops.fifo_diff.mask;
        u8 gyro_buff[ST_LSM6DSX_IIO_BUFF_SIZE];
@@ -399,19 +400,20 @@ int st_lsm6dsx_read_fifo(struct st_lsm6dsx_hw *hw)
                acc_sip = acc_sensor->sip;
                ts_sip = hw->ts_sip;
                offset = 0;
+               sip = 0;
 
                while (acc_sip > 0 || gyro_sip > 0 || ext_sip > 0) {
-                       if (gyro_sip > 0) {
+                       if (gyro_sip > 0 && !(sip % gyro_sensor->decimator)) {
                                memcpy(gyro_buff, &hw->buff[offset],
                                       ST_LSM6DSX_SAMPLE_SIZE);
                                offset += ST_LSM6DSX_SAMPLE_SIZE;
                        }
-                       if (acc_sip > 0) {
+                       if (acc_sip > 0 && !(sip % acc_sensor->decimator)) {
                                memcpy(acc_buff, &hw->buff[offset],
                                       ST_LSM6DSX_SAMPLE_SIZE);
                                offset += ST_LSM6DSX_SAMPLE_SIZE;
                        }
-                       if (ext_sip > 0) {
+                       if (ext_sip > 0 && !(sip % ext_sensor->decimator)) {
                                memcpy(ext_buff, &hw->buff[offset],
                                       ST_LSM6DSX_SAMPLE_SIZE);
                                offset += ST_LSM6DSX_SAMPLE_SIZE;
@@ -441,18 +443,25 @@ int st_lsm6dsx_read_fifo(struct st_lsm6dsx_hw *hw)
                                offset += ST_LSM6DSX_SAMPLE_SIZE;
                        }
 
-                       if (gyro_sip-- > 0)
+                       if (gyro_sip > 0 && !(sip % gyro_sensor->decimator)) {
                                iio_push_to_buffers_with_timestamp(
                                        hw->iio_devs[ST_LSM6DSX_ID_GYRO],
                                        gyro_buff, gyro_sensor->ts_ref + ts);
-                       if (acc_sip-- > 0)
+                               gyro_sip--;
+                       }
+                       if (acc_sip > 0 && !(sip % acc_sensor->decimator)) {
                                iio_push_to_buffers_with_timestamp(
                                        hw->iio_devs[ST_LSM6DSX_ID_ACC],
                                        acc_buff, acc_sensor->ts_ref + ts);
-                       if (ext_sip-- > 0)
+                               acc_sip--;
+                       }
+                       if (ext_sip > 0 && !(sip % ext_sensor->decimator)) {
                                iio_push_to_buffers_with_timestamp(
                                        hw->iio_devs[ST_LSM6DSX_ID_EXT0],
                                        ext_buff, ext_sensor->ts_ref + ts);
+                               ext_sip--;
+                       }
+                       sip++;
                }
        }
 
index 84d219ae6aee5d13e8b540e62da722265f425dc1..4426524b59f28648bf1557bac6709b3b6bc92e3d 100644 (file)
@@ -2036,11 +2036,21 @@ static int st_lsm6dsx_init_hw_timer(struct st_lsm6dsx_hw *hw)
        return 0;
 }
 
-static int st_lsm6dsx_init_device(struct st_lsm6dsx_hw *hw)
+static int st_lsm6dsx_reset_device(struct st_lsm6dsx_hw *hw)
 {
        const struct st_lsm6dsx_reg *reg;
        int err;
 
+       /*
+        * flush hw FIFO before device reset in order to avoid
+        * possible races on interrupt line 1. If the first interrupt
+        * line is asserted during hw reset the device will work in
+        * I3C-only mode (if it is supported)
+        */
+       err = st_lsm6dsx_flush_fifo(hw);
+       if (err < 0 && err != -ENOTSUPP)
+               return err;
+
        /* device sw reset */
        reg = &hw->settings->reset;
        err = regmap_update_bits(hw->regmap, reg->addr, reg->mask,
@@ -2059,6 +2069,18 @@ static int st_lsm6dsx_init_device(struct st_lsm6dsx_hw *hw)
 
        msleep(50);
 
+       return 0;
+}
+
+static int st_lsm6dsx_init_device(struct st_lsm6dsx_hw *hw)
+{
+       const struct st_lsm6dsx_reg *reg;
+       int err;
+
+       err = st_lsm6dsx_reset_device(hw);
+       if (err < 0)
+               return err;
+
        /* enable Block Data Update */
        reg = &hw->settings->bdu;
        err = regmap_update_bits(hw->regmap, reg->addr, reg->mask,
index 95ddd19d1aa7c369df3cb488805eed726fc33eb8..64ef07a307263a8335fe990c093f6bf4237f7aa8 100644 (file)
@@ -421,7 +421,8 @@ int st_lsm6dsx_shub_set_enable(struct st_lsm6dsx_sensor *sensor, bool enable)
 
        settings = sensor->ext_info.settings;
        if (enable) {
-               err = st_lsm6dsx_shub_set_odr(sensor, sensor->odr);
+               err = st_lsm6dsx_shub_set_odr(sensor,
+                                             sensor->ext_info.slv_odr);
                if (err < 0)
                        return err;
        } else {
@@ -459,7 +460,7 @@ st_lsm6dsx_shub_read_oneshot(struct st_lsm6dsx_sensor *sensor,
        if (err < 0)
                return err;
 
-       delay = 1000000000 / sensor->odr;
+       delay = 1000000000 / sensor->ext_info.slv_odr;
        usleep_range(delay, 2 * delay);
 
        len = min_t(int, sizeof(data), ch->scan_type.realbits >> 3);
@@ -500,8 +501,8 @@ st_lsm6dsx_shub_read_raw(struct iio_dev *iio_dev,
                iio_device_release_direct_mode(iio_dev);
                break;
        case IIO_CHAN_INFO_SAMP_FREQ:
-               *val = sensor->odr / 1000;
-               *val2 = (sensor->odr % 1000) * 1000;
+               *val = sensor->ext_info.slv_odr / 1000;
+               *val2 = (sensor->ext_info.slv_odr % 1000) * 1000;
                ret = IIO_VAL_INT_PLUS_MICRO;
                break;
        case IIO_CHAN_INFO_SCALE:
@@ -535,8 +536,20 @@ st_lsm6dsx_shub_write_raw(struct iio_dev *iio_dev,
 
                val = val * 1000 + val2 / 1000;
                err = st_lsm6dsx_shub_get_odr_val(sensor, val, &data);
-               if (!err)
-                       sensor->odr = val;
+               if (!err) {
+                       struct st_lsm6dsx_hw *hw = sensor->hw;
+                       struct st_lsm6dsx_sensor *ref_sensor;
+                       u8 odr_val;
+                       int odr;
+
+                       ref_sensor = iio_priv(hw->iio_devs[ST_LSM6DSX_ID_ACC]);
+                       odr = st_lsm6dsx_check_odr(ref_sensor, val, &odr_val);
+                       if (odr < 0)
+                               return odr;
+
+                       sensor->ext_info.slv_odr = val;
+                       sensor->odr = odr;
+               }
                break;
        }
        default:
@@ -613,6 +626,7 @@ st_lsm6dsx_shub_alloc_iiodev(struct st_lsm6dsx_hw *hw,
                             const struct st_lsm6dsx_ext_dev_settings *info,
                             u8 i2c_addr, const char *name)
 {
+       enum st_lsm6dsx_sensor_id ref_id = ST_LSM6DSX_ID_ACC;
        struct iio_chan_spec *ext_channels;
        struct st_lsm6dsx_sensor *sensor;
        struct iio_dev *iio_dev;
@@ -628,7 +642,8 @@ st_lsm6dsx_shub_alloc_iiodev(struct st_lsm6dsx_hw *hw,
        sensor = iio_priv(iio_dev);
        sensor->id = id;
        sensor->hw = hw;
-       sensor->odr = info->odr_table.odr_avl[0].milli_hz;
+       sensor->odr = hw->settings->odr_table[ref_id].odr_avl[0].milli_hz;
+       sensor->ext_info.slv_odr = info->odr_table.odr_avl[0].milli_hz;
        sensor->gain = info->fs_table.fs_avl[0].gain;
        sensor->ext_info.settings = info;
        sensor->ext_info.addr = i2c_addr;
index 2352c426bfb5baf99da6ed5c8b5de8081d45e074..24f7bbff4938fb03e31b8dba2e5a9ab2ffe6a1ce 100644 (file)
@@ -915,14 +915,11 @@ static ssize_t iio_write_channel_info(struct device *dev,
                        return -EINVAL;
                integer = ch;
        } else {
-               ret = iio_str_to_fixpoint(buf, fract_mult, &integer, &fract);
+               ret = __iio_str_to_fixpoint(buf, fract_mult, &integer, &fract,
+                                           scale_db);
                if (ret)
                        return ret;
        }
-       ret = __iio_str_to_fixpoint(buf, fract_mult, &integer, &fract,
-                                   scale_db);
-       if (ret)
-               return ret;
 
        ret = indio_dev->info->write_raw(indio_dev, this_attr->c,
                                         integer, fract, this_attr->address);
index 4794113ecd596c3f551ed7dc08c0e9171191f82b..17f14e0eafe4d484e5657ad138cc89145b925621 100644 (file)
@@ -862,7 +862,7 @@ static struct cm_id_private *cm_alloc_id_priv(struct ib_device *device,
 
        ret = xa_alloc_cyclic_irq(&cm.local_id_table, &id, NULL, xa_limit_32b,
                                  &cm.local_id_next, GFP_KERNEL);
-       if (ret)
+       if (ret < 0)
                goto error;
        cm_id_priv->id.local_id = (__force __be32)id ^ cm.random_id_operand;
 
@@ -1828,11 +1828,9 @@ static void cm_format_mra(struct cm_mra_msg *mra_msg,
 
 static void cm_format_rej(struct cm_rej_msg *rej_msg,
                          struct cm_id_private *cm_id_priv,
-                         enum ib_cm_rej_reason reason,
-                         void *ari,
-                         u8 ari_length,
-                         const void *private_data,
-                         u8 private_data_len)
+                         enum ib_cm_rej_reason reason, void *ari,
+                         u8 ari_length, const void *private_data,
+                         u8 private_data_len, enum ib_cm_state state)
 {
        lockdep_assert_held(&cm_id_priv->lock);
 
@@ -1840,7 +1838,7 @@ static void cm_format_rej(struct cm_rej_msg *rej_msg,
        IBA_SET(CM_REJ_REMOTE_COMM_ID, rej_msg,
                be32_to_cpu(cm_id_priv->id.remote_id));
 
-       switch(cm_id_priv->id.state) {
+       switch (state) {
        case IB_CM_REQ_RCVD:
                IBA_SET(CM_REJ_LOCAL_COMM_ID, rej_msg, be32_to_cpu(0));
                IBA_SET(CM_REJ_MESSAGE_REJECTED, rej_msg, CM_MSG_RESPONSE_REQ);
@@ -1905,8 +1903,9 @@ static void cm_dup_req_handler(struct cm_work *work,
                              cm_id_priv->private_data_len);
                break;
        case IB_CM_TIMEWAIT:
-               cm_format_rej((struct cm_rej_msg *) msg->mad, cm_id_priv,
-                             IB_CM_REJ_STALE_CONN, NULL, 0, NULL, 0);
+               cm_format_rej((struct cm_rej_msg *)msg->mad, cm_id_priv,
+                             IB_CM_REJ_STALE_CONN, NULL, 0, NULL, 0,
+                             IB_CM_TIMEWAIT);
                break;
        default:
                goto unlock;
@@ -2904,6 +2903,7 @@ static int cm_send_rej_locked(struct cm_id_private *cm_id_priv,
                              u8 ari_length, const void *private_data,
                              u8 private_data_len)
 {
+       enum ib_cm_state state = cm_id_priv->id.state;
        struct ib_mad_send_buf *msg;
        int ret;
 
@@ -2913,7 +2913,7 @@ static int cm_send_rej_locked(struct cm_id_private *cm_id_priv,
            (ari && ari_length > IB_CM_REJ_ARI_LENGTH))
                return -EINVAL;
 
-       switch (cm_id_priv->id.state) {
+       switch (state) {
        case IB_CM_REQ_SENT:
        case IB_CM_MRA_REQ_RCVD:
        case IB_CM_REQ_RCVD:
@@ -2925,7 +2925,8 @@ static int cm_send_rej_locked(struct cm_id_private *cm_id_priv,
                if (ret)
                        return ret;
                cm_format_rej((struct cm_rej_msg *)msg->mad, cm_id_priv, reason,
-                             ari, ari_length, private_data, private_data_len);
+                             ari, ari_length, private_data, private_data_len,
+                             state);
                break;
        case IB_CM_REP_SENT:
        case IB_CM_MRA_REP_RCVD:
@@ -2934,7 +2935,8 @@ static int cm_send_rej_locked(struct cm_id_private *cm_id_priv,
                if (ret)
                        return ret;
                cm_format_rej((struct cm_rej_msg *)msg->mad, cm_id_priv, reason,
-                             ari, ari_length, private_data, private_data_len);
+                             ari, ari_length, private_data, private_data_len,
+                             state);
                break;
        default:
                pr_debug("%s: local_id %d, cm_id->state: %d\n", __func__,
index 5128cb16bb4856f83f10c7a2dcb758d935418b36..177333d8bcdaeeb3a8e455248715776e892adb40 100644 (file)
@@ -360,7 +360,7 @@ lookup_get_fd_uobject(const struct uverbs_api_object *obj,
         * uverbs_uobject_fd_release(), and the caller is expected to ensure
         * that release is never done while a call to lookup is possible.
         */
-       if (f->f_op != fd_type->fops) {
+       if (f->f_op != fd_type->fops || uobject->ufile != ufile) {
                fput(f);
                return ERR_PTR(-EBADF);
        }
@@ -474,16 +474,15 @@ alloc_begin_fd_uobject(const struct uverbs_api_object *obj,
        filp = anon_inode_getfile(fd_type->name, fd_type->fops, NULL,
                                  fd_type->flags);
        if (IS_ERR(filp)) {
+               uverbs_uobject_put(uobj);
                uobj = ERR_CAST(filp);
-               goto err_uobj;
+               goto err_fd;
        }
        uobj->object = filp;
 
        uobj->id = new_fd;
        return uobj;
 
-err_uobj:
-       uverbs_uobject_put(uobj);
 err_fd:
        put_unused_fd(new_fd);
        return uobj;
@@ -679,7 +678,6 @@ void rdma_lookup_put_uobject(struct ib_uobject *uobj,
                             enum rdma_lookup_mode mode)
 {
        assert_uverbs_usecnt(uobj, mode);
-       uobj->uapi_object->type_class->lookup_put(uobj, mode);
        /*
         * In order to unlock an object, either decrease its usecnt for
         * read access or zero it in case of exclusive access. See
@@ -696,6 +694,7 @@ void rdma_lookup_put_uobject(struct ib_uobject *uobj,
                break;
        }
 
+       uobj->uapi_object->type_class->lookup_put(uobj, mode);
        /* Pairs with the kref obtained by type->lookup_get */
        uverbs_uobject_put(uobj);
 }
index 2d4083bf4a048767775eea73680debe4351f20df..17fc25db031145df82d7af89eade3d3e25d0b2e9 100644 (file)
@@ -820,6 +820,10 @@ void uverbs_user_mmap_disassociate(struct ib_uverbs_file *ufile)
                        ret = mmget_not_zero(mm);
                        if (!ret) {
                                list_del_init(&priv->list);
+                               if (priv->entry) {
+                                       rdma_user_mmap_entry_put(priv->entry);
+                                       priv->entry = NULL;
+                               }
                                mm = NULL;
                                continue;
                        }
index e8b4b3743661da0c6cfb1681efbe174875f216d4..688f196672215ee4b6c5384443218bb50cc48286 100644 (file)
@@ -1046,7 +1046,7 @@ i40iw_sc_query_rdma_features(struct i40iw_sc_cqp *cqp,
        u64 header;
 
        wqe = i40iw_sc_cqp_get_next_send_wqe(cqp, scratch);
-       if (wqe)
+       if (!wqe)
                return I40IW_ERR_RING_FULL;
 
        set_64bit_val(wqe, 32, feat_mem->pa);
index a66518a5c93868ac2ae3579c89736e1327417f1c..275722cec8c675690c573a000c452abc81f7d0f0 100644 (file)
@@ -1499,8 +1499,9 @@ static int __mlx4_ib_create_default_rules(
        int i;
 
        for (i = 0; i < ARRAY_SIZE(pdefault_rules->rules_create_list); i++) {
+               union ib_flow_spec ib_spec = {};
                int ret;
-               union ib_flow_spec ib_spec;
+
                switch (pdefault_rules->rules_create_list[i]) {
                case 0:
                        /* no rule */
index 1456db4b6295907c47e0b7f2d083819e58b49dc3..2210759843ba88e3e9033d0dd2572a2ab31c1839 100644 (file)
@@ -5558,7 +5558,9 @@ static void to_rdma_ah_attr(struct mlx5_ib_dev *ibdev,
        rdma_ah_set_path_bits(ah_attr, path->grh_mlid & 0x7f);
        rdma_ah_set_static_rate(ah_attr,
                                path->static_rate ? path->static_rate - 5 : 0);
-       if (path->grh_mlid & (1 << 7)) {
+
+       if (path->grh_mlid & (1 << 7) ||
+           ah_attr->type == RDMA_AH_ATTR_TYPE_ROCE) {
                u32 tc_fl = be32_to_cpu(path->tclass_flowlabel);
 
                rdma_ah_set_grh(ah_attr, NULL,
index 5724cbbe38b1f2432a3309f3139db548998a6181..04d2e72017fedaefe23ddb25900f583240cac8ca 100644 (file)
@@ -248,8 +248,8 @@ int rvt_create_cq(struct ib_cq *ibcq, const struct ib_cq_init_attr *attr,
         */
        if (udata && udata->outlen >= sizeof(__u64)) {
                cq->ip = rvt_create_mmap_info(rdi, sz, udata, u_wc);
-               if (!cq->ip) {
-                       err = -ENOMEM;
+               if (IS_ERR(cq->ip)) {
+                       err = PTR_ERR(cq->ip);
                        goto bail_wc;
                }
 
index 652f4a7efc1bed223d5052bf04eb46d296160888..37853aa3bcf7788eee80c219dc8f42e89b1eae20 100644 (file)
@@ -154,7 +154,7 @@ done:
  * @udata: user data (must be valid!)
  * @obj: opaque pointer to a cq, wq etc
  *
- * Return: rvt_mmap struct on success
+ * Return: rvt_mmap struct on success, ERR_PTR on failure
  */
 struct rvt_mmap_info *rvt_create_mmap_info(struct rvt_dev_info *rdi, u32 size,
                                           struct ib_udata *udata, void *obj)
@@ -166,7 +166,7 @@ struct rvt_mmap_info *rvt_create_mmap_info(struct rvt_dev_info *rdi, u32 size,
 
        ip = kmalloc_node(sizeof(*ip), GFP_KERNEL, rdi->dparms.node);
        if (!ip)
-               return ip;
+               return ERR_PTR(-ENOMEM);
 
        size = PAGE_ALIGN(size);
 
index 0e1b291d2cec8cacaf5a5b0b71113d626572c77d..500a7ee04c44e2afd0ce165b0018a1b46fbb3c2a 100644 (file)
@@ -1244,8 +1244,8 @@ struct ib_qp *rvt_create_qp(struct ib_pd *ibpd,
 
                        qp->ip = rvt_create_mmap_info(rdi, s, udata,
                                                      qp->r_rq.wq);
-                       if (!qp->ip) {
-                               ret = ERR_PTR(-ENOMEM);
+                       if (IS_ERR(qp->ip)) {
+                               ret = ERR_CAST(qp->ip);
                                goto bail_qpn;
                        }
 
index 24fef021d51dbb825135d01c6840339ed6a805ee..f547c115af0369883b099699aa9981aa4f394d7f 100644 (file)
@@ -111,8 +111,8 @@ int rvt_create_srq(struct ib_srq *ibsrq, struct ib_srq_init_attr *srq_init_attr,
                u32 s = sizeof(struct rvt_rwq) + srq->rq.size * sz;
 
                srq->ip = rvt_create_mmap_info(dev, s, udata, srq->rq.wq);
-               if (!srq->ip) {
-                       ret = -ENOMEM;
+               if (IS_ERR(srq->ip)) {
+                       ret = PTR_ERR(srq->ip);
                        goto bail_wq;
                }
 
index ae92c8080967c5bc66919c32db45390d091ac507..9f53aa4feb8782c0880120da0e26fe545e24f46e 100644 (file)
@@ -920,20 +920,27 @@ static int siw_fastreg_mr(struct ib_pd *pd, struct siw_sqe *sqe)
 {
        struct ib_mr *base_mr = (struct ib_mr *)(uintptr_t)sqe->base_mr;
        struct siw_device *sdev = to_siw_dev(pd->device);
-       struct siw_mem *mem = siw_mem_id2obj(sdev, sqe->rkey  >> 8);
+       struct siw_mem *mem;
        int rv = 0;
 
        siw_dbg_pd(pd, "STag 0x%08x\n", sqe->rkey);
 
-       if (unlikely(!mem || !base_mr)) {
+       if (unlikely(!base_mr)) {
                pr_warn("siw: fastreg: STag 0x%08x unknown\n", sqe->rkey);
                return -EINVAL;
        }
+
        if (unlikely(base_mr->rkey >> 8 != sqe->rkey  >> 8)) {
                pr_warn("siw: fastreg: STag 0x%08x: bad MR\n", sqe->rkey);
-               rv = -EINVAL;
-               goto out;
+               return -EINVAL;
        }
+
+       mem = siw_mem_id2obj(sdev, sqe->rkey  >> 8);
+       if (unlikely(!mem)) {
+               pr_warn("siw: fastreg: STag 0x%08x unknown\n", sqe->rkey);
+               return -EINVAL;
+       }
+
        if (unlikely(mem->pd != pd)) {
                pr_warn("siw: fastreg: PD mismatch\n");
                rv = -EINVAL;
index 2adfde8cdf19df99cfc5728aaaf320e73aaf98c9..2a11a63e7217ad93ae718fb0c082e7ccd3e9d6bb 100644 (file)
@@ -96,6 +96,8 @@ static inline void tcs_cmd_gen(struct tcs_cmd *cmd, u64 vote_x, u64 vote_y,
        if (!cmd)
                return;
 
+       memset(cmd, 0, sizeof(*cmd));
+
        if (vote_x == 0 && vote_y == 0)
                valid = false;
 
@@ -112,8 +114,7 @@ static inline void tcs_cmd_gen(struct tcs_cmd *cmd, u64 vote_x, u64 vote_y,
         * Set the wait for completion flag on command that need to be completed
         * before the next command.
         */
-       if (commit)
-               cmd->wait = true;
+       cmd->wait = commit;
 }
 
 static void tcs_list_gen(struct list_head *bcm_list, int bucket,
index 3d21c38e2dbbbc267db6b069b3cf2be7b5b5883d..0c390fe421ad3642d70ca6bd288dda78203fa543 100644 (file)
@@ -203,11 +203,12 @@ static int mei_me_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        }
        hw = to_me_hw(dev);
        hw->mem_addr = pcim_iomap_table(pdev)[0];
-       hw->irq = pdev->irq;
        hw->read_fws = mei_me_read_fws;
 
        pci_enable_msi(pdev);
 
+       hw->irq = pdev->irq;
+
         /* request and enable interrupt */
        irqflags = pci_dev_msi_enabled(pdev) ? IRQF_ONESHOT : IRQF_SHARED;
 
index 8f201d019f5a4d072255284d31f73c450786c4ef..3bfe72c59864cf24e2b762c7f6618289acf916ee 100644 (file)
@@ -116,7 +116,7 @@ config MIC_COSM
 
 config VOP
        tristate "VOP Driver"
-       depends on VOP_BUS
+       depends on VOP_BUS && VHOST_DPN
        select VHOST_RING
        select VIRTIO
        help
index 9db0570c5bebbeb0dad6b1097bb4aae6c6dcd233..661c25eb1c46f0f436fcd0b525cea9fceb5c899b 100644 (file)
@@ -50,7 +50,7 @@ config CAIF_HSI
 
 config CAIF_VIRTIO
        tristate "CAIF virtio transport driver"
-       depends on CAIF && HAS_DMA
+       depends on CAIF && HAS_DMA && VHOST_DPN
        select VHOST_RING
        select VIRTIO
        select GENERIC_ALLOCATOR
index 68e2381694b9ebd217a8e31debddcc7097ef6caa..c283593bef17e8b94e7eabb56d34f362e4ecbc4e 100644 (file)
@@ -1474,6 +1474,10 @@ static int b53_arl_rw_op(struct b53_device *dev, unsigned int op)
                reg |= ARLTBL_RW;
        else
                reg &= ~ARLTBL_RW;
+       if (dev->vlan_enabled)
+               reg &= ~ARLTBL_IVL_SVL_SELECT;
+       else
+               reg |= ARLTBL_IVL_SVL_SELECT;
        b53_write8(dev, B53_ARLIO_PAGE, B53_ARLTBL_RW_CTRL, reg);
 
        return b53_arl_op_wait(dev);
@@ -1483,6 +1487,7 @@ static int b53_arl_read(struct b53_device *dev, u64 mac,
                        u16 vid, struct b53_arl_entry *ent, u8 *idx,
                        bool is_valid)
 {
+       DECLARE_BITMAP(free_bins, B53_ARLTBL_MAX_BIN_ENTRIES);
        unsigned int i;
        int ret;
 
@@ -1490,6 +1495,8 @@ static int b53_arl_read(struct b53_device *dev, u64 mac,
        if (ret)
                return ret;
 
+       bitmap_zero(free_bins, dev->num_arl_entries);
+
        /* Read the bins */
        for (i = 0; i < dev->num_arl_entries; i++) {
                u64 mac_vid;
@@ -1501,13 +1508,24 @@ static int b53_arl_read(struct b53_device *dev, u64 mac,
                           B53_ARLTBL_DATA_ENTRY(i), &fwd_entry);
                b53_arl_to_entry(ent, mac_vid, fwd_entry);
 
-               if (!(fwd_entry & ARLTBL_VALID))
+               if (!(fwd_entry & ARLTBL_VALID)) {
+                       set_bit(i, free_bins);
                        continue;
+               }
                if ((mac_vid & ARLTBL_MAC_MASK) != mac)
                        continue;
+               if (dev->vlan_enabled &&
+                   ((mac_vid >> ARLTBL_VID_S) & ARLTBL_VID_MASK) != vid)
+                       continue;
                *idx = i;
+               return 0;
        }
 
+       if (bitmap_weight(free_bins, dev->num_arl_entries) == 0)
+               return -ENOSPC;
+
+       *idx = find_first_bit(free_bins, dev->num_arl_entries);
+
        return -ENOENT;
 }
 
@@ -1537,10 +1555,21 @@ static int b53_arl_op(struct b53_device *dev, int op, int port,
        if (op)
                return ret;
 
-       /* We could not find a matching MAC, so reset to a new entry */
-       if (ret) {
+       switch (ret) {
+       case -ENOSPC:
+               dev_dbg(dev->dev, "{%pM,%.4d} no space left in ARL\n",
+                       addr, vid);
+               return is_valid ? ret : 0;
+       case -ENOENT:
+               /* We could not find a matching MAC, so reset to a new entry */
+               dev_dbg(dev->dev, "{%pM,%.4d} not found, using idx: %d\n",
+                       addr, vid, idx);
                fwd_entry = 0;
-               idx = 1;
+               break;
+       default:
+               dev_dbg(dev->dev, "{%pM,%.4d} found, using idx: %d\n",
+                       addr, vid, idx);
+               break;
        }
 
        /* For multicast address, the port is a bitmask and the validity
@@ -1558,7 +1587,6 @@ static int b53_arl_op(struct b53_device *dev, int op, int port,
                ent.is_valid = !!(ent.port);
        }
 
-       ent.is_valid = is_valid;
        ent.vid = vid;
        ent.is_static = true;
        ent.is_age = false;
index 2a9f421680aad625d8e12020ce853808685eeb84..c90985c294a2e72888229963b89174e01bb6a978 100644 (file)
 /* ARL Table Read/Write Register (8 bit) */
 #define B53_ARLTBL_RW_CTRL             0x00
 #define    ARLTBL_RW                   BIT(0)
+#define    ARLTBL_IVL_SVL_SELECT       BIT(6)
 #define    ARLTBL_START_DONE           BIT(7)
 
 /* MAC Address Index Register (48 bit) */
  *
  * BCM5325 and BCM5365 share most definitions below
  */
-#define B53_ARLTBL_MAC_VID_ENTRY(n)    (0x10 * (n))
+#define B53_ARLTBL_MAC_VID_ENTRY(n)    ((0x10 * (n)) + 0x10)
 #define   ARLTBL_MAC_MASK              0xffffffffffffULL
 #define   ARLTBL_VID_S                 48
 #define   ARLTBL_VID_MASK_25           0xff
 #define   ARLTBL_VALID_25              BIT(63)
 
 /* ARL Table Data Entry N Registers (32 bit) */
-#define B53_ARLTBL_DATA_ENTRY(n)       ((0x10 * (n)) + 0x08)
+#define B53_ARLTBL_DATA_ENTRY(n)       ((0x10 * (n)) + 0x18)
 #define   ARLTBL_DATA_PORT_ID_MASK     0x1ff
 #define   ARLTBL_TC(tc)                        ((3 & tc) << 11)
 #define   ARLTBL_AGE                   BIT(14)
 #define   ARLTBL_STATIC                        BIT(15)
 #define   ARLTBL_VALID                 BIT(16)
 
+/* Maximum number of bin entries in the ARL for all switches */
+#define B53_ARLTBL_MAX_BIN_ENTRIES     4
+
 /* ARL Search Control Register (8 bit) */
 #define B53_ARL_SRCH_CTL               0x50
 #define B53_ARL_SRCH_CTL_25            0x20
index af7ce5c5488cbf8052c6392effaafec97f00d8be..b25356e21a1ea281b1db8b1d8b9cb83de8fb72ae 100644 (file)
@@ -664,7 +664,8 @@ static struct sk_buff *bcm_sysport_rx_refill(struct bcm_sysport_priv *priv,
        dma_addr_t mapping;
 
        /* Allocate a new SKB for a new packet */
-       skb = netdev_alloc_skb(priv->netdev, RX_BUF_LENGTH);
+       skb = __netdev_alloc_skb(priv->netdev, RX_BUF_LENGTH,
+                                GFP_ATOMIC | __GFP_NOWARN);
        if (!skb) {
                priv->mib.alloc_rx_buff_failed++;
                netif_err(priv, rx_err, ndev, "SKB alloc failed\n");
@@ -2475,7 +2476,6 @@ static int bcm_sysport_probe(struct platform_device *pdev)
                priv->wol_irq = platform_get_irq(pdev, 1);
        }
        if (priv->irq0 <= 0 || (priv->irq1 <= 0 && !priv->is_lite)) {
-               dev_err(&pdev->dev, "invalid interrupts\n");
                ret = -EINVAL;
                goto err_free_netdev;
        }
index c46c1b1416f7902da038b0896a7ec01456545b0b..a5d1a6cb9ce3800f3c526d63f628e39625afd18e 100644 (file)
@@ -172,7 +172,6 @@ static int bgmac_probe(struct platform_device *pdev)
 {
        struct device_node *np = pdev->dev.of_node;
        struct bgmac *bgmac;
-       struct resource *regs;
        const u8 *mac_addr;
 
        bgmac = bgmac_alloc(&pdev->dev);
@@ -202,31 +201,21 @@ static int bgmac_probe(struct platform_device *pdev)
        if (bgmac->irq < 0)
                return bgmac->irq;
 
-       regs = platform_get_resource_byname(pdev, IORESOURCE_MEM, "amac_base");
-       if (!regs) {
-               dev_err(&pdev->dev, "Unable to obtain base resource\n");
-               return -EINVAL;
-       }
-
-       bgmac->plat.base = devm_ioremap_resource(&pdev->dev, regs);
+       bgmac->plat.base =
+               devm_platform_ioremap_resource_byname(pdev, "amac_base");
        if (IS_ERR(bgmac->plat.base))
                return PTR_ERR(bgmac->plat.base);
 
-       regs = platform_get_resource_byname(pdev, IORESOURCE_MEM, "idm_base");
-       if (regs) {
-               bgmac->plat.idm_base = devm_ioremap_resource(&pdev->dev, regs);
-               if (IS_ERR(bgmac->plat.idm_base))
-                       return PTR_ERR(bgmac->plat.idm_base);
-               bgmac->feature_flags &= ~BGMAC_FEAT_IDM_MASK;
-       }
+       bgmac->plat.idm_base =
+               devm_platform_ioremap_resource_byname(pdev, "idm_base");
+       if (IS_ERR(bgmac->plat.idm_base))
+               return PTR_ERR(bgmac->plat.idm_base);
+       bgmac->feature_flags &= ~BGMAC_FEAT_IDM_MASK;
 
-       regs = platform_get_resource_byname(pdev, IORESOURCE_MEM, "nicpm_base");
-       if (regs) {
-               bgmac->plat.nicpm_base = devm_ioremap_resource(&pdev->dev,
-                                                              regs);
-               if (IS_ERR(bgmac->plat.nicpm_base))
-                       return PTR_ERR(bgmac->plat.nicpm_base);
-       }
+       bgmac->plat.nicpm_base =
+               devm_platform_ioremap_resource_byname(pdev, "nicpm_base");
+       if (IS_ERR(bgmac->plat.nicpm_base))
+               return PTR_ERR(bgmac->plat.nicpm_base);
 
        bgmac->read = platform_bgmac_read;
        bgmac->write = platform_bgmac_write;
index d975338bf78df35dfb6fd5a82961f89dde1621bb..79636c78127cdb503403f14994ae488af3d34bae 100644 (file)
@@ -934,6 +934,8 @@ static void bcmgenet_get_ethtool_stats(struct net_device *dev,
        if (netif_running(dev))
                bcmgenet_update_mib_counters(priv);
 
+       dev->netdev_ops->ndo_get_stats(dev);
+
        for (i = 0; i < BCMGENET_STATS_LEN; i++) {
                const struct bcmgenet_stats *s;
                char *p;
@@ -1622,7 +1624,8 @@ static struct sk_buff *bcmgenet_rx_refill(struct bcmgenet_priv *priv,
        dma_addr_t mapping;
 
        /* Allocate a new Rx skb */
-       skb = netdev_alloc_skb(priv->dev, priv->rx_buf_len + SKB_ALIGNMENT);
+       skb = __netdev_alloc_skb(priv->dev, priv->rx_buf_len + SKB_ALIGNMENT,
+                                GFP_ATOMIC | __GFP_NOWARN);
        if (!skb) {
                priv->mib.alloc_rx_buff_failed++;
                netif_err(priv, rx_err, priv->dev,
@@ -3156,6 +3159,7 @@ static struct net_device_stats *bcmgenet_get_stats(struct net_device *dev)
        dev->stats.rx_packets = rx_packets;
        dev->stats.rx_errors = rx_errors;
        dev->stats.rx_missed_errors = rx_errors;
+       dev->stats.rx_dropped = rx_dropped;
        return &dev->stats;
 }
 
index 19c11568113a635fe43b252a2721002894b19dec..7b9cd69f9844002e099dc34b59c72481ef9bbb24 100644 (file)
@@ -1049,9 +1049,9 @@ static void cudbg_t4_fwcache(struct cudbg_init *pdbg_init,
        }
 }
 
-static unsigned long cudbg_mem_region_size(struct cudbg_init *pdbg_init,
-                                          struct cudbg_error *cudbg_err,
-                                          u8 mem_type)
+static int cudbg_mem_region_size(struct cudbg_init *pdbg_init,
+                                struct cudbg_error *cudbg_err,
+                                u8 mem_type, unsigned long *region_size)
 {
        struct adapter *padap = pdbg_init->adap;
        struct cudbg_meminfo mem_info;
@@ -1060,15 +1060,23 @@ static unsigned long cudbg_mem_region_size(struct cudbg_init *pdbg_init,
 
        memset(&mem_info, 0, sizeof(struct cudbg_meminfo));
        rc = cudbg_fill_meminfo(padap, &mem_info);
-       if (rc)
+       if (rc) {
+               cudbg_err->sys_err = rc;
                return rc;
+       }
 
        cudbg_t4_fwcache(pdbg_init, cudbg_err);
        rc = cudbg_meminfo_get_mem_index(padap, &mem_info, mem_type, &mc_idx);
-       if (rc)
+       if (rc) {
+               cudbg_err->sys_err = rc;
                return rc;
+       }
+
+       if (region_size)
+               *region_size = mem_info.avail[mc_idx].limit -
+                              mem_info.avail[mc_idx].base;
 
-       return mem_info.avail[mc_idx].limit - mem_info.avail[mc_idx].base;
+       return 0;
 }
 
 static int cudbg_collect_mem_region(struct cudbg_init *pdbg_init,
@@ -1076,7 +1084,12 @@ static int cudbg_collect_mem_region(struct cudbg_init *pdbg_init,
                                    struct cudbg_error *cudbg_err,
                                    u8 mem_type)
 {
-       unsigned long size = cudbg_mem_region_size(pdbg_init, cudbg_err, mem_type);
+       unsigned long size = 0;
+       int rc;
+
+       rc = cudbg_mem_region_size(pdbg_init, cudbg_err, mem_type, &size);
+       if (rc)
+               return rc;
 
        return cudbg_read_fw_mem(pdbg_init, dbg_buff, mem_type, size,
                                 cudbg_err);
index af1f40cbccc882ee83d15c4fbd7fd7394350b6af..f5bc996ac77d5b04dd86a00169364ced14a2453a 100644 (file)
@@ -311,32 +311,17 @@ static int cxgb4_ptp_adjtime(struct ptp_clock_info *ptp, s64 delta)
  */
 static int cxgb4_ptp_gettime(struct ptp_clock_info *ptp, struct timespec64 *ts)
 {
-       struct adapter *adapter = (struct adapter *)container_of(ptp,
-                                  struct adapter, ptp_clock_info);
-       struct fw_ptp_cmd c;
+       struct adapter *adapter = container_of(ptp, struct adapter,
+                                              ptp_clock_info);
        u64 ns;
-       int err;
-
-       memset(&c, 0, sizeof(c));
-       c.op_to_portid = cpu_to_be32(FW_CMD_OP_V(FW_PTP_CMD) |
-                                    FW_CMD_REQUEST_F |
-                                    FW_CMD_READ_F |
-                                    FW_PTP_CMD_PORTID_V(0));
-       c.retval_len16 = cpu_to_be32(FW_CMD_LEN16_V(sizeof(c) / 16));
-       c.u.ts.sc = FW_PTP_SC_GET_TIME;
 
-       err = t4_wr_mbox(adapter, adapter->mbox, &c, sizeof(c), &c);
-       if (err < 0) {
-               dev_err(adapter->pdev_dev,
-                       "PTP: %s error %d\n", __func__, -err);
-               return err;
-       }
+       ns = t4_read_reg(adapter, T5_PORT_REG(0, MAC_PORT_PTP_SUM_LO_A));
+       ns |= (u64)t4_read_reg(adapter,
+                              T5_PORT_REG(0, MAC_PORT_PTP_SUM_HI_A)) << 32;
 
        /* convert to timespec*/
-       ns = be64_to_cpu(c.u.ts.tm);
        *ts = ns_to_timespec64(ns);
-
-       return err;
+       return 0;
 }
 
 /**
index bb20e50ddb848960c1db04c5905133543c6b893b..4a9fcd6c226c73d6f1f3df545cefbd899198e9bc 100644 (file)
 
 #define MAC_PORT_CFG2_A 0x818
 
+#define MAC_PORT_PTP_SUM_LO_A 0x990
+#define MAC_PORT_PTP_SUM_HI_A 0x994
+
 #define MPS_CMN_CTL_A  0x9000
 
 #define COUNTPAUSEMCRX_S    5
index f7103356ef56288efb05b58b7671bb8f23d465ca..0d51cbc88028b797c3afdae8be1555553110c553 100644 (file)
@@ -1476,7 +1476,7 @@ static bool e1000_check_64k_bound(struct e1000_adapter *adapter, void *start,
        if (hw->mac_type == e1000_82545 ||
            hw->mac_type == e1000_ce4100 ||
            hw->mac_type == e1000_82546) {
-               return ((begin ^ (end - 1)) >> 16) != 0 ? false : true;
+               return ((begin ^ (end - 1)) >> 16) == 0;
        }
 
        return true;
index 8c3e753bfb9d4883953003a7a834fe50c3ca56ee..2a037ec244b945aa04f7f263f77177c069b6ce6a 100644 (file)
@@ -1611,7 +1611,7 @@ static int i40e_config_rss_aq(struct i40e_vsi *vsi, const u8 *seed,
                }
        }
        if (lut) {
-               bool pf_lut = vsi->type == I40E_VSI_MAIN ? true : false;
+               bool pf_lut = vsi->type == I40E_VSI_MAIN;
 
                ret = i40e_aq_set_rss_lut(hw, vsi->id, pf_lut, lut, lut_size);
                if (ret) {
@@ -11436,7 +11436,7 @@ static int i40e_get_rss_aq(struct i40e_vsi *vsi, const u8 *seed,
        }
 
        if (lut) {
-               bool pf_lut = vsi->type == I40E_VSI_MAIN ? true : false;
+               bool pf_lut = vsi->type == I40E_VSI_MAIN;
 
                ret = i40e_aq_get_rss_lut(hw, vsi->id, pf_lut, lut, lut_size);
                if (ret) {
index 4d5ca302c067126b8627cb4809485b45c10e2460..a30edb436f4af11526e04c09623840288ebe4a29 100644 (file)
@@ -43,6 +43,7 @@
 #include <linux/ip.h>
 #include <linux/ipv6.h>
 #include <linux/moduleparam.h>
+#include <linux/indirect_call_wrapper.h>
 
 #include "mlx4_en.h"
 
@@ -261,6 +262,10 @@ static void mlx4_en_stamp_wqe(struct mlx4_en_priv *priv,
        }
 }
 
+INDIRECT_CALLABLE_DECLARE(u32 mlx4_en_free_tx_desc(struct mlx4_en_priv *priv,
+                                                  struct mlx4_en_tx_ring *ring,
+                                                  int index, u64 timestamp,
+                                                  int napi_mode));
 
 u32 mlx4_en_free_tx_desc(struct mlx4_en_priv *priv,
                         struct mlx4_en_tx_ring *ring,
@@ -329,6 +334,11 @@ u32 mlx4_en_free_tx_desc(struct mlx4_en_priv *priv,
        return tx_info->nr_txbb;
 }
 
+INDIRECT_CALLABLE_DECLARE(u32 mlx4_en_recycle_tx_desc(struct mlx4_en_priv *priv,
+                                                     struct mlx4_en_tx_ring *ring,
+                                                     int index, u64 timestamp,
+                                                     int napi_mode));
+
 u32 mlx4_en_recycle_tx_desc(struct mlx4_en_priv *priv,
                            struct mlx4_en_tx_ring *ring,
                            int index, u64 timestamp,
@@ -449,7 +459,9 @@ bool mlx4_en_process_tx_cq(struct net_device *dev,
                                timestamp = mlx4_en_get_cqe_ts(cqe);
 
                        /* free next descriptor */
-                       last_nr_txbb = ring->free_tx_desc(
+                       last_nr_txbb = INDIRECT_CALL_2(ring->free_tx_desc,
+                                                      mlx4_en_free_tx_desc,
+                                                      mlx4_en_recycle_tx_desc,
                                        priv, ring, ring_index,
                                        timestamp, napi_budget);
 
index 312e0a1ad43d7330ac26fbce72109b80592178ca..7d69a3061f1789d0804cff1f0c7f612ff02ed465 100644 (file)
@@ -7,10 +7,10 @@ config MLX5_CORE
        tristate "Mellanox 5th generation network adapters (ConnectX series) core driver"
        depends on PCI
        select NET_DEVLINK
-       imply PTP_1588_CLOCK
-       imply VXLAN
-       imply MLXFW
-       imply PCI_HYPERV_INTERFACE
+       depends on VXLAN || !VXLAN
+       depends on MLXFW || !MLXFW
+       depends on PTP_1588_CLOCK || !PTP_1588_CLOCK
+       depends on PCI_HYPERV_INTERFACE || !PCI_HYPERV_INTERFACE
        default n
        ---help---
          Core driver for low level functionality of the ConnectX-4 and
index c9c9b479bda5214f27d8245450e5efce2aefc01e..5ce6ebbc7f109908f746d56b5f85313e6dbb425b 100644 (file)
@@ -935,7 +935,7 @@ struct mlx5_fw_tracer *mlx5_fw_tracer_create(struct mlx5_core_dev *dev)
                return NULL;
        }
 
-       tracer = kzalloc(sizeof(*tracer), GFP_KERNEL);
+       tracer = kvzalloc(sizeof(*tracer), GFP_KERNEL);
        if (!tracer)
                return ERR_PTR(-ENOMEM);
 
@@ -982,7 +982,7 @@ destroy_workqueue:
        tracer->dev = NULL;
        destroy_workqueue(tracer->work_queue);
 free_tracer:
-       kfree(tracer);
+       kvfree(tracer);
        return ERR_PTR(err);
 }
 
@@ -1061,7 +1061,7 @@ void mlx5_fw_tracer_destroy(struct mlx5_fw_tracer *tracer)
        mlx5_fw_tracer_destroy_log_buf(tracer);
        flush_workqueue(tracer->work_queue);
        destroy_workqueue(tracer->work_queue);
-       kfree(tracer);
+       kvfree(tracer);
 }
 
 static int fw_tracer_event(struct notifier_block *nb, unsigned long action, void *data)
index 12a61bf82c14f8267b39afa0e194459e1a4b34b5..23701c0e36ec38c3533deb67c64e62da9b50bbf3 100644 (file)
@@ -367,6 +367,7 @@ enum {
        MLX5E_SQ_STATE_AM,
        MLX5E_SQ_STATE_TLS,
        MLX5E_SQ_STATE_VLAN_NEED_L2_INLINE,
+       MLX5E_SQ_STATE_PENDING_XSK_TX,
 };
 
 struct mlx5e_sq_wqe_info {
@@ -960,7 +961,7 @@ void mlx5e_page_release_dynamic(struct mlx5e_rq *rq,
 void mlx5e_handle_rx_cqe(struct mlx5e_rq *rq, struct mlx5_cqe64 *cqe);
 void mlx5e_handle_rx_cqe_mpwrq(struct mlx5e_rq *rq, struct mlx5_cqe64 *cqe);
 bool mlx5e_post_rx_wqes(struct mlx5e_rq *rq);
-void mlx5e_poll_ico_cq(struct mlx5e_cq *cq);
+int mlx5e_poll_ico_cq(struct mlx5e_cq *cq);
 bool mlx5e_post_rx_mpwqes(struct mlx5e_rq *rq);
 void mlx5e_dealloc_rx_wqe(struct mlx5e_rq *rq, u16 ix);
 void mlx5e_dealloc_rx_mpwqe(struct mlx5e_rq *rq, u16 ix);
index 16416eaac39ef5ab1de154ae97c555ea238a2e31..a172c5e39710b78362fadfd1db499da4786e4638 100644 (file)
@@ -12,6 +12,7 @@
 #include <net/flow_offload.h>
 #include <net/netfilter/nf_flow_table.h>
 #include <linux/workqueue.h>
+#include <linux/xarray.h>
 
 #include "esw/chains.h"
 #include "en/tc_ct.h"
@@ -35,7 +36,7 @@ struct mlx5_tc_ct_priv {
        struct mlx5_eswitch *esw;
        const struct net_device *netdev;
        struct idr fte_ids;
-       struct idr tuple_ids;
+       struct xarray tuple_ids;
        struct rhashtable zone_ht;
        struct mlx5_flow_table *ct;
        struct mlx5_flow_table *ct_nat;
@@ -238,7 +239,7 @@ mlx5_tc_ct_entry_del_rule(struct mlx5_tc_ct_priv *ct_priv,
 
        mlx5_eswitch_del_offloaded_rule(esw, zone_rule->rule, attr);
        mlx5_modify_header_dealloc(esw->dev, attr->modify_hdr);
-       idr_remove(&ct_priv->tuple_ids, zone_rule->tupleid);
+       xa_erase(&ct_priv->tuple_ids, zone_rule->tupleid);
 }
 
 static void
@@ -483,7 +484,7 @@ mlx5_tc_ct_entry_add_rule(struct mlx5_tc_ct_priv *ct_priv,
        struct mlx5_esw_flow_attr *attr = &zone_rule->attr;
        struct mlx5_eswitch *esw = ct_priv->esw;
        struct mlx5_flow_spec *spec = NULL;
-       u32 tupleid = 1;
+       u32 tupleid;
        int err;
 
        zone_rule->nat = nat;
@@ -493,12 +494,12 @@ mlx5_tc_ct_entry_add_rule(struct mlx5_tc_ct_priv *ct_priv,
                return -ENOMEM;
 
        /* Get tuple unique id */
-       err = idr_alloc_u32(&ct_priv->tuple_ids, zone_rule, &tupleid,
-                           TUPLE_ID_MAX, GFP_KERNEL);
+       err = xa_alloc(&ct_priv->tuple_ids, &tupleid, zone_rule,
+                      XA_LIMIT(1, TUPLE_ID_MAX), GFP_KERNEL);
        if (err) {
                netdev_warn(ct_priv->netdev,
                            "Failed to allocate tuple id, err: %d\n", err);
-               goto err_idr_alloc;
+               goto err_xa_alloc;
        }
        zone_rule->tupleid = tupleid;
 
@@ -539,8 +540,8 @@ mlx5_tc_ct_entry_add_rule(struct mlx5_tc_ct_priv *ct_priv,
 err_rule:
        mlx5_modify_header_dealloc(esw->dev, attr->modify_hdr);
 err_mod_hdr:
-       idr_remove(&ct_priv->tuple_ids, zone_rule->tupleid);
-err_idr_alloc:
+       xa_erase(&ct_priv->tuple_ids, zone_rule->tupleid);
+err_xa_alloc:
        kfree(spec);
        return err;
 }
@@ -1299,7 +1300,7 @@ mlx5_tc_ct_init(struct mlx5_rep_uplink_priv *uplink_priv)
        }
 
        idr_init(&ct_priv->fte_ids);
-       idr_init(&ct_priv->tuple_ids);
+       xa_init_flags(&ct_priv->tuple_ids, XA_FLAGS_ALLOC1);
        mutex_init(&ct_priv->control_lock);
        rhashtable_init(&ct_priv->zone_ht, &zone_params);
 
@@ -1334,7 +1335,7 @@ mlx5_tc_ct_clean(struct mlx5_rep_uplink_priv *uplink_priv)
 
        rhashtable_destroy(&ct_priv->zone_ht);
        mutex_destroy(&ct_priv->control_lock);
-       idr_destroy(&ct_priv->tuple_ids);
+       xa_destroy(&ct_priv->tuple_ids);
        idr_destroy(&ct_priv->fte_ids);
        kfree(ct_priv);
 
@@ -1352,7 +1353,7 @@ mlx5e_tc_ct_restore_flow(struct mlx5_rep_uplink_priv *uplink_priv,
        if (!ct_priv || !tupleid)
                return true;
 
-       zone_rule = idr_find(&ct_priv->tuple_ids, tupleid);
+       zone_rule = xa_load(&ct_priv->tuple_ids, tupleid);
        if (!zone_rule)
                return false;
 
index fe2d596cb361fa1ae03bfbfe28c2741965804f4b..3bcdb5b2fc2034f7819c2a0a86cdbe89b09d5564 100644 (file)
@@ -33,6 +33,9 @@ int mlx5e_xsk_wakeup(struct net_device *dev, u32 qid, u32 flags)
                if (unlikely(!test_bit(MLX5E_SQ_STATE_ENABLED, &c->xskicosq.state)))
                        return 0;
 
+               if (test_and_set_bit(MLX5E_SQ_STATE_PENDING_XSK_TX, &c->xskicosq.state))
+                       return 0;
+
                spin_lock(&c->xskicosq_lock);
                mlx5e_trigger_irq(&c->xskicosq);
                spin_unlock(&c->xskicosq_lock);
index f02150a97ac803e07fe7858d2c7333738e012b97..b314adf438da2d55c412e847a7ad149d415bcc65 100644 (file)
@@ -3583,7 +3583,12 @@ mlx5e_get_stats(struct net_device *dev, struct rtnl_link_stats64 *stats)
        struct mlx5e_vport_stats *vstats = &priv->stats.vport;
        struct mlx5e_pport_stats *pstats = &priv->stats.pport;
 
-       if (!mlx5e_monitor_counter_supported(priv)) {
+       /* In switchdev mode, monitor counters doesn't monitor
+        * rx/tx stats of 802_3. The update stats mechanism
+        * should keep the 802_3 layout counters updated
+        */
+       if (!mlx5e_monitor_counter_supported(priv) ||
+           mlx5e_is_uplink_rep(priv)) {
                /* update HW stats in background for next time */
                mlx5e_queue_update_stats(priv);
        }
index 6173faf542b06e4d65c5ac31dcb21bb536ff3ee2..e2beb89c1832fb443985fbd325c9893dced45128 100644 (file)
@@ -589,7 +589,7 @@ bool mlx5e_post_rx_wqes(struct mlx5e_rq *rq)
        return !!err;
 }
 
-void mlx5e_poll_ico_cq(struct mlx5e_cq *cq)
+int mlx5e_poll_ico_cq(struct mlx5e_cq *cq)
 {
        struct mlx5e_icosq *sq = container_of(cq, struct mlx5e_icosq, cq);
        struct mlx5_cqe64 *cqe;
@@ -597,11 +597,11 @@ void mlx5e_poll_ico_cq(struct mlx5e_cq *cq)
        int i;
 
        if (unlikely(!test_bit(MLX5E_SQ_STATE_ENABLED, &sq->state)))
-               return;
+               return 0;
 
        cqe = mlx5_cqwq_get_cqe(&cq->wq);
        if (likely(!cqe))
-               return;
+               return 0;
 
        /* sq->cc must be updated only after mlx5_cqwq_update_db_record(),
         * otherwise a cq overrun may occur
@@ -650,6 +650,8 @@ void mlx5e_poll_ico_cq(struct mlx5e_cq *cq)
        sq->cc = sqcc;
 
        mlx5_cqwq_update_db_record(&cq->wq);
+
+       return i;
 }
 
 bool mlx5e_post_rx_mpwqes(struct mlx5e_rq *rq)
index 87c49e7a164c84f6aa23b0f057d06a8b09a6168c..acb20215a33bb5c544b6b41cf0f60e975c155ab5 100644 (file)
@@ -152,7 +152,11 @@ int mlx5e_napi_poll(struct napi_struct *napi, int budget)
                                mlx5e_post_rx_wqes,
                                rq);
        if (xsk_open) {
-               mlx5e_poll_ico_cq(&c->xskicosq.cq);
+               if (mlx5e_poll_ico_cq(&c->xskicosq.cq))
+                       /* Don't clear the flag if nothing was polled to prevent
+                        * queueing more WQEs and overflowing XSKICOSQ.
+                        */
+                       clear_bit(MLX5E_SQ_STATE_PENDING_XSK_TX, &c->xskicosq.state);
                busy |= mlx5e_poll_xdpsq_cq(&xsksq->cq);
                busy_xsk |= mlx5e_napi_xsk_post(xsksq, xskrq);
        }
index 70a104e728f622656b1bd878b7a4994d2788502e..c3d04319ff44d6cf3b91af78578921349284ec4d 100644 (file)
@@ -380,7 +380,7 @@ struct mlxsw_afa_block *mlxsw_afa_block_create(struct mlxsw_afa *mlxsw_afa)
 
        block = kzalloc(sizeof(*block), GFP_KERNEL);
        if (!block)
-               return NULL;
+               return ERR_PTR(-ENOMEM);
        INIT_LIST_HEAD(&block->resource_list);
        block->afa = mlxsw_afa;
 
@@ -408,7 +408,7 @@ err_second_set_create:
        mlxsw_afa_set_destroy(block->first_set);
 err_first_set_create:
        kfree(block);
-       return NULL;
+       return ERR_PTR(-ENOMEM);
 }
 EXPORT_SYMBOL(mlxsw_afa_block_create);
 
index 6c66a0f1b79e38948af98b08bda300b55d5738e9..ad69913f19c10c7c645f574938f1c6f9e949384f 100644 (file)
@@ -88,8 +88,8 @@ static int mlxsw_sp2_acl_tcam_init(struct mlxsw_sp *mlxsw_sp, void *priv,
         * to be written using PEFA register to all indexes for all regions.
         */
        afa_block = mlxsw_afa_block_create(mlxsw_sp->afa);
-       if (!afa_block) {
-               err = -ENOMEM;
+       if (IS_ERR(afa_block)) {
+               err = PTR_ERR(afa_block);
                goto err_afa_block;
        }
        err = mlxsw_afa_block_continue(afa_block);
index 67ee880a87279e8be04ed492133c403c93e5d416..01cff711bbd2e69ee401fe91736989f0f5823d8a 100644 (file)
@@ -464,7 +464,7 @@ mlxsw_sp_acl_rulei_create(struct mlxsw_sp_acl *acl,
 
        rulei = kzalloc(sizeof(*rulei), GFP_KERNEL);
        if (!rulei)
-               return NULL;
+               return ERR_PTR(-ENOMEM);
 
        if (afa_block) {
                rulei->act_block = afa_block;
index 346f4a5fe053bc186008ebbf789f5d8f0919e1fa..221aa6a474eb104ce5be1591e91d134dc4aeb68b 100644 (file)
@@ -199,8 +199,8 @@ mlxsw_sp_mr_tcam_afa_block_create(struct mlxsw_sp *mlxsw_sp,
        int err;
 
        afa_block = mlxsw_afa_block_create(mlxsw_sp->afa);
-       if (!afa_block)
-               return ERR_PTR(-ENOMEM);
+       if (IS_ERR(afa_block))
+               return afa_block;
 
        err = mlxsw_afa_block_append_allocated_counter(afa_block,
                                                       counter_index);
index 5b145c6bad60661877ecd1bc34780b291abb183a..2ba15c263e8b34a1014bc760bf1bb7159eceb6a2 100644 (file)
@@ -1,19 +1,3 @@
-
-/*
- * snull.h -- definitions for the network module
- *
- * Copyright (C) 2001 Alessandro Rubini and Jonathan Corbet
- * Copyright (C) 2001 O'Reilly & Associates
- *
- * The source code in this file can be freely used, adapted,
- * and redistributed in source or binary form, so long as an
- * acknowledgment appears in derived source files.  The citation
- * should list that the code comes from the book "Linux Device
- * Drivers" by Alessandro Rubini and Jonathan Corbet, published
- * by O'Reilly & Associates.   No warranty is attached;
- * we cannot take responsibility for errors or fitness for use.
- */
-
 /* version dependencies have been confined to a separate file */
 
 /* Tunable parameters */
index 5419d4e478c0ed13d05c4c4ca7cfca3a36c5bfe4..2e4aaedb93f58098fa1e68fe364464d1e3eae325 100644 (file)
@@ -5,8 +5,13 @@
 #include <linux/clk-provider.h>
 #include <linux/pci.h>
 #include <linux/dmi.h>
+#include "dwmac-intel.h"
 #include "stmmac.h"
 
+struct intel_priv_data {
+       int mdio_adhoc_addr;    /* mdio address for serdes & etc */
+};
+
 /* This struct is used to associate PCI Function of MAC controller on a board,
  * discovered via DMI, with the address of PHY connected to the MAC. The
  * negative value of the address means that MAC controller is not connected
@@ -49,6 +54,172 @@ static int stmmac_pci_find_phy_addr(struct pci_dev *pdev,
        return -ENODEV;
 }
 
+static int serdes_status_poll(struct stmmac_priv *priv, int phyaddr,
+                             int phyreg, u32 mask, u32 val)
+{
+       unsigned int retries = 10;
+       int val_rd;
+
+       do {
+               val_rd = mdiobus_read(priv->mii, phyaddr, phyreg);
+               if ((val_rd & mask) == (val & mask))
+                       return 0;
+               udelay(POLL_DELAY_US);
+       } while (--retries);
+
+       return -ETIMEDOUT;
+}
+
+static int intel_serdes_powerup(struct net_device *ndev, void *priv_data)
+{
+       struct intel_priv_data *intel_priv = priv_data;
+       struct stmmac_priv *priv = netdev_priv(ndev);
+       int serdes_phy_addr = 0;
+       u32 data = 0;
+
+       if (!intel_priv->mdio_adhoc_addr)
+               return 0;
+
+       serdes_phy_addr = intel_priv->mdio_adhoc_addr;
+
+       /* assert clk_req */
+       data = mdiobus_read(priv->mii, serdes_phy_addr,
+                           SERDES_GCR0);
+
+       data |= SERDES_PLL_CLK;
+
+       mdiobus_write(priv->mii, serdes_phy_addr,
+                     SERDES_GCR0, data);
+
+       /* check for clk_ack assertion */
+       data = serdes_status_poll(priv, serdes_phy_addr,
+                                 SERDES_GSR0,
+                                 SERDES_PLL_CLK,
+                                 SERDES_PLL_CLK);
+
+       if (data) {
+               dev_err(priv->device, "Serdes PLL clk request timeout\n");
+               return data;
+       }
+
+       /* assert lane reset */
+       data = mdiobus_read(priv->mii, serdes_phy_addr,
+                           SERDES_GCR0);
+
+       data |= SERDES_RST;
+
+       mdiobus_write(priv->mii, serdes_phy_addr,
+                     SERDES_GCR0, data);
+
+       /* check for assert lane reset reflection */
+       data = serdes_status_poll(priv, serdes_phy_addr,
+                                 SERDES_GSR0,
+                                 SERDES_RST,
+                                 SERDES_RST);
+
+       if (data) {
+               dev_err(priv->device, "Serdes assert lane reset timeout\n");
+               return data;
+       }
+
+       /*  move power state to P0 */
+       data = mdiobus_read(priv->mii, serdes_phy_addr,
+                           SERDES_GCR0);
+
+       data &= ~SERDES_PWR_ST_MASK;
+       data |= SERDES_PWR_ST_P0 << SERDES_PWR_ST_SHIFT;
+
+       mdiobus_write(priv->mii, serdes_phy_addr,
+                     SERDES_GCR0, data);
+
+       /* Check for P0 state */
+       data = serdes_status_poll(priv, serdes_phy_addr,
+                                 SERDES_GSR0,
+                                 SERDES_PWR_ST_MASK,
+                                 SERDES_PWR_ST_P0 << SERDES_PWR_ST_SHIFT);
+
+       if (data) {
+               dev_err(priv->device, "Serdes power state P0 timeout.\n");
+               return data;
+       }
+
+       return 0;
+}
+
+static void intel_serdes_powerdown(struct net_device *ndev, void *intel_data)
+{
+       struct intel_priv_data *intel_priv = intel_data;
+       struct stmmac_priv *priv = netdev_priv(ndev);
+       int serdes_phy_addr = 0;
+       u32 data = 0;
+
+       if (!intel_priv->mdio_adhoc_addr)
+               return;
+
+       serdes_phy_addr = intel_priv->mdio_adhoc_addr;
+
+       /*  move power state to P3 */
+       data = mdiobus_read(priv->mii, serdes_phy_addr,
+                           SERDES_GCR0);
+
+       data &= ~SERDES_PWR_ST_MASK;
+       data |= SERDES_PWR_ST_P3 << SERDES_PWR_ST_SHIFT;
+
+       mdiobus_write(priv->mii, serdes_phy_addr,
+                     SERDES_GCR0, data);
+
+       /* Check for P3 state */
+       data = serdes_status_poll(priv, serdes_phy_addr,
+                                 SERDES_GSR0,
+                                 SERDES_PWR_ST_MASK,
+                                 SERDES_PWR_ST_P3 << SERDES_PWR_ST_SHIFT);
+
+       if (data) {
+               dev_err(priv->device, "Serdes power state P3 timeout\n");
+               return;
+       }
+
+       /* de-assert clk_req */
+       data = mdiobus_read(priv->mii, serdes_phy_addr,
+                           SERDES_GCR0);
+
+       data &= ~SERDES_PLL_CLK;
+
+       mdiobus_write(priv->mii, serdes_phy_addr,
+                     SERDES_GCR0, data);
+
+       /* check for clk_ack de-assert */
+       data = serdes_status_poll(priv, serdes_phy_addr,
+                                 SERDES_GSR0,
+                                 SERDES_PLL_CLK,
+                                 (u32)~SERDES_PLL_CLK);
+
+       if (data) {
+               dev_err(priv->device, "Serdes PLL clk de-assert timeout\n");
+               return;
+       }
+
+       /* de-assert lane reset */
+       data = mdiobus_read(priv->mii, serdes_phy_addr,
+                           SERDES_GCR0);
+
+       data &= ~SERDES_RST;
+
+       mdiobus_write(priv->mii, serdes_phy_addr,
+                     SERDES_GCR0, data);
+
+       /* check for de-assert lane reset reflection */
+       data = serdes_status_poll(priv, serdes_phy_addr,
+                                 SERDES_GSR0,
+                                 SERDES_RST,
+                                 (u32)~SERDES_RST);
+
+       if (data) {
+               dev_err(priv->device, "Serdes de-assert lane reset timeout\n");
+               return;
+       }
+}
+
 static void common_default_data(struct plat_stmmacenet_data *plat)
 {
        plat->clk_csr = 2;      /* clk_csr_i = 20-35MHz & MDC = clk_csr_i/16 */
@@ -189,6 +360,9 @@ static int ehl_sgmii_data(struct pci_dev *pdev,
        plat->phy_addr = 0;
        plat->phy_interface = PHY_INTERFACE_MODE_SGMII;
 
+       plat->serdes_powerup = intel_serdes_powerup;
+       plat->serdes_powerdown = intel_serdes_powerdown;
+
        return ehl_common_data(pdev, plat);
 }
 
@@ -233,6 +407,8 @@ static int ehl_pse0_sgmii1g_data(struct pci_dev *pdev,
                                 struct plat_stmmacenet_data *plat)
 {
        plat->phy_interface = PHY_INTERFACE_MODE_SGMII;
+       plat->serdes_powerup = intel_serdes_powerup;
+       plat->serdes_powerdown = intel_serdes_powerdown;
        return ehl_pse0_common_data(pdev, plat);
 }
 
@@ -263,6 +439,8 @@ static int ehl_pse1_sgmii1g_data(struct pci_dev *pdev,
                                 struct plat_stmmacenet_data *plat)
 {
        plat->phy_interface = PHY_INTERFACE_MODE_SGMII;
+       plat->serdes_powerup = intel_serdes_powerup;
+       plat->serdes_powerdown = intel_serdes_powerdown;
        return ehl_pse1_common_data(pdev, plat);
 }
 
@@ -291,6 +469,8 @@ static int tgl_sgmii_data(struct pci_dev *pdev,
        plat->bus_id = 1;
        plat->phy_addr = 0;
        plat->phy_interface = PHY_INTERFACE_MODE_SGMII;
+       plat->serdes_powerup = intel_serdes_powerup;
+       plat->serdes_powerdown = intel_serdes_powerdown;
        return tgl_common_data(pdev, plat);
 }
 
@@ -417,11 +597,17 @@ static int intel_eth_pci_probe(struct pci_dev *pdev,
                               const struct pci_device_id *id)
 {
        struct stmmac_pci_info *info = (struct stmmac_pci_info *)id->driver_data;
+       struct intel_priv_data *intel_priv;
        struct plat_stmmacenet_data *plat;
        struct stmmac_resources res;
        int i;
        int ret;
 
+       intel_priv = devm_kzalloc(&pdev->dev, sizeof(*intel_priv),
+                                 GFP_KERNEL);
+       if (!intel_priv)
+               return -ENOMEM;
+
        plat = devm_kzalloc(&pdev->dev, sizeof(*plat), GFP_KERNEL);
        if (!plat)
                return -ENOMEM;
@@ -457,6 +643,9 @@ static int intel_eth_pci_probe(struct pci_dev *pdev,
 
        pci_set_master(pdev);
 
+       plat->bsp_priv = intel_priv;
+       intel_priv->mdio_adhoc_addr = 0x15;
+
        ret = info->setup(pdev, plat);
        if (ret)
                return ret;
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.h b/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.h
new file mode 100644 (file)
index 0000000..e723096
--- /dev/null
@@ -0,0 +1,23 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright (c) 2020, Intel Corporation
+ * DWMAC Intel header file
+ */
+
+#ifndef __DWMAC_INTEL_H__
+#define __DWMAC_INTEL_H__
+
+#define POLL_DELAY_US 8
+
+/* SERDES Register */
+#define SERDES_GSR0    0x5     /* Global Status Reg0 */
+#define SERDES_GCR0    0xb     /* Global Configuration Reg0 */
+
+/* SERDES defines */
+#define SERDES_PLL_CLK         BIT(0)          /* PLL clk valid signal */
+#define SERDES_RST             BIT(2)          /* Serdes Reset */
+#define SERDES_PWR_ST_MASK     GENMASK(6, 4)   /* Serdes Power state*/
+#define SERDES_PWR_ST_SHIFT    4
+#define SERDES_PWR_ST_P0       0x0
+#define SERDES_PWR_ST_P3       0x3
+
+#endif /* __DWMAC_INTEL_H__ */
index 0e2fa14f142377b0c47751d2eb99fa11cb4e445d..a3934ca6a043bb652e527ea03152653896929e2a 100644 (file)
@@ -119,6 +119,7 @@ static int meson8b_init_rgmii_tx_clk(struct meson8b_dwmac *dwmac)
                { .div = 5, .val = 5, },
                { .div = 6, .val = 6, },
                { .div = 7, .val = 7, },
+               { /* end of array */ }
        };
 
        clk_configs = devm_kzalloc(dev, sizeof(*clk_configs), GFP_KERNEL);
index fa32cd5b418ef95c079190903193b118b1e406b9..70d41783329dd4e9b8b25fcc2487c244ad44cc7a 100644 (file)
@@ -291,16 +291,19 @@ static int socfpga_gen5_set_phy_mode(struct socfpga_dwmac *dwmac)
            phymode == PHY_INTERFACE_MODE_MII ||
            phymode == PHY_INTERFACE_MODE_GMII ||
            phymode == PHY_INTERFACE_MODE_SGMII) {
-               ctrl |= SYSMGR_EMACGRP_CTRL_PTP_REF_CLK_MASK << (reg_shift / 2);
                regmap_read(sys_mgr_base_addr, SYSMGR_FPGAGRP_MODULE_REG,
                            &module);
                module |= (SYSMGR_FPGAGRP_MODULE_EMAC << (reg_shift / 2));
                regmap_write(sys_mgr_base_addr, SYSMGR_FPGAGRP_MODULE_REG,
                             module);
-       } else {
-               ctrl &= ~(SYSMGR_EMACGRP_CTRL_PTP_REF_CLK_MASK << (reg_shift / 2));
        }
 
+       if (dwmac->f2h_ptp_ref_clk)
+               ctrl |= SYSMGR_EMACGRP_CTRL_PTP_REF_CLK_MASK << (reg_shift / 2);
+       else
+               ctrl &= ~(SYSMGR_EMACGRP_CTRL_PTP_REF_CLK_MASK <<
+                         (reg_shift / 2));
+
        regmap_write(sys_mgr_base_addr, reg_offset, ctrl);
 
        /* Deassert reset for the phy configuration to be sampled by
index fcf080243a0fef578299e337b919eb39ebcee2a6..d291612eeafb96b753da3a6e6b42fc2b16bc0d1e 100644 (file)
@@ -27,12 +27,16 @@ static void config_sub_second_increment(void __iomem *ioaddr,
        unsigned long data;
        u32 reg_value;
 
-       /* For GMAC3.x, 4.x versions, convert the ptp_clock to nano second
-        *      formula = (1/ptp_clock) * 1000000000
-        * where ptp_clock is 50MHz if fine method is used to update system
+       /* For GMAC3.x, 4.x versions, in "fine adjustement mode" set sub-second
+        * increment to twice the number of nanoseconds of a clock cycle.
+        * The calculation of the default_addend value by the caller will set it
+        * to mid-range = 2^31 when the remainder of this division is zero,
+        * which will make the accumulator overflow once every 2 ptp_clock
+        * cycles, adding twice the number of nanoseconds of a clock cycle :
+        * 2000000000ULL / ptp_clock.
         */
        if (value & PTP_TCR_TSCFUPDT)
-               data = (1000000000ULL / 50000000);
+               data = (2000000000ULL / ptp_clock);
        else
                data = (1000000000ULL / ptp_clock);
 
index e6898fd5223f2987fe9611360c33ee63e6686497..565da6498c846eac02648dd0c9da946431f58b5c 100644 (file)
@@ -4986,6 +4986,14 @@ int stmmac_dvr_probe(struct device *device,
                goto error_netdev_register;
        }
 
+       if (priv->plat->serdes_powerup) {
+               ret = priv->plat->serdes_powerup(ndev,
+                                                priv->plat->bsp_priv);
+
+               if (ret < 0)
+                       return ret;
+       }
+
 #ifdef CONFIG_DEBUG_FS
        stmmac_init_fs(ndev);
 #endif
@@ -5029,6 +5037,9 @@ int stmmac_dvr_remove(struct device *dev)
 
        stmmac_stop_all_dma(priv);
 
+       if (priv->plat->serdes_powerdown)
+               priv->plat->serdes_powerdown(ndev, priv->plat->bsp_priv);
+
        stmmac_mac_set(priv, priv->ioaddr, false);
        netif_carrier_off(ndev);
        unregister_netdev(ndev);
@@ -5081,6 +5092,9 @@ int stmmac_suspend(struct device *dev)
        /* Stop TX/RX DMA */
        stmmac_stop_all_dma(priv);
 
+       if (priv->plat->serdes_powerdown)
+               priv->plat->serdes_powerdown(ndev, priv->plat->bsp_priv);
+
        /* Enable Power down mode by programming the PMT regs */
        if (device_may_wakeup(priv->device)) {
                stmmac_pmt(priv, priv->hw, priv->wolopts);
@@ -5143,6 +5157,7 @@ int stmmac_resume(struct device *dev)
 {
        struct net_device *ndev = dev_get_drvdata(dev);
        struct stmmac_priv *priv = netdev_priv(ndev);
+       int ret;
 
        if (!netif_running(ndev))
                return 0;
@@ -5170,6 +5185,14 @@ int stmmac_resume(struct device *dev)
                        stmmac_mdio_reset(priv->mii);
        }
 
+       if (priv->plat->serdes_powerup) {
+               ret = priv->plat->serdes_powerup(ndev,
+                                                priv->plat->bsp_priv);
+
+               if (ret < 0)
+                       return ret;
+       }
+
        netif_device_attach(ndev);
 
        mutex_lock(&priv->lock);
index 269596c15133d01008d699baf47ec6a8ecef8a5d..2e52029235104762b0ea4870433c2df7347addd9 100644 (file)
@@ -1387,6 +1387,8 @@ static int ixp4xx_eth_probe(struct platform_device *pdev)
                return -ENODEV;
        regs_phys = res->start;
        port->regs = devm_ioremap_resource(dev, res);
+       if (IS_ERR(port->regs))
+               return PTR_ERR(port->regs);
 
        switch (port->id) {
        case IXP4XX_ETH_NPEA:
index 09f279c0182be4c05144c5caca6548cacfebbd49..6b461be1820bb91899a406032f0dd4dcdb01857e 100644 (file)
@@ -1207,7 +1207,7 @@ static int geneve_validate(struct nlattr *tb[], struct nlattr *data[],
                enum ifla_geneve_df df = nla_get_u8(data[IFLA_GENEVE_DF]);
 
                if (df < 0 || df > GENEVE_DF_MAX) {
-                       NL_SET_ERR_MSG_ATTR(extack, tb[IFLA_GENEVE_DF],
+                       NL_SET_ERR_MSG_ATTR(extack, data[IFLA_GENEVE_DF],
                                            "Invalid DF attribute");
                        return -EINVAL;
                }
index a183250ff66adc83cce7767dab9a1e35c57f0b3b..758baf7cb8a16cbf2ac6393a74c99e08a1279bfa 100644 (file)
@@ -4002,11 +4002,11 @@ static int macsec_newlink(struct net *net, struct net_device *dev,
                          struct netlink_ext_ack *extack)
 {
        struct macsec_dev *macsec = macsec_priv(dev);
+       rx_handler_func_t *rx_handler;
+       u8 icv_len = DEFAULT_ICV_LEN;
        struct net_device *real_dev;
-       int err;
+       int err, mtu;
        sci_t sci;
-       u8 icv_len = DEFAULT_ICV_LEN;
-       rx_handler_func_t *rx_handler;
 
        if (!tb[IFLA_LINK])
                return -EINVAL;
@@ -4033,7 +4033,11 @@ static int macsec_newlink(struct net *net, struct net_device *dev,
 
        if (data && data[IFLA_MACSEC_ICV_LEN])
                icv_len = nla_get_u8(data[IFLA_MACSEC_ICV_LEN]);
-       dev->mtu = real_dev->mtu - icv_len - macsec_extra_len(true);
+       mtu = real_dev->mtu - icv_len - macsec_extra_len(true);
+       if (mtu < 0)
+               dev->mtu = 0;
+       else
+               dev->mtu = mtu;
 
        rx_handler = rtnl_dereference(real_dev->rx_handler);
        if (rx_handler && rx_handler != macsec_handle_frame)
index e7289d67268fc72caf8fe186a8065454270b2190..0482adc9916bffee47e6f73e7c2495271eee37b3 100644 (file)
@@ -1704,7 +1704,7 @@ static int macvlan_device_event(struct notifier_block *unused,
                                                struct macvlan_dev,
                                                list);
 
-               if (macvlan_sync_address(vlan->dev, dev->dev_addr))
+               if (vlan && macvlan_sync_address(vlan->dev, dev->dev_addr))
                        return NOTIFY_BAD;
 
                break;
index 3840d2adbbb9a4eea910c31224ba4c00f51f3b7b..9717a1626f3fa1c4a1daea0e96858afc13472d95 100644 (file)
@@ -155,9 +155,6 @@ static int bcm84881_read_status(struct phy_device *phydev)
        if (phydev->autoneg == AUTONEG_ENABLE && !phydev->autoneg_complete)
                phydev->link = false;
 
-       if (!phydev->link)
-               return 0;
-
        linkmode_zero(phydev->lp_advertising);
        phydev->speed = SPEED_UNKNOWN;
        phydev->duplex = DUPLEX_UNKNOWN;
@@ -165,6 +162,9 @@ static int bcm84881_read_status(struct phy_device *phydev)
        phydev->asym_pause = 0;
        phydev->mdix = 0;
 
+       if (!phydev->link)
+               return 0;
+
        if (phydev->autoneg_complete) {
                val = genphy_c45_read_lpa(phydev);
                if (val < 0)
index 95e3f4644aeb2047256716455ee49dfcfa91f772..ff12492771ab7860f53aca370ae7fc04230921bb 100644 (file)
@@ -246,7 +246,8 @@ static int mv3310_power_up(struct phy_device *phydev)
        ret = phy_clear_bits_mmd(phydev, MDIO_MMD_VEND2, MV_V2_PORT_CTRL,
                                 MV_V2_PORT_CTRL_PWRDOWN);
 
-       if (priv->firmware_ver < 0x00030000)
+       if (phydev->drv->phy_id != MARVELL_PHY_ID_88X3310 ||
+           priv->firmware_ver < 0x00030000)
                return ret;
 
        return phy_set_bits_mmd(phydev, MDIO_MMD_VEND2, MV_V2_PORT_CTRL,
index 001def4509c29a79dd5ddee0a1f4b0532c99c43b..fed3e395f18e1c42bd81a5ef6537c18d8782f2ca 100644 (file)
@@ -3,9 +3,21 @@
 
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/delay.h>
 #include <linux/mii.h>
 #include <linux/phy.h>
 
+/* External Register Control Register */
+#define LAN87XX_EXT_REG_CTL                     (0x14)
+#define LAN87XX_EXT_REG_CTL_RD_CTL              (0x1000)
+#define LAN87XX_EXT_REG_CTL_WR_CTL              (0x0800)
+
+/* External Register Read Data Register */
+#define LAN87XX_EXT_REG_RD_DATA                 (0x15)
+
+/* External Register Write Data Register */
+#define LAN87XX_EXT_REG_WR_DATA                 (0x16)
+
 /* Interrupt Source Register */
 #define LAN87XX_INTERRUPT_SOURCE                (0x18)
 
 #define LAN87XX_MASK_LINK_UP                    (0x0004)
 #define LAN87XX_MASK_LINK_DOWN                  (0x0002)
 
+/* phyaccess nested types */
+#define        PHYACC_ATTR_MODE_READ           0
+#define        PHYACC_ATTR_MODE_WRITE          1
+#define        PHYACC_ATTR_MODE_MODIFY         2
+
+#define        PHYACC_ATTR_BANK_SMI            0
+#define        PHYACC_ATTR_BANK_MISC           1
+#define        PHYACC_ATTR_BANK_PCS            2
+#define        PHYACC_ATTR_BANK_AFE            3
+#define        PHYACC_ATTR_BANK_MAX            7
+
 #define DRIVER_AUTHOR  "Nisar Sayed <nisar.sayed@microchip.com>"
 #define DRIVER_DESC    "Microchip LAN87XX T1 PHY driver"
 
+struct access_ereg_val {
+       u8  mode;
+       u8  bank;
+       u8  offset;
+       u16 val;
+       u16 mask;
+};
+
+static int access_ereg(struct phy_device *phydev, u8 mode, u8 bank,
+                      u8 offset, u16 val)
+{
+       u16 ereg = 0;
+       int rc = 0;
+
+       if (mode > PHYACC_ATTR_MODE_WRITE || bank > PHYACC_ATTR_BANK_MAX)
+               return -EINVAL;
+
+       if (bank == PHYACC_ATTR_BANK_SMI) {
+               if (mode == PHYACC_ATTR_MODE_WRITE)
+                       rc = phy_write(phydev, offset, val);
+               else
+                       rc = phy_read(phydev, offset);
+               return rc;
+       }
+
+       if (mode == PHYACC_ATTR_MODE_WRITE) {
+               ereg = LAN87XX_EXT_REG_CTL_WR_CTL;
+               rc = phy_write(phydev, LAN87XX_EXT_REG_WR_DATA, val);
+               if (rc < 0)
+                       return rc;
+       } else {
+               ereg = LAN87XX_EXT_REG_CTL_RD_CTL;
+       }
+
+       ereg |= (bank << 8) | offset;
+
+       rc = phy_write(phydev, LAN87XX_EXT_REG_CTL, ereg);
+       if (rc < 0)
+               return rc;
+
+       if (mode == PHYACC_ATTR_MODE_READ)
+               rc = phy_read(phydev, LAN87XX_EXT_REG_RD_DATA);
+
+       return rc;
+}
+
+static int access_ereg_modify_changed(struct phy_device *phydev,
+                                     u8 bank, u8 offset, u16 val, u16 mask)
+{
+       int new = 0, rc = 0;
+
+       if (bank > PHYACC_ATTR_BANK_MAX)
+               return -EINVAL;
+
+       rc = access_ereg(phydev, PHYACC_ATTR_MODE_READ, bank, offset, val);
+       if (rc < 0)
+               return rc;
+
+       new = val | (rc & (mask ^ 0xFFFF));
+       rc = access_ereg(phydev, PHYACC_ATTR_MODE_WRITE, bank, offset, new);
+
+       return rc;
+}
+
+static int lan87xx_phy_init(struct phy_device *phydev)
+{
+       static const struct access_ereg_val init[] = {
+               /* TX Amplitude = 5 */
+               {PHYACC_ATTR_MODE_MODIFY, PHYACC_ATTR_BANK_AFE, 0x0B,
+                0x000A, 0x001E},
+               /* Clear SMI interrupts */
+               {PHYACC_ATTR_MODE_READ, PHYACC_ATTR_BANK_SMI, 0x18,
+                0, 0},
+               /* Clear MISC interrupts */
+               {PHYACC_ATTR_MODE_READ, PHYACC_ATTR_BANK_MISC, 0x08,
+                0, 0},
+               /* Turn on TC10 Ring Oscillator (ROSC) */
+               {PHYACC_ATTR_MODE_MODIFY, PHYACC_ATTR_BANK_MISC, 0x20,
+                0x0020, 0x0020},
+               /* WUR Detect Length to 1.2uS, LPC Detect Length to 1.09uS */
+               {PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_PCS, 0x20,
+                0x283C, 0},
+               /* Wake_In Debounce Length to 39uS, Wake_Out Length to 79uS */
+               {PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_MISC, 0x21,
+                0x274F, 0},
+               /* Enable Auto Wake Forward to Wake_Out, ROSC on, Sleep,
+                * and Wake_In to wake PHY
+                */
+               {PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_MISC, 0x20,
+                0x80A7, 0},
+               /* Enable WUP Auto Fwd, Enable Wake on MDI, Wakeup Debouncer
+                * to 128 uS
+                */
+               {PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_MISC, 0x24,
+                0xF110, 0},
+               /* Enable HW Init */
+               {PHYACC_ATTR_MODE_MODIFY, PHYACC_ATTR_BANK_SMI, 0x1A,
+                0x0100, 0x0100},
+       };
+       int rc, i;
+
+       /* Start manual initialization procedures in Managed Mode */
+       rc = access_ereg_modify_changed(phydev, PHYACC_ATTR_BANK_SMI,
+                                       0x1a, 0x0000, 0x0100);
+       if (rc < 0)
+               return rc;
+
+       /* Soft Reset the SMI block */
+       rc = access_ereg_modify_changed(phydev, PHYACC_ATTR_BANK_SMI,
+                                       0x00, 0x8000, 0x8000);
+       if (rc < 0)
+               return rc;
+
+       /* Check to see if the self-clearing bit is cleared */
+       usleep_range(1000, 2000);
+       rc = access_ereg(phydev, PHYACC_ATTR_MODE_READ,
+                        PHYACC_ATTR_BANK_SMI, 0x00, 0);
+       if (rc < 0)
+               return rc;
+       if ((rc & 0x8000) != 0)
+               return -ETIMEDOUT;
+
+       /* PHY Initialization */
+       for (i = 0; i < ARRAY_SIZE(init); i++) {
+               if (init[i].mode == PHYACC_ATTR_MODE_MODIFY) {
+                       rc = access_ereg_modify_changed(phydev, init[i].bank,
+                                                       init[i].offset,
+                                                       init[i].val,
+                                                       init[i].mask);
+               } else {
+                       rc = access_ereg(phydev, init[i].mode, init[i].bank,
+                                        init[i].offset, init[i].val);
+               }
+               if (rc < 0)
+                       return rc;
+       }
+
+       return 0;
+}
+
 static int lan87xx_phy_config_intr(struct phy_device *phydev)
 {
        int rc, val = 0;
@@ -40,6 +203,13 @@ static int lan87xx_phy_ack_interrupt(struct phy_device *phydev)
        return rc < 0 ? rc : 0;
 }
 
+static int lan87xx_config_init(struct phy_device *phydev)
+{
+       int rc = lan87xx_phy_init(phydev);
+
+       return rc < 0 ? rc : 0;
+}
+
 static struct phy_driver microchip_t1_phy_driver[] = {
        {
                .phy_id         = 0x0007c150,
@@ -48,6 +218,7 @@ static struct phy_driver microchip_t1_phy_driver[] = {
 
                .features       = PHY_BASIC_T1_FEATURES,
 
+               .config_init    = lan87xx_config_init,
                .config_aneg    = genphy_config_aneg,
 
                .ack_interrupt  = lan87xx_phy_ack_interrupt,
index 4004f98e50d9fc58a8d8d6449448840d3c9da748..04845a4017f935f3cdff0fbbbc41d281ab641672 100644 (file)
@@ -468,6 +468,9 @@ static const struct team_mode *team_mode_get(const char *kind)
        struct team_mode_item *mitem;
        const struct team_mode *mode = NULL;
 
+       if (!try_module_get(THIS_MODULE))
+               return NULL;
+
        spin_lock(&mode_list_lock);
        mitem = __find_mode(kind);
        if (!mitem) {
@@ -483,6 +486,7 @@ static const struct team_mode *team_mode_get(const char *kind)
        }
 
        spin_unlock(&mode_list_lock);
+       module_put(THIS_MODULE);
        return mode;
 }
 
index 66e00ddc0d421009be4ed5a61d510408e45aabbf..56f8aab46f89ba03ba28f7919b877260659f46e8 100644 (file)
@@ -188,8 +188,8 @@ static netdev_tx_t vrf_process_v6_outbound(struct sk_buff *skb,
        fl6.flowi6_proto = iph->nexthdr;
        fl6.flowi6_flags = FLOWI_FLAG_SKIP_NH_OIF;
 
-       dst = ip6_route_output(net, NULL, &fl6);
-       if (dst == dst_null)
+       dst = ip6_dst_lookup_flow(net, NULL, &fl6, NULL);
+       if (IS_ERR(dst) || dst == dst_null)
                goto err;
 
        skb_dst_drop(skb);
@@ -474,7 +474,8 @@ static struct sk_buff *vrf_ip6_out(struct net_device *vrf_dev,
        if (rt6_need_strict(&ipv6_hdr(skb)->daddr))
                return skb;
 
-       if (qdisc_tx_is_default(vrf_dev))
+       if (qdisc_tx_is_default(vrf_dev) ||
+           IP6CB(skb)->flags & IP6SKB_XFRM_TRANSFORMED)
                return vrf_ip6_out_direct(vrf_dev, sk, skb);
 
        return vrf_ip6_out_redirect(vrf_dev, skb);
@@ -686,7 +687,8 @@ static struct sk_buff *vrf_ip_out(struct net_device *vrf_dev,
            ipv4_is_lbcast(ip_hdr(skb)->daddr))
                return skb;
 
-       if (qdisc_tx_is_default(vrf_dev))
+       if (qdisc_tx_is_default(vrf_dev) ||
+           IPCB(skb)->flags & IPSKB_XFRM_TRANSFORMED)
                return vrf_ip_out_direct(vrf_dev, sk, skb);
 
        return vrf_ip_out_redirect(vrf_dev, skb);
index 45308b3350cf5f4934a9a6cfc7548a7b4175fc15..a5b415fed11efb8c6e2dcd30554ea6c10835d0ab 100644 (file)
@@ -3144,7 +3144,7 @@ static int vxlan_validate(struct nlattr *tb[], struct nlattr *data[],
                u32 id = nla_get_u32(data[IFLA_VXLAN_ID]);
 
                if (id >= VXLAN_N_VID) {
-                       NL_SET_ERR_MSG_ATTR(extack, tb[IFLA_VXLAN_ID],
+                       NL_SET_ERR_MSG_ATTR(extack, data[IFLA_VXLAN_ID],
                                            "VXLAN ID must be lower than 16777216");
                        return -ERANGE;
                }
@@ -3155,7 +3155,7 @@ static int vxlan_validate(struct nlattr *tb[], struct nlattr *data[],
                        = nla_data(data[IFLA_VXLAN_PORT_RANGE]);
 
                if (ntohs(p->high) < ntohs(p->low)) {
-                       NL_SET_ERR_MSG_ATTR(extack, tb[IFLA_VXLAN_PORT_RANGE],
+                       NL_SET_ERR_MSG_ATTR(extack, data[IFLA_VXLAN_PORT_RANGE],
                                            "Invalid source port range");
                        return -EINVAL;
                }
@@ -3165,7 +3165,7 @@ static int vxlan_validate(struct nlattr *tb[], struct nlattr *data[],
                enum ifla_vxlan_df df = nla_get_u8(data[IFLA_VXLAN_DF]);
 
                if (df < 0 || df > VXLAN_DF_MAX) {
-                       NL_SET_ERR_MSG_ATTR(extack, tb[IFLA_VXLAN_DF],
+                       NL_SET_ERR_MSG_ATTR(extack, data[IFLA_VXLAN_DF],
                                            "Invalid DF attribute");
                        return -EINVAL;
                }
index 529ebca1e9e13eb94d4574a29172ec311e614e58..1f7709d24f3526a1498a9f5a2f85e79c71ab811f 100644 (file)
@@ -354,6 +354,7 @@ out:
                usb_autopm_put_interface(i2400mu->usb_iface);
        d_fnend(8, dev, "(i2400m %p ack %p size %zu) = %ld\n",
                i2400m, ack, ack_size, (long) result);
+       usb_put_urb(&notif_urb);
        return result;
 
 error_exceeded:
index 6209f85a71ddb3438ed68a310a2de71e7280a778..0af9e997c9f6766e21ccf7b8d1b72a37a6622577 100644 (file)
@@ -374,7 +374,7 @@ out:
 }
 
 static void *
-il3945_rs_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir)
+il3945_rs_alloc(struct ieee80211_hw *hw)
 {
        return hw->priv;
 }
index 7c6e2c8634974dee2df38b8530d157ae4bbbffa2..0a02d8aca320619c0186a9d5e407faf1fcfa9064 100644 (file)
@@ -2474,7 +2474,7 @@ il4965_rs_fill_link_cmd(struct il_priv *il, struct il_lq_sta *lq_sta,
 }
 
 static void *
-il4965_rs_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir)
+il4965_rs_alloc(struct ieee80211_hw *hw)
 {
        return hw->priv;
 }
index 226165db7dfd5bfc46007192512993c0864f75be..dac809df7f1dd05e9db77c8bc2634f44761b9e7d 100644 (file)
@@ -3019,7 +3019,7 @@ static void rs_fill_link_cmd(struct iwl_priv *priv,
                        cpu_to_le16(priv->lib->bt_params->agg_time_limit);
 }
 
-static void *rs_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir)
+static void *rs_alloc(struct ieee80211_hw *hw)
 {
        return hw->priv;
 }
index ba2aff3af0fe9218ed1311e0e56a0c1d95f0a283..e3a33388be701464949af1c0d8e08518247233b9 100644 (file)
@@ -296,9 +296,14 @@ int iwl_sar_select_profile(struct iwl_fw_runtime *fwrt,
                if (!prof->enabled) {
                        IWL_DEBUG_RADIO(fwrt, "SAR profile %d is disabled.\n",
                                        profs[i]);
-                       /* if one of the profiles is disabled, we fail all */
-                       return -ENOENT;
+                       /*
+                        * if one of the profiles is disabled, we
+                        * ignore all of them and return 1 to
+                        * differentiate disabled from other failures.
+                        */
+                       return 1;
                }
+
                IWL_DEBUG_INFO(fwrt,
                               "SAR EWRD: chain %d profile index %d\n",
                               i, profs[i]);
index 73196cbc7fbefd8bb1511adda2ddbd7474664e2c..75d958bab0e380317192f22c339abd909456e63f 100644 (file)
@@ -8,7 +8,7 @@
  * Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved.
  * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
  * Copyright(c) 2016 - 2017 Intel Deutschland GmbH
- * Copyright(c) 2019 Intel Corporation
+ * Copyright(c) 2019 - 2020 Intel Corporation
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of version 2 of the GNU General Public License as
@@ -31,7 +31,7 @@
  * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
  * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
  * Copyright(c) 2016 - 2017 Intel Deutschland GmbH
- * Copyright(c) 2019 Intel Corporation
+ * Copyright(c) 2019 - 2020 Intel Corporation
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -99,7 +99,7 @@ enum iwl_mvm_dqa_txq {
        IWL_MVM_DQA_MAX_MGMT_QUEUE = 8,
        IWL_MVM_DQA_AP_PROBE_RESP_QUEUE = 9,
        IWL_MVM_DQA_MIN_DATA_QUEUE = 10,
-       IWL_MVM_DQA_MAX_DATA_QUEUE = 31,
+       IWL_MVM_DQA_MAX_DATA_QUEUE = 30,
 };
 
 enum iwl_mvm_tx_fifo {
index ff52e69c1c80a7664ace9470554a56b0c954f1b3..eeb750bdbda130400fe1d0052059880e253aa6e4 100644 (file)
@@ -1467,7 +1467,7 @@ static void iwl_req_fw_callback(const struct firmware *ucode_raw, void *context)
                                kmemdup(pieces->dbg_conf_tlv[i],
                                        pieces->dbg_conf_tlv_len[i],
                                        GFP_KERNEL);
-                       if (!pieces->dbg_conf_tlv[i])
+                       if (!drv->fw.dbg.conf_tlv[i])
                                goto out_free_fw;
                }
        }
index 9e9810d2b26221650b6f958a329d8bdc2f7706ed..ccf0bc16465d20c08948b5ea3c97e850c59ee84f 100644 (file)
@@ -532,8 +532,7 @@ static struct ieee80211_sband_iftype_data iwl_he_capa[] = {
                                        IEEE80211_HE_MAC_CAP1_TF_MAC_PAD_DUR_16US |
                                        IEEE80211_HE_MAC_CAP1_MULTI_TID_AGG_RX_QOS_8,
                                .mac_cap_info[2] =
-                                       IEEE80211_HE_MAC_CAP2_32BIT_BA_BITMAP |
-                                       IEEE80211_HE_MAC_CAP2_ACK_EN,
+                                       IEEE80211_HE_MAC_CAP2_32BIT_BA_BITMAP,
                                .mac_cap_info[3] =
                                        IEEE80211_HE_MAC_CAP3_OMI_CONTROL |
                                        IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_VHT_2,
@@ -617,8 +616,7 @@ static struct ieee80211_sband_iftype_data iwl_he_capa[] = {
                                        IEEE80211_HE_MAC_CAP1_TF_MAC_PAD_DUR_16US |
                                        IEEE80211_HE_MAC_CAP1_MULTI_TID_AGG_RX_QOS_8,
                                .mac_cap_info[2] =
-                                       IEEE80211_HE_MAC_CAP2_BSR |
-                                       IEEE80211_HE_MAC_CAP2_ACK_EN,
+                                       IEEE80211_HE_MAC_CAP2_BSR,
                                .mac_cap_info[3] =
                                        IEEE80211_HE_MAC_CAP3_OMI_CONTROL |
                                        IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_VHT_2,
index a4038f289ab31244c1681e37044724a814104ca1..e67c452fa92cff0b09d75f03fcfc3c984ea0246a 100644 (file)
@@ -727,6 +727,7 @@ int iwl_mvm_sar_select_profile(struct iwl_mvm *mvm, int prof_a, int prof_b)
                struct iwl_dev_tx_power_cmd_v4 v4;
        } cmd;
 
+       int ret;
        u16 len = 0;
 
        cmd.v5.v3.set_mode = cpu_to_le32(IWL_TX_POWER_MODE_SET_CHAINS);
@@ -741,9 +742,14 @@ int iwl_mvm_sar_select_profile(struct iwl_mvm *mvm, int prof_a, int prof_b)
                len = sizeof(cmd.v4.v3);
 
 
-       if (iwl_sar_select_profile(&mvm->fwrt, cmd.v5.v3.per_chain_restriction,
-                                  prof_a, prof_b))
-               return -ENOENT;
+       ret = iwl_sar_select_profile(&mvm->fwrt,
+                                    cmd.v5.v3.per_chain_restriction,
+                                    prof_a, prof_b);
+
+       /* return on error or if the profile is disabled (positive number) */
+       if (ret)
+               return ret;
+
        IWL_DEBUG_RADIO(mvm, "Sending REDUCE_TX_POWER_CMD per chain\n");
        return iwl_mvm_send_cmd_pdu(mvm, REDUCE_TX_POWER_CMD, 0, len, &cmd);
 }
@@ -1034,16 +1040,7 @@ static int iwl_mvm_sar_init(struct iwl_mvm *mvm)
                                "EWRD SAR BIOS table invalid or unavailable. (%d)\n",
                                ret);
 
-       ret = iwl_mvm_sar_select_profile(mvm, 1, 1);
-       /*
-        * If we don't have profile 0 from BIOS, just skip it.  This
-        * means that SAR Geo will not be enabled either, even if we
-        * have other valid profiles.
-        */
-       if (ret == -ENOENT)
-               return 1;
-
-       return ret;
+       return iwl_mvm_sar_select_profile(mvm, 1, 1);
 }
 
 static int iwl_mvm_load_rt_fw(struct iwl_mvm *mvm)
@@ -1272,7 +1269,7 @@ int iwl_mvm_up(struct iwl_mvm *mvm)
        ret = iwl_mvm_sar_init(mvm);
        if (ret == 0) {
                ret = iwl_mvm_sar_geo_init(mvm);
-       } else if (ret > 0 && !iwl_sar_get_wgds_table(&mvm->fwrt)) {
+       } else if (ret == -ENOENT && !iwl_sar_get_wgds_table(&mvm->fwrt)) {
                /*
                 * If basic SAR is not available, we check for WGDS,
                 * which should *not* be available either.  If it is
index c1aba2bf73cff4b0732d76f21b05fa8c79ee22ad..00e7fdbaeb7fd8104a536bfa45d75610860ea131 100644 (file)
@@ -3665,7 +3665,7 @@ static void rs_fill_lq_cmd(struct iwl_mvm *mvm,
                        cpu_to_le16(iwl_mvm_coex_agg_time_limit(mvm, sta));
 }
 
-static void *rs_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir)
+static void *rs_alloc(struct ieee80211_hw *hw)
 {
        return hw->priv;
 }
index 5ee33c8ae9d24cd55b38be4cf745a92fd19e85f3..77b8def26edb225130670a05c8ad204880bd7641 100644 (file)
@@ -8,7 +8,7 @@
  * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
  * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
  * Copyright(c) 2016 - 2017 Intel Deutschland GmbH
- * Copyright(c) 2018 - 2019 Intel Corporation
+ * Copyright(c) 2018 - 2020 Intel Corporation
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of version 2 of the GNU General Public License as
@@ -31,7 +31,7 @@
  * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
  * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
  * Copyright(c) 2016 - 2017 Intel Deutschland GmbH
- * Copyright(c) 2018 - 2019 Intel Corporation
+ * Copyright(c) 2018 - 2020 Intel Corporation
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -566,6 +566,7 @@ void iwl_mvm_rx_rx_mpdu(struct iwl_mvm *mvm, struct napi_struct *napi,
 
 struct iwl_mvm_stat_data {
        struct iwl_mvm *mvm;
+       __le32 flags;
        __le32 mac_id;
        u8 beacon_filter_average_energy;
        void *general;
@@ -606,6 +607,13 @@ static void iwl_mvm_stat_iterator(void *_data, u8 *mac,
                        -general->beacon_average_energy[vif_id];
        }
 
+       /* make sure that beacon statistics don't go backwards with TCM
+        * request to clear statistics
+        */
+       if (le32_to_cpu(data->flags) & IWL_STATISTICS_REPLY_FLG_CLEAR)
+               mvmvif->beacon_stats.accu_num_beacons +=
+                       mvmvif->beacon_stats.num_beacons;
+
        if (mvmvif->id != id)
                return;
 
@@ -763,6 +771,7 @@ void iwl_mvm_handle_rx_statistics(struct iwl_mvm *mvm,
 
                flags = stats->flag;
        }
+       data.flags = flags;
 
        iwl_mvm_rx_stats_check_trigger(mvm, pkt);
 
index 64ef3f3ba23b7d229afaf0ea7f144858abfc398c..56ae72debb96a0e510da48d0a127b473f1aaab4b 100644 (file)
@@ -722,6 +722,11 @@ static int iwl_mvm_find_free_queue(struct iwl_mvm *mvm, u8 sta_id,
 
        lockdep_assert_held(&mvm->mutex);
 
+       if (WARN(maxq >= mvm->trans->trans_cfg->base_params->num_of_queues,
+                "max queue %d >= num_of_queues (%d)", maxq,
+                mvm->trans->trans_cfg->base_params->num_of_queues))
+               maxq = mvm->trans->trans_cfg->base_params->num_of_queues - 1;
+
        /* This should not be hit with new TX path */
        if (WARN_ON(iwl_mvm_has_new_tx_api(mvm)))
                return -ENOSPC;
@@ -1164,9 +1169,9 @@ static int iwl_mvm_inactivity_check(struct iwl_mvm *mvm, u8 alloc_for_sta)
                                                   inactive_tid_bitmap,
                                                   &unshare_queues,
                                                   &changetid_queues);
-               if (ret >= 0 && free_queue < 0) {
+               if (ret && free_queue < 0) {
                        queue_owner = sta;
-                       free_queue = ret;
+                       free_queue = i;
                }
                /* only unlock sta lock - we still need the queue info lock */
                spin_unlock_bh(&mvmsta->lock);
index 01f248ba8fecfd6ead64945fc62ef35943f95e9d..9d5b1e51b50d7385afa6a4d3efd5f14952d4541a 100644 (file)
@@ -129,6 +129,18 @@ int iwl_pcie_ctxt_info_gen3_init(struct iwl_trans *trans,
        int cmdq_size = max_t(u32, IWL_CMD_QUEUE_SIZE,
                              trans->cfg->min_txq_size);
 
+       switch (trans_pcie->rx_buf_size) {
+       case IWL_AMSDU_DEF:
+               return -EINVAL;
+       case IWL_AMSDU_2K:
+               break;
+       case IWL_AMSDU_4K:
+       case IWL_AMSDU_8K:
+       case IWL_AMSDU_12K:
+               control_flags |= IWL_PRPH_SCRATCH_RB_SIZE_4K;
+               break;
+       }
+
        /* Allocate prph scratch */
        prph_scratch = dma_alloc_coherent(trans->dev, sizeof(*prph_scratch),
                                          &trans_pcie->prph_scratch_dma_addr,
@@ -143,10 +155,8 @@ int iwl_pcie_ctxt_info_gen3_init(struct iwl_trans *trans,
                cpu_to_le16((u16)iwl_read32(trans, CSR_HW_REV));
        prph_sc_ctrl->version.size = cpu_to_le16(sizeof(*prph_scratch) / 4);
 
-       control_flags = IWL_PRPH_SCRATCH_RB_SIZE_4K |
-                       IWL_PRPH_SCRATCH_MTR_MODE |
-                       (IWL_PRPH_MTR_FORMAT_256B &
-                        IWL_PRPH_SCRATCH_MTR_FORMAT);
+       control_flags |= IWL_PRPH_SCRATCH_MTR_MODE;
+       control_flags |= IWL_PRPH_MTR_FORMAT_256B & IWL_PRPH_SCRATCH_MTR_FORMAT;
 
        /* initialize RX default queue */
        prph_sc_ctrl->rbd_cfg.free_rbd_addr =
index 86fc001678174cd278af0c29eb93218ea4ed8159..9664dbc70ef1cfcd0ae30eff58a5562ab9ce06c3 100644 (file)
@@ -1418,6 +1418,9 @@ void iwl_trans_pcie_dyn_txq_free(struct iwl_trans *trans, int queue)
 
        iwl_pcie_gen2_txq_unmap(trans, queue);
 
+       iwl_pcie_gen2_txq_free_memory(trans, trans_pcie->txq[queue]);
+       trans_pcie->txq[queue] = NULL;
+
        IWL_DEBUG_TX_QUEUES(trans, "Deactivate queue %d\n", queue);
 }
 
index 7c4b7c31d07ab88e86a41dc5e1491b6edff1bef5..0528d4cb4d37478bbed6008b20dde478e5390f87 100644 (file)
@@ -4068,7 +4068,7 @@ static void hwsim_virtio_rx_work(struct work_struct *work)
        }
        vq = hwsim_vqs[HWSIM_VQ_RX];
        sg_init_one(sg, skb->head, skb_end_offset(skb));
-       err = virtqueue_add_inbuf(vq, sg, 1, skb, GFP_KERNEL);
+       err = virtqueue_add_inbuf(vq, sg, 1, skb, GFP_ATOMIC);
        if (WARN(err, "virtqueue_add_inbuf returned %d\n", err))
                nlmsg_free(skb);
        else
index 0c7d74902d33b7dd361d7ba31924b3809f476e12..4b5ea0ec9109362e97833a5f32b904fe6e6e4184 100644 (file)
@@ -261,7 +261,7 @@ static void rtl_rate_update(void *ppriv,
 {
 }
 
-static void *rtl_rate_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir)
+static void *rtl_rate_alloc(struct ieee80211_hw *hw)
 {
        struct rtl_priv *rtlpriv = rtl_priv(hw);
        return rtlpriv;
index 28c9a2409c50eceb3bc9c9722ee417421151ecc0..ca9ed5774eb1bfefb372fc87a9635788ea5b24f5 100644 (file)
@@ -5567,3 +5567,10 @@ static void pci_fixup_no_d0_pme(struct pci_dev *dev)
        dev->pme_support &= ~(PCI_PM_CAP_PME_D0 >> PCI_PM_CAP_PME_SHIFT);
 }
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ASMEDIA, 0x2142, pci_fixup_no_d0_pme);
+
+static void apex_pci_fixup_class(struct pci_dev *pdev)
+{
+       pdev->class = (PCI_CLASS_SYSTEM_OTHER << 8) | pdev->class;
+}
+DECLARE_PCI_FIXUP_CLASS_HEADER(0x1ac1, 0x089a,
+                              PCI_CLASS_NOT_DEFINED, 8, apex_pci_fixup_class);
index a208aca4ba7b376bfc350bc8f082dca93b21ac3b..c591c958f1ebc56ec33dd9c01f51a656f9866e7a 100644 (file)
@@ -1,7 +1,8 @@
 # SPDX-License-Identifier: GPL-2.0-only
 config PHY_TEGRA_XUSB
        tristate "NVIDIA Tegra XUSB pad controller driver"
-       depends on ARCH_TEGRA
+       depends on ARCH_TEGRA && USB_SUPPORT
+       select USB_COMMON
        select USB_CONN_GPIO
        select USB_PHY
        help
index dfda54cbd86638b18c229b0ea1dcde3bc4b7cda6..52d77db39829295c614434b4a6d64934905c7aa0 100644 (file)
@@ -400,8 +400,8 @@ static int ines_hwtstamp(struct mii_timestamper *mii_ts, struct ifreq *ifr)
        ines_write32(port, ts_stat_rx, ts_stat_rx);
        ines_write32(port, ts_stat_tx, ts_stat_tx);
 
-       port->rxts_enabled = ts_stat_rx == TS_ENABLE ? true : false;
-       port->txts_enabled = ts_stat_tx == TS_ENABLE ? true : false;
+       port->rxts_enabled = ts_stat_rx == TS_ENABLE;
+       port->txts_enabled = ts_stat_tx == TS_ENABLE;
 
        spin_unlock_irqrestore(&port->lock, flags);
 
index deb20096146a44b25b14e333327d5a0e5cb747e8..0066c83636d08bbcf9f60da7cfe511268f5cc430 100644 (file)
@@ -68,7 +68,7 @@ struct mtk_scp {
        wait_queue_head_t ack_wq;
 
        void __iomem *cpu_addr;
-       phys_addr_t phys_addr;
+       dma_addr_t dma_addr;
        size_t dram_size;
 
        struct rproc_subdev *rpmsg_subdev;
index ea3743e7e794f04797f3b3183abb7fadc4f0007b..2bead57c9cf9b1dfa0220c56c8231ab33ea91fb9 100644 (file)
@@ -330,7 +330,7 @@ static void *scp_da_to_va(struct rproc *rproc, u64 da, size_t len)
                if (offset >= 0 && (offset + len) < scp->sram_size)
                        return (void __force *)scp->sram_base + offset;
        } else {
-               offset = da - scp->phys_addr;
+               offset = da - scp->dma_addr;
                if (offset >= 0 && (offset + len) < scp->dram_size)
                        return (void __force *)scp->cpu_addr + offset;
        }
@@ -451,7 +451,7 @@ static int scp_map_memory_region(struct mtk_scp *scp)
        /* Reserved SCP code size */
        scp->dram_size = MAX_CODE_SIZE;
        scp->cpu_addr = dma_alloc_coherent(scp->dev, scp->dram_size,
-                                          &scp->phys_addr, GFP_KERNEL);
+                                          &scp->dma_addr, GFP_KERNEL);
        if (!scp->cpu_addr)
                return -ENOMEM;
 
@@ -461,7 +461,7 @@ static int scp_map_memory_region(struct mtk_scp *scp)
 static void scp_unmap_memory_region(struct mtk_scp *scp)
 {
        dma_free_coherent(scp->dev, scp->dram_size, scp->cpu_addr,
-                         scp->phys_addr);
+                         scp->dma_addr);
        of_reserved_mem_device_release(scp->dev);
 }
 
index ce49c3236ff7c83e00cbb7491c9db320c92cef44..5475d4f808a8e3b3e4945a5255050ff0da5611b5 100644 (file)
@@ -367,7 +367,7 @@ unroll_pd_votes:
        }
 
        return ret;
-};
+}
 
 static void q6v5_pds_disable(struct q6v5 *qproc, struct device **pds,
                             size_t pd_count)
@@ -1527,7 +1527,7 @@ unroll_attach:
                dev_pm_domain_detach(devs[i], false);
 
        return ret;
-};
+}
 
 static void q6v5_pds_detach(struct q6v5 *qproc, struct device **pds,
                            size_t pd_count)
@@ -1675,7 +1675,7 @@ static int q6v5_probe(struct platform_device *pdev)
        ret = of_property_read_string_index(pdev->dev.of_node, "firmware-name",
                                            1, &qproc->hexagon_mdt_image);
        if (ret < 0 && ret != -EINVAL)
-               return ret;
+               goto free_rproc;
 
        platform_set_drvdata(pdev, qproc);
 
@@ -1766,17 +1766,23 @@ static int q6v5_probe(struct platform_device *pdev)
        qproc->sysmon = qcom_add_sysmon_subdev(rproc, "modem", 0x12);
        if (IS_ERR(qproc->sysmon)) {
                ret = PTR_ERR(qproc->sysmon);
-               goto detach_proxy_pds;
+               goto remove_subdevs;
        }
 
        ret = rproc_add(rproc);
        if (ret)
-               goto detach_proxy_pds;
+               goto remove_sysmon_subdev;
 
        return 0;
 
-detach_proxy_pds:
+remove_sysmon_subdev:
+       qcom_remove_sysmon_subdev(qproc->sysmon);
+remove_subdevs:
        qcom_remove_ipa_notify_subdev(qproc->rproc, &qproc->ipa_notify_subdev);
+       qcom_remove_ssr_subdev(rproc, &qproc->ssr_subdev);
+       qcom_remove_smd_subdev(rproc, &qproc->smd_subdev);
+       qcom_remove_glink_subdev(rproc, &qproc->glink_subdev);
+detach_proxy_pds:
        q6v5_pds_detach(qproc, qproc->proxy_pds, qproc->proxy_pd_count);
 detach_active_pds:
        q6v5_pds_detach(qproc, qproc->active_pds, qproc->active_pd_count);
@@ -1789,19 +1795,20 @@ free_rproc:
 static int q6v5_remove(struct platform_device *pdev)
 {
        struct q6v5 *qproc = platform_get_drvdata(pdev);
+       struct rproc *rproc = qproc->rproc;
 
-       rproc_del(qproc->rproc);
+       rproc_del(rproc);
 
        qcom_remove_sysmon_subdev(qproc->sysmon);
-       qcom_remove_ipa_notify_subdev(qproc->rproc, &qproc->ipa_notify_subdev);
-       qcom_remove_glink_subdev(qproc->rproc, &qproc->glink_subdev);
-       qcom_remove_smd_subdev(qproc->rproc, &qproc->smd_subdev);
-       qcom_remove_ssr_subdev(qproc->rproc, &qproc->ssr_subdev);
+       qcom_remove_ipa_notify_subdev(rproc, &qproc->ipa_notify_subdev);
+       qcom_remove_ssr_subdev(rproc, &qproc->ssr_subdev);
+       qcom_remove_smd_subdev(rproc, &qproc->smd_subdev);
+       qcom_remove_glink_subdev(rproc, &qproc->glink_subdev);
 
-       q6v5_pds_detach(qproc, qproc->active_pds, qproc->active_pd_count);
        q6v5_pds_detach(qproc, qproc->proxy_pds, qproc->proxy_pd_count);
+       q6v5_pds_detach(qproc, qproc->active_pds, qproc->active_pd_count);
 
-       rproc_free(qproc->rproc);
+       rproc_free(rproc);
 
        return 0;
 }
index 7f8536b73295d50d85dae7203e7fea8443a6941b..52b871327b55351baabd81c03a3f5d45580bd7b9 100644 (file)
@@ -4,6 +4,7 @@
  */
 
 #include <linux/remoteproc.h>
+#include <linux/slab.h>
 
 #include "remoteproc_internal.h"
 
index 6a66dbf2df407db0371649d219b5a55247f32a86..0bdd56f02f1834a372b18ee76317fa85f6530cb2 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/regmap.h>
 #include <linux/remoteproc.h>
 #include <linux/reset.h>
+#include <linux/slab.h>
 #include <linux/workqueue.h>
 
 #include "remoteproc_internal.h"
index 232aa4e4013362124ba828c9a08a0fa93c210fb0..83f2b8804ee989df521372b879e709cb9d129cf5 100644 (file)
@@ -8,6 +8,7 @@
 #include <linux/platform_device.h>
 #include <linux/remoteproc.h>
 #include <linux/rpmsg/mtk_rpmsg.h>
+#include <linux/slab.h>
 #include <linux/workqueue.h>
 
 #include "rpmsg_internal.h"
index 17feff174f574930a096d0101b0cc5affdd981d8..2017c43dac1bcacad82c3b836ae1f97bf67aee34 100644 (file)
@@ -127,7 +127,7 @@ config CHR_DEV_SG
 
          For scanners, look at SANE (<http://www.sane-project.org/>). For CD
          writer software look at Cdrtools
-         (<http://cdrecord.berlios.de/private/cdrecord.html>)
+         (<http://cdrtools.sourceforge.net/>)
          and for burning a "disk at once": CDRDAO
          (<http://cdrdao.sourceforge.net/>). Cdparanoia is a high
          quality digital reader of audio CDs (<http://www.xiph.org/paranoia/>).
index 9c0ee192f0f9c8e9825c01b6fd91b9df96bbcd5b..20472aaaf630a4627abaa4287dbfe2a384474b49 100644 (file)
@@ -685,8 +685,10 @@ sg_write(struct file *filp, const char __user *buf, size_t count, loff_t * ppos)
        hp->flags = input_size; /* structure abuse ... */
        hp->pack_id = old_hdr.pack_id;
        hp->usr_ptr = NULL;
-       if (copy_from_user(cmnd, buf, cmd_size))
+       if (copy_from_user(cmnd, buf, cmd_size)) {
+               sg_remove_request(sfp, srp);
                return -EFAULT;
+       }
        /*
         * SG_DXFER_TO_FROM_DEV is functionally equivalent to SG_DXFER_FROM_DEV,
         * but is is possible that the app intended SG_DXFER_TO_DEV, because there
index cd4f6410e8c2f89cdf94c3f2c1ab356449f7a205..bcdcd3e7d7f12571f68ef453eeb12ca438c0c4f2 100644 (file)
@@ -478,12 +478,18 @@ int dpaa2_io_service_enqueue_multiple_desc_fq(struct dpaa2_io *d,
                                const struct dpaa2_fd *fd,
                                int nb)
 {
-       int i;
-       struct qbman_eq_desc ed[32];
+       struct qbman_eq_desc *ed;
+       int i, ret;
+
+       ed = kcalloc(sizeof(struct qbman_eq_desc), 32, GFP_KERNEL);
+       if (!ed)
+               return -ENOMEM;
 
        d = service_select(d);
-       if (!d)
-               return -ENODEV;
+       if (!d) {
+               ret = -ENODEV;
+               goto out;
+       }
 
        for (i = 0; i < nb; i++) {
                qbman_eq_desc_clear(&ed[i]);
@@ -491,7 +497,10 @@ int dpaa2_io_service_enqueue_multiple_desc_fq(struct dpaa2_io *d,
                qbman_eq_desc_set_fq(&ed[i], fqid[i]);
        }
 
-       return qbman_swp_enqueue_multiple_desc(d->swp, &ed[0], fd, nb);
+       ret = qbman_swp_enqueue_multiple_desc(d->swp, &ed[0], fd, nb);
+out:
+       kfree(ed);
+       return ret;
 }
 EXPORT_SYMBOL(dpaa2_io_service_enqueue_multiple_desc_fq);
 
index d1f49caa5b13779e9e9106f5fa4841f83c5e9be6..804b8ba9bf5c949e9df56aab130e53e2a99f8e94 100644 (file)
@@ -753,7 +753,7 @@ int qbman_swp_enqueue_multiple_mem_back(struct qbman_swp *s,
        if (!s->eqcr.available) {
                eqcr_ci = s->eqcr.ci;
                p = s->addr_cena + QBMAN_CENA_SWP_EQCR_CI_MEMBACK;
-               s->eqcr.ci = __raw_readl(p) & full_mask;
+               s->eqcr.ci = *p & full_mask;
                s->eqcr.available = qm_cyc_diff(s->eqcr.pi_ring_size,
                                        eqcr_ci, s->eqcr.ci);
                if (!s->eqcr.available) {
@@ -823,7 +823,6 @@ int qbman_swp_enqueue_multiple_desc_direct(struct qbman_swp *s,
        const uint32_t *cl;
        uint32_t eqcr_ci, eqcr_pi, half_mask, full_mask;
        int i, num_enqueued = 0;
-       uint64_t addr_cena;
 
        half_mask = (s->eqcr.pi_ci_mask>>1);
        full_mask = s->eqcr.pi_ci_mask;
@@ -867,7 +866,6 @@ int qbman_swp_enqueue_multiple_desc_direct(struct qbman_swp *s,
 
        /* Flush all the cacheline without load/store in between */
        eqcr_pi = s->eqcr.pi;
-       addr_cena = (uint64_t)s->addr_cena;
        for (i = 0; i < num_enqueued; i++)
                eqcr_pi++;
        s->eqcr.pi = eqcr_pi & full_mask;
@@ -901,7 +899,7 @@ int qbman_swp_enqueue_multiple_desc_mem_back(struct qbman_swp *s,
        if (!s->eqcr.available) {
                eqcr_ci = s->eqcr.ci;
                p = s->addr_cena + QBMAN_CENA_SWP_EQCR_CI_MEMBACK;
-               s->eqcr.ci = __raw_readl(p) & full_mask;
+               s->eqcr.ci = *p & full_mask;
                s->eqcr.available = qm_cyc_diff(s->eqcr.pi_ring_size,
                                        eqcr_ci, s->eqcr.ci);
                if (!s->eqcr.available)
index 67aa94b2481b273f8c8c31127605f60dfebd162d..d515d2cc20ed13d1afb90b99a4151654909da702 100644 (file)
@@ -21,6 +21,7 @@ config SOC_IMX8M
        bool "i.MX8M SoC family support"
        depends on ARCH_MXC || COMPILE_TEST
        default ARCH_MXC && ARM64
+       select SOC_BUS
        help
          If you say yes here you get support for the NXP i.MX8M family
          support, it will provide the SoC info like SoC family,
index 223f1f9d0922ff281c8ae1b1203a39b7d9f9bb15..646512d7276f4237b9e2b17f822be695f8265aa2 100644 (file)
@@ -19,7 +19,7 @@ config XILINX_VCU
 
 config ZYNQMP_POWER
        bool "Enable Xilinx Zynq MPSoC Power Management driver"
-       depends on PM && ARCH_ZYNQMP
+       depends on PM && ZYNQMP_FIRMWARE
        default y
        select MAILBOX
        select ZYNQMP_IPI_MBOX
@@ -35,7 +35,7 @@ config ZYNQMP_POWER
 config ZYNQMP_PM_DOMAINS
        bool "Enable Zynq MPSoC generic PM domains"
        default y
-       depends on PM && ARCH_ZYNQMP && ZYNQMP_FIRMWARE
+       depends on PM && ZYNQMP_FIRMWARE
        select PM_GENERIC_DOMAINS
        help
          Say yes to enable device power management through PM domains
index 08d1bbbebf2d7b59edc87b8dac466421a171b29f..e84b4fb493d627d5a17f183d99978ce2029fe376 100644 (file)
@@ -2725,8 +2725,10 @@ static int comedi_open(struct inode *inode, struct file *file)
        }
 
        cfp = kzalloc(sizeof(*cfp), GFP_KERNEL);
-       if (!cfp)
+       if (!cfp) {
+               comedi_dev_put(dev);
                return -ENOMEM;
+       }
 
        cfp->dev = dev;
 
index 83026ba63d1cc57a5fb0c727b72c22b2791e4f08..78a7c1b3448ab1088cf959bff6d4df4d85af0417 100644 (file)
@@ -92,6 +92,7 @@ static int dt2815_ao_insn(struct comedi_device *dev, struct comedi_subdevice *s,
        int ret;
 
        for (i = 0; i < insn->n; i++) {
+               /* FIXME: lo bit 0 chooses voltage output or current output */
                lo = ((data[i] & 0x0f) << 4) | (chan << 1) | 0x01;
                hi = (data[i] & 0xff0) >> 4;
 
@@ -105,6 +106,8 @@ static int dt2815_ao_insn(struct comedi_device *dev, struct comedi_subdevice *s,
                if (ret)
                        return ret;
 
+               outb(hi, dev->iobase + DT2815_DATA);
+
                devpriv->ao_readback[chan] = data[i];
        }
        return i;
index 46199c8ca441b6579d0330e133cfb9b90ea01f3a..f12f81c8dd2fb68bfd50ea16d79aa6bc84c2f6f6 100644 (file)
@@ -570,13 +570,6 @@ static const struct pci_device_id apex_pci_ids[] = {
        { PCI_DEVICE(APEX_PCI_VENDOR_ID, APEX_PCI_DEVICE_ID) }, { 0 }
 };
 
-static void apex_pci_fixup_class(struct pci_dev *pdev)
-{
-       pdev->class = (PCI_CLASS_SYSTEM_OTHER << 8) | pdev->class;
-}
-DECLARE_PCI_FIXUP_CLASS_HEADER(APEX_PCI_VENDOR_ID, APEX_PCI_DEVICE_ID,
-                              PCI_CLASS_NOT_DEFINED, 8, apex_pci_fixup_class);
-
 static int apex_pci_probe(struct pci_dev *pci_dev,
                          const struct pci_device_id *id)
 {
index a2d67c28f530c8991887a4ea64de2254613b2e79..5f0e089573a29fa972a9a8a9633ad039fc628757 100644 (file)
@@ -228,8 +228,7 @@ int gasket_sysfs_create_entries(struct device *device,
        }
 
        mutex_lock(&mapping->mutex);
-       for (i = 0; strcmp(attrs[i].attr.attr.name, GASKET_ARRAY_END_MARKER);
-               i++) {
+       for (i = 0; attrs[i].attr.attr.name != NULL; i++) {
                if (mapping->attribute_count == GASKET_SYSFS_MAX_NODES) {
                        dev_err(device,
                                "Maximum number of sysfs nodes reached for device\n");
index 1d0eed66a7f49fe2bf6088564cf53e549cd3b3fe..ab5aa351d55500bcbd7b9dfa167e7cad015c660a 100644 (file)
  */
 #define GASKET_SYSFS_MAX_NODES 196
 
-/* End markers for sysfs struct arrays. */
-#define GASKET_ARRAY_END_TOKEN GASKET_RESERVED_ARRAY_END
-#define GASKET_ARRAY_END_MARKER __stringify(GASKET_ARRAY_END_TOKEN)
-
 /*
  * Terminator struct for a gasket_sysfs_attr array. Must be at the end of
  * all gasket_sysfs_attribute arrays.
index 41b73f9670e2c82021df995cd5fbbbb609fe1d1b..ac3b188984d0f57db8d6e6a3fe23381bb5077a5f 100644 (file)
@@ -83,9 +83,6 @@ static int vnt_set_keymode(struct ieee80211_hw *hw, u8 *mac_addr,
        case  VNT_KEY_PAIRWISE:
                key_mode |= mode;
                key_inx = 4;
-               /* Don't save entry for pairwise key for station mode */
-               if (priv->op_mode == NL80211_IFTYPE_STATION)
-                       clear_bit(entry, &priv->key_entry_inuse);
                break;
        default:
                return -EINVAL;
@@ -109,7 +106,6 @@ static int vnt_set_keymode(struct ieee80211_hw *hw, u8 *mac_addr,
 int vnt_set_keys(struct ieee80211_hw *hw, struct ieee80211_sta *sta,
                 struct ieee80211_vif *vif, struct ieee80211_key_conf *key)
 {
-       struct ieee80211_bss_conf *conf = &vif->bss_conf;
        struct vnt_private *priv = hw->priv;
        u8 *mac_addr = NULL;
        u8 key_dec_mode = 0;
@@ -154,16 +150,12 @@ int vnt_set_keys(struct ieee80211_hw *hw, struct ieee80211_sta *sta,
                return -EOPNOTSUPP;
        }
 
-       if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) {
+       if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE)
                vnt_set_keymode(hw, mac_addr, key, VNT_KEY_PAIRWISE,
                                key_dec_mode, true);
-       } else {
-               vnt_set_keymode(hw, mac_addr, key, VNT_KEY_DEFAULTKEY,
+       else
+               vnt_set_keymode(hw, mac_addr, key, VNT_KEY_GROUP_ADDRESS,
                                key_dec_mode, true);
 
-               vnt_set_keymode(hw, (u8 *)conf->bssid, key,
-                               VNT_KEY_GROUP_ADDRESS, key_dec_mode, true);
-       }
-
        return 0;
 }
index 8e7269c87ea96b8a4c073ada02f44ac7b5b2b647..5f78cad3b6476541ba42d7c89ef5fb2f3eff6108 100644 (file)
@@ -625,8 +625,6 @@ static int vnt_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
 
        priv->op_mode = vif->type;
 
-       vnt_set_bss_mode(priv);
-
        /* LED blink on TX */
        vnt_mac_set_led(priv, LEDSTS_STS, LEDSTS_INTER);
 
@@ -713,7 +711,6 @@ static void vnt_bss_info_changed(struct ieee80211_hw *hw,
                priv->basic_rates = conf->basic_rates;
 
                vnt_update_top_rates(priv);
-               vnt_set_bss_mode(priv);
 
                dev_dbg(&priv->usb->dev, "basic rates %x\n", conf->basic_rates);
        }
@@ -742,11 +739,14 @@ static void vnt_bss_info_changed(struct ieee80211_hw *hw,
                        priv->short_slot_time = false;
 
                vnt_set_short_slot_time(priv);
-               vnt_update_ifs(priv);
                vnt_set_vga_gain_offset(priv, priv->bb_vga[0]);
                vnt_update_pre_ed_threshold(priv, false);
        }
 
+       if (changed & (BSS_CHANGED_BASIC_RATES | BSS_CHANGED_ERP_PREAMBLE |
+                      BSS_CHANGED_ERP_SLOT))
+               vnt_set_bss_mode(priv);
+
        if (changed & BSS_CHANGED_TXPOWER)
                vnt_rf_setpower(priv, priv->current_rate,
                                conf->chandef.chan->hw_value);
@@ -770,12 +770,15 @@ static void vnt_bss_info_changed(struct ieee80211_hw *hw,
                        vnt_mac_reg_bits_on(priv, MAC_REG_TFTCTL,
                                            TFTCTL_TSFCNTREN);
 
-                       vnt_adjust_tsf(priv, conf->beacon_rate->hw_value,
-                                      conf->sync_tsf, priv->current_tsf);
-
                        vnt_mac_set_beacon_interval(priv, conf->beacon_int);
 
                        vnt_reset_next_tbtt(priv, conf->beacon_int);
+
+                       vnt_adjust_tsf(priv, conf->beacon_rate->hw_value,
+                                      conf->sync_tsf, priv->current_tsf);
+
+                       vnt_update_next_tbtt(priv,
+                                            conf->sync_tsf, conf->beacon_int);
                } else {
                        vnt_clear_current_tsf(priv);
 
@@ -809,15 +812,11 @@ static void vnt_configure(struct ieee80211_hw *hw,
 {
        struct vnt_private *priv = hw->priv;
        u8 rx_mode = 0;
-       int rc;
 
        *total_flags &= FIF_ALLMULTI | FIF_OTHER_BSS | FIF_BCN_PRBRESP_PROMISC;
 
-       rc = vnt_control_in(priv, MESSAGE_TYPE_READ, MAC_REG_RCR,
-                           MESSAGE_REQUEST_MACREG, sizeof(u8), &rx_mode);
-
-       if (!rc)
-               rx_mode = RCR_MULTICAST | RCR_BROADCAST;
+       vnt_control_in(priv, MESSAGE_TYPE_READ, MAC_REG_RCR,
+                      MESSAGE_REQUEST_MACREG, sizeof(u8), &rx_mode);
 
        dev_dbg(&priv->usb->dev, "rx mode in = %x\n", rx_mode);
 
@@ -856,8 +855,12 @@ static int vnt_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
        case SET_KEY:
                return vnt_set_keys(hw, sta, vif, key);
        case DISABLE_KEY:
-               if (test_bit(key->hw_key_idx, &priv->key_entry_inuse))
+               if (test_bit(key->hw_key_idx, &priv->key_entry_inuse)) {
                        clear_bit(key->hw_key_idx, &priv->key_entry_inuse);
+
+                       vnt_mac_disable_keyentry(priv, key->hw_key_idx);
+               }
+
        default:
                break;
        }
index eae211e5860f1e16e673224c5f557cca912750c3..91b62c3dff7b8cda86fca34c6dde783106231f36 100644 (file)
@@ -207,7 +207,8 @@ static void vnt_int_process_data(struct vnt_private *priv)
                                priv->wake_up_count =
                                        priv->hw->conf.listen_interval;
 
-                       --priv->wake_up_count;
+                       if (priv->wake_up_count)
+                               --priv->wake_up_count;
 
                        /* Turn on wake up to listen next beacon */
                        if (priv->wake_up_count == 1)
index 27284a2dcd2b62395c5b140900ccca85a68ab683..436cc51c92c39765f9e9ba782fabecf62dda4830 100644 (file)
@@ -302,10 +302,6 @@ int hvc_instantiate(uint32_t vtermno, int index, const struct hv_ops *ops)
        vtermnos[index] = vtermno;
        cons_ops[index] = ops;
 
-       /* reserve all indices up to and including this index */
-       if (last_hvc < index)
-               last_hvc = index;
-
        /* check if we need to re-register the kernel console */
        hvc_check_console(index);
 
@@ -960,13 +956,22 @@ struct hvc_struct *hvc_alloc(uint32_t vtermno, int data,
                    cons_ops[i] == hp->ops)
                        break;
 
-       /* no matching slot, just use a counter */
-       if (i >= MAX_NR_HVC_CONSOLES)
-               i = ++last_hvc;
+       if (i >= MAX_NR_HVC_CONSOLES) {
+
+               /* find 'empty' slot for console */
+               for (i = 0; i < MAX_NR_HVC_CONSOLES && vtermnos[i] != -1; i++) {
+               }
+
+               /* no matching slot, just use a counter */
+               if (i == MAX_NR_HVC_CONSOLES)
+                       i = ++last_hvc + MAX_NR_HVC_CONSOLES;
+       }
 
        hp->index = i;
-       cons_ops[i] = ops;
-       vtermnos[i] = vtermno;
+       if (i < MAX_NR_HVC_CONSOLES) {
+               cons_ops[i] = ops;
+               vtermnos[i] = vtermno;
+       }
 
        list_add_tail(&(hp->next), &hvc_structs);
        mutex_unlock(&hvc_structs_mutex);
index fbaa4ec85560e661e22cd25a67169a00f4225ea2..e2138e7d5dc64b8c01deb1d77a9c744edeaffb52 100644 (file)
@@ -632,18 +632,21 @@ init_r_port(int board, int aiop, int chan, struct pci_dev *pci_dev)
        tty_port_init(&info->port);
        info->port.ops = &rocket_port_ops;
        info->flags &= ~ROCKET_MODE_MASK;
-       switch (pc104[board][line]) {
-       case 422:
-               info->flags |= ROCKET_MODE_RS422;
-               break;
-       case 485:
-               info->flags |= ROCKET_MODE_RS485;
-               break;
-       case 232:
-       default:
+       if (board < ARRAY_SIZE(pc104) && line < ARRAY_SIZE(pc104_1))
+               switch (pc104[board][line]) {
+               case 422:
+                       info->flags |= ROCKET_MODE_RS422;
+                       break;
+               case 485:
+                       info->flags |= ROCKET_MODE_RS485;
+                       break;
+               case 232:
+               default:
+                       info->flags |= ROCKET_MODE_RS232;
+                       break;
+               }
+       else
                info->flags |= ROCKET_MODE_RS232;
-               break;
-       }
 
        info->intmask = RXF_TRIG | TXFIFO_MT | SRC_INT | DELTA_CD | DELTA_CTS | DELTA_DSR;
        if (sInitChan(ctlp, &info->channel, aiop, chan) == 0) {
index 5674da2b76f0f23b4681f181aed82aab347abc98..ed0aa5c0d9b79829f26e501bab29a033369534e0 100644 (file)
@@ -843,8 +843,10 @@ static int bcm_uart_probe(struct platform_device *pdev)
        if (IS_ERR(clk) && pdev->dev.of_node)
                clk = of_clk_get(pdev->dev.of_node, 0);
 
-       if (IS_ERR(clk))
+       if (IS_ERR(clk)) {
+               clk_put(clk);
                return -ENODEV;
+       }
 
        port->iotype = UPIO_MEM;
        port->irq = res_irq->start;
index 42c8cc93b603b43aa4a206099dc696889008941d..c149f8c300074b0188f2c24ab047a437007a43f0 100644 (file)
@@ -680,6 +680,12 @@ static int owl_uart_probe(struct platform_device *pdev)
                return PTR_ERR(owl_port->clk);
        }
 
+       ret = clk_prepare_enable(owl_port->clk);
+       if (ret) {
+               dev_err(&pdev->dev, "could not enable clk\n");
+               return ret;
+       }
+
        owl_port->port.dev = &pdev->dev;
        owl_port->port.line = pdev->id;
        owl_port->port.type = PORT_OWL;
@@ -712,6 +718,7 @@ static int owl_uart_remove(struct platform_device *pdev)
 
        uart_remove_one_port(&owl_uart_driver, &owl_port->port);
        owl_uart_ports[pdev->id] = NULL;
+       clk_disable_unprepare(owl_port->clk);
 
        return 0;
 }
index c073aa7001c4fe716a7d4caa7b92c76e7d8c7454..e1179e74a2b89d892f4c8e0edceb3378c6755e5a 100644 (file)
@@ -870,9 +870,16 @@ static void sci_receive_chars(struct uart_port *port)
                                tty_insert_flip_char(tport, c, TTY_NORMAL);
                } else {
                        for (i = 0; i < count; i++) {
-                               char c = serial_port_in(port, SCxRDR);
-
-                               status = serial_port_in(port, SCxSR);
+                               char c;
+
+                               if (port->type == PORT_SCIF ||
+                                   port->type == PORT_HSCIF) {
+                                       status = serial_port_in(port, SCxSR);
+                                       c = serial_port_in(port, SCxRDR);
+                               } else {
+                                       c = serial_port_in(port, SCxRDR);
+                                       status = serial_port_in(port, SCxSR);
+                               }
                                if (uart_handle_sysrq_char(port, c)) {
                                        count--; i--;
                                        continue;
index eafada8fb6fad8755104ffa4fdc7cb40c8cc1d6e..e35073e93a5b4710a56039a3e36ed15a00dc9b90 100644 (file)
@@ -567,6 +567,9 @@ static int hv_probe(struct platform_device *op)
        sunserial_console_match(&sunhv_console, op->dev.of_node,
                                &sunhv_reg, port->line, false);
 
+       /* We need to initialize lock even for non-registered console */
+       spin_lock_init(&port->lock);
+
        err = uart_add_one_port(&sunhv_reg, port);
        if (err)
                goto out_unregister_driver;
index 6b26f767768ebb82c83e04cc436d944e029b8b68..ac137b6a1dc124afc0aa8e0b13f0584121a34ecc 100644 (file)
 
 #define CDNS_UART_TTY_NAME     "ttyPS"
 #define CDNS_UART_NAME         "xuartps"
+#define CDNS_UART_MAJOR                0       /* use dynamic node allocation */
+#define CDNS_UART_MINOR                0       /* works best with devtmpfs */
+#define CDNS_UART_NR_PORTS     16
 #define CDNS_UART_FIFO_SIZE    64      /* FIFO size */
 #define CDNS_UART_REGISTER_SPACE       0x1000
 #define TX_TIMEOUT             500000
 
 /* Rx Trigger level */
 static int rx_trigger_level = 56;
-static int uartps_major;
 module_param(rx_trigger_level, uint, 0444);
 MODULE_PARM_DESC(rx_trigger_level, "Rx trigger level, 1-63 bytes");
 
@@ -188,7 +190,6 @@ MODULE_PARM_DESC(rx_timeout, "Rx timeout, 1-255");
  * @pclk:              APB clock
  * @cdns_uart_driver:  Pointer to UART driver
  * @baud:              Current baud rate
- * @id:                        Port ID
  * @clk_rate_change_nb:        Notifier block for clock changes
  * @quirks:            Flags for RXBS support.
  */
@@ -198,7 +199,6 @@ struct cdns_uart {
        struct clk              *pclk;
        struct uart_driver      *cdns_uart_driver;
        unsigned int            baud;
-       int                     id;
        struct notifier_block   clk_rate_change_nb;
        u32                     quirks;
        bool cts_override;
@@ -1133,6 +1133,8 @@ static const struct uart_ops cdns_uart_ops = {
 #endif
 };
 
+static struct uart_driver cdns_uart_uart_driver;
+
 #ifdef CONFIG_SERIAL_XILINX_PS_UART_CONSOLE
 /**
  * cdns_uart_console_putchar - write the character to the FIFO buffer
@@ -1272,6 +1274,16 @@ static int cdns_uart_console_setup(struct console *co, char *options)
 
        return uart_set_options(port, co, baud, parity, bits, flow);
 }
+
+static struct console cdns_uart_console = {
+       .name   = CDNS_UART_TTY_NAME,
+       .write  = cdns_uart_console_write,
+       .device = uart_console_device,
+       .setup  = cdns_uart_console_setup,
+       .flags  = CON_PRINTBUFFER,
+       .index  = -1, /* Specified on the cmdline (e.g. console=ttyPS ) */
+       .data   = &cdns_uart_uart_driver,
+};
 #endif /* CONFIG_SERIAL_XILINX_PS_UART_CONSOLE */
 
 #ifdef CONFIG_PM_SLEEP
@@ -1403,89 +1415,8 @@ static const struct of_device_id cdns_uart_of_match[] = {
 };
 MODULE_DEVICE_TABLE(of, cdns_uart_of_match);
 
-/*
- * Maximum number of instances without alias IDs but if there is alias
- * which target "< MAX_UART_INSTANCES" range this ID can't be used.
- */
-#define MAX_UART_INSTANCES     32
-
-/* Stores static aliases list */
-static DECLARE_BITMAP(alias_bitmap, MAX_UART_INSTANCES);
-static int alias_bitmap_initialized;
-
-/* Stores actual bitmap of allocated IDs with alias IDs together */
-static DECLARE_BITMAP(bitmap, MAX_UART_INSTANCES);
-/* Protect bitmap operations to have unique IDs */
-static DEFINE_MUTEX(bitmap_lock);
-
-static int cdns_get_id(struct platform_device *pdev)
-{
-       int id, ret;
-
-       mutex_lock(&bitmap_lock);
-
-       /* Alias list is stable that's why get alias bitmap only once */
-       if (!alias_bitmap_initialized) {
-               ret = of_alias_get_alias_list(cdns_uart_of_match, "serial",
-                                             alias_bitmap, MAX_UART_INSTANCES);
-               if (ret && ret != -EOVERFLOW) {
-                       mutex_unlock(&bitmap_lock);
-                       return ret;
-               }
-
-               alias_bitmap_initialized++;
-       }
-
-       /* Make sure that alias ID is not taken by instance without alias */
-       bitmap_or(bitmap, bitmap, alias_bitmap, MAX_UART_INSTANCES);
-
-       dev_dbg(&pdev->dev, "Alias bitmap: %*pb\n",
-               MAX_UART_INSTANCES, bitmap);
-
-       /* Look for a serialN alias */
-       id = of_alias_get_id(pdev->dev.of_node, "serial");
-       if (id < 0) {
-               dev_warn(&pdev->dev,
-                        "No serial alias passed. Using the first free id\n");
-
-               /*
-                * Start with id 0 and check if there is no serial0 alias
-                * which points to device which is compatible with this driver.
-                * If alias exists then try next free position.
-                */
-               id = 0;
-
-               for (;;) {
-                       dev_info(&pdev->dev, "Checking id %d\n", id);
-                       id = find_next_zero_bit(bitmap, MAX_UART_INSTANCES, id);
-
-                       /* No free empty instance */
-                       if (id == MAX_UART_INSTANCES) {
-                               dev_err(&pdev->dev, "No free ID\n");
-                               mutex_unlock(&bitmap_lock);
-                               return -EINVAL;
-                       }
-
-                       dev_dbg(&pdev->dev, "The empty id is %d\n", id);
-                       /* Check if ID is empty */
-                       if (!test_and_set_bit(id, bitmap)) {
-                               /* Break the loop if bit is taken */
-                               dev_dbg(&pdev->dev,
-                                       "Selected ID %d allocation passed\n",
-                                       id);
-                               break;
-                       }
-                       dev_dbg(&pdev->dev,
-                               "Selected ID %d allocation failed\n", id);
-                       /* if taking bit fails then try next one */
-                       id++;
-               }
-       }
-
-       mutex_unlock(&bitmap_lock);
-
-       return id;
-}
+/* Temporary variable for storing number of instances */
+static int instances;
 
 /**
  * cdns_uart_probe - Platform driver probe
@@ -1495,16 +1426,11 @@ static int cdns_get_id(struct platform_device *pdev)
  */
 static int cdns_uart_probe(struct platform_device *pdev)
 {
-       int rc, irq;
+       int rc, id, irq;
        struct uart_port *port;
        struct resource *res;
        struct cdns_uart *cdns_uart_data;
        const struct of_device_id *match;
-       struct uart_driver *cdns_uart_uart_driver;
-       char *driver_name;
-#ifdef CONFIG_SERIAL_XILINX_PS_UART_CONSOLE
-       struct console *cdns_uart_console;
-#endif
 
        cdns_uart_data = devm_kzalloc(&pdev->dev, sizeof(*cdns_uart_data),
                        GFP_KERNEL);
@@ -1514,64 +1440,35 @@ static int cdns_uart_probe(struct platform_device *pdev)
        if (!port)
                return -ENOMEM;
 
-       cdns_uart_uart_driver = devm_kzalloc(&pdev->dev,
-                                            sizeof(*cdns_uart_uart_driver),
-                                            GFP_KERNEL);
-       if (!cdns_uart_uart_driver)
-               return -ENOMEM;
-
-       cdns_uart_data->id = cdns_get_id(pdev);
-       if (cdns_uart_data->id < 0)
-               return cdns_uart_data->id;
+       /* Look for a serialN alias */
+       id = of_alias_get_id(pdev->dev.of_node, "serial");
+       if (id < 0)
+               id = 0;
 
-       /* There is a need to use unique driver name */
-       driver_name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "%s%d",
-                                    CDNS_UART_NAME, cdns_uart_data->id);
-       if (!driver_name) {
-               rc = -ENOMEM;
-               goto err_out_id;
+       if (id >= CDNS_UART_NR_PORTS) {
+               dev_err(&pdev->dev, "Cannot get uart_port structure\n");
+               return -ENODEV;
        }
 
-       cdns_uart_uart_driver->owner = THIS_MODULE;
-       cdns_uart_uart_driver->driver_name = driver_name;
-       cdns_uart_uart_driver->dev_name = CDNS_UART_TTY_NAME;
-       cdns_uart_uart_driver->major = uartps_major;
-       cdns_uart_uart_driver->minor = cdns_uart_data->id;
-       cdns_uart_uart_driver->nr = 1;
-
+       if (!cdns_uart_uart_driver.state) {
+               cdns_uart_uart_driver.owner = THIS_MODULE;
+               cdns_uart_uart_driver.driver_name = CDNS_UART_NAME;
+               cdns_uart_uart_driver.dev_name = CDNS_UART_TTY_NAME;
+               cdns_uart_uart_driver.major = CDNS_UART_MAJOR;
+               cdns_uart_uart_driver.minor = CDNS_UART_MINOR;
+               cdns_uart_uart_driver.nr = CDNS_UART_NR_PORTS;
 #ifdef CONFIG_SERIAL_XILINX_PS_UART_CONSOLE
-       cdns_uart_console = devm_kzalloc(&pdev->dev, sizeof(*cdns_uart_console),
-                                        GFP_KERNEL);
-       if (!cdns_uart_console) {
-               rc = -ENOMEM;
-               goto err_out_id;
-       }
-
-       strncpy(cdns_uart_console->name, CDNS_UART_TTY_NAME,
-               sizeof(cdns_uart_console->name));
-       cdns_uart_console->index = cdns_uart_data->id;
-       cdns_uart_console->write = cdns_uart_console_write;
-       cdns_uart_console->device = uart_console_device;
-       cdns_uart_console->setup = cdns_uart_console_setup;
-       cdns_uart_console->flags = CON_PRINTBUFFER;
-       cdns_uart_console->data = cdns_uart_uart_driver;
-       cdns_uart_uart_driver->cons = cdns_uart_console;
+               cdns_uart_uart_driver.cons = &cdns_uart_console;
 #endif
 
-       rc = uart_register_driver(cdns_uart_uart_driver);
-       if (rc < 0) {
-               dev_err(&pdev->dev, "Failed to register driver\n");
-               goto err_out_id;
+               rc = uart_register_driver(&cdns_uart_uart_driver);
+               if (rc < 0) {
+                       dev_err(&pdev->dev, "Failed to register driver\n");
+                       return rc;
+               }
        }
 
-       cdns_uart_data->cdns_uart_driver = cdns_uart_uart_driver;
-
-       /*
-        * Setting up proper name_base needs to be done after uart
-        * registration because tty_driver structure is not filled.
-        * name_base is 0 by default.
-        */
-       cdns_uart_uart_driver->tty_driver->name_base = cdns_uart_data->id;
+       cdns_uart_data->cdns_uart_driver = &cdns_uart_uart_driver;
 
        match = of_match_node(cdns_uart_of_match, pdev->dev.of_node);
        if (match && match->data) {
@@ -1649,6 +1546,7 @@ static int cdns_uart_probe(struct platform_device *pdev)
        port->ops       = &cdns_uart_ops;
        port->fifosize  = CDNS_UART_FIFO_SIZE;
        port->has_sysrq = IS_ENABLED(CONFIG_SERIAL_XILINX_PS_UART_CONSOLE);
+       port->line      = id;
 
        /*
         * Register the port.
@@ -1680,7 +1578,7 @@ static int cdns_uart_probe(struct platform_device *pdev)
                console_port = port;
 #endif
 
-       rc = uart_add_one_port(cdns_uart_uart_driver, port);
+       rc = uart_add_one_port(&cdns_uart_uart_driver, port);
        if (rc) {
                dev_err(&pdev->dev,
                        "uart_add_one_port() failed; err=%i\n", rc);
@@ -1690,13 +1588,15 @@ static int cdns_uart_probe(struct platform_device *pdev)
 #ifdef CONFIG_SERIAL_XILINX_PS_UART_CONSOLE
        /* This is not port which is used for console that's why clean it up */
        if (console_port == port &&
-           !(cdns_uart_uart_driver->cons->flags & CON_ENABLED))
+           !(cdns_uart_uart_driver.cons->flags & CON_ENABLED))
                console_port = NULL;
 #endif
 
-       uartps_major = cdns_uart_uart_driver->tty_driver->major;
        cdns_uart_data->cts_override = of_property_read_bool(pdev->dev.of_node,
                                                             "cts-override");
+
+       instances++;
+
        return 0;
 
 err_out_pm_disable:
@@ -1712,12 +1612,8 @@ err_out_clk_disable:
 err_out_clk_dis_pclk:
        clk_disable_unprepare(cdns_uart_data->pclk);
 err_out_unregister_driver:
-       uart_unregister_driver(cdns_uart_data->cdns_uart_driver);
-err_out_id:
-       mutex_lock(&bitmap_lock);
-       if (cdns_uart_data->id < MAX_UART_INSTANCES)
-               clear_bit(cdns_uart_data->id, bitmap);
-       mutex_unlock(&bitmap_lock);
+       if (!instances)
+               uart_unregister_driver(cdns_uart_data->cdns_uart_driver);
        return rc;
 }
 
@@ -1740,10 +1636,6 @@ static int cdns_uart_remove(struct platform_device *pdev)
 #endif
        rc = uart_remove_one_port(cdns_uart_data->cdns_uart_driver, port);
        port->mapbase = 0;
-       mutex_lock(&bitmap_lock);
-       if (cdns_uart_data->id < MAX_UART_INSTANCES)
-               clear_bit(cdns_uart_data->id, bitmap);
-       mutex_unlock(&bitmap_lock);
        clk_disable_unprepare(cdns_uart_data->uartclk);
        clk_disable_unprepare(cdns_uart_data->pclk);
        pm_runtime_disable(&pdev->dev);
@@ -1756,13 +1648,8 @@ static int cdns_uart_remove(struct platform_device *pdev)
                console_port = NULL;
 #endif
 
-       /* If this is last instance major number should be initialized */
-       mutex_lock(&bitmap_lock);
-       if (bitmap_empty(bitmap, MAX_UART_INSTANCES))
-               uartps_major = 0;
-       mutex_unlock(&bitmap_lock);
-
-       uart_unregister_driver(cdns_uart_data->cdns_uart_driver);
+       if (!--instances)
+               uart_unregister_driver(cdns_uart_data->cdns_uart_driver);
        return rc;
 }
 
index 5e0d0813da5570f78f4ef247fe0977374b6770bc..0dc3878794fd021a60c434d36792f022073b8759 100644 (file)
@@ -74,6 +74,7 @@ int sysrq_mask(void)
                return 1;
        return sysrq_enabled;
 }
+EXPORT_SYMBOL_GPL(sysrq_mask);
 
 /*
  * A value of 1 means 'all', other nonzero values are an op mask:
@@ -1058,6 +1059,7 @@ int sysrq_toggle_support(int enable_mask)
 
        return 0;
 }
+EXPORT_SYMBOL_GPL(sysrq_toggle_support);
 
 static int __sysrq_swap_key_ops(int key, struct sysrq_key_op *insert_op_p,
                                 struct sysrq_key_op *remove_op_p)
index 309a39197be0a0199929474901deb36ada29ad34..e5ffed795e4cf4bc142c53c1717775cfb3a1a6d2 100644 (file)
@@ -81,6 +81,7 @@
 #include <linux/errno.h>
 #include <linux/kd.h>
 #include <linux/slab.h>
+#include <linux/vmalloc.h>
 #include <linux/major.h>
 #include <linux/mm.h>
 #include <linux/console.h>
@@ -350,7 +351,7 @@ static struct uni_screen *vc_uniscr_alloc(unsigned int cols, unsigned int rows)
        /* allocate everything in one go */
        memsize = cols * rows * sizeof(char32_t);
        memsize += rows * sizeof(char32_t *);
-       p = kmalloc(memsize, GFP_KERNEL);
+       p = vmalloc(memsize);
        if (!p)
                return NULL;
 
@@ -366,7 +367,7 @@ static struct uni_screen *vc_uniscr_alloc(unsigned int cols, unsigned int rows)
 
 static void vc_uniscr_set(struct vc_data *vc, struct uni_screen *new_uniscr)
 {
-       kfree(vc->vc_uni_screen);
+       vfree(vc->vc_uni_screen);
        vc->vc_uni_screen = new_uniscr;
 }
 
@@ -1206,7 +1207,7 @@ static int vc_do_resize(struct tty_struct *tty, struct vc_data *vc,
        if (new_cols == vc->vc_cols && new_rows == vc->vc_rows)
                return 0;
 
-       if (new_screen_size > (4 << 20))
+       if (new_screen_size > KMALLOC_MAX_SIZE)
                return -EINVAL;
        newscreen = kzalloc(new_screen_size, GFP_USER);
        if (!newscreen)
index 84d6f7df09a4ef453dd0ece34aaaafd32ab584bb..ded8d93834ca739bc11f7ff4e9f5d6c5c01e3f58 100644 (file)
@@ -412,9 +412,12 @@ static void acm_ctrl_irq(struct urb *urb)
 
 exit:
        retval = usb_submit_urb(urb, GFP_ATOMIC);
-       if (retval && retval != -EPERM)
+       if (retval && retval != -EPERM && retval != -ENODEV)
                dev_err(&acm->control->dev,
                        "%s - usb_submit_urb failed: %d\n", __func__, retval);
+       else
+               dev_vdbg(&acm->control->dev,
+                       "control resubmission terminated %d\n", retval);
 }
 
 static int acm_submit_read_urb(struct acm *acm, int index, gfp_t mem_flags)
@@ -430,6 +433,8 @@ static int acm_submit_read_urb(struct acm *acm, int index, gfp_t mem_flags)
                        dev_err(&acm->data->dev,
                                "urb %d failed submission with %d\n",
                                index, res);
+               } else {
+                       dev_vdbg(&acm->data->dev, "intended failure %d\n", res);
                }
                set_bit(index, &acm->read_urbs_free);
                return res;
@@ -471,6 +476,7 @@ static void acm_read_bulk_callback(struct urb *urb)
        int status = urb->status;
        bool stopped = false;
        bool stalled = false;
+       bool cooldown = false;
 
        dev_vdbg(&acm->data->dev, "got urb %d, len %d, status %d\n",
                rb->index, urb->actual_length, status);
@@ -497,6 +503,14 @@ static void acm_read_bulk_callback(struct urb *urb)
                        __func__, status);
                stopped = true;
                break;
+       case -EOVERFLOW:
+       case -EPROTO:
+               dev_dbg(&acm->data->dev,
+                       "%s - cooling babbling device\n", __func__);
+               usb_mark_last_busy(acm->dev);
+               set_bit(rb->index, &acm->urbs_in_error_delay);
+               cooldown = true;
+               break;
        default:
                dev_dbg(&acm->data->dev,
                        "%s - nonzero urb status received: %d\n",
@@ -518,9 +532,11 @@ static void acm_read_bulk_callback(struct urb *urb)
         */
        smp_mb__after_atomic();
 
-       if (stopped || stalled) {
+       if (stopped || stalled || cooldown) {
                if (stalled)
                        schedule_work(&acm->work);
+               else if (cooldown)
+                       schedule_delayed_work(&acm->dwork, HZ / 2);
                return;
        }
 
@@ -557,14 +573,20 @@ static void acm_softint(struct work_struct *work)
        struct acm *acm = container_of(work, struct acm, work);
 
        if (test_bit(EVENT_RX_STALL, &acm->flags)) {
-               if (!(usb_autopm_get_interface(acm->data))) {
+               smp_mb(); /* against acm_suspend() */
+               if (!acm->susp_count) {
                        for (i = 0; i < acm->rx_buflimit; i++)
                                usb_kill_urb(acm->read_urbs[i]);
                        usb_clear_halt(acm->dev, acm->in);
                        acm_submit_read_urbs(acm, GFP_KERNEL);
-                       usb_autopm_put_interface(acm->data);
+                       clear_bit(EVENT_RX_STALL, &acm->flags);
                }
-               clear_bit(EVENT_RX_STALL, &acm->flags);
+       }
+
+       if (test_and_clear_bit(ACM_ERROR_DELAY, &acm->flags)) {
+               for (i = 0; i < ACM_NR; i++) 
+                       if (test_and_clear_bit(i, &acm->urbs_in_error_delay))
+                                       acm_submit_read_urb(acm, i, GFP_NOIO);
        }
 
        if (test_and_clear_bit(EVENT_TTY_WAKEUP, &acm->flags))
@@ -1333,6 +1355,7 @@ made_compressed_probe:
        acm->readsize = readsize;
        acm->rx_buflimit = num_rx_buf;
        INIT_WORK(&acm->work, acm_softint);
+       INIT_DELAYED_WORK(&acm->dwork, acm_softint);
        init_waitqueue_head(&acm->wioctl);
        spin_lock_init(&acm->write_lock);
        spin_lock_init(&acm->read_lock);
@@ -1542,6 +1565,7 @@ static void acm_disconnect(struct usb_interface *intf)
 
        acm_kill_urbs(acm);
        cancel_work_sync(&acm->work);
+       cancel_delayed_work_sync(&acm->dwork);
 
        tty_unregister_device(acm_tty_driver, acm->minor);
 
@@ -1584,6 +1608,8 @@ static int acm_suspend(struct usb_interface *intf, pm_message_t message)
 
        acm_kill_urbs(acm);
        cancel_work_sync(&acm->work);
+       cancel_delayed_work_sync(&acm->dwork);
+       acm->urbs_in_error_delay = 0;
 
        return 0;
 }
index ca1c026382c2e1a98a330cde2043dee308d76aad..cd5e9d8ab237588bb2aa9cd615b9b1356b59e1cc 100644 (file)
@@ -109,8 +109,11 @@ struct acm {
 #              define EVENT_TTY_WAKEUP 0
 #              define EVENT_RX_STALL   1
 #              define ACM_THROTTLED    2
+#              define ACM_ERROR_DELAY  3
+       unsigned long urbs_in_error_delay;              /* these need to be restarted after a delay */
        struct usb_cdc_line_coding line;                /* bits, stop, parity */
-       struct work_struct work;                        /* work queue entry for line discipline waking up */
+       struct work_struct work;                        /* work queue entry for various purposes*/
+       struct delayed_work dwork;                      /* for cool downs needed in error recovery */
        unsigned int ctrlin;                            /* input control lines (DCD, DSR, RI, break, overruns) */
        unsigned int ctrlout;                           /* output control lines (DTR, RTS) */
        struct async_icount iocount;                    /* counters for control line changes */
index 54cd8ef795ec042027a19e30ef754309adcf2329..2b6565c06c237d43f22493a43be39272f0355aef 100644 (file)
@@ -1223,6 +1223,11 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type)
 #ifdef CONFIG_PM
                        udev->reset_resume = 1;
 #endif
+                       /* Don't set the change_bits when the device
+                        * was powered off.
+                        */
+                       if (test_bit(port1, hub->power_bits))
+                               set_bit(port1, hub->change_bits);
 
                } else {
                        /* The power session is gone; tell hub_wq */
@@ -2723,13 +2728,11 @@ static bool use_new_scheme(struct usb_device *udev, int retry,
 {
        int old_scheme_first_port =
                port_dev->quirks & USB_PORT_QUIRK_OLD_SCHEME;
-       int quick_enumeration = (udev->speed == USB_SPEED_HIGH);
 
        if (udev->speed >= USB_SPEED_SUPER)
                return false;
 
-       return USE_NEW_SCHEME(retry, old_scheme_first_port || old_scheme_first
-                             || quick_enumeration);
+       return USE_NEW_SCHEME(retry, old_scheme_first_port || old_scheme_first);
 }
 
 /* Is a USB 3.0 port in the Inactive or Compliance Mode state?
@@ -3088,6 +3091,15 @@ static int check_port_resume_type(struct usb_device *udev,
                if (portchange & USB_PORT_STAT_C_ENABLE)
                        usb_clear_port_feature(hub->hdev, port1,
                                        USB_PORT_FEAT_C_ENABLE);
+
+               /*
+                * Whatever made this reset-resume necessary may have
+                * turned on the port1 bit in hub->change_bits.  But after
+                * a successful reset-resume we want the bit to be clear;
+                * if it was on it would indicate that something happened
+                * following the reset-resume.
+                */
+               clear_bit(port1, hub->change_bits);
        }
 
        return status;
index d5f834f16993258a4ad715224e54543510c51b0c..a48678a0c83ac0d0253067e82966c1bc592240a4 100644 (file)
@@ -589,12 +589,13 @@ void usb_sg_cancel(struct usb_sg_request *io)
        int i, retval;
 
        spin_lock_irqsave(&io->lock, flags);
-       if (io->status) {
+       if (io->status || io->count == 0) {
                spin_unlock_irqrestore(&io->lock, flags);
                return;
        }
        /* shut everything down */
        io->status = -ECONNRESET;
+       io->count++;            /* Keep the request alive until we're done */
        spin_unlock_irqrestore(&io->lock, flags);
 
        for (i = io->entries - 1; i >= 0; --i) {
@@ -608,6 +609,12 @@ void usb_sg_cancel(struct usb_sg_request *io)
                        dev_warn(&io->dev->dev, "%s, unlink --> %d\n",
                                 __func__, retval);
        }
+
+       spin_lock_irqsave(&io->lock, flags);
+       io->count--;
+       if (!io->count)
+               complete(&io->complete);
+       spin_unlock_irqrestore(&io->lock, flags);
 }
 EXPORT_SYMBOL_GPL(usb_sg_cancel);
 
index da30b5664ff3d5da22c5219159545e9faa72fdca..3e8efe759c3e69a8f8c29f5cafe8c0a6b1cca6fc 100644 (file)
@@ -430,6 +430,10 @@ static const struct usb_device_id usb_quirk_list[] = {
        /* Corsair K70 LUX */
        { USB_DEVICE(0x1b1c, 0x1b36), .driver_info = USB_QUIRK_DELAY_INIT },
 
+       /* Corsair K70 RGB RAPDIFIRE */
+       { USB_DEVICE(0x1b1c, 0x1b38), .driver_info = USB_QUIRK_DELAY_INIT |
+         USB_QUIRK_DELAY_CTRL_MSG },
+
        /* MIDI keyboard WORLDE MINI */
        { USB_DEVICE(0x1c75, 0x0204), .driver_info =
                        USB_QUIRK_CONFIG_INTF_STRINGS },
index 6846eb0cba135236768d559277b9970731b09dc8..4c171a8e215f685b87110adaa91b0d98d0050501 100644 (file)
 
 /* Global TX Fifo Size Register */
 #define DWC31_GTXFIFOSIZ_TXFRAMNUM     BIT(15)         /* DWC_usb31 only */
-#define DWC31_GTXFIFOSIZ_TXFDEF(n)     ((n) & 0x7fff)  /* DWC_usb31 only */
-#define DWC3_GTXFIFOSIZ_TXFDEF(n)      ((n) & 0xffff)
+#define DWC31_GTXFIFOSIZ_TXFDEP(n)     ((n) & 0x7fff)  /* DWC_usb31 only */
+#define DWC3_GTXFIFOSIZ_TXFDEP(n)      ((n) & 0xffff)
 #define DWC3_GTXFIFOSIZ_TXFSTADDR(n)   ((n) & 0xffff0000)
 
+/* Global RX Fifo Size Register */
+#define DWC31_GRXFIFOSIZ_RXFDEP(n)     ((n) & 0x7fff)  /* DWC_usb31 only */
+#define DWC3_GRXFIFOSIZ_RXFDEP(n)      ((n) & 0xffff)
+
 /* Global Event Size Registers */
 #define DWC3_GEVNTSIZ_INTMASK          BIT(31)
 #define DWC3_GEVNTSIZ_SIZE(n)          ((n) & 0xffff)
index 4d3c79d90a6e4a420cc079dc62e2a25a49f1c705..00746c2848c060fd1eaa66b9c95612ffe74a9cfd 100644 (file)
@@ -1728,7 +1728,6 @@ static int __dwc3_gadget_wakeup(struct dwc3 *dwc)
        u32                     reg;
 
        u8                      link_state;
-       u8                      speed;
 
        /*
         * According to the Databook Remote wakeup request should
@@ -1738,16 +1737,13 @@ static int __dwc3_gadget_wakeup(struct dwc3 *dwc)
         */
        reg = dwc3_readl(dwc->regs, DWC3_DSTS);
 
-       speed = reg & DWC3_DSTS_CONNECTSPD;
-       if ((speed == DWC3_DSTS_SUPERSPEED) ||
-           (speed == DWC3_DSTS_SUPERSPEED_PLUS))
-               return 0;
-
        link_state = DWC3_DSTS_USBLNKST(reg);
 
        switch (link_state) {
+       case DWC3_LINK_STATE_RESET:
        case DWC3_LINK_STATE_RX_DET:    /* in HS, means Early Suspend */
        case DWC3_LINK_STATE_U3:        /* in HS, means SUSPEND */
+       case DWC3_LINK_STATE_RESUME:
                break;
        default:
                return -EINVAL;
@@ -2227,7 +2223,6 @@ static int dwc3_gadget_init_in_endpoint(struct dwc3_ep *dep)
 {
        struct dwc3 *dwc = dep->dwc;
        int mdwidth;
-       int kbytes;
        int size;
 
        mdwidth = DWC3_MDWIDTH(dwc->hwparams.hwparams0);
@@ -2236,24 +2231,24 @@ static int dwc3_gadget_init_in_endpoint(struct dwc3_ep *dep)
 
        size = dwc3_readl(dwc->regs, DWC3_GTXFIFOSIZ(dep->number >> 1));
        if (dwc3_is_usb31(dwc))
-               size = DWC31_GTXFIFOSIZ_TXFDEF(size);
+               size = DWC31_GTXFIFOSIZ_TXFDEP(size);
        else
-               size = DWC3_GTXFIFOSIZ_TXFDEF(size);
+               size = DWC3_GTXFIFOSIZ_TXFDEP(size);
 
        /* FIFO Depth is in MDWDITH bytes. Multiply */
        size *= mdwidth;
 
-       kbytes = size / 1024;
-       if (kbytes == 0)
-               kbytes = 1;
-
        /*
-        * FIFO sizes account an extra MDWIDTH * (kbytes + 1) bytes for
-        * internal overhead. We don't really know how these are used,
-        * but documentation say it exists.
+        * To meet performance requirement, a minimum TxFIFO size of 3x
+        * MaxPacketSize is recommended for endpoints that support burst and a
+        * minimum TxFIFO size of 2x MaxPacketSize for endpoints that don't
+        * support burst. Use those numbers and we can calculate the max packet
+        * limit as below.
         */
-       size -= mdwidth * (kbytes + 1);
-       size /= kbytes;
+       if (dwc->maximum_speed >= USB_SPEED_SUPER)
+               size /= 3;
+       else
+               size /= 2;
 
        usb_ep_set_maxpacket_limit(&dep->endpoint, size);
 
@@ -2271,8 +2266,39 @@ static int dwc3_gadget_init_in_endpoint(struct dwc3_ep *dep)
 static int dwc3_gadget_init_out_endpoint(struct dwc3_ep *dep)
 {
        struct dwc3 *dwc = dep->dwc;
+       int mdwidth;
+       int size;
+
+       mdwidth = DWC3_MDWIDTH(dwc->hwparams.hwparams0);
 
-       usb_ep_set_maxpacket_limit(&dep->endpoint, 1024);
+       /* MDWIDTH is represented in bits, convert to bytes */
+       mdwidth /= 8;
+
+       /* All OUT endpoints share a single RxFIFO space */
+       size = dwc3_readl(dwc->regs, DWC3_GRXFIFOSIZ(0));
+       if (dwc3_is_usb31(dwc))
+               size = DWC31_GRXFIFOSIZ_RXFDEP(size);
+       else
+               size = DWC3_GRXFIFOSIZ_RXFDEP(size);
+
+       /* FIFO depth is in MDWDITH bytes */
+       size *= mdwidth;
+
+       /*
+        * To meet performance requirement, a minimum recommended RxFIFO size
+        * is defined as follow:
+        * RxFIFO size >= (3 x MaxPacketSize) +
+        * (3 x 8 bytes setup packets size) + (16 bytes clock crossing margin)
+        *
+        * Then calculate the max packet limit as below.
+        */
+       size -= (3 * 8) + 16;
+       if (size < 0)
+               size = 0;
+       else
+               size /= 3;
+
+       usb_ep_set_maxpacket_limit(&dep->endpoint, size);
        dep->endpoint.max_streams = 15;
        dep->endpoint.ops = &dwc3_gadget_ep_ops;
        list_add_tail(&dep->endpoint.ep_list,
@@ -2484,14 +2510,7 @@ static int dwc3_gadget_ep_reclaim_trb_linear(struct dwc3_ep *dep,
 
 static bool dwc3_gadget_ep_request_completed(struct dwc3_request *req)
 {
-       /*
-        * For OUT direction, host may send less than the setup
-        * length. Return true for all OUT requests.
-        */
-       if (!req->direction)
-               return true;
-
-       return req->request.actual == req->request.length;
+       return req->num_pending_sgs == 0;
 }
 
 static int dwc3_gadget_ep_cleanup_completed_request(struct dwc3_ep *dep,
@@ -2515,8 +2534,7 @@ static int dwc3_gadget_ep_cleanup_completed_request(struct dwc3_ep *dep,
 
        req->request.actual = req->request.length - req->remaining;
 
-       if (!dwc3_gadget_ep_request_completed(req) ||
-                       req->num_pending_sgs) {
+       if (!dwc3_gadget_ep_request_completed(req)) {
                __dwc3_gadget_kick_transfer(dep);
                goto out;
        }
index 971c6b92484add56e477f22f600c7aa974bde664..171280c8022849c898b75df2280b33924572b1f1 100644 (file)
@@ -728,19 +728,19 @@ static void xdbc_handle_tx_event(struct xdbc_trb *evt_trb)
        case COMP_USB_TRANSACTION_ERROR:
        case COMP_STALL_ERROR:
        default:
-               if (ep_id == XDBC_EPID_OUT)
+               if (ep_id == XDBC_EPID_OUT || ep_id == XDBC_EPID_OUT_INTEL)
                        xdbc.flags |= XDBC_FLAGS_OUT_STALL;
-               if (ep_id == XDBC_EPID_IN)
+               if (ep_id == XDBC_EPID_IN || ep_id == XDBC_EPID_IN_INTEL)
                        xdbc.flags |= XDBC_FLAGS_IN_STALL;
 
                xdbc_trace("endpoint %d stalled\n", ep_id);
                break;
        }
 
-       if (ep_id == XDBC_EPID_IN) {
+       if (ep_id == XDBC_EPID_IN || ep_id == XDBC_EPID_IN_INTEL) {
                xdbc.flags &= ~XDBC_FLAGS_IN_PROCESS;
                xdbc_bulk_transfer(NULL, XDBC_MAX_PACKET, true);
-       } else if (ep_id == XDBC_EPID_OUT) {
+       } else if (ep_id == XDBC_EPID_OUT || ep_id == XDBC_EPID_OUT_INTEL) {
                xdbc.flags &= ~XDBC_FLAGS_OUT_PROCESS;
        } else {
                xdbc_trace("invalid endpoint id %d\n", ep_id);
index 673686eeddd74e71c828ba5efc9970bdcc4dea25..6e2b7266a695255236e58b00d388e6673bcbd4d6 100644 (file)
@@ -120,8 +120,22 @@ struct xdbc_ring {
        u32                     cycle_state;
 };
 
-#define XDBC_EPID_OUT          2
-#define XDBC_EPID_IN           3
+/*
+ * These are the "Endpoint ID" (also known as "Context Index") values for the
+ * OUT Transfer Ring and the IN Transfer Ring of a Debug Capability Context data
+ * structure.
+ * According to the "eXtensible Host Controller Interface for Universal Serial
+ * Bus (xHCI)" specification, section "7.6.3.2 Endpoint Contexts and Transfer
+ * Rings", these should be 0 and 1, and those are the values AMD machines give
+ * you; but Intel machines seem to use the formula from section "4.5.1 Device
+ * Context Index", which is supposed to be used for the Device Context only.
+ * Luckily the values from Intel don't overlap with those from AMD, so we can
+ * just test for both.
+ */
+#define XDBC_EPID_OUT          0
+#define XDBC_EPID_IN           1
+#define XDBC_EPID_OUT_INTEL    2
+#define XDBC_EPID_IN_INTEL     3
 
 struct xdbc_state {
        u16                     vendor;
index c81023b195c3cf34eee295a2723b77fc96a45eb9..10f01f974f67e071031b7ac4976d669b393d8f53 100644 (file)
@@ -1813,6 +1813,10 @@ static void ffs_data_reset(struct ffs_data *ffs)
        ffs->state = FFS_READ_DESCRIPTORS;
        ffs->setup_state = FFS_NO_SETUP;
        ffs->flags = 0;
+
+       ffs->ms_os_descs_ext_prop_count = 0;
+       ffs->ms_os_descs_ext_prop_name_len = 0;
+       ffs->ms_os_descs_ext_prop_data_len = 0;
 }
 
 
index 76406343fbe577d2d8e9fafe03c72a27dba8a051..ca7d95bf7397e15364206cc473b712a92e7dd862 100644 (file)
@@ -81,6 +81,7 @@ static int raw_event_queue_add(struct raw_event_queue *queue,
 static struct usb_raw_event *raw_event_queue_fetch(
                                struct raw_event_queue *queue)
 {
+       int ret;
        unsigned long flags;
        struct usb_raw_event *event;
 
@@ -89,11 +90,18 @@ static struct usb_raw_event *raw_event_queue_fetch(
         * there's at least one event queued by decrementing the semaphore,
         * and then take the lock to protect queue struct fields.
         */
-       if (down_interruptible(&queue->sema))
-               return NULL;
+       ret = down_interruptible(&queue->sema);
+       if (ret)
+               return ERR_PTR(ret);
        spin_lock_irqsave(&queue->lock, flags);
-       if (WARN_ON(!queue->size))
-               return NULL;
+       /*
+        * queue->size must have the same value as queue->sema counter (before
+        * the down_interruptible() call above), so this check is a fail-safe.
+        */
+       if (WARN_ON(!queue->size)) {
+               spin_unlock_irqrestore(&queue->lock, flags);
+               return ERR_PTR(-ENODEV);
+       }
        event = queue->events[0];
        queue->size--;
        memmove(&queue->events[0], &queue->events[1],
@@ -392,9 +400,8 @@ static int raw_ioctl_init(struct raw_dev *dev, unsigned long value)
        char *udc_device_name;
        unsigned long flags;
 
-       ret = copy_from_user(&arg, (void __user *)value, sizeof(arg));
-       if (ret)
-               return ret;
+       if (copy_from_user(&arg, (void __user *)value, sizeof(arg)))
+               return -EFAULT;
 
        switch (arg.speed) {
        case USB_SPEED_UNKNOWN:
@@ -501,15 +508,13 @@ out_unlock:
 
 static int raw_ioctl_event_fetch(struct raw_dev *dev, unsigned long value)
 {
-       int ret = 0;
        struct usb_raw_event arg;
        unsigned long flags;
        struct usb_raw_event *event;
        uint32_t length;
 
-       ret = copy_from_user(&arg, (void __user *)value, sizeof(arg));
-       if (ret)
-               return ret;
+       if (copy_from_user(&arg, (void __user *)value, sizeof(arg)))
+               return -EFAULT;
 
        spin_lock_irqsave(&dev->lock, flags);
        if (dev->state != STATE_DEV_RUNNING) {
@@ -525,25 +530,31 @@ static int raw_ioctl_event_fetch(struct raw_dev *dev, unsigned long value)
        spin_unlock_irqrestore(&dev->lock, flags);
 
        event = raw_event_queue_fetch(&dev->queue);
-       if (!event) {
+       if (PTR_ERR(event) == -EINTR) {
                dev_dbg(&dev->gadget->dev, "event fetching interrupted\n");
                return -EINTR;
        }
+       if (IS_ERR(event)) {
+               dev_err(&dev->gadget->dev, "failed to fetch event\n");
+               spin_lock_irqsave(&dev->lock, flags);
+               dev->state = STATE_DEV_FAILED;
+               spin_unlock_irqrestore(&dev->lock, flags);
+               return -ENODEV;
+       }
        length = min(arg.length, event->length);
-       ret = copy_to_user((void __user *)value, event,
-                               sizeof(*event) + length);
-       return ret;
+       if (copy_to_user((void __user *)value, event, sizeof(*event) + length))
+               return -EFAULT;
+
+       return 0;
 }
 
 static void *raw_alloc_io_data(struct usb_raw_ep_io *io, void __user *ptr,
                                bool get_from_user)
 {
-       int ret;
        void *data;
 
-       ret = copy_from_user(io, ptr, sizeof(*io));
-       if (ret)
-               return ERR_PTR(ret);
+       if (copy_from_user(io, ptr, sizeof(*io)))
+               return ERR_PTR(-EFAULT);
        if (io->ep >= USB_RAW_MAX_ENDPOINTS)
                return ERR_PTR(-EINVAL);
        if (!usb_raw_io_flags_valid(io->flags))
@@ -658,12 +669,13 @@ static int raw_ioctl_ep0_read(struct raw_dev *dev, unsigned long value)
        if (IS_ERR(data))
                return PTR_ERR(data);
        ret = raw_process_ep0_io(dev, &io, data, false);
-       if (ret < 0) {
-               kfree(data);
-               return ret;
-       }
+       if (ret)
+               goto free;
+
        length = min(io.length, (unsigned int)ret);
-       ret = copy_to_user((void __user *)(value + sizeof(io)), data, length);
+       if (copy_to_user((void __user *)(value + sizeof(io)), data, length))
+               ret = -EFAULT;
+free:
        kfree(data);
        return ret;
 }
@@ -952,12 +964,13 @@ static int raw_ioctl_ep_read(struct raw_dev *dev, unsigned long value)
        if (IS_ERR(data))
                return PTR_ERR(data);
        ret = raw_process_ep_io(dev, &io, data, false);
-       if (ret < 0) {
-               kfree(data);
-               return ret;
-       }
+       if (ret)
+               goto free;
+
        length = min(io.length, (unsigned int)ret);
-       ret = copy_to_user((void __user *)(value + sizeof(io)), data, length);
+       if (copy_to_user((void __user *)(value + sizeof(io)), data, length))
+               ret = -EFAULT;
+free:
        kfree(data);
        return ret;
 }
index 6e0432141c40911b29448ed1600b6d8e663387c1..22200341c8ec3a93f73d0132187616b98519a79b 100644 (file)
@@ -1951,10 +1951,10 @@ static irqreturn_t usba_vbus_irq_thread(int irq, void *devid)
                        usba_start(udc);
                } else {
                        udc->suspended = false;
-                       usba_stop(udc);
-
                        if (udc->driver->disconnect)
                                udc->driver->disconnect(&udc->gadget);
+
+                       usba_stop(udc);
                }
                udc->vbus_prev = vbus;
        }
index a4d9b5e1e50ea09747edc4b1bb0a4fadf7b440d8..d49c6dc1082dc980b47620a63fb28e35f5780c67 100644 (file)
@@ -540,7 +540,7 @@ static void bdc_req_complete(struct bdc_ep *ep, struct bdc_req *req,
 {
        struct bdc *bdc = ep->bdc;
 
-       if (req == NULL  || &req->queue == NULL || &req->usb_req == NULL)
+       if (req == NULL)
                return;
 
        dev_dbg(bdc->dev, "%s ep:%s status:%d\n", __func__, ep->name, status);
index 9eca1fe81061c81dd46d9a00fa2e6664f00f61bf..f37316d2c8fa4ff056ebe142c6422cbcf4d98416 100644 (file)
@@ -1571,6 +1571,8 @@ int xhci_hub_status_data(struct usb_hcd *hcd, char *buf)
                }
                if ((temp & PORT_RC))
                        reset_change = true;
+               if (temp & PORT_OC)
+                       status = 1;
        }
        if (!status && !reset_change) {
                xhci_dbg(xhci, "%s: stopping port polling.\n", __func__);
@@ -1636,6 +1638,13 @@ retry:
                                 port_index);
                        goto retry;
                }
+               /* bail out if port detected a over-current condition */
+               if (t1 & PORT_OC) {
+                       bus_state->bus_suspended = 0;
+                       spin_unlock_irqrestore(&xhci->lock, flags);
+                       xhci_dbg(xhci, "Bus suspend bailout, port over-current detected\n");
+                       return -EBUSY;
+               }
                /* suspend ports in U0, or bail out for new connect changes */
                if ((t1 & PORT_PE) && (t1 & PORT_PLS_MASK) == XDEV_U0) {
                        if ((t1 & PORT_CSC) && wake_enabled) {
index a78787bb513366ec6830ecf3dea8bf460670febe..0fda0c0f4d31fce5cc555dabceda120ee12fa9c4 100644 (file)
@@ -547,6 +547,23 @@ void xhci_find_new_dequeue_state(struct xhci_hcd *xhci,
                                stream_id);
                return;
        }
+       /*
+        * A cancelled TD can complete with a stall if HW cached the trb.
+        * In this case driver can't find cur_td, but if the ring is empty we
+        * can move the dequeue pointer to the current enqueue position.
+        */
+       if (!cur_td) {
+               if (list_empty(&ep_ring->td_list)) {
+                       state->new_deq_seg = ep_ring->enq_seg;
+                       state->new_deq_ptr = ep_ring->enqueue;
+                       state->new_cycle_state = ep_ring->cycle_state;
+                       goto done;
+               } else {
+                       xhci_warn(xhci, "Can't find new dequeue state, missing cur_td\n");
+                       return;
+               }
+       }
+
        /* Dig out the cycle state saved by the xHC during the stop ep cmd */
        xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb,
                        "Finding endpoint context");
@@ -592,6 +609,7 @@ void xhci_find_new_dequeue_state(struct xhci_hcd *xhci,
        state->new_deq_seg = new_seg;
        state->new_deq_ptr = new_deq;
 
+done:
        /* Don't update the ring cycle state for the producer (us). */
        xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb,
                        "Cycle state = 0x%x", state->new_cycle_state);
@@ -1856,8 +1874,8 @@ static void xhci_cleanup_halted_endpoint(struct xhci_hcd *xhci,
 
        if (reset_type == EP_HARD_RESET) {
                ep->ep_state |= EP_HARD_CLEAR_TOGGLE;
-               xhci_cleanup_stalled_ring(xhci, ep_index, stream_id, td);
-               xhci_clear_hub_tt_buffer(xhci, td, ep);
+               xhci_cleanup_stalled_ring(xhci, slot_id, ep_index, stream_id,
+                                         td);
        }
        xhci_ring_cmd_db(xhci);
 }
@@ -1978,11 +1996,18 @@ static int finish_td(struct xhci_hcd *xhci, struct xhci_td *td,
        if (trb_comp_code == COMP_STALL_ERROR ||
                xhci_requires_manual_halt_cleanup(xhci, ep_ctx,
                                                trb_comp_code)) {
-               /* Issue a reset endpoint command to clear the host side
-                * halt, followed by a set dequeue command to move the
-                * dequeue pointer past the TD.
-                * The class driver clears the device side halt later.
+               /*
+                * xhci internal endpoint state will go to a "halt" state for
+                * any stall, including default control pipe protocol stall.
+                * To clear the host side halt we need to issue a reset endpoint
+                * command, followed by a set dequeue command to move past the
+                * TD.
+                * Class drivers clear the device side halt from a functional
+                * stall later. Hub TT buffer should only be cleared for FS/LS
+                * devices behind HS hubs for functional stalls.
                 */
+               if ((ep_index != 0) || (trb_comp_code != COMP_STALL_ERROR))
+                       xhci_clear_hub_tt_buffer(xhci, td, ep);
                xhci_cleanup_halted_endpoint(xhci, slot_id, ep_index,
                                        ep_ring->stream_id, td, EP_HARD_RESET);
        } else {
@@ -2539,6 +2564,15 @@ static int handle_tx_event(struct xhci_hcd *xhci,
                                xhci_dbg(xhci, "td_list is empty while skip flag set. Clear skip flag for slot %u ep %u.\n",
                                         slot_id, ep_index);
                        }
+                       if (trb_comp_code == COMP_STALL_ERROR ||
+                           xhci_requires_manual_halt_cleanup(xhci, ep_ctx,
+                                                             trb_comp_code)) {
+                               xhci_cleanup_halted_endpoint(xhci, slot_id,
+                                                            ep_index,
+                                                            ep_ring->stream_id,
+                                                            NULL,
+                                                            EP_HARD_RESET);
+                       }
                        goto cleanup;
                }
 
index fe38275363e0f61d5968c0f546cdd9af79589453..bee5deccc83d81d09977dfa3ea334e61869b1cce 100644 (file)
@@ -3031,19 +3031,19 @@ static void xhci_setup_input_ctx_for_quirk(struct xhci_hcd *xhci,
                        added_ctxs, added_ctxs);
 }
 
-void xhci_cleanup_stalled_ring(struct xhci_hcd *xhci, unsigned int ep_index,
-                              unsigned int stream_id, struct xhci_td *td)
+void xhci_cleanup_stalled_ring(struct xhci_hcd *xhci, unsigned int slot_id,
+                              unsigned int ep_index, unsigned int stream_id,
+                              struct xhci_td *td)
 {
        struct xhci_dequeue_state deq_state;
-       struct usb_device *udev = td->urb->dev;
 
        xhci_dbg_trace(xhci, trace_xhci_dbg_reset_ep,
                        "Cleaning up stalled endpoint ring");
        /* We need to move the HW's dequeue pointer past this TD,
         * or it will attempt to resend it on the next doorbell ring.
         */
-       xhci_find_new_dequeue_state(xhci, udev->slot_id,
-                       ep_index, stream_id, td, &deq_state);
+       xhci_find_new_dequeue_state(xhci, slot_id, ep_index, stream_id, td,
+                                   &deq_state);
 
        if (!deq_state.new_deq_ptr || !deq_state.new_deq_seg)
                return;
@@ -3054,7 +3054,7 @@ void xhci_cleanup_stalled_ring(struct xhci_hcd *xhci, unsigned int ep_index,
        if (!(xhci->quirks & XHCI_RESET_EP_QUIRK)) {
                xhci_dbg_trace(xhci, trace_xhci_dbg_reset_ep,
                                "Queueing new dequeue state");
-               xhci_queue_new_dequeue_state(xhci, udev->slot_id,
+               xhci_queue_new_dequeue_state(xhci, slot_id,
                                ep_index, &deq_state);
        } else {
                /* Better hope no one uses the input context between now and the
@@ -3065,7 +3065,7 @@ void xhci_cleanup_stalled_ring(struct xhci_hcd *xhci, unsigned int ep_index,
                xhci_dbg_trace(xhci, trace_xhci_dbg_quirks,
                                "Setting up input context for "
                                "configure endpoint command");
-               xhci_setup_input_ctx_for_quirk(xhci, udev->slot_id,
+               xhci_setup_input_ctx_for_quirk(xhci, slot_id,
                                ep_index, &deq_state);
        }
 }
index 3289bb51620172c8490135aa3f9f7849a55246fb..86cfefdd6632b33f2a4e06805867777ee733e921 100644 (file)
@@ -2116,8 +2116,9 @@ void xhci_find_new_dequeue_state(struct xhci_hcd *xhci,
 void xhci_queue_new_dequeue_state(struct xhci_hcd *xhci,
                unsigned int slot_id, unsigned int ep_index,
                struct xhci_dequeue_state *deq_state);
-void xhci_cleanup_stalled_ring(struct xhci_hcd *xhci, unsigned int ep_index,
-               unsigned int stream_id, struct xhci_td *td);
+void xhci_cleanup_stalled_ring(struct xhci_hcd *xhci, unsigned int slot_id,
+                              unsigned int ep_index, unsigned int stream_id,
+                              struct xhci_td *td);
 void xhci_stop_endpoint_command_watchdog(struct timer_list *t);
 void xhci_handle_command_timeout(struct work_struct *work);
 
index 2ab9600d0898bc2b85e7663fcfe86551d078925c..fc8a5da4a07c9adeb8d4f447e9d323a6519d6c15 100644 (file)
@@ -1199,18 +1199,18 @@ static int sisusb_read_mem_bulk(struct sisusb_usb_data *sisusb, u32 addr,
 /* High level: Gfx (indexed) register access */
 
 #ifdef CONFIG_USB_SISUSBVGA_CON
-int sisusb_setreg(struct sisusb_usb_data *sisusb, int port, u8 data)
+int sisusb_setreg(struct sisusb_usb_data *sisusb, u32 port, u8 data)
 {
        return sisusb_write_memio_byte(sisusb, SISUSB_TYPE_IO, port, data);
 }
 
-int sisusb_getreg(struct sisusb_usb_data *sisusb, int port, u8 *data)
+int sisusb_getreg(struct sisusb_usb_data *sisusb, u32 port, u8 *data)
 {
        return sisusb_read_memio_byte(sisusb, SISUSB_TYPE_IO, port, data);
 }
 #endif
 
-int sisusb_setidxreg(struct sisusb_usb_data *sisusb, int port,
+int sisusb_setidxreg(struct sisusb_usb_data *sisusb, u32 port,
                u8 index, u8 data)
 {
        int ret;
@@ -1220,7 +1220,7 @@ int sisusb_setidxreg(struct sisusb_usb_data *sisusb, int port,
        return ret;
 }
 
-int sisusb_getidxreg(struct sisusb_usb_data *sisusb, int port,
+int sisusb_getidxreg(struct sisusb_usb_data *sisusb, u32 port,
                u8 index, u8 *data)
 {
        int ret;
@@ -1230,7 +1230,7 @@ int sisusb_getidxreg(struct sisusb_usb_data *sisusb, int port,
        return ret;
 }
 
-int sisusb_setidxregandor(struct sisusb_usb_data *sisusb, int port, u8 idx,
+int sisusb_setidxregandor(struct sisusb_usb_data *sisusb, u32 port, u8 idx,
                u8 myand, u8 myor)
 {
        int ret;
@@ -1245,7 +1245,7 @@ int sisusb_setidxregandor(struct sisusb_usb_data *sisusb, int port, u8 idx,
 }
 
 static int sisusb_setidxregmask(struct sisusb_usb_data *sisusb,
-               int port, u8 idx, u8 data, u8 mask)
+               u32 port, u8 idx, u8 data, u8 mask)
 {
        int ret;
        u8 tmp;
@@ -1258,13 +1258,13 @@ static int sisusb_setidxregmask(struct sisusb_usb_data *sisusb,
        return ret;
 }
 
-int sisusb_setidxregor(struct sisusb_usb_data *sisusb, int port,
+int sisusb_setidxregor(struct sisusb_usb_data *sisusb, u32 port,
                u8 index, u8 myor)
 {
        return sisusb_setidxregandor(sisusb, port, index, 0xff, myor);
 }
 
-int sisusb_setidxregand(struct sisusb_usb_data *sisusb, int port,
+int sisusb_setidxregand(struct sisusb_usb_data *sisusb, u32 port,
                u8 idx, u8 myand)
 {
        return sisusb_setidxregandor(sisusb, port, idx, myand, 0x00);
@@ -2785,8 +2785,8 @@ static loff_t sisusb_lseek(struct file *file, loff_t offset, int orig)
 static int sisusb_handle_command(struct sisusb_usb_data *sisusb,
                struct sisusb_command *y, unsigned long arg)
 {
-       int     retval, port, length;
-       u32     address;
+       int     retval, length;
+       u32     port, address;
 
        /* All our commands require the device
         * to be initialized.
index 1782c759c4ad582fbf9fb6e6fc7f6ce78bf7739a..ace09985dae4c53a81efe333a1e2b93204da150c 100644 (file)
@@ -812,17 +812,17 @@ static const struct SiS_VCLKData SiSUSB_VCLKData[] = {
 int SiSUSBSetMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo);
 int SiSUSBSetVESAMode(struct SiS_Private *SiS_Pr, unsigned short VModeNo);
 
-extern int sisusb_setreg(struct sisusb_usb_data *sisusb, int port, u8 data);
-extern int sisusb_getreg(struct sisusb_usb_data *sisusb, int port, u8 * data);
-extern int sisusb_setidxreg(struct sisusb_usb_data *sisusb, int port,
+extern int sisusb_setreg(struct sisusb_usb_data *sisusb, u32 port, u8 data);
+extern int sisusb_getreg(struct sisusb_usb_data *sisusb, u32 port, u8 * data);
+extern int sisusb_setidxreg(struct sisusb_usb_data *sisusb, u32 port,
                            u8 index, u8 data);
-extern int sisusb_getidxreg(struct sisusb_usb_data *sisusb, int port,
+extern int sisusb_getidxreg(struct sisusb_usb_data *sisusb, u32 port,
                            u8 index, u8 * data);
-extern int sisusb_setidxregandor(struct sisusb_usb_data *sisusb, int port,
+extern int sisusb_setidxregandor(struct sisusb_usb_data *sisusb, u32 port,
                                 u8 idx, u8 myand, u8 myor);
-extern int sisusb_setidxregor(struct sisusb_usb_data *sisusb, int port,
+extern int sisusb_setidxregor(struct sisusb_usb_data *sisusb, u32 port,
                              u8 index, u8 myor);
-extern int sisusb_setidxregand(struct sisusb_usb_data *sisusb, int port,
+extern int sisusb_setidxregand(struct sisusb_usb_data *sisusb, u32 port,
                               u8 idx, u8 myand);
 
 void sisusb_delete(struct kref *kref);
index 3670fda02c3460000b06be6e0d496a3eb014fbb7..d592071119ba6b84275dbe19916b8eaa20e24c82 100644 (file)
@@ -81,6 +81,19 @@ static void uas_free_streams(struct uas_dev_info *devinfo);
 static void uas_log_cmd_state(struct scsi_cmnd *cmnd, const char *prefix,
                                int status);
 
+/*
+ * This driver needs its own workqueue, as we need to control memory allocation.
+ *
+ * In the course of error handling and power management uas_wait_for_pending_cmnds()
+ * needs to flush pending work items. In these contexts we cannot allocate memory
+ * by doing block IO as we would deadlock. For the same reason we cannot wait
+ * for anything allocating memory not heeding these constraints.
+ *
+ * So we have to control all work items that can be on the workqueue we flush.
+ * Hence we cannot share a queue and need our own.
+ */
+static struct workqueue_struct *workqueue;
+
 static void uas_do_work(struct work_struct *work)
 {
        struct uas_dev_info *devinfo =
@@ -109,7 +122,7 @@ static void uas_do_work(struct work_struct *work)
                if (!err)
                        cmdinfo->state &= ~IS_IN_WORK_LIST;
                else
-                       schedule_work(&devinfo->work);
+                       queue_work(workqueue, &devinfo->work);
        }
 out:
        spin_unlock_irqrestore(&devinfo->lock, flags);
@@ -134,7 +147,7 @@ static void uas_add_work(struct uas_cmd_info *cmdinfo)
 
        lockdep_assert_held(&devinfo->lock);
        cmdinfo->state |= IS_IN_WORK_LIST;
-       schedule_work(&devinfo->work);
+       queue_work(workqueue, &devinfo->work);
 }
 
 static void uas_zap_pending(struct uas_dev_info *devinfo, int result)
@@ -190,6 +203,9 @@ static void uas_log_cmd_state(struct scsi_cmnd *cmnd, const char *prefix,
        struct uas_cmd_info *ci = (void *)&cmnd->SCp;
        struct uas_cmd_info *cmdinfo = (void *)&cmnd->SCp;
 
+       if (status == -ENODEV) /* too late */
+               return;
+
        scmd_printk(KERN_INFO, cmnd,
                    "%s %d uas-tag %d inflight:%s%s%s%s%s%s%s%s%s%s%s%s ",
                    prefix, status, cmdinfo->uas_tag,
@@ -1226,7 +1242,31 @@ static struct usb_driver uas_driver = {
        .id_table = uas_usb_ids,
 };
 
-module_usb_driver(uas_driver);
+static int __init uas_init(void)
+{
+       int rv;
+
+       workqueue = alloc_workqueue("uas", WQ_MEM_RECLAIM, 0);
+       if (!workqueue)
+               return -ENOMEM;
+
+       rv = usb_register(&uas_driver);
+       if (rv) {
+               destroy_workqueue(workqueue);
+               return -ENOMEM;
+       }
+
+       return 0;
+}
+
+static void __exit uas_exit(void)
+{
+       usb_deregister(&uas_driver);
+       destroy_workqueue(workqueue);
+}
+
+module_init(uas_init);
+module_exit(uas_exit);
 
 MODULE_LICENSE("GPL");
 MODULE_IMPORT_NS(USB_STORAGE);
index 1880f3e13f57633d7c401998d33f859e0423cc31..f6c3681fa2e9efa4d861199aa2fe12a1c8334652 100644 (file)
@@ -2323,6 +2323,13 @@ UNUSUAL_DEV(  0x3340, 0xffff, 0x0000, 0x0000,
                USB_SC_DEVICE,USB_PR_DEVICE,NULL,
                US_FL_MAX_SECTORS_64 ),
 
+/* Reported by Cyril Roelandt <tipecaml@gmail.com> */
+UNUSUAL_DEV(  0x357d, 0x7788, 0x0114, 0x0114,
+               "JMicron",
+               "USB to ATA/ATAPI Bridge",
+               USB_SC_DEVICE, USB_PR_DEVICE, NULL,
+               US_FL_BROKEN_FUA ),
+
 /* Reported by Andrey Rahmatullin <wrar@altlinux.org> */
 UNUSUAL_DEV(  0x4102, 0x1020, 0x0100,  0x0100,
                "iRiver",
index c823122f9cb7b30f66d6fe1082344d36c3f7137d..e8ddb81cb6df4a23d537955acc625b08a2612152 100644 (file)
@@ -198,7 +198,10 @@ EXPORT_SYMBOL_GPL(typec_altmode_vdm);
 const struct typec_altmode *
 typec_altmode_get_partner(struct typec_altmode *adev)
 {
-       return adev ? &to_altmode(adev)->partner->adev : NULL;
+       if (!adev || !to_altmode(adev)->partner)
+               return NULL;
+
+       return &to_altmode(adev)->partner->adev;
 }
 EXPORT_SYMBOL_GPL(typec_altmode_get_partner);
 
index 46457c133d2bcaa33121a4064ed1d0f5238ab076..7afe275b17d03459564d4288eb2021e406e1414a 100644 (file)
@@ -114,8 +114,8 @@ pi3usb30532_mux_set(struct typec_mux *mux, struct typec_mux_state *state)
 static int pi3usb30532_probe(struct i2c_client *client)
 {
        struct device *dev = &client->dev;
-       struct typec_switch_desc sw_desc;
-       struct typec_mux_desc mux_desc;
+       struct typec_switch_desc sw_desc = { };
+       struct typec_mux_desc mux_desc = { };
        struct pi3usb30532 *pi;
        int ret;
 
index de3576e6530ab2abdd9dc07a4c4c88b51521f0ca..82b19ebd7838e0c129d3bcff33a80b0217d80940 100644 (file)
@@ -3794,6 +3794,14 @@ static void _tcpm_cc_change(struct tcpm_port *port, enum typec_cc_status cc1,
                 */
                break;
 
+       case PORT_RESET:
+       case PORT_RESET_WAIT_OFF:
+               /*
+                * State set back to default mode once the timer completes.
+                * Ignore CC changes here.
+                */
+               break;
+
        default:
                if (tcpm_port_is_disconnected(port))
                        tcpm_set_state(port, unattached_state(port), 0);
@@ -3855,6 +3863,15 @@ static void _tcpm_pd_vbus_on(struct tcpm_port *port)
        case SRC_TRY_DEBOUNCE:
                /* Do nothing, waiting for sink detection */
                break;
+
+       case PORT_RESET:
+       case PORT_RESET_WAIT_OFF:
+               /*
+                * State set back to default mode once the timer completes.
+                * Ignore vbus changes here.
+                */
+               break;
+
        default:
                break;
        }
@@ -3908,10 +3925,19 @@ static void _tcpm_pd_vbus_off(struct tcpm_port *port)
        case PORT_RESET_WAIT_OFF:
                tcpm_set_state(port, tcpm_default_state(port), 0);
                break;
+
        case SRC_TRY_WAIT:
        case SRC_TRY_DEBOUNCE:
                /* Do nothing, waiting for sink detection */
                break;
+
+       case PORT_RESET:
+               /*
+                * State set back to default mode once the timer completes.
+                * Ignore vbus changes here.
+                */
+               break;
+
        default:
                if (port->pwr_role == TYPEC_SINK &&
                    port->attached)
index 7db1460104b78993ddf66a6e44e7361b9f56bfb0..e8140065c8a53f93ab97e7fbca4f49375284e30c 100644 (file)
@@ -1,21 +1,16 @@
 # SPDX-License-Identifier: GPL-2.0-only
-config VDPA
-       tristate
+menuconfig VDPA
+       tristate "vDPA drivers"
        help
          Enable this module to support vDPA device that uses a
          datapath which complies with virtio specifications with
          vendor specific control path.
 
-menuconfig VDPA_MENU
-       bool "VDPA drivers"
-       default n
-
-if VDPA_MENU
+if VDPA
 
 config VDPA_SIM
        tristate "vDPA device simulator"
-       depends on RUNTIME_TESTING_MENU
-       select VDPA
+       depends on RUNTIME_TESTING_MENU && HAS_DMA && VHOST_DPN
        select VHOST_RING
        default n
        help
@@ -24,9 +19,8 @@ config VDPA_SIM
          development of vDPA.
 
 config IFCVF
-       tristate "Intel IFC VF VDPA driver"
+       tristate "Intel IFC VF vDPA driver"
        depends on PCI_MSI
-       select VDPA
        default n
        help
          This kernel module can drive Intel IFC VF NIC to offload
@@ -34,4 +28,4 @@ config IFCVF
          To compile this driver as a module, choose M here: the module will
          be called ifcvf.
 
-endif # VDPA_MENU
+endif # VDPA
index b61b06ea26d346bc5ca13c0d986aa3c8bd03eace..e24371d644b5062c41357bf14eef66ffa76977be 100644 (file)
@@ -301,12 +301,10 @@ int ifcvf_set_vq_state(struct ifcvf_hw *hw, u16 qid, u64 num)
 
 static int ifcvf_hw_enable(struct ifcvf_hw *hw)
 {
-       struct ifcvf_lm_cfg __iomem *ifcvf_lm;
        struct virtio_pci_common_cfg __iomem *cfg;
        struct ifcvf_adapter *ifcvf;
        u32 i;
 
-       ifcvf_lm = (struct ifcvf_lm_cfg __iomem *)hw->lm_cfg;
        ifcvf = vf_to_adapter(hw);
        cfg = hw->common_cfg;
        ifc_iowrite16(IFCVF_MSI_CONFIG_OFF, &cfg->msix_config);
index 8d54dc5b08d2453b31d1b5046f4eda2959aa7dec..abf6a061cab6583db4e167235c9b4706add5dcfb 100644 (file)
@@ -31,11 +31,9 @@ static irqreturn_t ifcvf_intr_handler(int irq, void *arg)
 static int ifcvf_start_datapath(void *private)
 {
        struct ifcvf_hw *vf = ifcvf_private_to_vf(private);
-       struct ifcvf_adapter *ifcvf;
        u8 status;
        int ret;
 
-       ifcvf = vf_to_adapter(vf);
        vf->nr_vring = IFCVF_MAX_QUEUE_PAIRS * 2;
        ret = ifcvf_start_hw(vf);
        if (ret < 0) {
@@ -228,7 +226,7 @@ static u32 ifcvf_vdpa_get_vendor_id(struct vdpa_device *vdpa_dev)
        return IFCVF_SUBSYS_VENDOR_ID;
 }
 
-static u16 ifcvf_vdpa_get_vq_align(struct vdpa_device *vdpa_dev)
+static u32 ifcvf_vdpa_get_vq_align(struct vdpa_device *vdpa_dev)
 {
        return IFCVF_QUEUE_ALIGNMENT;
 }
index e9ed6a2b635b9ea9cf0c14f6834884c31eeb7f2c..ff6562f602e055fe14024572cbaf22cdddce2ae9 100644 (file)
@@ -116,7 +116,7 @@ EXPORT_SYMBOL_GPL(__vdpa_alloc_device);
 
 /**
  * vdpa_register_device - register a vDPA device
- * Callers must have a succeed call of vdpa_init_device() before.
+ * Callers must have a succeed call of vdpa_alloc_device() before.
  * @vdev: the vdpa device to be registered to vDPA bus
  *
  * Returns an error when fail to add to vDPA bus
index 6e8a0cf2fdebbc10acb530ea9ee4f73e88d99f2d..7957d2d41fc4b4cbc71c81441d612b3b7a47cbdc 100644 (file)
@@ -435,7 +435,7 @@ static u64 vdpasim_get_vq_state(struct vdpa_device *vdpa, u16 idx)
        return vrh->last_avail_idx;
 }
 
-static u16 vdpasim_get_vq_align(struct vdpa_device *vdpa)
+static u32 vdpasim_get_vq_align(struct vdpa_device *vdpa)
 {
        return VDPASIM_QUEUE_ALIGN;
 }
@@ -488,7 +488,7 @@ static u8 vdpasim_get_status(struct vdpa_device *vdpa)
        status = vdpasim->status;
        spin_unlock(&vdpasim->lock);
 
-       return vdpasim->status;
+       return status;
 }
 
 static void vdpasim_set_status(struct vdpa_device *vdpa, u8 status)
index 362b832f5338cd62a327518bd33e478f156e2472..c4f27379359537ecc983da9611214e8547edb3bf 100644 (file)
@@ -3,6 +3,8 @@ config VHOST_IOTLB
        tristate
        help
          Generic IOTLB implementation for vhost and vringh.
+         This option is selected by any driver which needs to support
+         an IOMMU in software.
 
 config VHOST_RING
        tristate
@@ -11,6 +13,15 @@ config VHOST_RING
          This option is selected by any driver which needs to access
          the host side of a virtio ring.
 
+config VHOST_DPN
+       bool
+       depends on !ARM || AEABI
+       default y
+       help
+         Anything selecting VHOST or VHOST_RING must depend on VHOST_DPN.
+         This excludes the deprecated ARM ABI since that forces a 4 byte
+         alignment on all structs - incompatible with virtio spec requirements.
+
 config VHOST
        tristate
        select VHOST_IOTLB
@@ -26,7 +37,7 @@ if VHOST_MENU
 
 config VHOST_NET
        tristate "Host kernel accelerator for virtio net"
-       depends on NET && EVENTFD && (TUN || !TUN) && (TAP || !TAP)
+       depends on NET && EVENTFD && (TUN || !TUN) && (TAP || !TAP) && VHOST_DPN
        select VHOST
        ---help---
          This kernel module can be loaded in host kernel to accelerate
@@ -38,7 +49,7 @@ config VHOST_NET
 
 config VHOST_SCSI
        tristate "VHOST_SCSI TCM fabric driver"
-       depends on TARGET_CORE && EVENTFD
+       depends on TARGET_CORE && EVENTFD && VHOST_DPN
        select VHOST
        default n
        ---help---
@@ -47,7 +58,7 @@ config VHOST_SCSI
 
 config VHOST_VSOCK
        tristate "vhost virtio-vsock driver"
-       depends on VSOCKETS && EVENTFD
+       depends on VSOCKETS && EVENTFD && VHOST_DPN
        select VHOST
        select VIRTIO_VSOCKETS_COMMON
        default n
@@ -61,9 +72,9 @@ config VHOST_VSOCK
 
 config VHOST_VDPA
        tristate "Vhost driver for vDPA-based backend"
-       depends on EVENTFD
+       depends on EVENTFD && VHOST_DPN
        select VHOST
-       select VDPA
+       depends on VDPA
        help
          This kernel module can be loaded in host kernel to accelerate
          guest virtio devices with the vDPA-based backends.
index 87469d67ede8d889df6a855d90f7f05dcc2d44c5..2927f02cc7e1b5af56c1626973f1499c96b25244 100644 (file)
@@ -424,7 +424,7 @@ static void vhost_net_disable_vq(struct vhost_net *n,
        struct vhost_net_virtqueue *nvq =
                container_of(vq, struct vhost_net_virtqueue, vq);
        struct vhost_poll *poll = n->poll + (nvq - n->vqs);
-       if (!vq->private_data)
+       if (!vhost_vq_get_backend(vq))
                return;
        vhost_poll_stop(poll);
 }
@@ -437,7 +437,7 @@ static int vhost_net_enable_vq(struct vhost_net *n,
        struct vhost_poll *poll = n->poll + (nvq - n->vqs);
        struct socket *sock;
 
-       sock = vq->private_data;
+       sock = vhost_vq_get_backend(vq);
        if (!sock)
                return 0;
 
@@ -524,7 +524,7 @@ static void vhost_net_busy_poll(struct vhost_net *net,
                return;
 
        vhost_disable_notify(&net->dev, vq);
-       sock = rvq->private_data;
+       sock = vhost_vq_get_backend(rvq);
 
        busyloop_timeout = poll_rx ? rvq->busyloop_timeout:
                                     tvq->busyloop_timeout;
@@ -570,8 +570,10 @@ static int vhost_net_tx_get_vq_desc(struct vhost_net *net,
 
        if (r == tvq->num && tvq->busyloop_timeout) {
                /* Flush batched packets first */
-               if (!vhost_sock_zcopy(tvq->private_data))
-                       vhost_tx_batch(net, tnvq, tvq->private_data, msghdr);
+               if (!vhost_sock_zcopy(vhost_vq_get_backend(tvq)))
+                       vhost_tx_batch(net, tnvq,
+                                      vhost_vq_get_backend(tvq),
+                                      msghdr);
 
                vhost_net_busy_poll(net, rvq, tvq, busyloop_intr, false);
 
@@ -685,7 +687,7 @@ static int vhost_net_build_xdp(struct vhost_net_virtqueue *nvq,
        struct vhost_virtqueue *vq = &nvq->vq;
        struct vhost_net *net = container_of(vq->dev, struct vhost_net,
                                             dev);
-       struct socket *sock = vq->private_data;
+       struct socket *sock = vhost_vq_get_backend(vq);
        struct page_frag *alloc_frag = &net->page_frag;
        struct virtio_net_hdr *gso;
        struct xdp_buff *xdp = &nvq->xdp[nvq->batched_xdp];
@@ -952,7 +954,7 @@ static void handle_tx(struct vhost_net *net)
        struct socket *sock;
 
        mutex_lock_nested(&vq->mutex, VHOST_NET_VQ_TX);
-       sock = vq->private_data;
+       sock = vhost_vq_get_backend(vq);
        if (!sock)
                goto out;
 
@@ -1121,7 +1123,7 @@ static void handle_rx(struct vhost_net *net)
        int recv_pkts = 0;
 
        mutex_lock_nested(&vq->mutex, VHOST_NET_VQ_RX);
-       sock = vq->private_data;
+       sock = vhost_vq_get_backend(vq);
        if (!sock)
                goto out;
 
@@ -1345,9 +1347,9 @@ static struct socket *vhost_net_stop_vq(struct vhost_net *n,
                container_of(vq, struct vhost_net_virtqueue, vq);
 
        mutex_lock(&vq->mutex);
-       sock = vq->private_data;
+       sock = vhost_vq_get_backend(vq);
        vhost_net_disable_vq(n, vq);
-       vq->private_data = NULL;
+       vhost_vq_set_backend(vq, NULL);
        vhost_net_buf_unproduce(nvq);
        nvq->rx_ring = NULL;
        mutex_unlock(&vq->mutex);
@@ -1521,7 +1523,7 @@ static long vhost_net_set_backend(struct vhost_net *n, unsigned index, int fd)
        }
 
        /* start polling new socket */
-       oldsock = vq->private_data;
+       oldsock = vhost_vq_get_backend(vq);
        if (sock != oldsock) {
                ubufs = vhost_net_ubuf_alloc(vq,
                                             sock && vhost_sock_zcopy(sock));
@@ -1531,7 +1533,7 @@ static long vhost_net_set_backend(struct vhost_net *n, unsigned index, int fd)
                }
 
                vhost_net_disable_vq(n, vq);
-               vq->private_data = sock;
+               vhost_vq_set_backend(vq, sock);
                vhost_net_buf_unproduce(nvq);
                r = vhost_vq_init_access(vq);
                if (r)
@@ -1568,7 +1570,7 @@ static long vhost_net_set_backend(struct vhost_net *n, unsigned index, int fd)
        return 0;
 
 err_used:
-       vq->private_data = oldsock;
+       vhost_vq_set_backend(vq, oldsock);
        vhost_net_enable_vq(n, vq);
        if (ubufs)
                vhost_net_ubuf_put_wait_and_free(ubufs);
index 7653667a8cdcbd8aa3e331548833449b8d629f92..c39952243fd3289f23844fb9bef6c41e175a0dba 100644 (file)
@@ -452,7 +452,7 @@ vhost_scsi_do_evt_work(struct vhost_scsi *vs, struct vhost_scsi_evt *evt)
        unsigned out, in;
        int head, ret;
 
-       if (!vq->private_data) {
+       if (!vhost_vq_get_backend(vq)) {
                vs->vs_events_missed = true;
                return;
        }
@@ -892,7 +892,7 @@ vhost_scsi_get_req(struct vhost_virtqueue *vq, struct vhost_scsi_ctx *vc,
        } else {
                struct vhost_scsi_tpg **vs_tpg, *tpg;
 
-               vs_tpg = vq->private_data;      /* validated at handler entry */
+               vs_tpg = vhost_vq_get_backend(vq);      /* validated at handler entry */
 
                tpg = READ_ONCE(vs_tpg[*vc->target]);
                if (unlikely(!tpg)) {
@@ -929,7 +929,7 @@ vhost_scsi_handle_vq(struct vhost_scsi *vs, struct vhost_virtqueue *vq)
         * We can handle the vq only after the endpoint is setup by calling the
         * VHOST_SCSI_SET_ENDPOINT ioctl.
         */
-       vs_tpg = vq->private_data;
+       vs_tpg = vhost_vq_get_backend(vq);
        if (!vs_tpg)
                goto out;
 
@@ -1184,7 +1184,7 @@ vhost_scsi_ctl_handle_vq(struct vhost_scsi *vs, struct vhost_virtqueue *vq)
         * We can handle the vq only after the endpoint is setup by calling the
         * VHOST_SCSI_SET_ENDPOINT ioctl.
         */
-       if (!vq->private_data)
+       if (!vhost_vq_get_backend(vq))
                goto out;
 
        memset(&vc, 0, sizeof(vc));
@@ -1322,7 +1322,7 @@ static void vhost_scsi_evt_handle_kick(struct vhost_work *work)
        struct vhost_scsi *vs = container_of(vq->dev, struct vhost_scsi, dev);
 
        mutex_lock(&vq->mutex);
-       if (!vq->private_data)
+       if (!vhost_vq_get_backend(vq))
                goto out;
 
        if (vs->vs_events_missed)
@@ -1460,7 +1460,7 @@ vhost_scsi_set_endpoint(struct vhost_scsi *vs,
                for (i = 0; i < VHOST_SCSI_MAX_VQ; i++) {
                        vq = &vs->vqs[i].vq;
                        mutex_lock(&vq->mutex);
-                       vq->private_data = vs_tpg;
+                       vhost_vq_set_backend(vq, vs_tpg);
                        vhost_vq_init_access(vq);
                        mutex_unlock(&vq->mutex);
                }
@@ -1547,7 +1547,7 @@ vhost_scsi_clear_endpoint(struct vhost_scsi *vs,
                for (i = 0; i < VHOST_SCSI_MAX_VQ; i++) {
                        vq = &vs->vqs[i].vq;
                        mutex_lock(&vq->mutex);
-                       vq->private_data = NULL;
+                       vhost_vq_set_backend(vq, NULL);
                        mutex_unlock(&vq->mutex);
                }
        }
index e37c92d4d7ada2ca4f06b8f91d3f6b2a6b303610..9a3a09005e03b16a5f561c9c34f9974a89733c31 100644 (file)
@@ -49,7 +49,7 @@ static void handle_vq(struct vhost_test *n)
        void *private;
 
        mutex_lock(&vq->mutex);
-       private = vq->private_data;
+       private = vhost_vq_get_backend(vq);
        if (!private) {
                mutex_unlock(&vq->mutex);
                return;
@@ -120,7 +120,7 @@ static int vhost_test_open(struct inode *inode, struct file *f)
        vqs[VHOST_TEST_VQ] = &n->vqs[VHOST_TEST_VQ];
        n->vqs[VHOST_TEST_VQ].handle_kick = handle_vq_kick;
        vhost_dev_init(dev, vqs, VHOST_TEST_VQ_MAX, UIO_MAXIOV,
-                      VHOST_TEST_PKT_WEIGHT, VHOST_TEST_WEIGHT);
+                      VHOST_TEST_PKT_WEIGHT, VHOST_TEST_WEIGHT, NULL);
 
        f->private_data = n;
 
@@ -133,8 +133,8 @@ static void *vhost_test_stop_vq(struct vhost_test *n,
        void *private;
 
        mutex_lock(&vq->mutex);
-       private = vq->private_data;
-       vq->private_data = NULL;
+       private = vhost_vq_get_backend(vq);
+       vhost_vq_set_backend(vq, NULL);
        mutex_unlock(&vq->mutex);
        return private;
 }
@@ -198,8 +198,8 @@ static long vhost_test_run(struct vhost_test *n, int test)
                priv = test ? n : NULL;
 
                /* start polling new socket */
-               oldpriv = vq->private_data;
-               vq->private_data = priv;
+               oldpriv = vhost_vq_get_backend(vq);
+               vhost_vq_set_backend(vq, priv);
 
                r = vhost_vq_init_access(&n->vqs[index]);
 
@@ -225,7 +225,7 @@ static long vhost_test_reset_owner(struct vhost_test *n)
 {
        void *priv = NULL;
        long err;
-       struct vhost_umem *umem;
+       struct vhost_iotlb *umem;
 
        mutex_lock(&n->dev.mutex);
        err = vhost_dev_check_owner(&n->dev);
index 421f02a8530af2bfb0b1f1c4c7aef0f338929d2d..0968361e3b7745906c1b7da2eab84a7bda4767bc 100644 (file)
@@ -296,7 +296,6 @@ static long vhost_vdpa_vring_ioctl(struct vhost_vdpa *v, unsigned int cmd,
        struct vdpa_callback cb;
        struct vhost_virtqueue *vq;
        struct vhost_vring_state s;
-       u8 status;
        u32 idx;
        long r;
 
@@ -310,8 +309,6 @@ static long vhost_vdpa_vring_ioctl(struct vhost_vdpa *v, unsigned int cmd,
        idx = array_index_nospec(idx, v->nvqs);
        vq = &v->vqs[idx];
 
-       status = ops->get_status(vdpa);
-
        if (cmd == VHOST_VDPA_SET_VRING_ENABLE) {
                if (copy_from_user(&s, argp, sizeof(s)))
                        return -EFAULT;
@@ -678,8 +675,6 @@ static int vhost_vdpa_open(struct inode *inode, struct file *filep)
        int nvqs, i, r, opened;
 
        v = container_of(inode->i_cdev, struct vhost_vdpa, cdev);
-       if (!v)
-               return -ENODEV;
 
        opened = atomic_cmpxchg(&v->opened, 0, 1);
        if (opened)
index 181382185bbce99c894a52d3269c7da566179d77..f8403bd46b85dd5d0183baee2ef650cdd37e0fa6 100644 (file)
@@ -231,6 +231,33 @@ enum {
                         (1ULL << VIRTIO_F_VERSION_1)
 };
 
+/**
+ * vhost_vq_set_backend - Set backend.
+ *
+ * @vq            Virtqueue.
+ * @private_data  The private data.
+ *
+ * Context: Need to call with vq->mutex acquired.
+ */
+static inline void vhost_vq_set_backend(struct vhost_virtqueue *vq,
+                                       void *private_data)
+{
+       vq->private_data = private_data;
+}
+
+/**
+ * vhost_vq_get_backend - Get backend.
+ *
+ * @vq            Virtqueue.
+ *
+ * Context: Need to call with vq->mutex acquired.
+ * Return: Private data previously set with vhost_vq_set_backend.
+ */
+static inline void *vhost_vq_get_backend(struct vhost_virtqueue *vq)
+{
+       return vq->private_data;
+}
+
 static inline bool vhost_has_feature(struct vhost_virtqueue *vq, int bit)
 {
        return vq->acked_features & (1ULL << bit);
index ee0491f579ace20c7c1ac000e7f7540b5a40bdd0..ba8e0d6cfd9748dfdd39fa28865287a578f4e960 100644 (file)
 #include <linux/uaccess.h>
 #include <linux/slab.h>
 #include <linux/export.h>
+#if IS_REACHABLE(CONFIG_VHOST_IOTLB)
 #include <linux/bvec.h>
 #include <linux/highmem.h>
 #include <linux/vhost_iotlb.h>
+#endif
 #include <uapi/linux/virtio_config.h>
 
 static __printf(1,2) __cold void vringh_bad(const char *fmt, ...)
@@ -1059,6 +1061,8 @@ int vringh_need_notify_kern(struct vringh *vrh)
 }
 EXPORT_SYMBOL(vringh_need_notify_kern);
 
+#if IS_REACHABLE(CONFIG_VHOST_IOTLB)
+
 static int iotlb_translate(const struct vringh *vrh,
                           u64 addr, u64 len, struct bio_vec iov[],
                           int iov_size, u32 perm)
@@ -1416,5 +1420,6 @@ int vringh_need_notify_iotlb(struct vringh *vrh)
 }
 EXPORT_SYMBOL(vringh_need_notify_iotlb);
 
+#endif
 
 MODULE_LICENSE("GPL");
index 97669484a3f690f5f699fd9f4cadc32719cfb65e..e36aaf9ba7bd9d29008fb23b4bf87b44a1b4e1bd 100644 (file)
@@ -91,7 +91,7 @@ vhost_transport_do_send_pkt(struct vhost_vsock *vsock,
 
        mutex_lock(&vq->mutex);
 
-       if (!vq->private_data)
+       if (!vhost_vq_get_backend(vq))
                goto out;
 
        /* Avoid further vmexits, we're already processing the virtqueue */
@@ -440,7 +440,7 @@ static void vhost_vsock_handle_tx_kick(struct vhost_work *work)
 
        mutex_lock(&vq->mutex);
 
-       if (!vq->private_data)
+       if (!vhost_vq_get_backend(vq))
                goto out;
 
        vhost_disable_notify(&vsock->dev, vq);
@@ -533,8 +533,8 @@ static int vhost_vsock_start(struct vhost_vsock *vsock)
                        goto err_vq;
                }
 
-               if (!vq->private_data) {
-                       vq->private_data = vsock;
+               if (!vhost_vq_get_backend(vq)) {
+                       vhost_vq_set_backend(vq, vsock);
                        ret = vhost_vq_init_access(vq);
                        if (ret)
                                goto err_vq;
@@ -547,14 +547,14 @@ static int vhost_vsock_start(struct vhost_vsock *vsock)
        return 0;
 
 err_vq:
-       vq->private_data = NULL;
+       vhost_vq_set_backend(vq, NULL);
        mutex_unlock(&vq->mutex);
 
        for (i = 0; i < ARRAY_SIZE(vsock->vqs); i++) {
                vq = &vsock->vqs[i];
 
                mutex_lock(&vq->mutex);
-               vq->private_data = NULL;
+               vhost_vq_set_backend(vq, NULL);
                mutex_unlock(&vq->mutex);
        }
 err:
@@ -577,7 +577,7 @@ static int vhost_vsock_stop(struct vhost_vsock *vsock)
                struct vhost_virtqueue *vq = &vsock->vqs[i];
 
                mutex_lock(&vq->mutex);
-               vq->private_data = NULL;
+               vhost_vq_set_backend(vq, NULL);
                mutex_unlock(&vq->mutex);
        }
 
index 2bbf94b15bba219e50a370299552a4097e872410..69a32dfc318a59c8ff5cf05e9e6114b421d1c73b 100644 (file)
@@ -45,7 +45,7 @@ config VIRTIO_PCI_LEGACY
 
 config VIRTIO_VDPA
        tristate "vDPA driver for virtio devices"
-       select VDPA
+       depends on VDPA
        select VIRTIO
        help
          This driver provides support for virtio based paravirtual
index 0ef16566c3f3390936a3e3d97e99a1fb97f40193..51086a5afdd4179d52ba109fc346564bcee29eb8 100644 (file)
@@ -165,7 +165,7 @@ static void tell_host(struct virtio_balloon *vb, struct virtqueue *vq)
 
 }
 
-int virtballoon_free_page_report(struct page_reporting_dev_info *pr_dev_info,
+static int virtballoon_free_page_report(struct page_reporting_dev_info *pr_dev_info,
                                   struct scatterlist *sg, unsigned int nents)
 {
        struct virtio_balloon *vb =
@@ -580,7 +580,7 @@ static u32 virtio_balloon_cmd_id_received(struct virtio_balloon *vb)
        if (test_and_clear_bit(VIRTIO_BALLOON_CONFIG_READ_CMD_ID,
                               &vb->config_read_bitmap))
                virtio_cread(vb->vdev, struct virtio_balloon_config,
-                            free_page_report_cmd_id,
+                            free_page_hint_cmd_id,
                             &vb->cmd_id_received_cache);
 
        return vb->cmd_id_received_cache;
index 5ae529671b3d34b33813ec62bce0931d04c5f359..efaf65b0f42d08f563fa545d382067a941548aab 100644 (file)
@@ -3,6 +3,7 @@
 #include <linux/virtio.h>
 #include <linux/virtio_config.h>
 #include <linux/input.h>
+#include <linux/slab.h>
 
 #include <uapi/linux/virtio_ids.h>
 #include <uapi/linux/virtio_input.h>
index 6765949b3aab61cedc3167852c4fb1d1c3199bd1..380ad5ace7cfd54c09463a5e44e5c63c9c21b7ec 100644 (file)
@@ -169,7 +169,7 @@ static int afs_record_cm_probe(struct afs_call *call, struct afs_server *server)
 
        spin_lock(&server->probe_lock);
 
-       if (!test_bit(AFS_SERVER_FL_HAVE_EPOCH, &server->flags)) {
+       if (!test_and_set_bit(AFS_SERVER_FL_HAVE_EPOCH, &server->flags)) {
                server->cm_epoch = call->epoch;
                server->probe.cm_epoch = call->epoch;
                goto out;
index e1b9ed679045de54dfbfb857a9bb17d24c28f301..a587767b6ae15a549a57052f389e57381c9599f4 100644 (file)
@@ -117,11 +117,8 @@ out:
               (unsigned int)rtt, ret);
 
        have_result |= afs_fs_probe_done(server);
-       if (have_result) {
-               server->probe.have_result = true;
-               wake_up_var(&server->probe.have_result);
+       if (have_result)
                wake_up_all(&server->probe_wq);
-       }
 }
 
 /*
index ef732dd4e7ef54a2beb08b1adcae0fabd25db950..80255513e2307ab1ab015292a37f8dd4f9e60bdf 100644 (file)
@@ -533,12 +533,10 @@ struct afs_server {
                u32             abort_code;
                u32             cm_epoch;
                short           error;
-               bool            have_result;
                bool            responded:1;
                bool            is_yfs:1;
                bool            not_yfs:1;
                bool            local_failure:1;
-               bool            no_epoch:1;
                bool            cm_probed:1;
                bool            said_rebooted:1;
                bool            said_inconsistent:1;
@@ -1335,7 +1333,7 @@ extern struct afs_volume *afs_create_volume(struct afs_fs_context *);
 extern void afs_activate_volume(struct afs_volume *);
 extern void afs_deactivate_volume(struct afs_volume *);
 extern void afs_put_volume(struct afs_cell *, struct afs_volume *);
-extern int afs_check_volume_status(struct afs_volume *, struct key *);
+extern int afs_check_volume_status(struct afs_volume *, struct afs_fs_cursor *);
 
 /*
  * write.c
index 172ba569cd602b0544d7b763b7f20c2bf6d7d8cd..2a3305e42b145cc1a5ea336092793a302c79ee4a 100644 (file)
@@ -192,7 +192,7 @@ bool afs_select_fileserver(struct afs_fs_cursor *fc)
                        write_unlock(&vnode->volume->servers_lock);
 
                        set_bit(AFS_VOLUME_NEEDS_UPDATE, &vnode->volume->flags);
-                       error = afs_check_volume_status(vnode->volume, fc->key);
+                       error = afs_check_volume_status(vnode->volume, fc);
                        if (error < 0)
                                goto failed_set_error;
 
@@ -281,7 +281,7 @@ bool afs_select_fileserver(struct afs_fs_cursor *fc)
 
                        set_bit(AFS_VOLUME_WAIT, &vnode->volume->flags);
                        set_bit(AFS_VOLUME_NEEDS_UPDATE, &vnode->volume->flags);
-                       error = afs_check_volume_status(vnode->volume, fc->key);
+                       error = afs_check_volume_status(vnode->volume, fc);
                        if (error < 0)
                                goto failed_set_error;
 
@@ -341,7 +341,7 @@ start:
        /* See if we need to do an update of the volume record.  Note that the
         * volume may have moved or even have been deleted.
         */
-       error = afs_check_volume_status(vnode->volume, fc->key);
+       error = afs_check_volume_status(vnode->volume, fc);
        if (error < 0)
                goto failed_set_error;
 
index b7f3cb2130caee38a6458d3d81422f83637698f7..11b90ac7ea30f57c88d2a048bee657341637a942 100644 (file)
@@ -594,12 +594,9 @@ retry:
        }
 
        ret = wait_on_bit(&server->flags, AFS_SERVER_FL_UPDATING,
-                         TASK_INTERRUPTIBLE);
+                         (fc->flags & AFS_FS_CURSOR_INTR) ?
+                         TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE);
        if (ret == -ERESTARTSYS) {
-               if (!(fc->flags & AFS_FS_CURSOR_INTR) && server->addresses) {
-                       _leave(" = t [intr]");
-                       return true;
-               }
                fc->error = ret;
                _leave(" = f [intr]");
                return false;
index 9a5ce9687779cb55b854689b429ba83447b1da9f..72eacc14e6e1b14eed726d18e669dd0255ae0879 100644 (file)
@@ -302,8 +302,8 @@ static void afs_vl_dump_edestaddrreq(const struct afs_vl_cursor *vc)
                                pr_notice("VC:  - nr=%u/%u/%u pf=%u\n",
                                          a->nr_ipv4, a->nr_addrs, a->max_addrs,
                                          a->preferred);
-                               pr_notice("VC:  - pr=%lx R=%lx F=%lx\n",
-                                         a->probed, a->responded, a->failed);
+                               pr_notice("VC:  - R=%lx F=%lx\n",
+                                         a->responded, a->failed);
                                if (a == vc->ac.alist)
                                        pr_notice("VC:  - current\n");
                        }
index 92ca5e27573b7a1d345f7edbc329206cbf548d69..4310336b9bb8c10543c0157950d4b19d2a4d0eab 100644 (file)
@@ -281,7 +281,7 @@ error:
 /*
  * Make sure the volume record is up to date.
  */
-int afs_check_volume_status(struct afs_volume *volume, struct key *key)
+int afs_check_volume_status(struct afs_volume *volume, struct afs_fs_cursor *fc)
 {
        time64_t now = ktime_get_real_seconds();
        int ret, retries = 0;
@@ -299,7 +299,7 @@ retry:
        }
 
        if (!test_and_set_bit_lock(AFS_VOLUME_UPDATING, &volume->flags)) {
-               ret = afs_update_volume_status(volume, key);
+               ret = afs_update_volume_status(volume, fc->key);
                clear_bit_unlock(AFS_VOLUME_WAIT, &volume->flags);
                clear_bit_unlock(AFS_VOLUME_UPDATING, &volume->flags);
                wake_up_bit(&volume->flags, AFS_VOLUME_WAIT);
@@ -312,7 +312,9 @@ retry:
                return 0;
        }
 
-       ret = wait_on_bit(&volume->flags, AFS_VOLUME_WAIT, TASK_INTERRUPTIBLE);
+       ret = wait_on_bit(&volume->flags, AFS_VOLUME_WAIT,
+                         (fc->flags & AFS_FS_CURSOR_INTR) ?
+                         TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE);
        if (ret == -ERESTARTSYS) {
                _leave(" = %d", ret);
                return ret;
index 52b6f646cdbd0af27d827d9e4d983ec1455c87f0..93672c3f1c78c886eaeffaff6746bf2ee2937d99 100644 (file)
@@ -19,7 +19,6 @@
 #include <linux/module.h>
 #include <linux/blkpg.h>
 #include <linux/magic.h>
-#include <linux/dax.h>
 #include <linux/buffer_head.h>
 #include <linux/swap.h>
 #include <linux/pagevec.h>
@@ -1893,6 +1892,16 @@ static void __blkdev_put(struct block_device *bdev, fmode_t mode, int for_part)
        struct gendisk *disk = bdev->bd_disk;
        struct block_device *victim = NULL;
 
+       /*
+        * Sync early if it looks like we're the last one.  If someone else
+        * opens the block device between now and the decrement of bd_openers
+        * then we did a sync that we didn't need to, but that's not the end
+        * of the world and we want to avoid long (could be several minute)
+        * syncs while holding the mutex.
+        */
+       if (bdev->bd_openers == 1)
+               sync_blockdev(bdev);
+
        mutex_lock_nested(&bdev->bd_mutex, for_part);
        if (for_part)
                bdev->bd_part_count--;
index 47f66c6a7d7fca39d6d55b7338f2685ac6b0155e..696f47103cfc93b9234d1bb9e27f06be49a1495c 100644 (file)
@@ -916,7 +916,7 @@ int btrfs_remove_block_group(struct btrfs_trans_handle *trans,
        path = btrfs_alloc_path();
        if (!path) {
                ret = -ENOMEM;
-               goto out;
+               goto out_put_group;
        }
 
        /*
@@ -954,7 +954,7 @@ int btrfs_remove_block_group(struct btrfs_trans_handle *trans,
                ret = btrfs_orphan_add(trans, BTRFS_I(inode));
                if (ret) {
                        btrfs_add_delayed_iput(inode);
-                       goto out;
+                       goto out_put_group;
                }
                clear_nlink(inode);
                /* One for the block groups ref */
@@ -977,13 +977,13 @@ int btrfs_remove_block_group(struct btrfs_trans_handle *trans,
 
        ret = btrfs_search_slot(trans, tree_root, &key, path, -1, 1);
        if (ret < 0)
-               goto out;
+               goto out_put_group;
        if (ret > 0)
                btrfs_release_path(path);
        if (ret == 0) {
                ret = btrfs_del_item(trans, tree_root, path);
                if (ret)
-                       goto out;
+                       goto out_put_group;
                btrfs_release_path(path);
        }
 
@@ -1102,9 +1102,9 @@ int btrfs_remove_block_group(struct btrfs_trans_handle *trans,
 
        ret = remove_block_group_free_space(trans, block_group);
        if (ret)
-               goto out;
+               goto out_put_group;
 
-       btrfs_put_block_group(block_group);
+       /* Once for the block groups rbtree */
        btrfs_put_block_group(block_group);
 
        ret = btrfs_search_slot(trans, root, &key, path, -1, 1);
@@ -1127,6 +1127,10 @@ int btrfs_remove_block_group(struct btrfs_trans_handle *trans,
                /* once for the tree */
                free_extent_map(em);
        }
+
+out_put_group:
+       /* Once for the lookup reference */
+       btrfs_put_block_group(block_group);
 out:
        if (remove_rsv)
                btrfs_delayed_refs_rsv_release(fs_info, 1);
@@ -1288,11 +1292,15 @@ static bool clean_pinned_extents(struct btrfs_trans_handle *trans,
        if (ret)
                goto err;
        mutex_unlock(&fs_info->unused_bg_unpin_mutex);
+       if (prev_trans)
+               btrfs_put_transaction(prev_trans);
 
        return true;
 
 err:
        mutex_unlock(&fs_info->unused_bg_unpin_mutex);
+       if (prev_trans)
+               btrfs_put_transaction(prev_trans);
        btrfs_dec_block_group_ro(bg);
        return false;
 }
index 21a15776dac421273316740a4d1741045a1134e6..353228d62f5a1232bea3363d3f702aa9b4ee842b 100644 (file)
@@ -1,4 +1,4 @@
-// SPDX-License-Identifier: GPL-2.0
+/* SPDX-License-Identifier: GPL-2.0 */
 
 #ifndef BTRFS_DISCARD_H
 #define BTRFS_DISCARD_H
index a6cb5cbbdb9f56a849cacceba0b96b3ee825cb97..d10c7be10f3b80158201c81707c116e9b9ab9e42 100644 (file)
@@ -2036,9 +2036,6 @@ void btrfs_free_fs_roots(struct btrfs_fs_info *fs_info)
                for (i = 0; i < ret; i++)
                        btrfs_drop_and_free_fs_root(fs_info, gang[i]);
        }
-
-       if (test_bit(BTRFS_FS_STATE_ERROR, &fs_info->fs_state))
-               btrfs_free_log_root_tree(NULL, fs_info);
 }
 
 static void btrfs_init_scrub(struct btrfs_fs_info *fs_info)
@@ -3888,7 +3885,7 @@ void btrfs_drop_and_free_fs_root(struct btrfs_fs_info *fs_info,
        spin_unlock(&fs_info->fs_roots_radix_lock);
 
        if (test_bit(BTRFS_FS_STATE_ERROR, &fs_info->fs_state)) {
-               btrfs_free_log(NULL, root);
+               ASSERT(root->log_root == NULL);
                if (root->reloc_root) {
                        btrfs_put_root(root->reloc_root);
                        root->reloc_root = NULL;
@@ -4211,6 +4208,36 @@ static void btrfs_error_commit_super(struct btrfs_fs_info *fs_info)
        up_write(&fs_info->cleanup_work_sem);
 }
 
+static void btrfs_drop_all_logs(struct btrfs_fs_info *fs_info)
+{
+       struct btrfs_root *gang[8];
+       u64 root_objectid = 0;
+       int ret;
+
+       spin_lock(&fs_info->fs_roots_radix_lock);
+       while ((ret = radix_tree_gang_lookup(&fs_info->fs_roots_radix,
+                                            (void **)gang, root_objectid,
+                                            ARRAY_SIZE(gang))) != 0) {
+               int i;
+
+               for (i = 0; i < ret; i++)
+                       gang[i] = btrfs_grab_root(gang[i]);
+               spin_unlock(&fs_info->fs_roots_radix_lock);
+
+               for (i = 0; i < ret; i++) {
+                       if (!gang[i])
+                               continue;
+                       root_objectid = gang[i]->root_key.objectid;
+                       btrfs_free_log(NULL, gang[i]);
+                       btrfs_put_root(gang[i]);
+               }
+               root_objectid++;
+               spin_lock(&fs_info->fs_roots_radix_lock);
+       }
+       spin_unlock(&fs_info->fs_roots_radix_lock);
+       btrfs_free_log_root_tree(NULL, fs_info);
+}
+
 static void btrfs_destroy_ordered_extents(struct btrfs_root *root)
 {
        struct btrfs_ordered_extent *ordered;
@@ -4603,6 +4630,7 @@ static int btrfs_cleanup_transaction(struct btrfs_fs_info *fs_info)
        btrfs_destroy_delayed_inodes(fs_info);
        btrfs_assert_delayed_root_empty(fs_info);
        btrfs_destroy_all_delalloc_inodes(fs_info);
+       btrfs_drop_all_logs(fs_info);
        mutex_unlock(&fs_info->transaction_kthread_mutex);
 
        return 0;
index d35936c934ab0dacc8623b800c3843fc09a7cca3..03bc7134e8cbf4282d3b872b5544b4b7750ea6fc 100644 (file)
@@ -4559,6 +4559,7 @@ int btrfs_recover_relocation(struct btrfs_root *root)
                if (IS_ERR(fs_root)) {
                        err = PTR_ERR(fs_root);
                        list_add_tail(&reloc_root->root_list, &reloc_roots);
+                       btrfs_end_transaction(trans);
                        goto out_unset;
                }
 
index 599a0bf7257bdbc735668a36c11371194cd82cd4..a60f60396cfa06efb622d2bea25261bf0ea0771a 100644 (file)
@@ -967,7 +967,7 @@ grow_dev_page(struct block_device *bdev, sector_t block,
        struct page *page;
        struct buffer_head *bh;
        sector_t end_block;
-       int ret = 0;            /* Will call free_more_memory() */
+       int ret = 0;
        gfp_t gfp_mask;
 
        gfp_mask = mapping_gfp_constraint(inode->i_mapping, ~__GFP_FS) | gfp;
index 05dd3dea684b478048deca2132be96b64af69ac4..39b708d9d86d069aa873d6a18fffbfba4fb0f028 100644 (file)
@@ -1891,7 +1891,8 @@ GLOBAL_EXTERN struct list_head            cifs_tcp_ses_list;
 /*
  * This lock protects the cifs_tcp_ses_list, the list of smb sessions per
  * tcp session, and the list of tcon's per smb session. It also protects
- * the reference counters for the server, smb session, and tcon. Finally,
+ * the reference counters for the server, smb session, and tcon. It also
+ * protects some fields in the TCP_Server_Info struct such as dstaddr. Finally,
  * changes to the tcon->tidStatus should be done while holding this lock.
  * generally the locks should be taken in order tcp_ses_lock before
  * tcon->open_file_lock and that before file->file_info_lock since the
index 95b3ab0ca8c0859ab145f32a2ad37858b3294d7f..28268ed461b8286fb302ed732b47b2776b10209a 100644 (file)
@@ -375,8 +375,10 @@ static int reconn_set_ipaddr(struct TCP_Server_Info *server)
                return rc;
        }
 
+       spin_lock(&cifs_tcp_ses_lock);
        rc = cifs_convert_address((struct sockaddr *)&server->dstaddr, ipaddr,
                                  strlen(ipaddr));
+       spin_unlock(&cifs_tcp_ses_lock);
        kfree(ipaddr);
 
        return !rc ? -1 : 0;
@@ -3373,6 +3375,10 @@ cifs_find_tcon(struct cifs_ses *ses, struct smb_vol *volume_info)
        spin_lock(&cifs_tcp_ses_lock);
        list_for_each(tmp, &ses->tcon_list) {
                tcon = list_entry(tmp, struct cifs_tcon, tcon_list);
+#ifdef CONFIG_CIFS_DFS_UPCALL
+               if (tcon->dfs_path)
+                       continue;
+#endif
                if (!match_tcon(tcon, volume_info))
                        continue;
                ++tcon->tc_count;
index a456febd4109ba41ad795fcafa672e2e47c2aafa..550ce9020a3eebe8e3cd5a8f216284aa545b024b 100644 (file)
@@ -1025,51 +1025,99 @@ int copy_path_name(char *dst, const char *src)
 }
 
 struct super_cb_data {
-       struct TCP_Server_Info *server;
+       void *data;
        struct super_block *sb;
 };
 
-static void super_cb(struct super_block *sb, void *arg)
+static void tcp_super_cb(struct super_block *sb, void *arg)
 {
-       struct super_cb_data *d = arg;
+       struct super_cb_data *sd = arg;
+       struct TCP_Server_Info *server = sd->data;
        struct cifs_sb_info *cifs_sb;
        struct cifs_tcon *tcon;
 
-       if (d->sb)
+       if (sd->sb)
                return;
 
        cifs_sb = CIFS_SB(sb);
        tcon = cifs_sb_master_tcon(cifs_sb);
-       if (tcon->ses->server == d->server)
-               d->sb = sb;
+       if (tcon->ses->server == server)
+               sd->sb = sb;
 }
 
-struct super_block *cifs_get_tcp_super(struct TCP_Server_Info *server)
+static struct super_block *__cifs_get_super(void (*f)(struct super_block *, void *),
+                                           void *data)
 {
-       struct super_cb_data d = {
-               .server = server,
+       struct super_cb_data sd = {
+               .data = data,
                .sb = NULL,
        };
 
-       iterate_supers_type(&cifs_fs_type, super_cb, &d);
+       iterate_supers_type(&cifs_fs_type, f, &sd);
 
-       if (unlikely(!d.sb))
-               return ERR_PTR(-ENOENT);
+       if (!sd.sb)
+               return ERR_PTR(-EINVAL);
        /*
         * Grab an active reference in order to prevent automounts (DFS links)
         * of expiring and then freeing up our cifs superblock pointer while
         * we're doing failover.
         */
-       cifs_sb_active(d.sb);
-       return d.sb;
+       cifs_sb_active(sd.sb);
+       return sd.sb;
 }
 
-void cifs_put_tcp_super(struct super_block *sb)
+static void __cifs_put_super(struct super_block *sb)
 {
        if (!IS_ERR_OR_NULL(sb))
                cifs_sb_deactive(sb);
 }
 
+struct super_block *cifs_get_tcp_super(struct TCP_Server_Info *server)
+{
+       return __cifs_get_super(tcp_super_cb, server);
+}
+
+void cifs_put_tcp_super(struct super_block *sb)
+{
+       __cifs_put_super(sb);
+}
+
+#ifdef CONFIG_CIFS_DFS_UPCALL
+static void tcon_super_cb(struct super_block *sb, void *arg)
+{
+       struct super_cb_data *sd = arg;
+       struct cifs_tcon *tcon = sd->data;
+       struct cifs_sb_info *cifs_sb;
+
+       if (sd->sb)
+               return;
+
+       cifs_sb = CIFS_SB(sb);
+       if (tcon->dfs_path && cifs_sb->origin_fullpath &&
+           !strcasecmp(tcon->dfs_path, cifs_sb->origin_fullpath))
+               sd->sb = sb;
+}
+
+static inline struct super_block *cifs_get_tcon_super(struct cifs_tcon *tcon)
+{
+       return __cifs_get_super(tcon_super_cb, tcon);
+}
+
+static inline void cifs_put_tcon_super(struct super_block *sb)
+{
+       __cifs_put_super(sb);
+}
+#else
+static inline struct super_block *cifs_get_tcon_super(struct cifs_tcon *tcon)
+{
+       return ERR_PTR(-EOPNOTSUPP);
+}
+
+static inline void cifs_put_tcon_super(struct super_block *sb)
+{
+}
+#endif
+
 int update_super_prepath(struct cifs_tcon *tcon, const char *prefix,
                         size_t prefix_len)
 {
@@ -1077,7 +1125,7 @@ int update_super_prepath(struct cifs_tcon *tcon, const char *prefix,
        struct cifs_sb_info *cifs_sb;
        int rc = 0;
 
-       sb = cifs_get_tcp_super(tcon->ses->server);
+       sb = cifs_get_tcon_super(tcon);
        if (IS_ERR(sb))
                return PTR_ERR(sb);
 
@@ -1099,6 +1147,6 @@ int update_super_prepath(struct cifs_tcon *tcon, const char *prefix,
        cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_USE_PREFIX_PATH;
 
 out:
-       cifs_put_tcp_super(sb);
+       cifs_put_tcon_super(sb);
        return rc;
 }
index b36c46f48705c7cc6c46683313b6b02505fd3ebb..f829f4165d38c1b196481b91d2d172b1c96090ec 100644 (file)
@@ -687,6 +687,11 @@ int open_shroot(unsigned int xid, struct cifs_tcon *tcon,
        if (smb3_encryption_required(tcon))
                flags |= CIFS_TRANSFORM_REQ;
 
+       if (!server->ops->new_lease_key)
+               return -EIO;
+
+       server->ops->new_lease_key(pfid);
+
        memset(rqst, 0, sizeof(rqst));
        resp_buftype[0] = resp_buftype[1] = CIFS_NO_BUFFER;
        memset(rsp_iov, 0, sizeof(rsp_iov));
index f8296a82d01dfd70deb38ede24feab53331825bd..408418e6aa13120224517139c17b5acc3e282842 100644 (file)
@@ -211,6 +211,8 @@ static int format_corename(struct core_name *cn, struct coredump_params *cprm,
                        return -ENOMEM;
                (*argv)[(*argc)++] = 0;
                ++pat_ptr;
+               if (!(*pat_ptr))
+                       return -ENOMEM;
        }
 
        /* Repeat as long as we have more pattern to process and more output
index 2d357680094cb434a935aa18666756e981270e38..ae49a55bda001bbe3877c0256cfaac6e51d92c13 100644 (file)
@@ -506,20 +506,11 @@ DEFINE_DEBUGFS_ATTRIBUTE(fops_u32_wo, NULL, debugfs_u32_set, "%llu\n");
  * This function creates a file in debugfs with the given name that
  * contains the value of the variable @value.  If the @mode variable is so
  * set, it can be read from, and written to.
- *
- * This function will return a pointer to a dentry if it succeeds.  This
- * pointer must be passed to the debugfs_remove() function when the file is
- * to be removed (no automatic cleanup happens if your module is unloaded,
- * you are responsible here.)  If an error occurs, ERR_PTR(-ERROR) will be
- * returned.
- *
- * If debugfs is not enabled in the kernel, the value ERR_PTR(-ENODEV) will
- * be returned.
  */
-struct dentry *debugfs_create_u32(const char *name, umode_t mode,
-                                struct dentry *parent, u32 *value)
+void debugfs_create_u32(const char *name, umode_t mode, struct dentry *parent,
+                       u32 *value)
 {
-       return debugfs_create_mode_unsafe(name, mode, parent, value, &fops_u32,
+       debugfs_create_mode_unsafe(name, mode, parent, value, &fops_u32,
                                   &fops_u32_ro, &fops_u32_wo);
 }
 EXPORT_SYMBOL_GPL(debugfs_create_u32);
index 6a04cc02565a1f3823ad9a109238bad9553a82f1..6774a5a6ded8290fb790bf70f04a1c6e3253cd7a 100644 (file)
@@ -91,7 +91,6 @@ static int exfat_allocate_bitmap(struct super_block *sb,
                }
        }
 
-       sbi->pbr_bh = NULL;
        return 0;
 }
 
@@ -137,8 +136,6 @@ void exfat_free_bitmap(struct exfat_sb_info *sbi)
 {
        int i;
 
-       brelse(sbi->pbr_bh);
-
        for (i = 0; i < sbi->map_sectors; i++)
                __brelse(sbi->vol_amap[i]);
 
index 67d4e46fb81003d0c367862ee986b37c80e7fa4e..d67fb8a6f770c28db8f1618c78fde493e2a4b965 100644 (file)
@@ -507,6 +507,7 @@ void exfat_msg(struct super_block *sb, const char *lv, const char *fmt, ...)
                __printf(3, 4) __cold;
 void exfat_get_entry_time(struct exfat_sb_info *sbi, struct timespec64 *ts,
                u8 tz, __le16 time, __le16 date, u8 time_ms);
+void exfat_truncate_atime(struct timespec64 *ts);
 void exfat_set_entry_time(struct exfat_sb_info *sbi, struct timespec64 *ts,
                u8 *tz, __le16 *time, __le16 *date, u8 *time_ms);
 unsigned short exfat_calc_chksum_2byte(void *data, int len,
index 483f683757aa87420ba347afd3c9db9e94b8a14d..4f76764165cf6f63a99c5e192ab33685e8e987b7 100644 (file)
@@ -273,6 +273,7 @@ int exfat_getattr(const struct path *path, struct kstat *stat,
        struct exfat_inode_info *ei = EXFAT_I(inode);
 
        generic_fillattr(inode, stat);
+       exfat_truncate_atime(&stat->atime);
        stat->result_mask |= STATX_BTIME;
        stat->btime.tv_sec = ei->i_crtime.tv_sec;
        stat->btime.tv_nsec = ei->i_crtime.tv_nsec;
@@ -339,6 +340,7 @@ int exfat_setattr(struct dentry *dentry, struct iattr *attr)
        }
 
        setattr_copy(inode, attr);
+       exfat_truncate_atime(&inode->i_atime);
        mark_inode_dirty(inode);
 
 out:
index 14a3300848f6a0fb754b9d34bdacbc31b90f5d07..ebd2cbe3cbc11c2aede3819c414020b9344ec1f9 100644 (file)
@@ -88,7 +88,8 @@ void exfat_get_entry_time(struct exfat_sb_info *sbi, struct timespec64 *ts,
        if (time_ms) {
                ts->tv_sec += time_ms / 100;
                ts->tv_nsec = (time_ms % 100) * 10 * NSEC_PER_MSEC;
-       }
+       } else
+               ts->tv_nsec = 0;
 
        if (tz & EXFAT_TZ_VALID)
                /* Adjust timezone to UTC0. */
@@ -124,6 +125,17 @@ void exfat_set_entry_time(struct exfat_sb_info *sbi, struct timespec64 *ts,
        *tz = EXFAT_TZ_VALID;
 }
 
+/*
+ * The timestamp for access_time has double seconds granularity.
+ * (There is no 10msIncrement field for access_time unlike create/modify_time)
+ * atime also has only a 2-second resolution.
+ */
+void exfat_truncate_atime(struct timespec64 *ts)
+{
+       ts->tv_sec = round_down(ts->tv_sec, 2);
+       ts->tv_nsec = 0;
+}
+
 unsigned short exfat_calc_chksum_2byte(void *data, int len,
                unsigned short chksum, int type)
 {
index a8681d91f56900107ea3df90e2b6dd986045a7bc..b72d782568b811ece222db0dd3575fd8bf2c958a 100644 (file)
@@ -595,6 +595,7 @@ static int exfat_create(struct inode *dir, struct dentry *dentry, umode_t mode,
        inode_inc_iversion(inode);
        inode->i_mtime = inode->i_atime = inode->i_ctime =
                EXFAT_I(inode)->i_crtime = current_time(inode);
+       exfat_truncate_atime(&inode->i_atime);
        /* timestamp is already written, so mark_inode_dirty() is unneeded. */
 
        d_instantiate(dentry, inode);
@@ -854,6 +855,7 @@ static int exfat_unlink(struct inode *dir, struct dentry *dentry)
 
        inode_inc_iversion(dir);
        dir->i_mtime = dir->i_atime = current_time(dir);
+       exfat_truncate_atime(&dir->i_atime);
        if (IS_DIRSYNC(dir))
                exfat_sync_inode(dir);
        else
@@ -861,6 +863,7 @@ static int exfat_unlink(struct inode *dir, struct dentry *dentry)
 
        clear_nlink(inode);
        inode->i_mtime = inode->i_atime = current_time(inode);
+       exfat_truncate_atime(&inode->i_atime);
        exfat_unhash_inode(inode);
        exfat_d_version_set(dentry, inode_query_iversion(dir));
 unlock:
@@ -903,6 +906,7 @@ static int exfat_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
        inode_inc_iversion(inode);
        inode->i_mtime = inode->i_atime = inode->i_ctime =
                EXFAT_I(inode)->i_crtime = current_time(inode);
+       exfat_truncate_atime(&inode->i_atime);
        /* timestamp is already written, so mark_inode_dirty() is unneeded. */
 
        d_instantiate(dentry, inode);
@@ -1019,6 +1023,7 @@ static int exfat_rmdir(struct inode *dir, struct dentry *dentry)
 
        inode_inc_iversion(dir);
        dir->i_mtime = dir->i_atime = current_time(dir);
+       exfat_truncate_atime(&dir->i_atime);
        if (IS_DIRSYNC(dir))
                exfat_sync_inode(dir);
        else
@@ -1027,6 +1032,7 @@ static int exfat_rmdir(struct inode *dir, struct dentry *dentry)
 
        clear_nlink(inode);
        inode->i_mtime = inode->i_atime = current_time(inode);
+       exfat_truncate_atime(&inode->i_atime);
        exfat_unhash_inode(inode);
        exfat_d_version_set(dentry, inode_query_iversion(dir));
 unlock:
@@ -1387,6 +1393,7 @@ static int exfat_rename(struct inode *old_dir, struct dentry *old_dentry,
        inode_inc_iversion(new_dir);
        new_dir->i_ctime = new_dir->i_mtime = new_dir->i_atime =
                EXFAT_I(new_dir)->i_crtime = current_time(new_dir);
+       exfat_truncate_atime(&new_dir->i_atime);
        if (IS_DIRSYNC(new_dir))
                exfat_sync_inode(new_dir);
        else
index 16ed202ef5279abc40b23d03cd346b4baf4c23d3..0565d5539d57c6678c81997228dc3b8116eb864c 100644 (file)
@@ -49,6 +49,7 @@ static void exfat_put_super(struct super_block *sb)
                sync_blockdev(sb->s_bdev);
        exfat_set_vol_flags(sb, VOL_CLEAN);
        exfat_free_bitmap(sbi);
+       brelse(sbi->pbr_bh);
        mutex_unlock(&sbi->s_lock);
 
        call_rcu(&sbi->rcu, exfat_delayed_free);
@@ -100,7 +101,7 @@ static int exfat_statfs(struct dentry *dentry, struct kstatfs *buf)
 int exfat_set_vol_flags(struct super_block *sb, unsigned short new_flag)
 {
        struct exfat_sb_info *sbi = EXFAT_SB(sb);
-       struct pbr64 *bpb;
+       struct pbr64 *bpb = (struct pbr64 *)sbi->pbr_bh->b_data;
        bool sync = 0;
 
        /* flags are not changed */
@@ -115,15 +116,6 @@ int exfat_set_vol_flags(struct super_block *sb, unsigned short new_flag)
        if (sb_rdonly(sb))
                return 0;
 
-       if (!sbi->pbr_bh) {
-               sbi->pbr_bh = sb_bread(sb, 0);
-               if (!sbi->pbr_bh) {
-                       exfat_msg(sb, KERN_ERR, "failed to read boot sector");
-                       return -ENOMEM;
-               }
-       }
-
-       bpb = (struct pbr64 *)sbi->pbr_bh->b_data;
        bpb->bsx.vol_flags = cpu_to_le16(new_flag);
 
        if (new_flag == VOL_DIRTY && !buffer_dirty(sbi->pbr_bh))
@@ -159,7 +151,6 @@ static int exfat_show_options(struct seq_file *m, struct dentry *root)
                seq_puts(m, ",iocharset=utf8");
        else if (sbi->nls_io)
                seq_printf(m, ",iocharset=%s", sbi->nls_io->charset);
-       seq_printf(m, ",bps=%ld", sb->s_blocksize);
        if (opts->errors == EXFAT_ERRORS_CONT)
                seq_puts(m, ",errors=continue");
        else if (opts->errors == EXFAT_ERRORS_PANIC)
@@ -351,14 +342,15 @@ static int exfat_read_root(struct inode *inode)
        exfat_save_attr(inode, ATTR_SUBDIR);
        inode->i_mtime = inode->i_atime = inode->i_ctime = ei->i_crtime =
                current_time(inode);
+       exfat_truncate_atime(&inode->i_atime);
        exfat_cache_init_inode(inode);
        return 0;
 }
 
-static struct pbr *exfat_read_pbr_with_logical_sector(struct super_block *sb,
-               struct buffer_head **prev_bh)
+static struct pbr *exfat_read_pbr_with_logical_sector(struct super_block *sb)
 {
-       struct pbr *p_pbr = (struct pbr *) (*prev_bh)->b_data;
+       struct exfat_sb_info *sbi = EXFAT_SB(sb);
+       struct pbr *p_pbr = (struct pbr *) (sbi->pbr_bh)->b_data;
        unsigned short logical_sect = 0;
 
        logical_sect = 1 << p_pbr->bsx.f64.sect_size_bits;
@@ -378,26 +370,23 @@ static struct pbr *exfat_read_pbr_with_logical_sector(struct super_block *sb,
        }
 
        if (logical_sect > sb->s_blocksize) {
-               struct buffer_head *bh = NULL;
-
-               __brelse(*prev_bh);
-               *prev_bh = NULL;
+               brelse(sbi->pbr_bh);
+               sbi->pbr_bh = NULL;
 
                if (!sb_set_blocksize(sb, logical_sect)) {
                        exfat_msg(sb, KERN_ERR,
                                "unable to set blocksize %u", logical_sect);
                        return NULL;
                }
-               bh = sb_bread(sb, 0);
-               if (!bh) {
+               sbi->pbr_bh = sb_bread(sb, 0);
+               if (!sbi->pbr_bh) {
                        exfat_msg(sb, KERN_ERR,
                                "unable to read boot sector (logical sector size = %lu)",
                                sb->s_blocksize);
                        return NULL;
                }
 
-               *prev_bh = bh;
-               p_pbr = (struct pbr *) bh->b_data;
+               p_pbr = (struct pbr *)sbi->pbr_bh->b_data;
        }
        return p_pbr;
 }
@@ -408,21 +397,20 @@ static int __exfat_fill_super(struct super_block *sb)
        int ret;
        struct pbr *p_pbr;
        struct pbr64 *p_bpb;
-       struct buffer_head *bh;
        struct exfat_sb_info *sbi = EXFAT_SB(sb);
 
        /* set block size to read super block */
        sb_min_blocksize(sb, 512);
 
        /* read boot sector */
-       bh = sb_bread(sb, 0);
-       if (!bh) {
+       sbi->pbr_bh = sb_bread(sb, 0);
+       if (!sbi->pbr_bh) {
                exfat_msg(sb, KERN_ERR, "unable to read boot sector");
                return -EIO;
        }
 
        /* PRB is read */
-       p_pbr = (struct pbr *)bh->b_data;
+       p_pbr = (struct pbr *)sbi->pbr_bh->b_data;
 
        /* check the validity of PBR */
        if (le16_to_cpu((p_pbr->signature)) != PBR_SIGNATURE) {
@@ -433,7 +421,7 @@ static int __exfat_fill_super(struct super_block *sb)
 
 
        /* check logical sector size */
-       p_pbr = exfat_read_pbr_with_logical_sector(sb, &bh);
+       p_pbr = exfat_read_pbr_with_logical_sector(sb);
        if (!p_pbr) {
                ret = -EIO;
                goto free_bh;
@@ -514,7 +502,7 @@ free_alloc_bitmap:
 free_upcase_table:
        exfat_free_upcase_table(sbi);
 free_bh:
-       brelse(bh);
+       brelse(sbi->pbr_bh);
        return ret;
 }
 
@@ -531,17 +519,18 @@ static int exfat_fill_super(struct super_block *sb, struct fs_context *fc)
        if (opts->discard) {
                struct request_queue *q = bdev_get_queue(sb->s_bdev);
 
-               if (!blk_queue_discard(q))
+               if (!blk_queue_discard(q)) {
                        exfat_msg(sb, KERN_WARNING,
                                "mounting with \"discard\" option, but the device does not support discard");
-               opts->discard = 0;
+                       opts->discard = 0;
+               }
        }
 
        sb->s_flags |= SB_NODIRATIME;
        sb->s_magic = EXFAT_SUPER_MAGIC;
        sb->s_op = &exfat_sops;
 
-       sb->s_time_gran = 1;
+       sb->s_time_gran = 10 * NSEC_PER_MSEC;
        sb->s_time_min = EXFAT_MIN_TIMESTAMP_SECS;
        sb->s_time_max = EXFAT_MAX_TIMESTAMP_SECS;
 
@@ -605,6 +594,7 @@ put_inode:
 free_table:
        exfat_free_upcase_table(sbi);
        exfat_free_bitmap(sbi);
+       brelse(sbi->pbr_bh);
 
 check_nls_io:
        unload_nls(sbi->nls_io);
@@ -717,6 +707,7 @@ static void __exit exit_exfat_fs(void)
 module_init(init_exfat_fs);
 module_exit(exit_exfat_fs);
 
+MODULE_ALIAS_FS("exfat");
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("exFAT filesystem support");
 MODULE_AUTHOR("Samsung Electronics Co., Ltd.");
index 381d50becd04a19d55f8953032238d93e839054b..c687f57fb65157602e0b2d4e993b0bb087094db5 100644 (file)
@@ -4200,17 +4200,17 @@ static void io_async_task_func(struct callback_head *cb)
 
        spin_unlock_irq(&ctx->completion_lock);
 
+       /* restore ->work in case we need to retry again */
+       memcpy(&req->work, &apoll->work, sizeof(req->work));
+
        if (canceled) {
                kfree(apoll);
                io_cqring_ev_posted(ctx);
                req_set_fail_links(req);
-               io_put_req(req);
+               io_double_put_req(req);
                return;
        }
 
-       /* restore ->work in case we need to retry again */
-       memcpy(&req->work, &apoll->work, sizeof(req->work));
-
        __set_current_state(TASK_RUNNING);
        mutex_lock(&ctx->uring_lock);
        __io_queue_sqe(req, NULL);
@@ -4369,7 +4369,7 @@ static bool io_poll_remove_one(struct io_kiocb *req)
 
        hash_del(&req->hash_node);
 
-       if (apoll) {
+       if (do_complete && apoll) {
                /*
                 * restore ->work because we need to call io_req_work_drop_env.
                 */
index c3b11a715082914c2bfee7be0d27a507be967fdd..5cf91322de0fc57f895d857d2c37ec436b6b862d 100644 (file)
@@ -1312,6 +1312,7 @@ nfsd4_run_cb_work(struct work_struct *work)
                container_of(work, struct nfsd4_callback, cb_work);
        struct nfs4_client *clp = cb->cb_clp;
        struct rpc_clnt *clnt;
+       int flags;
 
        if (cb->cb_need_restart) {
                cb->cb_need_restart = false;
@@ -1340,7 +1341,8 @@ nfsd4_run_cb_work(struct work_struct *work)
        }
 
        cb->cb_msg.rpc_cred = clp->cl_cb_cred;
-       rpc_call_async(clnt, &cb->cb_msg, RPC_TASK_SOFT | RPC_TASK_SOFTCONN,
+       flags = clp->cl_minorversion ? RPC_TASK_NOCONNECT : RPC_TASK_SOFTCONN;
+       rpc_call_async(clnt, &cb->cb_msg, RPC_TASK_SOFT | flags,
                        cb->cb_ops ? &nfsd4_cb_ops : &nfsd4_cb_probe_ops, cb);
 }
 
index e32ecedece0feb808567c92c1137ddcb20537d85..c107caa5652544ebadfb746663a551b022c75eb6 100644 (file)
@@ -267,6 +267,8 @@ find_or_allocate_block(struct nfs4_lockowner *lo, struct knfsd_fh *fh,
        if (!nbl) {
                nbl= kmalloc(sizeof(*nbl), GFP_KERNEL);
                if (nbl) {
+                       INIT_LIST_HEAD(&nbl->nbl_list);
+                       INIT_LIST_HEAD(&nbl->nbl_lru);
                        fh_copy_shallow(&nbl->nbl_fh, fh);
                        locks_init_lock(&nbl->nbl_lock);
                        nfsd4_init_cb(&nbl->nbl_cb, lo->lo_owner.so_client,
index 8e4f1ace467c1a25db933e33bce9de47d6995a26..1de77f1a600b20eac9414fd2d4716396b97de101 100644 (file)
@@ -275,7 +275,6 @@ static ssize_t dlmfs_file_write(struct file *filp,
                                loff_t *ppos)
 {
        int bytes_left;
-       ssize_t writelen;
        char *lvb_buf;
        struct inode *inode = file_inode(filp);
 
@@ -285,32 +284,30 @@ static ssize_t dlmfs_file_write(struct file *filp,
        if (*ppos >= i_size_read(inode))
                return -ENOSPC;
 
+       /* don't write past the lvb */
+       if (count > i_size_read(inode) - *ppos)
+               count = i_size_read(inode) - *ppos;
+
        if (!count)
                return 0;
 
        if (!access_ok(buf, count))
                return -EFAULT;
 
-       /* don't write past the lvb */
-       if ((count + *ppos) > i_size_read(inode))
-               writelen = i_size_read(inode) - *ppos;
-       else
-               writelen = count - *ppos;
-
-       lvb_buf = kmalloc(writelen, GFP_NOFS);
+       lvb_buf = kmalloc(count, GFP_NOFS);
        if (!lvb_buf)
                return -ENOMEM;
 
-       bytes_left = copy_from_user(lvb_buf, buf, writelen);
-       writelen -= bytes_left;
-       if (writelen)
-               user_dlm_write_lvb(inode, lvb_buf, writelen);
+       bytes_left = copy_from_user(lvb_buf, buf, count);
+       count -= bytes_left;
+       if (count)
+               user_dlm_write_lvb(inode, lvb_buf, count);
 
        kfree(lvb_buf);
 
-       *ppos = *ppos + writelen;
-       mlog(0, "wrote %zd bytes\n", writelen);
-       return writelen;
+       *ppos = *ppos + count;
+       mlog(0, "wrote %zu bytes\n", count);
+       return count;
 }
 
 static void dlmfs_init_once(void *foo)
index 49f6d7ff21394f5e15e440ade00ba3363e27cf68..1106137c747a3aab8f8340751eb713d6d936797f 100644 (file)
@@ -261,14 +261,13 @@ static int propagate_one(struct mount *m)
        child = copy_tree(last_source, last_source->mnt.mnt_root, type);
        if (IS_ERR(child))
                return PTR_ERR(child);
+       read_seqlock_excl(&mount_lock);
        mnt_set_mountpoint(m, mp, child);
+       if (m->mnt_master != dest_master)
+               SET_MNT_MARK(m->mnt_master);
+       read_sequnlock_excl(&mount_lock);
        last_dest = m;
        last_source = child;
-       if (m->mnt_master != dest_master) {
-               read_seqlock_excl(&mount_lock);
-               SET_MNT_MARK(m->mnt_master);
-               read_sequnlock_excl(&mount_lock);
-       }
        hlist_add_head(&child->mnt_hash, list);
        return count_mounts(m->mnt_ns, child);
 }
index 572898dd16a00c4b38c5e02383c6505968a23d6a..eb2255e95f62b799cd51fe5adc8a5169157a12cc 100644 (file)
@@ -3286,7 +3286,6 @@ static const struct inode_operations proc_tgid_base_inode_operations = {
 void proc_flush_pid(struct pid *pid)
 {
        proc_invalidate_siblings_dcache(&pid->inodes, &pid->lock);
-       put_pid(pid);
 }
 
 static struct dentry *proc_pid_instantiate(struct dentry * dentry,
index 7dc800cce35430962d9cb12ac098801efe80ccdb..c663202da8de79d5e432321194a9551416ff66c1 100644 (file)
@@ -266,7 +266,8 @@ static int vmcoredd_mmap_dumps(struct vm_area_struct *vma, unsigned long dst,
                if (start < offset + dump->size) {
                        tsz = min(offset + (u64)dump->size - start, (u64)size);
                        buf = dump->buf + start - offset;
-                       if (remap_vmalloc_range_partial(vma, dst, buf, tsz)) {
+                       if (remap_vmalloc_range_partial(vma, dst, buf, 0,
+                                                       tsz)) {
                                ret = -EFAULT;
                                goto out_unlock;
                        }
@@ -624,7 +625,7 @@ static int mmap_vmcore(struct file *file, struct vm_area_struct *vma)
                tsz = min(elfcorebuf_sz + elfnotes_sz - (size_t)start, size);
                kaddr = elfnotes_buf + start - elfcorebuf_sz - vmcoredd_orig_sz;
                if (remap_vmalloc_range_partial(vma, vma->vm_start + len,
-                                               kaddr, tsz))
+                                               kaddr, 0, tsz))
                        goto fail;
 
                size -= tsz;
index cd352530eca906eb64d722592c85e2fa3ef02886..a288cd60d2aed3f58f442a2a768c8ac785c015ec 100644 (file)
@@ -1302,8 +1302,8 @@ int get_tree_bdev(struct fs_context *fc,
        mutex_lock(&bdev->bd_fsfreeze_mutex);
        if (bdev->bd_fsfreeze_count > 0) {
                mutex_unlock(&bdev->bd_fsfreeze_mutex);
-               blkdev_put(bdev, mode);
                warnf(fc, "%pg: Can't mount, blockdev is frozen", bdev);
+               blkdev_put(bdev, mode);
                return -EBUSY;
        }
 
index 36341dfded7096f6d2ad1ef2f1082ace267253be..44ec80e705183bbb85f1707fd25d9f8786b7122a 100644 (file)
@@ -56,6 +56,7 @@ mandatory-y += topology.h
 mandatory-y += trace_clock.h
 mandatory-y += uaccess.h
 mandatory-y += unaligned.h
+mandatory-y += vermagic.h
 mandatory-y += vga.h
 mandatory-y += word-at-a-time.h
 mandatory-y += xor.h
diff --git a/include/asm-generic/vermagic.h b/include/asm-generic/vermagic.h
new file mode 100644 (file)
index 0000000..084274a
--- /dev/null
@@ -0,0 +1,7 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+#ifndef _ASM_GENERIC_VERMAGIC_H
+#define _ASM_GENERIC_VERMAGIC_H
+
+#define MODULE_ARCH_VERMAGIC ""
+
+#endif /* _ASM_GENERIC_VERMAGIC_H */
index 4fc87dee005ab13e8208c5d19c92700384edffbd..ee577a83cfe67a8af1ed3ed83ffa7ae345eb3787 100644 (file)
@@ -54,7 +54,6 @@ enum wb_reason {
        WB_REASON_SYNC,
        WB_REASON_PERIODIC,
        WB_REASON_LAPTOP_TIMER,
-       WB_REASON_FREE_MORE_MEM,
        WB_REASON_FS_FREE_SPACE,
        /*
         * There is no bdi forker thread any more and works are done
index a274d95fa66e4c9e9ef3ea12b478ac940e48e1f5..63cb3606dea7fde966de75791bf2225c5dea8674 100644 (file)
@@ -103,8 +103,8 @@ void debugfs_create_u8(const char *name, umode_t mode, struct dentry *parent,
                       u8 *value);
 void debugfs_create_u16(const char *name, umode_t mode, struct dentry *parent,
                        u16 *value);
-struct dentry *debugfs_create_u32(const char *name, umode_t mode,
-                                 struct dentry *parent, u32 *value);
+void debugfs_create_u32(const char *name, umode_t mode, struct dentry *parent,
+                       u32 *value);
 void debugfs_create_u64(const char *name, umode_t mode, struct dentry *parent,
                        u64 *value);
 struct dentry *debugfs_create_ulong(const char *name, umode_t mode,
@@ -250,12 +250,8 @@ static inline void debugfs_create_u8(const char *name, umode_t mode,
 static inline void debugfs_create_u16(const char *name, umode_t mode,
                                      struct dentry *parent, u16 *value) { }
 
-static inline struct dentry *debugfs_create_u32(const char *name, umode_t mode,
-                                               struct dentry *parent,
-                                               u32 *value)
-{
-       return ERR_PTR(-ENODEV);
-}
+static inline void debugfs_create_u32(const char *name, umode_t mode,
+                                     struct dentry *parent, u32 *value) { }
 
 static inline void debugfs_create_u64(const char *name, umode_t mode,
                                      struct dentry *parent, u64 *value) { }
index 17f56a070b205a1ebab8cea9ef1ae2c8960238bc..25c87507a1fa79e946f51677d748820b025a99a9 100644 (file)
@@ -600,7 +600,7 @@ void iio_device_unregister(struct iio_dev *indio_dev);
  * 0 on success, negative error number on failure.
  */
 #define devm_iio_device_register(dev, indio_dev) \
-       __devm_iio_device_register((dev), (indio_dev), THIS_MODULE);
+       __devm_iio_device_register((dev), (indio_dev), THIS_MODULE)
 int __devm_iio_device_register(struct device *dev, struct iio_dev *indio_dev,
                               struct module *this_mod);
 void devm_iio_device_unregister(struct device *dev, struct iio_dev *indio_dev);
index 6d58beb65454f7d126c65630c7aef4183e3c76ad..01276e3d01b920702642d789a830cd5d441319cb 100644 (file)
@@ -1048,7 +1048,7 @@ search_memslots(struct kvm_memslots *slots, gfn_t gfn)
                        start = slot + 1;
        }
 
-       if (gfn >= memslots[start].base_gfn &&
+       if (start < slots->used_slots && gfn >= memslots[start].base_gfn &&
            gfn < memslots[start].base_gfn + memslots[start].npages) {
                atomic_set(&slots->lru_slot, start);
                return &memslots[start];
index b18dca67253d662b42a68d2d5cb336cd069f9352..c2a7cfbca7131f4be57971a464475fd5faf183c4 100644 (file)
@@ -220,10 +220,8 @@ struct pnp_card {
 #define global_to_pnp_card(n) list_entry(n, struct pnp_card, global_list)
 #define protocol_to_pnp_card(n) list_entry(n, struct pnp_card, protocol_list)
 #define to_pnp_card(n) container_of(n, struct pnp_card, dev)
-#define pnp_for_each_card(card) \
-       for((card) = global_to_pnp_card(pnp_cards.next); \
-       (card) != global_to_pnp_card(&pnp_cards); \
-       (card) = global_to_pnp_card((card)->global_list.next))
+#define pnp_for_each_card(card)        \
+       list_for_each_entry(card, &pnp_cards, global_list)
 
 struct pnp_card_link {
        struct pnp_card *card;
@@ -276,14 +274,9 @@ struct pnp_dev {
 #define card_to_pnp_dev(n) list_entry(n, struct pnp_dev, card_list)
 #define protocol_to_pnp_dev(n) list_entry(n, struct pnp_dev, protocol_list)
 #define        to_pnp_dev(n) container_of(n, struct pnp_dev, dev)
-#define pnp_for_each_dev(dev) \
-       for((dev) = global_to_pnp_dev(pnp_global.next); \
-       (dev) != global_to_pnp_dev(&pnp_global); \
-       (dev) = global_to_pnp_dev((dev)->global_list.next))
-#define card_for_each_dev(card,dev) \
-       for((dev) = card_to_pnp_dev((card)->devices.next); \
-       (dev) != card_to_pnp_dev(&(card)->devices); \
-       (dev) = card_to_pnp_dev((dev)->card_list.next))
+#define pnp_for_each_dev(dev) list_for_each_entry(dev, &pnp_global, global_list)
+#define card_for_each_dev(card, dev)   \
+       list_for_each_entry(dev, &(card)->devices, card_list)
 #define pnp_dev_name(dev) (dev)->name
 
 static inline void *pnp_get_drvdata(struct pnp_dev *pdev)
@@ -437,14 +430,10 @@ struct pnp_protocol {
 };
 
 #define to_pnp_protocol(n) list_entry(n, struct pnp_protocol, protocol_list)
-#define protocol_for_each_card(protocol,card) \
-       for((card) = protocol_to_pnp_card((protocol)->cards.next); \
-       (card) != protocol_to_pnp_card(&(protocol)->cards); \
-       (card) = protocol_to_pnp_card((card)->protocol_list.next))
-#define protocol_for_each_dev(protocol,dev) \
-       for((dev) = protocol_to_pnp_dev((protocol)->devices.next); \
-       (dev) != protocol_to_pnp_dev(&(protocol)->devices); \
-       (dev) = protocol_to_pnp_dev((dev)->protocol_list.next))
+#define protocol_for_each_card(protocol, card) \
+       list_for_each_entry(card, &(protocol)->cards, protocol_list)
+#define protocol_for_each_dev(protocol, dev)   \
+       list_for_each_entry(dev, &(protocol)->devices, protocol_list)
 
 extern struct bus_type pnp_bus_type;
 
index fbafb353e9be586c6b87ee39088fdb87ceba33c3..bd964c31d333551871af461a0082227008c31993 100644 (file)
@@ -177,6 +177,8 @@ struct plat_stmmacenet_data {
        struct stmmac_rxq_cfg rx_queues_cfg[MTL_MAX_RX_QUEUES];
        struct stmmac_txq_cfg tx_queues_cfg[MTL_MAX_TX_QUEUES];
        void (*fix_mac_speed)(void *priv, unsigned int speed);
+       int (*serdes_powerup)(struct net_device *ndev, void *priv);
+       void (*serdes_powerdown)(struct net_device *ndev, void *priv);
        int (*init)(struct platform_device *pdev, void *priv);
        void (*exit)(struct platform_device *pdev, void *priv);
        struct mac_device_info *(*setup)(void *priv);
index 78fe2ac6dc6c5d7b3c477b42cecf04920622425c..cbcfbd0521e374254e90fea0562e29c716e62727 100644 (file)
@@ -170,6 +170,7 @@ extern bool svc_rdma_post_recvs(struct svcxprt_rdma *rdma);
 extern void svc_rdma_recv_ctxt_put(struct svcxprt_rdma *rdma,
                                   struct svc_rdma_recv_ctxt *ctxt);
 extern void svc_rdma_flush_recv_queues(struct svcxprt_rdma *rdma);
+extern void svc_rdma_release_rqst(struct svc_rqst *rqstp);
 extern int svc_rdma_recvfrom(struct svc_rqst *);
 
 /* svc_rdma_rw.c */
index 1fb11daa5c5334c6ecbbd5a77a3c0a6c152e3f84..a1fecf31162174036352198afee3260cdbab3670 100644 (file)
@@ -156,8 +156,7 @@ static inline struct tracepoint *tracepoint_ptr_deref(tracepoint_ptr_t *p)
  * Note, the proto and args passed in includes "__data" as the first parameter.
  * The reason for this is to handle the "void" prototype. If a tracepoint
  * has a "void" prototype, then it is invalid to declare a function
- * as "(void *, void)". The DECLARE_TRACE_NOARGS() will pass in just
- * "void *data", where as the DECLARE_TRACE() will pass in "void *data, proto".
+ * as "(void *, void)".
  */
 #define __DO_TRACE(tp, proto, args, cond, rcuidle)                     \
        do {                                                            \
@@ -373,25 +372,6 @@ static inline struct tracepoint *tracepoint_ptr_deref(tracepoint_ptr_t *p)
 # define __tracepoint_string
 #endif
 
-/*
- * The need for the DECLARE_TRACE_NOARGS() is to handle the prototype
- * (void). "void" is a special value in a function prototype and can
- * not be combined with other arguments. Since the DECLARE_TRACE()
- * macro adds a data element at the beginning of the prototype,
- * we need a way to differentiate "(void *data, proto)" from
- * "(void *data, void)". The second prototype is invalid.
- *
- * DECLARE_TRACE_NOARGS() passes "void" as the tracepoint prototype
- * and "void *__data" as the callback prototype.
- *
- * DECLARE_TRACE() passes "proto" as the tracepoint protoype and
- * "void *__data, proto" as the callback prototype.
- */
-#define DECLARE_TRACE_NOARGS(name)                                     \
-       __DECLARE_TRACE(name, void, ,                                   \
-                       cpu_online(raw_smp_processor_id()),             \
-                       void *__data, __data)
-
 #define DECLARE_TRACE(name, proto, args)                               \
        __DECLARE_TRACE(name, PARAMS(proto), PARAMS(args),              \
                        cpu_online(raw_smp_processor_id()),             \
index 733acfb7ef84a8e39d75000e4a589d148d17b973..5453af87a33ee4588e287e03e3561638d03f8637 100644 (file)
@@ -164,7 +164,7 @@ struct vdpa_config_ops {
        u64 (*get_vq_state)(struct vdpa_device *vdev, u16 idx);
 
        /* Device ops */
-       u16 (*get_vq_align)(struct vdpa_device *vdev);
+       u32 (*get_vq_align)(struct vdpa_device *vdev);
        u64 (*get_features)(struct vdpa_device *vdev);
        int (*set_features)(struct vdpa_device *vdev, u64 features);
        void (*set_config_cb)(struct vdpa_device *vdev,
index 9aced11e90000c45926045e5e0c6ea2e2c35f36c..dc236577b92f0959a76a797cc3421be99925b391 100644 (file)
@@ -1,5 +1,9 @@
 /* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _LINUX_VERMAGIC_H
+#define _LINUX_VERMAGIC_H
+
 #include <generated/utsrelease.h>
+#include <asm/vermagic.h>
 
 /* Simply sanity version stamp for modules. */
 #ifdef CONFIG_SMP
@@ -24,9 +28,6 @@
 #else
 #define MODULE_VERMAGIC_MODVERSIONS ""
 #endif
-#ifndef MODULE_ARCH_VERMAGIC
-#define MODULE_ARCH_VERMAGIC ""
-#endif
 #ifdef RANDSTRUCT_PLUGIN
 #include <generated/randomize_layout_hash.h>
 #define MODULE_RANDSTRUCT_PLUGIN "RANDSTRUCT_PLUGIN_" RANDSTRUCT_HASHED_SEED
@@ -41,3 +42,4 @@
        MODULE_ARCH_VERMAGIC                                            \
        MODULE_RANDSTRUCT_PLUGIN
 
+#endif /* _LINUX_VERMAGIC_H */
index 15f906e4a748f7495c36ef1ee189bd1c883c9e39..a493eac083933ff5f2b0a152f6439182646b9c00 100644 (file)
@@ -9,7 +9,6 @@
 #include <linux/device.h>
 #include <linux/mod_devicetable.h>
 #include <linux/gfp.h>
-#include <linux/vringh.h>
 
 /**
  * virtqueue - a queue to register buffers for sending or receiving.
index 0507a162ccd0e7ba4edf007654084effe3b5579a..a95d3cc74d79ba468a06502f8cb8acf808ab55a1 100644 (file)
@@ -137,7 +137,7 @@ extern void vunmap(const void *addr);
 
 extern int remap_vmalloc_range_partial(struct vm_area_struct *vma,
                                       unsigned long uaddr, void *kaddr,
-                                      unsigned long size);
+                                      unsigned long pgoff, unsigned long size);
 
 extern int remap_vmalloc_range(struct vm_area_struct *vma, void *addr,
                                                        unsigned long pgoff);
index bd0503ca6f8fc509aa7cc02e110e561b885b07be..9e2763d7c15912e0a77f7ca2e90e2ae836347c08 100644 (file)
 #include <linux/virtio_byteorder.h>
 #include <linux/uio.h>
 #include <linux/slab.h>
+#if IS_REACHABLE(CONFIG_VHOST_IOTLB)
 #include <linux/dma-direction.h>
 #include <linux/vhost_iotlb.h>
+#endif
 #include <asm/barrier.h>
 
 /* virtio_ring with information needed for host access. */
@@ -254,6 +256,8 @@ static inline __virtio64 cpu_to_vringh64(const struct vringh *vrh, u64 val)
        return __cpu_to_virtio64(vringh_is_little_endian(vrh), val);
 }
 
+#if IS_REACHABLE(CONFIG_VHOST_IOTLB)
+
 void vringh_set_iotlb(struct vringh *vrh, struct vhost_iotlb *iotlb);
 
 int vringh_init_iotlb(struct vringh *vrh, u64 features,
@@ -284,4 +288,6 @@ void vringh_notify_disable_iotlb(struct vringh *vrh);
 
 int vringh_need_notify_iotlb(struct vringh *vrh);
 
+#endif /* CONFIG_VHOST_IOTLB */
+
 #endif /* _LINUX_VRINGH_H */
index b6b4de0e4b5ede87ae1ac8c85be5dc034312ac04..97fec4d310acfd82e0bbf91b66ea11b9a5d1d4ac 100644 (file)
@@ -6007,7 +6007,9 @@ enum rate_control_capabilities {
 struct rate_control_ops {
        unsigned long capa;
        const char *name;
-       void *(*alloc)(struct ieee80211_hw *hw, struct dentry *debugfsdir);
+       void *(*alloc)(struct ieee80211_hw *hw);
+       void (*add_debugfs)(struct ieee80211_hw *hw, void *priv,
+                           struct dentry *debugfsdir);
        void (*free)(void *priv);
 
        void *(*alloc_sta)(void *priv, struct ieee80211_sta *sta, gfp_t gfp);
index 7d107113f988a6a169b06ee2622d89bdacf2580a..9205a76d967a03e4162bad03f2f4e53d6e976506 100644 (file)
@@ -41,7 +41,7 @@ enum {
        ND_OPT_DNSSL = 31,              /* RFC6106 */
        ND_OPT_6CO = 34,                /* RFC6775 */
        ND_OPT_CAPTIVE_PORTAL = 37,     /* RFC7710 */
-       ND_OPT_PREF64 = 38,             /* RFC-ietf-6man-ra-pref64-09 */
+       ND_OPT_PREF64 = 38,             /* RFC8781 */
        __ND_OPT_MAX
 };
 
index 5fa9eacd965a4abd6a4dd5262fa0d439aa9fe64e..dcf9a72eeaa6912202e8a1ca6cf800f7401bf517 100644 (file)
@@ -51,7 +51,7 @@ extern struct inet_hashinfo tcp_hashinfo;
 extern struct percpu_counter tcp_orphan_count;
 void tcp_time_wait(struct sock *sk, int state, int timeo);
 
-#define MAX_TCP_HEADER (128 + MAX_HEADER)
+#define MAX_TCP_HEADER L1_CACHE_ALIGN(128 + MAX_HEADER)
 #define MAX_TCP_OPTION_SPACE 40
 #define TCP_MIN_SND_MSS                48
 #define TCP_MIN_GSO_SIZE       (TCP_MIN_SND_MSS - MAX_TCP_OPTION_SPACE)
index 0dd52b0a5c1bf3ebe9364ecc4670e5a6ad212d7b..361cb64246f74087165f16493e942eaf690671c9 100644 (file)
@@ -168,7 +168,6 @@ int tegra_io_pad_power_disable(enum tegra_io_pad id);
 int tegra_io_rail_power_on(unsigned int id);
 int tegra_io_rail_power_off(unsigned int id);
 
-enum tegra_suspend_mode tegra_pmc_get_suspend_mode(void);
 void tegra_pmc_set_suspend_mode(enum tegra_suspend_mode mode);
 void tegra_pmc_enter_suspend_mode(enum tegra_suspend_mode mode);
 
@@ -220,11 +219,6 @@ static inline int tegra_io_rail_power_off(unsigned int id)
        return -ENOSYS;
 }
 
-static inline enum tegra_suspend_mode tegra_pmc_get_suspend_mode(void)
-{
-       return TEGRA_SUSPEND_NONE;
-}
-
 static inline void tegra_pmc_set_suspend_mode(enum tegra_suspend_mode mode)
 {
 }
@@ -235,4 +229,13 @@ static inline void tegra_pmc_enter_suspend_mode(enum tegra_suspend_mode mode)
 
 #endif /* CONFIG_SOC_TEGRA_PMC */
 
+#if defined(CONFIG_SOC_TEGRA_PMC) && defined(CONFIG_PM_SLEEP)
+enum tegra_suspend_mode tegra_pmc_get_suspend_mode(void);
+#else
+static inline enum tegra_suspend_mode tegra_pmc_get_suspend_mode(void)
+{
+       return TEGRA_SUSPEND_NONE;
+}
+#endif
+
 #endif /* __SOC_TEGRA_PMC_H__ */
index d4825b82c7a3b08f5e880501a1a771d2406ca7f5..b33abe93b905953f5d0faa7bebb678bd4d36c587 100644 (file)
@@ -351,7 +351,6 @@ struct snd_soc_dai {
 
        /* bit field */
        unsigned int probed:1;
-       unsigned int started[SNDRV_PCM_STREAM_LAST + 1];
 };
 
 static inline struct snd_soc_pcm_stream *
index 13458e4fbb132ed3a0fef16af7cd6317973e54fa..946f88a6c63d119ff71e5916615320d8dac2b273 100644 (file)
@@ -790,6 +790,9 @@ struct snd_soc_dai_link {
        const struct snd_soc_pcm_stream *params;
        unsigned int num_params;
 
+       struct snd_soc_dapm_widget *playback_widget;
+       struct snd_soc_dapm_widget *capture_widget;
+
        unsigned int dai_fmt;           /* format to set on init */
 
        enum snd_soc_dpcm_trigger trigger[2]; /* trigger type for DPCM */
index 7ecaa65b7106eb67a4400d16fd86f5cc620d7a8c..c2f580fd371b11e117be68238c8530bd88a84d1f 100644 (file)
@@ -130,7 +130,7 @@ DEFINE_EVENT(iocg_inuse_update, iocost_inuse_reset,
 
 TRACE_EVENT(iocost_ioc_vrate_adj,
 
-       TP_PROTO(struct ioc *ioc, u64 new_vrate, u32 (*missed_ppm)[2],
+       TP_PROTO(struct ioc *ioc, u64 new_vrate, u32 *missed_ppm,
                u32 rq_wait_pct, int nr_lagging, int nr_shortages,
                int nr_surpluses),
 
@@ -155,8 +155,8 @@ TRACE_EVENT(iocost_ioc_vrate_adj,
                __entry->old_vrate = atomic64_read(&ioc->vtime_rate);;
                __entry->new_vrate = new_vrate;
                __entry->busy_level = ioc->busy_level;
-               __entry->read_missed_ppm = (*missed_ppm)[READ];
-               __entry->write_missed_ppm = (*missed_ppm)[WRITE];
+               __entry->read_missed_ppm = missed_ppm[READ];
+               __entry->write_missed_ppm = missed_ppm[WRITE];
                __entry->rq_wait_pct = rq_wait_pct;
                __entry->nr_lagging = nr_lagging;
                __entry->nr_shortages = nr_shortages;
index 051f26fedc4db847214028eed03d54759f1e1413..596e0a8034772b5bbdd29288c6f04544b2b4ad6b 100644 (file)
@@ -1695,17 +1695,15 @@ DECLARE_EVENT_CLASS(svcrdma_sendcomp_event,
 
 TRACE_EVENT(svcrdma_post_send,
        TP_PROTO(
-               const struct ib_send_wr *wr,
-               int status
+               const struct ib_send_wr *wr
        ),
 
-       TP_ARGS(wr, status),
+       TP_ARGS(wr),
 
        TP_STRUCT__entry(
                __field(const void *, cqe)
                __field(unsigned int, num_sge)
                __field(u32, inv_rkey)
-               __field(int, status)
        ),
 
        TP_fast_assign(
@@ -1713,12 +1711,11 @@ TRACE_EVENT(svcrdma_post_send,
                __entry->num_sge = wr->num_sge;
                __entry->inv_rkey = (wr->opcode == IB_WR_SEND_WITH_INV) ?
                                        wr->ex.invalidate_rkey : 0;
-               __entry->status = status;
        ),
 
-       TP_printk("cqe=%p num_sge=%u inv_rkey=0x%08x status=%d",
+       TP_printk("cqe=%p num_sge=%u inv_rkey=0x%08x",
                __entry->cqe, __entry->num_sge,
-               __entry->inv_rkey, __entry->status
+               __entry->inv_rkey
        )
 );
 
@@ -1783,26 +1780,23 @@ TRACE_EVENT(svcrdma_wc_receive,
 TRACE_EVENT(svcrdma_post_rw,
        TP_PROTO(
                const void *cqe,
-               int sqecount,
-               int status
+               int sqecount
        ),
 
-       TP_ARGS(cqe, sqecount, status),
+       TP_ARGS(cqe, sqecount),
 
        TP_STRUCT__entry(
                __field(const void *, cqe)
                __field(int, sqecount)
-               __field(int, status)
        ),
 
        TP_fast_assign(
                __entry->cqe = cqe;
                __entry->sqecount = sqecount;
-               __entry->status = status;
        ),
 
-       TP_printk("cqe=%p sqecount=%d status=%d",
-               __entry->cqe, __entry->sqecount, __entry->status
+       TP_printk("cqe=%p sqecount=%d",
+               __entry->cqe, __entry->sqecount
        )
 );
 
@@ -1870,6 +1864,34 @@ DECLARE_EVENT_CLASS(svcrdma_sendqueue_event,
 DEFINE_SQ_EVENT(full);
 DEFINE_SQ_EVENT(retry);
 
+TRACE_EVENT(svcrdma_sq_post_err,
+       TP_PROTO(
+               const struct svcxprt_rdma *rdma,
+               int status
+       ),
+
+       TP_ARGS(rdma, status),
+
+       TP_STRUCT__entry(
+               __field(int, avail)
+               __field(int, depth)
+               __field(int, status)
+               __string(addr, rdma->sc_xprt.xpt_remotebuf)
+       ),
+
+       TP_fast_assign(
+               __entry->avail = atomic_read(&rdma->sc_sq_avail);
+               __entry->depth = rdma->sc_sq_depth;
+               __entry->status = status;
+               __assign_str(addr, rdma->sc_xprt.xpt_remotebuf);
+       ),
+
+       TP_printk("addr=%s sc_sq_avail=%d/%d status=%d",
+               __get_str(addr), __entry->avail, __entry->depth,
+               __entry->status
+       )
+);
+
 #endif /* _TRACE_RPCRDMA_H */
 
 #include <trace/define_trace.h>
index d94def25e4dc94098648cf9a2568f75f0e2865b3..85a33bea76f1a776584ca36927e2481d88052daa 100644 (file)
@@ -36,7 +36,6 @@
        EM( WB_REASON_SYNC,                     "sync")                 \
        EM( WB_REASON_PERIODIC,                 "periodic")             \
        EM( WB_REASON_LAPTOP_TIMER,             "laptop_timer")         \
-       EM( WB_REASON_FREE_MORE_MEM,            "free_more_memory")     \
        EM( WB_REASON_FS_FREE_SPACE,            "fs_free_space")        \
        EMe(WB_REASON_FORKER_THREAD,            "forker_thread")
 
index 2e29a671d67eb96a3139c893158aa0fc69466213..7bbf1b65be10bf26c5a9309dbeddc34de8072272 100644 (file)
@@ -1642,7 +1642,7 @@ union bpf_attr {
  *             ifindex, but doesn't require a map to do so.
  *     Return
  *             **XDP_REDIRECT** on success, or the value of the two lower bits
- *             of the **flags* argument on error.
+ *             of the *flags* argument on error.
  *
  * int bpf_sk_redirect_map(struct sk_buff *skb, struct bpf_map *map, u32 key, u64 flags)
  *     Description
index 991b2b7ada7a3cd88b4b44723e0b5757e4f3c4eb..8f24404ad04f14516af24523f32b9d07b5346c98 100644 (file)
@@ -119,8 +119,8 @@ enum hv_fcopy_op {
 
 struct hv_fcopy_hdr {
        __u32 operation;
-       uuid_le service_id0; /* currently unused */
-       uuid_le service_id1; /* currently unused */
+       __u8 service_id0[16]; /* currently unused */
+       __u8 service_id1[16]; /* currently unused */
 } __attribute__((packed));
 
 #define OVER_WRITE     0x1
index 19974392d3240fad6265dd7a7a6e045636268b17..dc3e656470dd589102771c2046c8de42fe5d670d 100644 (file)
@@ -48,8 +48,15 @@ struct virtio_balloon_config {
        __u32 num_pages;
        /* Number of pages we've actually got in balloon. */
        __u32 actual;
-       /* Free page report command id, readonly by guest */
-       __u32 free_page_report_cmd_id;
+       /*
+        * Free page hint command id, readonly by guest.
+        * Was previously named free_page_report_cmd_id so we
+        * need to carry that name for legacy support.
+        */
+       union {
+               __u32 free_page_hint_cmd_id;
+               __u32 free_page_report_cmd_id;  /* deprecated */
+       };
        /* Stores PAGE_POISON if page poisoning is in use */
        __u32 poison_val;
 };
index 5cbc9fcbfd45c1d03464acee3cf706a7f9ec528d..7955c56d6b3c331abf9652a0796f9ca39e984d8e 100644 (file)
@@ -73,8 +73,8 @@ struct vdso_timestamp {
  *
  * @offset is used by the special time namespace VVAR pages which are
  * installed instead of the real VVAR page. These namespace pages must set
- * @seq to 1 and @clock_mode to VLOCK_TIMENS to force the code into the
- * time namespace slow path. The namespace aware functions retrieve the
+ * @seq to 1 and @clock_mode to VDSO_CLOCKMODE_TIMENS to force the code into
+ * the time namespace slow path. The namespace aware functions retrieve the
  * real system wide VVAR page, read host time and add the per clock offset.
  * For clocks which are not affected by time namespace adjustment the
  * offset must be zero.
index b69c8b460341f5698ec518d8539df7f0904d22c6..87f31bf1f0a0c80304a6ff82cc4207aee1194ca7 100644 (file)
@@ -1326,6 +1326,9 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
        case AUDIT_FIRST_USER_MSG2 ... AUDIT_LAST_USER_MSG2:
                if (!audit_enabled && msg_type != AUDIT_USER_AVC)
                        return 0;
+               /* exit early if there isn't at least one character to print */
+               if (data_len < 2)
+                       return -EINVAL;
 
                err = audit_filter(msg_type, AUDIT_FILTER_USER);
                if (err == 1) { /* match or error */
index 70f71b154fa578e1d5d1ae7a4065af0223f64113..3fe0b006d2d2ef93887c34153940f27ad014b374 100644 (file)
@@ -469,7 +469,7 @@ static int cpu_map_update_elem(struct bpf_map *map, void *key, void *value,
                return -EOVERFLOW;
 
        /* Make sure CPU is a valid possible cpu */
-       if (!cpu_possible(key_cpu))
+       if (key_cpu >= nr_cpumask_bits || !cpu_possible(key_cpu))
                return -ENODEV;
 
        if (qsize == 0) {
index d85f372395407df1d02ab0fe5bbd7009a2289647..7626b802447128f4fc5ec789e24d9bb6d8e96a27 100644 (file)
@@ -2283,7 +2283,7 @@ static void bpf_link_show_fdinfo(struct seq_file *m, struct file *filp)
 }
 #endif
 
-const struct file_operations bpf_link_fops = {
+static const struct file_operations bpf_link_fops = {
 #ifdef CONFIG_PROC_FS
        .show_fdinfo    = bpf_link_show_fdinfo,
 #endif
@@ -3628,8 +3628,10 @@ static int link_update(union bpf_attr *attr)
                return PTR_ERR(link);
 
        new_prog = bpf_prog_get(attr->link_update.new_prog_fd);
-       if (IS_ERR(new_prog))
-               return PTR_ERR(new_prog);
+       if (IS_ERR(new_prog)) {
+               ret = PTR_ERR(new_prog);
+               goto out_put_link;
+       }
 
        if (flags & BPF_F_REPLACE) {
                old_prog = bpf_prog_get(attr->link_update.old_prog_fd);
@@ -3638,6 +3640,9 @@ static int link_update(union bpf_attr *attr)
                        old_prog = NULL;
                        goto out_put_progs;
                }
+       } else if (attr->link_update.old_prog_fd) {
+               ret = -EINVAL;
+               goto out_put_progs;
        }
 
 #ifdef CONFIG_CGROUP_BPF
@@ -3653,6 +3658,8 @@ out_put_progs:
                bpf_prog_put(old_prog);
        if (ret)
                bpf_prog_put(new_prog);
+out_put_link:
+       bpf_link_put(link);
        return ret;
 }
 
index 38cfcf701eeb7d9ec19349167800ad653cd087db..fa1d8245b9257fe6f0f40dfca35702ebe7662000 100644 (file)
@@ -2118,6 +2118,15 @@ static bool register_is_const(struct bpf_reg_state *reg)
        return reg->type == SCALAR_VALUE && tnum_is_const(reg->var_off);
 }
 
+static bool __is_pointer_value(bool allow_ptr_leaks,
+                              const struct bpf_reg_state *reg)
+{
+       if (allow_ptr_leaks)
+               return false;
+
+       return reg->type != SCALAR_VALUE;
+}
+
 static void save_register_state(struct bpf_func_state *state,
                                int spi, struct bpf_reg_state *reg)
 {
@@ -2308,6 +2317,16 @@ static int check_stack_read(struct bpf_verifier_env *env,
                         * which resets stack/reg liveness for state transitions
                         */
                        state->regs[value_regno].live |= REG_LIVE_WRITTEN;
+               } else if (__is_pointer_value(env->allow_ptr_leaks, reg)) {
+                       /* If value_regno==-1, the caller is asking us whether
+                        * it is acceptable to use this value as a SCALAR_VALUE
+                        * (e.g. for XADD).
+                        * We must not allow unprivileged callers to do that
+                        * with spilled pointers.
+                        */
+                       verbose(env, "leaking pointer from stack off %d\n",
+                               off);
+                       return -EACCES;
                }
                mark_reg_read(env, reg, reg->parent, REG_LIVE_READ64);
        } else {
@@ -2673,15 +2692,6 @@ static int check_sock_access(struct bpf_verifier_env *env, int insn_idx,
        return -EACCES;
 }
 
-static bool __is_pointer_value(bool allow_ptr_leaks,
-                              const struct bpf_reg_state *reg)
-{
-       if (allow_ptr_leaks)
-               return false;
-
-       return reg->type != SCALAR_VALUE;
-}
-
 static struct bpf_reg_state *reg_state(struct bpf_verifier_env *env, int regno)
 {
        return cur_regs(env) + regno;
@@ -3089,7 +3099,7 @@ static int check_ptr_to_btf_access(struct bpf_verifier_env *env,
        if (ret < 0)
                return ret;
 
-       if (atype == BPF_READ) {
+       if (atype == BPF_READ && value_regno >= 0) {
                if (ret == SCALAR_VALUE) {
                        mark_reg_unknown(env, regs, value_regno);
                        return 0;
@@ -10487,6 +10497,7 @@ static int check_attach_btf_id(struct bpf_verifier_env *env)
                                return -EINVAL;
                        }
                        env->ops = bpf_verifier_ops[tgt_prog->type];
+                       prog->expected_attach_type = tgt_prog->expected_attach_type;
                }
                if (!tgt_prog->jited) {
                        verbose(env, "Can attach to only JITed progs\n");
@@ -10831,6 +10842,13 @@ err_release_maps:
                 * them now. Otherwise free_used_maps() will release them.
                 */
                release_maps(env);
+
+       /* extension progs temporarily inherit the attach_type of their targets
+          for verification purposes, so set it back to zero before returning
+        */
+       if (env->prog->type == BPF_PROG_TYPE_EXT)
+               env->prog->expected_attach_type = 0;
+
        *prog = env->prog;
 err_unlock:
        if (!is_priv)
index bc9b98a9af9ac18b84b157612e3f73c067097d94..633b4ae72ed598449f3ba2bb0da24eb92e86b17e 100644 (file)
@@ -7491,10 +7491,17 @@ static void perf_event_task_output(struct perf_event *event,
                goto out;
 
        task_event->event_id.pid = perf_event_pid(event, task);
-       task_event->event_id.ppid = perf_event_pid(event, current);
-
        task_event->event_id.tid = perf_event_tid(event, task);
-       task_event->event_id.ptid = perf_event_tid(event, current);
+
+       if (task_event->event_id.header.type == PERF_RECORD_EXIT) {
+               task_event->event_id.ppid = perf_event_pid(event,
+                                                       task->real_parent);
+               task_event->event_id.ptid = perf_event_pid(event,
+                                                       task->real_parent);
+       } else {  /* PERF_RECORD_FORK */
+               task_event->event_id.ppid = perf_event_pid(event, current);
+               task_event->event_id.ptid = perf_event_tid(event, current);
+       }
 
        task_event->event_id.time = perf_event_clock(event);
 
index 389a88cb308192babd68abfb4f2022803c3346c1..ce2a75bc0adeb2bc7edd19e4df6680b272f62d99 100644 (file)
@@ -219,6 +219,7 @@ repeat:
 
        write_unlock_irq(&tasklist_lock);
        proc_flush_pid(thread_pid);
+       put_pid(thread_pid);
        release_thread(p);
        put_task_struct_rcu_user(p);
 
index 3a61a3b8eaa9e137d29106dd6ab0fffbbd826f02..9a2fbf98fd6fa2ea3c420d02ac4cb20d2ba73958 100644 (file)
@@ -1232,13 +1232,8 @@ static void uclamp_fork(struct task_struct *p)
                return;
 
        for_each_clamp_id(clamp_id) {
-               unsigned int clamp_value = uclamp_none(clamp_id);
-
-               /* By default, RT tasks always get 100% boost */
-               if (unlikely(rt_task(p) && clamp_id == UCLAMP_MIN))
-                       clamp_value = uclamp_none(UCLAMP_MAX);
-
-               uclamp_se_set(&p->uclamp_req[clamp_id], clamp_value, false);
+               uclamp_se_set(&p->uclamp_req[clamp_id],
+                             uclamp_none(clamp_id), false);
        }
 }
 
index 71310488441437f03f01859c930ee0187a1655bc..284fc1600063bd082c897c125ef4cc20c0612e39 100644 (file)
@@ -1989,8 +1989,12 @@ bool do_notify_parent(struct task_struct *tsk, int sig)
                if (psig->action[SIGCHLD-1].sa.sa_handler == SIG_IGN)
                        sig = 0;
        }
+       /*
+        * Send with __send_signal as si_pid and si_uid are in the
+        * parent's namespaces.
+        */
        if (valid_signal(sig) && sig)
-               __group_send_sig_info(sig, &info, tsk->parent);
+               __send_signal(sig, &info, tsk->parent, PIDTYPE_TGID, false);
        __wake_up_parent(tsk, tsk->parent);
        spin_unlock_irqrestore(&psig->siglock, flags);
 
index 041694a1eb74d88d8b0fb44d26f13d06a7a29d82..bd030b1b9514857cce1e0b38f0f9e2bcce7fa78f 100644 (file)
@@ -5165,6 +5165,7 @@ int unregister_ftrace_direct(unsigned long ip, unsigned long addr)
                        list_del_rcu(&direct->next);
                        synchronize_rcu_tasks();
                        kfree(direct);
+                       kfree(entry);
                        ftrace_direct_func_count--;
                }
        }
index 5f6834a2bf4119ef4a30879cac479e0cbc0e5bdf..fcab11cc6833b2ccb74a169ee184584de64f5205 100644 (file)
@@ -3320,6 +3320,9 @@ static void __destroy_hist_field(struct hist_field *hist_field)
        kfree(hist_field->name);
        kfree(hist_field->type);
 
+       kfree(hist_field->system);
+       kfree(hist_field->event_name);
+
        kfree(hist_field);
 }
 
@@ -4382,6 +4385,7 @@ static struct hist_field *create_var(struct hist_trigger_data *hist_data,
                goto out;
        }
 
+       var->ref = 1;
        var->flags = HIST_FIELD_FL_VAR;
        var->var.idx = idx;
        var->var.hist_data = var->hist_data = hist_data;
@@ -5011,6 +5015,9 @@ static void destroy_field_vars(struct hist_trigger_data *hist_data)
 
        for (i = 0; i < hist_data->n_field_vars; i++)
                destroy_field_var(hist_data->field_vars[i]);
+
+       for (i = 0; i < hist_data->n_save_vars; i++)
+               destroy_field_var(hist_data->save_vars[i]);
 }
 
 static void save_field_var(struct hist_trigger_data *hist_data,
index 9e31bfc818ff821dae0f82e4f5c1048a149a9f20..74738c9856f164af0f7ed08cbaaf4d9b4041aff0 100644 (file)
@@ -283,7 +283,7 @@ int tracing_map_add_key_field(struct tracing_map *map,
        return idx;
 }
 
-void tracing_map_array_clear(struct tracing_map_array *a)
+static void tracing_map_array_clear(struct tracing_map_array *a)
 {
        unsigned int i;
 
@@ -294,7 +294,7 @@ void tracing_map_array_clear(struct tracing_map_array *a)
                memset(a->pages[i], 0, PAGE_SIZE);
 }
 
-void tracing_map_array_free(struct tracing_map_array *a)
+static void tracing_map_array_free(struct tracing_map_array *a)
 {
        unsigned int i;
 
@@ -316,7 +316,7 @@ void tracing_map_array_free(struct tracing_map_array *a)
        kfree(a);
 }
 
-struct tracing_map_array *tracing_map_array_alloc(unsigned int n_elts,
+static struct tracing_map_array *tracing_map_array_alloc(unsigned int n_elts,
                                                  unsigned int entry_size)
 {
        struct tracing_map_array *a;
index 2dceaca27489c0666abf928b4f829bfbd38fc9fa..891e1c3549c465a6d18e86e79437b5bdb3aca824 100644 (file)
@@ -722,22 +722,22 @@ do {                                                                      \
 do { \
        if (__builtin_constant_p(bh) && (bh) == 0) \
                __asm__ ("{a%I4|add%I4c} %1,%3,%4\n\t{aze|addze} %0,%2" \
-               : "=r" ((USItype)(sh)), \
-               "=&r" ((USItype)(sl)) \
+               : "=r" (sh), \
+               "=&r" (sl) \
                : "%r" ((USItype)(ah)), \
                "%r" ((USItype)(al)), \
                "rI" ((USItype)(bl))); \
        else if (__builtin_constant_p(bh) && (bh) == ~(USItype) 0) \
                __asm__ ("{a%I4|add%I4c} %1,%3,%4\n\t{ame|addme} %0,%2" \
-               : "=r" ((USItype)(sh)), \
-               "=&r" ((USItype)(sl)) \
+               : "=r" (sh), \
+               "=&r" (sl) \
                : "%r" ((USItype)(ah)), \
                "%r" ((USItype)(al)), \
                "rI" ((USItype)(bl))); \
        else \
                __asm__ ("{a%I5|add%I5c} %1,%4,%5\n\t{ae|adde} %0,%2,%3" \
-               : "=r" ((USItype)(sh)), \
-               "=&r" ((USItype)(sl)) \
+               : "=r" (sh), \
+               "=&r" (sl) \
                : "%r" ((USItype)(ah)), \
                "r" ((USItype)(bh)), \
                "%r" ((USItype)(al)), \
@@ -747,36 +747,36 @@ do { \
 do { \
        if (__builtin_constant_p(ah) && (ah) == 0) \
                __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{sfze|subfze} %0,%2" \
-               : "=r" ((USItype)(sh)), \
-               "=&r" ((USItype)(sl)) \
+               : "=r" (sh), \
+               "=&r" (sl) \
                : "r" ((USItype)(bh)), \
                "rI" ((USItype)(al)), \
                "r" ((USItype)(bl))); \
        else if (__builtin_constant_p(ah) && (ah) == ~(USItype) 0) \
                __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{sfme|subfme} %0,%2" \
-               : "=r" ((USItype)(sh)), \
-               "=&r" ((USItype)(sl)) \
+               : "=r" (sh), \
+               "=&r" (sl) \
                : "r" ((USItype)(bh)), \
                "rI" ((USItype)(al)), \
                "r" ((USItype)(bl))); \
        else if (__builtin_constant_p(bh) && (bh) == 0) \
                __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{ame|addme} %0,%2" \
-               : "=r" ((USItype)(sh)), \
-               "=&r" ((USItype)(sl)) \
+               : "=r" (sh), \
+               "=&r" (sl) \
                : "r" ((USItype)(ah)), \
                "rI" ((USItype)(al)), \
                "r" ((USItype)(bl))); \
        else if (__builtin_constant_p(bh) && (bh) == ~(USItype) 0) \
                __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{aze|addze} %0,%2" \
-               : "=r" ((USItype)(sh)), \
-               "=&r" ((USItype)(sl)) \
+               : "=r" (sh), \
+               "=&r" (sl) \
                : "r" ((USItype)(ah)), \
                "rI" ((USItype)(al)), \
                "r" ((USItype)(bl))); \
        else \
                __asm__ ("{sf%I4|subf%I4c} %1,%5,%4\n\t{sfe|subfe} %0,%3,%2" \
-               : "=r" ((USItype)(sh)), \
-               "=&r" ((USItype)(sl)) \
+               : "=r" (sh), \
+               "=&r" (sl) \
                : "r" ((USItype)(ah)), \
                "r" ((USItype)(bh)), \
                "rI" ((USItype)(al)), \
@@ -787,7 +787,7 @@ do { \
 do { \
        USItype __m0 = (m0), __m1 = (m1); \
        __asm__ ("mulhwu %0,%1,%2" \
-       : "=r" ((USItype) ph) \
+       : "=r" (ph) \
        : "%r" (__m0), \
        "r" (__m1)); \
        (pl) = __m0 * __m1; \
index 6076df8e04a4e74dbb1405aa0e28ec9c72b59c4b..50681f0286ded05c26c0dc98660e4df5cd1ebecc 100644 (file)
--- a/mm/gup.c
+++ b/mm/gup.c
@@ -1088,7 +1088,7 @@ retry:
                 * potentially allocating memory.
                 */
                if (fatal_signal_pending(current)) {
-                       ret = -ERESTARTSYS;
+                       ret = -EINTR;
                        goto out;
                }
                cond_resched();
index cd459155d28a7ac1b8a7517ffd53c1992a329f68..bcabbe02192b1c8471b789adb77f333babc85110 100644 (file)
@@ -5365,8 +5365,8 @@ pte_t *huge_pte_offset(struct mm_struct *mm,
 {
        pgd_t *pgd;
        p4d_t *p4d;
-       pud_t *pud;
-       pmd_t *pmd;
+       pud_t *pud, pud_entry;
+       pmd_t *pmd, pmd_entry;
 
        pgd = pgd_offset(mm, addr);
        if (!pgd_present(*pgd))
@@ -5376,17 +5376,19 @@ pte_t *huge_pte_offset(struct mm_struct *mm,
                return NULL;
 
        pud = pud_offset(p4d, addr);
-       if (sz != PUD_SIZE && pud_none(*pud))
+       pud_entry = READ_ONCE(*pud);
+       if (sz != PUD_SIZE && pud_none(pud_entry))
                return NULL;
        /* hugepage or swap? */
-       if (pud_huge(*pud) || !pud_present(*pud))
+       if (pud_huge(pud_entry) || !pud_present(pud_entry))
                return (pte_t *)pud;
 
        pmd = pmd_offset(pud, addr);
-       if (sz != PMD_SIZE && pmd_none(*pmd))
+       pmd_entry = READ_ONCE(*pmd);
+       if (sz != PMD_SIZE && pmd_none(pmd_entry))
                return NULL;
        /* hugepage or swap? */
-       if (pmd_huge(*pmd) || !pmd_present(*pmd))
+       if (pmd_huge(pmd_entry) || !pmd_present(pmd_entry))
                return (pte_t *)pmd;
 
        return NULL;
index a558da9e717709e60cb31ab62a2ce9deebcb095c..281c00129a2ea7487b87d5e2642b8fdc4b82c929 100644 (file)
--- a/mm/ksm.c
+++ b/mm/ksm.c
@@ -2112,8 +2112,16 @@ static void cmp_and_merge_page(struct page *page, struct rmap_item *rmap_item)
 
                down_read(&mm->mmap_sem);
                vma = find_mergeable_vma(mm, rmap_item->address);
-               err = try_to_merge_one_page(vma, page,
-                                           ZERO_PAGE(rmap_item->address));
+               if (vma) {
+                       err = try_to_merge_one_page(vma, page,
+                                       ZERO_PAGE(rmap_item->address));
+               } else {
+                       /*
+                        * If the vma is out of date, we do not need to
+                        * continue.
+                        */
+                       err = 0;
+               }
                up_read(&mm->mmap_sem);
                /*
                 * In case of failure, the page was not really empty, so we
index 4bb30ed6c8d216cdc6bff02ef2b89d0331479f09..8cbd8c1bfe159e1c8df447660f5c6edfa1366d6d 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/swapops.h>
 #include <linux/shmem_fs.h>
 #include <linux/mmu_notifier.h>
+#include <linux/sched/mm.h>
 
 #include <asm/tlb.h>
 
@@ -1090,6 +1091,23 @@ int do_madvise(unsigned long start, size_t len_in, int behavior)
        if (write) {
                if (down_write_killable(&current->mm->mmap_sem))
                        return -EINTR;
+
+               /*
+                * We may have stolen the mm from another process
+                * that is undergoing core dumping.
+                *
+                * Right now that's io_ring, in the future it may
+                * be remote process management and not "current"
+                * at all.
+                *
+                * We need to fix core dumping to not do this,
+                * but for now we have the mmget_still_valid()
+                * model.
+                */
+               if (!mmget_still_valid(current->mm)) {
+                       up_write(&current->mm->mmap_sem);
+                       return -EINTR;
+               }
        } else {
                down_read(&current->mm->mmap_sem);
        }
index d722eb830317022d0b18392cdd7e61bc2d52195e..bd8840082c941647cc77113dd8ec30d7a6beff46 100644 (file)
@@ -952,7 +952,7 @@ static void shmem_undo_range(struct inode *inode, loff_t lstart, loff_t lend,
                                VM_BUG_ON_PAGE(PageWriteback(page), page);
                                if (shmem_punch_compound(page, start, end))
                                        truncate_inode_page(mapping, page);
-                               else {
+                               else if (IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE)) {
                                        /* Wipe the page and don't get stuck */
                                        clear_highpage(page);
                                        flush_dcache_page(page);
@@ -2179,7 +2179,11 @@ int shmem_lock(struct file *file, int lock, struct user_struct *user)
        struct shmem_inode_info *info = SHMEM_I(inode);
        int retval = -ENOMEM;
 
-       spin_lock_irq(&info->lock);
+       /*
+        * What serializes the accesses to info->flags?
+        * ipc_lock_object() when called from shmctl_do_lock(),
+        * no serialization needed when called from shm_destroy().
+        */
        if (lock && !(info->flags & VM_LOCKED)) {
                if (!user_shm_lock(inode->i_size, user))
                        goto out_nomem;
@@ -2194,7 +2198,6 @@ int shmem_lock(struct file *file, int lock, struct user_struct *user)
        retval = 0;
 
 out_nomem:
-       spin_unlock_irq(&info->lock);
        return retval;
 }
 
@@ -2399,11 +2402,11 @@ static int shmem_mfill_atomic_pte(struct mm_struct *dst_mm,
 
        lru_cache_add_anon(page);
 
-       spin_lock(&info->lock);
+       spin_lock_irq(&info->lock);
        info->alloced++;
        inode->i_blocks += BLOCKS_PER_PAGE;
        shmem_recalc_inode(inode);
-       spin_unlock(&info->lock);
+       spin_unlock_irq(&info->lock);
 
        inc_mm_counter(dst_mm, mm_counter_file(page));
        page_add_file_rmap(page, false);
index 332d4b459a907b6a25e8fef7452e26c61604c2ea..9bf44955c4f1e421f43905aec869e0cbcc80442c 100644 (file)
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -3533,6 +3533,7 @@ static int calculate_sizes(struct kmem_cache *s, int forced_order)
 {
        slab_flags_t flags = s->flags;
        unsigned int size = s->object_size;
+       unsigned int freepointer_area;
        unsigned int order;
 
        /*
@@ -3541,6 +3542,13 @@ static int calculate_sizes(struct kmem_cache *s, int forced_order)
         * the possible location of the free pointer.
         */
        size = ALIGN(size, sizeof(void *));
+       /*
+        * This is the area of the object where a freepointer can be
+        * safely written. If redzoning adds more to the inuse size, we
+        * can't use that portion for writing the freepointer, so
+        * s->offset must be limited within this for the general case.
+        */
+       freepointer_area = size;
 
 #ifdef CONFIG_SLUB_DEBUG
        /*
@@ -3582,13 +3590,13 @@ static int calculate_sizes(struct kmem_cache *s, int forced_order)
                 */
                s->offset = size;
                size += sizeof(void *);
-       } else if (size > sizeof(void *)) {
+       } else if (freepointer_area > sizeof(void *)) {
                /*
                 * Store freelist pointer near middle of object to keep
                 * it away from the edges of the object to avoid small
                 * sized over/underflows from neighboring allocations.
                 */
-               s->offset = ALIGN(size / 2, sizeof(void *));
+               s->offset = ALIGN(freepointer_area / 2, sizeof(void *));
        }
 
 #ifdef CONFIG_SLUB_DEBUG
index 399f219544f74eb45ba2766250b45b9cdbeb971a..9a8227afa0738ffa87d3604a28788141d1abdc9a 100644 (file)
@@ -34,6 +34,7 @@
 #include <linux/llist.h>
 #include <linux/bitops.h>
 #include <linux/rbtree_augmented.h>
+#include <linux/overflow.h>
 
 #include <linux/uaccess.h>
 #include <asm/tlbflush.h>
@@ -3054,6 +3055,7 @@ finished:
  * @vma:               vma to cover
  * @uaddr:             target user address to start at
  * @kaddr:             virtual address of vmalloc kernel memory
+ * @pgoff:             offset from @kaddr to start at
  * @size:              size of map area
  *
  * Returns:    0 for success, -Exxx on failure
@@ -3066,9 +3068,15 @@ finished:
  * Similar to remap_pfn_range() (see mm/memory.c)
  */
 int remap_vmalloc_range_partial(struct vm_area_struct *vma, unsigned long uaddr,
-                               void *kaddr, unsigned long size)
+                               void *kaddr, unsigned long pgoff,
+                               unsigned long size)
 {
        struct vm_struct *area;
+       unsigned long off;
+       unsigned long end_index;
+
+       if (check_shl_overflow(pgoff, PAGE_SHIFT, &off))
+               return -EINVAL;
 
        size = PAGE_ALIGN(size);
 
@@ -3082,8 +3090,10 @@ int remap_vmalloc_range_partial(struct vm_area_struct *vma, unsigned long uaddr,
        if (!(area->flags & (VM_USERMAP | VM_DMA_COHERENT)))
                return -EINVAL;
 
-       if (kaddr + size > area->addr + get_vm_area_size(area))
+       if (check_add_overflow(size, off, &end_index) ||
+           end_index > get_vm_area_size(area))
                return -EINVAL;
+       kaddr += off;
 
        do {
                struct page *page = vmalloc_to_page(kaddr);
@@ -3122,7 +3132,7 @@ int remap_vmalloc_range(struct vm_area_struct *vma, void *addr,
                                                unsigned long pgoff)
 {
        return remap_vmalloc_range_partial(vma, vma->vm_start,
-                                          addr + (pgoff << PAGE_SHIFT),
+                                          addr, pgoff,
                                           vma->vm_end - vma->vm_start);
 }
 EXPORT_SYMBOL(remap_vmalloc_range);
index b4c87fe31be2e860db70a9840ce88d8c82fe2efb..41b24cd31562addb9c6fa87cf87a282ceda62836 100644 (file)
@@ -127,10 +127,8 @@ static int write_classid(struct cgroup_subsys_state *css, struct cftype *cft,
        cs->classid = (u32)value;
 
        css_task_iter_start(css, 0, &it);
-       while ((p = css_task_iter_next(&it))) {
+       while ((p = css_task_iter_next(&it)))
                update_classid_task(p, cs->classid);
-               cond_resched();
-       }
        css_task_iter_end(&it);
 
        return 0;
index e94eb1aac6029e41b65bd2c1ceb044992aec3a4a..d1068803cd1116781e53052a6defe8b9ae9b9fe1 100644 (file)
@@ -1770,11 +1770,9 @@ int dsa_slave_create(struct dsa_port *port)
        rtnl_lock();
        ret = dsa_slave_change_mtu(slave_dev, ETH_DATA_LEN);
        rtnl_unlock();
-       if (ret && ret != -EOPNOTSUPP) {
-               dev_err(ds->dev, "error %d setting MTU on port %d\n",
-                       ret, port->index);
-               goto out_free;
-       }
+       if (ret)
+               dev_warn(ds->dev, "nonfatal error %d setting MTU on port %d\n",
+                        ret, port->index);
 
        netif_carrier_off(slave_dev);
 
index 6ed8c931717942a814aa6c9a8cac5ebd7e626c0f..55ca2e5218280c7857c9bad9351858d38df1916d 100644 (file)
@@ -2014,7 +2014,7 @@ static void fib_select_default(const struct flowi4 *flp, struct fib_result *res)
 
        hlist_for_each_entry_rcu(fa, fa_head, fa_list) {
                struct fib_info *next_fi = fa->fa_info;
-               struct fib_nh *nh;
+               struct fib_nh_common *nhc;
 
                if (fa->fa_slen != slen)
                        continue;
@@ -2037,8 +2037,8 @@ static void fib_select_default(const struct flowi4 *flp, struct fib_result *res)
                    fa->fa_type != RTN_UNICAST)
                        continue;
 
-               nh = fib_info_nh(next_fi, 0);
-               if (!nh->fib_nh_gw4 || nh->fib_nh_scope != RT_SCOPE_LINK)
+               nhc = fib_info_nhc(next_fi, 0);
+               if (!nhc->nhc_gw_family || nhc->nhc_scope != RT_SCOPE_LINK)
                        continue;
 
                fib_alias_accessed(fa);
index 89ba7c87de5df35d8a3807f360fd9d3845fcfa20..30ddb9dc9398beaf8aa7da1a90409c5c2e76d9b6 100644 (file)
@@ -58,9 +58,7 @@ int xfrm4_output_finish(struct sock *sk, struct sk_buff *skb)
 {
        memset(IPCB(skb), 0, sizeof(*IPCB(skb)));
 
-#ifdef CONFIG_NETFILTER
        IPCB(skb)->flags |= IPSKB_XFRM_TRANSFORMED;
-#endif
 
        return xfrm_output(sk, skb);
 }
index debdaeba5d8c130dbf7dd099bc29fbed80a7ac75..18d05403d3b52cc0e69c484c61f04d9f4a166457 100644 (file)
@@ -183,15 +183,14 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname,
                                        retv = -EBUSY;
                                        break;
                                }
-                       } else if (sk->sk_protocol == IPPROTO_TCP) {
-                               if (sk->sk_prot != &tcpv6_prot) {
-                                       retv = -EBUSY;
-                                       break;
-                               }
-                               break;
-                       } else {
+                       }
+                       if (sk->sk_protocol == IPPROTO_TCP &&
+                           sk->sk_prot != &tcpv6_prot) {
+                               retv = -EBUSY;
                                break;
                        }
+                       if (sk->sk_protocol != IPPROTO_TCP)
+                               break;
                        if (sk->sk_state != TCP_ESTABLISHED) {
                                retv = -ENOTCONN;
                                break;
index d38b476fc7f2b158c6e62e6f8829c7de1b5686bf..307f336b5353ef617d5ef9a2085cdea2f5276ba2 100644 (file)
@@ -8,6 +8,7 @@
 #include <net/rpl.h>
 
 #define IPV6_PFXTAIL_LEN(x) (sizeof(struct in6_addr) - (x))
+#define IPV6_RPL_BEST_ADDR_COMPRESSION 15
 
 static void ipv6_rpl_addr_decompress(struct in6_addr *dst,
                                     const struct in6_addr *daddr,
@@ -73,7 +74,7 @@ static unsigned char ipv6_rpl_srh_calc_cmpri(const struct ipv6_rpl_sr_hdr *inhdr
                }
        }
 
-       return plen;
+       return IPV6_RPL_BEST_ADDR_COMPRESSION;
 }
 
 static unsigned char ipv6_rpl_srh_calc_cmpre(const struct in6_addr *daddr,
@@ -83,10 +84,10 @@ static unsigned char ipv6_rpl_srh_calc_cmpre(const struct in6_addr *daddr,
 
        for (plen = 0; plen < sizeof(*daddr); plen++) {
                if (daddr->s6_addr[plen] != last_segment->s6_addr[plen])
-                       break;
+                       return plen;
        }
 
-       return plen;
+       return IPV6_RPL_BEST_ADDR_COMPRESSION;
 }
 
 void ipv6_rpl_srh_compress(struct ipv6_rpl_sr_hdr *outhdr,
index fbe51d40bd7e9f8b50bc3ba1c1d41710a162e29d..e34167f790e6795830ebe94b2872f5be4c6740a7 100644 (file)
@@ -111,9 +111,7 @@ int xfrm6_output_finish(struct sock *sk, struct sk_buff *skb)
 {
        memset(IP6CB(skb), 0, sizeof(*IP6CB(skb)));
 
-#ifdef CONFIG_NETFILTER
        IP6CB(skb)->flags |= IP6SKB_XFRM_TRANSFORMED;
-#endif
 
        return xfrm_output(sk, skb);
 }
index 0e9ad60fb2b3d9dc9a0bcacfb4e8ec08fd112df0..6423173bb87ed4bb0df0b17c59e09644cf2e0e56 100644 (file)
@@ -1183,8 +1183,6 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
        local->tx_headroom = max_t(unsigned int , local->hw.extra_tx_headroom,
                                   IEEE80211_TX_STATUS_HEADROOM);
 
-       debugfs_hw_add(local);
-
        /*
         * if the driver doesn't specify a max listen interval we
         * use 5 which should be a safe default
@@ -1273,6 +1271,9 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
        if (result < 0)
                goto fail_wiphy_register;
 
+       debugfs_hw_add(local);
+       rate_control_add_debugfs(local);
+
        rtnl_lock();
 
        /* add one default STA interface if supported */
index a1e9fc7878aa33f252ad33414d5dc1e86f8dd99b..b051f125d3af245a885023fcd124c593ac3c36df 100644 (file)
@@ -214,17 +214,16 @@ static ssize_t rcname_read(struct file *file, char __user *userbuf,
                                       ref->ops->name, len);
 }
 
-static const struct file_operations rcname_ops = {
+const struct file_operations rcname_ops = {
        .read = rcname_read,
        .open = simple_open,
        .llseek = default_llseek,
 };
 #endif
 
-static struct rate_control_ref *rate_control_alloc(const char *name,
-                                           struct ieee80211_local *local)
+static struct rate_control_ref *
+rate_control_alloc(const char *name, struct ieee80211_local *local)
 {
-       struct dentry *debugfsdir = NULL;
        struct rate_control_ref *ref;
 
        ref = kmalloc(sizeof(struct rate_control_ref), GFP_KERNEL);
@@ -234,13 +233,7 @@ static struct rate_control_ref *rate_control_alloc(const char *name,
        if (!ref->ops)
                goto free;
 
-#ifdef CONFIG_MAC80211_DEBUGFS
-       debugfsdir = debugfs_create_dir("rc", local->hw.wiphy->debugfsdir);
-       local->debugfs.rcdir = debugfsdir;
-       debugfs_create_file("name", 0400, debugfsdir, ref, &rcname_ops);
-#endif
-
-       ref->priv = ref->ops->alloc(&local->hw, debugfsdir);
+       ref->priv = ref->ops->alloc(&local->hw);
        if (!ref->priv)
                goto free;
        return ref;
index 5397c6dad056124db564f335404c20736ddd7ab4..79b44d3db171e9ddbc1d6e2de041d88e350696ac 100644 (file)
@@ -60,6 +60,29 @@ static inline void rate_control_add_sta_debugfs(struct sta_info *sta)
 #endif
 }
 
+extern const struct file_operations rcname_ops;
+
+static inline void rate_control_add_debugfs(struct ieee80211_local *local)
+{
+#ifdef CONFIG_MAC80211_DEBUGFS
+       struct dentry *debugfsdir;
+
+       if (!local->rate_ctrl)
+               return;
+
+       if (!local->rate_ctrl->ops->add_debugfs)
+               return;
+
+       debugfsdir = debugfs_create_dir("rc", local->hw.wiphy->debugfsdir);
+       local->debugfs.rcdir = debugfsdir;
+       debugfs_create_file("name", 0400, debugfsdir,
+                           local->rate_ctrl, &rcname_ops);
+
+       local->rate_ctrl->ops->add_debugfs(&local->hw, local->rate_ctrl->priv,
+                                          debugfsdir);
+#endif
+}
+
 void ieee80211_check_rate_mask(struct ieee80211_sub_if_data *sdata);
 
 /* Get a reference to the rate control algorithm. If `name' is NULL, get the
index 694a31978a0443dacbdfdd91ce9dd48d46974afe..5dc3e5bc4e6422f7472f3f5fa6c5fa714fd4ca32 100644 (file)
@@ -1635,7 +1635,7 @@ minstrel_ht_init_cck_rates(struct minstrel_priv *mp)
 }
 
 static void *
-minstrel_ht_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir)
+minstrel_ht_alloc(struct ieee80211_hw *hw)
 {
        struct minstrel_priv *mp;
 
@@ -1673,7 +1673,17 @@ minstrel_ht_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir)
        mp->update_interval = HZ / 10;
        mp->new_avg = true;
 
+       minstrel_ht_init_cck_rates(mp);
+
+       return mp;
+}
+
 #ifdef CONFIG_MAC80211_DEBUGFS
+static void minstrel_ht_add_debugfs(struct ieee80211_hw *hw, void *priv,
+                                   struct dentry *debugfsdir)
+{
+       struct minstrel_priv *mp = priv;
+
        mp->fixed_rate_idx = (u32) -1;
        debugfs_create_u32("fixed_rate_idx", S_IRUGO | S_IWUGO, debugfsdir,
                           &mp->fixed_rate_idx);
@@ -1681,12 +1691,8 @@ minstrel_ht_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir)
                           &mp->sample_switch);
        debugfs_create_bool("new_avg", S_IRUGO | S_IWUSR, debugfsdir,
                           &mp->new_avg);
-#endif
-
-       minstrel_ht_init_cck_rates(mp);
-
-       return mp;
 }
+#endif
 
 static void
 minstrel_ht_free(void *priv)
@@ -1725,6 +1731,7 @@ static const struct rate_control_ops mac80211_minstrel_ht = {
        .alloc = minstrel_ht_alloc,
        .free = minstrel_ht_free,
 #ifdef CONFIG_MAC80211_DEBUGFS
+       .add_debugfs = minstrel_ht_add_debugfs,
        .add_sta_debugfs = minstrel_ht_add_sta_debugfs,
 #endif
        .get_expected_throughput = minstrel_ht_get_expected_throughput,
index f8d5c25158293df653236d566418c364da622636..cd8487bc6fc2e368f01e41275518a4056c1cc552 100644 (file)
@@ -231,7 +231,8 @@ struct sta_info *sta_info_get_by_idx(struct ieee80211_sub_if_data *sdata,
        struct sta_info *sta;
        int i = 0;
 
-       list_for_each_entry_rcu(sta, &local->sta_list, list) {
+       list_for_each_entry_rcu(sta, &local->sta_list, list,
+                               lockdep_is_held(&local->sta_mtx)) {
                if (sdata != sta->sdata)
                        continue;
                if (i < idx) {
index faf57585b89282aae5937e74e948de8c6270d674..4a7c467b99db460387cb8f88e8a33a277229b49d 100644 (file)
@@ -876,12 +876,11 @@ void mptcp_incoming_options(struct sock *sk, struct sk_buff *skb,
                        mpext->data_seq = mp_opt->data_seq;
                        mpext->subflow_seq = mp_opt->subflow_seq;
                        mpext->dsn64 = mp_opt->dsn64;
+                       mpext->data_fin = mp_opt->data_fin;
                }
                mpext->data_len = mp_opt->data_len;
                mpext->use_map = 1;
        }
-
-       mpext->data_fin = mp_opt->data_fin;
 }
 
 void mptcp_write_options(__be32 *ptr, struct mptcp_out_options *opts)
index 86d61ab34c7c3c5d8327c7996c813adab634159c..b78edf237ba0ad6457f82758edf8623c913f9a4e 100644 (file)
@@ -599,12 +599,14 @@ static int mptcp_nl_fill_addr(struct sk_buff *skb,
            nla_put_s32(skb, MPTCP_PM_ADDR_ATTR_IF_IDX, entry->ifindex))
                goto nla_put_failure;
 
-       if (addr->family == AF_INET)
-               nla_put_in_addr(skb, MPTCP_PM_ADDR_ATTR_ADDR4,
-                               addr->addr.s_addr);
+       if (addr->family == AF_INET &&
+           nla_put_in_addr(skb, MPTCP_PM_ADDR_ATTR_ADDR4,
+                           addr->addr.s_addr))
+               goto nla_put_failure;
 #if IS_ENABLED(CONFIG_MPTCP_IPV6)
-       else if (addr->family == AF_INET6)
-               nla_put_in6_addr(skb, MPTCP_PM_ADDR_ATTR_ADDR6, &addr->addr6);
+       else if (addr->family == AF_INET6 &&
+                nla_put_in6_addr(skb, MPTCP_PM_ADDR_ATTR_ADDR6, &addr->addr6))
+               goto nla_put_failure;
 #endif
        nla_nest_end(skb, attr);
        return 0;
index 9936e33ac3511eb844ec3075b46bd36cfd7993ab..b22a63ba2348ae60e7f509ee7772faf19969660e 100644 (file)
@@ -1332,7 +1332,9 @@ static struct ipv6_pinfo *mptcp_inet6_sk(const struct sock *sk)
 }
 #endif
 
-struct sock *mptcp_sk_clone(const struct sock *sk, struct request_sock *req)
+struct sock *mptcp_sk_clone(const struct sock *sk,
+                           const struct tcp_options_received *opt_rx,
+                           struct request_sock *req)
 {
        struct mptcp_subflow_request_sock *subflow_req = mptcp_subflow_rsk(req);
        struct sock *nsk = sk_clone_lock(sk, GFP_ATOMIC);
@@ -1355,26 +1357,30 @@ struct sock *mptcp_sk_clone(const struct sock *sk, struct request_sock *req)
        msk->subflow = NULL;
 
        if (unlikely(mptcp_token_new_accept(subflow_req->token, nsk))) {
+               nsk->sk_state = TCP_CLOSE;
                bh_unlock_sock(nsk);
 
                /* we can't call into mptcp_close() here - possible BH context
-                * free the sock directly
+                * free the sock directly.
+                * sk_clone_lock() sets nsk refcnt to two, hence call sk_free()
+                * too.
                 */
-               nsk->sk_prot->destroy(nsk);
+               sk_common_release(nsk);
                sk_free(nsk);
                return NULL;
        }
 
        msk->write_seq = subflow_req->idsn + 1;
        atomic64_set(&msk->snd_una, msk->write_seq);
-       if (subflow_req->remote_key_valid) {
+       if (opt_rx->mptcp.mp_capable) {
                msk->can_ack = true;
-               msk->remote_key = subflow_req->remote_key;
+               msk->remote_key = opt_rx->mptcp.sndr_key;
                mptcp_crypto_key_sha(msk->remote_key, NULL, &ack_seq);
                ack_seq++;
                msk->ack_seq = ack_seq;
        }
 
+       sock_reset_flag(nsk, SOCK_RCU_FREE);
        /* will be fully established after successful MPC subflow creation */
        inet_sk_state_store(nsk, TCP_SYN_RECV);
        bh_unlock_sock(nsk);
@@ -1431,6 +1437,7 @@ static struct sock *mptcp_accept(struct sock *sk, int flags, int *err,
                newsk = new_mptcp_sock;
                mptcp_copy_inaddrs(newsk, ssk);
                list_add(&subflow->node, &msk->conn_list);
+               inet_sk_state_store(newsk, TCP_ESTABLISHED);
 
                bh_unlock_sock(new_mptcp_sock);
 
@@ -1775,6 +1782,8 @@ static int mptcp_listen(struct socket *sock, int backlog)
                goto unlock;
        }
 
+       sock_set_flag(sock->sk, SOCK_RCU_FREE);
+
        err = ssock->ops->listen(ssock, backlog);
        inet_sk_state_store(sock->sk, inet_sk_state_load(ssock->sk));
        if (!err)
index 67448002a2d793ffa47ddb7e9df36891f345b8c7..a2b3048037d088cbf17d8cccb383e107d332cb48 100644 (file)
@@ -206,12 +206,10 @@ struct mptcp_subflow_request_sock {
        struct  tcp_request_sock sk;
        u16     mp_capable : 1,
                mp_join : 1,
-               backup : 1,
-               remote_key_valid : 1;
+               backup : 1;
        u8      local_id;
        u8      remote_id;
        u64     local_key;
-       u64     remote_key;
        u64     idsn;
        u32     token;
        u32     ssn_offset;
@@ -332,7 +330,9 @@ void mptcp_proto_init(void);
 int mptcp_proto_v6_init(void);
 #endif
 
-struct sock *mptcp_sk_clone(const struct sock *sk, struct request_sock *req);
+struct sock *mptcp_sk_clone(const struct sock *sk,
+                           const struct tcp_options_received *opt_rx,
+                           struct request_sock *req);
 void mptcp_get_options(const struct sk_buff *skb,
                       struct tcp_options_received *opt_rx);
 
index 50a8bea987c6e859303941d1a41165c651806bfb..fabd06f2ff455e76cf281c4e6fc2d41b144ac2d9 100644 (file)
@@ -133,7 +133,6 @@ static void subflow_init_req(struct request_sock *req,
 
        subflow_req->mp_capable = 0;
        subflow_req->mp_join = 0;
-       subflow_req->remote_key_valid = 0;
 
 #ifdef CONFIG_TCP_MD5SIG
        /* no MPTCP if MD5SIG is enabled on this socket or we may run out of
@@ -347,6 +346,46 @@ static bool subflow_hmac_valid(const struct request_sock *req,
        return ret;
 }
 
+static void mptcp_sock_destruct(struct sock *sk)
+{
+       /* if new mptcp socket isn't accepted, it is free'd
+        * from the tcp listener sockets request queue, linked
+        * from req->sk.  The tcp socket is released.
+        * This calls the ULP release function which will
+        * also remove the mptcp socket, via
+        * sock_put(ctx->conn).
+        *
+        * Problem is that the mptcp socket will not be in
+        * SYN_RECV state and doesn't have SOCK_DEAD flag.
+        * Both result in warnings from inet_sock_destruct.
+        */
+
+       if (sk->sk_state == TCP_SYN_RECV) {
+               sk->sk_state = TCP_CLOSE;
+               WARN_ON_ONCE(sk->sk_socket);
+               sock_orphan(sk);
+       }
+
+       inet_sock_destruct(sk);
+}
+
+static void mptcp_force_close(struct sock *sk)
+{
+       inet_sk_state_store(sk, TCP_CLOSE);
+       sk_common_release(sk);
+}
+
+static void subflow_ulp_fallback(struct sock *sk,
+                                struct mptcp_subflow_context *old_ctx)
+{
+       struct inet_connection_sock *icsk = inet_csk(sk);
+
+       mptcp_subflow_tcp_fallback(sk, old_ctx);
+       icsk->icsk_ulp_ops = NULL;
+       rcu_assign_pointer(icsk->icsk_ulp_data, NULL);
+       tcp_sk(sk)->is_mptcp = 0;
+}
+
 static struct sock *subflow_syn_recv_sock(const struct sock *sk,
                                          struct sk_buff *skb,
                                          struct request_sock *req,
@@ -359,10 +398,12 @@ static struct sock *subflow_syn_recv_sock(const struct sock *sk,
        struct tcp_options_received opt_rx;
        bool fallback_is_fatal = false;
        struct sock *new_msk = NULL;
+       bool fallback = false;
        struct sock *child;
 
        pr_debug("listener=%p, req=%p, conn=%p", listener, req, listener->conn);
 
+       opt_rx.mptcp.mp_capable = 0;
        if (tcp_rsk(req)->is_mptcp == 0)
                goto create_child;
 
@@ -377,20 +418,16 @@ static struct sock *subflow_syn_recv_sock(const struct sock *sk,
                        goto create_msk;
                }
 
-               opt_rx.mptcp.mp_capable = 0;
                mptcp_get_options(skb, &opt_rx);
-               if (opt_rx.mptcp.mp_capable) {
-                       subflow_req->remote_key = opt_rx.mptcp.sndr_key;
-                       subflow_req->remote_key_valid = 1;
-               } else {
-                       subflow_req->mp_capable = 0;
+               if (!opt_rx.mptcp.mp_capable) {
+                       fallback = true;
                        goto create_child;
                }
 
 create_msk:
-               new_msk = mptcp_sk_clone(listener->conn, req);
+               new_msk = mptcp_sk_clone(listener->conn, &opt_rx, req);
                if (!new_msk)
-                       subflow_req->mp_capable = 0;
+                       fallback = true;
        } else if (subflow_req->mp_join) {
                fallback_is_fatal = true;
                opt_rx.mptcp.mp_join = 0;
@@ -409,12 +446,18 @@ create_child:
        if (child && *own_req) {
                struct mptcp_subflow_context *ctx = mptcp_subflow_ctx(child);
 
-               /* we have null ctx on TCP fallback, which is fatal on
-                * MPJ handshake
+               /* we need to fallback on ctx allocation failure and on pre-reqs
+                * checking above. In the latter scenario we additionally need
+                * to reset the context to non MPTCP status.
                 */
-               if (!ctx) {
+               if (!ctx || fallback) {
                        if (fallback_is_fatal)
                                goto close_child;
+
+                       if (ctx) {
+                               subflow_ulp_fallback(child, ctx);
+                               kfree_rcu(ctx, rcu);
+                       }
                        goto out;
                }
 
@@ -422,10 +465,17 @@ create_child:
                        /* new mpc subflow takes ownership of the newly
                         * created mptcp socket
                         */
-                       inet_sk_state_store(new_msk, TCP_ESTABLISHED);
+                       new_msk->sk_destruct = mptcp_sock_destruct;
                        mptcp_pm_new_connection(mptcp_sk(new_msk), 1);
                        ctx->conn = new_msk;
                        new_msk = NULL;
+
+                       /* with OoO packets we can reach here without ingress
+                        * mpc option
+                        */
+                       ctx->remote_key = opt_rx.mptcp.sndr_key;
+                       ctx->fully_established = opt_rx.mptcp.mp_capable;
+                       ctx->can_ack = opt_rx.mptcp.mp_capable;
                } else if (ctx->mp_join) {
                        struct mptcp_sock *owner;
 
@@ -444,7 +494,14 @@ create_child:
 out:
        /* dispose of the left over mptcp master, if any */
        if (unlikely(new_msk))
-               sock_put(new_msk);
+               mptcp_force_close(new_msk);
+
+       /* check for expected invariant - should never trigger, just help
+        * catching eariler subtle bugs
+        */
+       WARN_ON_ONCE(*own_req && child && tcp_sk(child)->is_mptcp &&
+                    (!mptcp_subflow_ctx(child) ||
+                     !mptcp_subflow_ctx(child)->conn));
        return child;
 
 close_child:
@@ -1047,17 +1104,6 @@ static void subflow_ulp_release(struct sock *sk)
        kfree_rcu(ctx, rcu);
 }
 
-static void subflow_ulp_fallback(struct sock *sk,
-                                struct mptcp_subflow_context *old_ctx)
-{
-       struct inet_connection_sock *icsk = inet_csk(sk);
-
-       mptcp_subflow_tcp_fallback(sk, old_ctx);
-       icsk->icsk_ulp_ops = NULL;
-       rcu_assign_pointer(icsk->icsk_ulp_data, NULL);
-       tcp_sk(sk)->is_mptcp = 0;
-}
-
 static void subflow_ulp_clone(const struct request_sock *req,
                              struct sock *newsk,
                              const gfp_t priority)
@@ -1091,9 +1137,6 @@ static void subflow_ulp_clone(const struct request_sock *req,
                 * is fully established only after we receive the remote key
                 */
                new_ctx->mp_capable = 1;
-               new_ctx->fully_established = subflow_req->remote_key_valid;
-               new_ctx->can_ack = subflow_req->remote_key_valid;
-               new_ctx->remote_key = subflow_req->remote_key;
                new_ctx->local_key = subflow_req->local_key;
                new_ctx->token = subflow_req->token;
                new_ctx->ssn_offset = subflow_req->ssn_offset;
index c0cb79495c358e9f70bb72d1ef349553b93cca31..4344e572b7f96c65e7df179f3596be0ad5499c18 100644 (file)
@@ -421,10 +421,12 @@ void nf_flow_table_offload_del_cb(struct nf_flowtable *flow_table,
 
        down_write(&flow_table->flow_block_lock);
        block_cb = flow_block_cb_lookup(block, cb, cb_priv);
-       if (block_cb)
+       if (block_cb) {
                list_del(&block_cb->list);
-       else
+               flow_block_cb_free(block_cb);
+       } else {
                WARN_ON(true);
+       }
        up_write(&flow_table->flow_block_lock);
 }
 EXPORT_SYMBOL_GPL(nf_flow_table_offload_del_cb);
index 64eedc17037ad783d3a99851038e91394465617e..3d816a1e5442e6b2678fddc0f18f3e0545298fb1 100644 (file)
@@ -1035,8 +1035,8 @@ int nf_nat_inet_register_fn(struct net *net, const struct nf_hook_ops *ops)
        ret = nf_nat_register_fn(net, NFPROTO_IPV4, ops, nf_nat_ipv4_ops,
                                 ARRAY_SIZE(nf_nat_ipv4_ops));
        if (ret)
-               nf_nat_ipv6_unregister_fn(net, ops);
-
+               nf_nat_unregister_fn(net, NFPROTO_IPV6, ops,
+                                       ARRAY_SIZE(nf_nat_ipv6_ops));
        return ret;
 }
 EXPORT_SYMBOL_GPL(nf_nat_inet_register_fn);
index 64280a1d3906c2b8f8fea3ad4796d14c210654ce..07b03c306f28abc4758ea3e17ac5c6ff1dff67ce 100644 (file)
@@ -14,6 +14,6 @@ config NETLABEL
          Documentation/netlabel as well as the NetLabel SourceForge project
          for configuration tools and additional documentation.
 
-          * http://netlabel.sf.net
+          * https://github.com/netlabel/netlabel_tools
 
          If you are unsure, say N.
index 79f12d8c7b86f59636f95c16d7974a5397f398f8..0891ee02ca4fe03145066852035de38e62a06ee2 100644 (file)
@@ -208,6 +208,7 @@ static int __must_check nr_add_node(ax25_address *nr, const char *mnemonic,
                /* refcount initialized at 1 */
                spin_unlock_bh(&nr_node_list_lock);
 
+               nr_neigh_put(nr_neigh);
                return 0;
        }
        nr_node_lock(nr_node);
index e726159cfcfae3151d21a76a1a9b5c29bb54fd6f..4340f25fe390f5baac7d0602e67803f2dc05ae57 100644 (file)
@@ -1895,7 +1895,8 @@ static void ovs_ct_limit_exit(struct net *net, struct ovs_net *ovs_net)
                struct hlist_head *head = &info->limits[i];
                struct ovs_ct_limit *ct_limit;
 
-               hlist_for_each_entry_rcu(ct_limit, head, hlist_node)
+               hlist_for_each_entry_rcu(ct_limit, head, hlist_node,
+                                        lockdep_ovsl_is_held())
                        kfree_rcu(ct_limit, rcu);
        }
        kfree(ovs_net->ct_limit_info->limits);
index d8ae541d22a8ce8979aef099be0c1e85801c91fc..94b024534987a02428e7bd579e531958ca4b190b 100644 (file)
@@ -2466,8 +2466,10 @@ static void __net_exit ovs_exit_net(struct net *dnet)
        struct net *net;
        LIST_HEAD(head);
 
-       ovs_ct_exit(dnet);
        ovs_lock();
+
+       ovs_ct_exit(dnet);
+
        list_for_each_entry_safe(dp, dp_next, &ovs_net->dps, list_node)
                __dp_destroy(dp);
 
index b1da5589a0c6a2c9db9912430dca3d5f06fff10c..c48f91075b5c60ee4fe9e10186c913baf5894a69 100644 (file)
@@ -82,7 +82,7 @@ static bool is_packet_valid(struct Qdisc *sch, struct sk_buff *nskb)
        if (q->skip_sock_check)
                goto skip;
 
-       if (!sk)
+       if (!sk || !sk_fullsock(sk))
                return false;
 
        if (!sock_flag(sk, SOCK_TXTIME))
@@ -137,8 +137,9 @@ static void report_sock_error(struct sk_buff *skb, u32 err, u8 code)
        struct sock_exterr_skb *serr;
        struct sk_buff *clone;
        ktime_t txtime = skb->tstamp;
+       struct sock *sk = skb->sk;
 
-       if (!skb->sk || !(skb->sk->sk_txtime_report_errors))
+       if (!sk || !sk_fullsock(sk) || !(sk->sk_txtime_report_errors))
                return;
 
        clone = skb_clone(skb, GFP_ATOMIC);
@@ -154,7 +155,7 @@ static void report_sock_error(struct sk_buff *skb, u32 err, u8 code)
        serr->ee.ee_data = (txtime >> 32); /* high part of tstamp */
        serr->ee.ee_info = txtime; /* low part of tstamp */
 
-       if (sock_queue_err_skb(skb->sk, clone))
+       if (sock_queue_err_skb(sk, clone))
                kfree_skb(clone);
 }
 
index 09050c1d5517e7b9269314423a550f2202cd6051..f7cb0b7faec2327ea803d5159eea22fe9f612c2f 100644 (file)
@@ -858,7 +858,11 @@ struct sctp_chunk *sctp_make_shutdown(const struct sctp_association *asoc,
        struct sctp_chunk *retval;
        __u32 ctsn;
 
-       ctsn = sctp_tsnmap_get_ctsn(&asoc->peer.tsn_map);
+       if (chunk && chunk->asoc)
+               ctsn = sctp_tsnmap_get_ctsn(&chunk->asoc->peer.tsn_map);
+       else
+               ctsn = sctp_tsnmap_get_ctsn(&asoc->peer.tsn_map);
+
        shut.cum_tsn_ack = htonl(ctsn);
 
        retval = sctp_make_control(asoc, SCTP_CID_SHUTDOWN, 0,
index 6a16af4b1ef61810fed8a04169109f311b070575..26788f4a3b9eb66091e03dec907a8b4e4ddc8554 100644 (file)
@@ -1865,7 +1865,7 @@ static enum sctp_disposition sctp_sf_do_dupcook_a(
                 */
                sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(repl));
                return sctp_sf_do_9_2_start_shutdown(net, ep, asoc,
-                                                    SCTP_ST_CHUNK(0), NULL,
+                                                    SCTP_ST_CHUNK(0), repl,
                                                     commands);
        } else {
                sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
@@ -5470,7 +5470,7 @@ enum sctp_disposition sctp_sf_do_9_2_start_shutdown(
         * in the Cumulative TSN Ack field the last sequential TSN it
         * has received from the peer.
         */
-       reply = sctp_make_shutdown(asoc, NULL);
+       reply = sctp_make_shutdown(asoc, arg);
        if (!reply)
                goto nomem;
 
@@ -6068,7 +6068,7 @@ enum sctp_disposition sctp_sf_autoclose_timer_expire(
        disposition = SCTP_DISPOSITION_CONSUME;
        if (sctp_outq_is_empty(&asoc->outqueue)) {
                disposition = sctp_sf_do_9_2_start_shutdown(net, ep, asoc, type,
-                                                           arg, commands);
+                                                           NULL, commands);
        }
 
        return disposition;
index af0ddd28b081cd166b4dc4339bfdcc0f548a6256..baef5ee43dbbdb3fbc9b5bdf780a585e8d877404 100644 (file)
@@ -529,7 +529,6 @@ void cache_purge(struct cache_detail *detail)
 {
        struct cache_head *ch = NULL;
        struct hlist_head *head = NULL;
-       struct hlist_node *tmp = NULL;
        int i = 0;
 
        spin_lock(&detail->hash_lock);
@@ -541,7 +540,9 @@ void cache_purge(struct cache_detail *detail)
        dprintk("RPC: %d entries in %s cache\n", detail->entries, detail->name);
        for (i = 0; i < detail->hash_size; i++) {
                head = &detail->hash_table[i];
-               hlist_for_each_entry_safe(ch, tmp, head, cache_list) {
+               while (!hlist_empty(head)) {
+                       ch = hlist_entry(head->first, struct cache_head,
+                                        cache_list);
                        sunrpc_begin_cache_remove_entry(ch, detail);
                        spin_unlock(&detail->hash_lock);
                        sunrpc_end_cache_remove_entry(ch, detail);
index e27e3532ec7567a9b4e3dd07f158c26f58aafb64..2284ff038dadb9f9b7f505e8a07eb49c33e79f62 100644 (file)
@@ -908,9 +908,6 @@ int svc_send(struct svc_rqst *rqstp)
        if (!xprt)
                goto out;
 
-       /* release the receive skb before sending the reply */
-       xprt->xpt_ops->xpo_release_rqst(rqstp);
-
        /* calculate over-all length */
        xb = &rqstp->rq_res;
        xb->len = xb->head[0].iov_len +
@@ -1040,6 +1037,8 @@ static void svc_delete_xprt(struct svc_xprt *xprt)
 
        dprintk("svc: svc_delete_xprt(%p)\n", xprt);
        xprt->xpt_ops->xpo_detach(xprt);
+       if (xprt->xpt_bc_xprt)
+               xprt->xpt_bc_xprt->ops->close(xprt->xpt_bc_xprt);
 
        spin_lock_bh(&serv->sv_lock);
        list_del_init(&xprt->xpt_list);
index 519cf9c4f8fd8bf46539c8b0ddca293838fde26a..023514e392b3106d4bec9867510f3279676637e6 100644 (file)
@@ -527,6 +527,8 @@ static int svc_udp_sendto(struct svc_rqst *rqstp)
        unsigned int uninitialized_var(sent);
        int err;
 
+       svc_release_udp_skb(rqstp);
+
        svc_set_cmsg_data(rqstp, cmh);
 
        err = xprt_sock_sendmsg(svsk->sk_sock, &msg, xdr, 0, 0, &sent);
@@ -1076,6 +1078,8 @@ static int svc_tcp_sendto(struct svc_rqst *rqstp)
        unsigned int uninitialized_var(sent);
        int err;
 
+       svc_release_skb(rqstp);
+
        err = xprt_sock_sendmsg(svsk->sk_sock, &msg, xdr, 0, marker, &sent);
        xdr_free_bvec(xdr);
        if (err < 0 || sent != (xdr->len + sizeof(marker)))
index d510a3a15d4be9d169598da0a06db896357190a0..af7eb8d202ae70fceffe554d184e27f9348dcc05 100644 (file)
@@ -244,6 +244,8 @@ static void
 xprt_rdma_bc_close(struct rpc_xprt *xprt)
 {
        dprintk("svcrdma: %s: xprt %p\n", __func__, xprt);
+
+       xprt_disconnect_done(xprt);
        xprt->cwnd = RPC_CWNDSHIFT;
 }
 
index 54469b72b25f3cf067d78d14daa1b1b5a58b58e5..efa5fcb5793f710cdd6d8eabe5a1353849f44db9 100644 (file)
@@ -223,6 +223,26 @@ void svc_rdma_recv_ctxt_put(struct svcxprt_rdma *rdma,
                svc_rdma_recv_ctxt_destroy(rdma, ctxt);
 }
 
+/**
+ * svc_rdma_release_rqst - Release transport-specific per-rqst resources
+ * @rqstp: svc_rqst being released
+ *
+ * Ensure that the recv_ctxt is released whether or not a Reply
+ * was sent. For example, the client could close the connection,
+ * or svc_process could drop an RPC, before the Reply is sent.
+ */
+void svc_rdma_release_rqst(struct svc_rqst *rqstp)
+{
+       struct svc_rdma_recv_ctxt *ctxt = rqstp->rq_xprt_ctxt;
+       struct svc_xprt *xprt = rqstp->rq_xprt;
+       struct svcxprt_rdma *rdma =
+               container_of(xprt, struct svcxprt_rdma, sc_xprt);
+
+       rqstp->rq_xprt_ctxt = NULL;
+       if (ctxt)
+               svc_rdma_recv_ctxt_put(rdma, ctxt);
+}
+
 static int __svc_rdma_post_recv(struct svcxprt_rdma *rdma,
                                struct svc_rdma_recv_ctxt *ctxt)
 {
@@ -820,6 +840,8 @@ int svc_rdma_recvfrom(struct svc_rqst *rqstp)
        __be32 *p;
        int ret;
 
+       rqstp->rq_xprt_ctxt = NULL;
+
        spin_lock(&rdma_xprt->sc_rq_dto_lock);
        ctxt = svc_rdma_next_recv_ctxt(&rdma_xprt->sc_read_complete_q);
        if (ctxt) {
index bd7c195d872ec0036ae0fee4f81747a0a34e7925..23c2d3ce0dc9a01d162a84f4aba6e607f34a05cf 100644 (file)
@@ -323,8 +323,6 @@ static int svc_rdma_post_chunk_ctxt(struct svc_rdma_chunk_ctxt *cc)
                if (atomic_sub_return(cc->cc_sqecount,
                                      &rdma->sc_sq_avail) > 0) {
                        ret = ib_post_send(rdma->sc_qp, first_wr, &bad_wr);
-                       trace_svcrdma_post_rw(&cc->cc_cqe,
-                                             cc->cc_sqecount, ret);
                        if (ret)
                                break;
                        return 0;
@@ -337,6 +335,7 @@ static int svc_rdma_post_chunk_ctxt(struct svc_rdma_chunk_ctxt *cc)
                trace_svcrdma_sq_retry(rdma);
        } while (1);
 
+       trace_svcrdma_sq_post_err(rdma, ret);
        set_bit(XPT_CLOSE, &xprt->xpt_flags);
 
        /* If even one was posted, there will be a completion. */
index 90cba3058f04cf40f69985ad01ee631982331f5c..b6c8643867f2cc943a16de17f70bcb8033e421c4 100644 (file)
@@ -322,15 +322,17 @@ int svc_rdma_send(struct svcxprt_rdma *rdma, struct ib_send_wr *wr)
                }
 
                svc_xprt_get(&rdma->sc_xprt);
+               trace_svcrdma_post_send(wr);
                ret = ib_post_send(rdma->sc_qp, wr, NULL);
-               trace_svcrdma_post_send(wr, ret);
-               if (ret) {
-                       set_bit(XPT_CLOSE, &rdma->sc_xprt.xpt_flags);
-                       svc_xprt_put(&rdma->sc_xprt);
-                       wake_up(&rdma->sc_send_wait);
-               }
-               break;
+               if (ret)
+                       break;
+               return 0;
        }
+
+       trace_svcrdma_sq_post_err(rdma, ret);
+       set_bit(XPT_CLOSE, &rdma->sc_xprt.xpt_flags);
+       svc_xprt_put(&rdma->sc_xprt);
+       wake_up(&rdma->sc_send_wait);
        return ret;
 }
 
@@ -924,12 +926,7 @@ int svc_rdma_sendto(struct svc_rqst *rqstp)
        ret = svc_rdma_send_reply_msg(rdma, sctxt, rctxt, rqstp);
        if (ret < 0)
                goto err1;
-       ret = 0;
-
-out:
-       rqstp->rq_xprt_ctxt = NULL;
-       svc_rdma_recv_ctxt_put(rdma, rctxt);
-       return ret;
+       return 0;
 
  err2:
        if (ret != -E2BIG && ret != -EINVAL)
@@ -938,16 +935,14 @@ out:
        ret = svc_rdma_send_error_msg(rdma, sctxt, rqstp);
        if (ret < 0)
                goto err1;
-       ret = 0;
-       goto out;
+       return 0;
 
  err1:
        svc_rdma_send_ctxt_put(rdma, sctxt);
  err0:
        trace_svcrdma_send_failed(rqstp, ret);
        set_bit(XPT_CLOSE, &xprt->xpt_flags);
-       ret = -ENOTCONN;
-       goto out;
+       return -ENOTCONN;
 }
 
 /**
index 8bb99980ae8562eb4ba4a62f7f2d5ee7f63c0887..ea54785db4f8fb60bece91da79e16aec93dce7ca 100644 (file)
@@ -71,7 +71,6 @@ static struct svc_xprt *svc_rdma_create(struct svc_serv *serv,
                                        struct sockaddr *sa, int salen,
                                        int flags);
 static struct svc_xprt *svc_rdma_accept(struct svc_xprt *xprt);
-static void svc_rdma_release_rqst(struct svc_rqst *);
 static void svc_rdma_detach(struct svc_xprt *xprt);
 static void svc_rdma_free(struct svc_xprt *xprt);
 static int svc_rdma_has_wspace(struct svc_xprt *xprt);
@@ -552,10 +551,6 @@ static struct svc_xprt *svc_rdma_accept(struct svc_xprt *xprt)
        return NULL;
 }
 
-static void svc_rdma_release_rqst(struct svc_rqst *rqstp)
-{
-}
-
 /*
  * When connected, an svc_xprt has at least two references:
  *
index 0bda8a73e8a86ea99ff5c04192a4624752d8a067..845d0be805ece18da98e87886c08595d18252d65 100644 (file)
@@ -2584,6 +2584,7 @@ static int bc_send_request(struct rpc_rqst *req)
 
 static void bc_close(struct rpc_xprt *xprt)
 {
+       xprt_disconnect_done(xprt);
 }
 
 /*
index c8c47fc7265361229c9e19f7e46eeb840089d93d..8c47ded2edb6143d3a79782e5f8404546a726ac4 100644 (file)
@@ -1712,6 +1712,7 @@ exit:
        case -EBUSY:
                this_cpu_inc(stats->stat[STAT_ASYNC]);
                *skb = NULL;
+               tipc_aead_put(aead);
                return rc;
        default:
                this_cpu_inc(stats->stat[STAT_NOK]);
index 10292c942384dbb0fc51e9f931bd25fbacfeab6a..803a3a6d0f50245023f3d179c025aaefc5963577 100644 (file)
@@ -2038,6 +2038,7 @@ void tipc_rcv(struct net *net, struct sk_buff *skb, struct tipc_bearer *b)
                n = tipc_node_find_by_id(net, ehdr->id);
        }
        tipc_crypto_rcv(net, (n) ? n->crypto_rx : NULL, &skb, b);
+       tipc_node_put(n);
        if (!skb)
                return;
 
@@ -2090,7 +2091,7 @@ rcv:
        /* Check/update node state before receiving */
        if (unlikely(skb)) {
                if (unlikely(skb_linearize(skb)))
-                       goto discard;
+                       goto out_node_put;
                tipc_node_write_lock(n);
                if (tipc_node_check_state(n, skb, bearer_id, &xmitq)) {
                        if (le->link) {
@@ -2119,6 +2120,7 @@ rcv:
        if (!skb_queue_empty(&xmitq))
                tipc_bearer_xmit(net, bearer_id, &xmitq, &le->maddr, n);
 
+out_node_put:
        tipc_node_put(n);
 discard:
        kfree_skb(skb);
index 00e782335cb0740daa172f0c1835bcc3285ba46b..25bf72ee6cad070804f26ab353b5192a8ebbf923 100644 (file)
@@ -115,8 +115,10 @@ int x25_lapb_receive_frame(struct sk_buff *skb, struct net_device *dev,
                goto drop;
        }
 
-       if (!pskb_may_pull(skb, 1))
+       if (!pskb_may_pull(skb, 1)) {
+               x25_neigh_put(nb);
                return 0;
+       }
 
        switch (skb->data[0]) {
 
index cc86bf6566e42aa4326c45f34d10592041133510..9894693f3be17817345afd206e277d4e9421f41f 100644 (file)
@@ -418,7 +418,7 @@ static int mdpy_mmap(struct mdev_device *mdev, struct vm_area_struct *vma)
                return -EINVAL;
 
        return remap_vmalloc_range_partial(vma, vma->vm_start,
-                                          mdev_state->memblk,
+                                          mdev_state->memblk, 0,
                                           vma->vm_end - vma->vm_start);
 }
 
index 97547108ee7fdb8b20f55280db7d6bd17e1e60f1..4b799737722c89f670d763bef0146685fb333b96 100644 (file)
@@ -309,7 +309,7 @@ define rule_dtc
 endef
 
 $(obj)/%.dt.yaml: $(src)/%.dts $(DTC) $(DT_TMP_SCHEMA) FORCE
-       $(call if_changed_rule,dtc)
+       $(call if_changed_rule,dtc,yaml)
 
 dtc-tmp = $(subst $(comma),_,$(dot-target).dts.tmp)
 
index d64c67b67e3c7b76073798f2959ee5ef41206f1b..eac40f0abd56a9f4700423664824da8a537bfd61 100755 (executable)
@@ -479,7 +479,7 @@ our $allocFunctions = qr{(?x:
                (?:kv|k|v)[czm]alloc(?:_node|_array)? |
                kstrdup(?:_const)? |
                kmemdup(?:_nul)?) |
-       (?:\w+)?alloc_skb(?:ip_align)? |
+       (?:\w+)?alloc_skb(?:_ip_align)? |
                                # dev_alloc_skb/netdev_alloc_skb, et al
        dma_alloc_coherent
 )};
index e0e39826dae90ab735d1510e882bd32a9536e005..eee5b7f3a092ae4ac46bcdf92ffe8bb3c643aafd 100755 (executable)
@@ -7,6 +7,9 @@ myname=${0##*/}
 # If no prefix forced, use the default CONFIG_
 CONFIG_="${CONFIG_-CONFIG_}"
 
+# We use an uncommon delimiter for sed substitutions
+SED_DELIM=$(echo -en "\001")
+
 usage() {
        cat >&2 <<EOL
 Manipulate options in a .config file from the command line.
@@ -83,7 +86,7 @@ txt_subst() {
        local infile="$3"
        local tmpfile="$infile.swp"
 
-       sed -e "s:$before:$after:" "$infile" >"$tmpfile"
+       sed -e "s$SED_DELIM$before$SED_DELIM$after$SED_DELIM" "$infile" >"$tmpfile"
        # replace original file with the edited one
        mv "$tmpfile" "$infile"
 }
index 86a632bf4d50a9bc70bd2250a57b45600fb0e52a..7e3ae4534df9164cb57d69a19f29f006ad3a218c 100644 (file)
@@ -641,8 +641,18 @@ static void hda_jackpoll_work(struct work_struct *work)
        struct hda_codec *codec =
                container_of(work, struct hda_codec, jackpoll_work.work);
 
-       snd_hda_jack_set_dirty_all(codec);
-       snd_hda_jack_poll_all(codec);
+       /* for non-polling trigger: we need nothing if already powered on */
+       if (!codec->jackpoll_interval && snd_hdac_is_power_on(&codec->core))
+               return;
+
+       /* the power-up/down sequence triggers the runtime resume */
+       snd_hda_power_up_pm(codec);
+       /* update jacks manually if polling is required, too */
+       if (codec->jackpoll_interval) {
+               snd_hda_jack_set_dirty_all(codec);
+               snd_hda_jack_poll_all(codec);
+       }
+       snd_hda_power_down_pm(codec);
 
        if (!codec->jackpoll_interval)
                return;
@@ -2951,18 +2961,14 @@ static int hda_codec_runtime_resume(struct device *dev)
 static int hda_codec_force_resume(struct device *dev)
 {
        struct hda_codec *codec = dev_to_hda_codec(dev);
-       bool forced_resume = hda_codec_need_resume(codec);
        int ret;
 
-       /* The get/put pair below enforces the runtime resume even if the
-        * device hasn't been used at suspend time.  This trick is needed to
-        * update the jack state change during the sleep.
-        */
-       if (forced_resume)
-               pm_runtime_get_noresume(dev);
        ret = pm_runtime_force_resume(dev);
-       if (forced_resume)
-               pm_runtime_put(dev);
+       /* schedule jackpoll work for jack detection update */
+       if (codec->jackpoll_interval ||
+           (pm_runtime_suspended(dev) && hda_codec_need_resume(codec)))
+               schedule_delayed_work(&codec->jackpoll_work,
+                                     codec->jackpoll_interval);
        return ret;
 }
 
index a5fab12defde2a648c469c45fdcc05f6f06bdffa..457a2c0654856ca932da2b58a16b4eac2b88ec42 100644 (file)
@@ -1004,7 +1004,8 @@ static void __azx_runtime_resume(struct azx *chip, bool from_rt)
 
        if (status && from_rt) {
                list_for_each_codec(codec, &chip->bus)
-                       if (status & (1 << codec->addr))
+                       if (!codec->relaxed_resume &&
+                           (status & (1 << codec->addr)))
                                schedule_delayed_work(&codec->jackpoll_work,
                                                      codec->jackpoll_interval);
        }
@@ -1044,9 +1045,7 @@ static int azx_suspend(struct device *dev)
 static int azx_resume(struct device *dev)
 {
        struct snd_card *card = dev_get_drvdata(dev);
-       struct hda_codec *codec;
        struct azx *chip;
-       bool forced_resume = false;
 
        if (!azx_is_pm_ready(card))
                return 0;
@@ -1058,19 +1057,7 @@ static int azx_resume(struct device *dev)
        if (azx_acquire_irq(chip, 1) < 0)
                return -EIO;
 
-       /* check for the forced resume */
-       list_for_each_codec(codec, &chip->bus) {
-               if (hda_codec_need_resume(codec)) {
-                       forced_resume = true;
-                       break;
-               }
-       }
-
-       if (forced_resume)
-               pm_runtime_get_noresume(dev);
        pm_runtime_force_resume(dev);
-       if (forced_resume)
-               pm_runtime_put(dev);
        snd_power_change_state(card, SNDRV_CTL_POWER_D0);
 
        trace_azx_resume(chip);
@@ -2092,7 +2079,6 @@ static void pcm_mmap_prepare(struct snd_pcm_substream *substream,
  * should be ignored from the beginning.
  */
 static const struct snd_pci_quirk driver_blacklist[] = {
-       SND_PCI_QUIRK(0x1043, 0x874f, "ASUS ROG Zenith II / Strix", 0),
        SND_PCI_QUIRK(0x1462, 0xcb59, "MSI TRX40 Creator", 0),
        SND_PCI_QUIRK(0x1462, 0xcb60, "MSI TRX40", 0),
        {}
index bb287a916dae0c8668ff09989e94ab2c4da1cef6..4eff16053bd5556177cd2bc5b3aefda6ec07659e 100644 (file)
@@ -38,6 +38,10 @@ static bool static_hdmi_pcm;
 module_param(static_hdmi_pcm, bool, 0644);
 MODULE_PARM_DESC(static_hdmi_pcm, "Don't restrict PCM parameters per ELD info");
 
+static bool enable_acomp = true;
+module_param(enable_acomp, bool, 0444);
+MODULE_PARM_DESC(enable_acomp, "Enable audio component binding (default=yes)");
+
 struct hdmi_spec_per_cvt {
        hda_nid_t cvt_nid;
        int assigned;
@@ -2505,6 +2509,11 @@ static void generic_acomp_init(struct hda_codec *codec,
 {
        struct hdmi_spec *spec = codec->spec;
 
+       if (!enable_acomp) {
+               codec_info(codec, "audio component disabled by module option\n");
+               return;
+       }
+
        spec->port2pin = port2pin;
        setup_drm_audio_ops(codec, ops);
        if (!snd_hdac_acomp_init(&codec->bus->core, &spec->drm_audio_ops,
index dc5557d79c43e079dbeb42b90ca8a96882f1d79e..c1a85c8f7b69cb8d4d807ff30ea8eba542d0639e 100644 (file)
@@ -377,6 +377,7 @@ static void alc_fill_eapd_coef(struct hda_codec *codec)
        case 0x10ec0233:
        case 0x10ec0235:
        case 0x10ec0236:
+       case 0x10ec0245:
        case 0x10ec0255:
        case 0x10ec0256:
        case 0x10ec0257:
@@ -797,9 +798,11 @@ static void alc_ssid_check(struct hda_codec *codec, const hda_nid_t *ports)
 {
        if (!alc_subsystem_id(codec, ports)) {
                struct alc_spec *spec = codec->spec;
-               codec_dbg(codec,
-                         "realtek: Enable default setup for auto mode as fallback\n");
-               spec->init_amp = ALC_INIT_DEFAULT;
+               if (spec->init_amp == ALC_INIT_UNDEFINED) {
+                       codec_dbg(codec,
+                                 "realtek: Enable default setup for auto mode as fallback\n");
+                       spec->init_amp = ALC_INIT_DEFAULT;
+               }
        }
 }
 
@@ -8196,6 +8199,7 @@ static int patch_alc269(struct hda_codec *codec)
                spec->gen.mixer_nid = 0;
                break;
        case 0x10ec0215:
+       case 0x10ec0245:
        case 0x10ec0285:
        case 0x10ec0289:
                spec->codec_variant = ALC269_TYPE_ALC215;
@@ -9457,6 +9461,7 @@ static const struct hda_device_id snd_hda_id_realtek[] = {
        HDA_CODEC_ENTRY(0x10ec0234, "ALC234", patch_alc269),
        HDA_CODEC_ENTRY(0x10ec0235, "ALC233", patch_alc269),
        HDA_CODEC_ENTRY(0x10ec0236, "ALC236", patch_alc269),
+       HDA_CODEC_ENTRY(0x10ec0245, "ALC245", patch_alc269),
        HDA_CODEC_ENTRY(0x10ec0255, "ALC255", patch_alc269),
        HDA_CODEC_ENTRY(0x10ec0256, "ALC256", patch_alc269),
        HDA_CODEC_ENTRY(0x10ec0257, "ALC257", patch_alc269),
index 024a7ee54cd5a6a36adae4a1326cee69330e49ca..e499c00e0c66a036acea52018756a11d1aaa6bee 100644 (file)
@@ -89,9 +89,9 @@ static int acp3x_5682_init(struct snd_soc_pcm_runtime *rtd)
        }
 
        snd_jack_set_key(pco_jack.jack, SND_JACK_BTN_0, KEY_PLAYPAUSE);
-       snd_jack_set_key(pco_jack.jack, SND_JACK_BTN_1, KEY_VOLUMEUP);
-       snd_jack_set_key(pco_jack.jack, SND_JACK_BTN_2, KEY_VOLUMEDOWN);
-       snd_jack_set_key(pco_jack.jack, SND_JACK_BTN_3, KEY_VOICECOMMAND);
+       snd_jack_set_key(pco_jack.jack, SND_JACK_BTN_1, KEY_VOICECOMMAND);
+       snd_jack_set_key(pco_jack.jack, SND_JACK_BTN_2, KEY_VOLUMEUP);
+       snd_jack_set_key(pco_jack.jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN);
 
        ret = snd_soc_component_set_jack(component, &pco_jack, NULL);
        if (ret) {
index e6a0c5d05fa5e458340b4f04c425c868babdbfe2..e60e0b6a689cdb2ca44e021f0478e308c7e75f08 100644 (file)
@@ -1525,6 +1525,7 @@ config SND_SOC_WM8804_SPI
 
 config SND_SOC_WM8900
        tristate
+       depends on SND_SOC_I2C_AND_SPI
 
 config SND_SOC_WM8903
        tristate "Wolfson Microelectronics WM8903 CODEC"
@@ -1576,6 +1577,7 @@ config SND_SOC_WM8985
 
 config SND_SOC_WM8988
        tristate
+       depends on SND_SOC_I2C_AND_SPI
 
 config SND_SOC_WM8990
        tristate
@@ -1594,6 +1596,7 @@ config SND_SOC_WM8994
 
 config SND_SOC_WM8995
        tristate
+       depends on SND_SOC_I2C_AND_SPI
 
 config SND_SOC_WM8996
        tristate
index fba9b749839ded0a2684075d4ccdeda6c521584e..f26b77faed5993730b0890a2f5b7069fabb65649 100644 (file)
@@ -142,14 +142,14 @@ static struct hdac_hdmi_pcm *
 hdac_hdmi_get_pcm_from_cvt(struct hdac_hdmi_priv *hdmi,
                           struct hdac_hdmi_cvt *cvt)
 {
-       struct hdac_hdmi_pcm *pcm = NULL;
+       struct hdac_hdmi_pcm *pcm;
 
        list_for_each_entry(pcm, &hdmi->pcm_list, head) {
                if (pcm->cvt == cvt)
-                       break;
+                       return pcm;
        }
 
-       return pcm;
+       return NULL;
 }
 
 static void hdac_hdmi_jack_report(struct hdac_hdmi_pcm *pcm,
index 40de9d7811d1fe29c45616b1fe24d05be16af4c8..a448d2a2918a95a3cca9e24576817033e05fe908 100644 (file)
@@ -1903,7 +1903,6 @@ const struct soc_enum madera_isrc_fsh[] = {
                              MADERA_ISRC4_FSH_SHIFT, 0xf,
                              MADERA_RATE_ENUM_SIZE,
                              madera_rate_text, madera_rate_val),
-
 };
 EXPORT_SYMBOL_GPL(madera_isrc_fsh);
 
@@ -1924,7 +1923,6 @@ const struct soc_enum madera_isrc_fsl[] = {
                              MADERA_ISRC4_FSL_SHIFT, 0xf,
                              MADERA_RATE_ENUM_SIZE,
                              madera_rate_text, madera_rate_val),
-
 };
 EXPORT_SYMBOL_GPL(madera_isrc_fsl);
 
@@ -1938,7 +1936,6 @@ const struct soc_enum madera_asrc1_rate[] = {
                              MADERA_ASYNC_RATE_ENUM_SIZE,
                              madera_rate_text + MADERA_SYNC_RATE_ENUM_SIZE,
                              madera_rate_val + MADERA_SYNC_RATE_ENUM_SIZE),
-
 };
 EXPORT_SYMBOL_GPL(madera_asrc1_rate);
 
@@ -1964,7 +1961,6 @@ const struct soc_enum madera_asrc2_rate[] = {
                              MADERA_ASYNC_RATE_ENUM_SIZE,
                              madera_rate_text + MADERA_SYNC_RATE_ENUM_SIZE,
                              madera_rate_val + MADERA_SYNC_RATE_ENUM_SIZE),
-
 };
 EXPORT_SYMBOL_GPL(madera_asrc2_rate);
 
index d5130193b4a2f9ba37b5502bac75b3e5a5c2f4bc..e8a8bf7b4ffed041e6e1b48430fb0702a9a74fa8 100644 (file)
@@ -1653,6 +1653,40 @@ static int sgtl5000_i2c_probe(struct i2c_client *client,
                dev_err(&client->dev,
                        "Error %d initializing CHIP_CLK_CTRL\n", ret);
 
+       /* Mute everything to avoid pop from the following power-up */
+       ret = regmap_write(sgtl5000->regmap, SGTL5000_CHIP_ANA_CTRL,
+                          SGTL5000_CHIP_ANA_CTRL_DEFAULT);
+       if (ret) {
+               dev_err(&client->dev,
+                       "Error %d muting outputs via CHIP_ANA_CTRL\n", ret);
+               goto disable_clk;
+       }
+
+       /*
+        * If VAG is powered-on (e.g. from previous boot), it would be disabled
+        * by the write to ANA_POWER in later steps of the probe code. This
+        * may create a loud pop even with all outputs muted. The proper way
+        * to circumvent this is disabling the bit first and waiting the proper
+        * cool-down time.
+        */
+       ret = regmap_read(sgtl5000->regmap, SGTL5000_CHIP_ANA_POWER, &value);
+       if (ret) {
+               dev_err(&client->dev, "Failed to read ANA_POWER: %d\n", ret);
+               goto disable_clk;
+       }
+       if (value & SGTL5000_VAG_POWERUP) {
+               ret = regmap_update_bits(sgtl5000->regmap,
+                                        SGTL5000_CHIP_ANA_POWER,
+                                        SGTL5000_VAG_POWERUP,
+                                        0);
+               if (ret) {
+                       dev_err(&client->dev, "Error %d disabling VAG\n", ret);
+                       goto disable_clk;
+               }
+
+               msleep(SGTL5000_VAG_POWERDOWN_DELAY);
+       }
+
        /* Follow section 2.2.1.1 of AN3663 */
        ana_pwr = SGTL5000_ANA_POWER_DEFAULT;
        if (sgtl5000->num_supplies <= VDDD) {
index a4bf4bca95bf7681bfb9f8b38dada3aa368d3c4e..56ec5863f25071ef2f78fd5c018f5b05f27c1e3b 100644 (file)
 /*
  * SGTL5000_CHIP_ANA_CTRL
  */
+#define SGTL5000_CHIP_ANA_CTRL_DEFAULT         0x0133
 #define SGTL5000_LINE_OUT_MUTE                 0x0100
 #define SGTL5000_HP_SEL_MASK                   0x0040
 #define SGTL5000_HP_SEL_SHIFT                  6
index 1554631cb397b1bf75f50cb520141636e1db6461..5b7f9fcf6cbf3b2781f0f38df83f37cfb7efb110 100644 (file)
@@ -820,8 +820,10 @@ static int tas571x_i2c_probe(struct i2c_client *client,
 
        priv->regmap = devm_regmap_init(dev, NULL, client,
                                        priv->chip->regmap_config);
-       if (IS_ERR(priv->regmap))
-               return PTR_ERR(priv->regmap);
+       if (IS_ERR(priv->regmap)) {
+               ret = PTR_ERR(priv->regmap);
+               goto disable_regs;
+       }
 
        priv->pdn_gpio = devm_gpiod_get_optional(dev, "pdn", GPIOD_OUT_LOW);
        if (IS_ERR(priv->pdn_gpio)) {
@@ -845,7 +847,7 @@ static int tas571x_i2c_probe(struct i2c_client *client,
 
        ret = regmap_write(priv->regmap, TAS571X_OSC_TRIM_REG, 0);
        if (ret)
-               return ret;
+               goto disable_regs;
 
        usleep_range(50000, 60000);
 
@@ -861,12 +863,20 @@ static int tas571x_i2c_probe(struct i2c_client *client,
                 */
                ret = regmap_update_bits(priv->regmap, TAS571X_MVOL_REG, 1, 0);
                if (ret)
-                       return ret;
+                       goto disable_regs;
        }
 
-       return devm_snd_soc_register_component(&client->dev,
+       ret = devm_snd_soc_register_component(&client->dev,
                                      &priv->component_driver,
                                      &tas571x_dai, 1);
+       if (ret)
+               goto disable_regs;
+
+       return ret;
+
+disable_regs:
+       regulator_bulk_disable(priv->chip->num_supply_names, priv->supplies);
+       return ret;
 }
 
 static int tas571x_i2c_remove(struct i2c_client *client)
index 55112c1bba5e74458d4a922d519a8e7162b38f72..6cf0f6612bdaf44685a20f7b99847e4f45675b44 100644 (file)
@@ -860,8 +860,7 @@ static int wm8960_hw_params(struct snd_pcm_substream *substream,
 
        wm8960->is_stream_in_use[tx] = true;
 
-       if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_ON &&
-           !wm8960->is_stream_in_use[!tx])
+       if (!wm8960->is_stream_in_use[!tx])
                return wm8960_configure_clocking(component);
 
        return 0;
index f2d6f2f81f14e15535189755e4c82b4553772230..d39d479e23786eb814d9adaedaeeb8cd37f20d39 100644 (file)
@@ -394,6 +394,7 @@ static struct sdw_dpn_prop wsa_sink_dpn_prop[WSA881X_MAX_SWR_PORTS] = {
                .min_ch = 1,
                .max_ch = 1,
                .simple_ch_prep_sm = true,
+               .read_only_wordlength = true,
        }, {
                /* COMP */
                .num = 2,
@@ -401,6 +402,7 @@ static struct sdw_dpn_prop wsa_sink_dpn_prop[WSA881X_MAX_SWR_PORTS] = {
                .min_ch = 1,
                .max_ch = 1,
                .simple_ch_prep_sm = true,
+               .read_only_wordlength = true,
        }, {
                /* BOOST */
                .num = 3,
@@ -408,6 +410,7 @@ static struct sdw_dpn_prop wsa_sink_dpn_prop[WSA881X_MAX_SWR_PORTS] = {
                .min_ch = 1,
                .max_ch = 1,
                .simple_ch_prep_sm = true,
+               .read_only_wordlength = true,
        }, {
                /* VISENSE */
                .num = 4,
@@ -415,6 +418,7 @@ static struct sdw_dpn_prop wsa_sink_dpn_prop[WSA881X_MAX_SWR_PORTS] = {
                .min_ch = 1,
                .max_ch = 1,
                .simple_ch_prep_sm = true,
+               .read_only_wordlength = true,
        }
 };
 
index bcedec6c6117cbae801548bf87607e6b0b26e8a1..7d85bd5aff9f0cb2f8d307940317f8dfbef72150 100644 (file)
@@ -113,14 +113,6 @@ static const struct snd_soc_acpi_adr_device rt1308_1_adr[] = {
        }
 };
 
-static const struct snd_soc_acpi_adr_device rt1308_2_adr[] = {
-       {
-               .adr = 0x000210025D130800,
-               .num_endpoints = 1,
-               .endpoints = &single_endpoint,
-       }
-};
-
 static const struct snd_soc_acpi_adr_device rt1308_1_group1_adr[] = {
        {
                .adr = 0x000110025D130800,
index ef8500349f2f2f335787cb9f63b20fc9848cda83..16ec9f382b0ffd9e45cadb32e47888e81f13cd7e 100644 (file)
@@ -87,14 +87,6 @@ static const struct snd_soc_acpi_adr_device rt1308_1_adr[] = {
        }
 };
 
-static const struct snd_soc_acpi_adr_device rt1308_2_adr[] = {
-       {
-               .adr = 0x000210025D130800,
-               .num_endpoints = 1,
-               .endpoints = &single_endpoint,
-       }
-};
-
 static const struct snd_soc_acpi_adr_device rt1308_1_group1_adr[] = {
        {
                .adr = 0x000110025D130800,
index af46845f4ef2ba184f1d85318cf1a3b17015dce1..89f7f64747cd0a562e3915fbf3918947b37d671e 100644 (file)
@@ -338,8 +338,10 @@ static int axg_card_add_link(struct snd_soc_card *card, struct device_node *np,
 
        if (axg_card_cpu_is_tdm_iface(dai_link->cpus->of_node))
                ret = axg_card_parse_tdm(card, np, index);
-       else if (axg_card_cpu_is_codec(dai_link->cpus->of_node))
+       else if (axg_card_cpu_is_codec(dai_link->cpus->of_node)) {
                dai_link->params = &codec_params;
+               dai_link->no_pcm = 0; /* link is not a DPCM BE */
+       }
 
        return ret;
 }
index 7b01dcb73e5e1c00b1082347cb12e9f4da275b44..4abf7efb7eacc54442ad7c3a662050d427086bbc 100644 (file)
@@ -108,8 +108,10 @@ static int gx_card_add_link(struct snd_soc_card *card, struct device_node *np,
                ret = gx_card_parse_i2s(card, np, index);
 
        /* Or apply codec to codec params if necessary */
-       else if (gx_card_cpu_identify(dai_link->cpus, "CODEC CTRL"))
+       else if (gx_card_cpu_identify(dai_link->cpus, "CODEC CTRL")) {
                dai_link->params = &codec_params;
+               dai_link->no_pcm = 0; /* link is not a DPCM BE */
+       }
 
        return ret;
 }
index d55e3ad96716081d679e21d100a881fc5eb8fc83..287ad2aa27f373154733b7de83a2a69af7050068 100644 (file)
@@ -116,10 +116,8 @@ static int apq8096_platform_probe(struct platform_device *pdev)
        card->dev = dev;
        dev_set_drvdata(dev, card);
        ret = qcom_snd_parse_of(card);
-       if (ret) {
-               dev_err(dev, "Error parsing OF data\n");
+       if (ret)
                goto err;
-       }
 
        apq8096_add_be_ops(card);
        ret = snd_soc_register_card(card);
index c1a7624eaf175f7856401e40b89b7a73d50b6255..2a5302f1db98aa9b5ad1a8604c723a2f9c36c682 100644 (file)
@@ -902,6 +902,8 @@ static struct snd_soc_dai_driver q6afe_dais[] = {
                                 SNDRV_PCM_RATE_16000,
                        .formats = SNDRV_PCM_FMTBIT_S16_LE |
                                   SNDRV_PCM_FMTBIT_S24_LE,
+                       .channels_min = 1,
+                       .channels_max = 8,
                        .rate_min =     8000,
                        .rate_max =     48000,
                },
@@ -917,6 +919,8 @@ static struct snd_soc_dai_driver q6afe_dais[] = {
                                 SNDRV_PCM_RATE_16000,
                        .formats = SNDRV_PCM_FMTBIT_S16_LE |
                                   SNDRV_PCM_FMTBIT_S24_LE,
+                       .channels_min = 1,
+                       .channels_max = 8,
                        .rate_min =     8000,
                        .rate_max =     48000,
                },
@@ -931,6 +935,8 @@ static struct snd_soc_dai_driver q6afe_dais[] = {
                        .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
                                 SNDRV_PCM_RATE_16000,
                        .formats = SNDRV_PCM_FMTBIT_S16_LE,
+                       .channels_min = 1,
+                       .channels_max = 8,
                        .rate_min =     8000,
                        .rate_max =     48000,
                },
@@ -946,6 +952,8 @@ static struct snd_soc_dai_driver q6afe_dais[] = {
                                 SNDRV_PCM_RATE_16000,
                        .formats = SNDRV_PCM_FMTBIT_S16_LE |
                                   SNDRV_PCM_FMTBIT_S24_LE,
+                       .channels_min = 1,
+                       .channels_max = 8,
                        .rate_min =     8000,
                        .rate_max =     48000,
                },
@@ -960,6 +968,8 @@ static struct snd_soc_dai_driver q6afe_dais[] = {
                        .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
                                 SNDRV_PCM_RATE_16000,
                        .formats = SNDRV_PCM_FMTBIT_S16_LE,
+                       .channels_min = 1,
+                       .channels_max = 8,
                        .rate_min =     8000,
                        .rate_max =     48000,
                },
@@ -975,6 +985,8 @@ static struct snd_soc_dai_driver q6afe_dais[] = {
                                 SNDRV_PCM_RATE_16000,
                        .formats = SNDRV_PCM_FMTBIT_S16_LE |
                                   SNDRV_PCM_FMTBIT_S24_LE,
+                       .channels_min = 1,
+                       .channels_max = 8,
                        .rate_min =     8000,
                        .rate_max =     48000,
                },
@@ -989,6 +1001,8 @@ static struct snd_soc_dai_driver q6afe_dais[] = {
                        .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
                                 SNDRV_PCM_RATE_16000,
                        .formats = SNDRV_PCM_FMTBIT_S16_LE,
+                       .channels_min = 1,
+                       .channels_max = 8,
                        .rate_min =     8000,
                        .rate_max =     48000,
                },
@@ -1004,6 +1018,8 @@ static struct snd_soc_dai_driver q6afe_dais[] = {
                                 SNDRV_PCM_RATE_16000,
                        .formats = SNDRV_PCM_FMTBIT_S16_LE |
                                   SNDRV_PCM_FMTBIT_S24_LE,
+                       .channels_min = 1,
+                       .channels_max = 8,
                        .rate_min =     8000,
                        .rate_max =     48000,
                },
index b2de65c7f95cb73248ed2436442472956abfe862..68e9388ff46f1b8b9b7d7995b0e6bcdb880fb2d2 100644 (file)
@@ -559,10 +559,8 @@ static int sdm845_snd_platform_probe(struct platform_device *pdev)
        card->dev = dev;
        dev_set_drvdata(dev, card);
        ret = qcom_snd_parse_of(card);
-       if (ret) {
-               dev_err(dev, "Error parsing OF data\n");
+       if (ret)
                goto parse_dt_fail;
-       }
 
        data->card = card;
        snd_soc_card_set_drvdata(card, data);
index 35888784829388bac9417c1e541911b2a92f7dfc..5e95c30fb2bacc936c9e3c25ac9588f5e8ac2f81 100644 (file)
@@ -656,60 +656,6 @@ void s3c_i2sv2_cleanup(struct snd_soc_dai *dai,
 }
 EXPORT_SYMBOL_GPL(s3c_i2sv2_cleanup);
 
-#ifdef CONFIG_PM
-static int s3c2412_i2s_suspend(struct snd_soc_dai *dai)
-{
-       struct s3c_i2sv2_info *i2s = to_info(dai);
-       u32 iismod;
-
-       if (dai->active) {
-               i2s->suspend_iismod = readl(i2s->regs + S3C2412_IISMOD);
-               i2s->suspend_iiscon = readl(i2s->regs + S3C2412_IISCON);
-               i2s->suspend_iispsr = readl(i2s->regs + S3C2412_IISPSR);
-
-               /* some basic suspend checks */
-
-               iismod = readl(i2s->regs + S3C2412_IISMOD);
-
-               if (iismod & S3C2412_IISCON_RXDMA_ACTIVE)
-                       pr_warn("%s: RXDMA active?\n", __func__);
-
-               if (iismod & S3C2412_IISCON_TXDMA_ACTIVE)
-                       pr_warn("%s: TXDMA active?\n", __func__);
-
-               if (iismod & S3C2412_IISCON_IIS_ACTIVE)
-                       pr_warn("%s: IIS active\n", __func__);
-       }
-
-       return 0;
-}
-
-static int s3c2412_i2s_resume(struct snd_soc_dai *dai)
-{
-       struct s3c_i2sv2_info *i2s = to_info(dai);
-
-       pr_info("dai_active %d, IISMOD %08x, IISCON %08x\n",
-               dai->active, i2s->suspend_iismod, i2s->suspend_iiscon);
-
-       if (dai->active) {
-               writel(i2s->suspend_iiscon, i2s->regs + S3C2412_IISCON);
-               writel(i2s->suspend_iismod, i2s->regs + S3C2412_IISMOD);
-               writel(i2s->suspend_iispsr, i2s->regs + S3C2412_IISPSR);
-
-               writel(S3C2412_IISFIC_RXFLUSH | S3C2412_IISFIC_TXFLUSH,
-                      i2s->regs + S3C2412_IISFIC);
-
-               ndelay(250);
-               writel(0x0, i2s->regs + S3C2412_IISFIC);
-       }
-
-       return 0;
-}
-#else
-#define s3c2412_i2s_suspend NULL
-#define s3c2412_i2s_resume  NULL
-#endif
-
 int s3c_i2sv2_register_component(struct device *dev, int id,
                           const struct snd_soc_component_driver *cmp_drv,
                           struct snd_soc_dai_driver *dai_drv)
@@ -727,9 +673,6 @@ int s3c_i2sv2_register_component(struct device *dev, int id,
        if (!ops->delay)
                ops->delay = s3c2412_i2s_delay;
 
-       dai_drv->suspend = s3c2412_i2s_suspend;
-       dai_drv->resume = s3c2412_i2s_resume;
-
        return devm_snd_soc_register_component(dev, cmp_drv, dai_drv, 1);
 }
 EXPORT_SYMBOL_GPL(s3c_i2sv2_register_component);
index 787a3f6e9f242235f581aec16c32e28b862d9903..b35d828c1cfe9b8ed6f46367ed2fbe485e5b7794 100644 (file)
@@ -117,6 +117,60 @@ static int s3c2412_i2s_hw_params(struct snd_pcm_substream *substream,
        return 0;
 }
 
+#ifdef CONFIG_PM
+static int s3c2412_i2s_suspend(struct snd_soc_component *component)
+{
+       struct s3c_i2sv2_info *i2s = snd_soc_component_get_drvdata(component);
+       u32 iismod;
+
+       if (component->active) {
+               i2s->suspend_iismod = readl(i2s->regs + S3C2412_IISMOD);
+               i2s->suspend_iiscon = readl(i2s->regs + S3C2412_IISCON);
+               i2s->suspend_iispsr = readl(i2s->regs + S3C2412_IISPSR);
+
+               /* some basic suspend checks */
+
+               iismod = readl(i2s->regs + S3C2412_IISMOD);
+
+               if (iismod & S3C2412_IISCON_RXDMA_ACTIVE)
+                       pr_warn("%s: RXDMA active?\n", __func__);
+
+               if (iismod & S3C2412_IISCON_TXDMA_ACTIVE)
+                       pr_warn("%s: TXDMA active?\n", __func__);
+
+               if (iismod & S3C2412_IISCON_IIS_ACTIVE)
+                       pr_warn("%s: IIS active\n", __func__);
+       }
+
+       return 0;
+}
+
+static int s3c2412_i2s_resume(struct snd_soc_component *component)
+{
+       struct s3c_i2sv2_info *i2s = snd_soc_component_get_drvdata(component);
+
+       pr_info("component_active %d, IISMOD %08x, IISCON %08x\n",
+               component->active, i2s->suspend_iismod, i2s->suspend_iiscon);
+
+       if (component->active) {
+               writel(i2s->suspend_iiscon, i2s->regs + S3C2412_IISCON);
+               writel(i2s->suspend_iismod, i2s->regs + S3C2412_IISMOD);
+               writel(i2s->suspend_iispsr, i2s->regs + S3C2412_IISPSR);
+
+               writel(S3C2412_IISFIC_RXFLUSH | S3C2412_IISFIC_TXFLUSH,
+                      i2s->regs + S3C2412_IISFIC);
+
+               ndelay(250);
+               writel(0x0, i2s->regs + S3C2412_IISFIC);
+       }
+
+       return 0;
+}
+#else
+#define s3c2412_i2s_suspend NULL
+#define s3c2412_i2s_resume  NULL
+#endif
+
 #define S3C2412_I2S_RATES \
        (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | SNDRV_PCM_RATE_16000 | \
        SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \
@@ -146,6 +200,8 @@ static struct snd_soc_dai_driver s3c2412_i2s_dai = {
 
 static const struct snd_soc_component_driver s3c2412_i2s_component = {
        .name           = "s3c2412-i2s",
+       .suspend        = s3c2412_i2s_suspend,
+       .resume         = s3c2412_i2s_resume,
 };
 
 static int s3c2412_iis_dev_probe(struct platform_device *pdev)
index fc5d089868dfc084cfa4e3234259a57402cd8d5e..4a7d3413917fc253e873e9f8f46bba6fa4ba63cf 100644 (file)
@@ -594,10 +594,16 @@ static int rsnd_ssi_stop(struct rsnd_mod *mod,
         * Capture:  It might not receave data. Do nothing
         */
        if (rsnd_io_is_play(io)) {
-               rsnd_mod_write(mod, SSICR, cr | EN);
+               rsnd_mod_write(mod, SSICR, cr | ssi->cr_en);
                rsnd_ssi_status_check(mod, DIRQ);
        }
 
+       /* In multi-SSI mode, stop is performed by setting ssi0129 in
+        * SSI_CONTROL to 0 (in rsnd_ssio_stop_gen2). Do nothing here.
+        */
+       if (rsnd_ssi_multi_slaves_runtime(io))
+               return 0;
+
        /*
         * disable SSI,
         * and, wait idle state
@@ -737,6 +743,9 @@ static void rsnd_ssi_parent_attach(struct rsnd_mod *mod,
        if (!rsnd_rdai_is_clk_master(rdai))
                return;
 
+       if (rsnd_ssi_is_multi_slave(mod, io))
+               return;
+
        switch (rsnd_mod_id(mod)) {
        case 1:
        case 2:
index f35d882118874c6868e14fe5a849dc15c7f3eb2f..9c7c3e7539c9347e2a045cad6ca167003524449e 100644 (file)
@@ -221,7 +221,7 @@ static int rsnd_ssiu_init_gen2(struct rsnd_mod *mod,
                        i;
 
                for_each_rsnd_mod_array(i, pos, io, rsnd_ssi_array) {
-                       shift   = (i * 4) + 16;
+                       shift   = (i * 4) + 20;
                        val     = (val & ~(0xF << shift)) |
                                rsnd_mod_id(pos) << shift;
                }
index 8f3cad8db89a4979a6ecefedb4e0972b73bc91af..31c41559034b9b29d8daeef299b470aaac1e3cff 100644 (file)
@@ -295,24 +295,17 @@ int snd_soc_dai_startup(struct snd_soc_dai *dai,
 {
        int ret = 0;
 
-       if (!dai->started[substream->stream] &&
-           dai->driver->ops->startup)
+       if (dai->driver->ops->startup)
                ret = dai->driver->ops->startup(substream, dai);
 
-       if (ret == 0)
-               dai->started[substream->stream] = 1;
-
        return ret;
 }
 
 void snd_soc_dai_shutdown(struct snd_soc_dai *dai,
                         struct snd_pcm_substream *substream)
 {
-       if (dai->started[substream->stream] &&
-           dai->driver->ops->shutdown)
+       if (dai->driver->ops->shutdown)
                dai->driver->ops->shutdown(substream, dai);
-
-       dai->started[substream->stream] = 0;
 }
 
 int snd_soc_dai_prepare(struct snd_soc_dai *dai,
index 679ed60d850ec6e00946c54ecc4c9aece98b1614..e2632841b321a2bdb47aff11fbe2f2493d808658 100644 (file)
@@ -423,7 +423,7 @@ static int dapm_kcontrol_data_alloc(struct snd_soc_dapm_widget *widget,
 
                        memset(&template, 0, sizeof(template));
                        template.reg = e->reg;
-                       template.mask = e->mask << e->shift_l;
+                       template.mask = e->mask;
                        template.shift = e->shift_l;
                        template.off_val = snd_soc_enum_item_to_val(e, 0);
                        template.on_val = template.off_val;
@@ -546,8 +546,22 @@ static bool dapm_kcontrol_set_value(const struct snd_kcontrol *kcontrol,
        if (data->value == value)
                return false;
 
-       if (data->widget)
-               data->widget->on_val = value;
+       if (data->widget) {
+               switch (dapm_kcontrol_get_wlist(kcontrol)->widgets[0]->id) {
+               case snd_soc_dapm_switch:
+               case snd_soc_dapm_mixer:
+               case snd_soc_dapm_mixer_named_ctl:
+                       data->widget->on_val = value & data->widget->mask;
+                       break;
+               case snd_soc_dapm_demux:
+               case snd_soc_dapm_mux:
+                       data->widget->on_val = value >> data->widget->shift;
+                       break;
+               default:
+                       data->widget->on_val = value;
+                       break;
+               }
+       }
 
        data->value = value;
 
@@ -4165,6 +4179,8 @@ snd_soc_dapm_new_dai(struct snd_soc_card *card,
        w = snd_soc_dapm_new_control_unlocked(&card->dapm, &template);
        if (IS_ERR(w)) {
                ret = PTR_ERR(w);
+               dev_err(rtd->dev, "ASoC: Failed to create %s widget: %d\n",
+                       link_name, ret);
                goto outfree_kcontrol_news;
        }
 
@@ -4283,52 +4299,58 @@ int snd_soc_dapm_link_dai_widgets(struct snd_soc_card *card)
        return 0;
 }
 
-static void dapm_add_valid_dai_widget(struct snd_soc_card *card,
-                                     struct snd_soc_pcm_runtime *rtd,
-                                     struct snd_soc_dai *codec_dai,
-                                     struct snd_soc_dai *cpu_dai)
+static void dapm_connect_dai_routes(struct snd_soc_dapm_context *dapm,
+                                   struct snd_soc_dai *src_dai,
+                                   struct snd_soc_dapm_widget *src,
+                                   struct snd_soc_dapm_widget *dai,
+                                   struct snd_soc_dai *sink_dai,
+                                   struct snd_soc_dapm_widget *sink)
 {
-       struct snd_soc_dapm_widget *playback = NULL, *capture = NULL;
-       struct snd_soc_dapm_widget *codec, *playback_cpu, *capture_cpu;
+       dev_dbg(dapm->dev, "connected DAI link %s:%s -> %s:%s\n",
+               src_dai->component->name, src->name,
+               sink_dai->component->name, sink->name);
+
+       if (dai) {
+               snd_soc_dapm_add_path(dapm, src, dai, NULL, NULL);
+               src = dai;
+       }
+
+       snd_soc_dapm_add_path(dapm, src, sink, NULL, NULL);
+}
+
+static void dapm_connect_dai_pair(struct snd_soc_card *card,
+                                 struct snd_soc_pcm_runtime *rtd,
+                                 struct snd_soc_dai *codec_dai,
+                                 struct snd_soc_dai *cpu_dai)
+{
+       struct snd_soc_dai_link *dai_link = rtd->dai_link;
+       struct snd_soc_dapm_widget *dai, *codec, *playback_cpu, *capture_cpu;
        struct snd_pcm_substream *substream;
        struct snd_pcm_str *streams = rtd->pcm->streams;
 
-       if (rtd->dai_link->params) {
+       if (dai_link->params) {
                playback_cpu = cpu_dai->capture_widget;
                capture_cpu = cpu_dai->playback_widget;
        } else {
-               playback = cpu_dai->playback_widget;
-               capture = cpu_dai->capture_widget;
-               playback_cpu = playback;
-               capture_cpu = capture;
+               playback_cpu = cpu_dai->playback_widget;
+               capture_cpu = cpu_dai->capture_widget;
        }
 
        /* connect BE DAI playback if widgets are valid */
        codec = codec_dai->playback_widget;
 
        if (playback_cpu && codec) {
-               if (!playback) {
+               if (dai_link->params && !dai_link->playback_widget) {
                        substream = streams[SNDRV_PCM_STREAM_PLAYBACK].substream;
-                       playback = snd_soc_dapm_new_dai(card, substream,
-                                                       "playback");
-                       if (IS_ERR(playback)) {
-                               dev_err(rtd->dev,
-                                       "ASoC: Failed to create DAI %s: %ld\n",
-                                       codec_dai->name,
-                                       PTR_ERR(playback));
+                       dai = snd_soc_dapm_new_dai(card, substream, "playback");
+                       if (IS_ERR(dai))
                                goto capture;
-                       }
-
-                       snd_soc_dapm_add_path(&card->dapm, playback_cpu,
-                                             playback, NULL, NULL);
+                       dai_link->playback_widget = dai;
                }
 
-               dev_dbg(rtd->dev, "connected DAI link %s:%s -> %s:%s\n",
-                       cpu_dai->component->name, playback_cpu->name,
-                       codec_dai->component->name, codec->name);
-
-               snd_soc_dapm_add_path(&card->dapm, playback, codec,
-                                     NULL, NULL);
+               dapm_connect_dai_routes(&card->dapm, cpu_dai, playback_cpu,
+                                       dai_link->playback_widget,
+                                       codec_dai, codec);
        }
 
 capture:
@@ -4336,50 +4358,18 @@ capture:
        codec = codec_dai->capture_widget;
 
        if (codec && capture_cpu) {
-               if (!capture) {
+               if (dai_link->params && !dai_link->capture_widget) {
                        substream = streams[SNDRV_PCM_STREAM_CAPTURE].substream;
-                       capture = snd_soc_dapm_new_dai(card, substream,
-                                                      "capture");
-                       if (IS_ERR(capture)) {
-                               dev_err(rtd->dev,
-                                       "ASoC: Failed to create DAI %s: %ld\n",
-                                       codec_dai->name,
-                                       PTR_ERR(capture));
+                       dai = snd_soc_dapm_new_dai(card, substream, "capture");
+                       if (IS_ERR(dai))
                                return;
-                       }
-
-                       snd_soc_dapm_add_path(&card->dapm, capture,
-                                             capture_cpu, NULL, NULL);
+                       dai_link->capture_widget = dai;
                }
 
-               dev_dbg(rtd->dev, "connected DAI link %s:%s -> %s:%s\n",
-                       codec_dai->component->name, codec->name,
-                       cpu_dai->component->name, capture_cpu->name);
-
-               snd_soc_dapm_add_path(&card->dapm, codec, capture,
-                                     NULL, NULL);
-       }
-}
-
-static void dapm_connect_dai_link_widgets(struct snd_soc_card *card,
-                                         struct snd_soc_pcm_runtime *rtd)
-{
-       struct snd_soc_dai *codec_dai;
-       int i;
-
-       if (rtd->num_cpus == 1) {
-               for_each_rtd_codec_dais(rtd, i, codec_dai)
-                       dapm_add_valid_dai_widget(card, rtd, codec_dai,
-                                                 rtd->cpu_dais[0]);
-       } else if (rtd->num_codecs == rtd->num_cpus) {
-               for_each_rtd_codec_dais(rtd, i, codec_dai)
-                       dapm_add_valid_dai_widget(card, rtd, codec_dai,
-                                                 rtd->cpu_dais[i]);
-       } else {
-               dev_err(card->dev,
-                       "N cpus to M codecs link is not supported yet\n");
+               dapm_connect_dai_routes(&card->dapm, codec_dai, codec,
+                                       dai_link->capture_widget,
+                                       cpu_dai, capture_cpu);
        }
-
 }
 
 static void soc_dapm_dai_stream_event(struct snd_soc_dai *dai, int stream,
@@ -4422,6 +4412,8 @@ static void soc_dapm_dai_stream_event(struct snd_soc_dai *dai, int stream,
 void snd_soc_dapm_connect_dai_link_widgets(struct snd_soc_card *card)
 {
        struct snd_soc_pcm_runtime *rtd;
+       struct snd_soc_dai *codec_dai;
+       int i;
 
        /* for each BE DAI link... */
        for_each_card_rtds(card, rtd)  {
@@ -4432,7 +4424,18 @@ void snd_soc_dapm_connect_dai_link_widgets(struct snd_soc_card *card)
                if (rtd->dai_link->dynamic)
                        continue;
 
-               dapm_connect_dai_link_widgets(card, rtd);
+               if (rtd->num_cpus == 1) {
+                       for_each_rtd_codec_dais(rtd, i, codec_dai)
+                               dapm_connect_dai_pair(card, rtd, codec_dai,
+                                                     rtd->cpu_dais[0]);
+               } else if (rtd->num_codecs == rtd->num_cpus) {
+                       for_each_rtd_codec_dais(rtd, i, codec_dai)
+                               dapm_connect_dai_pair(card, rtd, codec_dai,
+                                                     rtd->cpu_dais[i]);
+               } else {
+                       dev_err(card->dev,
+                               "N cpus to M codecs link is not supported yet\n");
+               }
        }
 }
 
index 289aebc1552935b273463f579f3d4a865a4f409f..1f302de4405259afc43ef17d244975de4addd229 100644 (file)
@@ -2911,8 +2911,17 @@ int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num)
        int i;
 
        if (rtd->dai_link->dynamic || rtd->dai_link->no_pcm) {
-               playback = rtd->dai_link->dpcm_playback;
-               capture = rtd->dai_link->dpcm_capture;
+               cpu_dai = asoc_rtd_to_cpu(rtd, 0);
+               if (rtd->num_cpus > 1) {
+                       dev_err(rtd->dev,
+                               "DPCM doesn't support Multi CPU yet\n");
+                       return -EINVAL;
+               }
+
+               playback = rtd->dai_link->dpcm_playback &&
+                          snd_soc_dai_stream_valid(cpu_dai, SNDRV_PCM_STREAM_PLAYBACK);
+               capture = rtd->dai_link->dpcm_capture &&
+                         snd_soc_dai_stream_valid(cpu_dai, SNDRV_PCM_STREAM_CAPTURE);
        } else {
                /* Adapt stream for codec2codec links */
                int cpu_capture = rtd->dai_link->params ?
index 87f75edba3dc8454a80b7f6ece5253156e0d03d9..6df3b0d12d87d5355fe130497ab0e96fc082f75c 100644 (file)
@@ -894,7 +894,13 @@ static int soc_tplg_dmixer_create(struct soc_tplg *tplg, unsigned int count,
                }
 
                /* create any TLV data */
-               soc_tplg_create_tlv(tplg, &kc, &mc->hdr);
+               err = soc_tplg_create_tlv(tplg, &kc, &mc->hdr);
+               if (err < 0) {
+                       dev_err(tplg->dev, "ASoC: failed to create TLV %s\n",
+                               mc->hdr.name);
+                       kfree(sm);
+                       continue;
+               }
 
                /* pass control to driver for optional further init */
                err = soc_tplg_init_kcontrol(tplg, &kc,
@@ -1118,6 +1124,7 @@ static int soc_tplg_kcontrol_elems_load(struct soc_tplg *tplg,
        struct snd_soc_tplg_hdr *hdr)
 {
        struct snd_soc_tplg_ctl_hdr *control_hdr;
+       int ret;
        int i;
 
        if (tplg->pass != SOC_TPLG_PASS_MIXER) {
@@ -1146,25 +1153,30 @@ static int soc_tplg_kcontrol_elems_load(struct soc_tplg *tplg,
                case SND_SOC_TPLG_CTL_RANGE:
                case SND_SOC_TPLG_DAPM_CTL_VOLSW:
                case SND_SOC_TPLG_DAPM_CTL_PIN:
-                       soc_tplg_dmixer_create(tplg, 1,
-                                              le32_to_cpu(hdr->payload_size));
+                       ret = soc_tplg_dmixer_create(tplg, 1,
+                                       le32_to_cpu(hdr->payload_size));
                        break;
                case SND_SOC_TPLG_CTL_ENUM:
                case SND_SOC_TPLG_CTL_ENUM_VALUE:
                case SND_SOC_TPLG_DAPM_CTL_ENUM_DOUBLE:
                case SND_SOC_TPLG_DAPM_CTL_ENUM_VIRT:
                case SND_SOC_TPLG_DAPM_CTL_ENUM_VALUE:
-                       soc_tplg_denum_create(tplg, 1,
-                                             le32_to_cpu(hdr->payload_size));
+                       ret = soc_tplg_denum_create(tplg, 1,
+                                       le32_to_cpu(hdr->payload_size));
                        break;
                case SND_SOC_TPLG_CTL_BYTES:
-                       soc_tplg_dbytes_create(tplg, 1,
-                                              le32_to_cpu(hdr->payload_size));
+                       ret = soc_tplg_dbytes_create(tplg, 1,
+                                       le32_to_cpu(hdr->payload_size));
                        break;
                default:
                        soc_bind_err(tplg, control_hdr, i);
                        return -EINVAL;
                }
+               if (ret < 0) {
+                       dev_err(tplg->dev, "ASoC: invalid control\n");
+                       return ret;
+               }
+
        }
 
        return 0;
@@ -1272,7 +1284,9 @@ static int soc_tplg_dapm_graph_elems_load(struct soc_tplg *tplg,
                routes[i]->dobj.index = tplg->index;
                list_add(&routes[i]->dobj.list, &tplg->comp->dobj_list);
 
-               soc_tplg_add_route(tplg, routes[i]);
+               ret = soc_tplg_add_route(tplg, routes[i]);
+               if (ret < 0)
+                       break;
 
                /* add route, but keep going if some fail */
                snd_soc_dapm_add_routes(dapm, routes[i], 1);
@@ -1355,7 +1369,13 @@ static struct snd_kcontrol_new *soc_tplg_dapm_widget_dmixer_create(
                }
 
                /* create any TLV data */
-               soc_tplg_create_tlv(tplg, &kc[i], &mc->hdr);
+               err = soc_tplg_create_tlv(tplg, &kc[i], &mc->hdr);
+               if (err < 0) {
+                       dev_err(tplg->dev, "ASoC: failed to create TLV %s\n",
+                               mc->hdr.name);
+                       kfree(sm);
+                       continue;
+               }
 
                /* pass control to driver for optional further init */
                err = soc_tplg_init_kcontrol(tplg, &kc[i],
@@ -1766,10 +1786,13 @@ static int soc_tplg_dapm_complete(struct soc_tplg *tplg)
        return 0;
 }
 
-static void set_stream_info(struct snd_soc_pcm_stream *stream,
+static int set_stream_info(struct snd_soc_pcm_stream *stream,
        struct snd_soc_tplg_stream_caps *caps)
 {
        stream->stream_name = kstrdup(caps->name, GFP_KERNEL);
+       if (!stream->stream_name)
+               return -ENOMEM;
+
        stream->channels_min = le32_to_cpu(caps->channels_min);
        stream->channels_max = le32_to_cpu(caps->channels_max);
        stream->rates = le32_to_cpu(caps->rates);
@@ -1777,6 +1800,8 @@ static void set_stream_info(struct snd_soc_pcm_stream *stream,
        stream->rate_max = le32_to_cpu(caps->rate_max);
        stream->formats = le64_to_cpu(caps->formats);
        stream->sig_bits = le32_to_cpu(caps->sig_bits);
+
+       return 0;
 }
 
 static void set_dai_flags(struct snd_soc_dai_driver *dai_drv,
@@ -1812,20 +1837,29 @@ static int soc_tplg_dai_create(struct soc_tplg *tplg,
        if (dai_drv == NULL)
                return -ENOMEM;
 
-       if (strlen(pcm->dai_name))
+       if (strlen(pcm->dai_name)) {
                dai_drv->name = kstrdup(pcm->dai_name, GFP_KERNEL);
+               if (!dai_drv->name) {
+                       ret = -ENOMEM;
+                       goto err;
+               }
+       }
        dai_drv->id = le32_to_cpu(pcm->dai_id);
 
        if (pcm->playback) {
                stream = &dai_drv->playback;
                caps = &pcm->caps[SND_SOC_TPLG_STREAM_PLAYBACK];
-               set_stream_info(stream, caps);
+               ret = set_stream_info(stream, caps);
+               if (ret < 0)
+                       goto err;
        }
 
        if (pcm->capture) {
                stream = &dai_drv->capture;
                caps = &pcm->caps[SND_SOC_TPLG_STREAM_CAPTURE];
-               set_stream_info(stream, caps);
+               ret = set_stream_info(stream, caps);
+               if (ret < 0)
+                       goto err;
        }
 
        if (pcm->compress)
@@ -1835,11 +1869,7 @@ static int soc_tplg_dai_create(struct soc_tplg *tplg,
        ret = soc_tplg_dai_load(tplg, dai_drv, pcm, NULL);
        if (ret < 0) {
                dev_err(tplg->comp->dev, "ASoC: DAI loading failed\n");
-               kfree(dai_drv->playback.stream_name);
-               kfree(dai_drv->capture.stream_name);
-               kfree(dai_drv->name);
-               kfree(dai_drv);
-               return ret;
+               goto err;
        }
 
        dai_drv->dobj.index = tplg->index;
@@ -1860,6 +1890,14 @@ static int soc_tplg_dai_create(struct soc_tplg *tplg,
                return ret;
        }
 
+       return 0;
+
+err:
+       kfree(dai_drv->playback.stream_name);
+       kfree(dai_drv->capture.stream_name);
+       kfree(dai_drv->name);
+       kfree(dai_drv);
+
        return ret;
 }
 
@@ -1916,11 +1954,20 @@ static int soc_tplg_fe_link_create(struct soc_tplg *tplg,
        if (strlen(pcm->pcm_name)) {
                link->name = kstrdup(pcm->pcm_name, GFP_KERNEL);
                link->stream_name = kstrdup(pcm->pcm_name, GFP_KERNEL);
+               if (!link->name || !link->stream_name) {
+                       ret = -ENOMEM;
+                       goto err;
+               }
        }
        link->id = le32_to_cpu(pcm->pcm_id);
 
-       if (strlen(pcm->dai_name))
+       if (strlen(pcm->dai_name)) {
                link->cpus->dai_name = kstrdup(pcm->dai_name, GFP_KERNEL);
+               if (!link->cpus->dai_name) {
+                       ret = -ENOMEM;
+                       goto err;
+               }
+       }
 
        link->codecs->name = "snd-soc-dummy";
        link->codecs->dai_name = "snd-soc-dummy-dai";
@@ -2088,7 +2135,9 @@ static int soc_tplg_pcm_elems_load(struct soc_tplg *tplg,
                        _pcm = pcm;
                } else {
                        abi_match = false;
-                       pcm_new_ver(tplg, pcm, &_pcm);
+                       ret = pcm_new_ver(tplg, pcm, &_pcm);
+                       if (ret < 0)
+                               return ret;
                }
 
                /* create the FE DAIs and DAI links */
@@ -2436,13 +2485,17 @@ static int soc_tplg_dai_config(struct soc_tplg *tplg,
        if (d->playback) {
                stream = &dai_drv->playback;
                caps = &d->caps[SND_SOC_TPLG_STREAM_PLAYBACK];
-               set_stream_info(stream, caps);
+               ret = set_stream_info(stream, caps);
+               if (ret < 0)
+                       goto err;
        }
 
        if (d->capture) {
                stream = &dai_drv->capture;
                caps = &d->caps[SND_SOC_TPLG_STREAM_CAPTURE];
-               set_stream_info(stream, caps);
+               ret = set_stream_info(stream, caps);
+               if (ret < 0)
+                       goto err;
        }
 
        if (d->flag_mask)
@@ -2454,10 +2507,15 @@ static int soc_tplg_dai_config(struct soc_tplg *tplg,
        ret = soc_tplg_dai_load(tplg, dai_drv, NULL, dai);
        if (ret < 0) {
                dev_err(tplg->comp->dev, "ASoC: DAI loading failed\n");
-               return ret;
+               goto err;
        }
 
        return 0;
+
+err:
+       kfree(dai_drv->playback.stream_name);
+       kfree(dai_drv->capture.stream_name);
+       return ret;
 }
 
 /* load physical DAI elements */
@@ -2466,7 +2524,7 @@ static int soc_tplg_dai_elems_load(struct soc_tplg *tplg,
 {
        struct snd_soc_tplg_dai *dai;
        int count;
-       int i;
+       int i, ret;
 
        count = le32_to_cpu(hdr->count);
 
@@ -2481,7 +2539,12 @@ static int soc_tplg_dai_elems_load(struct soc_tplg *tplg,
                        return -EINVAL;
                }
 
-               soc_tplg_dai_config(tplg, dai);
+               ret = soc_tplg_dai_config(tplg, dai);
+               if (ret < 0) {
+                       dev_err(tplg->dev, "ASoC: failed to configure DAI\n");
+                       return ret;
+               }
+
                tplg->pos += (sizeof(*dai) + le32_to_cpu(dai->priv.size));
        }
 
@@ -2589,7 +2652,7 @@ static int soc_valid_header(struct soc_tplg *tplg,
        }
 
        /* big endian firmware objects not supported atm */
-       if (hdr->magic == SOC_TPLG_MAGIC_BIG_ENDIAN) {
+       if (le32_to_cpu(hdr->magic) == SOC_TPLG_MAGIC_BIG_ENDIAN) {
                dev_err(tplg->dev,
                        "ASoC: pass %d big endian not supported header got %x at offset 0x%lx size 0x%zx.\n",
                        tplg->pass, hdr->magic,
index 6c23c57693309dbe4071659d568c87571a90b1a0..a32a3ef78ec5d36ac6f1fba9689ae8b1f2f955ec 100644 (file)
@@ -567,9 +567,25 @@ static void bdw_set_mach_params(const struct snd_soc_acpi_mach *mach,
 static struct snd_soc_dai_driver bdw_dai[] = {
 {
        .name = "ssp0-port",
+       .playback = {
+               .channels_min = 1,
+               .channels_max = 8,
+       },
+       .capture = {
+               .channels_min = 1,
+               .channels_max = 8,
+       },
 },
 {
        .name = "ssp1-port",
+       .playback = {
+               .channels_min = 1,
+               .channels_max = 8,
+       },
+       .capture = {
+               .channels_min = 1,
+               .channels_max = 8,
+       },
 },
 };
 
index f84391294f12c1f19d21bd526f21dd0378436a9a..29fd1d86156ce40227b7a54660ac555dd9333377 100644 (file)
@@ -459,21 +459,69 @@ static void byt_set_mach_params(const struct snd_soc_acpi_mach *mach,
 static struct snd_soc_dai_driver byt_dai[] = {
 {
        .name = "ssp0-port",
+       .playback = {
+               .channels_min = 1,
+               .channels_max = 8,
+       },
+       .capture = {
+               .channels_min = 1,
+               .channels_max = 8,
+       },
 },
 {
        .name = "ssp1-port",
+       .playback = {
+               .channels_min = 1,
+               .channels_max = 8,
+       },
+       .capture = {
+               .channels_min = 1,
+               .channels_max = 8,
+       },
 },
 {
        .name = "ssp2-port",
+       .playback = {
+               .channels_min = 1,
+               .channels_max = 8,
+       },
+       .capture = {
+               .channels_min = 1,
+               .channels_max = 8,
+       }
 },
 {
        .name = "ssp3-port",
+       .playback = {
+               .channels_min = 1,
+               .channels_max = 8,
+       },
+       .capture = {
+               .channels_min = 1,
+               .channels_max = 8,
+       },
 },
 {
        .name = "ssp4-port",
+       .playback = {
+               .channels_min = 1,
+               .channels_max = 8,
+       },
+       .capture = {
+               .channels_min = 1,
+               .channels_max = 8,
+       },
 },
 {
        .name = "ssp5-port",
+       .playback = {
+               .channels_min = 1,
+               .channels_max = 8,
+       },
+       .capture = {
+               .channels_min = 1,
+               .channels_max = 8,
+       },
 },
 };
 
index 0d0c9afd8791f46dafd9b11f448fb9f01efdd007..41f01c3e639eeb9a57333e513b0119051ec0e554 100644 (file)
@@ -837,7 +837,7 @@ static int stm32_sai_set_config(struct snd_soc_dai *cpu_dai,
                cr1 = SAI_XCR1_DS_SET(SAI_DATASIZE_32);
                break;
        default:
-               dev_err(cpu_dai->dev, "Data format not supported");
+               dev_err(cpu_dai->dev, "Data format not supported\n");
                return -EINVAL;
        }
 
@@ -1547,6 +1547,9 @@ static int stm32_sai_sub_probe(struct platform_device *pdev)
                return ret;
        }
 
+       if (STM_SAI_PROTOCOL_IS_SPDIF(sai))
+               conf = &stm32_sai_pcm_config_spdif;
+
        ret = snd_dmaengine_pcm_register(&pdev->dev, conf, 0);
        if (ret) {
                if (ret != -EPROBE_DEFER)
@@ -1556,15 +1559,10 @@ static int stm32_sai_sub_probe(struct platform_device *pdev)
 
        ret = snd_soc_register_component(&pdev->dev, &stm32_component,
                                         &sai->cpu_dai_drv, 1);
-       if (ret) {
+       if (ret)
                snd_dmaengine_pcm_unregister(&pdev->dev);
-               return ret;
-       }
-
-       if (STM_SAI_PROTOCOL_IS_SPDIF(sai))
-               conf = &stm32_sai_pcm_config_spdif;
 
-       return 0;
+       return ret;
 }
 
 static int stm32_sai_sub_remove(struct platform_device *pdev)
index 50e1874c847c68d98166daea260088d0e69de53c..5ffb457cc88cf0b0a1062589f808f6edb50d512f 100644 (file)
@@ -277,6 +277,52 @@ static bool s1810c_valid_sample_rate(struct audioformat *fp,
        return false;
 }
 
+/*
+ * Many Focusrite devices supports a limited set of sampling rates per
+ * altsetting. Maximum rate is exposed in the last 4 bytes of Format Type
+ * descriptor which has a non-standard bLength = 10.
+ */
+static bool focusrite_valid_sample_rate(struct snd_usb_audio *chip,
+                                       struct audioformat *fp,
+                                       unsigned int rate)
+{
+       struct usb_interface *iface;
+       struct usb_host_interface *alts;
+       unsigned char *fmt;
+       unsigned int max_rate;
+
+       iface = usb_ifnum_to_if(chip->dev, fp->iface);
+       if (!iface)
+               return true;
+
+       alts = &iface->altsetting[fp->altset_idx];
+       fmt = snd_usb_find_csint_desc(alts->extra, alts->extralen,
+                                     NULL, UAC_FORMAT_TYPE);
+       if (!fmt)
+               return true;
+
+       if (fmt[0] == 10) { /* bLength */
+               max_rate = combine_quad(&fmt[6]);
+
+               /* Validate max rate */
+               if (max_rate != 48000 &&
+                   max_rate != 96000 &&
+                   max_rate != 192000 &&
+                   max_rate != 384000) {
+
+                       usb_audio_info(chip,
+                               "%u:%d : unexpected max rate: %u\n",
+                               fp->iface, fp->altsetting, max_rate);
+
+                       return true;
+               }
+
+               return rate <= max_rate;
+       }
+
+       return true;
+}
+
 /*
  * Helper function to walk the array of sample rate triplets reported by
  * the device. The problem is that we need to parse whole array first to
@@ -319,6 +365,11 @@ static int parse_uac2_sample_rate_range(struct snd_usb_audio *chip,
                            !s1810c_valid_sample_rate(fp, rate))
                                goto skip_rate;
 
+                       /* Filter out invalid rates on Focusrite devices */
+                       if (USB_ID_VENDOR(chip->usb_id) == 0x1235 &&
+                           !focusrite_valid_sample_rate(chip, fp, rate))
+                               goto skip_rate;
+
                        if (fp->rate_table)
                                fp->rate_table[nr_rates] = rate;
                        if (!fp->rate_min || rate < fp->rate_min)
index e7b9040a54e65ba6e697934a0b649c389e58df29..a88d7854513b96ff7dc3f44ccaebfeea2b12ee35 100644 (file)
@@ -1776,8 +1776,10 @@ static void build_connector_control(struct usb_mixer_interface *mixer,
 {
        struct snd_kcontrol *kctl;
        struct usb_mixer_elem_info *cval;
+       const struct usbmix_name_map *map;
 
-       if (check_ignored_ctl(find_map(imap, term->id, 0)))
+       map = find_map(imap, term->id, 0);
+       if (check_ignored_ctl(map))
                return;
 
        cval = kzalloc(sizeof(*cval), GFP_KERNEL);
@@ -1809,8 +1811,12 @@ static void build_connector_control(struct usb_mixer_interface *mixer,
                usb_mixer_elem_info_free(cval);
                return;
        }
-       get_connector_control_name(mixer, term, is_input, kctl->id.name,
-                                  sizeof(kctl->id.name));
+
+       if (check_mapped_name(map, kctl->id.name, sizeof(kctl->id.name)))
+               strlcat(kctl->id.name, " Jack", sizeof(kctl->id.name));
+       else
+               get_connector_control_name(mixer, term, is_input, kctl->id.name,
+                                          sizeof(kctl->id.name));
        kctl->private_free = snd_usb_mixer_elem_free;
        snd_usb_mixer_add_control(&cval->head, kctl);
 }
@@ -3111,6 +3117,7 @@ static int snd_usb_mixer_controls(struct usb_mixer_interface *mixer)
                if (map->id == state.chip->usb_id) {
                        state.map = map->map;
                        state.selector_map = map->selector_map;
+                       mixer->connector_map = map->connector_map;
                        mixer->ignore_ctl_error |= map->ignore_ctl_error;
                        break;
                }
@@ -3192,10 +3199,32 @@ static int snd_usb_mixer_controls(struct usb_mixer_interface *mixer)
        return 0;
 }
 
+static int delegate_notify(struct usb_mixer_interface *mixer, int unitid,
+                          u8 *control, u8 *channel)
+{
+       const struct usbmix_connector_map *map = mixer->connector_map;
+
+       if (!map)
+               return unitid;
+
+       for (; map->id; map++) {
+               if (map->id == unitid) {
+                       if (control && map->control)
+                               *control = map->control;
+                       if (channel && map->channel)
+                               *channel = map->channel;
+                       return map->delegated_id;
+               }
+       }
+       return unitid;
+}
+
 void snd_usb_mixer_notify_id(struct usb_mixer_interface *mixer, int unitid)
 {
        struct usb_mixer_elem_list *list;
 
+       unitid = delegate_notify(mixer, unitid, NULL, NULL);
+
        for_each_mixer_elem(list, mixer, unitid) {
                struct usb_mixer_elem_info *info =
                        mixer_elem_list_to_info(list);
@@ -3265,6 +3294,8 @@ static void snd_usb_mixer_interrupt_v2(struct usb_mixer_interface *mixer,
                return;
        }
 
+       unitid = delegate_notify(mixer, unitid, &control, &channel);
+
        for_each_mixer_elem(list, mixer, unitid)
                count++;
 
index 65d6d08c96f53e6f67686d20a85ba85c7ca6809b..41ec9dc4139bbec3512ccd2bc2cc04124a451543 100644 (file)
@@ -6,6 +6,13 @@
 
 struct media_mixer_ctl;
 
+struct usbmix_connector_map {
+       u8 id;
+       u8 delegated_id;
+       u8 control;
+       u8 channel;
+};
+
 struct usb_mixer_interface {
        struct snd_usb_audio *chip;
        struct usb_host_interface *hostif;
@@ -18,6 +25,9 @@ struct usb_mixer_interface {
        /* the usb audio specification version this interface complies to */
        int protocol;
 
+       /* optional connector delegation map */
+       const struct usbmix_connector_map *connector_map;
+
        /* Sound Blaster remote control stuff */
        const struct rc_config *rc_cfg;
        u32 rc_code;
index b4e77000f441e96ed86e81e8ec3916290208e54e..0260c750e15693267b1b16095e124f6fb60cbeb6 100644 (file)
@@ -27,6 +27,7 @@ struct usbmix_ctl_map {
        u32 id;
        const struct usbmix_name_map *map;
        const struct usbmix_selector_map *selector_map;
+       const struct usbmix_connector_map *connector_map;
        int ignore_ctl_error;
 };
 
@@ -369,6 +370,33 @@ static const struct usbmix_name_map asus_rog_map[] = {
        {}
 };
 
+/* TRX40 mobos with Realtek ALC1220-VB */
+static const struct usbmix_name_map trx40_mobo_map[] = {
+       { 18, NULL }, /* OT, IEC958 - broken response, disabled */
+       { 19, NULL, 12 }, /* FU, Input Gain Pad - broken response, disabled */
+       { 16, "Speaker" },              /* OT */
+       { 22, "Speaker Playback" },     /* FU */
+       { 7, "Line" },                  /* IT */
+       { 19, "Line Capture" },         /* FU */
+       { 17, "Front Headphone" },      /* OT */
+       { 23, "Front Headphone Playback" },     /* FU */
+       { 8, "Mic" },                   /* IT */
+       { 20, "Mic Capture" },          /* FU */
+       { 9, "Front Mic" },             /* IT */
+       { 21, "Front Mic Capture" },    /* FU */
+       { 24, "IEC958 Playback" },      /* FU */
+       {}
+};
+
+static const struct usbmix_connector_map trx40_mobo_connector_map[] = {
+       { 10, 16 },     /* (Back) Speaker */
+       { 11, 17 },     /* Front Headphone */
+       { 13, 7 },      /* Line */
+       { 14, 8 },      /* Mic */
+       { 15, 9 },      /* Front Mic */
+       {}
+};
+
 /*
  * Control map entries
  */
@@ -500,7 +528,8 @@ static const struct usbmix_ctl_map usbmix_ctl_maps[] = {
        },
        {       /* Gigabyte TRX40 Aorus Pro WiFi */
                .id = USB_ID(0x0414, 0xa002),
-               .map = asus_rog_map,
+               .map = trx40_mobo_map,
+               .connector_map = trx40_mobo_connector_map,
        },
        {       /* ASUS ROG Zenith II */
                .id = USB_ID(0x0b05, 0x1916),
@@ -512,11 +541,13 @@ static const struct usbmix_ctl_map usbmix_ctl_maps[] = {
        },
        {       /* MSI TRX40 Creator */
                .id = USB_ID(0x0db0, 0x0d64),
-               .map = asus_rog_map,
+               .map = trx40_mobo_map,
+               .connector_map = trx40_mobo_connector_map,
        },
        {       /* MSI TRX40 */
                .id = USB_ID(0x0db0, 0x543d),
-               .map = asus_rog_map,
+               .map = trx40_mobo_map,
+               .connector_map = trx40_mobo_connector_map,
        },
        { 0 } /* terminator */
 };
index 02b036b2aefbd6a85c134c4f4e5f2822c3249065..a5f65a9a02546bd83dfd5e68f7d4433eed79518e 100644 (file)
@@ -1509,11 +1509,15 @@ static int snd_microii_spdif_default_get(struct snd_kcontrol *kcontrol,
 
        /* use known values for that card: interface#1 altsetting#1 */
        iface = usb_ifnum_to_if(chip->dev, 1);
-       if (!iface || iface->num_altsetting < 2)
-               return -EINVAL;
+       if (!iface || iface->num_altsetting < 2) {
+               err = -EINVAL;
+               goto end;
+       }
        alts = &iface->altsetting[1];
-       if (get_iface_desc(alts)->bNumEndpoints < 1)
-               return -EINVAL;
+       if (get_iface_desc(alts)->bNumEndpoints < 1) {
+               err = -EINVAL;
+               goto end;
+       }
        ep = get_endpoint(alts, 0)->bEndpointAddress;
 
        err = snd_usb_ctl_msg(chip->dev,
index e009d584e7d08aaed05dda6ad10a145488b5a133..a1df4c5b4f8cbf9ae6c63f95fe759897a41dda43 100644 (file)
@@ -2756,90 +2756,6 @@ YAMAHA_DEVICE(0x7010, "UB99"),
                .type = QUIRK_MIDI_NOVATION
        }
 },
-{
-       /*
-        * Focusrite Scarlett Solo 2nd generation
-        * Reports that playback should use Synch: Synchronous
-        * while still providing a feedback endpoint. Synchronous causes
-        * snapping on some sample rates.
-        * Force it to use Synch: Asynchronous.
-        */
-       USB_DEVICE(0x1235, 0x8205),
-       .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
-               .ifnum = QUIRK_ANY_INTERFACE,
-               .type = QUIRK_COMPOSITE,
-               .data = (const struct snd_usb_audio_quirk[]) {
-                       {
-                               .ifnum = 1,
-                               .type = QUIRK_AUDIO_FIXED_ENDPOINT,
-                               .data = & (const struct audioformat) {
-                                       .formats = SNDRV_PCM_FMTBIT_S32_LE,
-                                       .channels = 2,
-                                       .iface = 1,
-                                       .altsetting = 1,
-                                       .altset_idx = 1,
-                                       .attributes = 0,
-                                       .endpoint = 0x01,
-                                       .ep_attr = USB_ENDPOINT_XFER_ISOC |
-                                                  USB_ENDPOINT_SYNC_ASYNC,
-                                       .protocol = UAC_VERSION_2,
-                                       .rates = SNDRV_PCM_RATE_44100 |
-                                                SNDRV_PCM_RATE_48000 |
-                                                SNDRV_PCM_RATE_88200 |
-                                                SNDRV_PCM_RATE_96000 |
-                                                SNDRV_PCM_RATE_176400 |
-                                                SNDRV_PCM_RATE_192000,
-                                       .rate_min = 44100,
-                                       .rate_max = 192000,
-                                       .nr_rates = 6,
-                                       .rate_table = (unsigned int[]) {
-                                               44100, 48000, 88200,
-                                               96000, 176400, 192000
-                                       },
-                                       .clock = 41
-                               }
-                       },
-                       {
-                               .ifnum = 2,
-                               .type = QUIRK_AUDIO_FIXED_ENDPOINT,
-                               .data = & (const struct audioformat) {
-                                       .formats = SNDRV_PCM_FMTBIT_S32_LE,
-                                       .channels = 2,
-                                       .iface = 2,
-                                       .altsetting = 1,
-                                       .altset_idx = 1,
-                                       .attributes = 0,
-                                       .endpoint = 0x82,
-                                       .ep_attr = USB_ENDPOINT_XFER_ISOC |
-                                                  USB_ENDPOINT_SYNC_ASYNC |
-                                                  USB_ENDPOINT_USAGE_IMPLICIT_FB,
-                                       .protocol = UAC_VERSION_2,
-                                       .rates = SNDRV_PCM_RATE_44100 |
-                                                SNDRV_PCM_RATE_48000 |
-                                                SNDRV_PCM_RATE_88200 |
-                                                SNDRV_PCM_RATE_96000 |
-                                                SNDRV_PCM_RATE_176400 |
-                                                SNDRV_PCM_RATE_192000,
-                                       .rate_min = 44100,
-                                       .rate_max = 192000,
-                                       .nr_rates = 6,
-                                       .rate_table = (unsigned int[]) {
-                                               44100, 48000, 88200,
-                                               96000, 176400, 192000
-                                       },
-                                       .clock = 41
-                               }
-                       },
-                       {
-                               .ifnum = 3,
-                               .type = QUIRK_IGNORE_INTERFACE
-                       },
-                       {
-                               .ifnum = -1
-                       }
-               }
-       }
-},
 
 /* Access Music devices */
 {
@@ -3635,4 +3551,18 @@ AU0828_DEVICE(0x2040, 0x7270, "Hauppauge", "HVR-950Q"),
        }
 },
 
+#define ALC1220_VB_DESKTOP(vend, prod) { \
+       USB_DEVICE(vend, prod), \
+       .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { \
+               .vendor_name = "Realtek", \
+               .product_name = "ALC1220-VB-DT", \
+               .profile_name = "Realtek-ALC1220-VB-Desktop", \
+               .ifnum = QUIRK_NO_INTERFACE \
+       } \
+}
+ALC1220_VB_DESKTOP(0x0414, 0xa002), /* Gigabyte TRX40 Aorus Pro WiFi */
+ALC1220_VB_DESKTOP(0x0db0, 0x0d64), /* MSI TRX40 Creator */
+ALC1220_VB_DESKTOP(0x0db0, 0x543d), /* MSI TRX40 */
+#undef ALC1220_VB_DESKTOP
+
 #undef USB_DEVICE_VENDOR_SPEC
index a8ece17010686da6628b6961970ed1fda27cd4d2..351ba214a9d3fe1ba80129fb38a68bce570189df 100644 (file)
@@ -1806,6 +1806,20 @@ void snd_usb_audioformat_attributes_quirk(struct snd_usb_audio *chip,
                 */
                fp->attributes &= ~UAC_EP_CS_ATTR_FILL_MAX;
                break;
+       case USB_ID(0x1235, 0x8200):  /* Focusrite Scarlett 2i4 2nd gen */
+       case USB_ID(0x1235, 0x8202):  /* Focusrite Scarlett 2i2 2nd gen */
+       case USB_ID(0x1235, 0x8205):  /* Focusrite Scarlett Solo 2nd gen */
+               /*
+                * Reports that playback should use Synch: Synchronous
+                * while still providing a feedback endpoint.
+                * Synchronous causes snapping on some sample rates.
+                * Force it to use Synch: Asynchronous.
+                */
+               if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
+                       fp->ep_attr &= ~USB_ENDPOINT_SYNCTYPE;
+                       fp->ep_attr |= USB_ENDPOINT_SYNC_ASYNC;
+               }
+               break;
        }
 }
 
index 37d290fe9d4350caad5ddea7ea7432dd566ff85b..ecaf41265dcd0d61889130558694541288f117ef 100644 (file)
@@ -681,6 +681,8 @@ static int usX2Y_rate_set(struct usX2Ydev *usX2Y, int rate)
                        us->submitted = 2*NOOF_SETRATE_URBS;
                        for (i = 0; i < NOOF_SETRATE_URBS; ++i) {
                                struct urb *urb = us->urb[i];
+                               if (!urb)
+                                       continue;
                                if (urb->status) {
                                        if (!err)
                                                err = -ENODEV;
index 0fe0d584c57ea5aa2a9f915120fa24ff78d972ad..e17738479edcc01c94d9669611f2c706869dec71 100644 (file)
@@ -479,6 +479,7 @@ static int do_unregister(int argc, char **argv)
 
 static int do_register(int argc, char **argv)
 {
+       struct bpf_object_load_attr load_attr = {};
        const struct bpf_map_def *def;
        struct bpf_map_info info = {};
        __u32 info_len = sizeof(info);
@@ -499,7 +500,12 @@ static int do_register(int argc, char **argv)
 
        set_max_rlimit();
 
-       if (bpf_object__load(obj)) {
+       load_attr.obj = obj;
+       if (verifier_logs)
+               /* log_level1 + log_level2 + stats, but not stable UAPI */
+               load_attr.log_level = 1 + 2 + 4;
+
+       if (bpf_object__load_xattr(&load_attr)) {
                bpf_object__close(obj);
                return -1;
        }
index 39edd68afa8e08be1ea3adf9da188b56b9648e24..8a6f82e56a249af134cdb9261720a891f1fa1f4d 100644 (file)
@@ -8,7 +8,7 @@ BPFTOOL ?= $(DEFAULT_BPFTOOL)
 LIBBPF_SRC := $(abspath ../../lib/bpf)
 BPFOBJ := $(OUTPUT)/libbpf.a
 BPF_INCLUDE := $(OUTPUT)
-INCLUDES := -I$(BPF_INCLUDE) -I$(OUTPUT) -I$(abspath ../../lib)
+INCLUDES := -I$(OUTPUT) -I$(BPF_INCLUDE) -I$(abspath ../../lib)
 CFLAGS := -g -Wall
 
 # Try to detect best kernel BTF source
index 1e38d1930a972a3a442c314eb1cf5a611bbe472d..3bc6b0768a53170d486b497fe87d51cfee9a626c 100644 (file)
@@ -7,7 +7,7 @@ int main(int argc, char *argv[])
 {
        uint64_t old, new = argc;
 
-       argv = argv;
+       (void)argv;
        do {
                old = __sync_val_compare_and_swap(&x, 0, 0);
        } while (!__sync_bool_compare_and_swap(&x, old, new));
index 2e29a671d67eb96a3139c893158aa0fc69466213..7bbf1b65be10bf26c5a9309dbeddc34de8072272 100644 (file)
@@ -1642,7 +1642,7 @@ union bpf_attr {
  *             ifindex, but doesn't require a map to do so.
  *     Return
  *             **XDP_REDIRECT** on success, or the value of the two lower bits
- *             of the **flags* argument on error.
+ *             of the *flags* argument on error.
  *
  * int bpf_sk_redirect_map(struct sk_buff *skb, struct bpf_map *map, u32 key, u64 flags)
  *     Description
index 0b709fd10bbaaa8dbc7e663422ba2887c0e9a0ce..312f887570b21441b526a2559cc9f61447200a6b 100644 (file)
@@ -321,6 +321,8 @@ int bpf_get_link_xdp_info(int ifindex, struct xdp_link_info *info,
 
 static __u32 get_xdp_id(struct xdp_link_info *info, __u32 flags)
 {
+       flags &= XDP_FLAGS_MODES;
+
        if (info->attach_mode != XDP_ATTACHED_MULTI && !flags)
                return info->prog_id;
        if (flags & XDP_FLAGS_DRV_MODE)
index 09ddc8f1def3cf328d3b5531391b4fc00a43804a..c4857fa3f1d18537c2bcbbc37c6f40b966ffd7e1 100644 (file)
@@ -105,7 +105,7 @@ static int symbol_by_offset(const void *key, const struct rb_node *node)
 
        if (*o < s->offset)
                return -1;
-       if (*o > s->offset + s->len)
+       if (*o >= s->offset + s->len)
                return 1;
 
        return 0;
index ebbb10c61e246743e3b2be05f4b9098e02013600..0b79c2353a210ed8a60cd1908beb671e435ef38f 100644 (file)
@@ -99,7 +99,7 @@ static inline u32 sec_offset_hash(struct section *sec, unsigned long offset)
        offset &= OFFSET_STRIDE_MASK;
 
        ol = offset;
-       oh = offset >> 32;
+       oh = (offset >> 16) >> 16;
 
        __jhash_mix(ol, oh, idx);
 
index 845541544570a3c44ee04a85f84cfc31e5c9f26d..b5310832c19c640496ae92ad8845b92a10e66ef9 100644 (file)
@@ -41,6 +41,10 @@ uninstall :
        if [ -d $(DESTDIR)$(PREFIX)/lib/pm-graph/config ] ; then \
                rmdir $(DESTDIR)$(PREFIX)/lib/pm-graph/config; \
        fi;
+       rm -f $(DESTDIR)$(PREFIX)/lib/pm-graph/__pycache__/*
+       if [ -d $(DESTDIR)$(PREFIX)/lib/pm-graph/__pycache__ ] ; then \
+               rmdir $(DESTDIR)$(PREFIX)/lib/pm-graph/__pycache__; \
+       fi;
        rm -f $(DESTDIR)$(PREFIX)/lib/pm-graph/*
        if [ -d $(DESTDIR)$(PREFIX)/lib/pm-graph ] ; then \
                rmdir $(DESTDIR)$(PREFIX)/lib/pm-graph; \
index 96259f6e57152bc47ea8b72129471c14ee713371..afe6beb40ad91b6b33590992dc5db5479cf9b186 100644 (file)
@@ -1,7 +1,12 @@
-                     p m - g r a p h
+                                                _
+    _ __  _ __ ___         __ _ _ __ __ _ _ __ | |__
+   | '_ \| '_ ` _ \ _____ / _` | '__/ _` | '_ \| '_ \
+   | |_) | | | | | |_____| (_| | | | (_| | |_) | | | |
+   | .__/|_| |_| |_|      \__, |_|  \__,_| .__/|_| |_|
+   |_|                    |___/          |_|
 
    pm-graph: suspend/resume/boot timing analysis tools
-    Version: 5.5
+    Version: 5.6
      Author: Todd Brandt <todd.e.brandt@intel.com>
   Home Page: https://01.org/pm-graph
 
        - upstream version in git:
          https://github.com/intel/pm-graph/
 
- Requirements:
-       - runs with python2 or python3, choice is made by /usr/bin/python link
-       - python2 now requires python-configparser be installed
-
  Table of Contents
        - Overview
        - Setup
@@ -29,6 +30,8 @@
                - Basic Usage
                - Dev Mode Usage
                - Proc Mode Usage
+       - Endurance Testing
+               - Usage Examples
        - Configuration Files
                - Usage Examples
                - Config File Options
 |                            SETUP                               |
 ------------------------------------------------------------------
 
-    These packages are required to execute the scripts
+    Package Requirements
+       - runs with python2 or python3, choice is made by /usr/bin/python link
        - python
-       - python-requests
+       - python-configparser (for python2 sleepgraph)
+       - python-requests (for googlesheet.py)
+       - linux-tools-common (for turbostat usage in sleepgraph)
 
        Ubuntu:
-          sudo apt-get install python python-requests
+          sudo apt-get install python python-configparser python-requests linux-tools-common
 
        Fedora:
-          sudo dnf install python python-requests
+          sudo dnf install python python-configparser python-requests linux-tools-common
 
     The tools can most easily be installed via git clone and make install
 
@@ -190,6 +196,104 @@ _______________
 
  %> sudo ./sleepgraph.py -config config/suspend-proc.cfg
 
+------------------------------------------------------------------
+|                     ENDURANCE TESTING                          |
+------------------------------------------------------------------
+
+ The best way to gauge the health of a system is to run a series of
+ suspend/resumes over an extended period and analyze the behavior. This can be
+ accomplished with sleepgraph's -multi argument. You specify two numbers: the
+ number of tests to run OR the duration in days, hours, or minutes, and the
+ delay in seconds between them. For instance, -multi 20 5: execute 20 tests with
+ a 5 second delay between each, or -multi 24h 0: execute tests over a 24 hour
+ period with no delay between tests. You can include any other options you like
+ to generate the data you want. It's most useful to collect dev mode timelines
+ as the kprobes don't alter the performance much and you get more insight.
+
+ On completion, the output folder contains a series of folders for the
+ individual test data and a set of summary pages in the root. The summary.html
+ file is a tabular list of the tests with relevant info and links. The
+ summary-issue.html and summary-devices.html files include data taken from
+ all tests on kernel issues and device performance. The folder looks like this:
+
+  suspend-xN-{date}-{time}:
+       summary.html
+       summary-issues.html
+       summary-devices.html
+       suspend-{date}-{time} (1)
+       suspend-{date}-{time} (2)
+       ...
+
+ These are the relevant arguments to use for testing:
+
+  -m mode
+       Mode to initiate for suspend e.g. mem, freeze, standby (default: mem).
+
+  -rtcwake t
+       Use rtcwake to autoresume after t seconds (default: 15).
+
+  -gzip (optional)
+       Gzip the trace and dmesg logs to save space. The tool can also read in
+       gzipped logs for processing. This reduces the multitest folder size.
+
+  -dev (optional)
+       Add kernel source calls and threads to the timeline (default: disabled).
+
+  -multi n d
+       Execute n consecutive tests at d seconds intervals. The outputs will be
+       created in a new subdirectory: suspend-xN-{date}-{time}. When the multitest
+       run is done, the -summary command is called automatically to create summary
+       html files for all the data (unless you use -skiphtml). -skiphtml will
+       speed up the testing by not creating timelines or summary html files. You
+       can then run the tool again at a later time with -summary and -genhtml to
+       create the timelines.
+
+  -skiphtml (optional)
+       Run the test and capture the trace logs, but skip the timeline and summary
+       html generation. This can greatly speed up overall testing. You can then
+       copy the data to a faster host machine and run -summary -genhtml to
+       generate the timelines and summary.
+
+ These are the relevant commands to use after testing is complete:
+
+  -summary indir
+       Generate or regenerate the summary for a -multi test run. Creates three
+       files: summary.html, summary-issues.html, and summary-devices.html in the
+       current folder. summary.html is a table of tests with relevant info sorted
+       by kernel/host/mode, and links to the test html files. summary-issues.html
+       is a list of kernel issues found in dmesg from all the tests.
+       summary-devices.html is a list of devices and times from all the tests.
+
+  -genhtml
+       Used  with -summary to regenerate any missing html timelines from their
+       dmesg and ftrace logs. This will require a significant amount of time if
+       there are thousands of tests.
+
+Usage Examples
+_______________
+
+ A multitest is initiated like this:
+
+  %> sudo ./sleepgraph.py -m mem -rtcwake 10 -dev -gzip -multi 2000 0
+
+       or you can skip timeline generation in order to speed things up
+
+  %> sudo ./sleepgraph.py -m mem -rtcwake 10 -dev -gzip -multi 2000 0 -skiphtml
+
+ The tool will produce an output folder with all the test subfolders inside.
+ Each test subfolder contains the dmesg/ftrace logs and/or the html timeline
+ depending on whether you used the -skiphtml option. The root folder contains
+ the summary.html files.
+
+ The summary for an existing multitest is generated like this:
+
+  %> cd suspend-x2000-{date}-{time}
+  %> sleepgraph.py -summary .
+
+       or if you need to generate the html timelines you can use -genhtml
+
+  %> cd suspend-xN-{date}-{time}
+  %> sleepgraph.py -summary . -genhtml
 
 ------------------------------------------------------------------
 |                    CONFIGURATION FILES                         |
index d3b99a1e92d6f2aa584f695375fa5fd882d2e30a..2823cd3122f7bb325af60d5ea6d6a9528a9ef287 100755 (executable)
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/env python3
 # SPDX-License-Identifier: GPL-2.0-only
 #
 # Tool for analyzing boot timing
index 43aee64316df06a07d57054c1110934770ecca25..5126271de98a6a29b1c890c0c4187ca2bcbe2e20 100644 (file)
@@ -74,8 +74,10 @@ after the test is complete.
 Switch the display to the requested mode for the test using the xset command.
 This helps maintain the consistency of test data for better comparison.
 .TP
-\fB-skiphtml\fR
-Run the test and capture the trace logs, but skip the timeline generation.
+\fB-wifi\fR
+If a wifi connection is available, check that it reconnects after resume. Include
+the reconnect time in the total resume time calculation and treat wifi timeouts
+as resume failures.
 
 .SS "advanced"
 .TP
@@ -117,8 +119,24 @@ Include \fIt\fR ms delay before 1st suspend (default: 0 ms).
 Include \fIt\fR ms delay after last resume (default: 0 ms).
 .TP
 \fB-multi \fIn d\fR
-Execute \fIn\fR consecutive tests at \fId\fR seconds intervals. The outputs will
-be created in a new subdirectory with a summary page: suspend-xN-{date}-{time}.
+Used for endurance testing. If \fIn\fR is entirely numeric, it's treated as a count:
+Execute \fIn\fR consecutive tests at \fId\fR second intervals.
+If \fIn\fR is an integer followed by a "d", "h", or "m", it's treated as a duration:
+Execute tests continuously over \fIn\fR days, hours, or minutes at \fId\fR second intervals.
+The outputs will be created in a new subdirectory, for count: suspend-{date}-{time}-xN,
+for duration: suspend-{date}-{time}-Nm. When the multitest run is done, the \fI-summary\fR
+command is called automatically to create summary html files for all the data (unless you
+use \fI-skiphtml\fR). \fI-skiphtml\fR will speed up the testing by not creating timelines
+or summary html files. You can then run the tool again at a later time with \fI-summary\fR
+and \fI-genhtml\fR to create the timelines.
+.TP
+\fB-maxfail \fIn\fR
+Abort a -multi run after \fIn\fR consecutive fails. 0 means never abort (default = 0).
+.TP
+\fB-skiphtml\fR
+Run the test and capture the trace logs, but skip the timeline generation.
+You can generate the html timelines later with \fI-dmesg\fR & \fI-ftrace\fR, or
+by running \fI-summary\fR and \fI-genhtml\fR.
 
 .SS "ftrace debug"
 .TP
@@ -173,11 +191,20 @@ Set trace buffer size to N kilo-bytes (default: all of free memory up to 3GB)
 .SH COMMANDS
 .TP
 \fB-summary \fIindir\fR
-Create a summary page of all tests in \fIindir\fR. Creates summary.html
-in the current folder. The output page is a table of tests with
-suspend and resume values sorted by suspend mode, host, and kernel.
-Includes test averages by mode and links to the test html files.
-Use -genhtml to include tests with missing html.
+Create a set of summary pages for all tests in \fIindir\fR recursively.
+Creates summary.html, summary-issues.html, and summary-devices.html in the current folder.
+summary.html is a table of tests with relevant info sorted by kernel/host/mode,
+and links to the test html files. It identifies the minimum, maximum, and median
+suspend and resume times for you with highlights and links in the header.
+summary-issues.html is a list of kernel issues found in dmesg from all the tests.
+summary-devices.html is a list of devices and times from all the tests.
+
+Use \fI-genhtml\fR to regenerate any tests with missing html.
+.TP
+\fB-genhtml\fR
+Used with \fI-summary\fR to regenerate any missing html timelines from their
+dmesg and ftrace logs. This will require a significant amount of time if there
+are thousands of tests.
 .TP
 \fB-modes\fR
 List available suspend modes.
@@ -189,10 +216,7 @@ with any options you intend to use to see if they will work.
 \fB-fpdt\fR
 Print out the contents of the ACPI Firmware Performance Data Table.
 .TP
-\fB-battery\fR
-Print out battery status and current charge.
-.TP
-\fB-wifi\fR
+\fB-wificheck\fR
 Print out wifi status and connection details.
 .TP
 \fB-xon/-xoff/-xstandby/-xsuspend\fR
@@ -208,6 +232,9 @@ Print out system info extracted from BIOS. Reads /dev/mem directly instead of go
 \fB-devinfo\fR
 Print out the pm settings of all devices which support runtime suspend.
 .TP
+\fB-cmdinfo\fR
+Print out all the platform data collected from the system that makes it into the logs.
+.TP
 \fB-flist\fR
 Print the list of ftrace functions currently being captured. Functions
 that are not available as symbols in the current kernel are shown in red.
@@ -272,14 +299,20 @@ Run two suspends back to back, include a 500ms delay before, after, and in betwe
 .IP
 \f(CW$ sudo sleepgraph -m mem -rtcwake 15 -x2 -predelay 500 -x2delay 500 -postdelay 500\fR
 .PP
+Execute a suspend using a custom command.
+.IP
+\f(CW$ sudo sleepgraph -cmd "echo mem > /sys/power/state" -rtcwake 15\fR
+.PP
+
+.SS "endurance testing using -multi"
+.PP
 Do a batch run of 10 freezes with 30 seconds delay between runs.
 .IP
 \f(CW$ sudo sleepgraph -m freeze -rtcwake 15 -multi 10 30\fR
 .PP
-Execute a suspend using a custom command.
+Do a batch run of freezes for 24 hours.
 .IP
-\f(CW$ sudo sleepgraph -cmd "echo mem > /sys/power/state" -rtcwake 15\fR
-.PP
+\f(CW$ sudo sleepgraph -m freeze -rtcwake 15 -multi 24h 0\fR
 
 .SS "adding callgraph data"
 Add device callgraphs. Limit the trace depth and only show callgraphs 10ms or larger.
index f7d1c1f62f860b18b37749bdff0aff2e40dc9ec8..9b0404d107686aa5c63a5f9a06dbe76d00b47514 100755 (executable)
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/env python3
 # SPDX-License-Identifier: GPL-2.0-only
 #
 # Tool for analyzing suspend/resume timing
@@ -58,7 +58,7 @@ import re
 import platform
 import signal
 import codecs
-from datetime import datetime
+from datetime import datetime, timedelta
 import struct
 import configparser
 import gzip
@@ -81,12 +81,13 @@ def ascii(text):
 #       store system values and test parameters
 class SystemValues:
        title = 'SleepGraph'
-       version = '5.5'
+       version = '5.6'
        ansi = False
        rs = 0
        display = ''
        gzip = False
        sync = False
+       wifi = False
        verbose = False
        testlog = True
        dmesglog = True
@@ -97,7 +98,8 @@ class SystemValues:
        cgphase = ''
        cgtest = -1
        cgskip = ''
-       multitest = {'run': False, 'count': 0, 'delay': 0}
+       maxfail = 0
+       multitest = {'run': False, 'count': 1000000, 'delay': 0}
        max_graph_depth = 0
        callloopmaxgap = 0.0001
        callloopmaxlen = 0.005
@@ -148,7 +150,7 @@ class SystemValues:
        x2delay = 0
        skiphtml = False
        usecallgraph = False
-       ftopfunc = 'suspend_devices_and_enter'
+       ftopfunc = 'pm_suspend'
        ftop = False
        usetraceevents = False
        usetracemarkers = True
@@ -164,6 +166,8 @@ class SystemValues:
        predelay = 0
        postdelay = 0
        pmdebug = ''
+       tmstart = 'SUSPEND START %Y%m%d-%H:%M:%S.%f'
+       tmend = 'RESUME COMPLETE %Y%m%d-%H:%M:%S.%f'
        tracefuncs = {
                'sys_sync': {},
                'ksys_sync': {},
@@ -183,9 +187,11 @@ class SystemValues:
                'acpi_s2idle_sync': {},
                'acpi_s2idle_begin': {},
                'acpi_s2idle_prepare': {},
+               'acpi_s2idle_prepare_late': {},
                'acpi_s2idle_wake': {},
                'acpi_s2idle_wakeup': {},
                'acpi_s2idle_restore': {},
+               'acpi_s2idle_restore_early': {},
                'hibernate_preallocate_memory': {},
                'create_basic_memory_bitmaps': {},
                'swsusp_write': {},
@@ -270,12 +276,23 @@ class SystemValues:
                'intel_opregion_init': {},
                'intel_fbdev_set_suspend': {},
        }
+       infocmds = [
+               [0, 'kparams', 'cat', '/proc/cmdline'],
+               [0, 'mcelog', 'mcelog'],
+               [0, 'pcidevices', 'lspci', '-tv'],
+               [0, 'usbdevices', 'lsusb', '-t'],
+               [1, 'interrupts', 'cat', '/proc/interrupts'],
+               [1, 'wakeups', 'cat', '/sys/kernel/debug/wakeup_sources'],
+               [2, 'gpecounts', 'sh', '-c', 'grep -v invalid /sys/firmware/acpi/interrupts/*'],
+               [2, 'suspendstats', 'sh', '-c', 'grep -v invalid /sys/power/suspend_stats/*'],
+               [2, 'cpuidle', 'sh', '-c', 'grep -v invalid /sys/devices/system/cpu/cpu*/cpuidle/state*/s2idle/*'],
+               [2, 'battery', 'sh', '-c', 'grep -v invalid /sys/class/power_supply/*/*'],
+       ]
        cgblacklist = []
        kprobes = dict()
        timeformat = '%.3f'
        cmdline = '%s %s' % \
                        (os.path.basename(sys.argv[0]), ' '.join(sys.argv[1:]))
-       kparams = ''
        sudouser = ''
        def __init__(self):
                self.archargs = 'args_'+platform.machine()
@@ -295,6 +312,9 @@ class SystemValues:
                if os.getuid() == 0 and 'SUDO_USER' in os.environ and \
                        os.environ['SUDO_USER']:
                        self.sudouser = os.environ['SUDO_USER']
+       def resetlog(self):
+               self.logmsg = ''
+               self.platinfo = []
        def vprint(self, msg):
                self.logmsg += msg+'\n'
                if self.verbose or msg.startswith('WARNING:'):
@@ -304,11 +324,11 @@ class SystemValues:
                        return
                signame = self.signames[signum] if signum in self.signames else 'UNKNOWN'
                msg = 'Signal %s caused a tool exit, line %d' % (signame, frame.f_lineno)
-               sysvals.outputResult({'error':msg})
+               self.outputResult({'error':msg})
                sys.exit(3)
        def signalHandlerInit(self):
                capture = ['BUS', 'SYS', 'XCPU', 'XFSZ', 'PWR', 'HUP', 'INT', 'QUIT',
-                       'ILL', 'ABRT', 'FPE', 'SEGV', 'TERM', 'TSTP']
+                       'ILL', 'ABRT', 'FPE', 'SEGV', 'TERM']
                self.signames = dict()
                for i in capture:
                        s = 'SIG'+i
@@ -336,6 +356,8 @@ class SystemValues:
                        self.outputResult({'error':msg})
                        sys.exit(1)
                return False
+       def usable(self, file):
+               return (os.path.exists(file) and os.path.getsize(file) > 0)
        def getExec(self, cmd):
                try:
                        fp = Popen(['which', cmd], stdout=PIPE, stderr=PIPE).stdout
@@ -389,12 +411,6 @@ class SystemValues:
                r = info['bios-release-date'] if 'bios-release-date' in info else ''
                self.sysstamp = '# sysinfo | man:%s | plat:%s | cpu:%s | bios:%s | biosdate:%s | numcpu:%d | memsz:%d | memfr:%d' % \
                        (m, p, c, b, r, self.cpucount, self.memtotal, self.memfree)
-               try:
-                       kcmd = open('/proc/cmdline', 'r').read().strip()
-               except:
-                       kcmd = ''
-               if kcmd:
-                       self.sysstamp += '\n# kparams | %s' % kcmd
        def printSystemInfo(self, fatal=False):
                self.rootCheck(True)
                out = dmidecode(self.mempath, fatal)
@@ -441,6 +457,7 @@ class SystemValues:
                        self.testdir+'/'+self.prefix+'_'+self.suspendmode+'.html'
                if not os.path.isdir(self.testdir):
                        os.makedirs(self.testdir)
+               self.sudoUserchown(self.testdir)
        def getValueList(self, value):
                out = []
                for i in value.split(','):
@@ -486,7 +503,7 @@ class SystemValues:
                fp.close()
                self.dmesgstart = float(ktime)
        def getdmesg(self, testdata):
-               op = self.writeDatafileHeader(sysvals.dmesgfile, testdata)
+               op = self.writeDatafileHeader(self.dmesgfile, testdata)
                # store all new dmesg lines since initdmesg was called
                fp = Popen('dmesg', stdout=PIPE).stdout
                for line in fp:
@@ -716,9 +733,10 @@ class SystemValues:
                        if name == f:
                                return True
                return False
-       def initFtrace(self):
-               self.printSystemInfo(False)
-               pprint('INITIALIZING FTRACE...')
+       def initFtrace(self, quiet=False):
+               if not quiet:
+                       sysvals.printSystemInfo(False)
+                       pprint('INITIALIZING FTRACE...')
                # turn trace off
                self.fsetVal('0', 'tracing_on')
                self.cleanupFtrace()
@@ -746,7 +764,7 @@ class SystemValues:
                        if tgtsize < 65536:
                                tgtsize = int(self.fgetVal('buffer_size_kb')) * cpus
                                break
-               pprint('Setting trace buffers to %d kB (%d kB per cpu)' % (tgtsize, tgtsize/cpus))
+               self.vprint('Setting trace buffers to %d kB (%d kB per cpu)' % (tgtsize, tgtsize/cpus))
                # initialize the callgraph trace
                if(self.usecallgraph):
                        # set trace type
@@ -782,7 +800,8 @@ class SystemValues:
                        if self.usedevsrc:
                                for name in self.dev_tracefuncs:
                                        self.defaultKprobe(name, self.dev_tracefuncs[name])
-                       pprint('INITIALIZING KPROBES...')
+                       if not quiet:
+                               pprint('INITIALIZING KPROBES...')
                        self.addKprobes(self.verbose)
                if(self.usetraceevents):
                        # turn trace events on
@@ -827,21 +846,10 @@ class SystemValues:
                                fw = test['fw']
                                if(fw):
                                        fp.write('# fwsuspend %u fwresume %u\n' % (fw[0], fw[1]))
-                       if 'mcelog' in test:
-                               fp.write('# mcelog %s\n' % test['mcelog'])
                        if 'turbo' in test:
                                fp.write('# turbostat %s\n' % test['turbo'])
-                       if 'bat' in test:
-                               (a1, c1), (a2, c2) = test['bat']
-                               fp.write('# battery %s %d %s %d\n' % (a1, c1, a2, c2))
                        if 'wifi' in test:
-                               wstr = []
-                               for wifi in test['wifi']:
-                                       tmp = []
-                                       for key in sorted(wifi):
-                                               tmp.append('%s:%s' % (key, wifi[key]))
-                                       wstr.append('|'.join(tmp))
-                               fp.write('# wifi %s\n' % (','.join(wstr)))
+                               fp.write('# wifi %s\n' % test['wifi'])
                        if test['error'] or len(testdata) > 1:
                                fp.write('# enter_sleep_error %s\n' % test['error'])
                return fp
@@ -901,23 +909,7 @@ class SystemValues:
        def b64zip(self, data):
                out = base64.b64encode(codecs.encode(data.encode(), 'zlib')).decode()
                return out
-       def mcelog(self, clear=False):
-               cmd = self.getExec('mcelog')
-               if not cmd:
-                       return ''
-               if clear:
-                       call(cmd+' > /dev/null 2>&1', shell=True)
-                       return ''
-               try:
-                       fp = Popen([cmd], stdout=PIPE, stderr=PIPE).stdout
-                       out = ascii(fp.read()).strip()
-                       fp.close()
-               except:
-                       return ''
-               if not out:
-                       return ''
-               return self.b64zip(out)
-       def platforminfo(self):
+       def platforminfo(self, cmdafter):
                # add platform info on to a completed ftrace file
                if not os.path.exists(self.ftracefile):
                        return False
@@ -1001,31 +993,76 @@ class SystemValues:
                footer += '# platform-devinfo: %s\n' % self.b64zip(out)
 
                # add a line for each of these commands with their outputs
-               cmds = [
-                       ['pcidevices', 'lspci', '-tv'],
-                       ['interrupts', 'cat', '/proc/interrupts'],
-                       ['gpecounts', 'sh', '-c', 'grep -v invalid /sys/firmware/acpi/interrupts/gpe*'],
-               ]
-               for cargs in cmds:
-                       name = cargs[0]
-                       cmdline = ' '.join(cargs[1:])
-                       cmdpath = self.getExec(cargs[1])
-                       if not cmdpath:
+               for name, cmdline, info in cmdafter:
+                       footer += '# platform-%s: %s | %s\n' % (name, cmdline, self.b64zip(info))
+
+               with self.openlog(self.ftracefile, 'a') as fp:
+                       fp.write(footer)
+               return True
+       def commonPrefix(self, list):
+               if len(list) < 2:
+                       return ''
+               prefix = list[0]
+               for s in list[1:]:
+                       while s[:len(prefix)] != prefix and prefix:
+                               prefix = prefix[:len(prefix)-1]
+                       if not prefix:
+                               break
+               if '/' in prefix and prefix[-1] != '/':
+                       prefix = prefix[0:prefix.rfind('/')+1]
+               return prefix
+       def dictify(self, text, format):
+               out = dict()
+               header = True if format == 1 else False
+               delim = ' ' if format == 1 else ':'
+               for line in text.split('\n'):
+                       if header:
+                               header, out['@'] = False, line
+                               continue
+                       line = line.strip()
+                       if delim in line:
+                               data = line.split(delim, 1)
+                               num = re.search(r'[\d]+', data[1])
+                               if format == 2 and num:
+                                       out[data[0].strip()] = num.group()
+                               else:
+                                       out[data[0].strip()] = data[1]
+               return out
+       def cmdinfo(self, begin, debug=False):
+               out = []
+               if begin:
+                       self.cmd1 = dict()
+               for cargs in self.infocmds:
+                       delta, name = cargs[0], cargs[1]
+                       cmdline, cmdpath = ' '.join(cargs[2:]), self.getExec(cargs[2])
+                       if not cmdpath or (begin and not delta):
                                continue
-                       cmd = [cmdpath] + cargs[2:]
                        try:
-                               fp = Popen(cmd, stdout=PIPE, stderr=PIPE).stdout
+                               fp = Popen([cmdpath]+cargs[3:], stdout=PIPE, stderr=PIPE).stdout
                                info = ascii(fp.read()).strip()
                                fp.close()
                        except:
                                continue
-                       if not info:
-                               continue
-                       footer += '# platform-%s: %s | %s\n' % (name, cmdline, self.b64zip(info))
-
-               with self.openlog(self.ftracefile, 'a') as fp:
-                       fp.write(footer)
-               return True
+                       if not debug and begin:
+                               self.cmd1[name] = self.dictify(info, delta)
+                       elif not debug and delta and name in self.cmd1:
+                               before, after = self.cmd1[name], self.dictify(info, delta)
+                               dinfo = ('\t%s\n' % before['@']) if '@' in before else ''
+                               prefix = self.commonPrefix(list(before.keys()))
+                               for key in sorted(before):
+                                       if key in after and before[key] != after[key]:
+                                               title = key.replace(prefix, '')
+                                               if delta == 2:
+                                                       dinfo += '\t%s : %s -> %s\n' % \
+                                                               (title, before[key].strip(), after[key].strip())
+                                               else:
+                                                       dinfo += '%10s (start) : %s\n%10s (after) : %s\n' % \
+                                                               (title, before[key], title, after[key])
+                               dinfo = '\tnothing changed' if not dinfo else dinfo.rstrip()
+                               out.append((name, cmdline, dinfo))
+                       else:
+                               out.append((name, cmdline, '\tnothing' if not info else info))
+               return out
        def haveTurbostat(self):
                if not self.tstat:
                        return False
@@ -1035,8 +1072,8 @@ class SystemValues:
                fp = Popen([cmd, '-v'], stdout=PIPE, stderr=PIPE).stderr
                out = ascii(fp.read()).strip()
                fp.close()
-               if re.match('turbostat version [0-9\.]* .*', out):
-                       sysvals.vprint(out)
+               if re.match('turbostat version .*', out):
+                       self.vprint(out)
                        return True
                return False
        def turbostat(self):
@@ -1056,11 +1093,11 @@ class SystemValues:
                fp.close()
                if not keyline or not valline or len(keyline) != len(valline):
                        errmsg = 'unrecognized turbostat output:\n'+rawout.strip()
-                       sysvals.vprint(errmsg)
-                       if not sysvals.verbose:
+                       self.vprint(errmsg)
+                       if not self.verbose:
                                pprint(errmsg)
                        return ''
-               if sysvals.verbose:
+               if self.verbose:
                        pprint(rawout.strip())
                out = []
                for key in keyline:
@@ -1068,30 +1105,36 @@ class SystemValues:
                        val = valline[idx]
                        out.append('%s=%s' % (key, val))
                return '|'.join(out)
-       def checkWifi(self):
-               out = dict()
-               iwcmd, ifcmd = self.getExec('iwconfig'), self.getExec('ifconfig')
-               if not iwcmd or not ifcmd:
-                       return out
-               fp = Popen(iwcmd, stdout=PIPE, stderr=PIPE).stdout
-               for line in fp:
-                       m = re.match('(?P<dev>\S*) .* ESSID:(?P<ess>\S*)', ascii(line))
-                       if not m:
+       def wifiDetails(self, dev):
+               try:
+                       info = open('/sys/class/net/%s/device/uevent' % dev, 'r').read().strip()
+               except:
+                       return dev
+               vals = [dev]
+               for prop in info.split('\n'):
+                       if prop.startswith('DRIVER=') or prop.startswith('PCI_ID='):
+                               vals.append(prop.split('=')[-1])
+               return ':'.join(vals)
+       def checkWifi(self, dev=''):
+               try:
+                       w = open('/proc/net/wireless', 'r').read().strip()
+               except:
+                       return ''
+               for line in reversed(w.split('\n')):
+                       m = re.match(' *(?P<dev>.*): (?P<stat>[0-9a-f]*) .*', w.split('\n')[-1])
+                       if not m or (dev and dev != m.group('dev')):
                                continue
-                       out['device'] = m.group('dev')
-                       if '"' in m.group('ess'):
-                               out['essid'] = m.group('ess').strip('"')
-                               break
-               fp.close()
-               if 'device' in out:
-                       fp = Popen([ifcmd, out['device']], stdout=PIPE, stderr=PIPE).stdout
-                       for line in fp:
-                               m = re.match('.* inet (?P<ip>[0-9\.]*)', ascii(line))
-                               if m:
-                                       out['ip'] = m.group('ip')
-                                       break
-                       fp.close()
-               return out
+                       return m.group('dev')
+               return ''
+       def pollWifi(self, dev, timeout=60):
+               start = time.time()
+               while (time.time() - start) < timeout:
+                       w = self.checkWifi(dev)
+                       if w:
+                               return '%s reconnected %.2f' % \
+                                       (self.wifiDetails(dev), max(0, time.time() - start))
+                       time.sleep(0.01)
+               return '%s timeout %d' % (self.wifiDetails(dev), timeout)
        def errorSummary(self, errinfo, msg):
                found = False
                for entry in errinfo:
@@ -1113,8 +1156,9 @@ class SystemValues:
                                arr[j] = arr[j]\
                                        .replace('\\', '\\\\').replace(']', '\]').replace('[', '\[')\
                                        .replace('.', '\.').replace('+', '\+').replace('*', '\*')\
-                                       .replace('(', '\(').replace(')', '\)')
-               mstr = ' '.join(arr)
+                                       .replace('(', '\(').replace(')', '\)').replace('}', '\}')\
+                                       .replace('{', '\{')
+               mstr = ' *'.join(arr)
                entry = {
                        'line': msg,
                        'match': mstr,
@@ -1122,6 +1166,44 @@ class SystemValues:
                        'urls': {self.hostname: [self.htmlfile]}
                }
                errinfo.append(entry)
+       def multistat(self, start, idx, finish):
+               if 'time' in self.multitest:
+                       id = '%d Duration=%dmin' % (idx+1, self.multitest['time'])
+               else:
+                       id = '%d/%d' % (idx+1, self.multitest['count'])
+               t = time.time()
+               if 'start' not in self.multitest:
+                       self.multitest['start'] = self.multitest['last'] = t
+                       self.multitest['total'] = 0.0
+                       pprint('TEST (%s) START' % id)
+                       return
+               dt = t - self.multitest['last']
+               if not start:
+                       if idx == 0 and self.multitest['delay'] > 0:
+                               self.multitest['total'] += self.multitest['delay']
+                       pprint('TEST (%s) COMPLETE -- Duration %.1fs' % (id, dt))
+                       return
+               self.multitest['total'] += dt
+               self.multitest['last'] = t
+               avg = self.multitest['total'] / idx
+               if 'time' in self.multitest:
+                       left = finish - datetime.now()
+                       left -= timedelta(microseconds=left.microseconds)
+               else:
+                       left = timedelta(seconds=((self.multitest['count'] - idx) * int(avg)))
+               pprint('TEST (%s) START - Avg Duration %.1fs, Time left %s' % \
+                       (id, avg, str(left)))
+       def multiinit(self, c, d):
+               sz, unit = 'count', 'm'
+               if c.endswith('d') or c.endswith('h') or c.endswith('m'):
+                       sz, unit, c = 'time', c[-1], c[:-1]
+               self.multitest['run'] = True
+               self.multitest[sz] = getArgInt('multi: n d (exec count)', c, 1, 1000000, False)
+               self.multitest['delay'] = getArgInt('multi: n d (delay between tests)', d, 0, 3600, False)
+               if unit == 'd':
+                       self.multitest[sz] *= 1440
+               elif unit == 'h':
+                       self.multitest[sz] *= 60
 
 sysvals = SystemValues()
 switchvalues = ['enable', 'disable', 'on', 'off', 'true', 'false', '1', '0']
@@ -1210,25 +1292,30 @@ class Data:
                'resume_complete': {'order': 9, 'color': '#FFFFCC'},
        }
        errlist = {
-               'HWERROR' : '.*\[ *Hardware Error *\].*',
-               'FWBUG'   : '.*\[ *Firmware Bug *\].*',
-               'BUG'     : '.*BUG.*',
-               'ERROR'   : '.*ERROR.*',
-               'WARNING' : '.*WARNING.*',
-               'IRQ'     : '.*genirq: .*',
-               'TASKFAIL': '.*Freezing of tasks *.*',
-               'ACPI'    : '.*ACPI *(?P<b>[A-Za-z]*) *Error[: ].*',
-               'DEVFAIL' : '.* failed to (?P<b>[a-z]*) async: .*',
-               'DISKFULL': '.*No space left on device.*',
-               'USBERR'  : '.*usb .*device .*, error [0-9-]*',
-               'ATAERR'  : ' *ata[0-9\.]*: .*failed.*',
-               'MEIERR'  : ' *mei.*: .*failed.*',
-               'TPMERR'  : '(?i) *tpm *tpm[0-9]*: .*error.*',
+               'HWERROR' : r'.*\[ *Hardware Error *\].*',
+               'FWBUG'   : r'.*\[ *Firmware Bug *\].*',
+               'BUG'     : r'(?i).*\bBUG\b.*',
+               'ERROR'   : r'(?i).*\bERROR\b.*',
+               'WARNING' : r'(?i).*\bWARNING\b.*',
+               'FAULT'   : r'(?i).*\bFAULT\b.*',
+               'FAIL'    : r'(?i).*\bFAILED\b.*',
+               'INVALID' : r'(?i).*\bINVALID\b.*',
+               'CRASH'   : r'(?i).*\bCRASHED\b.*',
+               'IRQ'     : r'.*\bgenirq: .*',
+               'TASKFAIL': r'.*Freezing of tasks *.*',
+               'ACPI'    : r'.*\bACPI *(?P<b>[A-Za-z]*) *Error[: ].*',
+               'DISKFULL': r'.*\bNo space left on device.*',
+               'USBERR'  : r'.*usb .*device .*, error [0-9-]*',
+               'ATAERR'  : r' *ata[0-9\.]*: .*failed.*',
+               'MEIERR'  : r' *mei.*: .*failed.*',
+               'TPMERR'  : r'(?i) *tpm *tpm[0-9]*: .*error.*',
        }
        def __init__(self, num):
                idchar = 'abcdefghij'
                self.start = 0.0 # test start
                self.end = 0.0   # test end
+               self.hwstart = 0 # rtc test start
+               self.hwend = 0   # rtc test end
                self.tSuspended = 0.0 # low-level suspend start
                self.tResumed = 0.0   # low-level resume start
                self.tKernSus = 0.0   # kernel level suspend start
@@ -1240,10 +1327,8 @@ class Data:
                self.stamp = 0
                self.outfile = ''
                self.kerror = False
-               self.battery = 0
-               self.wifi = 0
+               self.wifi = dict()
                self.turbostat = 0
-               self.mcelog = 0
                self.enterfail = ''
                self.currphase = ''
                self.pstl = dict()    # process timeline
@@ -1308,6 +1393,8 @@ class Data:
                                continue
                        dir = 'suspend' if t < self.tSuspended else 'resume'
                        msg = m.group('msg')
+                       if re.match('capability: warning: .*', msg):
+                               continue
                        for err in self.errlist:
                                if re.match(self.errlist[err], msg):
                                        list.append((msg, err, dir, t, i, i))
@@ -1316,17 +1403,26 @@ class Data:
                msglist = []
                for msg, type, dir, t, idx1, idx2 in list:
                        msglist.append(msg)
-                       sysvals.vprint('kernel %s found in %s at %f' % (type, dir, t))
                        self.errorinfo[dir].append((type, t, idx1, idx2))
                if self.kerror:
                        sysvals.dmesglog = True
                if len(self.dmesgtext) < 1 and sysvals.dmesgfile:
                        lf.close()
                return msglist
-       def setStart(self, time):
+       def setStart(self, time, msg=''):
                self.start = time
-       def setEnd(self, time):
+               if msg:
+                       try:
+                               self.hwstart = datetime.strptime(msg, sysvals.tmstart)
+                       except:
+                               self.hwstart = 0
+       def setEnd(self, time, msg=''):
                self.end = time
+               if msg:
+                       try:
+                               self.hwend = datetime.strptime(msg, sysvals.tmend)
+                       except:
+                               self.hwend = 0
        def isTraceEventOutsideDeviceCalls(self, pid, time):
                for phase in self.sortedPhases():
                        list = self.dmesg[phase]['list']
@@ -1546,6 +1642,14 @@ class Data:
                                        self.trimTime(tS, tL, left)
                                        self.tLow.append('%.0f'%(tL*1000))
                        lp = phase
+       def getMemTime(self):
+               if not self.hwstart or not self.hwend:
+                       return
+               stime = (self.tSuspended - self.start) * 1000000
+               rtime = (self.end - self.tResumed) * 1000000
+               hws = self.hwstart + timedelta(microseconds=stime)
+               hwr = self.hwend - timedelta(microseconds=rtime)
+               self.tLow.append('%.0f'%((hwr - hws).total_seconds() * 1000))
        def getTimeValues(self):
                sktime = (self.tSuspended - self.tKernSus) * 1000
                rktime = (self.tKernRes - self.tResumed) * 1000
@@ -1883,9 +1987,9 @@ class Data:
                        c = self.addProcessUsageEvent(ps, tres)
                        if c > 0:
                                sysvals.vprint('%25s (res): %d' % (ps, c))
-       def handleEndMarker(self, time):
+       def handleEndMarker(self, time, msg=''):
                dm = self.dmesg
-               self.setEnd(time)
+               self.setEnd(time, msg)
                self.initDevicegroups()
                # give suspend_prepare an end if needed
                if 'suspend_prepare' in dm and dm['suspend_prepare']['end'] < 0:
@@ -2071,7 +2175,7 @@ class FTraceLine:
                if not self.fevent:
                        return False
                if sysvals.usetracemarkers:
-                       if(self.name == 'SUSPEND START'):
+                       if(self.name.startswith('SUSPEND START')):
                                return True
                        return False
                else:
@@ -2084,7 +2188,7 @@ class FTraceLine:
                if not self.fevent:
                        return False
                if sysvals.usetracemarkers:
-                       if(self.name == 'RESUME COMPLETE'):
+                       if(self.name.startswith('RESUME COMPLETE')):
                                return True
                        return False
                else:
@@ -2444,7 +2548,7 @@ class Timeline:
        def createHeader(self, sv, stamp):
                if(not stamp['time']):
                        return
-               self.html += '<div class="version"><a href="https://01.org/suspendresume">%s v%s</a></div>' \
+               self.html += '<div class="version"><a href="https://01.org/pm-graph">%s v%s</a></div>' \
                        % (sv.title, sv.version)
                if sv.logmsg and sv.testlog:
                        self.html += '<button id="showtest" class="logbtn btnfmt">log</button>'
@@ -2670,14 +2774,11 @@ class TestProps:
        stampfmt = '# [a-z]*-(?P<m>[0-9]{2})(?P<d>[0-9]{2})(?P<y>[0-9]{2})-'+\
                                '(?P<H>[0-9]{2})(?P<M>[0-9]{2})(?P<S>[0-9]{2})'+\
                                ' (?P<host>.*) (?P<mode>.*) (?P<kernel>.*)$'
-       batteryfmt = '^# battery (?P<a1>\w*) (?P<c1>\d*) (?P<a2>\w*) (?P<c2>\d*)'
-       wififmt    = '^# wifi (?P<w>.*)'
+       wififmt    = '^# wifi *(?P<d>\S*) *(?P<s>\S*) *(?P<t>[0-9\.]+).*'
        tstatfmt   = '^# turbostat (?P<t>\S*)'
-       mcelogfmt  = '^# mcelog (?P<m>\S*)'
        testerrfmt = '^# enter_sleep_error (?P<e>.*)'
        sysinfofmt = '^# sysinfo .*'
        cmdlinefmt = '^# command \| (?P<cmd>.*)'
-       kparamsfmt = '^# kparams \| (?P<kp>.*)'
        devpropfmt = '# Device Properties: .*'
        pinfofmt   = '# platform-(?P<val>[a-z,A-Z,0-9]*): (?P<info>.*)'
        tracertypefmt = '# tracer: (?P<t>.*)'
@@ -2695,11 +2796,8 @@ class TestProps:
                self.stamp = ''
                self.sysinfo = ''
                self.cmdline = ''
-               self.kparams = ''
                self.testerror = []
-               self.mcelog = []
                self.turbostat = []
-               self.battery = []
                self.wifi = []
                self.fwdata = []
                self.ftrace_line_fmt = self.ftrace_line_fmt_nop
@@ -2721,21 +2819,12 @@ class TestProps:
                elif re.match(self.sysinfofmt, line):
                        self.sysinfo = line
                        return True
-               elif re.match(self.kparamsfmt, line):
-                       self.kparams = line
-                       return True
                elif re.match(self.cmdlinefmt, line):
                        self.cmdline = line
                        return True
-               elif re.match(self.mcelogfmt, line):
-                       self.mcelog.append(line)
-                       return True
                elif re.match(self.tstatfmt, line):
                        self.turbostat.append(line)
                        return True
-               elif re.match(self.batteryfmt, line):
-                       self.battery.append(line)
-                       return True
                elif re.match(self.wififmt, line):
                        self.wifi.append(line)
                        return True
@@ -2749,6 +2838,8 @@ class TestProps:
        def parseStamp(self, data, sv):
                # global test data
                m = re.match(self.stampfmt, self.stamp)
+               if not self.stamp or not m:
+                       doError('data does not include the expected stamp')
                data.stamp = {'time': '', 'host': '', 'mode': ''}
                dt = datetime(int(m.group('y'))+2000, int(m.group('m')),
                        int(m.group('d')), int(m.group('H')), int(m.group('M')),
@@ -2780,10 +2871,6 @@ class TestProps:
                m = re.match(self.cmdlinefmt, self.cmdline)
                if m:
                        sv.cmdline = m.group('cmd')
-               if self.kparams:
-                       m = re.match(self.kparamsfmt, self.kparams)
-                       if m:
-                               sv.kparams = m.group('kp')
                if not sv.stamp:
                        sv.stamp = data.stamp
                # firmware data
@@ -2793,26 +2880,18 @@ class TestProps:
                                data.fwSuspend, data.fwResume = int(m.group('s')), int(m.group('r'))
                                if(data.fwSuspend > 0 or data.fwResume > 0):
                                        data.fwValid = True
-               # mcelog data
-               if len(self.mcelog) > data.testnumber:
-                       m = re.match(self.mcelogfmt, self.mcelog[data.testnumber])
-                       if m:
-                               data.mcelog = sv.b64unzip(m.group('m'))
                # turbostat data
                if len(self.turbostat) > data.testnumber:
                        m = re.match(self.tstatfmt, self.turbostat[data.testnumber])
                        if m:
                                data.turbostat = m.group('t')
-               # battery data
-               if len(self.battery) > data.testnumber:
-                       m = re.match(self.batteryfmt, self.battery[data.testnumber])
-                       if m:
-                               data.battery = m.groups()
                # wifi data
                if len(self.wifi) > data.testnumber:
                        m = re.match(self.wififmt, self.wifi[data.testnumber])
                        if m:
-                               data.wifi = m.group('w')
+                               data.wifi = {'dev': m.group('d'), 'stat': m.group('s'),
+                                       'time': float(m.group('t'))}
+                               data.stamp['wifi'] = m.group('d')
                # sleep mode enter errors
                if len(self.testerror) > data.testnumber:
                        m = re.match(self.testerrfmt, self.testerror[data.testnumber])
@@ -3012,13 +3091,13 @@ def appendIncompleteTraceLog(testruns):
                if(t.startMarker()):
                        data = testrun[testidx].data
                        tp.parseStamp(data, sysvals)
-                       data.setStart(t.time)
+                       data.setStart(t.time, t.name)
                        continue
                if(not data):
                        continue
                # find the end of resume
                if(t.endMarker()):
-                       data.setEnd(t.time)
+                       data.setEnd(t.time, t.name)
                        testidx += 1
                        if(testidx >= testcnt):
                                break
@@ -3081,7 +3160,7 @@ def parseTraceLog(live=False):
                doError('%s does not exist' % sysvals.ftracefile)
        if not live:
                sysvals.setupAllKprobes()
-       ksuscalls = ['pm_prepare_console']
+       ksuscalls = ['ksys_sync', 'pm_prepare_console']
        krescalls = ['pm_restore_console']
        tracewatch = ['irq_wakeup']
        if sysvals.usekprobes:
@@ -3094,7 +3173,7 @@ def parseTraceLog(live=False):
        testruns = []
        testdata = []
        testrun = 0
-       data = 0
+       data, limbo = 0, True
        tf = sysvals.openlog(sysvals.ftracefile, 'r')
        phase = 'suspend_prepare'
        for line in tf:
@@ -3141,16 +3220,16 @@ def parseTraceLog(live=False):
                        continue
                # find the start of suspend
                if(t.startMarker()):
-                       data = Data(len(testdata))
+                       data, limbo = Data(len(testdata)), False
                        testdata.append(data)
                        testrun = TestRun(data)
                        testruns.append(testrun)
                        tp.parseStamp(data, sysvals)
-                       data.setStart(t.time)
+                       data.setStart(t.time, t.name)
                        data.first_suspend_prepare = True
                        phase = data.setPhase('suspend_prepare', t.time, True)
                        continue
-               if(not data):
+               if(not data or limbo):
                        continue
                # process cpu exec line
                if t.type == 'tracing_mark_write':
@@ -3167,14 +3246,16 @@ def parseTraceLog(live=False):
                                continue
                # find the end of resume
                if(t.endMarker()):
-                       data.handleEndMarker(t.time)
+                       if data.tKernRes == 0:
+                               data.tKernRes = t.time
+                       data.handleEndMarker(t.time, t.name)
                        if(not sysvals.usetracemarkers):
                                # no trace markers? then quit and be sure to finish recording
                                # the event we used to trigger resume end
                                if('thaw_processes' in testrun.ttemp and len(testrun.ttemp['thaw_processes']) > 0):
                                        # if an entry exists, assume this is its end
                                        testrun.ttemp['thaw_processes'][-1]['end'] = t.time
-                               break
+                       limbo = True
                        continue
                # trace event processing
                if(t.fevent):
@@ -3197,7 +3278,7 @@ def parseTraceLog(live=False):
                                # -- phase changes --
                                # start of kernel suspend
                                if(re.match('suspend_enter\[.*', t.name)):
-                                       if(isbegin):
+                                       if(isbegin and data.tKernSus == 0):
                                                data.tKernSus = t.time
                                        continue
                                # suspend_prepare start
@@ -3225,7 +3306,7 @@ def parseTraceLog(live=False):
                                elif(re.match('machine_suspend\[.*', t.name)):
                                        if(isbegin):
                                                lp = data.lastPhase()
-                                               if lp == 'resume_machine':
+                                               if lp.startswith('resume_machine'):
                                                        data.dmesg[lp]['end'] = t.time
                                                phase = data.setPhase('suspend_machine', data.dmesg[lp]['end'], True)
                                                data.setPhase(phase, t.time, False)
@@ -3320,7 +3401,8 @@ def parseTraceLog(live=False):
                                        'proc': m_proc,
                                })
                                # start of kernel resume
-                               if(phase == 'suspend_prepare' and kprobename in ksuscalls):
+                               if(data.tKernSus == 0 and phase == 'suspend_prepare' \
+                                       and kprobename in ksuscalls):
                                        data.tKernSus = t.time
                        elif(t.freturn):
                                if(key not in tp.ktemp) or len(tp.ktemp[key]) < 1:
@@ -3355,7 +3437,7 @@ def parseTraceLog(live=False):
                sysvals.vprint('WARNING: ftrace start marker is missing')
        if data and not data.devicegroups:
                sysvals.vprint('WARNING: ftrace end marker is missing')
-               data.handleEndMarker(t.time)
+               data.handleEndMarker(t.time, t.name)
 
        if sysvals.suspendmode == 'command':
                for test in testruns:
@@ -3476,6 +3558,10 @@ def parseTraceLog(live=False):
                                        data.fwValid = False
                                sysvals.vprint('WARNING: phase "%s" is missing!' % p)
                        lp = p
+               if not terr and 'dev' in data.wifi and data.wifi['stat'] == 'timeout':
+                       terr = '%s%s failed in wifi_resume <i>(%s %.0fs timeout)</i>' % \
+                               (sysvals.suspendmode, tn, data.wifi['dev'], data.wifi['time'])
+                       error.append(terr)
                if not terr and data.enterfail:
                        pprint('test%s FAILED: enter %s failed with %s' % (tn, sysvals.suspendmode, data.enterfail))
                        terr = 'test%s failed to enter %s mode' % (tn, sysvals.suspendmode)
@@ -3933,7 +4019,7 @@ def createHTMLSummarySimple(testruns, htmlfile, title):
        tAvg, tMin, tMax, tMed = [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [dict(), dict()]
        iMin, iMed, iMax = [0, 0], [0, 0], [0, 0]
        num = 0
-       useturbo = False
+       useturbo = usewifi = False
        lastmode = ''
        cnt = dict()
        for data in sorted(testruns, key=lambda v:(v['mode'], v['host'], v['kernel'], v['time'])):
@@ -3952,17 +4038,17 @@ def createHTMLSummarySimple(testruns, htmlfile, title):
                        tAvg, tMin, tMax, tMed = [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [dict(), dict()]
                        iMin, iMed, iMax = [0, 0], [0, 0], [0, 0]
                        num = 0
-               pkgpc10 = syslpi = ''
+               pkgpc10 = syslpi = wifi = ''
                if 'pkgpc10' in data and 'syslpi' in data:
-                       pkgpc10 = data['pkgpc10']
-                       syslpi = data['syslpi']
-                       useturbo = True
+                       pkgpc10, syslpi, useturbo = data['pkgpc10'], data['syslpi'], True
+               if 'wifi' in data:
+                       wifi, usewifi = data['wifi'], True
                res = data['result']
                tVal = [float(data['suspend']), float(data['resume'])]
                list[mode]['data'].append([data['host'], data['kernel'],
                        data['time'], tVal[0], tVal[1], data['url'], res,
                        data['issues'], data['sus_worst'], data['sus_worsttime'],
-                       data['res_worst'], data['res_worsttime'], pkgpc10, syslpi])
+                       data['res_worst'], data['res_worsttime'], pkgpc10, syslpi, wifi])
                idx = len(list[mode]['data']) - 1
                if res.startswith('fail in'):
                        res = 'fail'
@@ -4002,7 +4088,12 @@ def createHTMLSummarySimple(testruns, htmlfile, title):
        td = '\t<td>{0}</td>\n'
        tdh = '\t<td{1}>{0}</td>\n'
        tdlink = '\t<td><a href="{0}">html</a></td>\n'
-       colspan = '14' if useturbo else '12'
+       cols = 12
+       if useturbo:
+               cols += 2
+       if usewifi:
+               cols += 1
+       colspan = '%d' % cols
 
        # table header
        html += '<table>\n<tr>\n' + th.format('#') +\
@@ -4013,6 +4104,8 @@ def createHTMLSummarySimple(testruns, htmlfile, title):
                th.format('Worst Resume Device') + th.format('RD Time')
        if useturbo:
                html += th.format('PkgPC10') + th.format('SysLPI')
+       if usewifi:
+               html += th.format('Wifi')
        html += th.format('Detail')+'</tr>\n'
        # export list into html
        head = '<tr class="head"><td>{0}</td><td>{1}</td>'+\
@@ -4076,6 +4169,8 @@ def createHTMLSummarySimple(testruns, htmlfile, title):
                        if useturbo:
                                html += td.format(d[12])                                                                # pkg_pc10
                                html += td.format(d[13])                                                                # syslpi
+                       if usewifi:
+                               html += td.format(d[14])                                                                # wifi
                        html += tdlink.format(d[5]) if d[5] else td.format('')          # url
                        html += '</tr>\n'
                        num += 1
@@ -4224,6 +4319,8 @@ def createHTML(testruns, testfail):
                        kerror = True
                if(sysvals.suspendmode in ['freeze', 'standby']):
                        data.trimFreezeTime(testruns[-1].tSuspended)
+               else:
+                       data.getMemTime()
 
        # html function templates
        html_error = '<div id="{1}" title="kernel error/warning" class="err" style="right:{0}%">{2}&rarr;</div>\n'
@@ -4242,13 +4339,10 @@ def createHTML(testruns, testfail):
                '<td class="green">Execution Time: <b>{0} ms</b></td>'\
                '<td class="yellow">Command: <b>{1}</b></td>'\
                '</tr>\n</table>\n'
-       html_timegroups = '<table class="time2">\n<tr>'\
-               '<td class="green" title="time from kernel enter_state({5}) to firmware mode [kernel time only]">{4}Kernel Suspend: {0} ms</td>'\
-               '<td class="purple">{4}Firmware Suspend: {1} ms</td>'\
-               '<td class="purple">{4}Firmware Resume: {2} ms</td>'\
-               '<td class="yellow" title="time from firmware mode to return from kernel enter_state({5}) [kernel time only]">{4}Kernel Resume: {3} ms</td>'\
-               '</tr>\n</table>\n'
        html_fail = '<table class="testfail"><tr><td>{0}</td></tr></table>\n'
+       html_kdesc = '<td class="{3}" title="time spent in kernel execution">{0}Kernel {2}: {1} ms</td>'
+       html_fwdesc = '<td class="{3}" title="time spent in firmware">{0}Firmware {2}: {1} ms</td>'
+       html_wifdesc = '<td class="yellow" title="time for wifi to reconnect after resume complete ({2})">{0}Wifi Resume: {1}</td>'
 
        # html format variables
        scaleH = 20
@@ -4264,13 +4358,10 @@ def createHTML(testruns, testfail):
        # Generate the header for this timeline
        for data in testruns:
                tTotal = data.end - data.start
-               sktime, rktime = data.getTimeValues()
                if(tTotal == 0):
                        doError('No timeline data')
-               if(len(data.tLow) > 0):
-                       low_time = '+'.join(data.tLow)
                if sysvals.suspendmode == 'command':
-                       run_time = '%.0f'%((data.end-data.start)*1000)
+                       run_time = '%.0f' % (tTotal * 1000)
                        if sysvals.testcommand:
                                testdesc = sysvals.testcommand
                        else:
@@ -4279,43 +4370,55 @@ def createHTML(testruns, testfail):
                                testdesc = ordinal(data.testnumber+1)+' '+testdesc
                        thtml = html_timetotal3.format(run_time, testdesc)
                        devtl.html += thtml
-               elif data.fwValid:
-                       suspend_time = '%.0f'%(sktime + (data.fwSuspend/1000000.0))
-                       resume_time = '%.0f'%(rktime + (data.fwResume/1000000.0))
-                       testdesc1 = 'Total'
-                       testdesc2 = ''
-                       stitle = 'time from kernel enter_state(%s) to low-power mode [kernel & firmware time]' % sysvals.suspendmode
-                       rtitle = 'time from low-power mode to return from kernel enter_state(%s) [firmware & kernel time]' % sysvals.suspendmode
-                       if(len(testruns) > 1):
-                               testdesc1 = testdesc2 = ordinal(data.testnumber+1)
-                               testdesc2 += ' '
-                       if(len(data.tLow) == 0):
-                               thtml = html_timetotal.format(suspend_time, \
-                                       resume_time, testdesc1, stitle, rtitle)
-                       else:
-                               thtml = html_timetotal2.format(suspend_time, low_time, \
-                                       resume_time, testdesc1, stitle, rtitle)
-                       devtl.html += thtml
+                       continue
+               # typical full suspend/resume header
+               stot, rtot = sktime, rktime = data.getTimeValues()
+               ssrc, rsrc, testdesc, testdesc2 = ['kernel'], ['kernel'], 'Kernel', ''
+               if data.fwValid:
+                       stot += (data.fwSuspend/1000000.0)
+                       rtot += (data.fwResume/1000000.0)
+                       ssrc.append('firmware')
+                       rsrc.append('firmware')
+                       testdesc = 'Total'
+               if 'time' in data.wifi and data.wifi['stat'] != 'timeout':
+                       rtot += data.end - data.tKernRes + (data.wifi['time'] * 1000.0)
+                       rsrc.append('wifi')
+                       testdesc = 'Total'
+               suspend_time, resume_time = '%.3f' % stot, '%.3f' % rtot
+               stitle = 'time from kernel suspend start to %s mode [%s time]' % \
+                       (sysvals.suspendmode, ' & '.join(ssrc))
+               rtitle = 'time from %s mode to kernel resume complete [%s time]' % \
+                       (sysvals.suspendmode, ' & '.join(rsrc))
+               if(len(testruns) > 1):
+                       testdesc = testdesc2 = ordinal(data.testnumber+1)
+                       testdesc2 += ' '
+               if(len(data.tLow) == 0):
+                       thtml = html_timetotal.format(suspend_time, \
+                               resume_time, testdesc, stitle, rtitle)
+               else:
+                       low_time = '+'.join(data.tLow)
+                       thtml = html_timetotal2.format(suspend_time, low_time, \
+                               resume_time, testdesc, stitle, rtitle)
+               devtl.html += thtml
+               if not data.fwValid and 'dev' not in data.wifi:
+                       continue
+               # extra detail when the times come from multiple sources
+               thtml = '<table class="time2">\n<tr>'
+               thtml += html_kdesc.format(testdesc2, '%.3f'%sktime, 'Suspend', 'green')
+               if data.fwValid:
                        sftime = '%.3f'%(data.fwSuspend / 1000000.0)
                        rftime = '%.3f'%(data.fwResume / 1000000.0)
-                       devtl.html += html_timegroups.format('%.3f'%sktime, \
-                               sftime, rftime, '%.3f'%rktime, testdesc2, sysvals.suspendmode)
-               else:
-                       suspend_time = '%.3f' % sktime
-                       resume_time = '%.3f' % rktime
-                       testdesc = 'Kernel'
-                       stitle = 'time from kernel enter_state(%s) to firmware mode [kernel time only]' % sysvals.suspendmode
-                       rtitle = 'time from firmware mode to return from kernel enter_state(%s) [kernel time only]' % sysvals.suspendmode
-                       if(len(testruns) > 1):
-                               testdesc = ordinal(data.testnumber+1)+' '+testdesc
-                       if(len(data.tLow) == 0):
-                               thtml = html_timetotal.format(suspend_time, \
-                                       resume_time, testdesc, stitle, rtitle)
+                       thtml += html_fwdesc.format(testdesc2, sftime, 'Suspend', 'green')
+                       thtml += html_fwdesc.format(testdesc2, rftime, 'Resume', 'yellow')
+               thtml += html_kdesc.format(testdesc2, '%.3f'%rktime, 'Resume', 'yellow')
+               if 'time' in data.wifi:
+                       if data.wifi['stat'] != 'timeout':
+                               wtime = '%.0f ms'%(data.end - data.tKernRes + (data.wifi['time'] * 1000.0))
                        else:
-                               thtml = html_timetotal2.format(suspend_time, low_time, \
-                                       resume_time, testdesc, stitle, rtitle)
-                       devtl.html += thtml
-
+                               wtime = 'TIMEOUT'
+                       thtml += html_wifdesc.format(testdesc2, wtime, data.wifi['dev'])
+               thtml += '</tr>\n</table>\n'
+               devtl.html += thtml
        if testfail:
                devtl.html += html_fail.format(testfail)
 
@@ -5082,28 +5185,32 @@ def setRuntimeSuspend(before=True):
 # Description:
 #       Execute system suspend through the sysfs interface, then copy the output
 #       dmesg and ftrace files to the test output directory.
-def executeSuspend():
+def executeSuspend(quiet=False):
        pm = ProcessMonitor()
        tp = sysvals.tpath
-       wifi = sysvals.checkWifi()
+       if sysvals.wifi:
+               wifi = sysvals.checkWifi()
        testdata = []
-       battery = True if getBattery() else False
        # run these commands to prepare the system for suspend
        if sysvals.display:
-               pprint('SET DISPLAY TO %s' % sysvals.display.upper())
+               if not quiet:
+                       pprint('SET DISPLAY TO %s' % sysvals.display.upper())
                displayControl(sysvals.display)
                time.sleep(1)
        if sysvals.sync:
-               pprint('SYNCING FILESYSTEMS')
+               if not quiet:
+                       pprint('SYNCING FILESYSTEMS')
                call('sync', shell=True)
        # mark the start point in the kernel ring buffer just as we start
        sysvals.initdmesg()
        # start ftrace
        if(sysvals.usecallgraph or sysvals.usetraceevents):
-               pprint('START TRACING')
+               if not quiet:
+                       pprint('START TRACING')
                sysvals.fsetVal('1', 'tracing_on')
                if sysvals.useprocmon:
                        pm.start()
+       sysvals.cmdinfo(True)
        # execute however many s/r runs requested
        for count in range(1,sysvals.execcount+1):
                # x2delay in between test runs
@@ -5119,15 +5226,14 @@ def executeSuspend():
                                pprint('SUSPEND START')
                        else:
                                pprint('SUSPEND START (press a key to resume)')
-               sysvals.mcelog(True)
-               bat1 = getBattery() if battery else False
                # set rtcwake
                if(sysvals.rtcwake):
-                       pprint('will issue an rtcwake in %d seconds' % sysvals.rtcwaketime)
+                       if not quiet:
+                               pprint('will issue an rtcwake in %d seconds' % sysvals.rtcwaketime)
                        sysvals.rtcWakeAlarmOn()
                # start of suspend trace marker
                if(sysvals.usecallgraph or sysvals.usetraceevents):
-                       sysvals.fsetVal('SUSPEND START', 'trace_marker')
+                       sysvals.fsetVal(datetime.now().strftime(sysvals.tmstart), 'trace_marker')
                # predelay delay
                if(count == 1 and sysvals.predelay > 0):
                        sysvals.fsetVal('WAIT %d' % sysvals.predelay, 'trace_marker')
@@ -5174,37 +5280,33 @@ def executeSuspend():
                # return from suspend
                pprint('RESUME COMPLETE')
                if(sysvals.usecallgraph or sysvals.usetraceevents):
-                       sysvals.fsetVal('RESUME COMPLETE', 'trace_marker')
+                       sysvals.fsetVal(datetime.now().strftime(sysvals.tmend), 'trace_marker')
+               if sysvals.wifi and wifi:
+                       tdata['wifi'] = sysvals.pollWifi(wifi)
                if(sysvals.suspendmode == 'mem' or sysvals.suspendmode == 'command'):
                        tdata['fw'] = getFPDT(False)
-               mcelog = sysvals.mcelog()
-               if mcelog:
-                       tdata['mcelog'] = mcelog
-               bat2 = getBattery() if battery else False
-               if battery and bat1 and bat2:
-                       tdata['bat'] = (bat1, bat2)
-               if 'device' in wifi and 'ip' in wifi:
-                       tdata['wifi'] = (wifi, sysvals.checkWifi())
                testdata.append(tdata)
+       cmdafter = sysvals.cmdinfo(False)
        # stop ftrace
        if(sysvals.usecallgraph or sysvals.usetraceevents):
                if sysvals.useprocmon:
                        pm.stop()
                sysvals.fsetVal('0', 'tracing_on')
        # grab a copy of the dmesg output
-       pprint('CAPTURING DMESG')
+       if not quiet:
+               pprint('CAPTURING DMESG')
        sysvals.getdmesg(testdata)
        # grab a copy of the ftrace output
        if(sysvals.usecallgraph or sysvals.usetraceevents):
-               pprint('CAPTURING TRACE')
+               if not quiet:
+                       pprint('CAPTURING TRACE')
                op = sysvals.writeDatafileHeader(sysvals.ftracefile, testdata)
                fp = open(tp+'trace', 'r')
                for line in fp:
                        op.write(line)
                op.close()
                sysvals.fsetVal('', 'trace')
-               sysvals.platforminfo()
-       return testdata
+               sysvals.platforminfo(cmdafter)
 
 def readFile(file):
        if os.path.islink(file):
@@ -5447,25 +5549,6 @@ def dmidecode(mempath, fatal=False):
                count += 1
        return out
 
-def getBattery():
-       p, charge, bat = '/sys/class/power_supply', 0, {}
-       if not os.path.exists(p):
-               return False
-       for d in os.listdir(p):
-               type = sysvals.getVal(os.path.join(p, d, 'type')).strip().lower()
-               if type != 'battery':
-                       continue
-               for v in ['status', 'energy_now', 'capacity_now']:
-                       bat[v] = sysvals.getVal(os.path.join(p, d, v)).strip().lower()
-               break
-       if 'status' not in bat:
-               return False
-       ac = False if 'discharging' in bat['status'] else True
-       for v in ['energy_now', 'capacity_now']:
-               if v in bat and bat[v]:
-                       charge = int(bat[v])
-       return (ac, charge)
-
 def displayControl(cmd):
        xset, ret = 'timeout 10 xset -d :0.0 {0}', 0
        if sysvals.sudouser:
@@ -5715,6 +5798,17 @@ def statusCheck(probecheck=False):
                status = 'rtcwake is not properly supported'
        pprint('    is rtcwake supported: %s' % res)
 
+       # check info commands
+       pprint('    optional commands this tool may use for info:')
+       no = sysvals.colorText('MISSING')
+       yes = sysvals.colorText('FOUND', 32)
+       for c in ['turbostat', 'mcelog', 'lspci', 'lsusb']:
+               if c == 'turbostat':
+                       res = yes if sysvals.haveTurbostat() else no
+               else:
+                       res = yes if sysvals.getExec(c) else no
+               pprint('        %s: %s' % (c, res))
+
        if not probecheck:
                return status
 
@@ -5780,8 +5874,9 @@ def getArgFloat(name, args, min, max, main=True):
                doError(name+': value should be between %f and %f' % (min, max), True)
        return val
 
-def processData(live=False):
-       pprint('PROCESSING DATA')
+def processData(live=False, quiet=False):
+       if not quiet:
+               pprint('PROCESSING DATA')
        sysvals.vprint('usetraceevents=%s, usetracemarkers=%s, usekprobes=%s' % \
                (sysvals.usetraceevents, sysvals.usetracemarkers, sysvals.usekprobes))
        error = ''
@@ -5796,20 +5891,17 @@ def processData(live=False):
                        parseKernelLog(data)
                if(sysvals.ftracefile and (sysvals.usecallgraph or sysvals.usetraceevents)):
                        appendIncompleteTraceLog(testruns)
+       if not sysvals.stamp:
+               pprint('ERROR: data does not include the expected stamp')
+               return (testruns, {'error': 'timeline generation failed'})
        shown = ['bios', 'biosdate', 'cpu', 'host', 'kernel', 'man', 'memfr',
-                       'memsz', 'mode', 'numcpu', 'plat', 'time']
+                       'memsz', 'mode', 'numcpu', 'plat', 'time', 'wifi']
        sysvals.vprint('System Info:')
        for key in sorted(sysvals.stamp):
                if key in shown:
                        sysvals.vprint('    %-8s : %s' % (key.upper(), sysvals.stamp[key]))
-       if sysvals.kparams:
-               sysvals.vprint('Kparams:\n    %s' % sysvals.kparams)
        sysvals.vprint('Command:\n    %s' % sysvals.cmdline)
        for data in testruns:
-               if data.mcelog:
-                       sysvals.vprint('MCELOG Data:')
-                       for line in data.mcelog.split('\n'):
-                               sysvals.vprint('    %s' % line)
                if data.turbostat:
                        idx, s = 0, 'Turbostat:\n    '
                        for val in data.turbostat.split('|'):
@@ -5819,23 +5911,13 @@ def processData(live=False):
                                        s += '\n    '
                                s += val + ' '
                        sysvals.vprint(s)
-               if data.battery:
-                       a1, c1, a2, c2 = data.battery
-                       s = 'Battery:\n    Before - AC: %s, Charge: %d\n     After - AC: %s, Charge: %d' % \
-                               (a1, int(c1), a2, int(c2))
-                       sysvals.vprint(s)
-               if data.wifi:
-                       w = data.wifi.replace('|', ' ').split(',')
-                       s = 'Wifi:\n    Before %s\n     After %s' % \
-                               (w[0], w[1])
-                       sysvals.vprint(s)
                data.printDetails()
-               if len(sysvals.platinfo) > 0:
-                       sysvals.vprint('\nPlatform Info:')
-                       for info in sysvals.platinfo:
-                               sysvals.vprint(info[0]+' - '+info[1])
-                               sysvals.vprint(info[2])
-                       sysvals.vprint('')
+       if len(sysvals.platinfo) > 0:
+               sysvals.vprint('\nPlatform Info:')
+               for info in sysvals.platinfo:
+                       sysvals.vprint('[%s - %s]' % (info[0], info[1]))
+                       sysvals.vprint(info[2])
+               sysvals.vprint('')
        if sysvals.cgdump:
                for data in testruns:
                        data.debugPrint()
@@ -5845,7 +5927,8 @@ def processData(live=False):
                return (testruns, {'error': 'timeline generation failed'})
        sysvals.vprint('Creating the html timeline (%s)...' % sysvals.htmlfile)
        createHTML(testruns, error)
-       pprint('DONE')
+       if not quiet:
+               pprint('DONE')
        data = testruns[0]
        stamp = data.stamp
        stamp['suspend'], stamp['resume'] = data.getTimeValues()
@@ -5872,31 +5955,28 @@ def rerunTest(htmlfile=''):
                        doError('a directory already exists with this name: %s' % sysvals.htmlfile)
                elif not os.access(sysvals.htmlfile, os.W_OK):
                        doError('missing permission to write to %s' % sysvals.htmlfile)
-       testruns, stamp = processData(False)
-       sysvals.logmsg = ''
+       testruns, stamp = processData()
+       sysvals.resetlog()
        return stamp
 
 # Function: runTest
 # Description:
 #       execute a suspend/resume, gather the logs, and generate the output
-def runTest(n=0):
+def runTest(n=0, quiet=False):
        # prepare for the test
-       sysvals.initFtrace()
+       sysvals.initFtrace(quiet)
        sysvals.initTestOutput('suspend')
 
        # execute the test
-       testdata = executeSuspend()
+       executeSuspend(quiet)
        sysvals.cleanupFtrace()
        if sysvals.skiphtml:
+               sysvals.outputResult({}, n)
                sysvals.sudoUserchown(sysvals.testdir)
                return
-       if not testdata[0]['error']:
-               testruns, stamp = processData(True)
-               for data in testruns:
-                       del data
-       else:
-               stamp = testdata[0]
-
+       testruns, stamp = processData(True, quiet)
+       for data in testruns:
+               del data
        sysvals.sudoUserchown(sysvals.testdir)
        sysvals.outputResult(stamp, n)
        if 'error' in stamp:
@@ -5904,13 +5984,14 @@ def runTest(n=0):
        return 0
 
 def find_in_html(html, start, end, firstonly=True):
-       n, out = 0, []
-       while n < len(html):
-               m = re.search(start, html[n:])
+       n, cnt, out = 0, len(html), []
+       while n < cnt:
+               e = cnt if (n + 10000 > cnt or n == 0) else n + 10000
+               m = re.search(start, html[n:e])
                if not m:
                        break
                i = m.end()
-               m = re.search(end, html[n+i:])
+               m = re.search(end, html[n+i:e])
                if not m:
                        break
                j = m.start()
@@ -5945,7 +6026,7 @@ def data_from_html(file, outpath, issues, fulldetail=False):
        tstr = dt.strftime('%Y/%m/%d %H:%M:%S')
        error = find_in_html(html, '<table class="testfail"><tr><td>', '</td>')
        if error:
-               m = re.match('[a-z]* failed in (?P<p>[a-z0-9_]*) phase', error)
+               m = re.match('[a-z0-9]* failed in (?P<p>\S*).*', error)
                if m:
                        result = 'fail in %s' % m.group('p')
                else:
@@ -5974,6 +6055,9 @@ def data_from_html(file, outpath, issues, fulldetail=False):
                                elist[err[0]] += 1
                for i in elist:
                        ilist.append('%sx%d' % (i, elist[i]) if elist[i] > 1 else i)
+       wifi = find_in_html(html, 'Wifi Resume: ', '</td>')
+       if wifi:
+               extra['wifi'] = wifi
        low = find_in_html(html, 'freeze time: <b>', ' ms</b>')
        if low and '|' in low:
                issue = 'FREEZEx%d' % len(low.split('|'))
@@ -6048,13 +6132,15 @@ def genHtml(subdir, force=False):
        for dirname, dirnames, filenames in os.walk(subdir):
                sysvals.dmesgfile = sysvals.ftracefile = sysvals.htmlfile = ''
                for filename in filenames:
-                       if(re.match('.*_dmesg.txt', filename)):
-                               sysvals.dmesgfile = os.path.join(dirname, filename)
-                       elif(re.match('.*_ftrace.txt', filename)):
-                               sysvals.ftracefile = os.path.join(dirname, filename)
+                       file = os.path.join(dirname, filename)
+                       if sysvals.usable(file):
+                               if(re.match('.*_dmesg.txt', filename)):
+                                       sysvals.dmesgfile = file
+                               elif(re.match('.*_ftrace.txt', filename)):
+                                       sysvals.ftracefile = file
                sysvals.setOutputFile()
-               if sysvals.ftracefile and sysvals.htmlfile and \
-                       (force or not os.path.exists(sysvals.htmlfile)):
+               if (sysvals.dmesgfile or sysvals.ftracefile) and sysvals.htmlfile and \
+                       (force or not sysvals.usable(sysvals.htmlfile)):
                        pprint('FTRACE: %s' % sysvals.ftracefile)
                        if sysvals.dmesgfile:
                                pprint('DMESG : %s' % sysvals.dmesgfile)
@@ -6169,9 +6255,9 @@ def configFromFile(file):
                                sysvals.cgtest = getArgInt('cgtest', value, 0, 1, False)
                        elif(option == 'cgphase'):
                                d = Data(0)
-                               if value not in d.sortedPhases():
+                               if value not in d.phasedef:
                                        doError('invalid phase --> (%s: %s), valid phases are %s'\
-                                               % (option, value, d.sortedPhases()), True)
+                                               % (option, value, d.phasedef.keys()), True)
                                sysvals.cgphase = value
                        elif(option == 'fadd'):
                                file = sysvals.configFile(value)
@@ -6184,9 +6270,7 @@ def configFromFile(file):
                                nums = value.split()
                                if len(nums) != 2:
                                        doError('multi requires 2 integers (exec_count and delay)', True)
-                               sysvals.multitest['run'] = True
-                               sysvals.multitest['count'] = getArgInt('multi: n d (exec count)', nums[0], 2, 1000000, False)
-                               sysvals.multitest['delay'] = getArgInt('multi: n d (delay between tests)', nums[1], 0, 3600, False)
+                               sysvals.multiinit(nums[0], nums[1])
                        elif(option == 'devicefilter'):
                                sysvals.setDeviceFilter(value)
                        elif(option == 'expandcg'):
@@ -6342,6 +6426,7 @@ def printHelp():
        '   -srgap       Add a visible gap in the timeline between sus/res (default: disabled)\n'\
        '   -skiphtml    Run the test and capture the trace logs, but skip the timeline (default: disabled)\n'\
        '   -result fn   Export a results table to a text file for parsing.\n'\
+       '   -wifi        If a wifi connection is available, check that it reconnects after resume.\n'\
        '  [testprep]\n'\
        '   -sync        Sync the filesystems before starting the test\n'\
        '   -rs on/off   Enable/disable runtime suspend for all devices, restore all after test\n'\
@@ -6356,8 +6441,10 @@ def printHelp():
        '   -predelay t  Include t ms delay before 1st suspend (default: 0 ms)\n'\
        '   -postdelay t Include t ms delay after last resume (default: 0 ms)\n'\
        '   -mindev ms   Discard all device blocks shorter than ms milliseconds (e.g. 0.001 for us)\n'\
-       '   -multi n d   Execute <n> consecutive tests at <d> seconds intervals. The outputs will\n'\
-       '                be created in a new subdirectory with a summary page.\n'\
+       '   -multi n d   Execute <n> consecutive tests at <d> seconds intervals. If <n> is followed\n'\
+       '                by a "d", "h", or "m" execute for <n> days, hours, or mins instead.\n'\
+       '                The outputs will be created in a new subdirectory with a summary page.\n'\
+       '   -maxfail n   Abort a -multi run after n consecutive fails (default is 0 = never abort)\n'\
        '  [debug]\n'\
        '   -f           Use ftrace to create device callgraphs (default: disabled)\n'\
        '   -ftop        Use ftrace on the top level call: "%s" (default: disabled)\n'\
@@ -6379,11 +6466,11 @@ def printHelp():
        '   -modes       List available suspend modes\n'\
        '   -status      Test to see if the system is enabled to run this tool\n'\
        '   -fpdt        Print out the contents of the ACPI Firmware Performance Data Table\n'\
-       '   -battery     Print out battery info (if available)\n'\
-       '   -wifi        Print out wifi connection info (if wireless-tools and device exists)\n'\
+       '   -wificheck   Print out wifi connection info\n'\
        '   -x<mode>     Test xset by toggling the given mode (on/off/standby/suspend)\n'\
        '   -sysinfo     Print out system info extracted from BIOS\n'\
        '   -devinfo     Print out the pm settings of all devices which support runtime suspend\n'\
+       '   -cmdinfo     Print out all the platform info collected before and after suspend/resume\n'\
        '   -flist       Print the list of functions currently being captured in ftrace\n'\
        '   -flistall    Print all functions capable of being captured in ftrace\n'\
        '   -summary dir Create a summary of tests in this dir [-genhtml builds missing html]\n'\
@@ -6399,8 +6486,8 @@ if __name__ == '__main__':
        genhtml = False
        cmd = ''
        simplecmds = ['-sysinfo', '-modes', '-fpdt', '-flist', '-flistall',
-               '-devinfo', '-status', '-battery', '-xon', '-xoff', '-xstandby',
-               '-xsuspend', '-xinit', '-xreset', '-xstat', '-wifi']
+               '-devinfo', '-status', '-xon', '-xoff', '-xstandby', '-xsuspend',
+               '-xinit', '-xreset', '-xstat', '-wificheck', '-cmdinfo']
        if '-f' in sys.argv:
                sysvals.cgskip = sysvals.configFile('cgskip.txt')
        # loop through the command line arguments
@@ -6462,8 +6549,15 @@ if __name__ == '__main__':
                        sysvals.usedevsrc = True
                elif(arg == '-sync'):
                        sysvals.sync = True
+               elif(arg == '-wifi'):
+                       sysvals.wifi = True
                elif(arg == '-gzip'):
                        sysvals.gzip = True
+               elif(arg == '-info'):
+                       try:
+                               val = next(args)
+                       except:
+                               doError('-info requires one string argument', True)
                elif(arg == '-rs'):
                        try:
                                val = next(args)
@@ -6555,10 +6649,14 @@ if __name__ == '__main__':
                        sysvals.cgexp = True
                elif(arg == '-srgap'):
                        sysvals.srgap = 5
+               elif(arg == '-maxfail'):
+                       sysvals.maxfail = getArgInt('-maxfail', args, 0, 1000000)
                elif(arg == '-multi'):
-                       sysvals.multitest['run'] = True
-                       sysvals.multitest['count'] = getArgInt('-multi n d (exec count)', args, 2, 1000000)
-                       sysvals.multitest['delay'] = getArgInt('-multi n d (delay between tests)', args, 0, 3600)
+                       try:
+                               c, d = next(args), next(args)
+                       except:
+                               doError('-multi requires two values', True)
+                       sysvals.multiinit(c, d)
                elif(arg == '-o'):
                        try:
                                val = next(args)
@@ -6655,13 +6753,6 @@ if __name__ == '__main__':
                elif(cmd == 'fpdt'):
                        if not getFPDT(True):
                                ret = 1
-               elif(cmd == 'battery'):
-                       out = getBattery()
-                       if out:
-                               pprint('AC Connect    : %s\nBattery Charge: %d' % out)
-                       else:
-                               pprint('no battery found')
-                               ret = 1
                elif(cmd == 'sysinfo'):
                        sysvals.printSystemInfo(True)
                elif(cmd == 'devinfo'):
@@ -6679,13 +6770,15 @@ if __name__ == '__main__':
                        ret = displayControl(cmd[1:])
                elif(cmd == 'xstat'):
                        pprint('Display Status: %s' % displayControl('stat').upper())
-               elif(cmd == 'wifi'):
-                       out = sysvals.checkWifi()
-                       if 'device' not in out:
-                               pprint('WIFI interface not found')
+               elif(cmd == 'wificheck'):
+                       dev = sysvals.checkWifi()
+                       if dev:
+                               print('%s is connected' % sysvals.wifiDetails(dev))
                        else:
-                               for key in sorted(out):
-                                       pprint('%6s: %s' % (key.upper(), out[key]))
+                               print('No wifi connection found')
+               elif(cmd == 'cmdinfo'):
+                       for out in sysvals.cmdinfo(False, True):
+                               print('[%s - %s]\n%s\n' % out)
                sys.exit(ret)
 
        # if instructed, re-analyze existing data files
@@ -6720,24 +6813,38 @@ if __name__ == '__main__':
        setRuntimeSuspend(True)
        if sysvals.display:
                displayControl('init')
-       ret = 0
+       failcnt, ret = 0, 0
        if sysvals.multitest['run']:
                # run multiple tests in a separate subdirectory
                if not sysvals.outdir:
-                       s = 'suspend-x%d' % sysvals.multitest['count']
-                       sysvals.outdir = datetime.now().strftime(s+'-%y%m%d-%H%M%S')
+                       if 'time' in sysvals.multitest:
+                               s = '-%dm' % sysvals.multitest['time']
+                       else:
+                               s = '-x%d' % sysvals.multitest['count']
+                       sysvals.outdir = datetime.now().strftime('suspend-%y%m%d-%H%M%S'+s)
                if not os.path.isdir(sysvals.outdir):
                        os.makedirs(sysvals.outdir)
+               sysvals.sudoUserchown(sysvals.outdir)
+               finish = datetime.now()
+               if 'time' in sysvals.multitest:
+                       finish += timedelta(minutes=sysvals.multitest['time'])
                for i in range(sysvals.multitest['count']):
-                       if(i != 0):
+                       sysvals.multistat(True, i, finish)
+                       if i != 0 and sysvals.multitest['delay'] > 0:
                                pprint('Waiting %d seconds...' % (sysvals.multitest['delay']))
                                time.sleep(sysvals.multitest['delay'])
-                       pprint('TEST (%d/%d) START' % (i+1, sysvals.multitest['count']))
                        fmt = 'suspend-%y%m%d-%H%M%S'
                        sysvals.testdir = os.path.join(sysvals.outdir, datetime.now().strftime(fmt))
-                       ret = runTest(i+1)
-                       pprint('TEST (%d/%d) COMPLETE' % (i+1, sysvals.multitest['count']))
-                       sysvals.logmsg = ''
+                       ret = runTest(i+1, True)
+                       failcnt = 0 if not ret else failcnt + 1
+                       if sysvals.maxfail > 0 and failcnt >= sysvals.maxfail:
+                               pprint('Maximum fail count of %d reached, aborting multitest' % (sysvals.maxfail))
+                               break
+                       time.sleep(5)
+                       sysvals.resetlog()
+                       sysvals.multistat(False, i, finish)
+                       if 'time' in sysvals.multitest and datetime.now() >= finish:
+                               break
                if not sysvals.skiphtml:
                        runSummary(sysvals.outdir, False, False)
                sysvals.sudoUserchown(sysvals.outdir)
index cde463af70711df168f3799a93e5ef535d81c9f0..c2642517e1d8d6a7bd77dbcdb0410b826e5ff960 100644 (file)
@@ -5,7 +5,8 @@
 static void test_fexit_bpf2bpf_common(const char *obj_file,
                                      const char *target_obj_file,
                                      int prog_cnt,
-                                     const char **prog_name)
+                                     const char **prog_name,
+                                     bool run_prog)
 {
        struct bpf_object *obj = NULL, *pkt_obj;
        int err, pkt_fd, i;
@@ -18,7 +19,8 @@ static void test_fexit_bpf2bpf_common(const char *obj_file,
 
        err = bpf_prog_load(target_obj_file, BPF_PROG_TYPE_UNSPEC,
                            &pkt_obj, &pkt_fd);
-       if (CHECK(err, "prog_load sched cls", "err %d errno %d\n", err, errno))
+       if (CHECK(err, "tgt_prog_load", "file %s err %d errno %d\n",
+                 target_obj_file, err, errno))
                return;
        DECLARE_LIBBPF_OPTS(bpf_object_open_opts, opts,
                            .attach_prog_fd = pkt_fd,
@@ -33,7 +35,7 @@ static void test_fexit_bpf2bpf_common(const char *obj_file,
 
        obj = bpf_object__open_file(obj_file, &opts);
        if (CHECK(IS_ERR_OR_NULL(obj), "obj_open",
-                 "failed to open fexit_bpf2bpf: %ld\n",
+                 "failed to open %s: %ld\n", obj_file,
                  PTR_ERR(obj)))
                goto close_prog;
 
@@ -49,6 +51,10 @@ static void test_fexit_bpf2bpf_common(const char *obj_file,
                if (CHECK(IS_ERR(link[i]), "attach_trace", "failed to link\n"))
                        goto close_prog;
        }
+
+       if (!run_prog)
+               goto close_prog;
+
        data_map = bpf_object__find_map_by_name(obj, "fexit_bp.bss");
        if (CHECK(!data_map, "find_data_map", "data map not found\n"))
                goto close_prog;
@@ -89,7 +95,7 @@ static void test_target_no_callees(void)
        test_fexit_bpf2bpf_common("./fexit_bpf2bpf_simple.o",
                                  "./test_pkt_md_access.o",
                                  ARRAY_SIZE(prog_name),
-                                 prog_name);
+                                 prog_name, true);
 }
 
 static void test_target_yes_callees(void)
@@ -103,7 +109,7 @@ static void test_target_yes_callees(void)
        test_fexit_bpf2bpf_common("./fexit_bpf2bpf.o",
                                  "./test_pkt_access.o",
                                  ARRAY_SIZE(prog_name),
-                                 prog_name);
+                                 prog_name, true);
 }
 
 static void test_func_replace(void)
@@ -120,7 +126,18 @@ static void test_func_replace(void)
        test_fexit_bpf2bpf_common("./fexit_bpf2bpf.o",
                                  "./test_pkt_access.o",
                                  ARRAY_SIZE(prog_name),
-                                 prog_name);
+                                 prog_name, true);
+}
+
+static void test_func_replace_verify(void)
+{
+       const char *prog_name[] = {
+               "freplace/do_bind",
+       };
+       test_fexit_bpf2bpf_common("./freplace_connect4.o",
+                                 "./connect4_prog.o",
+                                 ARRAY_SIZE(prog_name),
+                                 prog_name, false);
 }
 
 void test_fexit_bpf2bpf(void)
@@ -128,4 +145,5 @@ void test_fexit_bpf2bpf(void)
        test_target_no_callees();
        test_target_yes_callees();
        test_func_replace();
+       test_func_replace_verify();
 }
index 75085119c5bbf739d9c6bf9441ab65093fa93e56..ad3c498a8150014f7bcd1c5fe13257563e89bfbb 100644 (file)
 
 int _version SEC("version") = 1;
 
+__attribute__ ((noinline))
+int do_bind(struct bpf_sock_addr *ctx)
+{
+       struct sockaddr_in sa = {};
+
+       sa.sin_family = AF_INET;
+       sa.sin_port = bpf_htons(0);
+       sa.sin_addr.s_addr = bpf_htonl(SRC_REWRITE_IP4);
+
+       if (bpf_bind(ctx, (struct sockaddr *)&sa, sizeof(sa)) != 0)
+               return 0;
+
+       return 1;
+}
+
 SEC("cgroup/connect4")
 int connect_v4_prog(struct bpf_sock_addr *ctx)
 {
        struct bpf_sock_tuple tuple = {};
-       struct sockaddr_in sa;
        struct bpf_sock *sk;
 
        /* Verify that new destination is available. */
@@ -56,17 +70,7 @@ int connect_v4_prog(struct bpf_sock_addr *ctx)
        ctx->user_ip4 = bpf_htonl(DST_REWRITE_IP4);
        ctx->user_port = bpf_htons(DST_REWRITE_PORT4);
 
-       /* Rewrite source. */
-       memset(&sa, 0, sizeof(sa));
-
-       sa.sin_family = AF_INET;
-       sa.sin_port = bpf_htons(0);
-       sa.sin_addr.s_addr = bpf_htonl(SRC_REWRITE_IP4);
-
-       if (bpf_bind(ctx, (struct sockaddr *)&sa, sizeof(sa)) != 0)
-               return 0;
-
-       return 1;
+       return do_bind(ctx) ? 1 : 0;
 }
 
 char _license[] SEC("license") = "GPL";
diff --git a/tools/testing/selftests/bpf/progs/freplace_connect4.c b/tools/testing/selftests/bpf/progs/freplace_connect4.c
new file mode 100644 (file)
index 0000000..a0ae842
--- /dev/null
@@ -0,0 +1,18 @@
+#include <linux/stddef.h>
+#include <linux/ipv6.h>
+#include <linux/bpf.h>
+#include <linux/in.h>
+#include <sys/socket.h>
+#include <bpf/bpf_helpers.h>
+#include <bpf/bpf_endian.h>
+
+SEC("freplace/do_bind")
+int new_do_bind(struct bpf_sock_addr *ctx)
+{
+  struct sockaddr_in sa = {};
+
+  bpf_bind(ctx, (struct sockaddr *)&sa, sizeof(sa));
+  return 0;
+}
+
+char _license[] SEC("license") = "GPL";
index 88b0566da13d2654a5a682089f4f9054b7038a11..31538c9ed1939ca5360d0052086534720de8f67d 100644 (file)
@@ -20,20 +20,12 @@ struct bpf_map_def SEC("maps") btf_map = {
 
 BPF_ANNOTATE_KV_PAIR(btf_map, int, struct ipv_counts);
 
-struct dummy_tracepoint_args {
-       unsigned long long pad;
-       struct sock *sock;
-};
-
 __attribute__((noinline))
-int test_long_fname_2(struct dummy_tracepoint_args *arg)
+int test_long_fname_2(void)
 {
        struct ipv_counts *counts;
        int key = 0;
 
-       if (!arg->sock)
-               return 0;
-
        counts = bpf_map_lookup_elem(&btf_map, &key);
        if (!counts)
                return 0;
@@ -44,15 +36,15 @@ int test_long_fname_2(struct dummy_tracepoint_args *arg)
 }
 
 __attribute__((noinline))
-int test_long_fname_1(struct dummy_tracepoint_args *arg)
+int test_long_fname_1(void)
 {
-       return test_long_fname_2(arg);
+       return test_long_fname_2();
 }
 
 SEC("dummy_tracepoint")
-int _dummy_tracepoint(struct dummy_tracepoint_args *arg)
+int _dummy_tracepoint(void *arg)
 {
-       return test_long_fname_1(arg);
+       return test_long_fname_1();
 }
 
 char _license[] SEC("license") = "GPL";
index a924e53c8e9d8b32ac9f8afa0f19e90fbc1a79fa..6c5560162746b8a336f2086855889ebba388ac85 100644 (file)
@@ -28,20 +28,12 @@ struct {
        __type(value, struct ipv_counts);
 } btf_map SEC(".maps");
 
-struct dummy_tracepoint_args {
-       unsigned long long pad;
-       struct sock *sock;
-};
-
 __attribute__((noinline))
-int test_long_fname_2(struct dummy_tracepoint_args *arg)
+int test_long_fname_2(void)
 {
        struct ipv_counts *counts;
        int key = 0;
 
-       if (!arg->sock)
-               return 0;
-
        counts = bpf_map_lookup_elem(&btf_map, &key);
        if (!counts)
                return 0;
@@ -57,15 +49,15 @@ int test_long_fname_2(struct dummy_tracepoint_args *arg)
 }
 
 __attribute__((noinline))
-int test_long_fname_1(struct dummy_tracepoint_args *arg)
+int test_long_fname_1(void)
 {
-       return test_long_fname_2(arg);
+       return test_long_fname_2();
 }
 
 SEC("dummy_tracepoint")
-int _dummy_tracepoint(struct dummy_tracepoint_args *arg)
+int _dummy_tracepoint(void *arg)
 {
-       return test_long_fname_1(arg);
+       return test_long_fname_1();
 }
 
 char _license[] SEC("license") = "GPL";
index 983aedd1c07252b4b69ae1b100b6dc86cb2c509f..506da7fd2da2376d93605a9ceb49559fb5b9ccc3 100644 (file)
@@ -17,20 +17,12 @@ struct bpf_map_def SEC("maps") btf_map = {
        .max_entries = 4,
 };
 
-struct dummy_tracepoint_args {
-       unsigned long long pad;
-       struct sock *sock;
-};
-
 __attribute__((noinline))
-int test_long_fname_2(struct dummy_tracepoint_args *arg)
+int test_long_fname_2(void)
 {
        struct ipv_counts *counts;
        int key = 0;
 
-       if (!arg->sock)
-               return 0;
-
        counts = bpf_map_lookup_elem(&btf_map, &key);
        if (!counts)
                return 0;
@@ -41,15 +33,15 @@ int test_long_fname_2(struct dummy_tracepoint_args *arg)
 }
 
 __attribute__((noinline))
-int test_long_fname_1(struct dummy_tracepoint_args *arg)
+int test_long_fname_1(void)
 {
-       return test_long_fname_2(arg);
+       return test_long_fname_2();
 }
 
 SEC("dummy_tracepoint")
-int _dummy_tracepoint(struct dummy_tracepoint_args *arg)
+int _dummy_tracepoint(void *arg)
 {
-       return test_long_fname_1(arg);
+       return test_long_fname_1();
 }
 
 char _license[] SEC("license") = "GPL";
index 8da77cda5f4a578c449c567f6f1477c35bbda6e9..305fae8f80a98acc6709c60f5fd9407098775f09 100644 (file)
@@ -2854,7 +2854,7 @@ static struct btf_raw_test raw_tests[] = {
        .value_type_id = 1,
        .max_entries = 4,
        .btf_load_err = true,
-       .err_str = "vlen != 0",
+       .err_str = "Invalid func linkage",
 },
 
 {
index 7276620ef242a4b3ae40eea1b2288d0b5e78c4d7..8bfeb77c60bd364649a00bc604a76c9a4488c45b 100644 (file)
        },
        .result = ACCEPT,
 },
+{
+       "store PTR_TO_STACK in R10 to array map using BPF_B",
+       .insns = {
+       /* Load pointer to map. */
+       BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
+       BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
+       BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
+       BPF_LD_MAP_FD(BPF_REG_1, 0),
+       BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
+       BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
+       BPF_MOV64_IMM(BPF_REG_0, 2),
+       BPF_EXIT_INSN(),
+       BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
+       /* Copy R10 to R9. */
+       BPF_MOV64_REG(BPF_REG_9, BPF_REG_10),
+       /* Pollute other registers with unaligned values. */
+       BPF_MOV64_IMM(BPF_REG_2, -1),
+       BPF_MOV64_IMM(BPF_REG_3, -1),
+       BPF_MOV64_IMM(BPF_REG_4, -1),
+       BPF_MOV64_IMM(BPF_REG_5, -1),
+       BPF_MOV64_IMM(BPF_REG_6, -1),
+       BPF_MOV64_IMM(BPF_REG_7, -1),
+       BPF_MOV64_IMM(BPF_REG_8, -1),
+       /* Store both R9 and R10 with BPF_B and read back. */
+       BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_10, 0),
+       BPF_LDX_MEM(BPF_B, BPF_REG_2, BPF_REG_1, 0),
+       BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_9, 0),
+       BPF_LDX_MEM(BPF_B, BPF_REG_3, BPF_REG_1, 0),
+       /* Should read back as same value. */
+       BPF_JMP_REG(BPF_JEQ, BPF_REG_2, BPF_REG_3, 2),
+       BPF_MOV64_IMM(BPF_REG_0, 1),
+       BPF_EXIT_INSN(),
+       BPF_MOV64_IMM(BPF_REG_0, 42),
+       BPF_EXIT_INSN(),
+       },
+       .fixup_map_array_48b = { 3 },
+       .result = ACCEPT,
+       .retval = 42,
+       .prog_type = BPF_PROG_TYPE_SCHED_CLS,
+},
index 7f6c232cd8423e4b5cb17ec01554a964be795e69..ed1c2cea1dea66c06083c7b41ce0280ce7dd7b54 100644 (file)
@@ -88,6 +88,7 @@
        BPF_EXIT_INSN(),
        },
        .fixup_map_hash_48b = { 3 },
+       .errstr_unpriv = "leaking pointer from stack off -8",
        .errstr = "R0 invalid mem access 'inv'",
        .result = REJECT,
        .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
index c2c8de4faffff26a70e6a3bd131904aacabf5142..e59d985eeff0c8be95c79fd914ac706439952dc7 100644 (file)
@@ -11,5 +11,6 @@ CONFIG_PREEMPTIRQ_DELAY_TEST=m
 CONFIG_MODULES=y
 CONFIG_MODULE_UNLOAD=y
 CONFIG_SAMPLES=y
+CONFIG_SAMPLE_FTRACE_DIRECT=m
 CONFIG_SAMPLE_TRACE_PRINTK=m
 CONFIG_KALLSYMS_ALL=y
index 4c156aeab6b80c011ab6ad503c9521bc10341c7b..5ec4d9e18806cd81b547d5f64d2137af0a3249b5 100644 (file)
@@ -137,7 +137,7 @@ int dump_queue(struct msgque_data *msgque)
        for (kern_id = 0; kern_id < 256; kern_id++) {
                ret = msgctl(kern_id, MSG_STAT, &ds);
                if (ret < 0) {
-                       if (errno == -EINVAL)
+                       if (errno == EINVAL)
                                continue;
                        printf("Failed to get stats for IPC queue with id %d\n",
                                        kern_id);
index e84d901f85672fdc7df7fe9e947f3068f398d1bc..676b3a8b114d76c9db133df011d9174e51cd0c6c 100644 (file)
@@ -33,7 +33,7 @@ tap_timeout()
 {
        # Make sure tests will time out if utility is available.
        if [ -x /usr/bin/timeout ] ; then
-               /usr/bin/timeout "$kselftest_timeout" "$1"
+               /usr/bin/timeout --foreground "$kselftest_timeout" "$1"
        else
                "$1"
        fi
index 2902f6a78f8a313fa1da2511984bc47579a46916..2bb8c81fc0b44005d7533f739846d7d9c605805c 100644 (file)
@@ -705,7 +705,7 @@ static void __timeout_handler(int sig, siginfo_t *info, void *ucontext)
        /* Sanity check handler execution environment. */
        if (!t) {
                fprintf(TH_LOG_STREAM,
-                       "no active test in SIGARLM handler!?\n");
+                       "no active test in SIGALRM handler!?\n");
                abort();
        }
        if (sig != SIGALRM || sig != info->si_signo) {
@@ -731,7 +731,7 @@ void __wait_for_test(struct __test_metadata *t)
        if (sigaction(SIGALRM, &action, &saved_action)) {
                t->passed = 0;
                fprintf(TH_LOG_STREAM,
-                       "%s: unable to install SIGARLM handler\n",
+                       "%s: unable to install SIGALRM handler\n",
                        t->name);
                return;
        }
@@ -743,7 +743,7 @@ void __wait_for_test(struct __test_metadata *t)
        if (sigaction(SIGALRM, &saved_action, NULL)) {
                t->passed = 0;
                fprintf(TH_LOG_STREAM,
-                       "%s: unable to uninstall SIGARLM handler\n",
+                       "%s: unable to uninstall SIGALRM handler\n",
                        t->name);
                return;
        }
index 0a15f9e23431228eb8bd19798305afd1914683a1..187b14cad00cb37abfc7a24799de89d54fb7d8a7 100644 (file)
@@ -4,8 +4,9 @@ CFLAGS += -I../../../../include/uapi/
 CFLAGS += -I../../../../include/
 CFLAGS += -I../../../../usr/include/
 
-TEST_GEN_PROGS := memfd_test fuse_test fuse_mnt
+TEST_GEN_PROGS := memfd_test
 TEST_PROGS := run_fuse_test.sh run_hugetlbfs_test.sh
+TEST_GEN_FILES := fuse_test fuse_mnt
 
 fuse_mnt.o: CFLAGS += $(shell pkg-config fuse --cflags)
 
index 796670ebc65b37c66ee3c865bb6a90f5881267c2..6560ed796ac48e96fe3a5fb28c76ade7ac186b3a 100755 (executable)
@@ -749,6 +749,29 @@ ipv4_fcnal_runtime()
        run_cmd "ip netns exec me ping -c1 -w1 172.16.101.1"
        log_test $? 0 "Ping - multipath"
 
+       run_cmd "$IP ro delete 172.16.101.1/32 nhid 122"
+
+       #
+       # multiple default routes
+       # - tests fib_select_default
+       run_cmd "$IP nexthop add id 501 via 172.16.1.2 dev veth1"
+       run_cmd "$IP ro add default nhid 501"
+       run_cmd "$IP ro add default via 172.16.1.3 dev veth1 metric 20"
+       run_cmd "ip netns exec me ping -c1 -w1 172.16.101.1"
+       log_test $? 0 "Ping - multiple default routes, nh first"
+
+       # flip the order
+       run_cmd "$IP ro del default nhid 501"
+       run_cmd "$IP ro del default via 172.16.1.3 dev veth1 metric 20"
+       run_cmd "$IP ro add default via 172.16.1.2 dev veth1 metric 20"
+       run_cmd "$IP nexthop replace id 501 via 172.16.1.3 dev veth1"
+       run_cmd "$IP ro add default nhid 501 metric 20"
+       run_cmd "ip netns exec me ping -c1 -w1 172.16.101.1"
+       log_test $? 0 "Ping - multiple default routes, nh second"
+
+       run_cmd "$IP nexthop delete nhid 501"
+       run_cmd "$IP ro del default"
+
        #
        # IPv4 with blackhole nexthops
        #
index b7616704b55e982f20d55c768def568f54e0efc1..84205c3a55ebed11ddbbf307d771338e0f4d1ac5 100755 (executable)
@@ -618,16 +618,22 @@ fib_nexthop_test()
 
 fib_suppress_test()
 {
+       echo
+       echo "FIB rule with suppress_prefixlength"
+       setup
+
        $IP link add dummy1 type dummy
        $IP link set dummy1 up
        $IP -6 route add default dev dummy1
        $IP -6 rule add table main suppress_prefixlength 0
-       ping -f -c 1000 -W 1 1234::1 || true
+       ping -f -c 1000 -W 1 1234::1 >/dev/null 2>&1
        $IP -6 rule del table main suppress_prefixlength 0
        $IP link del dummy1
 
        # If we got here without crashing, we're good.
-       return 0
+       log_test 0 0 "FIB rule suppress test"
+
+       cleanup
 }
 
 ################################################################################
index 89fb3e0b552ec16e24b44f90f82e5047e22384d7..c0aa46ce14f6ce088b4c8b288b94aeeaf4e3fcac 100644 (file)
@@ -2803,12 +2803,13 @@ TEST(syscall_restart)
                         offsetof(struct seccomp_data, nr)),
 
 #ifdef __NR_sigreturn
-               BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_sigreturn, 6, 0),
+               BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_sigreturn, 7, 0),
 #endif
-               BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_read, 5, 0),
-               BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_exit, 4, 0),
-               BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_rt_sigreturn, 3, 0),
-               BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_nanosleep, 4, 0),
+               BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_read, 6, 0),
+               BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_exit, 5, 0),
+               BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_rt_sigreturn, 4, 0),
+               BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_nanosleep, 5, 0),
+               BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_clock_nanosleep, 4, 0),
                BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_restart_syscall, 4, 0),
 
                /* Allow __NR_write for easy logging. */
@@ -2895,7 +2896,8 @@ TEST(syscall_restart)
        ASSERT_EQ(PTRACE_EVENT_SECCOMP, (status >> 16));
        ASSERT_EQ(0, ptrace(PTRACE_GETEVENTMSG, child_pid, NULL, &msg));
        ASSERT_EQ(0x100, msg);
-       EXPECT_EQ(__NR_nanosleep, get_syscall(_metadata, child_pid));
+       ret = get_syscall(_metadata, child_pid);
+       EXPECT_TRUE(ret == __NR_nanosleep || ret == __NR_clock_nanosleep);
 
        /* Might as well check siginfo for sanity while we're here. */
        ASSERT_EQ(0, ptrace(PTRACE_GETSIGINFO, child_pid, NULL, &info));
index b630c7b5950a960b95a9bb0aeda79e41924ca989..8155c2ea7ccbb6ed1b9685f3c602105eb2c26173 100755 (executable)
@@ -1,17 +1,8 @@
 #!/bin/bash
 # SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause)
-self.flags = flags
 
-# Kselftest framework requirement - SKIP code is 4.
-ksft_skip=4
-
-
-if [ -f /dev/tpm0 ] ; then
-       python -m unittest -v tpm2_tests.SmokeTest
-       python -m unittest -v tpm2_tests.AsyncTest
-else
-       exit $ksft_skip
-fi
+python -m unittest -v tpm2_tests.SmokeTest
+python -m unittest -v tpm2_tests.AsyncTest
 
 CLEAR_CMD=$(which tpm2_clear)
 if [ -n $CLEAR_CMD ]; then
index 180b469c53b47d4e0e2e3d7c6bb2ecc7331065e2..a6f5e346635e560db7c7767b22f32f760922600a 100755 (executable)
@@ -1,11 +1,4 @@
 #!/bin/bash
 # SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause)
 
-# Kselftest framework requirement - SKIP code is 4.
-ksft_skip=4
-
-if [ -f /dev/tpmrm0 ] ; then
-       python -m unittest -v tpm2_tests.SpaceTest
-else
-       exit $ksft_skip
-fi
+python -m unittest -v tpm2_tests.SpaceTest
index d31db052dff6a5f62b70e5f01a03909d0a2e5cfb..6998877f707e84df504a605ea6251ff307f130c1 100644 (file)
@@ -1,7 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0
 # Makefile for vm selftests
 uname_M := $(shell uname -m 2>/dev/null || echo not)
-ARCH ?= $(shell echo $(uname_M) | sed -e 's/aarch64.*/arm64/')
+MACHINE ?= $(shell echo $(uname_M) | sed -e 's/aarch64.*/arm64/')
 
 CFLAGS = -Wall -I ../../../../usr/include $(EXTRA_CFLAGS)
 LDLIBS = -lrt
@@ -20,7 +20,7 @@ TEST_GEN_FILES += thuge-gen
 TEST_GEN_FILES += transhuge-stress
 TEST_GEN_FILES += userfaultfd
 
-ifneq (,$(filter $(ARCH),arm64 ia64 mips64 parisc64 ppc64 riscv64 s390x sh64 sparc64 x86_64))
+ifneq (,$(filter $(MACHINE),arm64 ia64 mips64 parisc64 ppc64 ppc64le riscv64 s390x sh64 sparc64 x86_64))
 TEST_GEN_FILES += va_128TBswitch
 TEST_GEN_FILES += virtual_address_range
 TEST_GEN_FILES += write_to_hugetlbfs
index 665009ebfba4a9feabd1b96e61008bb50c780d29..76ca5e7a3951acb9d65bf446b7432f8bc02918b5 100755 (executable)
@@ -59,7 +59,7 @@ else
 fi
 
 #filter 64bit architectures
-ARCH64STR="arm64 ia64 mips64 parisc64 ppc64 riscv64 s390x sh64 sparc64 x86_64"
+ARCH64STR="arm64 ia64 mips64 parisc64 ppc64 ppc64le riscv64 s390x sh64 sparc64 x86_64"
 if [ -z $ARCH ]; then
   ARCH=`uname -m 2>/dev/null | sed -e 's/aarch64.*/arm64/'`
 fi
index f33f32f1d20802e678e5e85f6bd23d298b3705fe..b587b9a7a124bb2fcda464c6efcc284dd4c37742 100644 (file)
@@ -4,7 +4,7 @@ test: virtio_test vringh_test
 virtio_test: virtio_ring.o virtio_test.o
 vringh_test: vringh_test.o vringh.o virtio_ring.o
 
-CFLAGS += -g -O2 -Werror -Wall -I. -I../include/ -I ../../usr/include/ -Wno-pointer-sign -fno-strict-overflow -fno-strict-aliasing -fno-common -MMD -U_FORTIFY_SOURCE
+CFLAGS += -g -O2 -Werror -Wall -I. -I../include/ -I ../../usr/include/ -Wno-pointer-sign -fno-strict-overflow -fno-strict-aliasing -fno-common -MMD -U_FORTIFY_SOURCE -include ../../include/linux/kconfig.h
 vpath %.c ../../drivers/virtio ../../drivers/vhost
 mod:
        ${MAKE} -C `pwd`/../.. M=`pwd`/vhost_test V=${V}
@@ -22,7 +22,8 @@ OOT_CONFIGS=\
        CONFIG_VHOST=m \
        CONFIG_VHOST_NET=n \
        CONFIG_VHOST_SCSI=n \
-       CONFIG_VHOST_VSOCK=n
+       CONFIG_VHOST_VSOCK=n \
+       CONFIG_VHOST_RING=n
 OOT_BUILD=KCFLAGS="-I "${OOT_VHOST} ${MAKE} -C ${OOT_KSRC} V=${V}
 oot-build:
        echo "UNSUPPORTED! Don't use the resulting modules in production!"
index d0351f83aebed9f1ce87c390e586ce45c7068337..04d563fc9b95ca0e80d323e271473492400f7273 100644 (file)
@@ -1,4 +1,5 @@
 /* SPDX-License-Identifier: GPL-2.0 */
+#include <stdlib.h>
 #if defined(__i386__) || defined(__x86_64__)
 #define barrier() asm volatile("" ::: "memory")
 #define virt_mb() __sync_synchronize()
diff --git a/tools/virtio/generated/autoconf.h b/tools/virtio/generated/autoconf.h
new file mode 100644 (file)
index 0000000..e69de29
index 903dc9c4bd115f196538138da3b32f30bcbd807e..2c51bccb97bb27ee816e64644c41b4c00f967796 100644 (file)
@@ -7,4 +7,5 @@
 
 #define READ_ONCE(var) (*((volatile typeof(var) *)(&(var))))
 
+#define __aligned(x) __attribute((__aligned__(x)))
 #endif
index 20f6cf04377f0c257aeb4bacb3133b6a35e9e9b6..9860622cbb151126571ef0962cdab5735c59c5dd 100644 (file)
@@ -1,6 +1,8 @@
 # SPDX-License-Identifier: GPL-2.0
 # Makefile for vm tools
 #
+include ../scripts/Makefile.include
+
 TARGETS=page-types slabinfo page_owner_sort
 
 LIB_DIR = ../lib/api