Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net
authorLinus Torvalds <torvalds@linux-foundation.org>
Sun, 19 Jan 2020 20:03:53 +0000 (12:03 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sun, 19 Jan 2020 20:03:53 +0000 (12:03 -0800)
Pull networking fixes from David Miller:

 1) Fix non-blocking connect() in x25, from Martin Schiller.

 2) Fix spurious decryption errors in kTLS, from Jakub Kicinski.

 3) Netfilter use-after-free in mtype_destroy(), from Cong Wang.

 4) Limit size of TSO packets properly in lan78xx driver, from Eric
    Dumazet.

 5) r8152 probe needs an endpoint sanity check, from Johan Hovold.

 6) Prevent looping in tcp_bpf_unhash() during sockmap/tls free, from
    John Fastabend.

 7) hns3 needs short frames padded on transmit, from Yunsheng Lin.

 8) Fix netfilter ICMP header corruption, from Eyal Birger.

 9) Fix soft lockup when low on memory in hns3, from Yonglong Liu.

10) Fix NTUPLE firmware command failures in bnxt_en, from Michael Chan.

11) Fix memory leak in act_ctinfo, from Eric Dumazet.

* git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net: (91 commits)
  cxgb4: reject overlapped queues in TC-MQPRIO offload
  cxgb4: fix Tx multi channel port rate limit
  net: sched: act_ctinfo: fix memory leak
  bnxt_en: Do not treat DSN (Digital Serial Number) read failure as fatal.
  bnxt_en: Fix ipv6 RFS filter matching logic.
  bnxt_en: Fix NTUPLE firmware command failures.
  net: systemport: Fixed queue mapping in internal ring map
  net: dsa: bcm_sf2: Configure IMP port for 2Gb/sec
  net: dsa: sja1105: Don't error out on disabled ports with no phy-mode
  net: phy: dp83867: Set FORCE_LINK_GOOD to default after reset
  net: hns: fix soft lockup when there is not enough memory
  net: avoid updating qdisc_xmit_lock_key in netdev_update_lockdep_key()
  net/sched: act_ife: initalize ife->metalist earlier
  netfilter: nat: fix ICMP header corruption on ICMP errors
  net: wan: lapbether.c: Use built-in RCU list checking
  netfilter: nf_tables: fix flowtable list del corruption
  netfilter: nf_tables: fix memory leak in nf_tables_parse_netdev_hooks()
  netfilter: nf_tables: remove WARN and add NLA_STRING upper limits
  netfilter: nft_tunnel: ERSPAN_VERSION must not be null
  netfilter: nft_tunnel: fix null-attribute check
  ...

313 files changed:
Documentation/ABI/stable/sysfs-driver-mlxreg-io
Documentation/devicetree/bindings/i2c/i2c-at91.txt
Documentation/process/embargoed-hardware-issues.rst
MAINTAINERS
Makefile
arch/arm/Kconfig
arch/arm/boot/dts/am571x-idk.dts
arch/arm/boot/dts/am572x-idk-common.dtsi
arch/arm/boot/dts/am57xx-beagle-x15-common.dtsi
arch/arm/boot/dts/aspeed-bmc-ibm-rainier.dts
arch/arm/boot/dts/aspeed-bmc-opp-tacoma.dts
arch/arm/boot/dts/aspeed-g6.dtsi
arch/arm/boot/dts/imx6dl-icore-mipi.dts
arch/arm/boot/dts/imx6q-dhcom-pdk2.dts
arch/arm/boot/dts/imx6q-dhcom-som.dtsi
arch/arm/boot/dts/imx6qdl-sabresd.dtsi
arch/arm/boot/dts/imx6sl-evk.dts
arch/arm/boot/dts/imx6sll-evk.dts
arch/arm/boot/dts/imx6sx-sdb-reva.dts
arch/arm/boot/dts/imx6sx-sdb.dts
arch/arm/boot/dts/imx7s-colibri.dtsi
arch/arm/boot/dts/imx7ulp.dtsi
arch/arm/boot/dts/meson8.dtsi
arch/arm/boot/dts/mmp3.dtsi
arch/arm/boot/dts/sun8i-a83t-cubietruck-plus.dts
arch/arm/kernel/process.c
arch/arm/mach-davinci/Kconfig
arch/arm/mach-mmp/time.c
arch/arm/mach-omap2/Kconfig
arch/arm/mach-omap2/pdata-quirks.c
arch/arm64/Kconfig
arch/arm64/boot/dts/allwinner/sun50i-a64-olinuxino-emmc.dts
arch/arm64/boot/dts/allwinner/sun50i-a64-olinuxino.dts
arch/arm64/boot/dts/altera/socfpga_stratix10.dtsi
arch/arm64/boot/dts/amlogic/meson-sm1-sei610.dts
arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi
arch/arm64/boot/dts/freescale/imx8mm.dtsi
arch/arm64/boot/dts/freescale/imx8mq-librem5-devkit.dts
arch/arm64/boot/dts/intel/socfpga_agilex.dtsi
arch/arm64/boot/dts/rockchip/rk3328-a1.dts
arch/arm64/include/asm/unistd.h
arch/arm64/include/uapi/asm/unistd.h
arch/arm64/kernel/process.c
arch/nds32/include/asm/cacheflush.h
arch/nds32/include/asm/pgtable.h
arch/parisc/Kconfig
arch/parisc/kernel/drivers.c
arch/parisc/kernel/process.c
arch/parisc/mm/init.c
arch/riscv/Kconfig
arch/riscv/include/asm/sifive_l2_cache.h [deleted file]
arch/riscv/kernel/head.S
arch/riscv/kernel/process.c
arch/s390/kernel/setup.c
arch/um/Kconfig
arch/um/include/asm/ptrace-generic.h
arch/um/kernel/process.c
arch/x86/boot/compressed/head_64.S
arch/x86/events/intel/uncore_snb.c
arch/x86/events/intel/uncore_snbep.c
arch/x86/kernel/cpu/amd.c
arch/x86/kernel/cpu/mce/therm_throt.c
arch/x86/kernel/cpu/resctrl/core.c
arch/x86/kernel/cpu/resctrl/rdtgroup.c
arch/x86/um/tls_32.c
arch/x86/um/tls_64.c
arch/xtensa/Kconfig
arch/xtensa/kernel/process.c
block/bio.c
block/blk-merge.c
block/blk-settings.c
drivers/base/firmware_loader/builtin/Makefile
drivers/block/null_blk_zoned.c
drivers/bus/ti-sysc.c
drivers/clk/clk.c
drivers/clk/mmp/clk-of-mmp2.c
drivers/clk/qcom/gcc-sdm845.c
drivers/clk/samsung/clk-exynos5420.c
drivers/clk/sunxi-ng/ccu-sun50i-h6-r.c
drivers/clk/sunxi-ng/ccu-sun8i-r.c
drivers/clk/sunxi-ng/ccu-sun8i-r40.c
drivers/clk/sunxi-ng/ccu-sun8i-v3s.c
drivers/clk/sunxi-ng/ccu-sun8i-v3s.h
drivers/clk/tegra/clk.c
drivers/clk/ti/clk-dra7-atl.c
drivers/cpufreq/cpufreq-dt-platdev.c
drivers/cpuidle/governors/teo.c
drivers/crypto/hisilicon/sec2/sec.h
drivers/crypto/hisilicon/sec2/sec_crypto.c
drivers/crypto/hisilicon/sec2/sec_main.c
drivers/edac/sifive_edac.c
drivers/firmware/efi/earlycon.c
drivers/firmware/efi/libstub/random.c
drivers/gpio/Kconfig
drivers/gpio/gpio-mockup.c
drivers/gpio/gpio-thunderx.c
drivers/gpio/gpio-zynq.c
drivers/gpio/gpiolib-acpi.c
drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
drivers/gpu/drm/amd/display/dc/core/dc_link.c
drivers/gpu/drm/drm_dp_mst_topology.c
drivers/gpu/drm/drm_fb_helper.c
drivers/gpu/drm/i915/display/intel_audio.c
drivers/gpu/drm/i915/display/intel_display.c
drivers/gpu/drm/i915/gt/intel_context.c
drivers/gpu/drm/i915/gt/intel_lrc.c
drivers/gpu/drm/i915/gt/intel_ring_submission.c
drivers/gpu/drm/i915/i915_drv.h
drivers/gpu/drm/i915/i915_gem_gtt.c
drivers/gpu/drm/i915/i915_pmu.c
drivers/gpu/drm/i915/i915_reg.h
drivers/gpu/drm/i915/intel_pm.c
drivers/gpu/drm/i915/selftests/i915_random.h
drivers/gpu/drm/rockchip/cdn-dp-core.h
drivers/gpu/drm/sun4i/sun4i_tcon.c
drivers/gpu/drm/sun4i/sun4i_tcon.h
drivers/gpu/drm/virtio/virtgpu_plane.c
drivers/hid/hidraw.c
drivers/hid/uhid.c
drivers/hwtracing/coresight/coresight-etm4x.c
drivers/i2c/busses/i2c-at91-core.c
drivers/i2c/busses/i2c-bcm2835.c
drivers/i2c/busses/i2c-iop3xx.c
drivers/i2c/busses/i2c-tegra.c
drivers/i2c/i2c-core-base.c
drivers/iio/adc/ad7124.c
drivers/iio/chemical/Kconfig
drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c
drivers/iio/industrialio-buffer.c
drivers/iio/light/vcnl4000.c
drivers/infiniband/hw/bnxt_re/ib_verbs.c
drivers/infiniband/hw/bnxt_re/qplib_fp.c
drivers/infiniband/hw/hfi1/iowait.c
drivers/infiniband/hw/hfi1/tid_rdma.c
drivers/infiniband/hw/i40iw/i40iw_verbs.c
drivers/input/evdev.c
drivers/input/input.c
drivers/input/keyboard/imx_sc_key.c
drivers/input/misc/uinput.c
drivers/iommu/dma-iommu.c
drivers/iommu/intel-iommu.c
drivers/iommu/iommu.c
drivers/irqchip/irq-ingenic.c
drivers/md/dm-snap-persistent.c
drivers/md/raid0.c
drivers/message/fusion/mptctl.c
drivers/misc/enclosure.c
drivers/misc/lkdtm/bugs.c
drivers/mtd/nand/onenand/omap2.c
drivers/mtd/nand/onenand/onenand_base.c
drivers/mtd/nand/onenand/samsung_mtd.c
drivers/mtd/nand/raw/cadence-nand-controller.c
drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c
drivers/mtd/nand/raw/stm32_fmc2_nand.c
drivers/mtd/sm_ftl.c
drivers/mtd/spi-nor/spi-nor.c
drivers/nvme/host/core.c
drivers/nvme/target/admin-cmd.c
drivers/phy/motorola/phy-cpcap-usb.c
drivers/phy/motorola/phy-mapphone-mdm6600.c
drivers/phy/qualcomm/phy-qcom-qmp.c
drivers/phy/rockchip/phy-rockchip-inno-hdmi.c
drivers/pinctrl/cirrus/Kconfig
drivers/pinctrl/meson/pinctrl-meson.c
drivers/platform/chrome/wilco_ec/keyboard_leds.c
drivers/platform/mellanox/mlxbf-tmfifo.c
drivers/platform/x86/asus-wmi.c
drivers/platform/x86/gpd-pocket-fan.c
drivers/platform/x86/intel_ips.h
drivers/platform/x86/intel_pmc_core.h
drivers/platform/x86/intel_pmc_core_pltdrv.c
drivers/powercap/intel_rapl_common.c
drivers/s390/crypto/ap_bus.c
drivers/s390/crypto/ap_bus.h
drivers/s390/crypto/ap_queue.c
drivers/s390/crypto/zcrypt_ccamisc.c
drivers/s390/crypto/zcrypt_cex2a.c
drivers/s390/crypto/zcrypt_cex2c.c
drivers/s390/crypto/zcrypt_cex4.c
drivers/scsi/fnic/vnic_dev.c
drivers/scsi/sd.c
drivers/scsi/storvsc_drv.c
drivers/soc/amlogic/meson-ee-pwrc.c
drivers/soc/sifive/sifive_l2_cache.c
drivers/soc/ti/wkup_m3_ipc.c
drivers/staging/comedi/drivers/adv_pci1710.c
drivers/staging/comedi/drivers/ni_routes.c
drivers/staging/rtl8188eu/os_dep/usb_intf.c
drivers/staging/vt6656/baseband.c
drivers/staging/vt6656/card.c
drivers/staging/vt6656/device.h
drivers/staging/vt6656/main_usb.c
drivers/staging/vt6656/usbpipe.c
drivers/staging/vt6656/usbpipe.h
drivers/staging/vt6656/wcmd.c
drivers/tee/optee/shm_pool.c
drivers/thermal/qcom/tsens.c
drivers/tty/serdev/core.c
drivers/tty/tty_port.c
drivers/usb/cdns3/gadget.c
drivers/usb/chipidea/host.c
drivers/usb/core/config.c
drivers/usb/core/hub.c
drivers/usb/dwc3/gadget.c
drivers/usb/gadget/udc/Kconfig
drivers/usb/host/ohci-da8xx.c
drivers/usb/musb/jz4740.c
drivers/usb/musb/musb_core.c
drivers/usb/musb/musbhsdma.c
drivers/usb/serial/ch341.c
drivers/usb/serial/io_edgeport.c
drivers/usb/serial/keyspan.c
drivers/usb/serial/opticon.c
drivers/usb/serial/option.c
drivers/usb/serial/quatech2.c
drivers/usb/serial/usb-serial-simple.c
drivers/usb/serial/usb-serial.c
drivers/usb/serial/usb-wwan.h
drivers/usb/serial/usb_wwan.c
drivers/usb/typec/tcpm/tcpci.c
drivers/usb/typec/ucsi/ucsi.h
fs/afs/dir.c
fs/btrfs/inode.c
fs/btrfs/ioctl.c
fs/btrfs/qgroup.c
fs/btrfs/relocation.c
fs/btrfs/root-tree.c
fs/btrfs/volumes.c
fs/buffer.c
fs/char_dev.c
fs/fuse/file.c
fs/internal.h
fs/io-wq.c
fs/io_uring.c
fs/mpage.c
fs/namei.c
fs/nfs/nfstrace.h
fs/pstore/ram.c
fs/pstore/ram_core.c
include/asm-generic/cacheflush.h
include/drm/drm_dp_mst_helper.h
include/dt-bindings/reset/amlogic,meson8b-reset.h
include/linux/blkdev.h
include/linux/bvec.h
include/linux/mm.h
include/linux/mmzone.h
include/linux/mtd/flashchip.h
include/linux/namei.h
include/linux/sched.h
include/soc/sifive/sifive_l2_cache.h [new file with mode: 0644]
include/trace/events/afs.h
include/trace/events/huge_memory.h
include/uapi/linux/input.h
init/main.c
kernel/cpu.c
kernel/cred.c
kernel/events/core.c
kernel/fork.c
kernel/futex.c
kernel/locking/lockdep.c
kernel/locking/rwsem.c
kernel/ptrace.c
kernel/rseq.c
kernel/time/posix-stubs.c
kernel/time/tick-sched.c
lib/vdso/gettimeofday.c
mm/huge_memory.c
mm/memcontrol.c
mm/mempolicy.c
mm/page-writeback.c
mm/page_alloc.c
mm/shmem.c
mm/slab.c
mm/slab_common.c
mm/slub.c
mm/sparse.c
mm/vmalloc.c
net/sunrpc/xprtrdma/verbs.c
net/sunrpc/xprtrdma/xprt_rdma.h
sound/core/seq/seq_timer.c
sound/firewire/dice/dice-extension.c
sound/firewire/tascam/amdtp-tascam.c
sound/hda/hdac_regmap.c
sound/pci/hda/hda_intel.c
sound/pci/hda/patch_realtek.c
sound/soc/codecs/cros_ec_codec.c
sound/soc/codecs/hdac_hda.c
sound/soc/codecs/msm8916-wcd-analog.c
sound/soc/codecs/msm8916-wcd-digital.c
sound/soc/codecs/rt5640.c
sound/soc/fsl/fsl_audmix.c
sound/soc/intel/boards/bytcht_es8316.c
sound/soc/intel/boards/cml_rt1011_rt5682.c
sound/soc/soc-component.c
sound/soc/soc-core.c
sound/soc/soc-topology.c
sound/soc/sof/imx/imx8.c
sound/soc/sof/intel/hda-codec.c
sound/soc/sof/intel/hda-dai.c
sound/soc/sof/intel/hda-loader.c
sound/soc/sof/ipc.c
sound/soc/sti/uniperif_player.c
sound/soc/stm/stm32_adfsdm.c
sound/soc/stm/stm32_sai_sub.c
sound/soc/stm/stm32_spdifrx.c
sound/usb/pcm.c
sound/usb/quirks.c
tools/lib/traceevent/parse-filter.c
tools/perf/builtin-report.c
tools/perf/util/hist.h
tools/perf/util/symbol-elf.c

index 8ca4984..05601a9 100644 (file)
@@ -29,13 +29,13 @@ Description:        This file shows the system fans direction:
 
                The files are read only.
 
-What:          /sys/devices/platform/mlxplat/mlxreg-io/hwmon/hwmon*/jtag_enable
+What:          /sys/devices/platform/mlxplat/mlxreg-io/hwmon/hwmon*/cpld3_version
 
 Date:          November 2018
 KernelVersion: 5.0
 Contact:       Vadim Pasternak <vadimpmellanox.com>
 Description:   These files show with which CPLD versions have been burned
-               on LED board.
+               on LED or Gearbox board.
 
                The files are read only.
 
@@ -121,6 +121,15 @@ Description:       These files show the system reset cause, as following: ComEx
 
                The files are read only.
 
+What:          /sys/devices/platform/mlxplat/mlxreg-io/hwmon/hwmon*/cpld4_version
+Date:          November 2018
+KernelVersion: 5.0
+Contact:       Vadim Pasternak <vadimpmellanox.com>
+Description:   These files show with which CPLD versions have been burned
+               on LED board.
+
+               The files are read only.
+
 Date:          June 2019
 KernelVersion: 5.3
 Contact:       Vadim Pasternak <vadimpmellanox.com>
index 2210f43..8347b1e 100644 (file)
@@ -18,8 +18,10 @@ Optional properties:
 - dma-names: should contain "tx" and "rx".
 - atmel,fifo-size: maximum number of data the RX and TX FIFOs can store for FIFO
   capable I2C controllers.
-- i2c-sda-hold-time-ns: TWD hold time, only available for "atmel,sama5d4-i2c"
-  and "atmel,sama5d2-i2c".
+- i2c-sda-hold-time-ns: TWD hold time, only available for:
+       "atmel,sama5d4-i2c",
+       "atmel,sama5d2-i2c",
+       "microchip,sam9x60-i2c".
 - Child nodes conforming to i2c bus binding
 
 Examples :
index 799580a..5d54946 100644 (file)
@@ -255,7 +255,7 @@ an involved disclosed party. The current ambassadors list:
   Red Hat      Josh Poimboeuf <jpoimboe@redhat.com>
   SUSE         Jiri Kosina <jkosina@suse.cz>
 
-  Amazon
+  Amazon       Peter Bowen <pzb@amzn.com>
   Google       Kees Cook <keescook@chromium.org>
   ============= ========================================================
 
index 7933584..cf6ccca 100644 (file)
@@ -720,7 +720,7 @@ F:  Documentation/devicetree/bindings/i2c/i2c-altera.txt
 F:     drivers/i2c/busses/i2c-altera.c
 
 ALTERA MAILBOX DRIVER
-M:     Ley Foon Tan <lftan@altera.com>
+M:     Ley Foon Tan <ley.foon.tan@intel.com>
 L:     nios2-dev@lists.rocketboards.org (moderated for non-subscribers)
 S:     Maintained
 F:     drivers/mailbox/mailbox-altera.c
@@ -1407,7 +1407,7 @@ T:        git git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc.git
 
 ARM/ACTIONS SEMI ARCHITECTURE
 M:     Andreas Färber <afaerber@suse.de>
-R:     Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+M:     Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 S:     Maintained
 N:     owl
@@ -11680,7 +11680,7 @@ F:      Documentation/scsi/NinjaSCSI.txt
 F:     drivers/scsi/nsp32*
 
 NIOS2 ARCHITECTURE
-M:     Ley Foon Tan <lftan@altera.com>
+M:     Ley Foon Tan <ley.foon.tan@intel.com>
 L:     nios2-dev@lists.rocketboards.org (moderated for non-subscribers)
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/lftan/nios2.git
 S:     Maintained
@@ -12564,7 +12564,7 @@ F:      Documentation/devicetree/bindings/pci/aardvark-pci.txt
 F:     drivers/pci/controller/pci-aardvark.c
 
 PCI DRIVER FOR ALTERA PCIE IP
-M:     Ley Foon Tan <lftan@altera.com>
+M:     Ley Foon Tan <ley.foon.tan@intel.com>
 L:     rfi@lists.rocketboards.org (moderated for non-subscribers)
 L:     linux-pci@vger.kernel.org
 S:     Supported
@@ -12743,7 +12743,7 @@ S:      Supported
 F:     Documentation/PCI/pci-error-recovery.rst
 
 PCI MSI DRIVER FOR ALTERA MSI IP
-M:     Ley Foon Tan <lftan@altera.com>
+M:     Ley Foon Tan <ley.foon.tan@intel.com>
 L:     rfi@lists.rocketboards.org (moderated for non-subscribers)
 L:     linux-pci@vger.kernel.org
 S:     Supported
index e4c2d03..0a7c37d 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -2,7 +2,7 @@
 VERSION = 5
 PATCHLEVEL = 5
 SUBLEVEL = 0
-EXTRAVERSION = -rc5
+EXTRAVERSION = -rc6
 NAME = Kleptomaniac Octopus
 
 # *DOCUMENTATION*
index ba75e36..96dab76 100644 (file)
@@ -72,6 +72,7 @@ config ARM
        select HAVE_ARM_SMCCC if CPU_V7
        select HAVE_EBPF_JIT if !CPU_ENDIAN_BE32
        select HAVE_CONTEXT_TRACKING
+       select HAVE_COPY_THREAD_TLS
        select HAVE_C_RECORDMCOUNT
        select HAVE_DEBUG_KMEMLEAK
        select HAVE_DMA_CONTIGUOUS if MMU
index 820ce3b..669559c 100644 (file)
 
 &pcie1_rc {
        status = "okay";
-       gpios = <&gpio3 23 GPIO_ACTIVE_HIGH>;
-};
-
-&pcie1_ep {
-       gpios = <&gpio3 23 GPIO_ACTIVE_HIGH>;
+       gpios = <&gpio5 18 GPIO_ACTIVE_HIGH>;
 };
 
 &mmc1 {
index a064f13..ddf1236 100644 (file)
        gpios = <&gpio3 23 GPIO_ACTIVE_HIGH>;
 };
 
-&pcie1_ep {
-       gpios = <&gpio3 23 GPIO_ACTIVE_HIGH>;
-};
-
 &mailbox5 {
        status = "okay";
        mbox_ipu1_ipc3x: mbox_ipu1_ipc3x {
index bc76f17..a813a0c 100644 (file)
                reg = <0x0 0x80000000 0x0 0x80000000>;
        };
 
+       main_12v0: fixedregulator-main_12v0 {
+               /* main supply */
+               compatible = "regulator-fixed";
+               regulator-name = "main_12v0";
+               regulator-min-microvolt = <12000000>;
+               regulator-max-microvolt = <12000000>;
+               regulator-always-on;
+               regulator-boot-on;
+       };
+
+       evm_5v0: fixedregulator-evm_5v0 {
+               /* Output of TPS54531D */
+               compatible = "regulator-fixed";
+               regulator-name = "evm_5v0";
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+               vin-supply = <&main_12v0>;
+               regulator-always-on;
+               regulator-boot-on;
+       };
+
        vdd_3v3: fixedregulator-vdd_3v3 {
                compatible = "regulator-fixed";
                regulator-name = "vdd_3v3";
        gpios = <&gpio2 8 GPIO_ACTIVE_LOW>;
 };
 
-&pcie1_ep {
-       gpios = <&gpio2 8 GPIO_ACTIVE_LOW>;
-};
-
 &mcasp3 {
        #sound-dai-cells = <0>;
        assigned-clocks = <&l4per2_clkctrl DRA7_L4PER2_MCASP3_CLKCTRL 24>;
index c1c9cd3..13f7aef 100644 (file)
                };
        };
 
-       pca0: pca9552@60 {
+       pca0: pca9552@61 {
                compatible = "nxp,pca9552";
-               reg = <0x60>;
+               reg = <0x61>;
                #address-cells = <1>;
                #size-cells = <0>;
 
        status = "okay";
 };
 
-&i2c13 {
-       status = "okay";
-};
-
-&i2c14 {
-       status = "okay";
-};
-
-&i2c15 {
-       status = "okay";
-};
-
-&i2c0 {
-       status = "okay";
-};
-
-&i2c1 {
-       status = "okay";
-};
-
-&i2c2 {
-       status = "okay";
-};
-
-&i2c3 {
-       status = "okay";
-
-       power-supply@68 {
-               compatible = "ibm,cffps2";
-               reg = <0x68>;
-       };
-
-       power-supply@69 {
-               compatible = "ibm,cffps2";
-               reg = <0x69>;
-       };
-
-       power-supply@6a {
-               compatible = "ibm,cffps2";
-               reg = <0x6a>;
-       };
-
-       power-supply@6b {
-               compatible = "ibm,cffps2";
-               reg = <0x6b>;
-       };
-};
-
-&i2c4 {
-       status = "okay";
-
-       tmp275@48 {
-               compatible = "ti,tmp275";
-               reg = <0x48>;
-       };
-
-       tmp275@49 {
-               compatible = "ti,tmp275";
-               reg = <0x49>;
-       };
-
-       tmp275@4a {
-               compatible = "ti,tmp275";
-               reg = <0x4a>;
-       };
-};
-
-&i2c5 {
-       status = "okay";
-
-       tmp275@48 {
-               compatible = "ti,tmp275";
-               reg = <0x48>;
-       };
-
-       tmp275@49 {
-               compatible = "ti,tmp275";
-               reg = <0x49>;
-       };
-};
-
-&i2c6 {
-       status = "okay";
-
-       tmp275@48 {
-               compatible = "ti,tmp275";
-               reg = <0x48>;
-       };
-
-       tmp275@4a {
-               compatible = "ti,tmp275";
-               reg = <0x4a>;
-       };
-
-       tmp275@4b {
-               compatible = "ti,tmp275";
-               reg = <0x4b>;
-       };
-};
-
-&i2c7 {
-       status = "okay";
-
-       si7021-a20@20 {
-               compatible = "silabs,si7020";
-               reg = <0x20>;
-       };
-
-       tmp275@48 {
-               compatible = "ti,tmp275";
-               reg = <0x48>;
-       };
-
-       max31785@52 {
-               compatible = "maxim,max31785a";
-               reg = <0x52>;
-               #address-cells = <1>;
-               #size-cells = <0>;
-
-               fan@0 {
-                       compatible = "pmbus-fan";
-                       reg = <0>;
-                       tach-pulses = <2>;
-               };
-
-               fan@1 {
-                       compatible = "pmbus-fan";
-                       reg = <1>;
-                       tach-pulses = <2>;
-               };
-
-               fan@2 {
-                       compatible = "pmbus-fan";
-                       reg = <2>;
-                       tach-pulses = <2>;
-               };
-
-               fan@3 {
-                       compatible = "pmbus-fan";
-                       reg = <3>;
-                       tach-pulses = <2>;
-               };
-       };
-
-       pca0: pca9552@60 {
-               compatible = "nxp,pca9552";
-               reg = <0x60>;
-               #address-cells = <1>;
-               #size-cells = <0>;
-
-               gpio-controller;
-               #gpio-cells = <2>;
-
-               gpio@0 {
-                       reg = <0>;
-               };
-
-               gpio@1 {
-                       reg = <1>;
-               };
-
-               gpio@2 {
-                       reg = <2>;
-               };
-
-               gpio@3 {
-                       reg = <3>;
-               };
-
-               gpio@4 {
-                       reg = <4>;
-               };
-
-               gpio@5 {
-                       reg = <5>;
-               };
-
-               gpio@6 {
-                       reg = <6>;
-               };
-
-               gpio@7 {
-                       reg = <7>;
-               };
-
-               gpio@8 {
-                       reg = <8>;
-               };
-
-               gpio@9 {
-                       reg = <9>;
-               };
-
-               gpio@10 {
-                       reg = <10>;
-               };
-
-               gpio@11 {
-                       reg = <11>;
-               };
-
-               gpio@12 {
-                       reg = <12>;
-               };
-
-               gpio@13 {
-                       reg = <13>;
-               };
-
-               gpio@14 {
-                       reg = <14>;
-               };
-
-               gpio@15 {
-                       reg = <15>;
-               };
-       };
-
-       dps: dps310@76 {
-               compatible = "infineon,dps310";
-               reg = <0x76>;
-               #io-channel-cells = <0>;
-       };
-};
-
-&i2c8 {
-       status = "okay";
-
-       ucd90320@b {
-               compatible = "ti,ucd90160";
-               reg = <0x0b>;
-       };
-
-       ucd90320@c {
-               compatible = "ti,ucd90160";
-               reg = <0x0c>;
-       };
-
-       ucd90320@11 {
-               compatible = "ti,ucd90160";
-               reg = <0x11>;
-       };
-
-       rtc@32 {
-               compatible = "epson,rx8900";
-               reg = <0x32>;
-       };
-
-       tmp275@48 {
-               compatible = "ti,tmp275";
-               reg = <0x48>;
-       };
-
-       tmp275@4a {
-               compatible = "ti,tmp275";
-               reg = <0x4a>;
-       };
-};
-
-&i2c9 {
-       status = "okay";
-
-       ir35221@42 {
-               compatible = "infineon,ir35221";
-               reg = <0x42>;
-       };
-
-       ir35221@43 {
-               compatible = "infineon,ir35221";
-               reg = <0x43>;
-       };
-
-       ir35221@44 {
-               compatible = "infineon,ir35221";
-               reg = <0x44>;
-       };
-
-       tmp423a@4c {
-               compatible = "ti,tmp423";
-               reg = <0x4c>;
-       };
-
-       tmp423b@4d {
-               compatible = "ti,tmp423";
-               reg = <0x4d>;
-       };
-
-       ir35221@72 {
-               compatible = "infineon,ir35221";
-               reg = <0x72>;
-       };
-
-       ir35221@73 {
-               compatible = "infineon,ir35221";
-               reg = <0x73>;
-       };
-
-       ir35221@74 {
-               compatible = "infineon,ir35221";
-               reg = <0x74>;
-       };
-};
-
-&i2c10 {
-       status = "okay";
-
-       ir35221@42 {
-               compatible = "infineon,ir35221";
-               reg = <0x42>;
-       };
-
-       ir35221@43 {
-               compatible = "infineon,ir35221";
-               reg = <0x43>;
-       };
-
-       ir35221@44 {
-               compatible = "infineon,ir35221";
-               reg = <0x44>;
-       };
-
-       tmp423a@4c {
-               compatible = "ti,tmp423";
-               reg = <0x4c>;
-       };
-
-       tmp423b@4d {
-               compatible = "ti,tmp423";
-               reg = <0x4d>;
-       };
-
-       ir35221@72 {
-               compatible = "infineon,ir35221";
-               reg = <0x72>;
-       };
-
-       ir35221@73 {
-               compatible = "infineon,ir35221";
-               reg = <0x73>;
-       };
-
-       ir35221@74 {
-               compatible = "infineon,ir35221";
-               reg = <0x74>;
-       };
-};
-
-&i2c11 {
-       status = "okay";
-
-       tmp275@48 {
-               compatible = "ti,tmp275";
-               reg = <0x48>;
-       };
-
-       tmp275@49 {
-               compatible = "ti,tmp275";
-               reg = <0x49>;
-       };
-};
-
-&i2c12 {
-       status = "okay";
-};
-
 &i2c13 {
        status = "okay";
 
index f02de4a..ff49ec7 100644 (file)
        };
 };
 
-&fmc {
-       status = "okay";
-       flash@0 {
-               status = "okay";
-               m25p,fast-read;
-               label = "bmc";
-               spi-max-frequency = <50000000>;
-#include "openbmc-flash-layout-128.dtsi"
-       };
-
-       flash@1 {
-               status = "okay";
-               m25p,fast-read;
-               label = "alt-bmc";
-               spi-max-frequency = <50000000>;
-       };
-};
-
-&spi1 {
-       status = "okay";
-       pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_spi1_default>;
-
-       flash@0 {
-               status = "okay";
-               m25p,fast-read;
-               label = "pnor";
-               spi-max-frequency = <100000000>;
-       };
-};
-
 &mac2 {
        status = "okay";
        pinctrl-names = "default";
 
 &emmc {
        status = "okay";
+};
+
+&fsim0 {
+       status = "okay";
+
        #address-cells = <2>;
        #size-cells = <0>;
 
        status = "okay";
 };
 
-&i2c0 {
-       status = "okay";
-};
-
-&i2c1 {
-       status = "okay";
-};
-
-&i2c2 {
-       status = "okay";
-};
-
-&i2c3 {
-       status = "okay";
-
-       bmp: bmp280@77 {
-               compatible = "bosch,bmp280";
-               reg = <0x77>;
-               #io-channel-cells = <1>;
-       };
-
-       max31785@52 {
-               compatible = "maxim,max31785a";
-               reg = <0x52>;
-               #address-cells = <1>;
-               #size-cells = <0>;
-
-               fan@0 {
-                       compatible = "pmbus-fan";
-                       reg = <0>;
-                       tach-pulses = <2>;
-                       maxim,fan-rotor-input = "tach";
-                       maxim,fan-pwm-freq = <25000>;
-                       maxim,fan-dual-tach;
-                       maxim,fan-no-watchdog;
-                       maxim,fan-no-fault-ramp;
-                       maxim,fan-ramp = <2>;
-                       maxim,fan-fault-pin-mon;
-               };
-
-               fan@1 {
-                       compatible = "pmbus-fan";
-                       reg = <1>;
-                       tach-pulses = <2>;
-                       maxim,fan-rotor-input = "tach";
-                       maxim,fan-pwm-freq = <25000>;
-                       maxim,fan-dual-tach;
-                       maxim,fan-no-watchdog;
-                       maxim,fan-no-fault-ramp;
-                       maxim,fan-ramp = <2>;
-                       maxim,fan-fault-pin-mon;
-               };
-
-               fan@2 {
-                       compatible = "pmbus-fan";
-                       reg = <2>;
-                       tach-pulses = <2>;
-                       maxim,fan-rotor-input = "tach";
-                       maxim,fan-pwm-freq = <25000>;
-                       maxim,fan-dual-tach;
-                       maxim,fan-no-watchdog;
-                       maxim,fan-no-fault-ramp;
-                       maxim,fan-ramp = <2>;
-                       maxim,fan-fault-pin-mon;
-               };
-
-               fan@3 {
-                       compatible = "pmbus-fan";
-                       reg = <3>;
-                       tach-pulses = <2>;
-                       maxim,fan-rotor-input = "tach";
-                       maxim,fan-pwm-freq = <25000>;
-                       maxim,fan-dual-tach;
-                       maxim,fan-no-watchdog;
-                       maxim,fan-no-fault-ramp;
-                       maxim,fan-ramp = <2>;
-                       maxim,fan-fault-pin-mon;
-               };
-       };
-
-       dps: dps310@76 {
-               compatible = "infineon,dps310";
-               reg = <0x76>;
-               #io-channel-cells = <0>;
-       };
-
-       pca0: pca9552@60 {
-               compatible = "nxp,pca9552";
-               reg = <0x60>;
-               #address-cells = <1>;
-               #size-cells = <0>;
-
-               gpio-controller;
-               #gpio-cells = <2>;
-
-               gpio@0 {
-                       reg = <0>;
-                       type = <PCA955X_TYPE_GPIO>;
-               };
-
-               gpio@1 {
-                       reg = <1>;
-                       type = <PCA955X_TYPE_GPIO>;
-               };
-
-               gpio@2 {
-                       reg = <2>;
-                       type = <PCA955X_TYPE_GPIO>;
-               };
-
-               gpio@3 {
-                       reg = <3>;
-                       type = <PCA955X_TYPE_GPIO>;
-               };
-
-               gpio@4 {
-                       reg = <4>;
-                       type = <PCA955X_TYPE_GPIO>;
-               };
-
-               gpio@5 {
-                       reg = <5>;
-                       type = <PCA955X_TYPE_GPIO>;
-               };
-
-               gpio@6 {
-                       reg = <6>;
-                       type = <PCA955X_TYPE_GPIO>;
-               };
-
-               gpio@7 {
-                       reg = <7>;
-                       type = <PCA955X_TYPE_GPIO>;
-               };
-
-               gpio@8 {
-                       reg = <8>;
-                       type = <PCA955X_TYPE_GPIO>;
-               };
-
-               gpio@9 {
-                       reg = <9>;
-                       type = <PCA955X_TYPE_GPIO>;
-               };
-
-               gpio@10 {
-                       reg = <10>;
-                       type = <PCA955X_TYPE_GPIO>;
-               };
-
-               gpio@11 {
-                       reg = <11>;
-                       type = <PCA955X_TYPE_GPIO>;
-               };
-
-               gpio@12 {
-                       reg = <12>;
-                       type = <PCA955X_TYPE_GPIO>;
-               };
-
-               gpio@13 {
-                       reg = <13>;
-                       type = <PCA955X_TYPE_GPIO>;
-               };
-
-               gpio@14 {
-                       reg = <14>;
-                       type = <PCA955X_TYPE_GPIO>;
-               };
-
-               gpio@15 {
-                       reg = <15>;
-                       type = <PCA955X_TYPE_GPIO>;
-               };
-       };
-
-       power-supply@68 {
-               compatible = "ibm,cffps1";
-               reg = <0x68>;
-       };
-
-       power-supply@69 {
-               compatible = "ibm,cffps1";
-               reg = <0x69>;
-       };
-};
-
-&i2c4 {
-       status = "okay";
-
-       tmp423a@4c {
-               compatible = "ti,tmp423";
-               reg = <0x4c>;
-       };
-
-       ir35221@70 {
-               compatible = "infineon,ir35221";
-               reg = <0x70>;
-       };
-
-       ir35221@71 {
-               compatible = "infineon,ir35221";
-               reg = <0x71>;
-       };
-};
-
-&i2c5 {
-       status = "okay";
-
-       tmp423a@4c {
-               compatible = "ti,tmp423";
-               reg = <0x4c>;
-       };
-
-       ir35221@70 {
-               compatible = "infineon,ir35221";
-               reg = <0x70>;
-       };
-
-       ir35221@71 {
-               compatible = "infineon,ir35221";
-               reg = <0x71>;
-       };
-};
-
-&i2c7 {
-       status = "okay";
-};
-
-&i2c9 {
-       status = "okay";
-
-       tmp275@4a {
-               compatible = "ti,tmp275";
-               reg = <0x4a>;
-       };
-};
-
-&i2c10 {
-       status = "okay";
-};
-
-&i2c11 {
-       status = "okay";
-
-       pca9552: pca9552@60 {
-               compatible = "nxp,pca9552";
-               reg = <0x60>;
-               #address-cells = <1>;
-               #size-cells = <0>;
-               gpio-controller;
-               #gpio-cells = <2>;
-
-               gpio-line-names = "PS_SMBUS_RESET_N", "APSS_RESET_N",
-                       "GPU0_TH_OVERT_N_BUFF", "GPU1_TH_OVERT_N_BUFF",
-                       "GPU2_TH_OVERT_N_BUFF", "GPU3_TH_OVERT_N_BUFF",
-                       "GPU4_TH_OVERT_N_BUFF", "GPU5_TH_OVERT_N_BUFF",
-                       "GPU0_PWR_GOOD_BUFF", "GPU1_PWR_GOOD_BUFF",
-                       "GPU2_PWR_GOOD_BUFF", "GPU3_PWR_GOOD_BUFF",
-                       "GPU4_PWR_GOOD_BUFF", "GPU5_PWR_GOOD_BUFF",
-                       "12V_BREAKER_FLT_N", "THROTTLE_UNLATCHED_N";
-
-               gpio@0 {
-                       reg = <0>;
-                       type = <PCA955X_TYPE_GPIO>;
-               };
-
-               gpio@1 {
-                       reg = <1>;
-                       type = <PCA955X_TYPE_GPIO>;
-               };
-
-               gpio@2 {
-                       reg = <2>;
-                       type = <PCA955X_TYPE_GPIO>;
-               };
-
-               gpio@3 {
-                       reg = <3>;
-                       type = <PCA955X_TYPE_GPIO>;
-               };
-
-               gpio@4 {
-                       reg = <4>;
-                       type = <PCA955X_TYPE_GPIO>;
-               };
-
-               gpio@5 {
-                       reg = <5>;
-                       type = <PCA955X_TYPE_GPIO>;
-               };
-
-               gpio@6 {
-                       reg = <6>;
-                       type = <PCA955X_TYPE_GPIO>;
-               };
-
-               gpio@7 {
-                       reg = <7>;
-                       type = <PCA955X_TYPE_GPIO>;
-               };
-
-               gpio@8 {
-                       reg = <8>;
-                       type = <PCA955X_TYPE_GPIO>;
-               };
-
-               gpio@9 {
-                       reg = <9>;
-                       type = <PCA955X_TYPE_GPIO>;
-               };
-
-               gpio@10 {
-                       reg = <10>;
-                       type = <PCA955X_TYPE_GPIO>;
-               };
-
-               gpio@11 {
-                       reg = <11>;
-                       type = <PCA955X_TYPE_GPIO>;
-               };
-
-               gpio@12 {
-                       reg = <12>;
-                       type = <PCA955X_TYPE_GPIO>;
-               };
-
-               gpio@13 {
-                       reg = <13>;
-                       type = <PCA955X_TYPE_GPIO>;
-               };
-
-               gpio@14 {
-                       reg = <14>;
-                       type = <PCA955X_TYPE_GPIO>;
-               };
-
-               gpio@15 {
-                       reg = <15>;
-                       type = <PCA955X_TYPE_GPIO>;
-               };
-       };
-
-       rtc@32 {
-               compatible = "epson,rx8900";
-               reg = <0x32>;
-       };
-
-       eeprom@51 {
-               compatible = "atmel,24c64";
-               reg = <0x51>;
-       };
-
-       ucd90160@64 {
-               compatible = "ti,ucd90160";
-               reg = <0x64>;
-       };
-};
-
-&i2c12 {
-       status = "okay";
-};
-
-&i2c13 {
-       status = "okay";
-};
-
 &pinctrl {
        /* Hog these as no driver is probed for the entire LPC block */
        pinctrl-names = "default";
index 5f6142d..b72afba 100644 (file)
                                spi-max-frequency = <50000000>;
                                status = "disabled";
                        };
-
-                       fsim0: fsi@1e79b000 {
-                               compatible = "aspeed,ast2600-fsi-master", "fsi-master";
-                               reg = <0x1e79b000 0x94>;
-                               interrupts = <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>;
-                               pinctrl-names = "default";
-                               pinctrl-0 = <&pinctrl_fsi1_default>;
-                               clocks = <&syscon ASPEED_CLK_GATE_FSICLK>;
-                               status = "disabled";
-                       };
-
-                       fsim1: fsi@1e79b100 {
-                               compatible = "aspeed,ast2600-fsi-master", "fsi-master";
-                               reg = <0x1e79b100 0x94>;
-                               interrupts = <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>;
-                               pinctrl-names = "default";
-                               pinctrl-0 = <&pinctrl_fsi2_default>;
-                               clocks = <&syscon ASPEED_CLK_GATE_FSICLK>;
-                               status = "disabled";
-                       };
                };
 
                mdio0: mdio@1e650000 {
                                ranges = <0 0x1e78a000 0x1000>;
                        };
 
+                       fsim0: fsi@1e79b000 {
+                               compatible = "aspeed,ast2600-fsi-master", "fsi-master";
+                               reg = <0x1e79b000 0x94>;
+                               interrupts = <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>;
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&pinctrl_fsi1_default>;
+                               clocks = <&syscon ASPEED_CLK_GATE_FSICLK>;
+                               status = "disabled";
+                       };
+
+                       fsim1: fsi@1e79b100 {
+                               compatible = "aspeed,ast2600-fsi-master", "fsi-master";
+                               reg = <0x1e79b100 0x94>;
+                               interrupts = <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>;
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&pinctrl_fsi2_default>;
+                               clocks = <&syscon ASPEED_CLK_GATE_FSICLK>;
+                               status = "disabled";
+                       };
                };
        };
 };
index e43bccb..d8f3821 100644 (file)
@@ -8,7 +8,7 @@
 /dts-v1/;
 
 #include "imx6dl.dtsi"
-#include "imx6qdl-icore.dtsi"
+#include "imx6qdl-icore-1.5.dtsi"
 
 / {
        model = "Engicam i.CoreM6 DualLite/Solo MIPI Starter Kit";
index 5219553..bb74fc6 100644 (file)
@@ -63,7 +63,7 @@
                #sound-dai-cells = <0>;
                clocks = <&clk_ext_audio_codec>;
                VDDA-supply = <&reg_3p3v>;
-               VDDIO-supply = <&reg_3p3v>;
+               VDDIO-supply = <&sw2_reg>;
        };
 };
 
index 845cfad..87f0aa8 100644 (file)
        };
 
        rtc@56 {
-               compatible = "rv3029c2";
+               compatible = "microcrystal,rv3029";
                pinctrl-names = "default";
                pinctrl-0 = <&pinctrl_rtc_hw300>;
                reg = <0x56>;
index 71ca76a..fe59dde 100644 (file)
        vin-supply = <&vgen5_reg>;
 };
 
-&reg_vdd3p0 {
-       vin-supply = <&sw2_reg>;
-};
-
 &reg_vdd2p5 {
        vin-supply = <&vgen5_reg>;
 };
index 4829aa6..bc86cfa 100644 (file)
        vin-supply = <&sw2_reg>;
 };
 
-&reg_vdd3p0 {
-       vin-supply = <&sw2_reg>;
-};
-
 &reg_vdd2p5 {
        vin-supply = <&sw2_reg>;
 };
index 3e1d32f..5ace9e6 100644 (file)
        status = "okay";
 };
 
-&reg_3p0 {
-       vin-supply = <&sw2_reg>;
-};
-
 &snvs_poweroff {
        status = "okay";
 };
index f1830ed..91a7548 100644 (file)
        vin-supply = <&vgen6_reg>;
 };
 
-&reg_vdd3p0 {
-       vin-supply = <&sw2_reg>;
-};
-
 &reg_vdd2p5 {
        vin-supply = <&vgen6_reg>;
 };
index a8ee708..5a63ca6 100644 (file)
        vin-supply = <&vgen6_reg>;
 };
 
-&reg_vdd3p0 {
-       vin-supply = <&sw2_reg>;
-};
-
 &reg_vdd2p5 {
        vin-supply = <&vgen6_reg>;
 };
index 1fb1ec5..6d16e32 100644 (file)
@@ -49,3 +49,7 @@
                reg = <0x80000000 0x10000000>;
        };
 };
+
+&gpmi {
+       status = "okay";
+};
index d37a192..ab91c98 100644 (file)
                #address-cells = <1>;
                #size-cells = <0>;
 
-               cpu0: cpu@0 {
+               cpu0: cpu@f00 {
                        compatible = "arm,cortex-a7";
                        device_type = "cpu";
-                       reg = <0>;
+                       reg = <0xf00>;
                };
        };
 
index 5a7e3e5..3c534cd 100644 (file)
 &aobus {
        pmu: pmu@e0 {
                compatible = "amlogic,meson8-pmu", "syscon";
-               reg = <0xe0 0x8>;
+               reg = <0xe0 0x18>;
        };
 
        pinctrl_aobus: pinctrl@84 {
index d9762de..6f48082 100644 (file)
 
                        twsi1: i2c@d4011000 {
                                compatible = "mrvl,mmp-twsi";
-                               reg = <0xd4011000 0x1000>;
+                               reg = <0xd4011000 0x70>;
                                interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&soc_clocks MMP2_CLK_TWSI0>;
                                resets = <&soc_clocks MMP2_CLK_TWSI0>;
 
                        twsi2: i2c@d4031000 {
                                compatible = "mrvl,mmp-twsi";
-                               reg = <0xd4031000 0x1000>;
+                               reg = <0xd4031000 0x70>;
                                interrupt-parent = <&twsi_mux>;
                                interrupts = <0>;
                                clocks = <&soc_clocks MMP2_CLK_TWSI1>;
 
                        twsi3: i2c@d4032000 {
                                compatible = "mrvl,mmp-twsi";
-                               reg = <0xd4032000 0x1000>;
+                               reg = <0xd4032000 0x70>;
                                interrupt-parent = <&twsi_mux>;
                                interrupts = <1>;
                                clocks = <&soc_clocks MMP2_CLK_TWSI2>;
 
                        twsi4: i2c@d4033000 {
                                compatible = "mrvl,mmp-twsi";
-                               reg = <0xd4033000 0x1000>;
+                               reg = <0xd4033000 0x70>;
                                interrupt-parent = <&twsi_mux>;
                                interrupts = <2>;
                                clocks = <&soc_clocks MMP2_CLK_TWSI3>;
 
                        twsi5: i2c@d4033800 {
                                compatible = "mrvl,mmp-twsi";
-                               reg = <0xd4033800 0x1000>;
+                               reg = <0xd4033800 0x70>;
                                interrupt-parent = <&twsi_mux>;
                                interrupts = <3>;
                                clocks = <&soc_clocks MMP2_CLK_TWSI4>;
 
                        twsi6: i2c@d4034000 {
                                compatible = "mrvl,mmp-twsi";
-                               reg = <0xd4034000 0x1000>;
+                               reg = <0xd4034000 0x70>;
                                interrupt-parent = <&twsi_mux>;
                                interrupts = <4>;
                                clocks = <&soc_clocks MMP2_CLK_TWSI5>;
index fb92850..d9be511 100644 (file)
                initial-mode = <1>; /* initialize in HUB mode */
                disabled-ports = <1>;
                intn-gpios = <&pio 7 5 GPIO_ACTIVE_HIGH>; /* PH5 */
-               reset-gpios = <&pio 4 16 GPIO_ACTIVE_HIGH>; /* PE16 */
+               reset-gpios = <&pio 4 16 GPIO_ACTIVE_LOW>; /* PE16 */
                connect-gpios = <&pio 4 17 GPIO_ACTIVE_HIGH>; /* PE17 */
                refclk-frequency = <19200000>;
        };
index cea1c27..46e478f 100644 (file)
@@ -226,8 +226,8 @@ void release_thread(struct task_struct *dead_task)
 asmlinkage void ret_from_fork(void) __asm__("ret_from_fork");
 
 int
-copy_thread(unsigned long clone_flags, unsigned long stack_start,
-           unsigned long stk_sz, struct task_struct *p)
+copy_thread_tls(unsigned long clone_flags, unsigned long stack_start,
+           unsigned long stk_sz, struct task_struct *p, unsigned long tls)
 {
        struct thread_info *thread = task_thread_info(p);
        struct pt_regs *childregs = task_pt_regs(p);
@@ -261,7 +261,7 @@ copy_thread(unsigned long clone_flags, unsigned long stack_start,
        clear_ptrace_hw_breakpoint(p);
 
        if (clone_flags & CLONE_SETTLS)
-               thread->tp_value[0] = childregs->ARM_r3;
+               thread->tp_value[0] = tls;
        thread->tp_value[1] = get_tpuser();
 
        thread_notify(THREAD_NOTIFY_COPY, thread);
index dd427bd..02b180a 100644 (file)
@@ -9,6 +9,7 @@ menuconfig ARCH_DAVINCI
        select PM_GENERIC_DOMAINS if PM
        select PM_GENERIC_DOMAINS_OF if PM && OF
        select REGMAP_MMIO
+       select RESET_CONTROLLER
        select HAVE_IDE
        select PINCTRL_SINGLE
 
index 110dcb3..c65cfc1 100644 (file)
@@ -207,7 +207,7 @@ static int __init mmp_dt_init_timer(struct device_node *np)
                ret = clk_prepare_enable(clk);
                if (ret)
                        return ret;
-               rate = clk_get_rate(clk) / 2;
+               rate = clk_get_rate(clk);
        } else if (cpu_is_pj4()) {
                rate = 6500000;
        } else {
index ad08d47..dca7d06 100644 (file)
@@ -95,6 +95,7 @@ config ARCH_OMAP2PLUS
        bool
        select ARCH_HAS_BANDGAP
        select ARCH_HAS_HOLES_MEMORYMODEL
+       select ARCH_HAS_RESET_CONTROLLER
        select ARCH_OMAP
        select CLKSRC_MMIO
        select GENERIC_IRQ_CHIP
@@ -105,11 +106,11 @@ config ARCH_OMAP2PLUS
        select OMAP_DM_TIMER
        select OMAP_GPMC
        select PINCTRL
+       select RESET_CONTROLLER
        select SOC_BUS
        select TI_SYSC
        select OMAP_IRQCHIP
        select CLKSRC_TI_32K
-       select ARCH_HAS_RESET_CONTROLLER
        help
          Systems based on OMAP2, OMAP3, OMAP4 or OMAP5
 
index ca52271..e95c224 100644 (file)
@@ -306,10 +306,14 @@ static void __init dra7x_evm_mmc_quirk(void)
 
 static struct clockdomain *ti_sysc_find_one_clockdomain(struct clk *clk)
 {
+       struct clk_hw *hw = __clk_get_hw(clk);
        struct clockdomain *clkdm = NULL;
        struct clk_hw_omap *hwclk;
 
-       hwclk = to_clk_hw_omap(__clk_get_hw(clk));
+       hwclk = to_clk_hw_omap(hw);
+       if (!omap2_clk_is_hw_omap(hw))
+               return NULL;
+
        if (hwclk && hwclk->clkdm_name)
                clkdm = clkdm_lookup(hwclk->clkdm_name);
 
index b1b4476..e688dfa 100644 (file)
@@ -138,6 +138,7 @@ config ARM64
        select HAVE_CMPXCHG_DOUBLE
        select HAVE_CMPXCHG_LOCAL
        select HAVE_CONTEXT_TRACKING
+       select HAVE_COPY_THREAD_TLS
        select HAVE_DEBUG_BUGVERBOSE
        select HAVE_DEBUG_KMEMLEAK
        select HAVE_DMA_CONTIGUOUS
index 96ab022..121e6cc 100644 (file)
@@ -15,7 +15,7 @@
        pinctrl-names = "default";
        pinctrl-0 = <&mmc2_pins>;
        vmmc-supply = <&reg_dcdc1>;
-       vqmmc-supply = <&reg_dcdc1>;
+       vqmmc-supply = <&reg_eldo1>;
        bus-width = <8>;
        non-removable;
        cap-mmc-hw-reset;
index 01a9a52..393c194 100644 (file)
 &mmc1 {
        pinctrl-names = "default";
        pinctrl-0 = <&mmc1_pins>;
-       vmmc-supply = <&reg_aldo2>;
+       vmmc-supply = <&reg_dcdc1>;
        vqmmc-supply = <&reg_dldo4>;
        mmc-pwrseq = <&wifi_pwrseq>;
        bus-width = <4>;
index 144a2c1..d1fc9c2 100644 (file)
 
        pmu {
                compatible = "arm,armv8-pmuv3";
-               interrupts = <0 120 8>,
-                            <0 121 8>,
-                            <0 122 8>,
-                            <0 123 8>;
+               interrupts = <0 170 4>,
+                            <0 171 4>,
+                            <0 172 4>,
+                            <0 173 4>;
                interrupt-affinity = <&cpu0>,
                                     <&cpu1>,
                                     <&cpu2>,
index 5bd0746..a8bb3fa 100644 (file)
        };
 
        gpio-keys {
-               compatible = "gpio-keys-polled";
-               poll-interval = <100>;
+               compatible = "gpio-keys";
 
                key1 {
                        label = "A";
                        linux,code = <BTN_0>;
                        gpios = <&gpio GPIOH_6 GPIO_ACTIVE_LOW>;
+                       interrupt-parent = <&gpio_intc>;
+                       interrupts = <34 IRQ_TYPE_EDGE_BOTH>;
                };
 
                key2 {
                        label = "B";
                        linux,code = <BTN_1>;
                        gpios = <&gpio GPIOH_7 GPIO_ACTIVE_LOW>;
+                       interrupt-parent = <&gpio_intc>;
+                       interrupts = <35 IRQ_TYPE_EDGE_BOTH>;
                };
 
                key3 {
                        label = "C";
                        linux,code = <BTN_2>;
                        gpios = <&gpio_ao GPIOAO_2 GPIO_ACTIVE_LOW>;
+                       interrupt-parent = <&gpio_intc>;
+                       interrupts = <2 IRQ_TYPE_EDGE_BOTH>;
+               };
+
+               mic_mute {
+                       label = "MicMute";
+                       linux,code = <SW_MUTE_DEVICE>;
+                       linux,input-type = <EV_SW>;
+                       gpios = <&gpio_ao GPIOE_2 GPIO_ACTIVE_LOW>;
+                       interrupt-parent = <&gpio_intc>;
+                       interrupts = <99 IRQ_TYPE_EDGE_BOTH>;
+               };
+
+               power_key {
+                       label = "PowerKey";
+                       linux,code = <KEY_POWER>;
+                       gpios = <&gpio_ao GPIOAO_3 GPIO_ACTIVE_LOW>;
+                       interrupt-parent = <&gpio_intc>;
+                       interrupts = <3 IRQ_TYPE_EDGE_BOTH>;
                };
        };
 
 
        bluetooth {
                compatible = "brcm,bcm43438-bt";
+               interrupt-parent = <&gpio_intc>;
+               interrupts = <95 IRQ_TYPE_LEVEL_HIGH>;
                shutdown-gpios = <&gpio GPIOX_17 GPIO_ACTIVE_HIGH>;
                max-speed = <2000000>;
                clocks = <&wifi32k>;
index 13a3cbe..a6f9b77 100644 (file)
                dcfg: syscon@1e00000 {
                        compatible = "fsl,ls1028a-dcfg", "syscon";
                        reg = <0x0 0x1e00000 0x0 0x10000>;
-                       big-endian;
+                       little-endian;
                };
 
                rst: syscon@1e60000 {
index 6edbdfe..3d95b66 100644 (file)
                                reg = <0x30bd0000 0x10000>;
                                interrupts = <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clk IMX8MM_CLK_SDMA1_ROOT>,
-                                        <&clk IMX8MM_CLK_SDMA1_ROOT>;
+                                        <&clk IMX8MM_CLK_AHB>;
                                clock-names = "ipg", "ahb";
                                #dma-cells = <3>;
                                fsl,sdma-ram-script-name = "imx/sdma/sdma-imx7d.bin";
index 2a759df..596bc65 100644 (file)
                pinctrl-names = "default";
                pinctrl-0 = <&pinctrl_imu>;
                interrupt-parent = <&gpio3>;
-               interrupts = <19 IRQ_TYPE_LEVEL_LOW>;
+               interrupts = <19 IRQ_TYPE_LEVEL_HIGH>;
                vdd-supply = <&reg_3v3_p>;
                vddio-supply = <&reg_3v3_p>;
        };
index 94090c6..d43e129 100644 (file)
 
        pmu {
                compatible = "arm,armv8-pmuv3";
-               interrupts = <0 120 8>,
-                            <0 121 8>,
-                            <0 122 8>,
-                            <0 123 8>;
+               interrupts = <0 170 4>,
+                            <0 171 4>,
+                            <0 172 4>,
+                            <0 173 4>;
                interrupt-affinity = <&cpu0>,
                                     <&cpu1>,
                                     <&cpu2>,
index 76b49f5..16f1656 100644 (file)
@@ -49,7 +49,8 @@
 
        ir-receiver {
                compatible = "gpio-ir-receiver";
-               gpios = <&gpio2 RK_PA2 GPIO_ACTIVE_HIGH>;
+               gpios = <&gpio2 RK_PA2 GPIO_ACTIVE_LOW>;
+               linux,rc-map-name = "rc-beelink-gs1";
        };
 };
 
index 2629a68..5af8258 100644 (file)
@@ -42,7 +42,6 @@
 #endif
 
 #define __ARCH_WANT_SYS_CLONE
-#define __ARCH_WANT_SYS_CLONE3
 
 #ifndef __COMPAT_SYSCALL_NR
 #include <uapi/asm/unistd.h>
index 4703d21..f83a70e 100644 (file)
@@ -19,5 +19,6 @@
 #define __ARCH_WANT_NEW_STAT
 #define __ARCH_WANT_SET_GET_RLIMIT
 #define __ARCH_WANT_TIME32_SYSCALLS
+#define __ARCH_WANT_SYS_CLONE3
 
 #include <asm-generic/unistd.h>
index 71f788c..d54586d 100644 (file)
@@ -360,8 +360,8 @@ int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src)
 
 asmlinkage void ret_from_fork(void) asm("ret_from_fork");
 
-int copy_thread(unsigned long clone_flags, unsigned long stack_start,
-               unsigned long stk_sz, struct task_struct *p)
+int copy_thread_tls(unsigned long clone_flags, unsigned long stack_start,
+               unsigned long stk_sz, struct task_struct *p, unsigned long tls)
 {
        struct pt_regs *childregs = task_pt_regs(p);
 
@@ -394,11 +394,11 @@ int copy_thread(unsigned long clone_flags, unsigned long stack_start,
                }
 
                /*
-                * If a TLS pointer was passed to clone (4th argument), use it
-                * for the new thread.
+                * If a TLS pointer was passed to clone, use it for the new
+                * thread.
                 */
                if (clone_flags & CLONE_SETTLS)
-                       p->thread.uw.tp_value = childregs->regs[3];
+                       p->thread.uw.tp_value = tls;
        } else {
                memset(childregs, 0, sizeof(struct pt_regs));
                childregs->pstate = PSR_MODE_EL1h;
index d9ac7e6..caddded 100644 (file)
@@ -9,7 +9,11 @@
 #define PG_dcache_dirty PG_arch_1
 
 void flush_icache_range(unsigned long start, unsigned long end);
+#define flush_icache_range flush_icache_range
+
 void flush_icache_page(struct vm_area_struct *vma, struct page *page);
+#define flush_icache_page flush_icache_page
+
 #ifdef CONFIG_CPU_CACHE_ALIASING
 void flush_cache_mm(struct mm_struct *mm);
 void flush_cache_dup_mm(struct mm_struct *mm);
@@ -40,12 +44,11 @@ void invalidate_kernel_vmap_range(void *addr, int size);
 #define flush_dcache_mmap_unlock(mapping) xa_unlock_irq(&(mapping)->i_pages)
 
 #else
-#include <asm-generic/cacheflush.h>
-#undef flush_icache_range
-#undef flush_icache_page
-#undef flush_icache_user_range
 void flush_icache_user_range(struct vm_area_struct *vma, struct page *page,
                             unsigned long addr, int len);
+#define flush_icache_user_range flush_icache_user_range
+
+#include <asm-generic/cacheflush.h>
 #endif
 
 #endif /* __NDS32_CACHEFLUSH_H__ */
index 0214e41..6abc58a 100644 (file)
@@ -195,7 +195,7 @@ extern void paging_init(void);
 #define pte_unmap(pte)         do { } while (0)
 #define pte_unmap_nested(pte)  do { } while (0)
 
-#define pmd_off_k(address)     pmd_offset(pgd_offset_k(address), address)
+#define pmd_off_k(address)     pmd_offset(pud_offset(p4d_offset(pgd_offset_k(address), (address)), (address)), (address))
 
 #define set_pte_at(mm,addr,ptep,pteval) set_pte(ptep,pteval)
 /*
index b16237c..0c29d6c 100644 (file)
@@ -62,6 +62,7 @@ config PARISC
        select HAVE_FTRACE_MCOUNT_RECORD if HAVE_DYNAMIC_FTRACE
        select HAVE_KPROBES_ON_FTRACE
        select HAVE_DYNAMIC_FTRACE_WITH_REGS
+       select HAVE_COPY_THREAD_TLS
 
        help
          The PA-RISC microprocessor is designed by Hewlett-Packard and used
index a6c9f49..a5f3e50 100644 (file)
@@ -889,8 +889,8 @@ static void print_parisc_device(struct parisc_device *dev)
        static int count;
 
        print_pa_hwpath(dev, hw_path);
-       pr_info("%d. %s at 0x%px [%s] { %d, 0x%x, 0x%.3x, 0x%.5x }",
-               ++count, dev->name, (void*) dev->hpa.start, hw_path, dev->id.hw_type,
+       pr_info("%d. %s at %pap [%s] { %d, 0x%x, 0x%.3x, 0x%.5x }",
+               ++count, dev->name, &(dev->hpa.start), hw_path, dev->id.hw_type,
                dev->id.hversion_rev, dev->id.hversion, dev->id.sversion);
 
        if (dev->num_addrs) {
index ecc5c27..230a642 100644 (file)
@@ -208,8 +208,8 @@ arch_initcall(parisc_idle_init);
  * Copy architecture-specific thread state
  */
 int
-copy_thread(unsigned long clone_flags, unsigned long usp,
-           unsigned long kthread_arg, struct task_struct *p)
+copy_thread_tls(unsigned long clone_flags, unsigned long usp,
+           unsigned long kthread_arg, struct task_struct *p, unsigned long tls)
 {
        struct pt_regs *cregs = &(p->thread.regs);
        void *stack = task_stack_page(p);
@@ -254,9 +254,9 @@ copy_thread(unsigned long clone_flags, unsigned long usp,
                cregs->ksp = (unsigned long)stack + THREAD_SZ_ALGN + FRAME_SIZE;
                cregs->kpc = (unsigned long) &child_return;
 
-               /* Setup thread TLS area from the 4th parameter in clone */
+               /* Setup thread TLS area */
                if (clone_flags & CLONE_SETTLS)
-                       cregs->cr27 = cregs->gr[23];
+                       cregs->cr27 = tls;
        }
 
        return 0;
index ddca828..354cf06 100644 (file)
@@ -401,7 +401,7 @@ static void __init map_pages(unsigned long start_vaddr,
                        pmd = (pmd_t *) __pa(pmd);
                }
 
-               pgd_populate(NULL, pg_dir, __va(pmd));
+               pud_populate(NULL, (pud_t *)pg_dir, __va(pmd));
 #endif
                pg_dir++;
 
index a31169b..fa7dc03 100644 (file)
@@ -65,6 +65,7 @@ config RISCV
        select ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT if MMU
        select HAVE_ARCH_MMAP_RND_BITS if MMU
        select ARCH_HAS_GCOV_PROFILE_ALL
+       select HAVE_COPY_THREAD_TLS
 
 config ARCH_MMAP_RND_BITS_MIN
        default 18 if 64BIT
diff --git a/arch/riscv/include/asm/sifive_l2_cache.h b/arch/riscv/include/asm/sifive_l2_cache.h
deleted file mode 100644 (file)
index 04f6748..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * SiFive L2 Cache Controller header file
- *
- */
-
-#ifndef _ASM_RISCV_SIFIVE_L2_CACHE_H
-#define _ASM_RISCV_SIFIVE_L2_CACHE_H
-
-extern int register_sifive_l2_error_notifier(struct notifier_block *nb);
-extern int unregister_sifive_l2_error_notifier(struct notifier_block *nb);
-
-#define SIFIVE_L2_ERR_TYPE_CE 0
-#define SIFIVE_L2_ERR_TYPE_UE 1
-
-#endif /* _ASM_RISCV_SIFIVE_L2_CACHE_H */
index 797802c..2227db6 100644 (file)
@@ -251,7 +251,7 @@ ENTRY(reset_regs)
 #ifdef CONFIG_FPU
        csrr    t0, CSR_MISA
        andi    t0, t0, (COMPAT_HWCAP_ISA_F | COMPAT_HWCAP_ISA_D)
-       bnez    t0, .Lreset_regs_done
+       beqz    t0, .Lreset_regs_done
 
        li      t1, SR_FS
        csrs    CSR_STATUS, t1
index 95a3031..817cf7b 100644 (file)
@@ -99,8 +99,8 @@ int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src)
        return 0;
 }
 
-int copy_thread(unsigned long clone_flags, unsigned long usp,
-       unsigned long arg, struct task_struct *p)
+int copy_thread_tls(unsigned long clone_flags, unsigned long usp,
+       unsigned long arg, struct task_struct *p, unsigned long tls)
 {
        struct pt_regs *childregs = task_pt_regs(p);
 
@@ -121,7 +121,7 @@ int copy_thread(unsigned long clone_flags, unsigned long usp,
                if (usp) /* User fork */
                        childregs->sp = usp;
                if (clone_flags & CLONE_SETTLS)
-                       childregs->tp = childregs->a5;
+                       childregs->tp = tls;
                childregs->a0 = 0; /* Return value of fork() */
                p->thread.ra = (unsigned long)ret_from_fork;
        }
index 9cbf490..d5fbd75 100644 (file)
@@ -1052,7 +1052,7 @@ static void __init log_component_list(void)
 
        if (!early_ipl_comp_list_addr)
                return;
-       if (ipl_block.hdr.flags & IPL_PL_FLAG_IPLSR)
+       if (ipl_block.hdr.flags & IPL_PL_FLAG_SIPL)
                pr_info("Linux is running with Secure-IPL enabled\n");
        else
                pr_info("Linux is running with Secure-IPL disabled\n");
index 2a6d04f..6f0edd0 100644 (file)
@@ -14,6 +14,7 @@ config UML
        select HAVE_FUTEX_CMPXCHG if FUTEX
        select HAVE_DEBUG_KMEMLEAK
        select HAVE_DEBUG_BUGVERBOSE
+       select HAVE_COPY_THREAD_TLS
        select GENERIC_IRQ_SHOW
        select GENERIC_CPU_DEVICES
        select GENERIC_CLOCKEVENTS
index 81c647e..adf91ef 100644 (file)
@@ -36,7 +36,7 @@ extern long subarch_ptrace(struct task_struct *child, long request,
 extern unsigned long getreg(struct task_struct *child, int regno);
 extern int putreg(struct task_struct *child, int regno, unsigned long value);
 
-extern int arch_copy_tls(struct task_struct *new);
+extern int arch_set_tls(struct task_struct *new, unsigned long tls);
 extern void clear_flushed_tls(struct task_struct *task);
 extern int syscall_trace_enter(struct pt_regs *regs);
 extern void syscall_trace_leave(struct pt_regs *regs);
index 263a8f0..17045e7 100644 (file)
@@ -153,8 +153,8 @@ void fork_handler(void)
        userspace(&current->thread.regs.regs, current_thread_info()->aux_fp_regs);
 }
 
-int copy_thread(unsigned long clone_flags, unsigned long sp,
-               unsigned long arg, struct task_struct * p)
+int copy_thread_tls(unsigned long clone_flags, unsigned long sp,
+               unsigned long arg, struct task_struct * p, unsigned long tls)
 {
        void (*handler)(void);
        int kthread = current->flags & PF_KTHREAD;
@@ -188,7 +188,7 @@ int copy_thread(unsigned long clone_flags, unsigned long sp,
                 * Set a new TLS for the child thread?
                 */
                if (clone_flags & CLONE_SETTLS)
-                       ret = arch_copy_tls(p);
+                       ret = arch_set_tls(p, tls);
        }
 
        return ret;
index 58a512e..ee60b81 100644 (file)
@@ -244,6 +244,11 @@ SYM_FUNC_START(efi32_stub_entry)
        leal    efi32_config(%ebp), %eax
        movl    %eax, efi_config(%ebp)
 
+       /* Disable paging */
+       movl    %cr0, %eax
+       btrl    $X86_CR0_PG_BIT, %eax
+       movl    %eax, %cr0
+
        jmp     startup_32
 SYM_FUNC_END(efi32_stub_entry)
 #endif
index dbaa1b0..c37cb12 100644 (file)
@@ -15,6 +15,7 @@
 #define PCI_DEVICE_ID_INTEL_SKL_HQ_IMC         0x1910
 #define PCI_DEVICE_ID_INTEL_SKL_SD_IMC         0x190f
 #define PCI_DEVICE_ID_INTEL_SKL_SQ_IMC         0x191f
+#define PCI_DEVICE_ID_INTEL_SKL_E3_IMC         0x1918
 #define PCI_DEVICE_ID_INTEL_KBL_Y_IMC          0x590c
 #define PCI_DEVICE_ID_INTEL_KBL_U_IMC          0x5904
 #define PCI_DEVICE_ID_INTEL_KBL_UQ_IMC         0x5914
@@ -657,6 +658,10 @@ static const struct pci_device_id skl_uncore_pci_ids[] = {
                PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_SKL_SQ_IMC),
                .driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0),
        },
+       { /* IMC */
+               PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_SKL_E3_IMC),
+               .driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0),
+       },
        { /* IMC */
                PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_KBL_Y_IMC),
                .driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0),
@@ -826,6 +831,7 @@ static const struct imc_uncore_pci_dev desktop_imc_pci_ids[] = {
        IMC_DEV(SKL_HQ_IMC, &skl_uncore_pci_driver),  /* 6th Gen Core H Quad Core */
        IMC_DEV(SKL_SD_IMC, &skl_uncore_pci_driver),  /* 6th Gen Core S Dual Core */
        IMC_DEV(SKL_SQ_IMC, &skl_uncore_pci_driver),  /* 6th Gen Core S Quad Core */
+       IMC_DEV(SKL_E3_IMC, &skl_uncore_pci_driver),  /* Xeon E3 V5 Gen Core processor */
        IMC_DEV(KBL_Y_IMC, &skl_uncore_pci_driver),  /* 7th Gen Core Y */
        IMC_DEV(KBL_U_IMC, &skl_uncore_pci_driver),  /* 7th Gen Core U */
        IMC_DEV(KBL_UQ_IMC, &skl_uncore_pci_driver),  /* 7th Gen Core U Quad Core */
index b10a5ec..ad20220 100644 (file)
 #define SNR_M2M_PCI_PMON_BOX_CTL               0x438
 #define SNR_M2M_PCI_PMON_UMASK_EXT             0xff
 
-/* SNR PCIE3 */
-#define SNR_PCIE3_PCI_PMON_CTL0                        0x508
-#define SNR_PCIE3_PCI_PMON_CTR0                        0x4e8
-#define SNR_PCIE3_PCI_PMON_BOX_CTL             0x4e4
-
 /* SNR IMC */
 #define SNR_IMC_MMIO_PMON_FIXED_CTL            0x54
 #define SNR_IMC_MMIO_PMON_FIXED_CTR            0x38
@@ -4328,27 +4323,12 @@ static struct intel_uncore_type snr_uncore_m2m = {
        .format_group   = &snr_m2m_uncore_format_group,
 };
 
-static struct intel_uncore_type snr_uncore_pcie3 = {
-       .name           = "pcie3",
-       .num_counters   = 4,
-       .num_boxes      = 1,
-       .perf_ctr_bits  = 48,
-       .perf_ctr       = SNR_PCIE3_PCI_PMON_CTR0,
-       .event_ctl      = SNR_PCIE3_PCI_PMON_CTL0,
-       .event_mask     = SNBEP_PMON_RAW_EVENT_MASK,
-       .box_ctl        = SNR_PCIE3_PCI_PMON_BOX_CTL,
-       .ops            = &ivbep_uncore_pci_ops,
-       .format_group   = &ivbep_uncore_format_group,
-};
-
 enum {
        SNR_PCI_UNCORE_M2M,
-       SNR_PCI_UNCORE_PCIE3,
 };
 
 static struct intel_uncore_type *snr_pci_uncores[] = {
        [SNR_PCI_UNCORE_M2M]            = &snr_uncore_m2m,
-       [SNR_PCI_UNCORE_PCIE3]          = &snr_uncore_pcie3,
        NULL,
 };
 
@@ -4357,10 +4337,6 @@ static const struct pci_device_id snr_uncore_pci_ids[] = {
                PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x344a),
                .driver_data = UNCORE_PCI_DEV_FULL_DATA(12, 0, SNR_PCI_UNCORE_M2M, 0),
        },
-       { /* PCIe3 */
-               PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x334a),
-               .driver_data = UNCORE_PCI_DEV_FULL_DATA(4, 0, SNR_PCI_UNCORE_PCIE3, 0),
-       },
        { /* end: all zeroes */ }
 };
 
@@ -4536,6 +4512,7 @@ static struct uncore_event_desc snr_uncore_imc_freerunning_events[] = {
        INTEL_UNCORE_EVENT_DESC(write,          "event=0xff,umask=0x21"),
        INTEL_UNCORE_EVENT_DESC(write.scale,    "3.814697266e-6"),
        INTEL_UNCORE_EVENT_DESC(write.unit,     "MiB"),
+       { /* end: all zeroes */ },
 };
 
 static struct intel_uncore_ops snr_uncore_imc_freerunning_ops = {
index 90f75e5..62c3027 100644 (file)
@@ -615,9 +615,9 @@ static void early_detect_mem_encrypt(struct cpuinfo_x86 *c)
                return;
 
 clear_all:
-               clear_cpu_cap(c, X86_FEATURE_SME);
+               setup_clear_cpu_cap(X86_FEATURE_SME);
 clear_sev:
-               clear_cpu_cap(c, X86_FEATURE_SEV);
+               setup_clear_cpu_cap(X86_FEATURE_SEV);
        }
 }
 
index b38010b..6c3e1c9 100644 (file)
@@ -467,6 +467,7 @@ static int thermal_throttle_online(unsigned int cpu)
 {
        struct thermal_state *state = &per_cpu(thermal_state, cpu);
        struct device *dev = get_cpu_device(cpu);
+       u32 l;
 
        state->package_throttle.level = PACKAGE_LEVEL;
        state->core_throttle.level = CORE_LEVEL;
@@ -474,6 +475,10 @@ static int thermal_throttle_online(unsigned int cpu)
        INIT_DELAYED_WORK(&state->package_throttle.therm_work, throttle_active_work);
        INIT_DELAYED_WORK(&state->core_throttle.therm_work, throttle_active_work);
 
+       /* Unmask the thermal vector after the above workqueues are initialized. */
+       l = apic_read(APIC_LVTTHMR);
+       apic_write(APIC_LVTTHMR, l & ~APIC_LVT_MASKED);
+
        return thermal_throttle_add_dev(dev, cpu);
 }
 
@@ -722,10 +727,6 @@ void intel_init_thermal(struct cpuinfo_x86 *c)
        rdmsr(MSR_IA32_MISC_ENABLE, l, h);
        wrmsr(MSR_IA32_MISC_ENABLE, l | MSR_IA32_MISC_ENABLE_TM1, h);
 
-       /* Unmask the thermal vector: */
-       l = apic_read(APIC_LVTTHMR);
-       apic_write(APIC_LVTTHMR, l & ~APIC_LVT_MASKED);
-
        pr_info_once("CPU0: Thermal monitoring enabled (%s)\n",
                      tm2 ? "TM2" : "TM1");
 
index 03eb90d..89049b3 100644 (file)
@@ -618,7 +618,7 @@ static void domain_remove_cpu(int cpu, struct rdt_resource *r)
                if (static_branch_unlikely(&rdt_mon_enable_key))
                        rmdir_mondata_subdir_allrdtgrp(r, d->id);
                list_del(&d->list);
-               if (is_mbm_enabled())
+               if (r->mon_capable && is_mbm_enabled())
                        cancel_delayed_work(&d->mbm_over);
                if (is_llc_occupancy_enabled() &&  has_busy_rmid(r, d)) {
                        /*
index 2e3b06d..dac7209 100644 (file)
@@ -1741,9 +1741,6 @@ static int set_cache_qos_cfg(int level, bool enable)
        struct rdt_domain *d;
        int cpu;
 
-       if (!zalloc_cpumask_var(&cpu_mask, GFP_KERNEL))
-               return -ENOMEM;
-
        if (level == RDT_RESOURCE_L3)
                update = l3_qos_cfg_update;
        else if (level == RDT_RESOURCE_L2)
@@ -1751,6 +1748,9 @@ static int set_cache_qos_cfg(int level, bool enable)
        else
                return -EINVAL;
 
+       if (!zalloc_cpumask_var(&cpu_mask, GFP_KERNEL))
+               return -ENOMEM;
+
        r_l = &rdt_resources_all[level];
        list_for_each_entry(d, &r_l->domains, list) {
                /* Pick one CPU from each domain instance to update MSR */
index 5bd949d..ac8eee0 100644 (file)
@@ -215,14 +215,12 @@ static int set_tls_entry(struct task_struct* task, struct user_desc *info,
        return 0;
 }
 
-int arch_copy_tls(struct task_struct *new)
+int arch_set_tls(struct task_struct *new, unsigned long tls)
 {
        struct user_desc info;
        int idx, ret = -EFAULT;
 
-       if (copy_from_user(&info,
-                          (void __user *) UPT_SI(&new->thread.regs.regs),
-                          sizeof(info)))
+       if (copy_from_user(&info, (void __user *) tls, sizeof(info)))
                goto out;
 
        ret = -EINVAL;
index 3a621e0..ebd3855 100644 (file)
@@ -6,14 +6,13 @@ void clear_flushed_tls(struct task_struct *task)
 {
 }
 
-int arch_copy_tls(struct task_struct *t)
+int arch_set_tls(struct task_struct *t, unsigned long tls)
 {
        /*
         * If CLONE_SETTLS is set, we need to save the thread id
-        * (which is argument 5, child_tid, of clone) so it can be set
-        * during context switches.
+        * so it can be set during context switches.
         */
-       t->thread.arch.fs = t->thread.regs.regs.gp[R8 / sizeof(long)];
+       t->thread.arch.fs = tls;
 
        return 0;
 }
index 4a3fa29..296c532 100644 (file)
@@ -24,6 +24,7 @@ config XTENSA
        select HAVE_ARCH_JUMP_LABEL if !XIP_KERNEL
        select HAVE_ARCH_KASAN if MMU && !XIP_KERNEL
        select HAVE_ARCH_TRACEHOOK
+       select HAVE_COPY_THREAD_TLS
        select HAVE_DEBUG_KMEMLEAK
        select HAVE_DMA_CONTIGUOUS
        select HAVE_EXIT_THREAD
index 9e1c491..3edecc4 100644 (file)
@@ -202,8 +202,9 @@ int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src)
  * involved.  Much simpler to just not copy those live frames across.
  */
 
-int copy_thread(unsigned long clone_flags, unsigned long usp_thread_fn,
-               unsigned long thread_fn_arg, struct task_struct *p)
+int copy_thread_tls(unsigned long clone_flags, unsigned long usp_thread_fn,
+               unsigned long thread_fn_arg, struct task_struct *p,
+               unsigned long tls)
 {
        struct pt_regs *childregs = task_pt_regs(p);
 
@@ -266,9 +267,8 @@ int copy_thread(unsigned long clone_flags, unsigned long usp_thread_fn,
 
                childregs->syscall = regs->syscall;
 
-               /* The thread pointer is passed in the '4th argument' (= a5) */
                if (clone_flags & CLONE_SETTLS)
-                       childregs->threadptr = childregs->areg[5];
+                       childregs->threadptr = tls;
        } else {
                p->thread.ra = MAKE_RA_FOR_CALL(
                                (unsigned long)ret_from_kernel_thread, 1);
index 006bcc5..94d6972 100644 (file)
@@ -538,6 +538,16 @@ void zero_fill_bio_iter(struct bio *bio, struct bvec_iter start)
 }
 EXPORT_SYMBOL(zero_fill_bio_iter);
 
+/**
+ * bio_truncate - truncate the bio to small size of @new_size
+ * @bio:       the bio to be truncated
+ * @new_size:  new size for truncating the bio
+ *
+ * Description:
+ *   Truncate the bio to new size of @new_size. If bio_op(bio) is
+ *   REQ_OP_READ, zero the truncated part. This function should only
+ *   be used for handling corner cases, such as bio eod.
+ */
 void bio_truncate(struct bio *bio, unsigned new_size)
 {
        struct bio_vec bv;
@@ -548,7 +558,7 @@ void bio_truncate(struct bio *bio, unsigned new_size)
        if (new_size >= bio->bi_iter.bi_size)
                return;
 
-       if (bio_data_dir(bio) != READ)
+       if (bio_op(bio) != REQ_OP_READ)
                goto exit;
 
        bio_for_each_segment(bv, bio, iter) {
index 347782a..1534ed7 100644 (file)
@@ -164,8 +164,13 @@ static inline unsigned get_max_segment_size(const struct request_queue *q,
        unsigned long mask = queue_segment_boundary(q);
 
        offset = mask & (page_to_phys(start_page) + offset);
-       return min_t(unsigned long, mask - offset + 1,
-                    queue_max_segment_size(q));
+
+       /*
+        * overflow may be triggered in case of zero page physical address
+        * on 32bit arch, use queue's max segment size when that happens.
+        */
+       return min_not_zero(mask - offset + 1,
+                       (unsigned long)queue_max_segment_size(q));
 }
 
 /**
index 5f6dcc7..c8eda2e 100644 (file)
@@ -328,7 +328,7 @@ EXPORT_SYMBOL(blk_queue_max_segment_size);
  *   storage device can address.  The default of 512 covers most
  *   hardware.
  **/
-void blk_queue_logical_block_size(struct request_queue *q, unsigned short size)
+void blk_queue_logical_block_size(struct request_queue *q, unsigned int size)
 {
        q->limits.logical_block_size = size;
 
index 4a66888..5fa7ce3 100644 (file)
@@ -17,7 +17,7 @@ PROGBITS  = $(if $(CONFIG_ARM),%,@)progbits
 filechk_fwbin = \
        echo "/* Generated by $(src)/Makefile */"               ;\
        echo "    .section .rodata"                             ;\
-       echo "    .p2align $(ASM_ALIGN)"                        ;\
+       echo "    .p2align 4"                                   ;\
        echo "_fw_$(FWSTR)_bin:"                                ;\
        echo "    .incbin \"$(fwdir)/$(FWNAME)\""               ;\
        echo "_fw_end:"                                         ;\
index 5cf49d9..ed34785 100644 (file)
@@ -129,11 +129,13 @@ static blk_status_t null_zone_write(struct nullb_cmd *cmd, sector_t sector,
                return BLK_STS_IOERR;
        case BLK_ZONE_COND_EMPTY:
        case BLK_ZONE_COND_IMP_OPEN:
+       case BLK_ZONE_COND_EXP_OPEN:
+       case BLK_ZONE_COND_CLOSED:
                /* Writes must be at the write pointer position */
                if (sector != zone->wp)
                        return BLK_STS_IOERR;
 
-               if (zone->cond == BLK_ZONE_COND_EMPTY)
+               if (zone->cond != BLK_ZONE_COND_EXP_OPEN)
                        zone->cond = BLK_ZONE_COND_IMP_OPEN;
 
                zone->wp += nr_sectors;
index f4d1597..ccb44fe 100644 (file)
@@ -343,6 +343,12 @@ static int sysc_get_clocks(struct sysc *ddata)
                return -EINVAL;
        }
 
+       /* Always add a slot for main clocks fck and ick even if unused */
+       if (!nr_fck)
+               ddata->nr_clocks++;
+       if (!nr_ick)
+               ddata->nr_clocks++;
+
        ddata->clocks = devm_kcalloc(ddata->dev,
                                     ddata->nr_clocks, sizeof(*ddata->clocks),
                                     GFP_KERNEL);
@@ -421,7 +427,7 @@ static int sysc_enable_opt_clocks(struct sysc *ddata)
        struct clk *clock;
        int i, error;
 
-       if (!ddata->clocks)
+       if (!ddata->clocks || ddata->nr_clocks < SYSC_OPTFCK0 + 1)
                return 0;
 
        for (i = SYSC_OPTFCK0; i < SYSC_MAX_CLOCKS; i++) {
@@ -455,7 +461,7 @@ static void sysc_disable_opt_clocks(struct sysc *ddata)
        struct clk *clock;
        int i;
 
-       if (!ddata->clocks)
+       if (!ddata->clocks || ddata->nr_clocks < SYSC_OPTFCK0 + 1)
                return;
 
        for (i = SYSC_OPTFCK0; i < SYSC_MAX_CLOCKS; i++) {
index 6a11239..772258d 100644 (file)
@@ -3426,11 +3426,17 @@ static int __clk_core_init(struct clk_core *core)
        if (core->flags & CLK_IS_CRITICAL) {
                unsigned long flags;
 
-               clk_core_prepare(core);
+               ret = clk_core_prepare(core);
+               if (ret)
+                       goto out;
 
                flags = clk_enable_lock();
-               clk_core_enable(core);
+               ret = clk_core_enable(core);
                clk_enable_unlock(flags);
+               if (ret) {
+                       clk_core_unprepare(core);
+                       goto out;
+               }
        }
 
        clk_core_reparent_orphans_nolock();
index a60a1be..b4a95cb 100644 (file)
@@ -134,7 +134,7 @@ static DEFINE_SPINLOCK(ssp3_lock);
 static const char *ssp_parent_names[] = {"vctcxo_4", "vctcxo_2", "vctcxo", "pll1_16"};
 
 static DEFINE_SPINLOCK(timer_lock);
-static const char *timer_parent_names[] = {"clk32", "vctcxo_2", "vctcxo_4", "vctcxo"};
+static const char *timer_parent_names[] = {"clk32", "vctcxo_4", "vctcxo_2", "vctcxo"};
 
 static DEFINE_SPINLOCK(reset_lock);
 
index f7b370f..f6ce888 100644 (file)
@@ -3255,6 +3255,7 @@ static struct gdsc hlos1_vote_aggre_noc_mmu_audio_tbu_gdsc = {
                .name = "hlos1_vote_aggre_noc_mmu_audio_tbu_gdsc",
        },
        .pwrsts = PWRSTS_OFF_ON,
+       .flags = VOTABLE,
 };
 
 static struct gdsc hlos1_vote_aggre_noc_mmu_pcie_tbu_gdsc = {
@@ -3263,6 +3264,7 @@ static struct gdsc hlos1_vote_aggre_noc_mmu_pcie_tbu_gdsc = {
                .name = "hlos1_vote_aggre_noc_mmu_pcie_tbu_gdsc",
        },
        .pwrsts = PWRSTS_OFF_ON,
+       .flags = VOTABLE,
 };
 
 static struct gdsc hlos1_vote_aggre_noc_mmu_tbu1_gdsc = {
@@ -3271,6 +3273,7 @@ static struct gdsc hlos1_vote_aggre_noc_mmu_tbu1_gdsc = {
                .name = "hlos1_vote_aggre_noc_mmu_tbu1_gdsc",
        },
        .pwrsts = PWRSTS_OFF_ON,
+       .flags = VOTABLE,
 };
 
 static struct gdsc hlos1_vote_aggre_noc_mmu_tbu2_gdsc = {
@@ -3279,6 +3282,7 @@ static struct gdsc hlos1_vote_aggre_noc_mmu_tbu2_gdsc = {
                .name = "hlos1_vote_aggre_noc_mmu_tbu2_gdsc",
        },
        .pwrsts = PWRSTS_OFF_ON,
+       .flags = VOTABLE,
 };
 
 static struct gdsc hlos1_vote_mmnoc_mmu_tbu_hf0_gdsc = {
@@ -3287,6 +3291,7 @@ static struct gdsc hlos1_vote_mmnoc_mmu_tbu_hf0_gdsc = {
                .name = "hlos1_vote_mmnoc_mmu_tbu_hf0_gdsc",
        },
        .pwrsts = PWRSTS_OFF_ON,
+       .flags = VOTABLE,
 };
 
 static struct gdsc hlos1_vote_mmnoc_mmu_tbu_hf1_gdsc = {
@@ -3295,6 +3300,7 @@ static struct gdsc hlos1_vote_mmnoc_mmu_tbu_hf1_gdsc = {
                .name = "hlos1_vote_mmnoc_mmu_tbu_hf1_gdsc",
        },
        .pwrsts = PWRSTS_OFF_ON,
+       .flags = VOTABLE,
 };
 
 static struct gdsc hlos1_vote_mmnoc_mmu_tbu_sf_gdsc = {
@@ -3303,6 +3309,7 @@ static struct gdsc hlos1_vote_mmnoc_mmu_tbu_sf_gdsc = {
                .name = "hlos1_vote_mmnoc_mmu_tbu_sf_gdsc",
        },
        .pwrsts = PWRSTS_OFF_ON,
+       .flags = VOTABLE,
 };
 
 static struct clk_regmap *gcc_sdm845_clocks[] = {
index 3a991ca..c9e5a1f 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/clk-provider.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
+#include <linux/clk.h>
 
 #include "clk.h"
 #include "clk-cpu.h"
@@ -1646,6 +1647,13 @@ static void __init exynos5x_clk_init(struct device_node *np,
                                     exynos5x_subcmus);
        }
 
+       /*
+        * Keep top part of G3D clock path enabled permanently to ensure
+        * that the internal busses get their clock regardless of the
+        * main G3D clock enablement status.
+        */
+       clk_prepare_enable(__clk_lookup("mout_sw_aclk_g3d"));
+
        samsung_clk_of_add_provider(np, ctx);
 }
 
index 45a1ed3..50f8d1b 100644 (file)
@@ -23,9 +23,9 @@
  */
 
 static const char * const ar100_r_apb2_parents[] = { "osc24M", "osc32k",
-                                            "pll-periph0", "iosc" };
+                                                    "iosc", "pll-periph0" };
 static const struct ccu_mux_var_prediv ar100_r_apb2_predivs[] = {
-       { .index = 2, .shift = 0, .width = 5 },
+       { .index = 3, .shift = 0, .width = 5 },
 };
 
 static struct ccu_div ar100_clk = {
@@ -51,17 +51,7 @@ static struct ccu_div ar100_clk = {
 
 static CLK_FIXED_FACTOR_HW(r_ahb_clk, "r-ahb", &ar100_clk.common.hw, 1, 1, 0);
 
-static struct ccu_div r_apb1_clk = {
-       .div            = _SUNXI_CCU_DIV(0, 2),
-
-       .common         = {
-               .reg            = 0x00c,
-               .hw.init        = CLK_HW_INIT("r-apb1",
-                                             "r-ahb",
-                                             &ccu_div_ops,
-                                             0),
-       },
-};
+static SUNXI_CCU_M(r_apb1_clk, "r-apb1", "r-ahb", 0x00c, 0, 2, 0);
 
 static struct ccu_div r_apb2_clk = {
        .div            = _SUNXI_CCU_DIV_FLAGS(8, 2, CLK_DIVIDER_POWER_OF_TWO),
index 4646fdc..4c8c491 100644 (file)
@@ -51,19 +51,7 @@ static struct ccu_div ar100_clk = {
 
 static CLK_FIXED_FACTOR_HW(ahb0_clk, "ahb0", &ar100_clk.common.hw, 1, 1, 0);
 
-static struct ccu_div apb0_clk = {
-       .div            = _SUNXI_CCU_DIV_FLAGS(0, 2, CLK_DIVIDER_POWER_OF_TWO),
-
-       .common         = {
-               .reg            = 0x0c,
-               .hw.init        = CLK_HW_INIT_HW("apb0",
-                                                &ahb0_clk.hw,
-                                                &ccu_div_ops,
-                                                0),
-       },
-};
-
-static SUNXI_CCU_M(a83t_apb0_clk, "apb0", "ahb0", 0x0c, 0, 2, 0);
+static SUNXI_CCU_M(apb0_clk, "apb0", "ahb0", 0x0c, 0, 2, 0);
 
 /*
  * Define the parent as an array that can be reused to save space
@@ -127,7 +115,7 @@ static struct ccu_mp a83t_ir_clk = {
 
 static struct ccu_common *sun8i_a83t_r_ccu_clks[] = {
        &ar100_clk.common,
-       &a83t_apb0_clk.common,
+       &apb0_clk.common,
        &apb0_pio_clk.common,
        &apb0_ir_clk.common,
        &apb0_timer_clk.common,
@@ -167,7 +155,7 @@ static struct clk_hw_onecell_data sun8i_a83t_r_hw_clks = {
        .hws    = {
                [CLK_AR100]             = &ar100_clk.common.hw,
                [CLK_AHB0]              = &ahb0_clk.hw,
-               [CLK_APB0]              = &a83t_apb0_clk.common.hw,
+               [CLK_APB0]              = &apb0_clk.common.hw,
                [CLK_APB0_PIO]          = &apb0_pio_clk.common.hw,
                [CLK_APB0_IR]           = &apb0_ir_clk.common.hw,
                [CLK_APB0_TIMER]        = &apb0_timer_clk.common.hw,
@@ -282,9 +270,6 @@ static void __init sunxi_r_ccu_init(struct device_node *node,
 
 static void __init sun8i_a83t_r_ccu_setup(struct device_node *node)
 {
-       /* Fix apb0 bus gate parents here */
-       apb0_gate_parent[0] = &a83t_apb0_clk.common.hw;
-
        sunxi_r_ccu_init(node, &sun8i_a83t_r_ccu_desc);
 }
 CLK_OF_DECLARE(sun8i_a83t_r_ccu, "allwinner,sun8i-a83t-r-ccu",
index 8974908..23bfe1d 100644 (file)
@@ -761,7 +761,8 @@ static struct ccu_mp outa_clk = {
                .reg            = 0x1f0,
                .features       = CCU_FEATURE_FIXED_PREDIV,
                .hw.init        = CLK_HW_INIT_PARENTS("outa", out_parents,
-                                                     &ccu_mp_ops, 0),
+                                                     &ccu_mp_ops,
+                                                     CLK_SET_RATE_PARENT),
        }
 };
 
@@ -779,7 +780,8 @@ static struct ccu_mp outb_clk = {
                .reg            = 0x1f4,
                .features       = CCU_FEATURE_FIXED_PREDIV,
                .hw.init        = CLK_HW_INIT_PARENTS("outb", out_parents,
-                                                     &ccu_mp_ops, 0),
+                                                     &ccu_mp_ops,
+                                                     CLK_SET_RATE_PARENT),
        }
 };
 
index 5c779ee..0e36ca3 100644 (file)
@@ -618,7 +618,7 @@ static struct clk_hw_onecell_data sun8i_v3s_hw_clks = {
                [CLK_MBUS]              = &mbus_clk.common.hw,
                [CLK_MIPI_CSI]          = &mipi_csi_clk.common.hw,
        },
-       .num    = CLK_NUMBER,
+       .num    = CLK_PLL_DDR1 + 1,
 };
 
 static struct clk_hw_onecell_data sun8i_v3_hw_clks = {
@@ -700,7 +700,7 @@ static struct clk_hw_onecell_data sun8i_v3_hw_clks = {
                [CLK_MBUS]              = &mbus_clk.common.hw,
                [CLK_MIPI_CSI]          = &mipi_csi_clk.common.hw,
        },
-       .num    = CLK_NUMBER,
+       .num    = CLK_I2S0 + 1,
 };
 
 static struct ccu_reset_map sun8i_v3s_ccu_resets[] = {
index b0160d3..108eeee 100644 (file)
@@ -51,6 +51,4 @@
 
 #define CLK_PLL_DDR1           74
 
-#define CLK_NUMBER             (CLK_I2S0 + 1)
-
 #endif /* _CCU_SUN8I_H3_H_ */
index e6bd6d1..f6cdce4 100644 (file)
@@ -231,8 +231,10 @@ struct clk ** __init tegra_clk_init(void __iomem *regs, int num, int banks)
        periph_banks = banks;
 
        clks = kcalloc(num, sizeof(struct clk *), GFP_KERNEL);
-       if (!clks)
+       if (!clks) {
                kfree(periph_clk_enb_refcnt);
+               return NULL;
+       }
 
        clk_num = num;
 
index f65e16c..8d4c08b 100644 (file)
@@ -233,7 +233,6 @@ static int of_dra7_atl_clk_probe(struct platform_device *pdev)
        cinfo->iobase = of_iomap(node, 0);
        cinfo->dev = &pdev->dev;
        pm_runtime_enable(cinfo->dev);
-       pm_runtime_irq_safe(cinfo->dev);
 
        pm_runtime_get_sync(cinfo->dev);
        atl_write(cinfo, DRA7_ATL_PCLKMUX_REG(0), DRA7_ATL_PCLKMUX);
index f1d170d..aba591d 100644 (file)
@@ -121,6 +121,8 @@ static const struct of_device_id blacklist[] __initconst = {
        { .compatible = "mediatek,mt8176", },
        { .compatible = "mediatek,mt8183", },
 
+       { .compatible = "nvidia,tegra20", },
+       { .compatible = "nvidia,tegra30", },
        { .compatible = "nvidia,tegra124", },
        { .compatible = "nvidia,tegra210", },
 
index de7e706..6deaaf5 100644 (file)
@@ -198,7 +198,7 @@ static void teo_update(struct cpuidle_driver *drv, struct cpuidle_device *dev)
         * pattern detection.
         */
        cpu_data->intervals[cpu_data->interval_idx++] = measured_ns;
-       if (cpu_data->interval_idx > INTERVALS)
+       if (cpu_data->interval_idx >= INTERVALS)
                cpu_data->interval_idx = 0;
 }
 
index 26754d0..b846d73 100644 (file)
@@ -40,7 +40,7 @@ struct sec_req {
        int req_id;
 
        /* Status of the SEC request */
-       int fake_busy;
+       atomic_t fake_busy;
 };
 
 /**
@@ -132,8 +132,8 @@ struct sec_debug_file {
 };
 
 struct sec_dfx {
-       u64 send_cnt;
-       u64 recv_cnt;
+       atomic64_t send_cnt;
+       atomic64_t recv_cnt;
 };
 
 struct sec_debug {
index 62b04e1..0a5391f 100644 (file)
@@ -120,7 +120,7 @@ static void sec_req_cb(struct hisi_qp *qp, void *resp)
                return;
        }
 
-       __sync_add_and_fetch(&req->ctx->sec->debug.dfx.recv_cnt, 1);
+       atomic64_inc(&req->ctx->sec->debug.dfx.recv_cnt);
 
        req->ctx->req_op->buf_unmap(req->ctx, req);
 
@@ -135,13 +135,13 @@ static int sec_bd_send(struct sec_ctx *ctx, struct sec_req *req)
        mutex_lock(&qp_ctx->req_lock);
        ret = hisi_qp_send(qp_ctx->qp, &req->sec_sqe);
        mutex_unlock(&qp_ctx->req_lock);
-       __sync_add_and_fetch(&ctx->sec->debug.dfx.send_cnt, 1);
+       atomic64_inc(&ctx->sec->debug.dfx.send_cnt);
 
        if (ret == -EBUSY)
                return -ENOBUFS;
 
        if (!ret) {
-               if (req->fake_busy)
+               if (atomic_read(&req->fake_busy))
                        ret = -EBUSY;
                else
                        ret = -EINPROGRESS;
@@ -641,7 +641,7 @@ static void sec_skcipher_callback(struct sec_ctx *ctx, struct sec_req *req)
        if (ctx->c_ctx.c_mode == SEC_CMODE_CBC && req->c_req.encrypt)
                sec_update_iv(req);
 
-       if (__sync_bool_compare_and_swap(&req->fake_busy, 1, 0))
+       if (atomic_cmpxchg(&req->fake_busy, 1, 0) != 1)
                sk_req->base.complete(&sk_req->base, -EINPROGRESS);
 
        sk_req->base.complete(&sk_req->base, req->err_type);
@@ -672,9 +672,9 @@ static int sec_request_init(struct sec_ctx *ctx, struct sec_req *req)
        }
 
        if (ctx->fake_req_limit <= atomic_inc_return(&qp_ctx->pending_reqs))
-               req->fake_busy = 1;
+               atomic_set(&req->fake_busy, 1);
        else
-               req->fake_busy = 0;
+               atomic_set(&req->fake_busy, 0);
 
        ret = ctx->req_op->get_res(ctx, req);
        if (ret) {
index 74f0654..ab742df 100644 (file)
@@ -608,6 +608,14 @@ static const struct file_operations sec_dbg_fops = {
        .write = sec_debug_write,
 };
 
+static int debugfs_atomic64_t_get(void *data, u64 *val)
+{
+        *val = atomic64_read((atomic64_t *)data);
+        return 0;
+}
+DEFINE_DEBUGFS_ATTRIBUTE(fops_atomic64_t_ro, debugfs_atomic64_t_get, NULL,
+                        "%lld\n");
+
 static int sec_core_debug_init(struct sec_dev *sec)
 {
        struct hisi_qm *qm = &sec->qm;
@@ -628,9 +636,11 @@ static int sec_core_debug_init(struct sec_dev *sec)
 
        debugfs_create_regset32("regs", 0444, tmp_d, regset);
 
-       debugfs_create_u64("send_cnt", 0444, tmp_d, &dfx->send_cnt);
+       debugfs_create_file("send_cnt", 0444, tmp_d, &dfx->send_cnt,
+                           &fops_atomic64_t_ro);
 
-       debugfs_create_u64("recv_cnt", 0444, tmp_d, &dfx->recv_cnt);
+       debugfs_create_file("recv_cnt", 0444, tmp_d, &dfx->recv_cnt,
+                           &fops_atomic64_t_ro);
 
        return 0;
 }
index 413cdb4..c0cc72a 100644 (file)
@@ -10,7 +10,7 @@
 #include <linux/edac.h>
 #include <linux/platform_device.h>
 #include "edac_module.h"
-#include <asm/sifive_l2_cache.h>
+#include <soc/sifive/sifive_l2_cache.h>
 
 #define DRVNAME "sifive_edac"
 
index d4077db..5d4f847 100644 (file)
@@ -17,7 +17,7 @@ static const struct console *earlycon_console __initdata;
 static const struct font_desc *font;
 static u32 efi_x, efi_y;
 static u64 fb_base;
-static pgprot_t fb_prot;
+static bool fb_wb;
 static void *efi_fb;
 
 /*
@@ -33,10 +33,8 @@ static int __init efi_earlycon_remap_fb(void)
        if (!earlycon_console || !(earlycon_console->flags & CON_ENABLED))
                return 0;
 
-       if (pgprot_val(fb_prot) == pgprot_val(PAGE_KERNEL))
-               efi_fb = memremap(fb_base, screen_info.lfb_size, MEMREMAP_WB);
-       else
-               efi_fb = memremap(fb_base, screen_info.lfb_size, MEMREMAP_WC);
+       efi_fb = memremap(fb_base, screen_info.lfb_size,
+                         fb_wb ? MEMREMAP_WB : MEMREMAP_WC);
 
        return efi_fb ? 0 : -ENOMEM;
 }
@@ -53,9 +51,12 @@ late_initcall(efi_earlycon_unmap_fb);
 
 static __ref void *efi_earlycon_map(unsigned long start, unsigned long len)
 {
+       pgprot_t fb_prot;
+
        if (efi_fb)
                return efi_fb + start;
 
+       fb_prot = fb_wb ? PAGE_KERNEL : pgprot_writecombine(PAGE_KERNEL);
        return early_memremap_prot(fb_base + start, len, pgprot_val(fb_prot));
 }
 
@@ -215,10 +216,7 @@ static int __init efi_earlycon_setup(struct earlycon_device *device,
        if (screen_info.capabilities & VIDEO_CAPABILITY_64BIT_BASE)
                fb_base |= (u64)screen_info.ext_lfb_base << 32;
 
-       if (opt && !strcmp(opt, "ram"))
-               fb_prot = PAGE_KERNEL;
-       else
-               fb_prot = pgprot_writecombine(PAGE_KERNEL);
+       fb_wb = opt && !strcmp(opt, "ram");
 
        si = &screen_info;
        xres = si->lfb_width;
index 35edd7c..97378cf 100644 (file)
@@ -33,7 +33,7 @@ efi_status_t efi_get_random_bytes(efi_system_table_t *sys_table_arg,
 {
        efi_guid_t rng_proto = EFI_RNG_PROTOCOL_GUID;
        efi_status_t status;
-       struct efi_rng_protocol *rng;
+       struct efi_rng_protocol *rng = NULL;
 
        status = efi_call_early(locate_protocol, &rng_proto, NULL,
                                (void **)&rng);
@@ -162,8 +162,8 @@ efi_status_t efi_random_get_seed(efi_system_table_t *sys_table_arg)
        efi_guid_t rng_proto = EFI_RNG_PROTOCOL_GUID;
        efi_guid_t rng_algo_raw = EFI_RNG_ALGORITHM_RAW;
        efi_guid_t rng_table_guid = LINUX_EFI_RANDOM_SEED_TABLE_GUID;
-       struct efi_rng_protocol *rng;
-       struct linux_efi_random_seed *seed;
+       struct efi_rng_protocol *rng = NULL;
+       struct linux_efi_random_seed *seed = NULL;
        efi_status_t status;
 
        status = efi_call_early(locate_protocol, &rng_proto, NULL,
index 6ab25fe..4b6d2ef 100644 (file)
@@ -573,7 +573,6 @@ config GPIO_THUNDERX
        tristate "Cavium ThunderX/OCTEON-TX GPIO"
        depends on ARCH_THUNDER || (64BIT && COMPILE_TEST)
        depends on PCI_MSI
-       select GPIOLIB_IRQCHIP
        select IRQ_DOMAIN_HIERARCHY
        select IRQ_FASTEOI_HIERARCHY_HANDLERS
        help
@@ -1148,6 +1147,7 @@ config GPIO_MADERA
 config GPIO_MAX77620
        tristate "GPIO support for PMIC MAX77620 and MAX20024"
        depends on MFD_MAX77620
+       select GPIOLIB_IRQCHIP
        help
          GPIO driver for MAX77620 and MAX20024 PMIC from Maxim Semiconductor.
          MAX77620 PMIC has 8 pins that can be configured as GPIOs. The
index c4fdc19..94b8d3a 100644 (file)
@@ -156,7 +156,7 @@ static int gpio_mockup_apply_pull(struct gpio_mockup_chip *chip,
        mutex_lock(&chip->lock);
 
        if (test_bit(FLAG_REQUESTED, &desc->flags) &&
-               !test_bit(FLAG_IS_OUT, &desc->flags)) {
+           !test_bit(FLAG_IS_OUT, &desc->flags)) {
                curr = __gpio_mockup_get(chip, offset);
                if (curr == value)
                        goto out;
@@ -165,7 +165,7 @@ static int gpio_mockup_apply_pull(struct gpio_mockup_chip *chip,
                irq_type = irq_get_trigger_type(irq);
 
                if ((value == 1 && (irq_type & IRQ_TYPE_EDGE_RISING)) ||
-                       (value == 0 && (irq_type & IRQ_TYPE_EDGE_FALLING)))
+                   (value == 0 && (irq_type & IRQ_TYPE_EDGE_FALLING)))
                        irq_sim_fire(sim, offset);
        }
 
index d08d86a..4627704 100644 (file)
@@ -53,6 +53,7 @@ struct thunderx_line {
 struct thunderx_gpio {
        struct gpio_chip        chip;
        u8 __iomem              *register_base;
+       struct irq_domain       *irqd;
        struct msix_entry       *msix_entries;  /* per line MSI-X */
        struct thunderx_line    *line_entries;  /* per line irq info */
        raw_spinlock_t          lock;
@@ -285,60 +286,54 @@ static void thunderx_gpio_set_multiple(struct gpio_chip *chip,
        }
 }
 
-static void thunderx_gpio_irq_ack(struct irq_data *d)
+static void thunderx_gpio_irq_ack(struct irq_data *data)
 {
-       struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
-       struct thunderx_gpio *txgpio = gpiochip_get_data(gc);
+       struct thunderx_line *txline = irq_data_get_irq_chip_data(data);
 
        writeq(GPIO_INTR_INTR,
-              txgpio->register_base + intr_reg(irqd_to_hwirq(d)));
+              txline->txgpio->register_base + intr_reg(txline->line));
 }
 
-static void thunderx_gpio_irq_mask(struct irq_data *d)
+static void thunderx_gpio_irq_mask(struct irq_data *data)
 {
-       struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
-       struct thunderx_gpio *txgpio = gpiochip_get_data(gc);
+       struct thunderx_line *txline = irq_data_get_irq_chip_data(data);
 
        writeq(GPIO_INTR_ENA_W1C,
-              txgpio->register_base + intr_reg(irqd_to_hwirq(d)));
+              txline->txgpio->register_base + intr_reg(txline->line));
 }
 
-static void thunderx_gpio_irq_mask_ack(struct irq_data *d)
+static void thunderx_gpio_irq_mask_ack(struct irq_data *data)
 {
-       struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
-       struct thunderx_gpio *txgpio = gpiochip_get_data(gc);
+       struct thunderx_line *txline = irq_data_get_irq_chip_data(data);
 
        writeq(GPIO_INTR_ENA_W1C | GPIO_INTR_INTR,
-              txgpio->register_base + intr_reg(irqd_to_hwirq(d)));
+              txline->txgpio->register_base + intr_reg(txline->line));
 }
 
-static void thunderx_gpio_irq_unmask(struct irq_data *d)
+static void thunderx_gpio_irq_unmask(struct irq_data *data)
 {
-       struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
-       struct thunderx_gpio *txgpio = gpiochip_get_data(gc);
+       struct thunderx_line *txline = irq_data_get_irq_chip_data(data);
 
        writeq(GPIO_INTR_ENA_W1S,
-              txgpio->register_base + intr_reg(irqd_to_hwirq(d)));
+              txline->txgpio->register_base + intr_reg(txline->line));
 }
 
-static int thunderx_gpio_irq_set_type(struct irq_data *d,
+static int thunderx_gpio_irq_set_type(struct irq_data *data,
                                      unsigned int flow_type)
 {
-       struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
-       struct thunderx_gpio *txgpio = gpiochip_get_data(gc);
-       struct thunderx_line *txline =
-               &txgpio->line_entries[irqd_to_hwirq(d)];
+       struct thunderx_line *txline = irq_data_get_irq_chip_data(data);
+       struct thunderx_gpio *txgpio = txline->txgpio;
        u64 bit_cfg;
 
-       irqd_set_trigger_type(d, flow_type);
+       irqd_set_trigger_type(data, flow_type);
 
        bit_cfg = txline->fil_bits | GPIO_BIT_CFG_INT_EN;
 
        if (flow_type & IRQ_TYPE_EDGE_BOTH) {
-               irq_set_handler_locked(d, handle_fasteoi_ack_irq);
+               irq_set_handler_locked(data, handle_fasteoi_ack_irq);
                bit_cfg |= GPIO_BIT_CFG_INT_TYPE;
        } else {
-               irq_set_handler_locked(d, handle_fasteoi_mask_irq);
+               irq_set_handler_locked(data, handle_fasteoi_mask_irq);
        }
 
        raw_spin_lock(&txgpio->lock);
@@ -367,6 +362,33 @@ static void thunderx_gpio_irq_disable(struct irq_data *data)
        irq_chip_disable_parent(data);
 }
 
+static int thunderx_gpio_irq_request_resources(struct irq_data *data)
+{
+       struct thunderx_line *txline = irq_data_get_irq_chip_data(data);
+       struct thunderx_gpio *txgpio = txline->txgpio;
+       int r;
+
+       r = gpiochip_lock_as_irq(&txgpio->chip, txline->line);
+       if (r)
+               return r;
+
+       r = irq_chip_request_resources_parent(data);
+       if (r)
+               gpiochip_unlock_as_irq(&txgpio->chip, txline->line);
+
+       return r;
+}
+
+static void thunderx_gpio_irq_release_resources(struct irq_data *data)
+{
+       struct thunderx_line *txline = irq_data_get_irq_chip_data(data);
+       struct thunderx_gpio *txgpio = txline->txgpio;
+
+       irq_chip_release_resources_parent(data);
+
+       gpiochip_unlock_as_irq(&txgpio->chip, txline->line);
+}
+
 /*
  * Interrupts are chained from underlying MSI-X vectors.  We have
  * these irq_chip functions to be able to handle level triggering
@@ -383,24 +405,50 @@ static struct irq_chip thunderx_gpio_irq_chip = {
        .irq_unmask             = thunderx_gpio_irq_unmask,
        .irq_eoi                = irq_chip_eoi_parent,
        .irq_set_affinity       = irq_chip_set_affinity_parent,
+       .irq_request_resources  = thunderx_gpio_irq_request_resources,
+       .irq_release_resources  = thunderx_gpio_irq_release_resources,
        .irq_set_type           = thunderx_gpio_irq_set_type,
 
        .flags                  = IRQCHIP_SET_TYPE_MASKED
 };
 
-static int thunderx_gpio_child_to_parent_hwirq(struct gpio_chip *gc,
-                                              unsigned int child,
-                                              unsigned int child_type,
-                                              unsigned int *parent,
-                                              unsigned int *parent_type)
+static int thunderx_gpio_irq_translate(struct irq_domain *d,
+                                      struct irq_fwspec *fwspec,
+                                      irq_hw_number_t *hwirq,
+                                      unsigned int *type)
 {
-       struct thunderx_gpio *txgpio = gpiochip_get_data(gc);
-
-       *parent = txgpio->base_msi + (2 * child);
-       *parent_type = IRQ_TYPE_LEVEL_HIGH;
+       struct thunderx_gpio *txgpio = d->host_data;
+
+       if (WARN_ON(fwspec->param_count < 2))
+               return -EINVAL;
+       if (fwspec->param[0] >= txgpio->chip.ngpio)
+               return -EINVAL;
+       *hwirq = fwspec->param[0];
+       *type = fwspec->param[1] & IRQ_TYPE_SENSE_MASK;
        return 0;
 }
 
+static int thunderx_gpio_irq_alloc(struct irq_domain *d, unsigned int virq,
+                                  unsigned int nr_irqs, void *arg)
+{
+       struct thunderx_line *txline = arg;
+
+       return irq_domain_set_hwirq_and_chip(d, virq, txline->line,
+                                            &thunderx_gpio_irq_chip, txline);
+}
+
+static const struct irq_domain_ops thunderx_gpio_irqd_ops = {
+       .alloc          = thunderx_gpio_irq_alloc,
+       .translate      = thunderx_gpio_irq_translate
+};
+
+static int thunderx_gpio_to_irq(struct gpio_chip *chip, unsigned int offset)
+{
+       struct thunderx_gpio *txgpio = gpiochip_get_data(chip);
+
+       return irq_find_mapping(txgpio->irqd, offset);
+}
+
 static int thunderx_gpio_probe(struct pci_dev *pdev,
                               const struct pci_device_id *id)
 {
@@ -408,7 +456,6 @@ static int thunderx_gpio_probe(struct pci_dev *pdev,
        struct device *dev = &pdev->dev;
        struct thunderx_gpio *txgpio;
        struct gpio_chip *chip;
-       struct gpio_irq_chip *girq;
        int ngpio, i;
        int err = 0;
 
@@ -453,8 +500,8 @@ static int thunderx_gpio_probe(struct pci_dev *pdev,
        }
 
        txgpio->msix_entries = devm_kcalloc(dev,
-                                           ngpio, sizeof(struct msix_entry),
-                                           GFP_KERNEL);
+                                         ngpio, sizeof(struct msix_entry),
+                                         GFP_KERNEL);
        if (!txgpio->msix_entries) {
                err = -ENOMEM;
                goto out;
@@ -495,6 +542,27 @@ static int thunderx_gpio_probe(struct pci_dev *pdev,
        if (err < 0)
                goto out;
 
+       /*
+        * Push GPIO specific irqdomain on hierarchy created as a side
+        * effect of the pci_enable_msix()
+        */
+       txgpio->irqd = irq_domain_create_hierarchy(irq_get_irq_data(txgpio->msix_entries[0].vector)->domain,
+                                                  0, 0, of_node_to_fwnode(dev->of_node),
+                                                  &thunderx_gpio_irqd_ops, txgpio);
+       if (!txgpio->irqd) {
+               err = -ENOMEM;
+               goto out;
+       }
+
+       /* Push on irq_data and the domain for each line. */
+       for (i = 0; i < ngpio; i++) {
+               err = irq_domain_push_irq(txgpio->irqd,
+                                         txgpio->msix_entries[i].vector,
+                                         &txgpio->line_entries[i]);
+               if (err < 0)
+                       dev_err(dev, "irq_domain_push_irq: %d\n", err);
+       }
+
        chip->label = KBUILD_MODNAME;
        chip->parent = dev;
        chip->owner = THIS_MODULE;
@@ -509,28 +577,11 @@ static int thunderx_gpio_probe(struct pci_dev *pdev,
        chip->set = thunderx_gpio_set;
        chip->set_multiple = thunderx_gpio_set_multiple;
        chip->set_config = thunderx_gpio_set_config;
-       girq = &chip->irq;
-       girq->chip = &thunderx_gpio_irq_chip;
-       girq->fwnode = of_node_to_fwnode(dev->of_node);
-       girq->parent_domain =
-               irq_get_irq_data(txgpio->msix_entries[0].vector)->domain;
-       girq->child_to_parent_hwirq = thunderx_gpio_child_to_parent_hwirq;
-       girq->handler = handle_bad_irq;
-       girq->default_type = IRQ_TYPE_NONE;
-
+       chip->to_irq = thunderx_gpio_to_irq;
        err = devm_gpiochip_add_data(dev, chip, txgpio);
        if (err)
                goto out;
 
-       /* Push on irq_data and the domain for each line. */
-       for (i = 0; i < ngpio; i++) {
-               err = irq_domain_push_irq(chip->irq.domain,
-                                         txgpio->msix_entries[i].vector,
-                                         chip);
-               if (err < 0)
-                       dev_err(dev, "irq_domain_push_irq: %d\n", err);
-       }
-
        dev_info(dev, "ThunderX GPIO: %d lines with base %d.\n",
                 ngpio, chip->base);
        return 0;
@@ -545,10 +596,10 @@ static void thunderx_gpio_remove(struct pci_dev *pdev)
        struct thunderx_gpio *txgpio = pci_get_drvdata(pdev);
 
        for (i = 0; i < txgpio->chip.ngpio; i++)
-               irq_domain_pop_irq(txgpio->chip.irq.domain,
+               irq_domain_pop_irq(txgpio->irqd,
                                   txgpio->msix_entries[i].vector);
 
-       irq_domain_remove(txgpio->chip.irq.domain);
+       irq_domain_remove(txgpio->irqd);
 
        pci_set_drvdata(pdev, NULL);
 }
index 4c3f637..05ba16f 100644 (file)
@@ -684,6 +684,8 @@ static void zynq_gpio_restore_context(struct zynq_gpio *gpio)
        unsigned int bank_num;
 
        for (bank_num = 0; bank_num < gpio->p_data->max_bank; bank_num++) {
+               writel_relaxed(ZYNQ_GPIO_IXR_DISABLE_ALL, gpio->base_addr +
+                               ZYNQ_GPIO_INTDIS_OFFSET(bank_num));
                writel_relaxed(gpio->context.datalsw[bank_num],
                               gpio->base_addr +
                               ZYNQ_GPIO_DATA_LSW_OFFSET(bank_num));
@@ -693,9 +695,6 @@ static void zynq_gpio_restore_context(struct zynq_gpio *gpio)
                writel_relaxed(gpio->context.dirm[bank_num],
                               gpio->base_addr +
                               ZYNQ_GPIO_DIRM_OFFSET(bank_num));
-               writel_relaxed(gpio->context.int_en[bank_num],
-                              gpio->base_addr +
-                              ZYNQ_GPIO_INTEN_OFFSET(bank_num));
                writel_relaxed(gpio->context.int_type[bank_num],
                               gpio->base_addr +
                               ZYNQ_GPIO_INTTYPE_OFFSET(bank_num));
@@ -705,6 +704,9 @@ static void zynq_gpio_restore_context(struct zynq_gpio *gpio)
                writel_relaxed(gpio->context.int_any[bank_num],
                               gpio->base_addr +
                               ZYNQ_GPIO_INTANY_OFFSET(bank_num));
+               writel_relaxed(~(gpio->context.int_en[bank_num]),
+                              gpio->base_addr +
+                              ZYNQ_GPIO_INTEN_OFFSET(bank_num));
        }
 }
 
index d30e57d..31fee5e 100644 (file)
 #include "gpiolib.h"
 #include "gpiolib-acpi.h"
 
+#define QUIRK_NO_EDGE_EVENTS_ON_BOOT           0x01l
+#define QUIRK_NO_WAKEUP                                0x02l
+
 static int run_edge_events_on_boot = -1;
 module_param(run_edge_events_on_boot, int, 0444);
 MODULE_PARM_DESC(run_edge_events_on_boot,
                 "Run edge _AEI event-handlers at boot: 0=no, 1=yes, -1=auto");
 
+static int honor_wakeup = -1;
+module_param(honor_wakeup, int, 0444);
+MODULE_PARM_DESC(honor_wakeup,
+                "Honor the ACPI wake-capable flag: 0=no, 1=yes, -1=auto");
+
 /**
  * struct acpi_gpio_event - ACPI GPIO event handler data
  *
@@ -281,7 +289,7 @@ static acpi_status acpi_gpiochip_alloc_event(struct acpi_resource *ares,
        event->handle = evt_handle;
        event->handler = handler;
        event->irq = irq;
-       event->irq_is_wake = agpio->wake_capable == ACPI_WAKE_CAPABLE;
+       event->irq_is_wake = honor_wakeup && agpio->wake_capable == ACPI_WAKE_CAPABLE;
        event->pin = pin;
        event->desc = desc;
 
@@ -1309,7 +1317,7 @@ static int acpi_gpio_handle_deferred_request_irqs(void)
 /* We must use _sync so that this runs after the first deferred_probe run */
 late_initcall_sync(acpi_gpio_handle_deferred_request_irqs);
 
-static const struct dmi_system_id run_edge_events_on_boot_blacklist[] = {
+static const struct dmi_system_id gpiolib_acpi_quirks[] = {
        {
                /*
                 * The Minix Neo Z83-4 has a micro-USB-B id-pin handler for
@@ -1319,7 +1327,8 @@ static const struct dmi_system_id run_edge_events_on_boot_blacklist[] = {
                .matches = {
                        DMI_MATCH(DMI_SYS_VENDOR, "MINIX"),
                        DMI_MATCH(DMI_PRODUCT_NAME, "Z83-4"),
-               }
+               },
+               .driver_data = (void *)QUIRK_NO_EDGE_EVENTS_ON_BOOT,
        },
        {
                /*
@@ -1331,20 +1340,52 @@ static const struct dmi_system_id run_edge_events_on_boot_blacklist[] = {
                .matches = {
                        DMI_MATCH(DMI_SYS_VENDOR, "Wortmann_AG"),
                        DMI_MATCH(DMI_PRODUCT_NAME, "TERRA_PAD_1061"),
-               }
+               },
+               .driver_data = (void *)QUIRK_NO_EDGE_EVENTS_ON_BOOT,
+       },
+       {
+               /*
+                * Various HP X2 10 Cherry Trail models use an external
+                * embedded-controller connected via I2C + an ACPI GPIO
+                * event handler. The embedded controller generates various
+                * spurious wakeup events when suspended. So disable wakeup
+                * for its handler (it uses the only ACPI GPIO event handler).
+                * This breaks wakeup when opening the lid, the user needs
+                * to press the power-button to wakeup the system. The
+                * alternative is suspend simply not working, which is worse.
+                */
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "HP"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "HP x2 Detachable 10-p0XX"),
+               },
+               .driver_data = (void *)QUIRK_NO_WAKEUP,
        },
        {} /* Terminating entry */
 };
 
 static int acpi_gpio_setup_params(void)
 {
+       const struct dmi_system_id *id;
+       long quirks = 0;
+
+       id = dmi_first_match(gpiolib_acpi_quirks);
+       if (id)
+               quirks = (long)id->driver_data;
+
        if (run_edge_events_on_boot < 0) {
-               if (dmi_check_system(run_edge_events_on_boot_blacklist))
+               if (quirks & QUIRK_NO_EDGE_EVENTS_ON_BOOT)
                        run_edge_events_on_boot = 0;
                else
                        run_edge_events_on_boot = 1;
        }
 
+       if (honor_wakeup < 0) {
+               if (quirks & QUIRK_NO_WAKEUP)
+                       honor_wakeup = 0;
+               else
+                       honor_wakeup = 1;
+       }
+
        return 0;
 }
 
index 0ffc944..01a793a 100644 (file)
@@ -142,7 +142,7 @@ int amdgpu_async_gfx_ring = 1;
 int amdgpu_mcbp = 0;
 int amdgpu_discovery = -1;
 int amdgpu_mes = 0;
-int amdgpu_noretry = 1;
+int amdgpu_noretry;
 int amdgpu_force_asic_type = -1;
 
 struct amdgpu_mgpu_info mgpu_info = {
@@ -588,7 +588,7 @@ MODULE_PARM_DESC(mes,
 module_param_named(mes, amdgpu_mes, int, 0444);
 
 MODULE_PARM_DESC(noretry,
-       "Disable retry faults (0 = retry enabled, 1 = retry disabled (default))");
+       "Disable retry faults (0 = retry enabled (default), 1 = retry disabled)");
 module_param_named(noretry, amdgpu_noretry, int, 0644);
 
 /**
@@ -1359,7 +1359,8 @@ static struct drm_driver kms_driver = {
        .driver_features =
            DRIVER_USE_AGP | DRIVER_ATOMIC |
            DRIVER_GEM |
-           DRIVER_RENDER | DRIVER_MODESET | DRIVER_SYNCOBJ,
+           DRIVER_RENDER | DRIVER_MODESET | DRIVER_SYNCOBJ |
+           DRIVER_SYNCOBJ_TIMELINE,
        .load = amdgpu_driver_load_kms,
        .open = amdgpu_driver_open_kms,
        .postclose = amdgpu_driver_postclose_kms,
index 4ef4d31..2f52b7f 100644 (file)
@@ -254,7 +254,7 @@ static const struct soc15_reg_golden golden_settings_sdma_4_3[] = {
        SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_RLC0_RB_WPTR_POLL_CNTL, 0xfffffff7, 0x00403000),
        SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_RLC1_RB_WPTR_POLL_CNTL, 0xfffffff7, 0x00403000),
        SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_UTCL1_PAGE, 0x000003ff, 0x000003c0),
-       SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_UTCL1_WATERMK, 0xfc000000, 0x00000000)
+       SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_UTCL1_WATERMK, 0xfc000000, 0x03fbe1fe)
 };
 
 static u32 sdma_v4_0_get_reg_offset(struct amdgpu_device *adev,
index 7aac956..803e59d 100644 (file)
@@ -3356,27 +3356,21 @@ get_output_color_space(const struct dc_crtc_timing *dc_crtc_timing)
        return color_space;
 }
 
-static void reduce_mode_colour_depth(struct dc_crtc_timing *timing_out)
-{
-       if (timing_out->display_color_depth <= COLOR_DEPTH_888)
-               return;
-
-       timing_out->display_color_depth--;
-}
-
-static void adjust_colour_depth_from_display_info(struct dc_crtc_timing *timing_out,
-                                               const struct drm_display_info *info)
+static bool adjust_colour_depth_from_display_info(
+       struct dc_crtc_timing *timing_out,
+       const struct drm_display_info *info)
 {
+       enum dc_color_depth depth = timing_out->display_color_depth;
        int normalized_clk;
-       if (timing_out->display_color_depth <= COLOR_DEPTH_888)
-               return;
        do {
                normalized_clk = timing_out->pix_clk_100hz / 10;
                /* YCbCr 4:2:0 requires additional adjustment of 1/2 */
                if (timing_out->pixel_encoding == PIXEL_ENCODING_YCBCR420)
                        normalized_clk /= 2;
                /* Adjusting pix clock following on HDMI spec based on colour depth */
-               switch (timing_out->display_color_depth) {
+               switch (depth) {
+               case COLOR_DEPTH_888:
+                       break;
                case COLOR_DEPTH_101010:
                        normalized_clk = (normalized_clk * 30) / 24;
                        break;
@@ -3387,14 +3381,15 @@ static void adjust_colour_depth_from_display_info(struct dc_crtc_timing *timing_
                        normalized_clk = (normalized_clk * 48) / 24;
                        break;
                default:
-                       return;
+                       /* The above depths are the only ones valid for HDMI. */
+                       return false;
                }
-               if (normalized_clk <= info->max_tmds_clock)
-                       return;
-               reduce_mode_colour_depth(timing_out);
-
-       } while (timing_out->display_color_depth > COLOR_DEPTH_888);
-
+               if (normalized_clk <= info->max_tmds_clock) {
+                       timing_out->display_color_depth = depth;
+                       return true;
+               }
+       } while (--depth > COLOR_DEPTH_666);
+       return false;
 }
 
 static void fill_stream_properties_from_drm_display_mode(
@@ -3474,8 +3469,14 @@ static void fill_stream_properties_from_drm_display_mode(
 
        stream->out_transfer_func->type = TF_TYPE_PREDEFINED;
        stream->out_transfer_func->tf = TRANSFER_FUNCTION_SRGB;
-       if (stream->signal == SIGNAL_TYPE_HDMI_TYPE_A)
-               adjust_colour_depth_from_display_info(timing_out, info);
+       if (stream->signal == SIGNAL_TYPE_HDMI_TYPE_A) {
+               if (!adjust_colour_depth_from_display_info(timing_out, info) &&
+                   drm_mode_is_420_also(info, mode_in) &&
+                   timing_out->pixel_encoding != PIXEL_ENCODING_YCBCR420) {
+                       timing_out->pixel_encoding = PIXEL_ENCODING_YCBCR420;
+                       adjust_colour_depth_from_display_info(timing_out, info);
+               }
+       }
 }
 
 static void fill_audio_info(struct audio_info *audio_info,
index 62d8289..4619f94 100644 (file)
@@ -817,8 +817,8 @@ static bool dc_link_detect_helper(struct dc_link *link,
                }
 
                case SIGNAL_TYPE_EDP: {
-                       read_current_link_settings_on_detect(link);
                        detect_edp_sink_caps(link);
+                       read_current_link_settings_on_detect(link);
                        sink_caps.transaction_type = DDC_TRANSACTION_TYPE_I2C_OVER_AUX;
                        sink_caps.signal = SIGNAL_TYPE_EDP;
                        break;
index 273dd80..5a61a55 100644 (file)
@@ -393,7 +393,7 @@ drm_dp_encode_sideband_req(const struct drm_dp_sideband_msg_req_body *req,
                        memcpy(&buf[idx], req->u.i2c_read.transactions[i].bytes, req->u.i2c_read.transactions[i].num_bytes);
                        idx += req->u.i2c_read.transactions[i].num_bytes;
 
-                       buf[idx] = (req->u.i2c_read.transactions[i].no_stop_bit & 0x1) << 5;
+                       buf[idx] = (req->u.i2c_read.transactions[i].no_stop_bit & 0x1) << 4;
                        buf[idx] |= (req->u.i2c_read.transactions[i].i2c_transaction_delay & 0xf);
                        idx++;
                }
@@ -1190,6 +1190,8 @@ static int drm_dp_mst_wait_tx_reply(struct drm_dp_mst_branch *mstb,
                    txmsg->state == DRM_DP_SIDEBAND_TX_SENT) {
                        mstb->tx_slots[txmsg->seqno] = NULL;
                }
+               mgr->is_waiting_for_dwn_reply = false;
+
        }
 out:
        if (unlikely(ret == -EIO) && drm_debug_enabled(DRM_UT_DP)) {
@@ -1199,6 +1201,7 @@ out:
        }
        mutex_unlock(&mgr->qlock);
 
+       drm_dp_mst_kick_tx(mgr);
        return ret;
 }
 
@@ -2318,7 +2321,7 @@ drm_dp_mst_handle_conn_stat(struct drm_dp_mst_branch *mstb,
 {
        struct drm_dp_mst_topology_mgr *mgr = mstb->mgr;
        struct drm_dp_mst_port *port;
-       int old_ddps, ret;
+       int old_ddps, old_input, ret, i;
        u8 new_pdt;
        bool dowork = false, create_connector = false;
 
@@ -2349,6 +2352,7 @@ drm_dp_mst_handle_conn_stat(struct drm_dp_mst_branch *mstb,
        }
 
        old_ddps = port->ddps;
+       old_input = port->input;
        port->input = conn_stat->input_port;
        port->mcs = conn_stat->message_capability_status;
        port->ldps = conn_stat->legacy_device_plug_status;
@@ -2373,6 +2377,28 @@ drm_dp_mst_handle_conn_stat(struct drm_dp_mst_branch *mstb,
                dowork = false;
        }
 
+       if (!old_input && old_ddps != port->ddps && !port->ddps) {
+               for (i = 0; i < mgr->max_payloads; i++) {
+                       struct drm_dp_vcpi *vcpi = mgr->proposed_vcpis[i];
+                       struct drm_dp_mst_port *port_validated;
+
+                       if (!vcpi)
+                               continue;
+
+                       port_validated =
+                               container_of(vcpi, struct drm_dp_mst_port, vcpi);
+                       port_validated =
+                               drm_dp_mst_topology_get_port_validated(mgr, port_validated);
+                       if (!port_validated) {
+                               mutex_lock(&mgr->payload_lock);
+                               vcpi->num_slots = 0;
+                               mutex_unlock(&mgr->payload_lock);
+                       } else {
+                               drm_dp_mst_topology_put_port(port_validated);
+                       }
+               }
+       }
+
        if (port->connector)
                drm_modeset_unlock(&mgr->base.lock);
        else if (create_connector)
@@ -2718,9 +2744,11 @@ static void process_single_down_tx_qlock(struct drm_dp_mst_topology_mgr *mgr)
        ret = process_single_tx_qlock(mgr, txmsg, false);
        if (ret == 1) {
                /* txmsg is sent it should be in the slots now */
+               mgr->is_waiting_for_dwn_reply = true;
                list_del(&txmsg->next);
        } else if (ret) {
                DRM_DEBUG_KMS("failed to send msg in q %d\n", ret);
+               mgr->is_waiting_for_dwn_reply = false;
                list_del(&txmsg->next);
                if (txmsg->seqno != -1)
                        txmsg->dst->tx_slots[txmsg->seqno] = NULL;
@@ -2760,7 +2788,8 @@ static void drm_dp_queue_down_tx(struct drm_dp_mst_topology_mgr *mgr,
                drm_dp_mst_dump_sideband_msg_tx(&p, txmsg);
        }
 
-       if (list_is_singular(&mgr->tx_msg_downq))
+       if (list_is_singular(&mgr->tx_msg_downq) &&
+           !mgr->is_waiting_for_dwn_reply)
                process_single_down_tx_qlock(mgr);
        mutex_unlock(&mgr->qlock);
 }
@@ -3678,6 +3707,7 @@ static int drm_dp_mst_handle_down_rep(struct drm_dp_mst_topology_mgr *mgr)
        mutex_lock(&mgr->qlock);
        txmsg->state = DRM_DP_SIDEBAND_TX_RX;
        mstb->tx_slots[slot] = NULL;
+       mgr->is_waiting_for_dwn_reply = false;
        mutex_unlock(&mgr->qlock);
 
        wake_up_all(&mgr->tx_waitq);
@@ -3687,6 +3717,9 @@ static int drm_dp_mst_handle_down_rep(struct drm_dp_mst_topology_mgr *mgr)
 no_msg:
        drm_dp_mst_topology_put_mstb(mstb);
 clear_down_rep_recv:
+       mutex_lock(&mgr->qlock);
+       mgr->is_waiting_for_dwn_reply = false;
+       mutex_unlock(&mgr->qlock);
        memset(&mgr->down_rep_recv, 0, sizeof(struct drm_dp_sideband_msg_rx));
 
        return 0;
@@ -4497,7 +4530,7 @@ static void drm_dp_tx_work(struct work_struct *work)
        struct drm_dp_mst_topology_mgr *mgr = container_of(work, struct drm_dp_mst_topology_mgr, tx_work);
 
        mutex_lock(&mgr->qlock);
-       if (!list_empty(&mgr->tx_msg_downq))
+       if (!list_empty(&mgr->tx_msg_downq) && !mgr->is_waiting_for_dwn_reply)
                process_single_down_tx_qlock(mgr);
        mutex_unlock(&mgr->qlock);
 }
index 8ebeccd..d8e8f39 100644 (file)
@@ -1283,7 +1283,7 @@ int drm_fb_helper_check_var(struct fb_var_screeninfo *var,
         * Changes struct fb_var_screeninfo are currently not pushed back
         * to KMS, hence fail if different settings are requested.
         */
-       if (var->bits_per_pixel != fb->format->cpp[0] * 8 ||
+       if (var->bits_per_pixel > fb->format->cpp[0] * 8 ||
            var->xres > fb->width || var->yres > fb->height ||
            var->xres_virtual > fb->width || var->yres_virtual > fb->height) {
                DRM_DEBUG("fb requested width/height/bpp can't fit in current fb "
@@ -1308,6 +1308,11 @@ int drm_fb_helper_check_var(struct fb_var_screeninfo *var,
                drm_fb_helper_fill_pixel_fmt(var, fb->format->depth);
        }
 
+       /*
+        * Likewise, bits_per_pixel should be rounded up to a supported value.
+        */
+       var->bits_per_pixel = fb->format->cpp[0] * 8;
+
        /*
         * drm fbdev emulation doesn't support changing the pixel format at all,
         * so reject all pixel format changing requests.
index 85e6b2b..3a5ac13 100644 (file)
@@ -856,7 +856,7 @@ static unsigned long i915_audio_component_get_power(struct device *kdev)
                }
 
                /* Force CDCLK to 2*BCLK as long as we need audio powered. */
-               if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv))
+               if (IS_GEMINILAKE(dev_priv))
                        glk_force_audio_cdclk(dev_priv, true);
 
                if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv))
@@ -875,7 +875,7 @@ static void i915_audio_component_put_power(struct device *kdev,
 
        /* Stop forcing CDCLK to 2*BCLK if no need for audio to be powered. */
        if (--dev_priv->audio_power_refcount == 0)
-               if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv))
+               if (IS_GEMINILAKE(dev_priv))
                        glk_force_audio_cdclk(dev_priv, false);
 
        intel_display_power_put(dev_priv, POWER_DOMAIN_AUDIO, cookie);
index effc425..3018977 100644 (file)
@@ -4515,8 +4515,6 @@ static void icl_disable_transcoder_port_sync(const struct intel_crtc_state *old_
 {
        struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->base.crtc);
        struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
-       i915_reg_t reg;
-       u32 trans_ddi_func_ctl2_val;
 
        if (old_crtc_state->master_transcoder == INVALID_TRANSCODER)
                return;
@@ -4524,10 +4522,7 @@ static void icl_disable_transcoder_port_sync(const struct intel_crtc_state *old_
        DRM_DEBUG_KMS("Disabling Transcoder Port Sync on Slave Transcoder %s\n",
                      transcoder_name(old_crtc_state->cpu_transcoder));
 
-       reg = TRANS_DDI_FUNC_CTL2(old_crtc_state->cpu_transcoder);
-       trans_ddi_func_ctl2_val = ~(PORT_SYNC_MODE_ENABLE |
-                                   PORT_SYNC_MODE_MASTER_SELECT_MASK);
-       I915_WRITE(reg, trans_ddi_func_ctl2_val);
+       I915_WRITE(TRANS_DDI_FUNC_CTL2(old_crtc_state->cpu_transcoder), 0);
 }
 
 static void intel_fdi_normal_train(struct intel_crtc *crtc)
index ef7bc41..5b7ff3c 100644 (file)
@@ -123,6 +123,10 @@ static int __context_pin_state(struct i915_vma *vma)
        if (err)
                return err;
 
+       err = i915_active_acquire(&vma->active);
+       if (err)
+               goto err_unpin;
+
        /*
         * And mark it as a globally pinned object to let the shrinker know
         * it cannot reclaim the object until we release it.
@@ -131,14 +135,44 @@ static int __context_pin_state(struct i915_vma *vma)
        vma->obj->mm.dirty = true;
 
        return 0;
+
+err_unpin:
+       i915_vma_unpin(vma);
+       return err;
 }
 
 static void __context_unpin_state(struct i915_vma *vma)
 {
        i915_vma_make_shrinkable(vma);
+       i915_active_release(&vma->active);
        __i915_vma_unpin(vma);
 }
 
+static int __ring_active(struct intel_ring *ring)
+{
+       int err;
+
+       err = i915_active_acquire(&ring->vma->active);
+       if (err)
+               return err;
+
+       err = intel_ring_pin(ring);
+       if (err)
+               goto err_active;
+
+       return 0;
+
+err_active:
+       i915_active_release(&ring->vma->active);
+       return err;
+}
+
+static void __ring_retire(struct intel_ring *ring)
+{
+       intel_ring_unpin(ring);
+       i915_active_release(&ring->vma->active);
+}
+
 __i915_active_call
 static void __intel_context_retire(struct i915_active *active)
 {
@@ -151,7 +185,7 @@ static void __intel_context_retire(struct i915_active *active)
                __context_unpin_state(ce->state);
 
        intel_timeline_unpin(ce->timeline);
-       intel_ring_unpin(ce->ring);
+       __ring_retire(ce->ring);
 
        intel_context_put(ce);
 }
@@ -163,7 +197,7 @@ static int __intel_context_active(struct i915_active *active)
 
        intel_context_get(ce);
 
-       err = intel_ring_pin(ce->ring);
+       err = __ring_active(ce->ring);
        if (err)
                goto err_put;
 
@@ -183,7 +217,7 @@ static int __intel_context_active(struct i915_active *active)
 err_timeline:
        intel_timeline_unpin(ce->timeline);
 err_ring:
-       intel_ring_unpin(ce->ring);
+       __ring_retire(ce->ring);
 err_put:
        intel_context_put(ce);
        return err;
index 75dd0e0..d925a10 100644 (file)
@@ -2664,6 +2664,14 @@ static u32 *gen9_init_indirectctx_bb(struct intel_engine_cs *engine, u32 *batch)
        /* WaFlushCoherentL3CacheLinesAtContextSwitch:skl,bxt,glk */
        batch = gen8_emit_flush_coherentl3_wa(engine, batch);
 
+       /* WaClearSlmSpaceAtContextSwitch:skl,bxt,kbl,glk,cfl */
+       batch = gen8_emit_pipe_control(batch,
+                                      PIPE_CONTROL_FLUSH_L3 |
+                                      PIPE_CONTROL_STORE_DATA_INDEX |
+                                      PIPE_CONTROL_CS_STALL |
+                                      PIPE_CONTROL_QW_WRITE,
+                                      LRC_PPHWSP_SCRATCH_ADDR);
+
        batch = emit_lri(batch, lri, ARRAY_SIZE(lri));
 
        /* WaMediaPoolStateCmdInWABB:bxt,glk */
@@ -4416,9 +4424,11 @@ intel_execlists_create_virtual(struct i915_gem_context *ctx,
        ve->base.gt = siblings[0]->gt;
        ve->base.uncore = siblings[0]->uncore;
        ve->base.id = -1;
+
        ve->base.class = OTHER_CLASS;
        ve->base.uabi_class = I915_ENGINE_CLASS_INVALID;
        ve->base.instance = I915_ENGINE_CLASS_INVALID_VIRTUAL;
+       ve->base.uabi_instance = I915_ENGINE_CLASS_INVALID_VIRTUAL;
 
        /*
         * The decision on whether to submit a request using semaphores
index a47d5a7..9302621 100644 (file)
@@ -1413,14 +1413,6 @@ static inline int mi_set_context(struct i915_request *rq, u32 flags)
        int len;
        u32 *cs;
 
-       flags |= MI_MM_SPACE_GTT;
-       if (IS_HASWELL(i915))
-               /* These flags are for resource streamer on HSW+ */
-               flags |= HSW_MI_RS_SAVE_STATE_EN | HSW_MI_RS_RESTORE_STATE_EN;
-       else
-               /* We need to save the extended state for powersaving modes */
-               flags |= MI_SAVE_EXT_STATE_EN | MI_RESTORE_EXT_STATE_EN;
-
        len = 4;
        if (IS_GEN(i915, 7))
                len += 2 + (num_engines ? 4 * num_engines + 6 : 0);
@@ -1589,22 +1581,21 @@ static int switch_context(struct i915_request *rq)
        }
 
        if (ce->state) {
-               u32 hw_flags;
+               u32 flags;
 
                GEM_BUG_ON(rq->engine->id != RCS0);
 
-               /*
-                * The kernel context(s) is treated as pure scratch and is not
-                * expected to retain any state (as we sacrifice it during
-                * suspend and on resume it may be corrupted). This is ok,
-                * as nothing actually executes using the kernel context; it
-                * is purely used for flushing user contexts.
-                */
-               hw_flags = 0;
-               if (i915_gem_context_is_kernel(rq->gem_context))
-                       hw_flags = MI_RESTORE_INHIBIT;
+               /* For resource streamer on HSW+ and power context elsewhere */
+               BUILD_BUG_ON(HSW_MI_RS_SAVE_STATE_EN != MI_SAVE_EXT_STATE_EN);
+               BUILD_BUG_ON(HSW_MI_RS_RESTORE_STATE_EN != MI_RESTORE_EXT_STATE_EN);
+
+               flags = MI_SAVE_EXT_STATE_EN | MI_MM_SPACE_GTT;
+               if (!i915_gem_context_is_kernel(rq->gem_context))
+                       flags |= MI_RESTORE_EXT_STATE_EN;
+               else
+                       flags |= MI_RESTORE_INHIBIT;
 
-               ret = mi_set_context(rq, hw_flags);
+               ret = mi_set_context(rq, flags);
                if (ret)
                        return ret;
        }
index e29bc13..21aa08f 100644 (file)
@@ -1660,8 +1660,10 @@ IS_SUBPLATFORM(const struct drm_i915_private *i915,
        (IS_BROADWELL(dev_priv) || IS_GEN(dev_priv, 9))
 
 /* WaRsDisableCoarsePowerGating:skl,cnl */
-#define NEEDS_WaRsDisableCoarsePowerGating(dev_priv) \
-       (IS_CANNONLAKE(dev_priv) || IS_GEN(dev_priv, 9))
+#define NEEDS_WaRsDisableCoarsePowerGating(dev_priv)                   \
+       (IS_CANNONLAKE(dev_priv) ||                                     \
+        IS_SKL_GT3(dev_priv) ||                                        \
+        IS_SKL_GT4(dev_priv))
 
 #define HAS_GMBUS_IRQ(dev_priv) (INTEL_GEN(dev_priv) >= 4)
 #define HAS_GMBUS_BURST_READ(dev_priv) (INTEL_GEN(dev_priv) >= 10 || \
index 6239a9a..c083f51 100644 (file)
@@ -3304,7 +3304,7 @@ void i915_ggtt_disable_guc(struct i915_ggtt *ggtt)
 
 static void ggtt_restore_mappings(struct i915_ggtt *ggtt)
 {
-       struct i915_vma *vma, *vn;
+       struct i915_vma *vma;
        bool flush = false;
        int open;
 
@@ -3319,15 +3319,12 @@ static void ggtt_restore_mappings(struct i915_ggtt *ggtt)
        open = atomic_xchg(&ggtt->vm.open, 0);
 
        /* clflush objects bound into the GGTT and rebind them. */
-       list_for_each_entry_safe(vma, vn, &ggtt->vm.bound_list, vm_link) {
+       list_for_each_entry(vma, &ggtt->vm.bound_list, vm_link) {
                struct drm_i915_gem_object *obj = vma->obj;
 
                if (!i915_vma_is_bound(vma, I915_VMA_GLOBAL_BIND))
                        continue;
 
-               if (!__i915_vma_unbind(vma))
-                       continue;
-
                clear_bit(I915_VMA_GLOBAL_BIND_BIT, __i915_vma_flags(vma));
                WARN_ON(i915_vma_bind(vma,
                                      obj ? obj->cache_level : 0,
index 6f09aa0..d6d2e6f 100644 (file)
@@ -1074,12 +1074,17 @@ void i915_pmu_register(struct drm_i915_private *i915)
        hrtimer_init(&pmu->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
        pmu->timer.function = i915_sample;
 
-       if (!is_igp(i915))
+       if (!is_igp(i915)) {
                pmu->name = kasprintf(GFP_KERNEL,
-                                     "i915-%s",
+                                     "i915_%s",
                                      dev_name(i915->drm.dev));
-       else
+               if (pmu->name) {
+                       /* tools/perf reserves colons as special. */
+                       strreplace((char *)pmu->name, ':', '_');
+               }
+       } else {
                pmu->name = "i915";
+       }
        if (!pmu->name)
                goto err;
 
index 4fd3d76..094011b 100644 (file)
@@ -4177,7 +4177,13 @@ enum {
 #define  CPSSUNIT_CLKGATE_DIS          REG_BIT(9)
 
 #define UNSLICE_UNIT_LEVEL_CLKGATE     _MMIO(0x9434)
-#define  VFUNIT_CLKGATE_DIS            (1 << 20)
+#define   VFUNIT_CLKGATE_DIS           REG_BIT(20)
+#define   HSUNIT_CLKGATE_DIS           REG_BIT(8)
+#define   VSUNIT_CLKGATE_DIS           REG_BIT(3)
+
+#define UNSLICE_UNIT_LEVEL_CLKGATE2    _MMIO(0x94e4)
+#define   VSUNIT_CLKGATE_DIS_TGL       REG_BIT(19)
+#define   PSDUNIT_CLKGATE_DIS          REG_BIT(5)
 
 #define INF_UNIT_LEVEL_CLKGATE         _MMIO(0x9560)
 #define   CGPSF_CLKGATE_DIS            (1 << 3)
index 75ae6f4..86379ed 100644 (file)
@@ -6565,6 +6565,17 @@ static void icl_init_clock_gating(struct drm_i915_private *dev_priv)
        /* WaEnable32PlaneMode:icl */
        I915_WRITE(GEN9_CSFE_CHICKEN1_RCS,
                   _MASKED_BIT_ENABLE(GEN11_ENABLE_32_PLANE_MODE));
+
+       /*
+        * Wa_1408615072:icl,ehl  (vsunit)
+        * Wa_1407596294:icl,ehl  (hsunit)
+        */
+       intel_uncore_rmw(&dev_priv->uncore, UNSLICE_UNIT_LEVEL_CLKGATE,
+                        0, VSUNIT_CLKGATE_DIS | HSUNIT_CLKGATE_DIS);
+
+       /* Wa_1407352427:icl,ehl */
+       intel_uncore_rmw(&dev_priv->uncore, UNSLICE_UNIT_LEVEL_CLKGATE2,
+                        0, PSDUNIT_CLKGATE_DIS);
 }
 
 static void tgl_init_clock_gating(struct drm_i915_private *dev_priv)
index 35cc69a..05364ec 100644 (file)
@@ -25,6 +25,7 @@
 #ifndef __I915_SELFTESTS_RANDOM_H__
 #define __I915_SELFTESTS_RANDOM_H__
 
+#include <linux/math64.h>
 #include <linux/random.h>
 
 #include "../i915_selftest.h"
index 83c4586..81ac9b6 100644 (file)
@@ -95,7 +95,7 @@ struct cdn_dp_device {
        struct cdn_dp_port *port[MAX_PHY];
        u8 ports;
        u8 max_lanes;
-       u8 max_rate;
+       unsigned int max_rate;
        u8 lanes;
        int active_port;
 
index 42651d7..c81cdce 100644 (file)
@@ -489,7 +489,7 @@ static void sun4i_tcon0_mode_set_rgb(struct sun4i_tcon *tcon,
 
        WARN_ON(!tcon->quirks->has_channel_0);
 
-       tcon->dclk_min_div = 1;
+       tcon->dclk_min_div = tcon->quirks->dclk_min_div;
        tcon->dclk_max_div = 127;
        sun4i_tcon0_mode_set_common(tcon, mode);
 
@@ -1426,12 +1426,14 @@ static int sun8i_r40_tcon_tv_set_mux(struct sun4i_tcon *tcon,
 static const struct sun4i_tcon_quirks sun4i_a10_quirks = {
        .has_channel_0          = true,
        .has_channel_1          = true,
+       .dclk_min_div           = 4,
        .set_mux                = sun4i_a10_tcon_set_mux,
 };
 
 static const struct sun4i_tcon_quirks sun5i_a13_quirks = {
        .has_channel_0          = true,
        .has_channel_1          = true,
+       .dclk_min_div           = 4,
        .set_mux                = sun5i_a13_tcon_set_mux,
 };
 
@@ -1440,6 +1442,7 @@ static const struct sun4i_tcon_quirks sun6i_a31_quirks = {
        .has_channel_1          = true,
        .has_lvds_alt           = true,
        .needs_de_be_mux        = true,
+       .dclk_min_div           = 1,
        .set_mux                = sun6i_tcon_set_mux,
 };
 
@@ -1447,11 +1450,13 @@ static const struct sun4i_tcon_quirks sun6i_a31s_quirks = {
        .has_channel_0          = true,
        .has_channel_1          = true,
        .needs_de_be_mux        = true,
+       .dclk_min_div           = 1,
 };
 
 static const struct sun4i_tcon_quirks sun7i_a20_quirks = {
        .has_channel_0          = true,
        .has_channel_1          = true,
+       .dclk_min_div           = 4,
        /* Same display pipeline structure as A10 */
        .set_mux                = sun4i_a10_tcon_set_mux,
 };
@@ -1459,11 +1464,13 @@ static const struct sun4i_tcon_quirks sun7i_a20_quirks = {
 static const struct sun4i_tcon_quirks sun8i_a33_quirks = {
        .has_channel_0          = true,
        .has_lvds_alt           = true,
+       .dclk_min_div           = 1,
 };
 
 static const struct sun4i_tcon_quirks sun8i_a83t_lcd_quirks = {
        .supports_lvds          = true,
        .has_channel_0          = true,
+       .dclk_min_div           = 1,
 };
 
 static const struct sun4i_tcon_quirks sun8i_a83t_tv_quirks = {
@@ -1477,11 +1484,13 @@ static const struct sun4i_tcon_quirks sun8i_r40_tv_quirks = {
 
 static const struct sun4i_tcon_quirks sun8i_v3s_quirks = {
        .has_channel_0          = true,
+       .dclk_min_div           = 1,
 };
 
 static const struct sun4i_tcon_quirks sun9i_a80_tcon_lcd_quirks = {
-       .has_channel_0  = true,
-       .needs_edp_reset = true,
+       .has_channel_0          = true,
+       .needs_edp_reset        = true,
+       .dclk_min_div           = 1,
 };
 
 static const struct sun4i_tcon_quirks sun9i_a80_tcon_tv_quirks = {
index f9f1fe8..a62ec82 100644 (file)
@@ -224,6 +224,7 @@ struct sun4i_tcon_quirks {
        bool    needs_de_be_mux; /* sun6i needs mux to select backend */
        bool    needs_edp_reset; /* a80 edp reset needed for tcon0 access */
        bool    supports_lvds;   /* Does the TCON support an LVDS output? */
+       u8      dclk_min_div;   /* minimum divider for TCON0 DCLK */
 
        /* callback to handle tcon muxing options */
        int     (*set_mux)(struct sun4i_tcon *, const struct drm_encoder *);
index 3905241..1635a9f 100644 (file)
@@ -232,6 +232,7 @@ static void virtio_gpu_cursor_plane_update(struct drm_plane *plane,
                if (!objs)
                        return;
                virtio_gpu_array_add_obj(objs, vgfb->base.obj[0]);
+               virtio_gpu_array_lock_resv(objs);
                virtio_gpu_cmd_transfer_to_host_2d
                        (vgdev, 0,
                         plane->state->crtc_w,
index f61f212..7a75aff 100644 (file)
@@ -249,13 +249,14 @@ out:
 static __poll_t hidraw_poll(struct file *file, poll_table *wait)
 {
        struct hidraw_list *list = file->private_data;
+       __poll_t mask = EPOLLOUT | EPOLLWRNORM; /* hidraw is always writable */
 
        poll_wait(file, &list->hidraw->wait, wait);
        if (list->head != list->tail)
-               return EPOLLIN | EPOLLRDNORM;
+               mask |= EPOLLIN | EPOLLRDNORM;
        if (!list->hidraw->exist)
-               return EPOLLERR | EPOLLHUP;
-       return EPOLLOUT | EPOLLWRNORM;
+               mask |= EPOLLERR | EPOLLHUP;
+       return mask;
 }
 
 static int hidraw_open(struct inode *inode, struct file *file)
index 935c3d0..8fe3efc 100644 (file)
@@ -766,13 +766,14 @@ unlock:
 static __poll_t uhid_char_poll(struct file *file, poll_table *wait)
 {
        struct uhid_device *uhid = file->private_data;
+       __poll_t mask = EPOLLOUT | EPOLLWRNORM; /* uhid is always writable */
 
        poll_wait(file, &uhid->waitq, wait);
 
        if (uhid->head != uhid->tail)
-               return EPOLLIN | EPOLLRDNORM;
+               mask |= EPOLLIN | EPOLLRDNORM;
 
-       return EPOLLOUT | EPOLLWRNORM;
+       return mask;
 }
 
 static const struct file_operations uhid_fops = {
index dc3f507..a90d757 100644 (file)
@@ -1132,7 +1132,6 @@ static void etm4_init_trace_id(struct etmv4_drvdata *drvdata)
        drvdata->trcid = coresight_get_trace_id(drvdata->cpu);
 }
 
-#ifdef CONFIG_CPU_PM
 static int etm4_cpu_save(struct etmv4_drvdata *drvdata)
 {
        int i, ret = 0;
@@ -1402,17 +1401,17 @@ static struct notifier_block etm4_cpu_pm_nb = {
 
 static int etm4_cpu_pm_register(void)
 {
-       return cpu_pm_register_notifier(&etm4_cpu_pm_nb);
+       if (IS_ENABLED(CONFIG_CPU_PM))
+               return cpu_pm_register_notifier(&etm4_cpu_pm_nb);
+
+       return 0;
 }
 
 static void etm4_cpu_pm_unregister(void)
 {
-       cpu_pm_unregister_notifier(&etm4_cpu_pm_nb);
+       if (IS_ENABLED(CONFIG_CPU_PM))
+               cpu_pm_unregister_notifier(&etm4_cpu_pm_nb);
 }
-#else
-static int etm4_cpu_pm_register(void) { return 0; }
-static void etm4_cpu_pm_unregister(void) { }
-#endif
 
 static int etm4_probe(struct amba_device *adev, const struct amba_id *id)
 {
index e13af48..5137e62 100644 (file)
@@ -174,7 +174,7 @@ static struct at91_twi_pdata sama5d2_config = {
 
 static struct at91_twi_pdata sam9x60_config = {
        .clk_max_div = 7,
-       .clk_offset = 4,
+       .clk_offset = 3,
        .has_unre_flag = true,
        .has_alt_cmd = true,
        .has_hold_field = true,
index e01b2b5..5ab901a 100644 (file)
@@ -58,6 +58,7 @@ struct bcm2835_i2c_dev {
        struct i2c_adapter adapter;
        struct completion completion;
        struct i2c_msg *curr_msg;
+       struct clk *bus_clk;
        int num_msgs;
        u32 msg_err;
        u8 *msg_buf;
@@ -404,7 +405,6 @@ static int bcm2835_i2c_probe(struct platform_device *pdev)
        struct resource *mem, *irq;
        int ret;
        struct i2c_adapter *adap;
-       struct clk *bus_clk;
        struct clk *mclk;
        u32 bus_clk_rate;
 
@@ -427,11 +427,11 @@ static int bcm2835_i2c_probe(struct platform_device *pdev)
                return PTR_ERR(mclk);
        }
 
-       bus_clk = bcm2835_i2c_register_div(&pdev->dev, mclk, i2c_dev);
+       i2c_dev->bus_clk = bcm2835_i2c_register_div(&pdev->dev, mclk, i2c_dev);
 
-       if (IS_ERR(bus_clk)) {
+       if (IS_ERR(i2c_dev->bus_clk)) {
                dev_err(&pdev->dev, "Could not register clock\n");
-               return PTR_ERR(bus_clk);
+               return PTR_ERR(i2c_dev->bus_clk);
        }
 
        ret = of_property_read_u32(pdev->dev.of_node, "clock-frequency",
@@ -442,13 +442,13 @@ static int bcm2835_i2c_probe(struct platform_device *pdev)
                bus_clk_rate = 100000;
        }
 
-       ret = clk_set_rate_exclusive(bus_clk, bus_clk_rate);
+       ret = clk_set_rate_exclusive(i2c_dev->bus_clk, bus_clk_rate);
        if (ret < 0) {
                dev_err(&pdev->dev, "Could not set clock frequency\n");
                return ret;
        }
 
-       ret = clk_prepare_enable(bus_clk);
+       ret = clk_prepare_enable(i2c_dev->bus_clk);
        if (ret) {
                dev_err(&pdev->dev, "Couldn't prepare clock");
                return ret;
@@ -491,10 +491,9 @@ static int bcm2835_i2c_probe(struct platform_device *pdev)
 static int bcm2835_i2c_remove(struct platform_device *pdev)
 {
        struct bcm2835_i2c_dev *i2c_dev = platform_get_drvdata(pdev);
-       struct clk *bus_clk = devm_clk_get(i2c_dev->dev, "div");
 
-       clk_rate_exclusive_put(bus_clk);
-       clk_disable_unprepare(bus_clk);
+       clk_rate_exclusive_put(i2c_dev->bus_clk);
+       clk_disable_unprepare(i2c_dev->bus_clk);
 
        free_irq(i2c_dev->irq, i2c_dev);
        i2c_del_adapter(&i2c_dev->adapter);
index 3855638..2f8b805 100644 (file)
@@ -433,13 +433,17 @@ iop3xx_i2c_probe(struct platform_device *pdev)
        adapter_data->gpio_scl = devm_gpiod_get_optional(&pdev->dev,
                                                         "scl",
                                                         GPIOD_ASIS);
-       if (IS_ERR(adapter_data->gpio_scl))
-               return PTR_ERR(adapter_data->gpio_scl);
+       if (IS_ERR(adapter_data->gpio_scl)) {
+               ret = PTR_ERR(adapter_data->gpio_scl);
+               goto free_both;
+       }
        adapter_data->gpio_sda = devm_gpiod_get_optional(&pdev->dev,
                                                         "sda",
                                                         GPIOD_ASIS);
-       if (IS_ERR(adapter_data->gpio_sda))
-               return PTR_ERR(adapter_data->gpio_sda);
+       if (IS_ERR(adapter_data->gpio_sda)) {
+               ret = PTR_ERR(adapter_data->gpio_sda);
+               goto free_both;
+       }
 
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        if (!res) {
index a98bf31..61339c6 100644 (file)
@@ -1608,14 +1608,18 @@ static int tegra_i2c_probe(struct platform_device *pdev)
        }
 
        pm_runtime_enable(&pdev->dev);
-       if (!pm_runtime_enabled(&pdev->dev))
+       if (!pm_runtime_enabled(&pdev->dev)) {
                ret = tegra_i2c_runtime_resume(&pdev->dev);
-       else
+               if (ret < 0) {
+                       dev_err(&pdev->dev, "runtime resume failed\n");
+                       goto unprepare_div_clk;
+               }
+       } else {
                ret = pm_runtime_get_sync(i2c_dev->dev);
-
-       if (ret < 0) {
-               dev_err(&pdev->dev, "runtime resume failed\n");
-               goto unprepare_div_clk;
+               if (ret < 0) {
+                       dev_err(&pdev->dev, "runtime resume failed\n");
+                       goto disable_rpm;
+               }
        }
 
        if (i2c_dev->is_multimaster_mode) {
@@ -1623,7 +1627,7 @@ static int tegra_i2c_probe(struct platform_device *pdev)
                if (ret < 0) {
                        dev_err(i2c_dev->dev, "div_clk enable failed %d\n",
                                ret);
-                       goto disable_rpm;
+                       goto put_rpm;
                }
        }
 
@@ -1671,11 +1675,16 @@ disable_div_clk:
        if (i2c_dev->is_multimaster_mode)
                clk_disable(i2c_dev->div_clk);
 
-disable_rpm:
-       pm_runtime_disable(&pdev->dev);
-       if (!pm_runtime_status_suspended(&pdev->dev))
+put_rpm:
+       if (pm_runtime_enabled(&pdev->dev))
+               pm_runtime_put_sync(&pdev->dev);
+       else
                tegra_i2c_runtime_suspend(&pdev->dev);
 
+disable_rpm:
+       if (pm_runtime_enabled(&pdev->dev))
+               pm_runtime_disable(&pdev->dev);
+
 unprepare_div_clk:
        clk_unprepare(i2c_dev->div_clk);
 
@@ -1710,9 +1719,14 @@ static int tegra_i2c_remove(struct platform_device *pdev)
 static int __maybe_unused tegra_i2c_suspend(struct device *dev)
 {
        struct tegra_i2c_dev *i2c_dev = dev_get_drvdata(dev);
+       int err;
 
        i2c_mark_adapter_suspended(&i2c_dev->adapter);
 
+       err = pm_runtime_force_suspend(dev);
+       if (err < 0)
+               return err;
+
        return 0;
 }
 
@@ -1733,6 +1747,10 @@ static int __maybe_unused tegra_i2c_resume(struct device *dev)
        if (err)
                return err;
 
+       err = pm_runtime_force_resume(dev);
+       if (err < 0)
+               return err;
+
        i2c_mark_adapter_resumed(&i2c_dev->adapter);
 
        return 0;
index 9f8dcd3..35b2097 100644 (file)
@@ -186,10 +186,11 @@ int i2c_generic_scl_recovery(struct i2c_adapter *adap)
         * If we can set SDA, we will always create a STOP to ensure additional
         * pulses will do no harm. This is achieved by letting SDA follow SCL
         * half a cycle later. Check the 'incomplete_write_byte' fault injector
-        * for details.
+        * for details. Note that we must honour tsu:sto, 4us, but lets use 5us
+        * here for simplicity.
         */
        bri->set_scl(adap, scl);
-       ndelay(RECOVERY_NDELAY / 2);
+       ndelay(RECOVERY_NDELAY);
        if (bri->set_sda)
                bri->set_sda(adap, scl);
        ndelay(RECOVERY_NDELAY / 2);
@@ -211,7 +212,13 @@ int i2c_generic_scl_recovery(struct i2c_adapter *adap)
                scl = !scl;
                bri->set_scl(adap, scl);
                /* Creating STOP again, see above */
-               ndelay(RECOVERY_NDELAY / 2);
+               if (scl)  {
+                       /* Honour minimum tsu:sto */
+                       ndelay(RECOVERY_NDELAY);
+               } else {
+                       /* Honour minimum tf and thd:dat */
+                       ndelay(RECOVERY_NDELAY / 2);
+               }
                if (bri->set_sda)
                        bri->set_sda(adap, scl);
                ndelay(RECOVERY_NDELAY / 2);
index 3f03abf..306bf15 100644 (file)
@@ -494,13 +494,11 @@ static int ad7124_of_parse_channel_config(struct iio_dev *indio_dev,
                st->channel_config[channel].buf_negative =
                        of_property_read_bool(child, "adi,buffered-negative");
 
-               *chan = ad7124_channel_template;
-               chan->address = channel;
-               chan->scan_index = channel;
-               chan->channel = ain[0];
-               chan->channel2 = ain[1];
-
-               chan++;
+               chan[channel] = ad7124_channel_template;
+               chan[channel].address = channel;
+               chan[channel].scan_index = channel;
+               chan[channel].channel = ain[0];
+               chan[channel].channel2 = ain[1];
        }
 
        return 0;
index fa45860..0b91de4 100644 (file)
@@ -65,6 +65,7 @@ config IAQCORE
 config PMS7003
        tristate "Plantower PMS7003 particulate matter sensor"
        depends on SERIAL_DEV_BUS
+       select IIO_BUFFER
        select IIO_TRIGGERED_BUFFER
        help
          Say Y here to build support for the Plantower PMS7003 particulate
index a7d40c0..b921dd9 100644 (file)
@@ -1301,7 +1301,8 @@ static int st_lsm6dsx_check_whoami(struct st_lsm6dsx_hw *hw, int id,
 
        for (i = 0; i < ARRAY_SIZE(st_lsm6dsx_sensor_settings); i++) {
                for (j = 0; j < ST_LSM6DSX_MAX_ID; j++) {
-                       if (id == st_lsm6dsx_sensor_settings[i].id[j].hw_id)
+                       if (st_lsm6dsx_sensor_settings[i].id[j].name &&
+                           id == st_lsm6dsx_sensor_settings[i].id[j].hw_id)
                                break;
                }
                if (j < ST_LSM6DSX_MAX_ID)
index c193d64..112225c 100644 (file)
@@ -566,7 +566,7 @@ static int iio_compute_scan_bytes(struct iio_dev *indio_dev,
                                const unsigned long *mask, bool timestamp)
 {
        unsigned bytes = 0;
-       int length, i;
+       int length, i, largest = 0;
 
        /* How much space will the demuxed element take? */
        for_each_set_bit(i, mask,
@@ -574,13 +574,17 @@ static int iio_compute_scan_bytes(struct iio_dev *indio_dev,
                length = iio_storage_bytes_for_si(indio_dev, i);
                bytes = ALIGN(bytes, length);
                bytes += length;
+               largest = max(largest, length);
        }
 
        if (timestamp) {
                length = iio_storage_bytes_for_timestamp(indio_dev);
                bytes = ALIGN(bytes, length);
                bytes += length;
+               largest = max(largest, length);
        }
+
+       bytes = ALIGN(bytes, largest);
        return bytes;
 }
 
index 16dacea..b0e241a 100644 (file)
@@ -163,7 +163,6 @@ static int vcnl4200_init(struct vcnl4000_data *data)
        if (ret < 0)
                return ret;
 
-       data->al_scale = 24000;
        data->vcnl4200_al.reg = VCNL4200_AL_DATA;
        data->vcnl4200_ps.reg = VCNL4200_PS_DATA;
        switch (id) {
@@ -172,11 +171,13 @@ static int vcnl4200_init(struct vcnl4000_data *data)
                /* show 54ms in total. */
                data->vcnl4200_al.sampling_rate = ktime_set(0, 54000 * 1000);
                data->vcnl4200_ps.sampling_rate = ktime_set(0, 4200 * 1000);
+               data->al_scale = 24000;
                break;
        case VCNL4040_PROD_ID:
                /* Integration time is 80ms, add 10ms. */
                data->vcnl4200_al.sampling_rate = ktime_set(0, 100000 * 1000);
                data->vcnl4200_ps.sampling_rate = ktime_set(0, 100000 * 1000);
+               data->al_scale = 120000;
                break;
        }
        data->vcnl4200_al.last_measurement = ktime_set(0, 0);
index 9b6ca15..ad5112a 100644 (file)
@@ -3305,8 +3305,10 @@ int bnxt_re_dereg_mr(struct ib_mr *ib_mr, struct ib_udata *udata)
        int rc;
 
        rc = bnxt_qplib_free_mrw(&rdev->qplib_res, &mr->qplib_mr);
-       if (rc)
+       if (rc) {
                dev_err(rdev_to_dev(rdev), "Dereg MR failed: %#x\n", rc);
+               return rc;
+       }
 
        if (mr->pages) {
                rc = bnxt_qplib_free_fast_reg_page_list(&rdev->qplib_res,
index 958c1ff..4d07d22 100644 (file)
@@ -2283,13 +2283,13 @@ static int bnxt_qplib_cq_process_req(struct bnxt_qplib_cq *cq,
                        /* Add qp to flush list of the CQ */
                        bnxt_qplib_add_flush_qp(qp);
                } else {
+                       /* Before we complete, do WA 9060 */
+                       if (do_wa9060(qp, cq, cq_cons, sw_sq_cons,
+                                     cqe_sq_cons)) {
+                               *lib_qp = qp;
+                               goto out;
+                       }
                        if (swq->flags & SQ_SEND_FLAGS_SIGNAL_COMP) {
-                               /* Before we complete, do WA 9060 */
-                               if (do_wa9060(qp, cq, cq_cons, sw_sq_cons,
-                                             cqe_sq_cons)) {
-                                       *lib_qp = qp;
-                                       goto out;
-                               }
                                cqe->status = CQ_REQ_STATUS_OK;
                                cqe++;
                                (*budget)--;
index adb4a1b..5836fe7 100644 (file)
@@ -81,7 +81,9 @@ void iowait_init(struct iowait *wait, u32 tx_limit,
 void iowait_cancel_work(struct iowait *w)
 {
        cancel_work_sync(&iowait_get_ib_work(w)->iowork);
-       cancel_work_sync(&iowait_get_tid_work(w)->iowork);
+       /* Make sure that the iowork for TID RDMA is used */
+       if (iowait_get_tid_work(w)->iowork.func)
+               cancel_work_sync(&iowait_get_tid_work(w)->iowork);
 }
 
 /**
index e53f542..8a2e0d9 100644 (file)
@@ -4633,6 +4633,15 @@ void hfi1_rc_rcv_tid_rdma_ack(struct hfi1_packet *packet)
                         */
                        fpsn = full_flow_psn(flow, flow->flow_state.spsn);
                        req->r_ack_psn = psn;
+                       /*
+                        * If resync_psn points to the last flow PSN for a
+                        * segment and the new segment (likely from a new
+                        * request) starts with a new generation number, we
+                        * need to adjust resync_psn accordingly.
+                        */
+                       if (flow->flow_state.generation !=
+                           (resync_psn >> HFI1_KDETH_BTH_SEQ_SHIFT))
+                               resync_psn = mask_psn(fpsn - 1);
                        flow->resync_npkts +=
                                delta_psn(mask_psn(resync_psn + 1), fpsn);
                        /*
index 8637594..dbd96d0 100644 (file)
@@ -169,8 +169,7 @@ static void i40iw_dealloc_ucontext(struct ib_ucontext *context)
 static int i40iw_mmap(struct ib_ucontext *context, struct vm_area_struct *vma)
 {
        struct i40iw_ucontext *ucontext;
-       u64 db_addr_offset;
-       u64 push_offset;
+       u64 db_addr_offset, push_offset, pfn;
 
        ucontext = to_ucontext(context);
        if (ucontext->iwdev->sc_dev.is_pf) {
@@ -189,7 +188,6 @@ static int i40iw_mmap(struct ib_ucontext *context, struct vm_area_struct *vma)
 
        if (vma->vm_pgoff == (db_addr_offset >> PAGE_SHIFT)) {
                vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
-               vma->vm_private_data = ucontext;
        } else {
                if ((vma->vm_pgoff - (push_offset >> PAGE_SHIFT)) % 2)
                        vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
@@ -197,12 +195,12 @@ static int i40iw_mmap(struct ib_ucontext *context, struct vm_area_struct *vma)
                        vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
        }
 
-       if (io_remap_pfn_range(vma, vma->vm_start,
-                              vma->vm_pgoff + (pci_resource_start(ucontext->iwdev->ldev->pcidev, 0) >> PAGE_SHIFT),
-                              PAGE_SIZE, vma->vm_page_prot))
-               return -EAGAIN;
+       pfn = vma->vm_pgoff +
+             (pci_resource_start(ucontext->iwdev->ldev->pcidev, 0) >>
+              PAGE_SHIFT);
 
-       return 0;
+       return rdma_user_mmap_io(context, vma, pfn, PAGE_SIZE,
+                                vma->vm_page_prot, NULL);
 }
 
 /**
index d7dd6fc..f918fca 100644 (file)
@@ -224,13 +224,13 @@ static void __pass_event(struct evdev_client *client,
                 */
                client->tail = (client->head - 2) & (client->bufsize - 1);
 
-               client->buffer[client->tail].input_event_sec =
-                                               event->input_event_sec;
-               client->buffer[client->tail].input_event_usec =
-                                               event->input_event_usec;
-               client->buffer[client->tail].type = EV_SYN;
-               client->buffer[client->tail].code = SYN_DROPPED;
-               client->buffer[client->tail].value = 0;
+               client->buffer[client->tail] = (struct input_event) {
+                       .input_event_sec = event->input_event_sec,
+                       .input_event_usec = event->input_event_usec,
+                       .type = EV_SYN,
+                       .code = SYN_DROPPED,
+                       .value = 0,
+               };
 
                client->packet_head = client->tail;
        }
index 5508627..ee6c323 100644 (file)
@@ -878,16 +878,18 @@ static int input_default_setkeycode(struct input_dev *dev,
                }
        }
 
-       __clear_bit(*old_keycode, dev->keybit);
-       __set_bit(ke->keycode, dev->keybit);
-
-       for (i = 0; i < dev->keycodemax; i++) {
-               if (input_fetch_keycode(dev, i) == *old_keycode) {
-                       __set_bit(*old_keycode, dev->keybit);
-                       break; /* Setting the bit twice is useless, so break */
+       if (*old_keycode <= KEY_MAX) {
+               __clear_bit(*old_keycode, dev->keybit);
+               for (i = 0; i < dev->keycodemax; i++) {
+                       if (input_fetch_keycode(dev, i) == *old_keycode) {
+                               __set_bit(*old_keycode, dev->keybit);
+                               /* Setting the bit twice is useless, so break */
+                               break;
+                       }
                }
        }
 
+       __set_bit(ke->keycode, dev->keybit);
        return 0;
 }
 
@@ -943,9 +945,13 @@ int input_set_keycode(struct input_dev *dev,
         * Simulate keyup event if keycode is not present
         * in the keymap anymore
         */
-       if (test_bit(EV_KEY, dev->evbit) &&
-           !is_event_supported(old_keycode, dev->keybit, KEY_MAX) &&
-           __test_and_clear_bit(old_keycode, dev->key)) {
+       if (old_keycode > KEY_MAX) {
+               dev_warn(dev->dev.parent ?: &dev->dev,
+                        "%s: got too big old keycode %#x\n",
+                        __func__, old_keycode);
+       } else if (test_bit(EV_KEY, dev->evbit) &&
+                  !is_event_supported(old_keycode, dev->keybit, KEY_MAX) &&
+                  __test_and_clear_bit(old_keycode, dev->key)) {
                struct input_value vals[] =  {
                        { EV_KEY, old_keycode, 0 },
                        input_value_sync
index 5379952..9f809ae 100644 (file)
@@ -78,7 +78,13 @@ static void imx_sc_check_for_events(struct work_struct *work)
                return;
        }
 
-       state = (bool)msg.state;
+       /*
+        * The response data from SCU firmware is 4 bytes,
+        * but ONLY the first byte is the key state, other
+        * 3 bytes could be some dirty data, so we should
+        * ONLY take the first byte as key state.
+        */
+       state = (bool)(msg.state & 0xff);
 
        if (state ^ priv->keystate) {
                priv->keystate = state;
index fd25378..f259313 100644 (file)
@@ -74,12 +74,16 @@ static int uinput_dev_event(struct input_dev *dev,
        struct uinput_device    *udev = input_get_drvdata(dev);
        struct timespec64       ts;
 
-       udev->buff[udev->head].type = type;
-       udev->buff[udev->head].code = code;
-       udev->buff[udev->head].value = value;
        ktime_get_ts64(&ts);
-       udev->buff[udev->head].input_event_sec = ts.tv_sec;
-       udev->buff[udev->head].input_event_usec = ts.tv_nsec / NSEC_PER_USEC;
+
+       udev->buff[udev->head] = (struct input_event) {
+               .input_event_sec = ts.tv_sec,
+               .input_event_usec = ts.tv_nsec / NSEC_PER_USEC,
+               .type = type,
+               .code = code,
+               .value = value,
+       };
+
        udev->head = (udev->head + 1) % UINPUT_BUFFER_SIZE;
 
        wake_up_interruptible(&udev->waitq);
@@ -689,13 +693,14 @@ static ssize_t uinput_read(struct file *file, char __user *buffer,
 static __poll_t uinput_poll(struct file *file, poll_table *wait)
 {
        struct uinput_device *udev = file->private_data;
+       __poll_t mask = EPOLLOUT | EPOLLWRNORM; /* uinput is always writable */
 
        poll_wait(file, &udev->waitq, wait);
 
        if (udev->head != udev->tail)
-               return EPOLLIN | EPOLLRDNORM;
+               mask |= EPOLLIN | EPOLLRDNORM;
 
-       return EPOLLOUT | EPOLLWRNORM;
+       return mask;
 }
 
 static int uinput_release(struct inode *inode, struct file *file)
index c363294..a2e96a5 100644 (file)
@@ -1203,7 +1203,6 @@ int iommu_dma_prepare_msi(struct msi_desc *desc, phys_addr_t msi_addr)
 {
        struct device *dev = msi_desc_to_dev(desc);
        struct iommu_domain *domain = iommu_get_domain_for_dev(dev);
-       struct iommu_dma_cookie *cookie;
        struct iommu_dma_msi_page *msi_page;
        static DEFINE_MUTEX(msi_prepare_lock); /* see below */
 
@@ -1212,8 +1211,6 @@ int iommu_dma_prepare_msi(struct msi_desc *desc, phys_addr_t msi_addr)
                return 0;
        }
 
-       cookie = domain->iova_cookie;
-
        /*
         * In fact the whole prepare operation should already be serialised by
         * irq_domain_mutex further up the callchain, but that's pretty subtle
index 4296661..1801f0a 100644 (file)
@@ -5624,8 +5624,10 @@ static int intel_iommu_add_device(struct device *dev)
 
        group = iommu_group_get_for_dev(dev);
 
-       if (IS_ERR(group))
-               return PTR_ERR(group);
+       if (IS_ERR(group)) {
+               ret = PTR_ERR(group);
+               goto unlink;
+       }
 
        iommu_group_put(group);
 
@@ -5651,7 +5653,8 @@ static int intel_iommu_add_device(struct device *dev)
                                if (!get_private_domain_for_dev(dev)) {
                                        dev_warn(dev,
                                                 "Failed to get a private domain.\n");
-                                       return -ENOMEM;
+                                       ret = -ENOMEM;
+                                       goto unlink;
                                }
 
                                dev_info(dev,
@@ -5666,6 +5669,10 @@ static int intel_iommu_add_device(struct device *dev)
        }
 
        return 0;
+
+unlink:
+       iommu_device_unlink(&iommu->iommu, dev);
+       return ret;
 }
 
 static void intel_iommu_remove_device(struct device *dev)
@@ -5817,6 +5824,13 @@ static void intel_iommu_apply_resv_region(struct device *dev,
        WARN_ON_ONCE(!reserve_iova(&dmar_domain->iovad, start, end));
 }
 
+static struct iommu_group *intel_iommu_device_group(struct device *dev)
+{
+       if (dev_is_pci(dev))
+               return pci_device_group(dev);
+       return generic_device_group(dev);
+}
+
 #ifdef CONFIG_INTEL_IOMMU_SVM
 struct intel_iommu *intel_svm_device_to_iommu(struct device *dev)
 {
@@ -5989,7 +6003,7 @@ const struct iommu_ops intel_iommu_ops = {
        .get_resv_regions       = intel_iommu_get_resv_regions,
        .put_resv_regions       = intel_iommu_put_resv_regions,
        .apply_resv_region      = intel_iommu_apply_resv_region,
-       .device_group           = pci_device_group,
+       .device_group           = intel_iommu_device_group,
        .dev_has_feat           = intel_iommu_dev_has_feat,
        .dev_feat_enabled       = intel_iommu_dev_feat_enabled,
        .dev_enable_feat        = intel_iommu_dev_enable_feat,
index fdd4075..3ead597 100644 (file)
@@ -751,6 +751,7 @@ err_put_group:
        mutex_unlock(&group->mutex);
        dev->iommu_group = NULL;
        kobject_put(group->devices_kobj);
+       sysfs_remove_link(group->devices_kobj, device->name);
 err_free_name:
        kfree(device->name);
 err_remove_link:
index 01d18b3..c5589ee 100644 (file)
@@ -17,7 +17,6 @@
 #include <linux/delay.h>
 
 #include <asm/io.h>
-#include <asm/mach-jz4740/irq.h>
 
 struct ingenic_intc_data {
        void __iomem *base;
@@ -50,7 +49,7 @@ static irqreturn_t intc_cascade(int irq, void *data)
                while (pending) {
                        int bit = __fls(pending);
 
-                       irq = irq_find_mapping(domain, bit + (i * 32));
+                       irq = irq_linear_revmap(domain, bit + (i * 32));
                        generic_handle_irq(irq);
                        pending &= ~BIT(bit);
                }
@@ -97,8 +96,7 @@ static int __init ingenic_intc_of_init(struct device_node *node,
                goto out_unmap_irq;
        }
 
-       domain = irq_domain_add_legacy(node, num_chips * 32,
-                                      JZ4740_IRQ_BASE, 0,
+       domain = irq_domain_add_linear(node, num_chips * 32,
                                       &irq_generic_chip_ops, NULL);
        if (!domain) {
                err = -ENOMEM;
index 3c50c4e..963d377 100644 (file)
@@ -17,7 +17,7 @@
 #include <linux/dm-bufio.h>
 
 #define DM_MSG_PREFIX "persistent snapshot"
-#define DM_CHUNK_SIZE_DEFAULT_SECTORS 32       /* 16KB */
+#define DM_CHUNK_SIZE_DEFAULT_SECTORS 32U      /* 16KB */
 
 #define DM_PREFETCH_CHUNKS             12
 
index b7c2097..322386f 100644 (file)
@@ -87,7 +87,7 @@ static int create_strip_zones(struct mddev *mddev, struct r0conf **private_conf)
        char b[BDEVNAME_SIZE];
        char b2[BDEVNAME_SIZE];
        struct r0conf *conf = kzalloc(sizeof(*conf), GFP_KERNEL);
-       unsigned short blksize = 512;
+       unsigned blksize = 512;
 
        *private_conf = ERR_PTR(-ENOMEM);
        if (!conf)
index f9ac224..1074b88 100644 (file)
@@ -100,19 +100,19 @@ struct buflist {
  * Function prototypes. Called from OS entry point mptctl_ioctl.
  * arg contents specific to function.
  */
-static int mptctl_fw_download(unsigned long arg);
-static int mptctl_getiocinfo(unsigned long arg, unsigned int cmd);
-static int mptctl_gettargetinfo(unsigned long arg);
-static int mptctl_readtest(unsigned long arg);
-static int mptctl_mpt_command(unsigned long arg);
-static int mptctl_eventquery(unsigned long arg);
-static int mptctl_eventenable(unsigned long arg);
-static int mptctl_eventreport(unsigned long arg);
-static int mptctl_replace_fw(unsigned long arg);
-
-static int mptctl_do_reset(unsigned long arg);
-static int mptctl_hp_hostinfo(unsigned long arg, unsigned int cmd);
-static int mptctl_hp_targetinfo(unsigned long arg);
+static int mptctl_fw_download(MPT_ADAPTER *iocp, unsigned long arg);
+static int mptctl_getiocinfo(MPT_ADAPTER *iocp, unsigned long arg, unsigned int cmd);
+static int mptctl_gettargetinfo(MPT_ADAPTER *iocp, unsigned long arg);
+static int mptctl_readtest(MPT_ADAPTER *iocp, unsigned long arg);
+static int mptctl_mpt_command(MPT_ADAPTER *iocp, unsigned long arg);
+static int mptctl_eventquery(MPT_ADAPTER *iocp, unsigned long arg);
+static int mptctl_eventenable(MPT_ADAPTER *iocp, unsigned long arg);
+static int mptctl_eventreport(MPT_ADAPTER *iocp, unsigned long arg);
+static int mptctl_replace_fw(MPT_ADAPTER *iocp, unsigned long arg);
+
+static int mptctl_do_reset(MPT_ADAPTER *iocp, unsigned long arg);
+static int mptctl_hp_hostinfo(MPT_ADAPTER *iocp, unsigned long arg, unsigned int cmd);
+static int mptctl_hp_targetinfo(MPT_ADAPTER *iocp, unsigned long arg);
 
 static int  mptctl_probe(struct pci_dev *, const struct pci_device_id *);
 static void mptctl_remove(struct pci_dev *);
@@ -123,8 +123,8 @@ static long compat_mpctl_ioctl(struct file *f, unsigned cmd, unsigned long arg);
 /*
  * Private function calls.
  */
-static int mptctl_do_mpt_command(struct mpt_ioctl_command karg, void __user *mfPtr);
-static int mptctl_do_fw_download(int ioc, char __user *ufwbuf, size_t fwlen);
+static int mptctl_do_mpt_command(MPT_ADAPTER *iocp, struct mpt_ioctl_command karg, void __user *mfPtr);
+static int mptctl_do_fw_download(MPT_ADAPTER *iocp, char __user *ufwbuf, size_t fwlen);
 static MptSge_t *kbuf_alloc_2_sgl(int bytes, u32 dir, int sge_offset, int *frags,
                struct buflist **blp, dma_addr_t *sglbuf_dma, MPT_ADAPTER *ioc);
 static void kfree_sgl(MptSge_t *sgl, dma_addr_t sgl_dma,
@@ -656,19 +656,19 @@ __mptctl_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
         * by TM and FW reloads.
         */
        if ((cmd & ~IOCSIZE_MASK) == (MPTIOCINFO & ~IOCSIZE_MASK)) {
-               return mptctl_getiocinfo(arg, _IOC_SIZE(cmd));
+               return mptctl_getiocinfo(iocp, arg, _IOC_SIZE(cmd));
        } else if (cmd == MPTTARGETINFO) {
-               return mptctl_gettargetinfo(arg);
+               return mptctl_gettargetinfo(iocp, arg);
        } else if (cmd == MPTTEST) {
-               return mptctl_readtest(arg);
+               return mptctl_readtest(iocp, arg);
        } else if (cmd == MPTEVENTQUERY) {
-               return mptctl_eventquery(arg);
+               return mptctl_eventquery(iocp, arg);
        } else if (cmd == MPTEVENTENABLE) {
-               return mptctl_eventenable(arg);
+               return mptctl_eventenable(iocp, arg);
        } else if (cmd == MPTEVENTREPORT) {
-               return mptctl_eventreport(arg);
+               return mptctl_eventreport(iocp, arg);
        } else if (cmd == MPTFWREPLACE) {
-               return mptctl_replace_fw(arg);
+               return mptctl_replace_fw(iocp, arg);
        }
 
        /* All of these commands require an interrupt or
@@ -678,15 +678,15 @@ __mptctl_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
                return ret;
 
        if (cmd == MPTFWDOWNLOAD)
-               ret = mptctl_fw_download(arg);
+               ret = mptctl_fw_download(iocp, arg);
        else if (cmd == MPTCOMMAND)
-               ret = mptctl_mpt_command(arg);
+               ret = mptctl_mpt_command(iocp, arg);
        else if (cmd == MPTHARDRESET)
-               ret = mptctl_do_reset(arg);
+               ret = mptctl_do_reset(iocp, arg);
        else if ((cmd & ~IOCSIZE_MASK) == (HP_GETHOSTINFO & ~IOCSIZE_MASK))
-               ret = mptctl_hp_hostinfo(arg, _IOC_SIZE(cmd));
+               ret = mptctl_hp_hostinfo(iocp, arg, _IOC_SIZE(cmd));
        else if (cmd == HP_GETTARGETINFO)
-               ret = mptctl_hp_targetinfo(arg);
+               ret = mptctl_hp_targetinfo(iocp, arg);
        else
                ret = -EINVAL;
 
@@ -705,11 +705,10 @@ mptctl_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
        return ret;
 }
 
-static int mptctl_do_reset(unsigned long arg)
+static int mptctl_do_reset(MPT_ADAPTER *iocp, unsigned long arg)
 {
        struct mpt_ioctl_diag_reset __user *urinfo = (void __user *) arg;
        struct mpt_ioctl_diag_reset krinfo;
-       MPT_ADAPTER             *iocp;
 
        if (copy_from_user(&krinfo, urinfo, sizeof(struct mpt_ioctl_diag_reset))) {
                printk(KERN_ERR MYNAM "%s@%d::mptctl_do_reset - "
@@ -718,12 +717,6 @@ static int mptctl_do_reset(unsigned long arg)
                return -EFAULT;
        }
 
-       if (mpt_verify_adapter(krinfo.hdr.iocnum, &iocp) < 0) {
-               printk(KERN_DEBUG MYNAM "%s@%d::mptctl_do_reset - ioc%d not found!\n",
-                               __FILE__, __LINE__, krinfo.hdr.iocnum);
-               return -ENODEV; /* (-6) No such device or address */
-       }
-
        dctlprintk(iocp, printk(MYIOC_s_DEBUG_FMT "mptctl_do_reset called.\n",
            iocp->name));
 
@@ -754,7 +747,7 @@ static int mptctl_do_reset(unsigned long arg)
  *             -ENOMSG if FW upload returned bad status
  */
 static int
-mptctl_fw_download(unsigned long arg)
+mptctl_fw_download(MPT_ADAPTER *iocp, unsigned long arg)
 {
        struct mpt_fw_xfer __user *ufwdl = (void __user *) arg;
        struct mpt_fw_xfer       kfwdl;
@@ -766,7 +759,7 @@ mptctl_fw_download(unsigned long arg)
                return -EFAULT;
        }
 
-       return mptctl_do_fw_download(kfwdl.iocnum, kfwdl.bufp, kfwdl.fwlen);
+       return mptctl_do_fw_download(iocp, kfwdl.bufp, kfwdl.fwlen);
 }
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -784,11 +777,10 @@ mptctl_fw_download(unsigned long arg)
  *             -ENOMSG if FW upload returned bad status
  */
 static int
-mptctl_do_fw_download(int ioc, char __user *ufwbuf, size_t fwlen)
+mptctl_do_fw_download(MPT_ADAPTER *iocp, char __user *ufwbuf, size_t fwlen)
 {
        FWDownload_t            *dlmsg;
        MPT_FRAME_HDR           *mf;
-       MPT_ADAPTER             *iocp;
        FWDownloadTCSGE_t       *ptsge;
        MptSge_t                *sgl, *sgIn;
        char                    *sgOut;
@@ -808,17 +800,10 @@ mptctl_do_fw_download(int ioc, char __user *ufwbuf, size_t fwlen)
        pFWDownloadReply_t       ReplyMsg = NULL;
        unsigned long            timeleft;
 
-       if (mpt_verify_adapter(ioc, &iocp) < 0) {
-               printk(KERN_DEBUG MYNAM "ioctl_fwdl - ioc%d not found!\n",
-                                ioc);
-               return -ENODEV; /* (-6) No such device or address */
-       } else {
-
-               /*  Valid device. Get a message frame and construct the FW download message.
-               */
-               if ((mf = mpt_get_msg_frame(mptctl_id, iocp)) == NULL)
-                       return -EAGAIN;
-       }
+       /*  Valid device. Get a message frame and construct the FW download message.
+       */
+       if ((mf = mpt_get_msg_frame(mptctl_id, iocp)) == NULL)
+               return -EAGAIN;
 
        dctlprintk(iocp, printk(MYIOC_s_DEBUG_FMT
            "mptctl_do_fwdl called. mptctl_id = %xh.\n", iocp->name, mptctl_id));
@@ -826,8 +811,6 @@ mptctl_do_fw_download(int ioc, char __user *ufwbuf, size_t fwlen)
            iocp->name, ufwbuf));
        dctlprintk(iocp, printk(MYIOC_s_DEBUG_FMT "DbG: kfwdl.fwlen = %d\n",
            iocp->name, (int)fwlen));
-       dctlprintk(iocp, printk(MYIOC_s_DEBUG_FMT "DbG: kfwdl.ioc   = %04xh\n",
-           iocp->name, ioc));
 
        dlmsg = (FWDownload_t*) mf;
        ptsge = (FWDownloadTCSGE_t *) &dlmsg->SGL;
@@ -1238,13 +1221,11 @@ kfree_sgl(MptSge_t *sgl, dma_addr_t sgl_dma, struct buflist *buflist, MPT_ADAPTE
  *             -ENODEV  if no such device/adapter
  */
 static int
-mptctl_getiocinfo (unsigned long arg, unsigned int data_size)
+mptctl_getiocinfo (MPT_ADAPTER *ioc, unsigned long arg, unsigned int data_size)
 {
        struct mpt_ioctl_iocinfo __user *uarg = (void __user *) arg;
        struct mpt_ioctl_iocinfo *karg;
-       MPT_ADAPTER             *ioc;
        struct pci_dev          *pdev;
-       int                     iocnum;
        unsigned int            port;
        int                     cim_rev;
        struct scsi_device      *sdev;
@@ -1272,14 +1253,6 @@ mptctl_getiocinfo (unsigned long arg, unsigned int data_size)
                return PTR_ERR(karg);
        }
 
-       if (((iocnum = mpt_verify_adapter(karg->hdr.iocnum, &ioc)) < 0) ||
-           (ioc == NULL)) {
-               printk(KERN_DEBUG MYNAM "%s::mptctl_getiocinfo() @%d - ioc%d not found!\n",
-                               __FILE__, __LINE__, iocnum);
-               kfree(karg);
-               return -ENODEV;
-       }
-
        /* Verify the data transfer size is correct. */
        if (karg->hdr.maxDataSize != data_size) {
                printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_getiocinfo - "
@@ -1385,15 +1358,13 @@ mptctl_getiocinfo (unsigned long arg, unsigned int data_size)
  *             -ENODEV  if no such device/adapter
  */
 static int
-mptctl_gettargetinfo (unsigned long arg)
+mptctl_gettargetinfo (MPT_ADAPTER *ioc, unsigned long arg)
 {
        struct mpt_ioctl_targetinfo __user *uarg = (void __user *) arg;
        struct mpt_ioctl_targetinfo karg;
-       MPT_ADAPTER             *ioc;
        VirtDevice              *vdevice;
        char                    *pmem;
        int                     *pdata;
-       int                     iocnum;
        int                     numDevices = 0;
        int                     lun;
        int                     maxWordsLeft;
@@ -1408,13 +1379,6 @@ mptctl_gettargetinfo (unsigned long arg)
                return -EFAULT;
        }
 
-       if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
-           (ioc == NULL)) {
-               printk(KERN_DEBUG MYNAM "%s::mptctl_gettargetinfo() @%d - ioc%d not found!\n",
-                               __FILE__, __LINE__, iocnum);
-               return -ENODEV;
-       }
-
        dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mptctl_gettargetinfo called.\n",
            ioc->name));
        /* Get the port number and set the maximum number of bytes
@@ -1510,12 +1474,10 @@ mptctl_gettargetinfo (unsigned long arg)
  *             -ENODEV  if no such device/adapter
  */
 static int
-mptctl_readtest (unsigned long arg)
+mptctl_readtest (MPT_ADAPTER *ioc, unsigned long arg)
 {
        struct mpt_ioctl_test __user *uarg = (void __user *) arg;
        struct mpt_ioctl_test    karg;
-       MPT_ADAPTER *ioc;
-       int iocnum;
 
        if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_test))) {
                printk(KERN_ERR MYNAM "%s@%d::mptctl_readtest - "
@@ -1524,13 +1486,6 @@ mptctl_readtest (unsigned long arg)
                return -EFAULT;
        }
 
-       if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
-           (ioc == NULL)) {
-               printk(KERN_DEBUG MYNAM "%s::mptctl_readtest() @%d - ioc%d not found!\n",
-                               __FILE__, __LINE__, iocnum);
-               return -ENODEV;
-       }
-
        dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mptctl_readtest called.\n",
            ioc->name));
        /* Fill in the data and return the structure to the calling
@@ -1571,12 +1526,10 @@ mptctl_readtest (unsigned long arg)
  *             -ENODEV  if no such device/adapter
  */
 static int
-mptctl_eventquery (unsigned long arg)
+mptctl_eventquery (MPT_ADAPTER *ioc, unsigned long arg)
 {
        struct mpt_ioctl_eventquery __user *uarg = (void __user *) arg;
        struct mpt_ioctl_eventquery      karg;
-       MPT_ADAPTER *ioc;
-       int iocnum;
 
        if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_eventquery))) {
                printk(KERN_ERR MYNAM "%s@%d::mptctl_eventquery - "
@@ -1585,13 +1538,6 @@ mptctl_eventquery (unsigned long arg)
                return -EFAULT;
        }
 
-       if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
-           (ioc == NULL)) {
-               printk(KERN_DEBUG MYNAM "%s::mptctl_eventquery() @%d - ioc%d not found!\n",
-                               __FILE__, __LINE__, iocnum);
-               return -ENODEV;
-       }
-
        dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mptctl_eventquery called.\n",
            ioc->name));
        karg.eventEntries = MPTCTL_EVENT_LOG_SIZE;
@@ -1610,12 +1556,10 @@ mptctl_eventquery (unsigned long arg)
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 static int
-mptctl_eventenable (unsigned long arg)
+mptctl_eventenable (MPT_ADAPTER *ioc, unsigned long arg)
 {
        struct mpt_ioctl_eventenable __user *uarg = (void __user *) arg;
        struct mpt_ioctl_eventenable     karg;
-       MPT_ADAPTER *ioc;
-       int iocnum;
 
        if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_eventenable))) {
                printk(KERN_ERR MYNAM "%s@%d::mptctl_eventenable - "
@@ -1624,13 +1568,6 @@ mptctl_eventenable (unsigned long arg)
                return -EFAULT;
        }
 
-       if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
-           (ioc == NULL)) {
-               printk(KERN_DEBUG MYNAM "%s::mptctl_eventenable() @%d - ioc%d not found!\n",
-                               __FILE__, __LINE__, iocnum);
-               return -ENODEV;
-       }
-
        dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mptctl_eventenable called.\n",
            ioc->name));
        if (ioc->events == NULL) {
@@ -1658,12 +1595,10 @@ mptctl_eventenable (unsigned long arg)
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 static int
-mptctl_eventreport (unsigned long arg)
+mptctl_eventreport (MPT_ADAPTER *ioc, unsigned long arg)
 {
        struct mpt_ioctl_eventreport __user *uarg = (void __user *) arg;
        struct mpt_ioctl_eventreport     karg;
-       MPT_ADAPTER              *ioc;
-       int                      iocnum;
        int                      numBytes, maxEvents, max;
 
        if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_eventreport))) {
@@ -1673,12 +1608,6 @@ mptctl_eventreport (unsigned long arg)
                return -EFAULT;
        }
 
-       if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
-           (ioc == NULL)) {
-               printk(KERN_DEBUG MYNAM "%s::mptctl_eventreport() @%d - ioc%d not found!\n",
-                               __FILE__, __LINE__, iocnum);
-               return -ENODEV;
-       }
        dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mptctl_eventreport called.\n",
            ioc->name));
 
@@ -1712,12 +1641,10 @@ mptctl_eventreport (unsigned long arg)
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 static int
-mptctl_replace_fw (unsigned long arg)
+mptctl_replace_fw (MPT_ADAPTER *ioc, unsigned long arg)
 {
        struct mpt_ioctl_replace_fw __user *uarg = (void __user *) arg;
        struct mpt_ioctl_replace_fw      karg;
-       MPT_ADAPTER              *ioc;
-       int                      iocnum;
        int                      newFwSize;
 
        if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_replace_fw))) {
@@ -1727,13 +1654,6 @@ mptctl_replace_fw (unsigned long arg)
                return -EFAULT;
        }
 
-       if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
-           (ioc == NULL)) {
-               printk(KERN_DEBUG MYNAM "%s::mptctl_replace_fw() @%d - ioc%d not found!\n",
-                               __FILE__, __LINE__, iocnum);
-               return -ENODEV;
-       }
-
        dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mptctl_replace_fw called.\n",
            ioc->name));
        /* If caching FW, Free the old FW image
@@ -1780,12 +1700,10 @@ mptctl_replace_fw (unsigned long arg)
  *             -ENOMEM if memory allocation error
  */
 static int
-mptctl_mpt_command (unsigned long arg)
+mptctl_mpt_command (MPT_ADAPTER *ioc, unsigned long arg)
 {
        struct mpt_ioctl_command __user *uarg = (void __user *) arg;
        struct mpt_ioctl_command  karg;
-       MPT_ADAPTER     *ioc;
-       int             iocnum;
        int             rc;
 
 
@@ -1796,14 +1714,7 @@ mptctl_mpt_command (unsigned long arg)
                return -EFAULT;
        }
 
-       if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
-           (ioc == NULL)) {
-               printk(KERN_DEBUG MYNAM "%s::mptctl_mpt_command() @%d - ioc%d not found!\n",
-                               __FILE__, __LINE__, iocnum);
-               return -ENODEV;
-       }
-
-       rc = mptctl_do_mpt_command (karg, &uarg->MF);
+       rc = mptctl_do_mpt_command (ioc, karg, &uarg->MF);
 
        return rc;
 }
@@ -1821,9 +1732,8 @@ mptctl_mpt_command (unsigned long arg)
  *             -EPERM if SCSI I/O and target is untagged
  */
 static int
-mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr)
+mptctl_do_mpt_command (MPT_ADAPTER *ioc, struct mpt_ioctl_command karg, void __user *mfPtr)
 {
-       MPT_ADAPTER     *ioc;
        MPT_FRAME_HDR   *mf = NULL;
        MPIHeader_t     *hdr;
        char            *psge;
@@ -1832,7 +1742,7 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr)
        dma_addr_t      dma_addr_in;
        dma_addr_t      dma_addr_out;
        int             sgSize = 0;     /* Num SG elements */
-       int             iocnum, flagsLength;
+       int             flagsLength;
        int             sz, rc = 0;
        int             msgContext;
        u16             req_idx;
@@ -1847,13 +1757,6 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr)
        bufIn.kptr = bufOut.kptr = NULL;
        bufIn.len = bufOut.len = 0;
 
-       if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
-           (ioc == NULL)) {
-               printk(KERN_DEBUG MYNAM "%s::mptctl_do_mpt_command() @%d - ioc%d not found!\n",
-                               __FILE__, __LINE__, iocnum);
-               return -ENODEV;
-       }
-
        spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
        if (ioc->ioc_reset_in_progress) {
                spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
@@ -2418,17 +2321,15 @@ done_free_mem:
  *             -ENOMEM if memory allocation error
  */
 static int
-mptctl_hp_hostinfo(unsigned long arg, unsigned int data_size)
+mptctl_hp_hostinfo(MPT_ADAPTER *ioc, unsigned long arg, unsigned int data_size)
 {
        hp_host_info_t  __user *uarg = (void __user *) arg;
-       MPT_ADAPTER             *ioc;
        struct pci_dev          *pdev;
        char                    *pbuf=NULL;
        dma_addr_t              buf_dma;
        hp_host_info_t          karg;
        CONFIGPARMS             cfg;
        ConfigPageHeader_t      hdr;
-       int                     iocnum;
        int                     rc, cim_rev;
        ToolboxIstwiReadWriteRequest_t  *IstwiRWRequest;
        MPT_FRAME_HDR           *mf = NULL;
@@ -2452,12 +2353,6 @@ mptctl_hp_hostinfo(unsigned long arg, unsigned int data_size)
                return -EFAULT;
        }
 
-       if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
-           (ioc == NULL)) {
-               printk(KERN_DEBUG MYNAM "%s::mptctl_hp_hostinfo() @%d - ioc%d not found!\n",
-                               __FILE__, __LINE__, iocnum);
-               return -ENODEV;
-       }
        dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT ": mptctl_hp_hostinfo called.\n",
            ioc->name));
 
@@ -2659,15 +2554,13 @@ retry_wait:
  *             -ENOMEM if memory allocation error
  */
 static int
-mptctl_hp_targetinfo(unsigned long arg)
+mptctl_hp_targetinfo(MPT_ADAPTER *ioc, unsigned long arg)
 {
        hp_target_info_t __user *uarg = (void __user *) arg;
        SCSIDevicePage0_t       *pg0_alloc;
        SCSIDevicePage3_t       *pg3_alloc;
-       MPT_ADAPTER             *ioc;
        MPT_SCSI_HOST           *hd = NULL;
        hp_target_info_t        karg;
-       int                     iocnum;
        int                     data_sz;
        dma_addr_t              page_dma;
        CONFIGPARMS             cfg;
@@ -2681,12 +2574,6 @@ mptctl_hp_targetinfo(unsigned long arg)
                return -EFAULT;
        }
 
-       if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
-               (ioc == NULL)) {
-               printk(KERN_DEBUG MYNAM "%s::mptctl_hp_targetinfo() @%d - ioc%d not found!\n",
-                               __FILE__, __LINE__, iocnum);
-               return -ENODEV;
-       }
        if (karg.hdr.id >= MPT_MAX_FC_DEVICES)
                return -EINVAL;
        dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mptctl_hp_targetinfo called.\n",
@@ -2854,7 +2741,7 @@ compat_mptfwxfer_ioctl(struct file *filp, unsigned int cmd,
        kfw.fwlen = kfw32.fwlen;
        kfw.bufp = compat_ptr(kfw32.bufp);
 
-       ret = mptctl_do_fw_download(kfw.iocnum, kfw.bufp, kfw.fwlen);
+       ret = mptctl_do_fw_download(iocp, kfw.bufp, kfw.fwlen);
 
        mutex_unlock(&iocp->ioctl_cmds.mutex);
 
@@ -2908,7 +2795,7 @@ compat_mpt_command(struct file *filp, unsigned int cmd,
 
        /* Pass new structure to do_mpt_command
         */
-       ret = mptctl_do_mpt_command (karg, &uarg->MF);
+       ret = mptctl_do_mpt_command (iocp, karg, &uarg->MF);
 
        mutex_unlock(&iocp->ioctl_cmds.mutex);
 
index 6d27ccf..3c2d405 100644 (file)
@@ -406,10 +406,9 @@ int enclosure_remove_device(struct enclosure_device *edev, struct device *dev)
                cdev = &edev->component[i];
                if (cdev->dev == dev) {
                        enclosure_remove_links(cdev);
-                       device_del(&cdev->cdev);
                        put_device(dev);
                        cdev->dev = NULL;
-                       return device_add(&cdev->cdev);
+                       return 0;
                }
        }
        return -ENODEV;
index a4fdad0..de87693 100644 (file)
@@ -278,7 +278,7 @@ void lkdtm_STACK_GUARD_PAGE_TRAILING(void)
 
 void lkdtm_UNSET_SMEP(void)
 {
-#ifdef CONFIG_X86_64
+#if IS_ENABLED(CONFIG_X86_64) && !IS_ENABLED(CONFIG_UML)
 #define MOV_CR4_DEPTH  64
        void (*direct_write_cr4)(unsigned long val);
        unsigned char *insn;
@@ -338,13 +338,13 @@ void lkdtm_UNSET_SMEP(void)
                native_write_cr4(cr4);
        }
 #else
-       pr_err("FAIL: this test is x86_64-only\n");
+       pr_err("XFAIL: this test is x86_64-only\n");
 #endif
 }
 
-#ifdef CONFIG_X86_32
 void lkdtm_DOUBLE_FAULT(void)
 {
+#ifdef CONFIG_X86_32
        /*
         * Trigger #DF by setting the stack limit to zero.  This clobbers
         * a GDT TLS slot, which is okay because the current task will die
@@ -373,6 +373,8 @@ void lkdtm_DOUBLE_FAULT(void)
        asm volatile ("movw %0, %%ss; addl $0, (%%esp)" ::
                      "r" ((unsigned short)(GDT_ENTRY_TLS_MIN << 3)));
 
-       panic("tried to double fault but didn't die\n");
-}
+       pr_err("FAIL: tried to double fault but didn't die\n");
+#else
+       pr_err("XFAIL: this test is ia32-only\n");
 #endif
+}
index edf94ee..aa9368b 100644 (file)
@@ -148,13 +148,13 @@ static int omap2_onenand_wait(struct mtd_info *mtd, int state)
        unsigned long timeout;
        u32 syscfg;
 
-       if (state == FL_RESETING || state == FL_PREPARING_ERASE ||
+       if (state == FL_RESETTING || state == FL_PREPARING_ERASE ||
            state == FL_VERIFYING_ERASE) {
                int i = 21;
                unsigned int intr_flags = ONENAND_INT_MASTER;
 
                switch (state) {
-               case FL_RESETING:
+               case FL_RESETTING:
                        intr_flags |= ONENAND_INT_RESET;
                        break;
                case FL_PREPARING_ERASE:
@@ -328,7 +328,8 @@ static inline int omap2_onenand_dma_transfer(struct omap2_onenand *c,
        struct dma_async_tx_descriptor *tx;
        dma_cookie_t cookie;
 
-       tx = dmaengine_prep_dma_memcpy(c->dma_chan, dst, src, count, 0);
+       tx = dmaengine_prep_dma_memcpy(c->dma_chan, dst, src, count,
+                                      DMA_CTRL_ACK | DMA_PREP_INTERRUPT);
        if (!tx) {
                dev_err(&c->pdev->dev, "Failed to prepare DMA memcpy\n");
                return -EIO;
@@ -375,7 +376,7 @@ static int omap2_onenand_read_bufferram(struct mtd_info *mtd, int area,
         * context fallback to PIO mode.
         */
        if (!virt_addr_valid(buf) || bram_offset & 3 || (size_t)buf & 3 ||
-           count < 384 || in_interrupt() || oops_in_progress )
+           count < 384 || in_interrupt() || oops_in_progress)
                goto out_copy;
 
        xtra = count & 3;
@@ -422,7 +423,7 @@ static int omap2_onenand_write_bufferram(struct mtd_info *mtd, int area,
         * context fallback to PIO mode.
         */
        if (!virt_addr_valid(buf) || bram_offset & 3 || (size_t)buf & 3 ||
-           count < 384 || in_interrupt() || oops_in_progress )
+           count < 384 || in_interrupt() || oops_in_progress)
                goto out_copy;
 
        dma_src = dma_map_single(dev, buf, count, DMA_TO_DEVICE);
@@ -528,7 +529,8 @@ static int omap2_onenand_probe(struct platform_device *pdev)
                 c->gpmc_cs, c->phys_base, c->onenand.base,
                 c->dma_chan ? "DMA" : "PIO");
 
-       if ((r = onenand_scan(&c->mtd, 1)) < 0)
+       r = onenand_scan(&c->mtd, 1);
+       if (r < 0)
                goto err_release_dma;
 
        freq = omap2_onenand_get_freq(c->onenand.version_id);
index 77bd32a..85640ee 100644 (file)
@@ -2853,7 +2853,7 @@ static int onenand_otp_write_oob_nolock(struct mtd_info *mtd, loff_t to,
 
                /* Exit OTP access mode */
                this->command(mtd, ONENAND_CMD_RESET, 0, 0);
-               this->wait(mtd, FL_RESETING);
+               this->wait(mtd, FL_RESETTING);
 
                status = this->read_word(this->base + ONENAND_REG_CTRL_STATUS);
                status &= 0x60;
@@ -2924,7 +2924,7 @@ static int do_otp_read(struct mtd_info *mtd, loff_t from, size_t len,
 
        /* Exit OTP access mode */
        this->command(mtd, ONENAND_CMD_RESET, 0, 0);
-       this->wait(mtd, FL_RESETING);
+       this->wait(mtd, FL_RESETTING);
 
        return ret;
 }
@@ -2968,7 +2968,7 @@ static int do_otp_write(struct mtd_info *mtd, loff_t to, size_t len,
 
        /* Exit OTP access mode */
        this->command(mtd, ONENAND_CMD_RESET, 0, 0);
-       this->wait(mtd, FL_RESETING);
+       this->wait(mtd, FL_RESETTING);
 
        return ret;
 }
@@ -3008,7 +3008,7 @@ static int do_otp_lock(struct mtd_info *mtd, loff_t from, size_t len,
 
                /* Exit OTP access mode */
                this->command(mtd, ONENAND_CMD_RESET, 0, 0);
-               this->wait(mtd, FL_RESETING);
+               this->wait(mtd, FL_RESETTING);
        } else {
                ops.mode = MTD_OPS_PLACE_OOB;
                ops.ooblen = len;
@@ -3413,7 +3413,7 @@ static int flexonenand_get_boundary(struct mtd_info *mtd)
                this->boundary[die] = bdry & FLEXONENAND_PI_MASK;
 
                this->command(mtd, ONENAND_CMD_RESET, 0, 0);
-               this->wait(mtd, FL_RESETING);
+               this->wait(mtd, FL_RESETTING);
 
                printk(KERN_INFO "Die %d boundary: %d%s\n", die,
                       this->boundary[die], locked ? "(Locked)" : "(Unlocked)");
@@ -3635,7 +3635,7 @@ static int flexonenand_set_boundary(struct mtd_info *mtd, int die,
        ret = this->wait(mtd, FL_WRITING);
 out:
        this->write_word(ONENAND_CMD_RESET, this->base + ONENAND_REG_COMMAND);
-       this->wait(mtd, FL_RESETING);
+       this->wait(mtd, FL_RESETTING);
        if (!ret)
                /* Recalculate device size on boundary change*/
                flexonenand_get_size(mtd);
@@ -3671,7 +3671,7 @@ static int onenand_chip_probe(struct mtd_info *mtd)
        /* Reset OneNAND to read default register values */
        this->write_word(ONENAND_CMD_RESET, this->base + ONENAND_BOOTRAM);
        /* Wait reset */
-       this->wait(mtd, FL_RESETING);
+       this->wait(mtd, FL_RESETTING);
 
        /* Restore system configuration 1 */
        this->write_word(syscfg, this->base + ONENAND_REG_SYS_CFG1);
index 55e5536..beb7987 100644 (file)
@@ -675,12 +675,12 @@ static int s5pc110_read_bufferram(struct mtd_info *mtd, int area,
 normal:
        if (count != mtd->writesize) {
                /* Copy the bufferram to memory to prevent unaligned access */
-               memcpy(this->page_buf, p, mtd->writesize);
-               p = this->page_buf + offset;
+               memcpy_fromio(this->page_buf, p, mtd->writesize);
+               memcpy(buffer, this->page_buf + offset, count);
+       } else {
+               memcpy_fromio(buffer, p, count);
        }
 
-       memcpy(buffer, p, count);
-
        return 0;
 }
 
index 3a36285..f6c7102 100644 (file)
@@ -914,8 +914,8 @@ static void cadence_nand_get_caps(struct cdns_nand_ctrl *cdns_ctrl)
 /* Prepare CDMA descriptor. */
 static void
 cadence_nand_cdma_desc_prepare(struct cdns_nand_ctrl *cdns_ctrl,
-                              char nf_mem, u32 flash_ptr, char *mem_ptr,
-                              char *ctrl_data_ptr, u16 ctype)
+                              char nf_mem, u32 flash_ptr, dma_addr_t mem_ptr,
+                                  dma_addr_t ctrl_data_ptr, u16 ctype)
 {
        struct cadence_nand_cdma_desc *cdma_desc = cdns_ctrl->cdma_desc;
 
@@ -931,13 +931,13 @@ cadence_nand_cdma_desc_prepare(struct cdns_nand_ctrl *cdns_ctrl,
        cdma_desc->command_flags |= CDMA_CF_DMA_MASTER;
        cdma_desc->command_flags  |= CDMA_CF_INT;
 
-       cdma_desc->memory_pointer = (uintptr_t)mem_ptr;
+       cdma_desc->memory_pointer = mem_ptr;
        cdma_desc->status = 0;
        cdma_desc->sync_flag_pointer = 0;
        cdma_desc->sync_arguments = 0;
 
        cdma_desc->command_type = ctype;
-       cdma_desc->ctrl_data_ptr = (uintptr_t)ctrl_data_ptr;
+       cdma_desc->ctrl_data_ptr = ctrl_data_ptr;
 }
 
 static u8 cadence_nand_check_desc_error(struct cdns_nand_ctrl *cdns_ctrl,
@@ -1280,8 +1280,7 @@ cadence_nand_cdma_transfer(struct cdns_nand_ctrl *cdns_ctrl, u8 chip_nr,
        }
 
        cadence_nand_cdma_desc_prepare(cdns_ctrl, chip_nr, page,
-                                      (void *)dma_buf, (void *)dma_ctrl_dat,
-                                      ctype);
+                                      dma_buf, dma_ctrl_dat, ctype);
 
        status = cadence_nand_cdma_send_and_wait(cdns_ctrl, thread_nr);
 
@@ -1360,7 +1359,7 @@ static int cadence_nand_erase(struct nand_chip *chip, u32 page)
 
        cadence_nand_cdma_desc_prepare(cdns_ctrl,
                                       cdns_chip->cs[chip->cur_cs],
-                                      page, NULL, NULL,
+                                      page, 0, 0,
                                       CDMA_CT_ERASE);
        status = cadence_nand_cdma_send_and_wait(cdns_ctrl, thread_nr);
        if (status) {
index 334fe31..b9d5d55 100644 (file)
@@ -148,6 +148,10 @@ static int gpmi_init(struct gpmi_nand_data *this)
        struct resources *r = &this->resources;
        int ret;
 
+       ret = pm_runtime_get_sync(this->dev);
+       if (ret < 0)
+               return ret;
+
        ret = gpmi_reset_block(r->gpmi_regs, false);
        if (ret)
                goto err_out;
@@ -179,8 +183,9 @@ static int gpmi_init(struct gpmi_nand_data *this)
         */
        writel(BM_GPMI_CTRL1_DECOUPLE_CS, r->gpmi_regs + HW_GPMI_CTRL1_SET);
 
-       return 0;
 err_out:
+       pm_runtime_mark_last_busy(this->dev);
+       pm_runtime_put_autosuspend(this->dev);
        return ret;
 }
 
@@ -2722,6 +2727,10 @@ static int gpmi_pm_resume(struct device *dev)
                return ret;
        }
 
+       /* Set flag to get timing setup restored for next exec_op */
+       if (this->hw.clk_rate)
+               this->hw.must_apply_timings = true;
+
        /* re-init the BCH registers */
        ret = bch_set_geometry(this);
        if (ret) {
index 9e63800..3ba73f1 100644 (file)
@@ -37,6 +37,7 @@
 /* Max ECC buffer length */
 #define FMC2_MAX_ECC_BUF_LEN           (FMC2_BCHDSRS_LEN * FMC2_MAX_SG)
 
+#define FMC2_TIMEOUT_US                        1000
 #define FMC2_TIMEOUT_MS                        1000
 
 /* Timings */
@@ -53,6 +54,8 @@
 #define FMC2_PMEM                      0x88
 #define FMC2_PATT                      0x8c
 #define FMC2_HECCR                     0x94
+#define FMC2_ISR                       0x184
+#define FMC2_ICR                       0x188
 #define FMC2_CSQCR                     0x200
 #define FMC2_CSQCFGR1                  0x204
 #define FMC2_CSQCFGR2                  0x208
 #define FMC2_PATT_ATTHIZ(x)            (((x) & 0xff) << 24)
 #define FMC2_PATT_DEFAULT              0x0a0a0a0a
 
+/* Register: FMC2_ISR */
+#define FMC2_ISR_IHLF                  BIT(1)
+
+/* Register: FMC2_ICR */
+#define FMC2_ICR_CIHLF                 BIT(1)
+
 /* Register: FMC2_CSQCR */
 #define FMC2_CSQCR_CSQSTART            BIT(0)
 
@@ -1322,6 +1331,31 @@ static void stm32_fmc2_write_data(struct nand_chip *chip, const void *buf,
                stm32_fmc2_set_buswidth_16(fmc2, true);
 }
 
+static int stm32_fmc2_waitrdy(struct nand_chip *chip, unsigned long timeout_ms)
+{
+       struct stm32_fmc2_nfc *fmc2 = to_stm32_nfc(chip->controller);
+       const struct nand_sdr_timings *timings;
+       u32 isr, sr;
+
+       /* Check if there is no pending requests to the NAND flash */
+       if (readl_relaxed_poll_timeout_atomic(fmc2->io_base + FMC2_SR, sr,
+                                             sr & FMC2_SR_NWRF, 1,
+                                             FMC2_TIMEOUT_US))
+               dev_warn(fmc2->dev, "Waitrdy timeout\n");
+
+       /* Wait tWB before R/B# signal is low */
+       timings = nand_get_sdr_timings(&chip->data_interface);
+       ndelay(PSEC_TO_NSEC(timings->tWB_max));
+
+       /* R/B# signal is low, clear high level flag */
+       writel_relaxed(FMC2_ICR_CIHLF, fmc2->io_base + FMC2_ICR);
+
+       /* Wait R/B# signal is high */
+       return readl_relaxed_poll_timeout_atomic(fmc2->io_base + FMC2_ISR,
+                                                isr, isr & FMC2_ISR_IHLF,
+                                                5, 1000 * timeout_ms);
+}
+
 static int stm32_fmc2_exec_op(struct nand_chip *chip,
                              const struct nand_operation *op,
                              bool check_only)
@@ -1366,8 +1400,8 @@ static int stm32_fmc2_exec_op(struct nand_chip *chip,
                        break;
 
                case NAND_OP_WAITRDY_INSTR:
-                       ret = nand_soft_waitrdy(chip,
-                                               instr->ctx.waitrdy.timeout_ms);
+                       ret = stm32_fmc2_waitrdy(chip,
+                                                instr->ctx.waitrdy.timeout_ms);
                        break;
                }
        }
index 4744bf9..b9f2724 100644 (file)
@@ -247,7 +247,8 @@ static int sm_read_sector(struct sm_ftl *ftl,
 
        /* FTL can contain -1 entries that are by default filled with bits */
        if (block == -1) {
-               memset(buffer, 0xFF, SM_SECTOR_SIZE);
+               if (buffer)
+                       memset(buffer, 0xFF, SM_SECTOR_SIZE);
                return 0;
        }
 
index f4afe12..b0cd443 100644 (file)
@@ -2124,6 +2124,8 @@ static int spi_nor_sr2_bit1_quad_enable(struct spi_nor *nor)
        if (nor->bouncebuf[0] & SR2_QUAD_EN_BIT1)
                return 0;
 
+       nor->bouncebuf[0] |= SR2_QUAD_EN_BIT1;
+
        return spi_nor_write_16bit_cr_and_check(nor, nor->bouncebuf[0]);
 }
 
@@ -4596,6 +4598,7 @@ static void sst_set_default_init(struct spi_nor *nor)
 static void st_micron_set_default_init(struct spi_nor *nor)
 {
        nor->flags |= SNOR_F_HAS_LOCK;
+       nor->flags &= ~SNOR_F_HAS_16BIT_SR;
        nor->params.quad_enable = NULL;
        nor->params.set_4byte = st_micron_set_4byte;
 }
@@ -4768,9 +4771,7 @@ static void spi_nor_info_init_params(struct spi_nor *nor)
 
 static void spansion_post_sfdp_fixups(struct spi_nor *nor)
 {
-       struct mtd_info *mtd = &nor->mtd;
-
-       if (mtd->size <= SZ_16M)
+       if (nor->params.size <= SZ_16M)
                return;
 
        nor->flags |= SNOR_F_4B_OPCODES;
index 667f18f..5dc32b7 100644 (file)
@@ -222,6 +222,8 @@ static blk_status_t nvme_error_status(u16 status)
        case NVME_SC_CAP_EXCEEDED:
                return BLK_STS_NOSPC;
        case NVME_SC_LBA_RANGE:
+       case NVME_SC_CMD_INTERRUPTED:
+       case NVME_SC_NS_NOT_READY:
                return BLK_STS_TARGET;
        case NVME_SC_BAD_ATTRIBUTES:
        case NVME_SC_ONCS_NOT_SUPPORTED:
index 56c21b5..72a7e41 100644 (file)
@@ -24,6 +24,16 @@ u32 nvmet_get_log_page_len(struct nvme_command *cmd)
        return len;
 }
 
+static u32 nvmet_feat_data_len(struct nvmet_req *req, u32 cdw10)
+{
+       switch (cdw10 & 0xff) {
+       case NVME_FEAT_HOST_ID:
+               return sizeof(req->sq->ctrl->hostid);
+       default:
+               return 0;
+       }
+}
+
 u64 nvmet_get_log_page_offset(struct nvme_command *cmd)
 {
        return le64_to_cpu(cmd->get_log_page.lpo);
@@ -778,7 +788,7 @@ static void nvmet_execute_get_features(struct nvmet_req *req)
        u32 cdw10 = le32_to_cpu(req->cmd->common.cdw10);
        u16 status = 0;
 
-       if (!nvmet_check_data_len(req, 0))
+       if (!nvmet_check_data_len(req, nvmet_feat_data_len(req, cdw10)))
                return;
 
        switch (cdw10 & 0xff) {
index ead06c6..12e71a3 100644 (file)
@@ -115,7 +115,7 @@ struct cpcap_usb_ints_state {
 enum cpcap_gpio_mode {
        CPCAP_DM_DP,
        CPCAP_MDM_RX_TX,
-       CPCAP_UNKNOWN,
+       CPCAP_UNKNOWN_DISABLED, /* Seems to disable USB lines */
        CPCAP_OTG_DM_DP,
 };
 
@@ -134,6 +134,8 @@ struct cpcap_phy_ddata {
        struct iio_channel *id;
        struct regulator *vusb;
        atomic_t active;
+       unsigned int vbus_provider:1;
+       unsigned int docked:1;
 };
 
 static bool cpcap_usb_vbus_valid(struct cpcap_phy_ddata *ddata)
@@ -207,6 +209,19 @@ static int cpcap_phy_get_ints_state(struct cpcap_phy_ddata *ddata,
 static int cpcap_usb_set_uart_mode(struct cpcap_phy_ddata *ddata);
 static int cpcap_usb_set_usb_mode(struct cpcap_phy_ddata *ddata);
 
+static void cpcap_usb_try_musb_mailbox(struct cpcap_phy_ddata *ddata,
+                                      enum musb_vbus_id_status status)
+{
+       int error;
+
+       error = musb_mailbox(status);
+       if (!error)
+               return;
+
+       dev_dbg(ddata->dev, "%s: musb_mailbox failed: %i\n",
+               __func__, error);
+}
+
 static void cpcap_usb_detect(struct work_struct *work)
 {
        struct cpcap_phy_ddata *ddata;
@@ -220,16 +235,66 @@ static void cpcap_usb_detect(struct work_struct *work)
        if (error)
                return;
 
-       if (s.id_ground) {
-               dev_dbg(ddata->dev, "id ground, USB host mode\n");
+       vbus = cpcap_usb_vbus_valid(ddata);
+
+       /* We need to kick the VBUS as USB A-host */
+       if (s.id_ground && ddata->vbus_provider) {
+               dev_dbg(ddata->dev, "still in USB A-host mode, kicking VBUS\n");
+
+               cpcap_usb_try_musb_mailbox(ddata, MUSB_ID_GROUND);
+
+               error = regmap_update_bits(ddata->reg, CPCAP_REG_USBC3,
+                                          CPCAP_BIT_VBUSSTBY_EN |
+                                          CPCAP_BIT_VBUSEN_SPI,
+                                          CPCAP_BIT_VBUSEN_SPI);
+               if (error)
+                       goto out_err;
+
+               return;
+       }
+
+       if (vbus && s.id_ground && ddata->docked) {
+               dev_dbg(ddata->dev, "still docked as A-host, signal ID down\n");
+
+               cpcap_usb_try_musb_mailbox(ddata, MUSB_ID_GROUND);
+
+               return;
+       }
+
+       /* No VBUS needed with docks */
+       if (vbus && s.id_ground && !ddata->vbus_provider) {
+               dev_dbg(ddata->dev, "connected to a dock\n");
+
+               ddata->docked = true;
+
                error = cpcap_usb_set_usb_mode(ddata);
                if (error)
                        goto out_err;
 
-               error = musb_mailbox(MUSB_ID_GROUND);
+               cpcap_usb_try_musb_mailbox(ddata, MUSB_ID_GROUND);
+
+               /*
+                * Force check state again after musb has reoriented,
+                * otherwise devices won't enumerate after loading PHY
+                * driver.
+                */
+               schedule_delayed_work(&ddata->detect_work,
+                                     msecs_to_jiffies(1000));
+
+               return;
+       }
+
+       if (s.id_ground && !ddata->docked) {
+               dev_dbg(ddata->dev, "id ground, USB host mode\n");
+
+               ddata->vbus_provider = true;
+
+               error = cpcap_usb_set_usb_mode(ddata);
                if (error)
                        goto out_err;
 
+               cpcap_usb_try_musb_mailbox(ddata, MUSB_ID_GROUND);
+
                error = regmap_update_bits(ddata->reg, CPCAP_REG_USBC3,
                                           CPCAP_BIT_VBUSSTBY_EN |
                                           CPCAP_BIT_VBUSEN_SPI,
@@ -248,43 +313,26 @@ static void cpcap_usb_detect(struct work_struct *work)
 
        vbus = cpcap_usb_vbus_valid(ddata);
 
+       /* Otherwise assume we're connected to a USB host */
        if (vbus) {
-               /* Are we connected to a docking station with vbus? */
-               if (s.id_ground) {
-                       dev_dbg(ddata->dev, "connected to a dock\n");
-
-                       /* No VBUS needed with docks */
-                       error = cpcap_usb_set_usb_mode(ddata);
-                       if (error)
-                               goto out_err;
-                       error = musb_mailbox(MUSB_ID_GROUND);
-                       if (error)
-                               goto out_err;
-
-                       return;
-               }
-
-               /* Otherwise assume we're connected to a USB host */
                dev_dbg(ddata->dev, "connected to USB host\n");
                error = cpcap_usb_set_usb_mode(ddata);
                if (error)
                        goto out_err;
-               error = musb_mailbox(MUSB_VBUS_VALID);
-               if (error)
-                       goto out_err;
+               cpcap_usb_try_musb_mailbox(ddata, MUSB_VBUS_VALID);
 
                return;
        }
 
+       ddata->vbus_provider = false;
+       ddata->docked = false;
+       cpcap_usb_try_musb_mailbox(ddata, MUSB_VBUS_OFF);
+
        /* Default to debug UART mode */
        error = cpcap_usb_set_uart_mode(ddata);
        if (error)
                goto out_err;
 
-       error = musb_mailbox(MUSB_VBUS_OFF);
-       if (error)
-               goto out_err;
-
        dev_dbg(ddata->dev, "set UART mode\n");
 
        return;
@@ -376,7 +424,8 @@ static int cpcap_usb_set_uart_mode(struct cpcap_phy_ddata *ddata)
 {
        int error;
 
-       error = cpcap_usb_gpio_set_mode(ddata, CPCAP_DM_DP);
+       /* Disable lines to prevent glitches from waking up mdm6600 */
+       error = cpcap_usb_gpio_set_mode(ddata, CPCAP_UNKNOWN_DISABLED);
        if (error)
                goto out_err;
 
@@ -403,6 +452,11 @@ static int cpcap_usb_set_uart_mode(struct cpcap_phy_ddata *ddata)
        if (error)
                goto out_err;
 
+       /* Enable UART mode */
+       error = cpcap_usb_gpio_set_mode(ddata, CPCAP_DM_DP);
+       if (error)
+               goto out_err;
+
        return 0;
 
 out_err:
@@ -415,7 +469,8 @@ static int cpcap_usb_set_usb_mode(struct cpcap_phy_ddata *ddata)
 {
        int error;
 
-       error = cpcap_usb_gpio_set_mode(ddata, CPCAP_OTG_DM_DP);
+       /* Disable lines to prevent glitches from waking up mdm6600 */
+       error = cpcap_usb_gpio_set_mode(ddata, CPCAP_UNKNOWN_DISABLED);
        if (error)
                return error;
 
@@ -434,12 +489,6 @@ static int cpcap_usb_set_usb_mode(struct cpcap_phy_ddata *ddata)
        if (error)
                goto out_err;
 
-       error = regmap_update_bits(ddata->reg, CPCAP_REG_USBC2,
-                                  CPCAP_BIT_USBXCVREN,
-                                  CPCAP_BIT_USBXCVREN);
-       if (error)
-               goto out_err;
-
        error = regmap_update_bits(ddata->reg, CPCAP_REG_USBC3,
                                   CPCAP_BIT_PU_SPI |
                                   CPCAP_BIT_DMPD_SPI |
@@ -455,6 +504,11 @@ static int cpcap_usb_set_usb_mode(struct cpcap_phy_ddata *ddata)
        if (error)
                goto out_err;
 
+       /* Enable USB mode */
+       error = cpcap_usb_gpio_set_mode(ddata, CPCAP_OTG_DM_DP);
+       if (error)
+               goto out_err;
+
        return 0;
 
 out_err:
@@ -649,9 +703,7 @@ static int cpcap_usb_phy_remove(struct platform_device *pdev)
        if (error)
                dev_err(ddata->dev, "could not set UART mode\n");
 
-       error = musb_mailbox(MUSB_VBUS_OFF);
-       if (error)
-               dev_err(ddata->dev, "could not set mailbox\n");
+       cpcap_usb_try_musb_mailbox(ddata, MUSB_VBUS_OFF);
 
        usb_remove_phy(&ddata->phy);
        cancel_delayed_work_sync(&ddata->detect_work);
index ee184d5..f20524f 100644 (file)
@@ -200,7 +200,7 @@ static void phy_mdm6600_status(struct work_struct *work)
        struct phy_mdm6600 *ddata;
        struct device *dev;
        DECLARE_BITMAP(values, PHY_MDM6600_NR_STATUS_LINES);
-       int error, i, val = 0;
+       int error;
 
        ddata = container_of(work, struct phy_mdm6600, status_work.work);
        dev = ddata->dev;
@@ -212,16 +212,11 @@ static void phy_mdm6600_status(struct work_struct *work)
        if (error)
                return;
 
-       for (i = 0; i < PHY_MDM6600_NR_STATUS_LINES; i++) {
-               val |= test_bit(i, values) << i;
-               dev_dbg(ddata->dev, "XXX %s: i: %i values[i]: %i val: %i\n",
-                       __func__, i, test_bit(i, values), val);
-       }
-       ddata->status = values[0];
+       ddata->status = values[0] & ((1 << PHY_MDM6600_NR_STATUS_LINES) - 1);
 
        dev_info(dev, "modem status: %i %s\n",
                 ddata->status,
-                phy_mdm6600_status_name[ddata->status & 7]);
+                phy_mdm6600_status_name[ddata->status]);
        complete(&ddata->ack);
 }
 
index 091e203..66f9172 100644 (file)
@@ -66,7 +66,7 @@
 /* QPHY_V3_PCS_MISC_CLAMP_ENABLE register bits */
 #define CLAMP_EN                               BIT(0) /* enables i/o clamp_n */
 
-#define PHY_INIT_COMPLETE_TIMEOUT              1000
+#define PHY_INIT_COMPLETE_TIMEOUT              10000
 #define POWER_DOWN_DELAY_US_MIN                        10
 #define POWER_DOWN_DELAY_US_MAX                        11
 
index 2b97fb1..9ca20c9 100644 (file)
@@ -603,6 +603,8 @@ static long inno_hdmi_phy_rk3228_clk_round_rate(struct clk_hw *hw,
 {
        const struct pre_pll_config *cfg = pre_pll_cfg_table;
 
+       rate = (rate / 1000) * 1000;
+
        for (; cfg->pixclock != 0; cfg++)
                if (cfg->pixclock == rate && !cfg->fracdiv)
                        break;
@@ -755,6 +757,8 @@ static long inno_hdmi_phy_rk3328_clk_round_rate(struct clk_hw *hw,
 {
        const struct pre_pll_config *cfg = pre_pll_cfg_table;
 
+       rate = (rate / 1000) * 1000;
+
        for (; cfg->pixclock != 0; cfg++)
                if (cfg->pixclock == rate)
                        break;
index f1806fd..530426a 100644 (file)
@@ -2,6 +2,7 @@
 config PINCTRL_LOCHNAGAR
        tristate "Cirrus Logic Lochnagar pinctrl driver"
        depends on MFD_LOCHNAGAR
+       select GPIOLIB
        select PINMUX
        select PINCONF
        select GENERIC_PINCONF
index 3c80828..bbc919b 100644 (file)
@@ -441,6 +441,7 @@ static int meson_pinconf_get_drive_strength(struct meson_pinctrl *pc,
                return ret;
 
        meson_calc_reg_and_bit(bank, pin, REG_DS, &reg, &bit);
+       bit = bit << 1;
 
        ret = regmap_read(pc->reg_ds, reg, &val);
        if (ret)
index bb0edf5..5731d1b 100644 (file)
@@ -73,13 +73,6 @@ static int send_kbbl_msg(struct wilco_ec_device *ec,
                return ret;
        }
 
-       if (response->status) {
-               dev_err(ec->dev,
-                       "EC reported failure sending keyboard LEDs command: %d",
-                       response->status);
-               return -EIO;
-       }
-
        return 0;
 }
 
@@ -87,6 +80,7 @@ static int set_kbbl(struct wilco_ec_device *ec, enum led_brightness brightness)
 {
        struct wilco_keyboard_leds_msg request;
        struct wilco_keyboard_leds_msg response;
+       int ret;
 
        memset(&request, 0, sizeof(request));
        request.command = WILCO_EC_COMMAND_KBBL;
@@ -94,7 +88,18 @@ static int set_kbbl(struct wilco_ec_device *ec, enum led_brightness brightness)
        request.mode    = WILCO_KBBL_MODE_FLAG_PWM;
        request.percent = brightness;
 
-       return send_kbbl_msg(ec, &request, &response);
+       ret = send_kbbl_msg(ec, &request, &response);
+       if (ret < 0)
+               return ret;
+
+       if (response.status) {
+               dev_err(ec->dev,
+                       "EC reported failure sending keyboard LEDs command: %d",
+                       response.status);
+               return -EIO;
+       }
+
+       return 0;
 }
 
 static int kbbl_exist(struct wilco_ec_device *ec, bool *exists)
@@ -140,6 +145,13 @@ static int kbbl_init(struct wilco_ec_device *ec)
        if (ret < 0)
                return ret;
 
+       if (response.status) {
+               dev_err(ec->dev,
+                       "EC reported failure sending keyboard LEDs command: %d",
+                       response.status);
+               return -EIO;
+       }
+
        if (response.mode & WILCO_KBBL_MODE_FLAG_PWM)
                return response.percent;
 
index 9a5c9fd..5739a96 100644 (file)
@@ -149,7 +149,7 @@ struct mlxbf_tmfifo_irq_info {
  * @work: work struct for deferred process
  * @timer: background timer
  * @vring: Tx/Rx ring
- * @spin_lock: spin lock
+ * @spin_lock: Tx/Rx spin lock
  * @is_ready: ready flag
  */
 struct mlxbf_tmfifo {
@@ -164,7 +164,7 @@ struct mlxbf_tmfifo {
        struct work_struct work;
        struct timer_list timer;
        struct mlxbf_tmfifo_vring *vring[2];
-       spinlock_t spin_lock;           /* spin lock */
+       spinlock_t spin_lock[2];        /* spin lock */
        bool is_ready;
 };
 
@@ -525,7 +525,7 @@ static void mlxbf_tmfifo_console_tx(struct mlxbf_tmfifo *fifo, int avail)
        writeq(*(u64 *)&hdr, fifo->tx_base + MLXBF_TMFIFO_TX_DATA);
 
        /* Use spin-lock to protect the 'cons->tx_buf'. */
-       spin_lock_irqsave(&fifo->spin_lock, flags);
+       spin_lock_irqsave(&fifo->spin_lock[0], flags);
 
        while (size > 0) {
                addr = cons->tx_buf.buf + cons->tx_buf.tail;
@@ -552,7 +552,7 @@ static void mlxbf_tmfifo_console_tx(struct mlxbf_tmfifo *fifo, int avail)
                }
        }
 
-       spin_unlock_irqrestore(&fifo->spin_lock, flags);
+       spin_unlock_irqrestore(&fifo->spin_lock[0], flags);
 }
 
 /* Rx/Tx one word in the descriptor buffer. */
@@ -731,9 +731,9 @@ static bool mlxbf_tmfifo_rxtx_one_desc(struct mlxbf_tmfifo_vring *vring,
                fifo->vring[is_rx] = NULL;
 
                /* Notify upper layer that packet is done. */
-               spin_lock_irqsave(&fifo->spin_lock, flags);
+               spin_lock_irqsave(&fifo->spin_lock[is_rx], flags);
                vring_interrupt(0, vring->vq);
-               spin_unlock_irqrestore(&fifo->spin_lock, flags);
+               spin_unlock_irqrestore(&fifo->spin_lock[is_rx], flags);
        }
 
 mlxbf_tmfifo_desc_done:
@@ -852,10 +852,10 @@ static bool mlxbf_tmfifo_virtio_notify(struct virtqueue *vq)
                 * worker handler.
                 */
                if (vring->vdev_id == VIRTIO_ID_CONSOLE) {
-                       spin_lock_irqsave(&fifo->spin_lock, flags);
+                       spin_lock_irqsave(&fifo->spin_lock[0], flags);
                        tm_vdev = fifo->vdev[VIRTIO_ID_CONSOLE];
                        mlxbf_tmfifo_console_output(tm_vdev, vring);
-                       spin_unlock_irqrestore(&fifo->spin_lock, flags);
+                       spin_unlock_irqrestore(&fifo->spin_lock[0], flags);
                } else if (test_and_set_bit(MLXBF_TM_TX_LWM_IRQ,
                                            &fifo->pend_events)) {
                        return true;
@@ -1189,7 +1189,8 @@ static int mlxbf_tmfifo_probe(struct platform_device *pdev)
        if (!fifo)
                return -ENOMEM;
 
-       spin_lock_init(&fifo->spin_lock);
+       spin_lock_init(&fifo->spin_lock[0]);
+       spin_lock_init(&fifo->spin_lock[1]);
        INIT_WORK(&fifo->work, mlxbf_tmfifo_work_handler);
        mutex_init(&fifo->lock);
 
index 821b08e..982f0cc 100644 (file)
@@ -512,13 +512,7 @@ static void kbd_led_update(struct asus_wmi *asus)
 {
        int ctrl_param = 0;
 
-       /*
-        * bits 0-2: level
-        * bit 7: light on/off
-        */
-       if (asus->kbd_led_wk > 0)
-               ctrl_param = 0x80 | (asus->kbd_led_wk & 0x7F);
-
+       ctrl_param = 0x80 | (asus->kbd_led_wk & 0x7F);
        asus_wmi_set_devstate(ASUS_WMI_DEVID_KBD_BACKLIGHT, ctrl_param, NULL);
 }
 
index be85ed9..b471b86 100644 (file)
 
 #define MAX_SPEED 3
 
-static int temp_limits[3] = { 55000, 60000, 65000 };
+#define TEMP_LIMIT0_DEFAULT    55000
+#define TEMP_LIMIT1_DEFAULT    60000
+#define TEMP_LIMIT2_DEFAULT    65000
+
+#define HYSTERESIS_DEFAULT     3000
+
+#define SPEED_ON_AC_DEFAULT    2
+
+static int temp_limits[3] = {
+       TEMP_LIMIT0_DEFAULT, TEMP_LIMIT1_DEFAULT, TEMP_LIMIT2_DEFAULT,
+};
 module_param_array(temp_limits, int, NULL, 0444);
 MODULE_PARM_DESC(temp_limits,
                 "Millicelsius values above which the fan speed increases");
 
-static int hysteresis = 3000;
+static int hysteresis = HYSTERESIS_DEFAULT;
 module_param(hysteresis, int, 0444);
 MODULE_PARM_DESC(hysteresis,
                 "Hysteresis in millicelsius before lowering the fan speed");
 
-static int speed_on_ac = 2;
+static int speed_on_ac = SPEED_ON_AC_DEFAULT;
 module_param(speed_on_ac, int, 0444);
 MODULE_PARM_DESC(speed_on_ac,
                 "minimum fan speed to allow when system is powered by AC");
@@ -117,21 +127,24 @@ static int gpd_pocket_fan_probe(struct platform_device *pdev)
        int i;
 
        for (i = 0; i < ARRAY_SIZE(temp_limits); i++) {
-               if (temp_limits[i] < 40000 || temp_limits[i] > 70000) {
+               if (temp_limits[i] < 20000 || temp_limits[i] > 90000) {
                        dev_err(&pdev->dev, "Invalid temp-limit %d (must be between 40000 and 70000)\n",
                                temp_limits[i]);
-                       return -EINVAL;
+                       temp_limits[0] = TEMP_LIMIT0_DEFAULT;
+                       temp_limits[1] = TEMP_LIMIT1_DEFAULT;
+                       temp_limits[2] = TEMP_LIMIT2_DEFAULT;
+                       break;
                }
        }
        if (hysteresis < 1000 || hysteresis > 10000) {
                dev_err(&pdev->dev, "Invalid hysteresis %d (must be between 1000 and 10000)\n",
                        hysteresis);
-               return -EINVAL;
+               hysteresis = HYSTERESIS_DEFAULT;
        }
        if (speed_on_ac < 0 || speed_on_ac > MAX_SPEED) {
                dev_err(&pdev->dev, "Invalid speed_on_ac %d (must be between 0 and 3)\n",
                        speed_on_ac);
-               return -EINVAL;
+               speed_on_ac = SPEED_ON_AC_DEFAULT;
        }
 
        fan = devm_kzalloc(&pdev->dev, sizeof(*fan), GFP_KERNEL);
index 512ad23..35ed971 100644 (file)
@@ -1,4 +1,4 @@
-// SPDX-License-Identifier: GPL-2.0
+/* SPDX-License-Identifier: GPL-2.0 */
 /*
  * Copyright (c) 2010 Intel Corporation
  */
index fdee577..8203ae3 100644 (file)
@@ -1,4 +1,4 @@
-// SPDX-License-Identifier: GPL-2.0
+/* SPDX-License-Identifier: GPL-2.0 */
 /*
  * Intel Core SoC Power Management Controller Header File
  *
index 6fe829f..e1266f5 100644 (file)
@@ -44,6 +44,8 @@ static const struct x86_cpu_id intel_pmc_core_platform_ids[] = {
        INTEL_CPU_FAM6(KABYLAKE, pmc_core_device),
        INTEL_CPU_FAM6(CANNONLAKE_L, pmc_core_device),
        INTEL_CPU_FAM6(ICELAKE_L, pmc_core_device),
+       INTEL_CPU_FAM6(COMETLAKE, pmc_core_device),
+       INTEL_CPU_FAM6(COMETLAKE_L, pmc_core_device),
        {}
 };
 MODULE_DEVICE_TABLE(x86cpu, intel_pmc_core_platform_ids);
index a67701e..2e5b6a6 100644 (file)
@@ -1295,6 +1295,9 @@ struct rapl_package *rapl_add_package(int cpu, struct rapl_if_priv *priv)
        struct cpuinfo_x86 *c = &cpu_data(cpu);
        int ret;
 
+       if (!rapl_defaults)
+               return ERR_PTR(-ENODEV);
+
        rp = kzalloc(sizeof(struct rapl_package), GFP_KERNEL);
        if (!rp)
                return ERR_PTR(-ENOMEM);
index a191506..5256e3c 100644 (file)
@@ -793,8 +793,6 @@ static int ap_device_probe(struct device *dev)
                drvres = ap_drv->flags & AP_DRIVER_FLAG_DEFAULT;
                if (!!devres != !!drvres)
                        return -ENODEV;
-               /* (re-)init queue's state machine */
-               ap_queue_reinit_state(to_ap_queue(dev));
        }
 
        /* Add queue/card to list of active queues/cards */
index 433b7b6..bb35ba4 100644 (file)
@@ -261,7 +261,7 @@ void ap_queue_prepare_remove(struct ap_queue *aq);
 void ap_queue_remove(struct ap_queue *aq);
 void ap_queue_suspend(struct ap_device *ap_dev);
 void ap_queue_resume(struct ap_device *ap_dev);
-void ap_queue_reinit_state(struct ap_queue *aq);
+void ap_queue_init_state(struct ap_queue *aq);
 
 struct ap_card *ap_card_create(int id, int queue_depth, int raw_device_type,
                               int comp_device_type, unsigned int functions);
index dad2be3..37c3bdc 100644 (file)
@@ -638,7 +638,7 @@ struct ap_queue *ap_queue_create(ap_qid_t qid, int device_type)
        aq->ap_dev.device.type = &ap_queue_type;
        aq->ap_dev.device_type = device_type;
        aq->qid = qid;
-       aq->state = AP_STATE_RESET_START;
+       aq->state = AP_STATE_UNBOUND;
        aq->interrupt = AP_INTR_DISABLED;
        spin_lock_init(&aq->lock);
        INIT_LIST_HEAD(&aq->list);
@@ -771,10 +771,11 @@ void ap_queue_remove(struct ap_queue *aq)
        spin_unlock_bh(&aq->lock);
 }
 
-void ap_queue_reinit_state(struct ap_queue *aq)
+void ap_queue_init_state(struct ap_queue *aq)
 {
        spin_lock_bh(&aq->lock);
        aq->state = AP_STATE_RESET_START;
        ap_wait(ap_sm_event(aq, AP_EVENT_POLL));
        spin_unlock_bh(&aq->lock);
 }
+EXPORT_SYMBOL(ap_queue_init_state);
index c1db64a..110fe9d 100644 (file)
@@ -1037,8 +1037,8 @@ static int _ip_cprb_helper(u16 cardnr, u16 domain,
        prepparm = (struct iprepparm *) prepcblk->rpl_parmb;
 
        /* do some plausibility checks on the key block */
-       if (prepparm->kb.len < 120 + 5 * sizeof(uint16_t) ||
-           prepparm->kb.len > 136 + 5 * sizeof(uint16_t)) {
+       if (prepparm->kb.len < 120 + 3 * sizeof(uint16_t) ||
+           prepparm->kb.len > 136 + 3 * sizeof(uint16_t)) {
                DEBUG_ERR("%s reply with invalid or unknown key block\n",
                          __func__);
                rc = -EIO;
index c50f3e8..7cbb384 100644 (file)
@@ -175,6 +175,7 @@ static int zcrypt_cex2a_queue_probe(struct ap_device *ap_dev)
        zq->queue = aq;
        zq->online = 1;
        atomic_set(&zq->load, 0);
+       ap_queue_init_state(aq);
        ap_queue_init_reply(aq, &zq->reply);
        aq->request_timeout = CEX2A_CLEANUP_TIME,
        aq->private = zq;
index 35c7c66..c78c0d1 100644 (file)
@@ -220,6 +220,7 @@ static int zcrypt_cex2c_queue_probe(struct ap_device *ap_dev)
        zq->queue = aq;
        zq->online = 1;
        atomic_set(&zq->load, 0);
+       ap_rapq(aq->qid);
        rc = zcrypt_cex2c_rng_supported(aq);
        if (rc < 0) {
                zcrypt_queue_free(zq);
@@ -231,6 +232,7 @@ static int zcrypt_cex2c_queue_probe(struct ap_device *ap_dev)
        else
                zq->ops = zcrypt_msgtype(MSGTYPE06_NAME,
                                         MSGTYPE06_VARIANT_NORNG);
+       ap_queue_init_state(aq);
        ap_queue_init_reply(aq, &zq->reply);
        aq->request_timeout = CEX2C_CLEANUP_TIME;
        aq->private = zq;
index 442e3d6..6fabc90 100644 (file)
@@ -381,6 +381,7 @@ static int zcrypt_cex4_queue_probe(struct ap_device *ap_dev)
        zq->queue = aq;
        zq->online = 1;
        atomic_set(&zq->load, 0);
+       ap_queue_init_state(aq);
        ap_queue_init_reply(aq, &zq->reply);
        aq->request_timeout = CEX4_CLEANUP_TIME,
        aq->private = zq;
index 1f55b9e..1b88a3b 100644 (file)
@@ -688,26 +688,26 @@ int vnic_dev_soft_reset_done(struct vnic_dev *vdev, int *done)
 
 int vnic_dev_hang_notify(struct vnic_dev *vdev)
 {
-       u64 a0, a1;
+       u64 a0 = 0, a1 = 0;
        int wait = 1000;
        return vnic_dev_cmd(vdev, CMD_HANG_NOTIFY, &a0, &a1, wait);
 }
 
 int vnic_dev_mac_addr(struct vnic_dev *vdev, u8 *mac_addr)
 {
-       u64 a0, a1;
+       u64 a[2] = {};
        int wait = 1000;
        int err, i;
 
        for (i = 0; i < ETH_ALEN; i++)
                mac_addr[i] = 0;
 
-       err = vnic_dev_cmd(vdev, CMD_MAC_ADDR, &a0, &a1, wait);
+       err = vnic_dev_cmd(vdev, CMD_MAC_ADDR, &a[0], &a[1], wait);
        if (err)
                return err;
 
        for (i = 0; i < ETH_ALEN; i++)
-               mac_addr[i] = ((u8 *)&a0)[i];
+               mac_addr[i] = ((u8 *)&a)[i];
 
        return 0;
 }
@@ -732,30 +732,30 @@ void vnic_dev_packet_filter(struct vnic_dev *vdev, int directed, int multicast,
 
 void vnic_dev_add_addr(struct vnic_dev *vdev, u8 *addr)
 {
-       u64 a0 = 0, a1 = 0;
+       u64 a[2] = {};
        int wait = 1000;
        int err;
        int i;
 
        for (i = 0; i < ETH_ALEN; i++)
-               ((u8 *)&a0)[i] = addr[i];
+               ((u8 *)&a)[i] = addr[i];
 
-       err = vnic_dev_cmd(vdev, CMD_ADDR_ADD, &a0, &a1, wait);
+       err = vnic_dev_cmd(vdev, CMD_ADDR_ADD, &a[0], &a[1], wait);
        if (err)
                pr_err("Can't add addr [%pM], %d\n", addr, err);
 }
 
 void vnic_dev_del_addr(struct vnic_dev *vdev, u8 *addr)
 {
-       u64 a0 = 0, a1 = 0;
+       u64 a[2] = {};
        int wait = 1000;
        int err;
        int i;
 
        for (i = 0; i < ETH_ALEN; i++)
-               ((u8 *)&a0)[i] = addr[i];
+               ((u8 *)&a)[i] = addr[i];
 
-       err = vnic_dev_cmd(vdev, CMD_ADDR_DEL, &a0, &a1, wait);
+       err = vnic_dev_cmd(vdev, CMD_ADDR_DEL, &a[0], &a[1], wait);
        if (err)
                pr_err("Can't del addr [%pM], %d\n", addr, err);
 }
index cea6259..65ce10c 100644 (file)
@@ -2211,8 +2211,10 @@ static int sd_read_protection_type(struct scsi_disk *sdkp, unsigned char *buffer
        u8 type;
        int ret = 0;
 
-       if (scsi_device_protection(sdp) == 0 || (buffer[12] & 1) == 0)
+       if (scsi_device_protection(sdp) == 0 || (buffer[12] & 1) == 0) {
+               sdkp->protection_type = 0;
                return ret;
+       }
 
        type = ((buffer[12] >> 1) & 7) + 1; /* P_TYPE 0 = Type 1 */
 
index f8faf8b..fb41636 100644 (file)
@@ -1842,9 +1842,11 @@ static int storvsc_probe(struct hv_device *device,
         */
        host->sg_tablesize = (stor_device->max_transfer_bytes >> PAGE_SHIFT);
        /*
+        * For non-IDE disks, the host supports multiple channels.
         * Set the number of HW queues we are supporting.
         */
-       host->nr_hw_queues = num_present_cpus();
+       if (!dev_is_ide)
+               host->nr_hw_queues = num_present_cpus();
 
        /*
         * Set the error handler work queue.
index 5823f5b..3f0261d 100644 (file)
@@ -323,6 +323,8 @@ static int meson_ee_pwrc_init_domain(struct platform_device *pdev,
                                     struct meson_ee_pwrc *pwrc,
                                     struct meson_ee_pwrc_domain *dom)
 {
+       int ret;
+
        dom->pwrc = pwrc;
        dom->num_rstc = dom->desc.reset_names_count;
        dom->num_clks = dom->desc.clk_names_count;
@@ -368,15 +370,21 @@ static int meson_ee_pwrc_init_domain(struct platform_device *pdev,
          * prepare/enable counters won't be in sync.
          */
        if (dom->num_clks && dom->desc.get_power && !dom->desc.get_power(dom)) {
-               int ret = clk_bulk_prepare_enable(dom->num_clks, dom->clks);
+               ret = clk_bulk_prepare_enable(dom->num_clks, dom->clks);
                if (ret)
                        return ret;
 
-               pm_genpd_init(&dom->base, &pm_domain_always_on_gov, false);
-       } else
-               pm_genpd_init(&dom->base, NULL,
-                             (dom->desc.get_power ?
-                              dom->desc.get_power(dom) : true));
+               ret = pm_genpd_init(&dom->base, &pm_domain_always_on_gov,
+                                   false);
+               if (ret)
+                       return ret;
+       } else {
+               ret = pm_genpd_init(&dom->base, NULL,
+                                   (dom->desc.get_power ?
+                                    dom->desc.get_power(dom) : true));
+               if (ret)
+                       return ret;
+       }
 
        return 0;
 }
@@ -441,9 +449,7 @@ static int meson_ee_pwrc_probe(struct platform_device *pdev)
                pwrc->xlate.domains[i] = &dom->base;
        }
 
-       of_genpd_add_provider_onecell(pdev->dev.of_node, &pwrc->xlate);
-
-       return 0;
+       return of_genpd_add_provider_onecell(pdev->dev.of_node, &pwrc->xlate);
 }
 
 static void meson_ee_pwrc_shutdown(struct platform_device *pdev)
index a9ffff3..a506939 100644 (file)
@@ -9,7 +9,7 @@
 #include <linux/interrupt.h>
 #include <linux/of_irq.h>
 #include <linux/of_address.h>
-#include <asm/sifive_l2_cache.h>
+#include <soc/sifive/sifive_l2_cache.h>
 
 #define SIFIVE_L2_DIRECCFIX_LOW 0x100
 #define SIFIVE_L2_DIRECCFIX_HIGH 0x104
index 378369d..e9ece45 100644 (file)
@@ -419,6 +419,8 @@ static void wkup_m3_rproc_boot_thread(struct wkup_m3_ipc *m3_ipc)
        ret = rproc_boot(m3_ipc->rproc);
        if (ret)
                dev_err(dev, "rproc_boot failed\n");
+       else
+               m3_ipc_state = m3_ipc;
 
        do_exit(0);
 }
@@ -505,8 +507,6 @@ static int wkup_m3_ipc_probe(struct platform_device *pdev)
                goto err_put_rproc;
        }
 
-       m3_ipc_state = m3_ipc;
-
        return 0;
 
 err_put_rproc:
index dbff0f7..ddc0dc9 100644 (file)
@@ -46,8 +46,8 @@
 #define PCI171X_RANGE_UNI      BIT(4)
 #define PCI171X_RANGE_GAIN(x)  (((x) & 0x7) << 0)
 #define PCI171X_MUX_REG                0x04    /* W:   A/D multiplexor control */
-#define PCI171X_MUX_CHANH(x)   (((x) & 0xf) << 8)
-#define PCI171X_MUX_CHANL(x)   (((x) & 0xf) << 0)
+#define PCI171X_MUX_CHANH(x)   (((x) & 0xff) << 8)
+#define PCI171X_MUX_CHANL(x)   (((x) & 0xff) << 0)
 #define PCI171X_MUX_CHAN(x)    (PCI171X_MUX_CHANH(x) | PCI171X_MUX_CHANL(x))
 #define PCI171X_STATUS_REG     0x06    /* R:   status register */
 #define PCI171X_STATUS_IRQ     BIT(11) /* 1=IRQ occurred */
index 673d732..8f398b3 100644 (file)
@@ -72,9 +72,6 @@ static int ni_find_device_routes(const char *device_family,
                }
        }
 
-       if (!rv)
-               return -ENODATA;
-
        /* Second, find the set of routes valid for this device. */
        for (i = 0; ni_device_routes_list[i]; ++i) {
                if (memcmp(ni_device_routes_list[i]->device, board_name,
@@ -84,12 +81,12 @@ static int ni_find_device_routes(const char *device_family,
                }
        }
 
-       if (!dr)
-               return -ENODATA;
-
        tables->route_values = rv;
        tables->valid_routes = dr;
 
+       if (!rv || !dr)
+               return -ENODATA;
+
        return 0;
 }
 
@@ -487,6 +484,9 @@ int ni_find_route_source(const u8 src_sel_reg_value, int dest,
 {
        int src;
 
+       if (!tables->route_values)
+               return -EINVAL;
+
        dest = B(dest); /* subtract NI names offset */
        /* ensure we are not going to under/over run the route value table */
        if (dest < 0 || dest >= NI_NUM_NAMES)
index a7cac07..b5d42f4 100644 (file)
@@ -37,6 +37,7 @@ static const struct usb_device_id rtw_usb_id_tbl[] = {
        {USB_DEVICE(0x2001, 0x3311)}, /* DLink GO-USB-N150 REV B1 */
        {USB_DEVICE(0x2001, 0x331B)}, /* D-Link DWA-121 rev B1 */
        {USB_DEVICE(0x2357, 0x010c)}, /* TP-Link TL-WN722N v2 */
+       {USB_DEVICE(0x2357, 0x0111)}, /* TP-Link TL-WN727N v5.21 */
        {USB_DEVICE(0x0df6, 0x0076)}, /* Sitecom N150 v2 */
        {USB_DEVICE(USB_VENDER_ID_REALTEK, 0xffef)}, /* Rosewill RNX-N150NUB */
        {}      /* Terminating entry */
index 8d19ae7..4e651b6 100644 (file)
@@ -449,8 +449,8 @@ int vnt_vt3184_init(struct vnt_private *priv)
 
        memcpy(array, addr, length);
 
-       ret = vnt_control_out(priv, MESSAGE_TYPE_WRITE, 0,
-                             MESSAGE_REQUEST_BBREG, length, array);
+       ret = vnt_control_out_blocks(priv, VNT_REG_BLOCK_SIZE,
+                                    MESSAGE_REQUEST_BBREG, length, array);
        if (ret)
                goto end;
 
index 56cd77f..7958fc1 100644 (file)
@@ -719,7 +719,7 @@ end:
  */
 int vnt_radio_power_on(struct vnt_private *priv)
 {
-       int ret = true;
+       int ret = 0;
 
        vnt_exit_deep_sleep(priv);
 
index 6074ced..50e1c89 100644 (file)
@@ -259,6 +259,7 @@ struct vnt_private {
        u8 mac_hw;
        /* netdev */
        struct usb_device *usb;
+       struct usb_interface *intf;
 
        u64 tsf_time;
        u8 rx_rate;
index 4ac85ec..9cb924c 100644 (file)
@@ -949,7 +949,7 @@ static const struct ieee80211_ops vnt_mac_ops = {
 
 int vnt_init(struct vnt_private *priv)
 {
-       if (!(vnt_init_registers(priv)))
+       if (vnt_init_registers(priv))
                return -EAGAIN;
 
        SET_IEEE80211_PERM_ADDR(priv->hw, priv->permanent_net_addr);
@@ -992,6 +992,7 @@ vt6656_probe(struct usb_interface *intf, const struct usb_device_id *id)
        priv = hw->priv;
        priv->hw = hw;
        priv->usb = udev;
+       priv->intf = intf;
 
        vnt_set_options(priv);
 
index d3304df..d977d47 100644 (file)
@@ -59,7 +59,9 @@ int vnt_control_out(struct vnt_private *priv, u8 request, u16 value,
 
        kfree(usb_buffer);
 
-       if (ret >= 0 && ret < (int)length)
+       if (ret == (int)length)
+               ret = 0;
+       else
                ret = -EIO;
 
 end_unlock:
@@ -74,6 +76,23 @@ int vnt_control_out_u8(struct vnt_private *priv, u8 reg, u8 reg_off, u8 data)
                               reg_off, reg, sizeof(u8), &data);
 }
 
+int vnt_control_out_blocks(struct vnt_private *priv,
+                          u16 block, u8 reg, u16 length, u8 *data)
+{
+       int ret = 0, i;
+
+       for (i = 0; i < length; i += block) {
+               u16 len = min_t(int, length - i, block);
+
+               ret = vnt_control_out(priv, MESSAGE_TYPE_WRITE,
+                                     i, reg, len, data + i);
+               if (ret)
+                       goto end;
+       }
+end:
+       return ret;
+}
+
 int vnt_control_in(struct vnt_private *priv, u8 request, u16 value,
                   u16 index, u16 length, u8 *buffer)
 {
@@ -103,7 +122,9 @@ int vnt_control_in(struct vnt_private *priv, u8 request, u16 value,
 
        kfree(usb_buffer);
 
-       if (ret >= 0 && ret < (int)length)
+       if (ret == (int)length)
+               ret = 0;
+       else
                ret = -EIO;
 
 end_unlock:
index 95147ec..b65d9c0 100644 (file)
@@ -18,6 +18,8 @@
 
 #include "device.h"
 
+#define VNT_REG_BLOCK_SIZE     64
+
 int vnt_control_out(struct vnt_private *priv, u8 request, u16 value,
                    u16 index, u16 length, u8 *buffer);
 int vnt_control_in(struct vnt_private *priv, u8 request, u16 value,
@@ -26,6 +28,9 @@ int vnt_control_in(struct vnt_private *priv, u8 request, u16 value,
 int vnt_control_out_u8(struct vnt_private *priv, u8 reg, u8 ref_off, u8 data);
 int vnt_control_in_u8(struct vnt_private *priv, u8 reg, u8 reg_off, u8 *data);
 
+int vnt_control_out_blocks(struct vnt_private *priv,
+                          u16 block, u8 reg, u16 len, u8 *data);
+
 int vnt_start_interrupt_urb(struct vnt_private *priv);
 int vnt_submit_rx_urb(struct vnt_private *priv, struct vnt_rcb *rcb);
 int vnt_tx_context(struct vnt_private *priv,
index 3eb2f11..2c5250c 100644 (file)
@@ -99,6 +99,7 @@ void vnt_run_command(struct work_struct *work)
                if (vnt_init(priv)) {
                        /* If fail all ends TODO retry */
                        dev_err(&priv->usb->dev, "failed to start\n");
+                       usb_set_intfdata(priv->intf, NULL);
                        ieee80211_free_hw(priv->hw);
                        return;
                }
index 0332a53..d767eeb 100644 (file)
@@ -28,9 +28,22 @@ static int pool_op_alloc(struct tee_shm_pool_mgr *poolm,
        shm->size = PAGE_SIZE << order;
 
        if (shm->flags & TEE_SHM_DMA_BUF) {
+               unsigned int nr_pages = 1 << order, i;
+               struct page **pages;
+
+               pages = kcalloc(nr_pages, sizeof(pages), GFP_KERNEL);
+               if (!pages)
+                       return -ENOMEM;
+
+               for (i = 0; i < nr_pages; i++) {
+                       pages[i] = page;
+                       page++;
+               }
+
                shm->flags |= TEE_SHM_REGISTER;
-               rc = optee_shm_register(shm->ctx, shm, &page, 1 << order,
+               rc = optee_shm_register(shm->ctx, shm, pages, nr_pages,
                                        (unsigned long)shm->kaddr);
+               kfree(pages);
        }
 
        return rc;
index 015e7d2..0e7cf52 100644 (file)
@@ -110,6 +110,9 @@ static int tsens_register(struct tsens_priv *priv)
        irq = platform_get_irq_byname(pdev, "uplow");
        if (irq < 0) {
                ret = irq;
+               /* For old DTs with no IRQ defined */
+               if (irq == -ENXIO)
+                       ret = 0;
                goto err_put_device;
        }
 
index 226adee..ce5309d 100644 (file)
@@ -663,6 +663,12 @@ static acpi_status acpi_serdev_register_device(struct serdev_controller *ctrl,
        return AE_OK;
 }
 
+static const struct acpi_device_id serdev_acpi_devices_blacklist[] = {
+       { "INT3511", 0 },
+       { "INT3512", 0 },
+       { },
+};
+
 static acpi_status acpi_serdev_add_device(acpi_handle handle, u32 level,
                                          void *data, void **return_value)
 {
@@ -675,6 +681,10 @@ static acpi_status acpi_serdev_add_device(acpi_handle handle, u32 level,
        if (acpi_device_enumerated(adev))
                return AE_OK;
 
+       /* Skip if black listed */
+       if (!acpi_match_device_ids(adev, serdev_acpi_devices_blacklist))
+               return AE_OK;
+
        if (acpi_serdev_check_resources(ctrl, adev))
                return AE_OK;
 
index 5023c85..044c3cb 100644 (file)
@@ -89,8 +89,7 @@ void tty_port_link_device(struct tty_port *port,
 {
        if (WARN_ON(index >= driver->num))
                return;
-       if (!driver->ports[index])
-               driver->ports[index] = port;
+       driver->ports[index] = port;
 }
 EXPORT_SYMBOL_GPL(tty_port_link_device);
 
index 4c1e755..02f6ca2 100644 (file)
@@ -1375,13 +1375,10 @@ static void cdns3_check_usb_interrupt_proceed(struct cdns3_device *priv_dev,
  */
 static irqreturn_t cdns3_device_irq_handler(int irq, void *data)
 {
-       struct cdns3_device *priv_dev;
-       struct cdns3 *cdns = data;
+       struct cdns3_device *priv_dev = data;
        irqreturn_t ret = IRQ_NONE;
        u32 reg;
 
-       priv_dev = cdns->gadget_dev;
-
        /* check USB device interrupt */
        reg = readl(&priv_dev->regs->usb_ists);
        if (reg) {
@@ -1419,14 +1416,12 @@ static irqreturn_t cdns3_device_irq_handler(int irq, void *data)
  */
 static irqreturn_t cdns3_device_thread_irq_handler(int irq, void *data)
 {
-       struct cdns3_device *priv_dev;
-       struct cdns3 *cdns = data;
+       struct cdns3_device *priv_dev = data;
        irqreturn_t ret = IRQ_NONE;
        unsigned long flags;
        int bit;
        u32 reg;
 
-       priv_dev = cdns->gadget_dev;
        spin_lock_irqsave(&priv_dev->lock, flags);
 
        reg = readl(&priv_dev->regs->usb_ists);
@@ -2539,7 +2534,7 @@ void cdns3_gadget_exit(struct cdns3 *cdns)
 
        priv_dev = cdns->gadget_dev;
 
-       devm_free_irq(cdns->dev, cdns->dev_irq, cdns);
+       devm_free_irq(cdns->dev, cdns->dev_irq, priv_dev);
 
        pm_runtime_mark_last_busy(cdns->dev);
        pm_runtime_put_autosuspend(cdns->dev);
@@ -2710,7 +2705,8 @@ static int __cdns3_gadget_init(struct cdns3 *cdns)
        ret = devm_request_threaded_irq(cdns->dev, cdns->dev_irq,
                                        cdns3_device_irq_handler,
                                        cdns3_device_thread_irq_handler,
-                                       IRQF_SHARED, dev_name(cdns->dev), cdns);
+                                       IRQF_SHARED, dev_name(cdns->dev),
+                                       cdns->gadget_dev);
 
        if (ret)
                goto err0;
index b45ceb9..48e4a5c 100644 (file)
@@ -26,6 +26,7 @@ static int (*orig_bus_suspend)(struct usb_hcd *hcd);
 
 struct ehci_ci_priv {
        struct regulator *reg_vbus;
+       bool enabled;
 };
 
 static int ehci_ci_portpower(struct usb_hcd *hcd, int portnum, bool enable)
@@ -37,7 +38,7 @@ static int ehci_ci_portpower(struct usb_hcd *hcd, int portnum, bool enable)
        int ret = 0;
        int port = HCS_N_PORTS(ehci->hcs_params);
 
-       if (priv->reg_vbus) {
+       if (priv->reg_vbus && enable != priv->enabled) {
                if (port > 1) {
                        dev_warn(dev,
                                "Not support multi-port regulator control\n");
@@ -53,6 +54,7 @@ static int ehci_ci_portpower(struct usb_hcd *hcd, int portnum, bool enable)
                                enable ? "enable" : "disable", ret);
                        return ret;
                }
+               priv->enabled = enable;
        }
 
        if (enable && (ci->platdata->phy_mode == USBPHY_INTERFACE_MODE_HSIC)) {
index 5f40117..26bc05e 100644 (file)
@@ -203,9 +203,58 @@ static const unsigned short super_speed_maxpacket_maxes[4] = {
        [USB_ENDPOINT_XFER_INT] = 1024,
 };
 
-static int usb_parse_endpoint(struct device *ddev, int cfgno, int inum,
-    int asnum, struct usb_host_interface *ifp, int num_ep,
-    unsigned char *buffer, int size)
+static bool endpoint_is_duplicate(struct usb_endpoint_descriptor *e1,
+               struct usb_endpoint_descriptor *e2)
+{
+       if (e1->bEndpointAddress == e2->bEndpointAddress)
+               return true;
+
+       if (usb_endpoint_xfer_control(e1) || usb_endpoint_xfer_control(e2)) {
+               if (usb_endpoint_num(e1) == usb_endpoint_num(e2))
+                       return true;
+       }
+
+       return false;
+}
+
+/*
+ * Check for duplicate endpoint addresses in other interfaces and in the
+ * altsetting currently being parsed.
+ */
+static bool config_endpoint_is_duplicate(struct usb_host_config *config,
+               int inum, int asnum, struct usb_endpoint_descriptor *d)
+{
+       struct usb_endpoint_descriptor *epd;
+       struct usb_interface_cache *intfc;
+       struct usb_host_interface *alt;
+       int i, j, k;
+
+       for (i = 0; i < config->desc.bNumInterfaces; ++i) {
+               intfc = config->intf_cache[i];
+
+               for (j = 0; j < intfc->num_altsetting; ++j) {
+                       alt = &intfc->altsetting[j];
+
+                       if (alt->desc.bInterfaceNumber == inum &&
+                                       alt->desc.bAlternateSetting != asnum)
+                               continue;
+
+                       for (k = 0; k < alt->desc.bNumEndpoints; ++k) {
+                               epd = &alt->endpoint[k].desc;
+
+                               if (endpoint_is_duplicate(epd, d))
+                                       return true;
+                       }
+               }
+       }
+
+       return false;
+}
+
+static int usb_parse_endpoint(struct device *ddev, int cfgno,
+               struct usb_host_config *config, int inum, int asnum,
+               struct usb_host_interface *ifp, int num_ep,
+               unsigned char *buffer, int size)
 {
        unsigned char *buffer0 = buffer;
        struct usb_endpoint_descriptor *d;
@@ -242,13 +291,10 @@ static int usb_parse_endpoint(struct device *ddev, int cfgno, int inum,
                goto skip_to_next_endpoint_or_interface_descriptor;
 
        /* Check for duplicate endpoint addresses */
-       for (i = 0; i < ifp->desc.bNumEndpoints; ++i) {
-               if (ifp->endpoint[i].desc.bEndpointAddress ==
-                   d->bEndpointAddress) {
-                       dev_warn(ddev, "config %d interface %d altsetting %d has a duplicate endpoint with address 0x%X, skipping\n",
-                           cfgno, inum, asnum, d->bEndpointAddress);
-                       goto skip_to_next_endpoint_or_interface_descriptor;
-               }
+       if (config_endpoint_is_duplicate(config, inum, asnum, d)) {
+               dev_warn(ddev, "config %d interface %d altsetting %d has a duplicate endpoint with address 0x%X, skipping\n",
+                               cfgno, inum, asnum, d->bEndpointAddress);
+               goto skip_to_next_endpoint_or_interface_descriptor;
        }
 
        endpoint = &ifp->endpoint[ifp->desc.bNumEndpoints];
@@ -346,12 +392,16 @@ static int usb_parse_endpoint(struct device *ddev, int cfgno, int inum,
                        endpoint->desc.wMaxPacketSize = cpu_to_le16(8);
        }
 
-       /* Validate the wMaxPacketSize field */
+       /*
+        * Validate the wMaxPacketSize field.
+        * Some devices have isochronous endpoints in altsetting 0;
+        * the USB-2 spec requires such endpoints to have wMaxPacketSize = 0
+        * (see the end of section 5.6.3), so don't warn about them.
+        */
        maxp = usb_endpoint_maxp(&endpoint->desc);
-       if (maxp == 0) {
-               dev_warn(ddev, "config %d interface %d altsetting %d endpoint 0x%X has wMaxPacketSize 0, skipping\n",
+       if (maxp == 0 && !(usb_endpoint_xfer_isoc(d) && asnum == 0)) {
+               dev_warn(ddev, "config %d interface %d altsetting %d endpoint 0x%X has invalid wMaxPacketSize 0\n",
                    cfgno, inum, asnum, d->bEndpointAddress);
-               goto skip_to_next_endpoint_or_interface_descriptor;
        }
 
        /* Find the highest legal maxpacket size for this endpoint */
@@ -522,8 +572,8 @@ static int usb_parse_interface(struct device *ddev, int cfgno,
                if (((struct usb_descriptor_header *) buffer)->bDescriptorType
                     == USB_DT_INTERFACE)
                        break;
-               retval = usb_parse_endpoint(ddev, cfgno, inum, asnum, alt,
-                   num_ep, buffer, size);
+               retval = usb_parse_endpoint(ddev, cfgno, config, inum, asnum,
+                               alt, num_ep, buffer, size);
                if (retval < 0)
                        return retval;
                ++n;
index f229ad6..3405b14 100644 (file)
@@ -1192,6 +1192,7 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type)
                         * PORT_OVER_CURRENT is not. So check for any of them.
                         */
                        if (udev || (portstatus & USB_PORT_STAT_CONNECTION) ||
+                           (portchange & USB_PORT_STAT_C_CONNECTION) ||
                            (portstatus & USB_PORT_STAT_OVERCURRENT) ||
                            (portchange & USB_PORT_STAT_C_OVERCURRENT))
                                set_bit(port1, hub->change_bits);
@@ -2692,7 +2693,7 @@ static unsigned hub_is_wusb(struct usb_hub *hub)
 #define SET_ADDRESS_TRIES      2
 #define GET_DESCRIPTOR_TRIES   2
 #define SET_CONFIG_TRIES       (2 * (use_both_schemes + 1))
-#define USE_NEW_SCHEME(i, scheme)      ((i) / 2 == (int)scheme)
+#define USE_NEW_SCHEME(i, scheme)      ((i) / 2 == (int)(scheme))
 
 #define HUB_ROOT_RESET_TIME    60      /* times are in msec */
 #define HUB_SHORT_RESET_TIME   10
index 0c960a9..154f3f3 100644 (file)
@@ -2467,6 +2467,13 @@ 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;
 }
 
index ae70ce2..797d6ac 100644 (file)
@@ -445,6 +445,7 @@ config USB_TEGRA_XUDC
        tristate "NVIDIA Tegra Superspeed USB 3.0 Device Controller"
        depends on ARCH_TEGRA || COMPILE_TEST
        depends on PHY_TEGRA_XUSB
+       select USB_ROLE_SWITCH
        help
         Enables NVIDIA Tegra USB 3.0 device mode controller driver.
 
index 38183ac..1371b0c 100644 (file)
@@ -415,13 +415,17 @@ static int ohci_da8xx_probe(struct platform_device *pdev)
        }
 
        da8xx_ohci->oc_gpio = devm_gpiod_get_optional(dev, "oc", GPIOD_IN);
-       if (IS_ERR(da8xx_ohci->oc_gpio))
+       if (IS_ERR(da8xx_ohci->oc_gpio)) {
+               error = PTR_ERR(da8xx_ohci->oc_gpio);
                goto err;
+       }
 
        if (da8xx_ohci->oc_gpio) {
                oc_irq = gpiod_to_irq(da8xx_ohci->oc_gpio);
-               if (oc_irq < 0)
+               if (oc_irq < 0) {
+                       error = oc_irq;
                        goto err;
+               }
 
                error = devm_request_threaded_irq(dev, oc_irq, NULL,
                                ohci_da8xx_oc_thread, IRQF_TRIGGER_RISING |
index 5261f8d..e3b8c84 100644 (file)
@@ -75,14 +75,17 @@ static struct musb_hdrc_platform_data jz4740_musb_platform_data = {
 static int jz4740_musb_init(struct musb *musb)
 {
        struct device *dev = musb->controller->parent;
+       int err;
 
        if (dev->of_node)
                musb->xceiv = devm_usb_get_phy_by_phandle(dev, "phys", 0);
        else
                musb->xceiv = devm_usb_get_phy(dev, USB_PHY_TYPE_USB2);
        if (IS_ERR(musb->xceiv)) {
-               dev_err(dev, "No transceiver configured\n");
-               return PTR_ERR(musb->xceiv);
+               err = PTR_ERR(musb->xceiv);
+               if (err != -EPROBE_DEFER)
+                       dev_err(dev, "No transceiver configured: %d", err);
+               return err;
        }
 
        /* Silicon does not implement ConfigData register.
index 15cca91..5ebf30b 100644 (file)
@@ -1840,6 +1840,9 @@ ATTRIBUTE_GROUPS(musb);
 #define MUSB_QUIRK_B_INVALID_VBUS_91   (MUSB_DEVCTL_BDEVICE | \
                                         (2 << MUSB_DEVCTL_VBUS_SHIFT) | \
                                         MUSB_DEVCTL_SESSION)
+#define MUSB_QUIRK_B_DISCONNECT_99     (MUSB_DEVCTL_BDEVICE | \
+                                        (3 << MUSB_DEVCTL_VBUS_SHIFT) | \
+                                        MUSB_DEVCTL_SESSION)
 #define MUSB_QUIRK_A_DISCONNECT_19     ((3 << MUSB_DEVCTL_VBUS_SHIFT) | \
                                         MUSB_DEVCTL_SESSION)
 
@@ -1862,6 +1865,11 @@ static void musb_pm_runtime_check_session(struct musb *musb)
        s = MUSB_DEVCTL_FSDEV | MUSB_DEVCTL_LSDEV |
                MUSB_DEVCTL_HR;
        switch (devctl & ~s) {
+       case MUSB_QUIRK_B_DISCONNECT_99:
+               musb_dbg(musb, "Poll devctl in case of suspend after disconnect\n");
+               schedule_delayed_work(&musb->irq_work,
+                                     msecs_to_jiffies(1000));
+               break;
        case MUSB_QUIRK_B_INVALID_VBUS_91:
                if (musb->quirk_retries && !musb->flush_irq_work) {
                        musb_dbg(musb,
@@ -2310,6 +2318,9 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl)
        musb_disable_interrupts(musb);
        musb_writeb(musb->mregs, MUSB_DEVCTL, 0);
 
+       /* MUSB_POWER_SOFTCONN might be already set, JZ4740 does this. */
+       musb_writeb(musb->mregs, MUSB_POWER, 0);
+
        /* Init IRQ workqueue before request_irq */
        INIT_DELAYED_WORK(&musb->irq_work, musb_irq_work);
        INIT_DELAYED_WORK(&musb->deassert_reset_work, musb_deassert_reset);
index 5fc6825..2d3751d 100644 (file)
@@ -425,7 +425,7 @@ struct dma_controller *musbhs_dma_controller_create(struct musb *musb,
        controller->controller.channel_abort = dma_channel_abort;
 
        if (request_irq(irq, dma_controller_irq, 0,
-                       dev_name(musb->controller), &controller->controller)) {
+                       dev_name(musb->controller), controller)) {
                dev_err(dev, "request_irq %d failed!\n", irq);
                musb_dma_controller_destroy(&controller->controller);
 
index df582fe..d3f420f 100644 (file)
@@ -642,9 +642,13 @@ static int ch341_tiocmget(struct tty_struct *tty)
 static int ch341_reset_resume(struct usb_serial *serial)
 {
        struct usb_serial_port *port = serial->port[0];
-       struct ch341_private *priv = usb_get_serial_port_data(port);
+       struct ch341_private *priv;
        int ret;
 
+       priv = usb_get_serial_port_data(port);
+       if (!priv)
+               return 0;
+
        /* reconfigure ch341 serial port after bus-reset */
        ch341_configure(serial->dev, priv);
 
index 9690a5f..5737add 100644 (file)
@@ -716,7 +716,7 @@ static void edge_interrupt_callback(struct urb *urb)
                        if (txCredits) {
                                port = edge_serial->serial->port[portNumber];
                                edge_port = usb_get_serial_port_data(port);
-                               if (edge_port->open) {
+                               if (edge_port && edge_port->open) {
                                        spin_lock_irqsave(&edge_port->ep_lock,
                                                          flags);
                                        edge_port->txCredits += txCredits;
@@ -1725,7 +1725,8 @@ static void edge_break(struct tty_struct *tty, int break_state)
 static void process_rcvd_data(struct edgeport_serial *edge_serial,
                                unsigned char *buffer, __u16 bufferLength)
 {
-       struct device *dev = &edge_serial->serial->dev->dev;
+       struct usb_serial *serial = edge_serial->serial;
+       struct device *dev = &serial->dev->dev;
        struct usb_serial_port *port;
        struct edgeport_port *edge_port;
        __u16 lastBufferLength;
@@ -1821,11 +1822,10 @@ static void process_rcvd_data(struct edgeport_serial *edge_serial,
 
                        /* spit this data back into the tty driver if this
                           port is open */
-                       if (rxLen) {
-                               port = edge_serial->serial->port[
-                                                       edge_serial->rxPort];
+                       if (rxLen && edge_serial->rxPort < serial->num_ports) {
+                               port = serial->port[edge_serial->rxPort];
                                edge_port = usb_get_serial_port_data(port);
-                               if (edge_port->open) {
+                               if (edge_port && edge_port->open) {
                                        dev_dbg(dev, "%s - Sending %d bytes to TTY for port %d\n",
                                                __func__, rxLen,
                                                edge_serial->rxPort);
@@ -1833,8 +1833,8 @@ static void process_rcvd_data(struct edgeport_serial *edge_serial,
                                                        rxLen);
                                        edge_port->port->icount.rx += rxLen;
                                }
-                               buffer += rxLen;
                        }
+                       buffer += rxLen;
                        break;
 
                case EXPECT_HDR3:       /* Expect 3rd byte of status header */
@@ -1869,6 +1869,8 @@ static void process_rcvd_status(struct edgeport_serial *edge_serial,
        __u8 code = edge_serial->rxStatusCode;
 
        /* switch the port pointer to the one being currently talked about */
+       if (edge_serial->rxPort >= edge_serial->serial->num_ports)
+               return;
        port = edge_serial->serial->port[edge_serial->rxPort];
        edge_port = usb_get_serial_port_data(port);
        if (edge_port == NULL) {
index e66a59e..aa3dbce 100644 (file)
@@ -1058,6 +1058,8 @@ static void       usa49_glocont_callback(struct urb *urb)
        for (i = 0; i < serial->num_ports; ++i) {
                port = serial->port[i];
                p_priv = usb_get_serial_port_data(port);
+               if (!p_priv)
+                       continue;
 
                if (p_priv->resend_cont) {
                        dev_dbg(&port->dev, "%s - sending setup\n", __func__);
@@ -1459,6 +1461,8 @@ static void usa67_glocont_callback(struct urb *urb)
        for (i = 0; i < serial->num_ports; ++i) {
                port = serial->port[i];
                p_priv = usb_get_serial_port_data(port);
+               if (!p_priv)
+                       continue;
 
                if (p_priv->resend_cont) {
                        dev_dbg(&port->dev, "%s - sending setup\n", __func__);
index cb7aac9..ed2b4e6 100644 (file)
@@ -113,7 +113,7 @@ static int send_control_msg(struct usb_serial_port *port, u8 requesttype,
        retval = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
                                requesttype,
                                USB_DIR_OUT|USB_TYPE_VENDOR|USB_RECIP_INTERFACE,
-                               0, 0, buffer, 1, 0);
+                               0, 0, buffer, 1, USB_CTRL_SET_TIMEOUT);
        kfree(buffer);
 
        if (retval < 0)
index e9491d4..084cc2f 100644 (file)
@@ -248,6 +248,7 @@ static void option_instat_callback(struct urb *urb);
 #define QUECTEL_PRODUCT_BG96                   0x0296
 #define QUECTEL_PRODUCT_EP06                   0x0306
 #define QUECTEL_PRODUCT_EM12                   0x0512
+#define QUECTEL_PRODUCT_RM500Q                 0x0800
 
 #define CMOTECH_VENDOR_ID                      0x16d8
 #define CMOTECH_PRODUCT_6001                   0x6001
@@ -567,6 +568,9 @@ static void option_instat_callback(struct urb *urb);
 /* Interface must have two endpoints */
 #define NUMEP2         BIT(16)
 
+/* Device needs ZLP */
+#define ZLP            BIT(17)
+
 
 static const struct usb_device_id option_ids[] = {
        { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) },
@@ -1101,6 +1105,11 @@ static const struct usb_device_id option_ids[] = {
        { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM12, 0xff, 0xff, 0xff),
          .driver_info = RSVD(1) | RSVD(2) | RSVD(3) | RSVD(4) | NUMEP2 },
        { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM12, 0xff, 0, 0) },
+       { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RM500Q, 0xff, 0xff, 0x30) },
+       { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RM500Q, 0xff, 0, 0) },
+       { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RM500Q, 0xff, 0xff, 0x10),
+         .driver_info = ZLP },
+
        { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6001) },
        { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CMU_300) },
        { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6003),
@@ -1172,6 +1181,8 @@ static const struct usb_device_id option_ids[] = {
          .driver_info = NCTRL(0) | RSVD(3) },
        { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1102, 0xff),    /* Telit ME910 (ECM) */
          .driver_info = NCTRL(0) },
+       { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x110a, 0xff),    /* Telit ME910G1 */
+         .driver_info = NCTRL(0) | RSVD(3) },
        { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE910),
          .driver_info = NCTRL(0) | RSVD(1) | RSVD(2) },
        { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE910_USBCFG4),
@@ -1196,6 +1207,8 @@ static const struct usb_device_id option_ids[] = {
          .driver_info = NCTRL(0) | RSVD(1) },
        { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1901, 0xff),    /* Telit LN940 (MBIM) */
          .driver_info = NCTRL(0) },
+       { USB_DEVICE(TELIT_VENDOR_ID, 0x9010),                          /* Telit SBL FN980 flashing device */
+         .driver_info = NCTRL(0) | ZLP },
        { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MF622, 0xff, 0xff, 0xff) }, /* ZTE WCDMA products */
        { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0002, 0xff, 0xff, 0xff),
          .driver_info = RSVD(1) },
@@ -2097,6 +2110,9 @@ static int option_attach(struct usb_serial *serial)
        if (!(device_flags & NCTRL(iface_desc->bInterfaceNumber)))
                data->use_send_setup = 1;
 
+       if (device_flags & ZLP)
+               data->use_zlp = 1;
+
        spin_lock_init(&data->susp_lock);
 
        usb_set_serial_data(serial, data);
index a62981c..f93b81a 100644 (file)
@@ -841,7 +841,10 @@ static void qt2_update_msr(struct usb_serial_port *port, unsigned char *ch)
        u8 newMSR = (u8) *ch;
        unsigned long flags;
 
+       /* May be called from qt2_process_read_urb() for an unbound port. */
        port_priv = usb_get_serial_port_data(port);
+       if (!port_priv)
+               return;
 
        spin_lock_irqsave(&port_priv->lock, flags);
        port_priv->shadowMSR = newMSR;
@@ -869,7 +872,10 @@ static void qt2_update_lsr(struct usb_serial_port *port, unsigned char *ch)
        unsigned long flags;
        u8 newLSR = (u8) *ch;
 
+       /* May be called from qt2_process_read_urb() for an unbound port. */
        port_priv = usb_get_serial_port_data(port);
+       if (!port_priv)
+               return;
 
        if (newLSR & UART_LSR_BI)
                newLSR &= (u8) (UART_LSR_OE | UART_LSR_BI);
index edbbb13..bd23a7c 100644 (file)
@@ -86,6 +86,8 @@ DEVICE(moto_modem, MOTO_IDS);
 #define MOTOROLA_TETRA_IDS()                   \
        { USB_DEVICE(0x0cad, 0x9011) }, /* Motorola Solutions TETRA PEI */ \
        { USB_DEVICE(0x0cad, 0x9012) }, /* MTP6550 */ \
+       { USB_DEVICE(0x0cad, 0x9013) }, /* MTP3xxx */ \
+       { USB_DEVICE(0x0cad, 0x9015) }, /* MTP85xx */ \
        { USB_DEVICE(0x0cad, 0x9016) }  /* TPG2200 */
 DEVICE(motorola_tetra, MOTOROLA_TETRA_IDS);
 
index 8f066bb..dc7a65b 100644 (file)
@@ -1317,6 +1317,9 @@ static int usb_serial_register(struct usb_serial_driver *driver)
                return -EINVAL;
        }
 
+       /* Prevent individual ports from being unbound. */
+       driver->driver.suppress_bind_attrs = true;
+
        usb_serial_operations_init(driver);
 
        /* Add this device to our list of devices */
index 1c120ea..934e936 100644 (file)
@@ -38,6 +38,7 @@ struct usb_wwan_intf_private {
        spinlock_t susp_lock;
        unsigned int suspended:1;
        unsigned int use_send_setup:1;
+       unsigned int use_zlp:1;
        int in_flight;
        unsigned int open_ports;
        void *private;
index 7e855c8..13be21a 100644 (file)
@@ -461,6 +461,7 @@ static struct urb *usb_wwan_setup_urb(struct usb_serial_port *port,
                                      void (*callback) (struct urb *))
 {
        struct usb_serial *serial = port->serial;
+       struct usb_wwan_intf_private *intfdata = usb_get_serial_data(serial);
        struct urb *urb;
 
        urb = usb_alloc_urb(0, GFP_KERNEL);     /* No ISO */
@@ -471,6 +472,9 @@ static struct urb *usb_wwan_setup_urb(struct usb_serial_port *port,
                          usb_sndbulkpipe(serial->dev, endpoint) | dir,
                          buf, len, callback, ctx);
 
+       if (intfdata->use_zlp && dir == USB_DIR_OUT)
+               urb->transfer_flags |= URB_ZERO_PACKET;
+
        return urb;
 }
 
index c1f7073..8b4ff9f 100644 (file)
@@ -432,20 +432,30 @@ irqreturn_t tcpci_irq(struct tcpci *tcpci)
 
        if (status & TCPC_ALERT_RX_STATUS) {
                struct pd_message msg;
-               unsigned int cnt;
+               unsigned int cnt, payload_cnt;
                u16 header;
 
                regmap_read(tcpci->regmap, TCPC_RX_BYTE_CNT, &cnt);
+               /*
+                * 'cnt' corresponds to READABLE_BYTE_COUNT in section 4.4.14
+                * of the TCPCI spec [Rev 2.0 Ver 1.0 October 2017] and is
+                * defined in table 4-36 as one greater than the number of
+                * bytes received. And that number includes the header. So:
+                */
+               if (cnt > 3)
+                       payload_cnt = cnt - (1 + sizeof(msg.header));
+               else
+                       payload_cnt = 0;
 
                tcpci_read16(tcpci, TCPC_RX_HDR, &header);
                msg.header = cpu_to_le16(header);
 
-               if (WARN_ON(cnt > sizeof(msg.payload)))
-                       cnt = sizeof(msg.payload);
+               if (WARN_ON(payload_cnt > sizeof(msg.payload)))
+                       payload_cnt = sizeof(msg.payload);
 
-               if (cnt > 0)
+               if (payload_cnt > 0)
                        regmap_raw_read(tcpci->regmap, TCPC_RX_DATA,
-                                       &msg.payload, cnt);
+                                       &msg.payload, payload_cnt);
 
                /* Read complete, clear RX status alert bit */
                tcpci_write16(tcpci, TCPC_ALERT, TCPC_ALERT_RX_STATUS);
index 8569bbd..831c947 100644 (file)
@@ -94,15 +94,15 @@ void ucsi_connector_change(struct ucsi *ucsi, u8 num);
 #define UCSI_ENABLE_NTFY_CMD_COMPLETE          BIT(16)
 #define UCSI_ENABLE_NTFY_EXT_PWR_SRC_CHANGE    BIT(17)
 #define UCSI_ENABLE_NTFY_PWR_OPMODE_CHANGE     BIT(18)
-#define UCSI_ENABLE_NTFY_CAP_CHANGE            BIT(19)
-#define UCSI_ENABLE_NTFY_PWR_LEVEL_CHANGE      BIT(20)
-#define UCSI_ENABLE_NTFY_PD_RESET_COMPLETE     BIT(21)
-#define UCSI_ENABLE_NTFY_CAM_CHANGE            BIT(22)
-#define UCSI_ENABLE_NTFY_BAT_STATUS_CHANGE     BIT(23)
-#define UCSI_ENABLE_NTFY_PARTNER_CHANGE                BIT(24)
-#define UCSI_ENABLE_NTFY_PWR_DIR_CHANGE                BIT(25)
-#define UCSI_ENABLE_NTFY_CONNECTOR_CHANGE      BIT(26)
-#define UCSI_ENABLE_NTFY_ERROR                 BIT(27)
+#define UCSI_ENABLE_NTFY_CAP_CHANGE            BIT(21)
+#define UCSI_ENABLE_NTFY_PWR_LEVEL_CHANGE      BIT(22)
+#define UCSI_ENABLE_NTFY_PD_RESET_COMPLETE     BIT(23)
+#define UCSI_ENABLE_NTFY_CAM_CHANGE            BIT(24)
+#define UCSI_ENABLE_NTFY_BAT_STATUS_CHANGE     BIT(25)
+#define UCSI_ENABLE_NTFY_PARTNER_CHANGE                BIT(27)
+#define UCSI_ENABLE_NTFY_PWR_DIR_CHANGE                BIT(28)
+#define UCSI_ENABLE_NTFY_CONNECTOR_CHANGE      BIT(30)
+#define UCSI_ENABLE_NTFY_ERROR                 BIT(31)
 #define UCSI_ENABLE_NTFY_ALL                   0xdbe70000
 
 /* SET_UOR command bits */
index 497f979..5c794f4 100644 (file)
@@ -908,6 +908,7 @@ static struct dentry *afs_lookup(struct inode *dir, struct dentry *dentry,
                                 unsigned int flags)
 {
        struct afs_vnode *dvnode = AFS_FS_I(dir);
+       struct afs_fid fid = {};
        struct inode *inode;
        struct dentry *d;
        struct key *key;
@@ -951,21 +952,18 @@ static struct dentry *afs_lookup(struct inode *dir, struct dentry *dentry,
        afs_stat_v(dvnode, n_lookup);
        inode = afs_do_lookup(dir, dentry, key);
        key_put(key);
-       if (inode == ERR_PTR(-ENOENT)) {
+       if (inode == ERR_PTR(-ENOENT))
                inode = afs_try_auto_mntpt(dentry, dir);
-       } else {
-               dentry->d_fsdata =
-                       (void *)(unsigned long)dvnode->status.data_version;
-       }
+
+       if (!IS_ERR_OR_NULL(inode))
+               fid = AFS_FS_I(inode)->fid;
+
        d = d_splice_alias(inode, dentry);
        if (!IS_ERR_OR_NULL(d)) {
                d->d_fsdata = dentry->d_fsdata;
-               trace_afs_lookup(dvnode, &d->d_name,
-                                inode ? AFS_FS_I(inode) : NULL);
+               trace_afs_lookup(dvnode, &d->d_name, &fid);
        } else {
-               trace_afs_lookup(dvnode, &dentry->d_name,
-                                IS_ERR_OR_NULL(inode) ? NULL
-                                : AFS_FS_I(inode));
+               trace_afs_lookup(dvnode, &dentry->d_name, &fid);
        }
        return d;
 }
index 5509c41..c70baaf 100644 (file)
@@ -4238,18 +4238,30 @@ out:
 }
 
 static int btrfs_unlink_subvol(struct btrfs_trans_handle *trans,
-                              struct inode *dir, u64 objectid,
-                              const char *name, int name_len)
+                              struct inode *dir, struct dentry *dentry)
 {
        struct btrfs_root *root = BTRFS_I(dir)->root;
+       struct btrfs_inode *inode = BTRFS_I(d_inode(dentry));
        struct btrfs_path *path;
        struct extent_buffer *leaf;
        struct btrfs_dir_item *di;
        struct btrfs_key key;
+       const char *name = dentry->d_name.name;
+       int name_len = dentry->d_name.len;
        u64 index;
        int ret;
+       u64 objectid;
        u64 dir_ino = btrfs_ino(BTRFS_I(dir));
 
+       if (btrfs_ino(inode) == BTRFS_FIRST_FREE_OBJECTID) {
+               objectid = inode->root->root_key.objectid;
+       } else if (btrfs_ino(inode) == BTRFS_EMPTY_SUBVOL_DIR_OBJECTID) {
+               objectid = inode->location.objectid;
+       } else {
+               WARN_ON(1);
+               return -EINVAL;
+       }
+
        path = btrfs_alloc_path();
        if (!path)
                return -ENOMEM;
@@ -4271,13 +4283,16 @@ static int btrfs_unlink_subvol(struct btrfs_trans_handle *trans,
        }
        btrfs_release_path(path);
 
-       ret = btrfs_del_root_ref(trans, objectid, root->root_key.objectid,
-                                dir_ino, &index, name, name_len);
-       if (ret < 0) {
-               if (ret != -ENOENT) {
-                       btrfs_abort_transaction(trans, ret);
-                       goto out;
-               }
+       /*
+        * This is a placeholder inode for a subvolume we didn't have a
+        * reference to at the time of the snapshot creation.  In the meantime
+        * we could have renamed the real subvol link into our snapshot, so
+        * depending on btrfs_del_root_ref to return -ENOENT here is incorret.
+        * Instead simply lookup the dir_index_item for this entry so we can
+        * remove it.  Otherwise we know we have a ref to the root and we can
+        * call btrfs_del_root_ref, and it _shouldn't_ fail.
+        */
+       if (btrfs_ino(inode) == BTRFS_EMPTY_SUBVOL_DIR_OBJECTID) {
                di = btrfs_search_dir_index_item(root, path, dir_ino,
                                                 name, name_len);
                if (IS_ERR_OR_NULL(di)) {
@@ -4292,8 +4307,16 @@ static int btrfs_unlink_subvol(struct btrfs_trans_handle *trans,
                leaf = path->nodes[0];
                btrfs_item_key_to_cpu(leaf, &key, path->slots[0]);
                index = key.offset;
+               btrfs_release_path(path);
+       } else {
+               ret = btrfs_del_root_ref(trans, objectid,
+                                        root->root_key.objectid, dir_ino,
+                                        &index, name, name_len);
+               if (ret) {
+                       btrfs_abort_transaction(trans, ret);
+                       goto out;
+               }
        }
-       btrfs_release_path(path);
 
        ret = btrfs_delete_delayed_dir_index(trans, BTRFS_I(dir), index);
        if (ret) {
@@ -4487,8 +4510,7 @@ int btrfs_delete_subvolume(struct inode *dir, struct dentry *dentry)
 
        btrfs_record_snapshot_destroy(trans, BTRFS_I(dir));
 
-       ret = btrfs_unlink_subvol(trans, dir, dest->root_key.objectid,
-                                 dentry->d_name.name, dentry->d_name.len);
+       ret = btrfs_unlink_subvol(trans, dir, dentry);
        if (ret) {
                err = ret;
                btrfs_abort_transaction(trans, ret);
@@ -4583,10 +4605,7 @@ static int btrfs_rmdir(struct inode *dir, struct dentry *dentry)
                return PTR_ERR(trans);
 
        if (unlikely(btrfs_ino(BTRFS_I(inode)) == BTRFS_EMPTY_SUBVOL_DIR_OBJECTID)) {
-               err = btrfs_unlink_subvol(trans, dir,
-                                         BTRFS_I(inode)->location.objectid,
-                                         dentry->d_name.name,
-                                         dentry->d_name.len);
+               err = btrfs_unlink_subvol(trans, dir, dentry);
                goto out;
        }
 
@@ -9536,7 +9555,6 @@ static int btrfs_rename_exchange(struct inode *old_dir,
        u64 new_ino = btrfs_ino(BTRFS_I(new_inode));
        u64 old_idx = 0;
        u64 new_idx = 0;
-       u64 root_objectid;
        int ret;
        bool root_log_pinned = false;
        bool dest_log_pinned = false;
@@ -9642,10 +9660,7 @@ static int btrfs_rename_exchange(struct inode *old_dir,
 
        /* src is a subvolume */
        if (old_ino == BTRFS_FIRST_FREE_OBJECTID) {
-               root_objectid = BTRFS_I(old_inode)->root->root_key.objectid;
-               ret = btrfs_unlink_subvol(trans, old_dir, root_objectid,
-                                         old_dentry->d_name.name,
-                                         old_dentry->d_name.len);
+               ret = btrfs_unlink_subvol(trans, old_dir, old_dentry);
        } else { /* src is an inode */
                ret = __btrfs_unlink_inode(trans, root, BTRFS_I(old_dir),
                                           BTRFS_I(old_dentry->d_inode),
@@ -9661,10 +9676,7 @@ static int btrfs_rename_exchange(struct inode *old_dir,
 
        /* dest is a subvolume */
        if (new_ino == BTRFS_FIRST_FREE_OBJECTID) {
-               root_objectid = BTRFS_I(new_inode)->root->root_key.objectid;
-               ret = btrfs_unlink_subvol(trans, new_dir, root_objectid,
-                                         new_dentry->d_name.name,
-                                         new_dentry->d_name.len);
+               ret = btrfs_unlink_subvol(trans, new_dir, new_dentry);
        } else { /* dest is an inode */
                ret = __btrfs_unlink_inode(trans, dest, BTRFS_I(new_dir),
                                           BTRFS_I(new_dentry->d_inode),
@@ -9862,7 +9874,6 @@ static int btrfs_rename(struct inode *old_dir, struct dentry *old_dentry,
        struct inode *new_inode = d_inode(new_dentry);
        struct inode *old_inode = d_inode(old_dentry);
        u64 index = 0;
-       u64 root_objectid;
        int ret;
        u64 old_ino = btrfs_ino(BTRFS_I(old_inode));
        bool log_pinned = false;
@@ -9970,10 +9981,7 @@ static int btrfs_rename(struct inode *old_dir, struct dentry *old_dentry,
                                BTRFS_I(old_inode), 1);
 
        if (unlikely(old_ino == BTRFS_FIRST_FREE_OBJECTID)) {
-               root_objectid = BTRFS_I(old_inode)->root->root_key.objectid;
-               ret = btrfs_unlink_subvol(trans, old_dir, root_objectid,
-                                       old_dentry->d_name.name,
-                                       old_dentry->d_name.len);
+               ret = btrfs_unlink_subvol(trans, old_dir, old_dentry);
        } else {
                ret = __btrfs_unlink_inode(trans, root, BTRFS_I(old_dir),
                                        BTRFS_I(d_inode(old_dentry)),
@@ -9992,10 +10000,7 @@ static int btrfs_rename(struct inode *old_dir, struct dentry *old_dentry,
                new_inode->i_ctime = current_time(new_inode);
                if (unlikely(btrfs_ino(BTRFS_I(new_inode)) ==
                             BTRFS_EMPTY_SUBVOL_DIR_OBJECTID)) {
-                       root_objectid = BTRFS_I(new_inode)->location.objectid;
-                       ret = btrfs_unlink_subvol(trans, new_dir, root_objectid,
-                                               new_dentry->d_name.name,
-                                               new_dentry->d_name.len);
+                       ret = btrfs_unlink_subvol(trans, new_dir, new_dentry);
                        BUG_ON(new_inode->i_nlink == 0);
                } else {
                        ret = btrfs_unlink_inode(trans, dest, BTRFS_I(new_dir),
index 18e328c..12ae31e 100644 (file)
@@ -4252,7 +4252,19 @@ static long btrfs_ioctl_scrub(struct file *file, void __user *arg)
                              &sa->progress, sa->flags & BTRFS_SCRUB_READONLY,
                              0);
 
-       if (ret == 0 && copy_to_user(arg, sa, sizeof(*sa)))
+       /*
+        * Copy scrub args to user space even if btrfs_scrub_dev() returned an
+        * error. This is important as it allows user space to know how much
+        * progress scrub has done. For example, if scrub is canceled we get
+        * -ECANCELED from btrfs_scrub_dev() and return that error back to user
+        * space. Later user space can inspect the progress from the structure
+        * btrfs_ioctl_scrub_args and resume scrub from where it left off
+        * previously (btrfs-progs does this).
+        * If we fail to copy the btrfs_ioctl_scrub_args structure to user space
+        * then return -EFAULT to signal the structure was not copied or it may
+        * be corrupt and unreliable due to a partial copy.
+        */
+       if (copy_to_user(arg, sa, sizeof(*sa)))
                ret = -EFAULT;
 
        if (!(sa->flags & BTRFS_SCRUB_READONLY))
index d4282e1..39fc8c3 100644 (file)
@@ -2423,8 +2423,12 @@ int btrfs_qgroup_account_extent(struct btrfs_trans_handle *trans, u64 bytenr,
        u64 nr_old_roots = 0;
        int ret = 0;
 
+       /*
+        * If quotas get disabled meanwhile, the resouces need to be freed and
+        * we can't just exit here.
+        */
        if (!test_bit(BTRFS_FS_QUOTA_ENABLED, &fs_info->flags))
-               return 0;
+               goto out_free;
 
        if (new_roots) {
                if (!maybe_fs_roots(new_roots))
index c582457..da5abd6 100644 (file)
@@ -517,6 +517,34 @@ static int update_backref_cache(struct btrfs_trans_handle *trans,
        return 1;
 }
 
+static bool reloc_root_is_dead(struct btrfs_root *root)
+{
+       /*
+        * Pair with set_bit/clear_bit in clean_dirty_subvols and
+        * btrfs_update_reloc_root. We need to see the updated bit before
+        * trying to access reloc_root
+        */
+       smp_rmb();
+       if (test_bit(BTRFS_ROOT_DEAD_RELOC_TREE, &root->state))
+               return true;
+       return false;
+}
+
+/*
+ * Check if this subvolume tree has valid reloc tree.
+ *
+ * Reloc tree after swap is considered dead, thus not considered as valid.
+ * This is enough for most callers, as they don't distinguish dead reloc root
+ * from no reloc root.  But should_ignore_root() below is a special case.
+ */
+static bool have_reloc_root(struct btrfs_root *root)
+{
+       if (reloc_root_is_dead(root))
+               return false;
+       if (!root->reloc_root)
+               return false;
+       return true;
+}
 
 static int should_ignore_root(struct btrfs_root *root)
 {
@@ -525,6 +553,10 @@ static int should_ignore_root(struct btrfs_root *root)
        if (!test_bit(BTRFS_ROOT_REF_COWS, &root->state))
                return 0;
 
+       /* This root has been merged with its reloc tree, we can ignore it */
+       if (reloc_root_is_dead(root))
+               return 1;
+
        reloc_root = root->reloc_root;
        if (!reloc_root)
                return 0;
@@ -1439,7 +1471,7 @@ int btrfs_init_reloc_root(struct btrfs_trans_handle *trans,
         * The subvolume has reloc tree but the swap is finished, no need to
         * create/update the dead reloc tree
         */
-       if (test_bit(BTRFS_ROOT_DEAD_RELOC_TREE, &root->state))
+       if (reloc_root_is_dead(root))
                return 0;
 
        if (root->reloc_root) {
@@ -1478,8 +1510,7 @@ int btrfs_update_reloc_root(struct btrfs_trans_handle *trans,
        struct btrfs_root_item *root_item;
        int ret;
 
-       if (test_bit(BTRFS_ROOT_DEAD_RELOC_TREE, &root->state) ||
-           !root->reloc_root)
+       if (!have_reloc_root(root))
                goto out;
 
        reloc_root = root->reloc_root;
@@ -1489,6 +1520,11 @@ int btrfs_update_reloc_root(struct btrfs_trans_handle *trans,
        if (fs_info->reloc_ctl->merge_reloc_tree &&
            btrfs_root_refs(root_item) == 0) {
                set_bit(BTRFS_ROOT_DEAD_RELOC_TREE, &root->state);
+               /*
+                * Mark the tree as dead before we change reloc_root so
+                * have_reloc_root will not touch it from now on.
+                */
+               smp_wmb();
                __del_reloc_root(reloc_root);
        }
 
@@ -2201,6 +2237,11 @@ static int clean_dirty_subvols(struct reloc_control *rc)
                                if (ret2 < 0 && !ret)
                                        ret = ret2;
                        }
+                       /*
+                        * Need barrier to ensure clear_bit() only happens after
+                        * root->reloc_root = NULL. Pairs with have_reloc_root.
+                        */
+                       smp_wmb();
                        clear_bit(BTRFS_ROOT_DEAD_RELOC_TREE, &root->state);
                        btrfs_put_fs_root(root);
                } else {
@@ -4718,7 +4759,7 @@ void btrfs_reloc_pre_snapshot(struct btrfs_pending_snapshot *pending,
        struct btrfs_root *root = pending->root;
        struct reloc_control *rc = root->fs_info->reloc_ctl;
 
-       if (!root->reloc_root || !rc)
+       if (!rc || !have_reloc_root(root))
                return;
 
        if (!rc->merge_reloc_tree)
@@ -4752,7 +4793,7 @@ int btrfs_reloc_post_snapshot(struct btrfs_trans_handle *trans,
        struct reloc_control *rc = root->fs_info->reloc_ctl;
        int ret;
 
-       if (!root->reloc_root || !rc)
+       if (!rc || !have_reloc_root(root))
                return 0;
 
        rc = root->fs_info->reloc_ctl;
index 3b17b64..612411c 100644 (file)
@@ -376,11 +376,13 @@ again:
                leaf = path->nodes[0];
                ref = btrfs_item_ptr(leaf, path->slots[0],
                                     struct btrfs_root_ref);
-
-               WARN_ON(btrfs_root_ref_dirid(leaf, ref) != dirid);
-               WARN_ON(btrfs_root_ref_name_len(leaf, ref) != name_len);
                ptr = (unsigned long)(ref + 1);
-               WARN_ON(memcmp_extent_buffer(leaf, name, ptr, name_len));
+               if ((btrfs_root_ref_dirid(leaf, ref) != dirid) ||
+                   (btrfs_root_ref_name_len(leaf, ref) != name_len) ||
+                   memcmp_extent_buffer(leaf, name, ptr, name_len)) {
+                       err = -ENOENT;
+                       goto out;
+               }
                *sequence = btrfs_root_ref_sequence(leaf, ref);
 
                ret = btrfs_del_item(trans, tree_root, path);
index a6d3f08..9b78e72 100644 (file)
@@ -3881,7 +3881,11 @@ int btrfs_balance(struct btrfs_fs_info *fs_info,
                }
        }
 
-       num_devices = btrfs_num_devices(fs_info);
+       /*
+        * rw_devices will not change at the moment, device add/delete/replace
+        * are excluded by EXCL_OP
+        */
+       num_devices = fs_info->fs_devices->rw_devices;
 
        /*
         * SINGLE profile on-disk has no profile bit, but in-memory we have a
index e94a661..18a87ec 100644 (file)
@@ -3031,7 +3031,7 @@ static void end_bio_bh_io_sync(struct bio *bio)
  * errors, this only handles the "we need to be able to
  * do IO at the final sector" case.
  */
-void guard_bio_eod(int op, struct bio *bio)
+void guard_bio_eod(struct bio *bio)
 {
        sector_t maxsector;
        struct hd_struct *part;
@@ -3095,15 +3095,15 @@ static int submit_bh_wbc(int op, int op_flags, struct buffer_head *bh,
        bio->bi_end_io = end_bio_bh_io_sync;
        bio->bi_private = bh;
 
-       /* Take care of bh's that straddle the end of the device */
-       guard_bio_eod(op, bio);
-
        if (buffer_meta(bh))
                op_flags |= REQ_META;
        if (buffer_prio(bh))
                op_flags |= REQ_PRIO;
        bio_set_op_attrs(bio, op, op_flags);
 
+       /* Take care of bh's that straddle the end of the device */
+       guard_bio_eod(bio);
+
        if (wbc) {
                wbc_init_bio(wbc, bio);
                wbc_account_cgroup_owner(wbc, bh->b_page, bh->b_size);
index 00dfe17..c5e6eff 100644 (file)
@@ -352,7 +352,7 @@ static struct kobject *cdev_get(struct cdev *p)
 
        if (owner && !try_module_get(owner))
                return NULL;
-       kobj = kobject_get(&p->kobj);
+       kobj = kobject_get_unless_zero(&p->kobj);
        if (!kobj)
                module_put(owner);
        return kobj;
index a63d779..ce71538 100644 (file)
@@ -882,6 +882,7 @@ static void fuse_send_readpages(struct fuse_io_args *ia, struct file *file)
        struct fuse_args_pages *ap = &ia->ap;
        loff_t pos = page_offset(ap->pages[0]);
        size_t count = ap->num_pages << PAGE_SHIFT;
+       ssize_t res;
        int err;
 
        ap->args.out_pages = true;
@@ -896,7 +897,8 @@ static void fuse_send_readpages(struct fuse_io_args *ia, struct file *file)
                if (!err)
                        return;
        } else {
-               err = fuse_simple_request(fc, &ap->args);
+               res = fuse_simple_request(fc, &ap->args);
+               err = res < 0 ? res : 0;
        }
        fuse_readpages_end(fc, &ap->args, err);
 }
index 4a7da1d..e3fa695 100644 (file)
@@ -38,7 +38,7 @@ static inline int __sync_blockdev(struct block_device *bdev, int wait)
 /*
  * buffer.c
  */
-extern void guard_bio_eod(int rw, struct bio *bio);
+extern void guard_bio_eod(struct bio *bio);
 extern int __block_write_begin_int(struct page *page, loff_t pos, unsigned len,
                get_block_t *get_block, struct iomap *iomap);
 
index 541c8a3..5147d22 100644 (file)
@@ -445,10 +445,14 @@ next:
                        task_unlock(current);
                }
                if ((work->flags & IO_WQ_WORK_NEEDS_USER) && !worker->mm &&
-                   wq->mm && mmget_not_zero(wq->mm)) {
-                       use_mm(wq->mm);
-                       set_fs(USER_DS);
-                       worker->mm = wq->mm;
+                   wq->mm) {
+                       if (mmget_not_zero(wq->mm)) {
+                               use_mm(wq->mm);
+                               set_fs(USER_DS);
+                               worker->mm = wq->mm;
+                       } else {
+                               work->flags |= IO_WQ_WORK_CANCEL;
+                       }
                }
                if (!worker->creds)
                        worker->creds = override_creds(wq->creds);
index 562e3a1..187dd94 100644 (file)
@@ -1786,6 +1786,9 @@ static int io_setup_async_rw(struct io_kiocb *req, ssize_t io_size,
                             struct iovec *iovec, struct iovec *fast_iov,
                             struct iov_iter *iter)
 {
+       if (req->opcode == IORING_OP_READ_FIXED ||
+           req->opcode == IORING_OP_WRITE_FIXED)
+               return 0;
        if (!req->io && io_alloc_async_ctx(req))
                return -ENOMEM;
 
@@ -1840,6 +1843,7 @@ static int io_read(struct io_kiocb *req, struct io_kiocb **nxt,
        if (!force_nonblock)
                req->rw.kiocb.ki_flags &= ~IOCB_NOWAIT;
 
+       req->result = 0;
        io_size = ret;
        if (req->flags & REQ_F_LINK)
                req->result = io_size;
@@ -1863,18 +1867,6 @@ static int io_read(struct io_kiocb *req, struct io_kiocb **nxt,
                else
                        ret2 = loop_rw_iter(READ, req->file, kiocb, &iter);
 
-               /*
-                * In case of a short read, punt to async. This can happen
-                * if we have data partially cached. Alternatively we can
-                * return the short read, in which case the application will
-                * need to issue another SQE and wait for it. That SQE will
-                * need async punt anyway, so it's more efficient to do it
-                * here.
-                */
-               if (force_nonblock && !(req->flags & REQ_F_NOWAIT) &&
-                   (req->flags & REQ_F_ISREG) &&
-                   ret2 > 0 && ret2 < io_size)
-                       ret2 = -EAGAIN;
                /* Catch -EAGAIN return for forced non-blocking submission */
                if (!force_nonblock || ret2 != -EAGAIN) {
                        kiocb_done(kiocb, ret2, nxt, req->in_async);
@@ -1939,6 +1931,7 @@ static int io_write(struct io_kiocb *req, struct io_kiocb **nxt,
        if (!force_nonblock)
                req->rw.kiocb.ki_flags &= ~IOCB_NOWAIT;
 
+       req->result = 0;
        io_size = ret;
        if (req->flags & REQ_F_LINK)
                req->result = io_size;
@@ -2046,6 +2039,28 @@ static bool io_req_cancelled(struct io_kiocb *req)
        return false;
 }
 
+static void io_link_work_cb(struct io_wq_work **workptr)
+{
+       struct io_wq_work *work = *workptr;
+       struct io_kiocb *link = work->data;
+
+       io_queue_linked_timeout(link);
+       work->func = io_wq_submit_work;
+}
+
+static void io_wq_assign_next(struct io_wq_work **workptr, struct io_kiocb *nxt)
+{
+       struct io_kiocb *link;
+
+       io_prep_async_work(nxt, &link);
+       *workptr = &nxt->work;
+       if (link) {
+               nxt->work.flags |= IO_WQ_WORK_CB;
+               nxt->work.func = io_link_work_cb;
+               nxt->work.data = link;
+       }
+}
+
 static void io_fsync_finish(struct io_wq_work **workptr)
 {
        struct io_kiocb *req = container_of(*workptr, struct io_kiocb, work);
@@ -2064,7 +2079,7 @@ static void io_fsync_finish(struct io_wq_work **workptr)
        io_cqring_add_event(req, ret);
        io_put_req_find_next(req, &nxt);
        if (nxt)
-               *workptr = &nxt->work;
+               io_wq_assign_next(workptr, nxt);
 }
 
 static int io_fsync(struct io_kiocb *req, struct io_kiocb **nxt,
@@ -2120,7 +2135,7 @@ static void io_sync_file_range_finish(struct io_wq_work **workptr)
        io_cqring_add_event(req, ret);
        io_put_req_find_next(req, &nxt);
        if (nxt)
-               *workptr = &nxt->work;
+               io_wq_assign_next(workptr, nxt);
 }
 
 static int io_sync_file_range(struct io_kiocb *req, struct io_kiocb **nxt,
@@ -2386,7 +2401,7 @@ static void io_accept_finish(struct io_wq_work **workptr)
                return;
        __io_accept(req, &nxt, false);
        if (nxt)
-               *workptr = &nxt->work;
+               io_wq_assign_next(workptr, nxt);
 }
 #endif
 
@@ -2617,7 +2632,7 @@ static void io_poll_complete_work(struct io_wq_work **workptr)
                req_set_fail_links(req);
        io_put_req_find_next(req, &nxt);
        if (nxt)
-               *workptr = &nxt->work;
+               io_wq_assign_next(workptr, nxt);
 }
 
 static int io_poll_wake(struct wait_queue_entry *wait, unsigned mode, int sync,
@@ -3271,24 +3286,24 @@ static int io_issue_sqe(struct io_kiocb *req, const struct io_uring_sqe *sqe,
                return ret;
 
        if (ctx->flags & IORING_SETUP_IOPOLL) {
+               const bool in_async = io_wq_current_is_worker();
+
                if (req->result == -EAGAIN)
                        return -EAGAIN;
 
+               /* workqueue context doesn't hold uring_lock, grab it now */
+               if (in_async)
+                       mutex_lock(&ctx->uring_lock);
+
                io_iopoll_req_issued(req);
+
+               if (in_async)
+                       mutex_unlock(&ctx->uring_lock);
        }
 
        return 0;
 }
 
-static void io_link_work_cb(struct io_wq_work **workptr)
-{
-       struct io_wq_work *work = *workptr;
-       struct io_kiocb *link = work->data;
-
-       io_queue_linked_timeout(link);
-       work->func = io_wq_submit_work;
-}
-
 static void io_wq_submit_work(struct io_wq_work **workptr)
 {
        struct io_wq_work *work = *workptr;
@@ -3325,17 +3340,8 @@ static void io_wq_submit_work(struct io_wq_work **workptr)
        }
 
        /* if a dependent link is ready, pass it back */
-       if (!ret && nxt) {
-               struct io_kiocb *link;
-
-               io_prep_async_work(nxt, &link);
-               *workptr = &nxt->work;
-               if (link) {
-                       nxt->work.flags |= IO_WQ_WORK_CB;
-                       nxt->work.func = io_link_work_cb;
-                       nxt->work.data = link;
-               }
-       }
+       if (!ret && nxt)
+               io_wq_assign_next(workptr, nxt);
 }
 
 static bool io_req_op_valid(int op)
@@ -5153,6 +5159,12 @@ SYSCALL_DEFINE6(io_uring_enter, unsigned int, fd, u32, to_submit,
        } else if (to_submit) {
                struct mm_struct *cur_mm;
 
+               if (current->mm != ctx->sqo_mm ||
+                   current_cred() != ctx->creds) {
+                       ret = -EPERM;
+                       goto out;
+               }
+
                to_submit = min(to_submit, ctx->sq_entries);
                mutex_lock(&ctx->uring_lock);
                /* already have mm, so io_submit_sqes() won't try to grab it */
index a63620c..ccba3c4 100644 (file)
@@ -62,7 +62,7 @@ static struct bio *mpage_bio_submit(int op, int op_flags, struct bio *bio)
 {
        bio->bi_end_io = mpage_end_io;
        bio_set_op_attrs(bio, op, op_flags);
-       guard_bio_eod(op, bio);
+       guard_bio_eod(bio);
        submit_bio(bio);
        return NULL;
 }
index d6c91d1..d2720dc 100644 (file)
@@ -1232,6 +1232,7 @@ static int follow_managed(struct path *path, struct nameidata *nd)
                        BUG_ON(!path->dentry->d_op);
                        BUG_ON(!path->dentry->d_op->d_manage);
                        ret = path->dentry->d_op->d_manage(path, false);
+                       flags = smp_load_acquire(&path->dentry->d_flags);
                        if (ret < 0)
                                break;
                }
@@ -1649,17 +1650,15 @@ again:
        if (IS_ERR(dentry))
                return dentry;
        if (unlikely(!d_in_lookup(dentry))) {
-               if (!(flags & LOOKUP_NO_REVAL)) {
-                       int error = d_revalidate(dentry, flags);
-                       if (unlikely(error <= 0)) {
-                               if (!error) {
-                                       d_invalidate(dentry);
-                                       dput(dentry);
-                                       goto again;
-                               }
+               int error = d_revalidate(dentry, flags);
+               if (unlikely(error <= 0)) {
+                       if (!error) {
+                               d_invalidate(dentry);
                                dput(dentry);
-                               dentry = ERR_PTR(error);
+                               goto again;
                        }
+                       dput(dentry);
+                       dentry = ERR_PTR(error);
                }
        } else {
                old = inode->i_op->lookup(inode, dentry, flags);
@@ -2617,72 +2616,6 @@ int user_path_at_empty(int dfd, const char __user *name, unsigned flags,
 }
 EXPORT_SYMBOL(user_path_at_empty);
 
-/**
- * mountpoint_last - look up last component for umount
- * @nd:   pathwalk nameidata - currently pointing at parent directory of "last"
- *
- * This is a special lookup_last function just for umount. In this case, we
- * need to resolve the path without doing any revalidation.
- *
- * The nameidata should be the result of doing a LOOKUP_PARENT pathwalk. Since
- * mountpoints are always pinned in the dcache, their ancestors are too. Thus,
- * in almost all cases, this lookup will be served out of the dcache. The only
- * cases where it won't are if nd->last refers to a symlink or the path is
- * bogus and it doesn't exist.
- *
- * Returns:
- * -error: if there was an error during lookup. This includes -ENOENT if the
- *         lookup found a negative dentry.
- *
- * 0:      if we successfully resolved nd->last and found it to not to be a
- *         symlink that needs to be followed.
- *
- * 1:      if we successfully resolved nd->last and found it to be a symlink
- *         that needs to be followed.
- */
-static int
-mountpoint_last(struct nameidata *nd)
-{
-       int error = 0;
-       struct dentry *dir = nd->path.dentry;
-       struct path path;
-
-       /* If we're in rcuwalk, drop out of it to handle last component */
-       if (nd->flags & LOOKUP_RCU) {
-               if (unlazy_walk(nd))
-                       return -ECHILD;
-       }
-
-       nd->flags &= ~LOOKUP_PARENT;
-
-       if (unlikely(nd->last_type != LAST_NORM)) {
-               error = handle_dots(nd, nd->last_type);
-               if (error)
-                       return error;
-               path.dentry = dget(nd->path.dentry);
-       } else {
-               path.dentry = d_lookup(dir, &nd->last);
-               if (!path.dentry) {
-                       /*
-                        * No cached dentry. Mounted dentries are pinned in the
-                        * cache, so that means that this dentry is probably
-                        * a symlink or the path doesn't actually point
-                        * to a mounted dentry.
-                        */
-                       path.dentry = lookup_slow(&nd->last, dir,
-                                            nd->flags | LOOKUP_NO_REVAL);
-                       if (IS_ERR(path.dentry))
-                               return PTR_ERR(path.dentry);
-               }
-       }
-       if (d_flags_negative(smp_load_acquire(&path.dentry->d_flags))) {
-               dput(path.dentry);
-               return -ENOENT;
-       }
-       path.mnt = nd->path.mnt;
-       return step_into(nd, &path, 0, d_backing_inode(path.dentry), 0);
-}
-
 /**
  * path_mountpoint - look up a path to be umounted
  * @nd:                lookup context
@@ -2699,14 +2632,17 @@ path_mountpoint(struct nameidata *nd, unsigned flags, struct path *path)
        int err;
 
        while (!(err = link_path_walk(s, nd)) &&
-               (err = mountpoint_last(nd)) > 0) {
+               (err = lookup_last(nd)) > 0) {
                s = trailing_symlink(nd);
        }
+       if (!err && (nd->flags & LOOKUP_RCU))
+               err = unlazy_walk(nd);
+       if (!err)
+               err = handle_lookup_down(nd);
        if (!err) {
                *path = nd->path;
                nd->path.mnt = NULL;
                nd->path.dentry = NULL;
-               follow_mount(path);
        }
        terminate_walk(nd);
        return err;
index f64a33d..2a82dcc 100644 (file)
@@ -206,7 +206,6 @@ TRACE_DEFINE_ENUM(LOOKUP_AUTOMOUNT);
 TRACE_DEFINE_ENUM(LOOKUP_PARENT);
 TRACE_DEFINE_ENUM(LOOKUP_REVAL);
 TRACE_DEFINE_ENUM(LOOKUP_RCU);
-TRACE_DEFINE_ENUM(LOOKUP_NO_REVAL);
 TRACE_DEFINE_ENUM(LOOKUP_OPEN);
 TRACE_DEFINE_ENUM(LOOKUP_CREATE);
 TRACE_DEFINE_ENUM(LOOKUP_EXCL);
@@ -224,7 +223,6 @@ TRACE_DEFINE_ENUM(LOOKUP_DOWN);
                        { LOOKUP_PARENT, "PARENT" }, \
                        { LOOKUP_REVAL, "REVAL" }, \
                        { LOOKUP_RCU, "RCU" }, \
-                       { LOOKUP_NO_REVAL, "NO_REVAL" }, \
                        { LOOKUP_OPEN, "OPEN" }, \
                        { LOOKUP_CREATE, "CREATE" }, \
                        { LOOKUP_EXCL, "EXCL" }, \
index 487ee39..013486b 100644 (file)
@@ -583,12 +583,12 @@ static int ramoops_init_przs(const char *name,
                prz_ar[i] = persistent_ram_new(*paddr, zone_sz, sig,
                                               &cxt->ecc_info,
                                               cxt->memtype, flags, label);
+               kfree(label);
                if (IS_ERR(prz_ar[i])) {
                        err = PTR_ERR(prz_ar[i]);
                        dev_err(dev, "failed to request %s mem region (0x%zx@0x%llx): %d\n",
                                name, record_size,
                                (unsigned long long)*paddr, err);
-                       kfree(label);
 
                        while (i > 0) {
                                i--;
@@ -629,12 +629,12 @@ static int ramoops_init_prz(const char *name,
        label = kasprintf(GFP_KERNEL, "ramoops:%s", name);
        *prz = persistent_ram_new(*paddr, sz, sig, &cxt->ecc_info,
                                  cxt->memtype, PRZ_FLAG_ZAP_OLD, label);
+       kfree(label);
        if (IS_ERR(*prz)) {
                int err = PTR_ERR(*prz);
 
                dev_err(dev, "failed to request %s mem region (0x%zx@0x%llx): %d\n",
                        name, sz, (unsigned long long)*paddr, err);
-               kfree(label);
                return err;
        }
 
index 8823f65..1f4d8c0 100644 (file)
@@ -574,7 +574,7 @@ struct persistent_ram_zone *persistent_ram_new(phys_addr_t start, size_t size,
        /* Initialize general buffer state. */
        raw_spin_lock_init(&prz->buffer_lock);
        prz->flags = flags;
-       prz->label = label;
+       prz->label = kstrdup(label, GFP_KERNEL);
 
        ret = persistent_ram_buffer_map(start, size, prz, memtype);
        if (ret)
index a950a22..cac7404 100644 (file)
  * The cache doesn't need to be flushed when TLB entries change when
  * the cache is mapped to physical memory, not virtual memory
  */
+#ifndef flush_cache_all
 static inline void flush_cache_all(void)
 {
 }
+#endif
 
+#ifndef flush_cache_mm
 static inline void flush_cache_mm(struct mm_struct *mm)
 {
 }
+#endif
 
+#ifndef flush_cache_dup_mm
 static inline void flush_cache_dup_mm(struct mm_struct *mm)
 {
 }
+#endif
 
+#ifndef flush_cache_range
 static inline void flush_cache_range(struct vm_area_struct *vma,
                                     unsigned long start,
                                     unsigned long end)
 {
 }
+#endif
 
+#ifndef flush_cache_page
 static inline void flush_cache_page(struct vm_area_struct *vma,
                                    unsigned long vmaddr,
                                    unsigned long pfn)
 {
 }
+#endif
 
+#ifndef flush_dcache_page
 static inline void flush_dcache_page(struct page *page)
 {
 }
+#endif
 
+#ifndef flush_dcache_mmap_lock
 static inline void flush_dcache_mmap_lock(struct address_space *mapping)
 {
 }
+#endif
 
+#ifndef flush_dcache_mmap_unlock
 static inline void flush_dcache_mmap_unlock(struct address_space *mapping)
 {
 }
+#endif
 
+#ifndef flush_icache_range
 static inline void flush_icache_range(unsigned long start, unsigned long end)
 {
 }
+#endif
 
+#ifndef flush_icache_page
 static inline void flush_icache_page(struct vm_area_struct *vma,
                                     struct page *page)
 {
 }
+#endif
 
+#ifndef flush_icache_user_range
 static inline void flush_icache_user_range(struct vm_area_struct *vma,
                                           struct page *page,
                                           unsigned long addr, int len)
 {
 }
+#endif
 
+#ifndef flush_cache_vmap
 static inline void flush_cache_vmap(unsigned long start, unsigned long end)
 {
 }
+#endif
 
+#ifndef flush_cache_vunmap
 static inline void flush_cache_vunmap(unsigned long start, unsigned long end)
 {
 }
+#endif
 
-#define copy_to_user_page(vma, page, vaddr, dst, src, len) \
+#ifndef copy_to_user_page
+#define copy_to_user_page(vma, page, vaddr, dst, src, len)     \
        do { \
                memcpy(dst, src, len); \
                flush_icache_user_range(vma, page, vaddr, len); \
        } while (0)
+#endif
+
+#ifndef copy_from_user_page
 #define copy_from_user_page(vma, page, vaddr, dst, src, len) \
        memcpy(dst, src, len)
+#endif
 
 #endif /* __ASM_CACHEFLUSH_H */
index d5fc90b..c1bda70 100644 (file)
@@ -605,6 +605,12 @@ struct drm_dp_mst_topology_mgr {
         * &drm_dp_sideband_msg_tx.state once they are queued
         */
        struct mutex qlock;
+
+       /**
+        * @is_waiting_for_dwn_reply: indicate whether is waiting for down reply
+        */
+       bool is_waiting_for_dwn_reply;
+
        /**
         * @tx_msg_downq: List of pending down replies.
         */
index c614438..fbc524a 100644 (file)
@@ -46,9 +46,9 @@
 #define RESET_VD_RMEM                  64
 #define RESET_AUDIN                    65
 #define RESET_DBLK                     66
-#define RESET_PIC_DC                   66
-#define RESET_PSC                      66
-#define RESET_NAND                     66
+#define RESET_PIC_DC                   67
+#define RESET_PSC                      68
+#define RESET_NAND                     69
 #define RESET_GE2D                     70
 #define RESET_PARSER_REG               71
 #define RESET_PARSER_FETCH             72
index 47eb22a..4c636c4 100644 (file)
@@ -328,6 +328,7 @@ struct queue_limits {
        unsigned int            max_sectors;
        unsigned int            max_segment_size;
        unsigned int            physical_block_size;
+       unsigned int            logical_block_size;
        unsigned int            alignment_offset;
        unsigned int            io_min;
        unsigned int            io_opt;
@@ -338,7 +339,6 @@ struct queue_limits {
        unsigned int            discard_granularity;
        unsigned int            discard_alignment;
 
-       unsigned short          logical_block_size;
        unsigned short          max_segments;
        unsigned short          max_integrity_segments;
        unsigned short          max_discard_segments;
@@ -1077,7 +1077,7 @@ extern void blk_queue_max_write_same_sectors(struct request_queue *q,
                unsigned int max_write_same_sectors);
 extern void blk_queue_max_write_zeroes_sectors(struct request_queue *q,
                unsigned int max_write_same_sectors);
-extern void blk_queue_logical_block_size(struct request_queue *, unsigned short);
+extern void blk_queue_logical_block_size(struct request_queue *, unsigned int);
 extern void blk_queue_physical_block_size(struct request_queue *, unsigned int);
 extern void blk_queue_alignment_offset(struct request_queue *q,
                                       unsigned int alignment);
@@ -1291,7 +1291,7 @@ static inline unsigned int queue_max_segment_size(const struct request_queue *q)
        return q->limits.max_segment_size;
 }
 
-static inline unsigned short queue_logical_block_size(const struct request_queue *q)
+static inline unsigned queue_logical_block_size(const struct request_queue *q)
 {
        int retval = 512;
 
@@ -1301,7 +1301,7 @@ static inline unsigned short queue_logical_block_size(const struct request_queue
        return retval;
 }
 
-static inline unsigned short bdev_logical_block_size(struct block_device *bdev)
+static inline unsigned int bdev_logical_block_size(struct block_device *bdev)
 {
        return queue_logical_block_size(bdev_get_queue(bdev));
 }
index 679a422..a81c13a 100644 (file)
@@ -153,26 +153,4 @@ static inline void bvec_advance(const struct bio_vec *bvec,
        }
 }
 
-/*
- * Get the last single-page segment from the multi-page bvec and store it
- * in @seg
- */
-static inline void mp_bvec_last_segment(const struct bio_vec *bvec,
-                                       struct bio_vec *seg)
-{
-       unsigned total = bvec->bv_offset + bvec->bv_len;
-       unsigned last_page = (total - 1) / PAGE_SIZE;
-
-       seg->bv_page = bvec->bv_page + last_page;
-
-       /* the whole segment is inside the last page */
-       if (bvec->bv_offset >= last_page * PAGE_SIZE) {
-               seg->bv_offset = bvec->bv_offset % PAGE_SIZE;
-               seg->bv_len = bvec->bv_len;
-       } else {
-               seg->bv_offset = 0;
-               seg->bv_len = total - last_page * PAGE_SIZE;
-       }
-}
-
 #endif /* __LINUX_BVEC_ITER_H */
index 80a9162..cfaa8fe 100644 (file)
@@ -2658,13 +2658,25 @@ static inline bool want_init_on_free(void)
               !page_poisoning_enabled();
 }
 
-#ifdef CONFIG_DEBUG_PAGEALLOC_ENABLE_DEFAULT
-DECLARE_STATIC_KEY_TRUE(_debug_pagealloc_enabled);
+#ifdef CONFIG_DEBUG_PAGEALLOC
+extern void init_debug_pagealloc(void);
 #else
-DECLARE_STATIC_KEY_FALSE(_debug_pagealloc_enabled);
+static inline void init_debug_pagealloc(void) {}
 #endif
+extern bool _debug_pagealloc_enabled_early;
+DECLARE_STATIC_KEY_FALSE(_debug_pagealloc_enabled);
 
 static inline bool debug_pagealloc_enabled(void)
+{
+       return IS_ENABLED(CONFIG_DEBUG_PAGEALLOC) &&
+               _debug_pagealloc_enabled_early;
+}
+
+/*
+ * For use in fast paths after init_debug_pagealloc() has run, or when a
+ * false negative result is not harmful when called too early.
+ */
+static inline bool debug_pagealloc_enabled_static(void)
 {
        if (!IS_ENABLED(CONFIG_DEBUG_PAGEALLOC))
                return false;
index 89d8ff0..5334ad8 100644 (file)
@@ -215,9 +215,8 @@ enum node_stat_item {
        NR_INACTIVE_FILE,       /*  "     "     "   "       "         */
        NR_ACTIVE_FILE,         /*  "     "     "   "       "         */
        NR_UNEVICTABLE,         /*  "     "     "   "       "         */
-       NR_SLAB_RECLAIMABLE,    /* Please do not reorder this item */
-       NR_SLAB_UNRECLAIMABLE,  /* and this one without looking at
-                                * memcg_flush_percpu_vmstats() first. */
+       NR_SLAB_RECLAIMABLE,
+       NR_SLAB_UNRECLAIMABLE,
        NR_ISOLATED_ANON,       /* Temporary isolated pages from anon lru */
        NR_ISOLATED_FILE,       /* Temporary isolated pages from file lru */
        WORKINGSET_NODES,
index ecc88a4..c04f690 100644 (file)
@@ -40,7 +40,7 @@ typedef enum {
        FL_READING,
        FL_CACHEDPRG,
        /* These 4 come from onenand_state_t, which has been unified here */
-       FL_RESETING,
+       FL_RESETTING,
        FL_OTPING,
        FL_PREPARING_ERASE,
        FL_VERIFYING_ERASE,
index 7fe7b87..07bfb08 100644 (file)
@@ -34,7 +34,6 @@ enum {LAST_NORM, LAST_ROOT, LAST_DOT, LAST_DOTDOT, LAST_BIND};
 
 /* internal use only */
 #define LOOKUP_PARENT          0x0010
-#define LOOKUP_NO_REVAL                0x0080
 #define LOOKUP_JUMPED          0x1000
 #define LOOKUP_ROOT            0x2000
 #define LOOKUP_ROOT_GRABBED    0x0008
index 467d260..716ad1d 100644 (file)
@@ -1929,11 +1929,11 @@ static inline void rseq_migrate(struct task_struct *t)
 
 /*
  * If parent process has a registered restartable sequences area, the
- * child inherits. Only applies when forking a process, not a thread.
+ * child inherits. Unregister rseq for a clone with CLONE_VM set.
  */
 static inline void rseq_fork(struct task_struct *t, unsigned long clone_flags)
 {
-       if (clone_flags & CLONE_THREAD) {
+       if (clone_flags & CLONE_VM) {
                t->rseq = NULL;
                t->rseq_sig = 0;
                t->rseq_event_mask = 0;
diff --git a/include/soc/sifive/sifive_l2_cache.h b/include/soc/sifive/sifive_l2_cache.h
new file mode 100644 (file)
index 0000000..92ade10
--- /dev/null
@@ -0,0 +1,16 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * SiFive L2 Cache Controller header file
+ *
+ */
+
+#ifndef __SOC_SIFIVE_L2_CACHE_H
+#define __SOC_SIFIVE_L2_CACHE_H
+
+extern int register_sifive_l2_error_notifier(struct notifier_block *nb);
+extern int unregister_sifive_l2_error_notifier(struct notifier_block *nb);
+
+#define SIFIVE_L2_ERR_TYPE_CE 0
+#define SIFIVE_L2_ERR_TYPE_UE 1
+
+#endif /* __SOC_SIFIVE_L2_CACHE_H */
index d5ec4fa..564ba1b 100644 (file)
@@ -915,9 +915,9 @@ TRACE_EVENT(afs_call_state,
 
 TRACE_EVENT(afs_lookup,
            TP_PROTO(struct afs_vnode *dvnode, const struct qstr *name,
-                    struct afs_vnode *vnode),
+                    struct afs_fid *fid),
 
-           TP_ARGS(dvnode, name, vnode),
+           TP_ARGS(dvnode, name, fid),
 
            TP_STRUCT__entry(
                    __field_struct(struct afs_fid,      dfid            )
@@ -928,13 +928,7 @@ TRACE_EVENT(afs_lookup,
            TP_fast_assign(
                    int __len = min_t(int, name->len, 23);
                    __entry->dfid = dvnode->fid;
-                   if (vnode) {
-                           __entry->fid = vnode->fid;
-                   } else {
-                           __entry->fid.vid = 0;
-                           __entry->fid.vnode = 0;
-                           __entry->fid.unique = 0;
-                   }
+                   __entry->fid = *fid;
                    memcpy(__entry->name, name->name, __len);
                    __entry->name[__len] = 0;
                           ),
index dd4db33..d82a0f4 100644 (file)
@@ -31,7 +31,8 @@
        EM( SCAN_ALLOC_HUGE_PAGE_FAIL,  "alloc_huge_page_failed")       \
        EM( SCAN_CGROUP_CHARGE_FAIL,    "ccgroup_charge_failed")        \
        EM( SCAN_EXCEED_SWAP_PTE,       "exceed_swap_pte")              \
-       EMe(SCAN_TRUNCATED,             "truncated")                    \
+       EM( SCAN_TRUNCATED,             "truncated")                    \
+       EMe(SCAN_PAGE_HAS_PRIVATE,      "page_has_private")             \
 
 #undef EM
 #undef EMe
index f056b2a..9a61c28 100644 (file)
@@ -34,6 +34,7 @@ struct input_event {
        __kernel_ulong_t __sec;
 #if defined(__sparc__) && defined(__arch64__)
        unsigned int __usec;
+       unsigned int __pad;
 #else
        __kernel_ulong_t __usec;
 #endif
index 2cd7360..da1bc0b 100644 (file)
@@ -553,6 +553,7 @@ static void __init mm_init(void)
         * bigger than MAX_ORDER unless SPARSEMEM.
         */
        page_ext_init_flatmem();
+       init_debug_pagealloc();
        report_meminit();
        mem_init();
        kmem_cache_init();
index a59cc98..4dc279e 100644 (file)
@@ -1909,6 +1909,78 @@ void __cpuhp_remove_state(enum cpuhp_state state, bool invoke)
 }
 EXPORT_SYMBOL(__cpuhp_remove_state);
 
+#ifdef CONFIG_HOTPLUG_SMT
+static void cpuhp_offline_cpu_device(unsigned int cpu)
+{
+       struct device *dev = get_cpu_device(cpu);
+
+       dev->offline = true;
+       /* Tell user space about the state change */
+       kobject_uevent(&dev->kobj, KOBJ_OFFLINE);
+}
+
+static void cpuhp_online_cpu_device(unsigned int cpu)
+{
+       struct device *dev = get_cpu_device(cpu);
+
+       dev->offline = false;
+       /* Tell user space about the state change */
+       kobject_uevent(&dev->kobj, KOBJ_ONLINE);
+}
+
+int cpuhp_smt_disable(enum cpuhp_smt_control ctrlval)
+{
+       int cpu, ret = 0;
+
+       cpu_maps_update_begin();
+       for_each_online_cpu(cpu) {
+               if (topology_is_primary_thread(cpu))
+                       continue;
+               ret = cpu_down_maps_locked(cpu, CPUHP_OFFLINE);
+               if (ret)
+                       break;
+               /*
+                * As this needs to hold the cpu maps lock it's impossible
+                * to call device_offline() because that ends up calling
+                * cpu_down() which takes cpu maps lock. cpu maps lock
+                * needs to be held as this might race against in kernel
+                * abusers of the hotplug machinery (thermal management).
+                *
+                * So nothing would update device:offline state. That would
+                * leave the sysfs entry stale and prevent onlining after
+                * smt control has been changed to 'off' again. This is
+                * called under the sysfs hotplug lock, so it is properly
+                * serialized against the regular offline usage.
+                */
+               cpuhp_offline_cpu_device(cpu);
+       }
+       if (!ret)
+               cpu_smt_control = ctrlval;
+       cpu_maps_update_done();
+       return ret;
+}
+
+int cpuhp_smt_enable(void)
+{
+       int cpu, ret = 0;
+
+       cpu_maps_update_begin();
+       cpu_smt_control = CPU_SMT_ENABLED;
+       for_each_present_cpu(cpu) {
+               /* Skip online CPUs and CPUs on offline nodes */
+               if (cpu_online(cpu) || !node_online(cpu_to_node(cpu)))
+                       continue;
+               ret = _cpu_up(cpu, 0, CPUHP_ONLINE);
+               if (ret)
+                       break;
+               /* See comment in cpuhp_smt_disable() */
+               cpuhp_online_cpu_device(cpu);
+       }
+       cpu_maps_update_done();
+       return ret;
+}
+#endif
+
 #if defined(CONFIG_SYSFS) && defined(CONFIG_HOTPLUG_CPU)
 static ssize_t show_cpuhp_state(struct device *dev,
                                struct device_attribute *attr, char *buf)
@@ -2063,77 +2135,6 @@ static const struct attribute_group cpuhp_cpu_root_attr_group = {
 
 #ifdef CONFIG_HOTPLUG_SMT
 
-static void cpuhp_offline_cpu_device(unsigned int cpu)
-{
-       struct device *dev = get_cpu_device(cpu);
-
-       dev->offline = true;
-       /* Tell user space about the state change */
-       kobject_uevent(&dev->kobj, KOBJ_OFFLINE);
-}
-
-static void cpuhp_online_cpu_device(unsigned int cpu)
-{
-       struct device *dev = get_cpu_device(cpu);
-
-       dev->offline = false;
-       /* Tell user space about the state change */
-       kobject_uevent(&dev->kobj, KOBJ_ONLINE);
-}
-
-int cpuhp_smt_disable(enum cpuhp_smt_control ctrlval)
-{
-       int cpu, ret = 0;
-
-       cpu_maps_update_begin();
-       for_each_online_cpu(cpu) {
-               if (topology_is_primary_thread(cpu))
-                       continue;
-               ret = cpu_down_maps_locked(cpu, CPUHP_OFFLINE);
-               if (ret)
-                       break;
-               /*
-                * As this needs to hold the cpu maps lock it's impossible
-                * to call device_offline() because that ends up calling
-                * cpu_down() which takes cpu maps lock. cpu maps lock
-                * needs to be held as this might race against in kernel
-                * abusers of the hotplug machinery (thermal management).
-                *
-                * So nothing would update device:offline state. That would
-                * leave the sysfs entry stale and prevent onlining after
-                * smt control has been changed to 'off' again. This is
-                * called under the sysfs hotplug lock, so it is properly
-                * serialized against the regular offline usage.
-                */
-               cpuhp_offline_cpu_device(cpu);
-       }
-       if (!ret)
-               cpu_smt_control = ctrlval;
-       cpu_maps_update_done();
-       return ret;
-}
-
-int cpuhp_smt_enable(void)
-{
-       int cpu, ret = 0;
-
-       cpu_maps_update_begin();
-       cpu_smt_control = CPU_SMT_ENABLED;
-       for_each_present_cpu(cpu) {
-               /* Skip online CPUs and CPUs on offline nodes */
-               if (cpu_online(cpu) || !node_online(cpu_to_node(cpu)))
-                       continue;
-               ret = _cpu_up(cpu, 0, CPUHP_ONLINE);
-               if (ret)
-                       break;
-               /* See comment in cpuhp_smt_disable() */
-               cpuhp_online_cpu_device(cpu);
-       }
-       cpu_maps_update_done();
-       return ret;
-}
-
-
 static ssize_t
 __store_smt_control(struct device *dev, struct device_attribute *attr,
                    const char *buf, size_t count)
index 9ed51b7..809a985 100644 (file)
@@ -175,8 +175,8 @@ void exit_creds(struct task_struct *tsk)
        put_cred(cred);
 
 #ifdef CONFIG_KEYS_REQUEST_CACHE
-       key_put(current->cached_requested_key);
-       current->cached_requested_key = NULL;
+       key_put(tsk->cached_requested_key);
+       tsk->cached_requested_key = NULL;
 #endif
 }
 
index a1f8bde..2173c23 100644 (file)
@@ -11465,8 +11465,10 @@ SYSCALL_DEFINE5(perf_event_open,
                }
        }
 
-       if (perf_need_aux_event(event) && !perf_get_aux_event(event, group_leader))
+       if (perf_need_aux_event(event) && !perf_get_aux_event(event, group_leader)) {
+               err = -EINVAL;
                goto err_locked;
+       }
 
        /*
         * Must be under the same ctx::mutex as perf_install_in_context(),
index 2508a4f..0808095 100644 (file)
@@ -2578,6 +2578,16 @@ SYSCALL_DEFINE5(clone, unsigned long, clone_flags, unsigned long, newsp,
 #endif
 
 #ifdef __ARCH_WANT_SYS_CLONE3
+
+/*
+ * copy_thread implementations handle CLONE_SETTLS by reading the TLS value from
+ * the registers containing the syscall arguments for clone. This doesn't work
+ * with clone3 since the TLS value is passed in clone_args instead.
+ */
+#ifndef CONFIG_HAVE_COPY_THREAD_TLS
+#error clone3 requires copy_thread_tls support in arch
+#endif
+
 noinline static int copy_clone_args_from_user(struct kernel_clone_args *kargs,
                                              struct clone_args __user *uargs,
                                              size_t usize)
index 03c518e..0cf84c8 100644 (file)
@@ -1178,6 +1178,7 @@ out_error:
 
 /**
  * wait_for_owner_exiting - Block until the owner has exited
+ * @ret: owner's current futex lock status
  * @exiting:   Pointer to the exiting task
  *
  * Caller must hold a refcount on @exiting.
index 32282e7..32406ef 100644 (file)
@@ -482,7 +482,7 @@ static struct lock_trace *save_trace(void)
        struct lock_trace *trace, *t2;
        struct hlist_head *hash_head;
        u32 hash;
-       unsigned int max_entries;
+       int max_entries;
 
        BUILD_BUG_ON_NOT_POWER_OF_2(STACK_TRACE_HASH_SIZE);
        BUILD_BUG_ON(LOCK_TRACE_SIZE_IN_LONGS >= MAX_STACK_TRACE_ENTRIES);
@@ -490,10 +490,8 @@ static struct lock_trace *save_trace(void)
        trace = (struct lock_trace *)(stack_trace + nr_stack_trace_entries);
        max_entries = MAX_STACK_TRACE_ENTRIES - nr_stack_trace_entries -
                LOCK_TRACE_SIZE_IN_LONGS;
-       trace->nr_entries = stack_trace_save(trace->entries, max_entries, 3);
 
-       if (nr_stack_trace_entries >= MAX_STACK_TRACE_ENTRIES -
-           LOCK_TRACE_SIZE_IN_LONGS - 1) {
+       if (max_entries <= 0) {
                if (!debug_locks_off_graph_unlock())
                        return NULL;
 
@@ -502,6 +500,7 @@ static struct lock_trace *save_trace(void)
 
                return NULL;
        }
+       trace->nr_entries = stack_trace_save(trace->entries, max_entries, 3);
 
        hash = jhash(trace->entries, trace->nr_entries *
                     sizeof(trace->entries[0]), 0);
index 44e6876..0d9b6be 100644 (file)
@@ -1226,8 +1226,8 @@ wait:
                 * In this case, we attempt to acquire the lock again
                 * without sleeping.
                 */
-               if ((wstate == WRITER_HANDOFF) &&
-                   (rwsem_spin_on_owner(sem, 0) == OWNER_NULL))
+               if (wstate == WRITER_HANDOFF &&
+                   rwsem_spin_on_owner(sem, RWSEM_NONSPINNABLE) == OWNER_NULL)
                        goto trylock_again;
 
                /* Block until there are no active lockers. */
index cb9ddcc..43d6179 100644 (file)
@@ -264,12 +264,17 @@ static int ptrace_check_attach(struct task_struct *child, bool ignore_state)
        return ret;
 }
 
-static int ptrace_has_cap(struct user_namespace *ns, unsigned int mode)
+static bool ptrace_has_cap(const struct cred *cred, struct user_namespace *ns,
+                          unsigned int mode)
 {
+       int ret;
+
        if (mode & PTRACE_MODE_NOAUDIT)
-               return has_ns_capability_noaudit(current, ns, CAP_SYS_PTRACE);
+               ret = security_capable(cred, ns, CAP_SYS_PTRACE, CAP_OPT_NOAUDIT);
        else
-               return has_ns_capability(current, ns, CAP_SYS_PTRACE);
+               ret = security_capable(cred, ns, CAP_SYS_PTRACE, CAP_OPT_NONE);
+
+       return ret == 0;
 }
 
 /* Returns 0 on success, -errno on denial. */
@@ -321,7 +326,7 @@ static int __ptrace_may_access(struct task_struct *task, unsigned int mode)
            gid_eq(caller_gid, tcred->sgid) &&
            gid_eq(caller_gid, tcred->gid))
                goto ok;
-       if (ptrace_has_cap(tcred->user_ns, mode))
+       if (ptrace_has_cap(cred, tcred->user_ns, mode))
                goto ok;
        rcu_read_unlock();
        return -EPERM;
@@ -340,7 +345,7 @@ ok:
        mm = task->mm;
        if (mm &&
            ((get_dumpable(mm) != SUID_DUMP_USER) &&
-            !ptrace_has_cap(mm->user_ns, mode)))
+            !ptrace_has_cap(cred, mm->user_ns, mode)))
            return -EPERM;
 
        return security_ptrace_access_check(task, mode);
index 27c48eb..a4f86a9 100644 (file)
@@ -310,6 +310,8 @@ SYSCALL_DEFINE4(rseq, struct rseq __user *, rseq, u32, rseq_len,
        int ret;
 
        if (flags & RSEQ_FLAG_UNREGISTER) {
+               if (flags & ~RSEQ_FLAG_UNREGISTER)
+                       return -EINVAL;
                /* Unregister rseq for current thread. */
                if (current->rseq != rseq || !current->rseq)
                        return -EINVAL;
index 67df65f..20c65a7 100644 (file)
@@ -151,6 +151,9 @@ SYSCALL_DEFINE4(clock_nanosleep, const clockid_t, which_clock, int, flags,
 
 #ifdef CONFIG_COMPAT
 COMPAT_SYS_NI(timer_create);
+#endif
+
+#if defined(CONFIG_COMPAT) || defined(CONFIG_ALPHA)
 COMPAT_SYS_NI(getitimer);
 COMPAT_SYS_NI(setitimer);
 #endif
index 8b192e6..a792d21 100644 (file)
@@ -58,8 +58,9 @@ static void tick_do_update_jiffies64(ktime_t now)
 
        /*
         * Do a quick check without holding jiffies_lock:
+        * The READ_ONCE() pairs with two updates done later in this function.
         */
-       delta = ktime_sub(now, last_jiffies_update);
+       delta = ktime_sub(now, READ_ONCE(last_jiffies_update));
        if (delta < tick_period)
                return;
 
@@ -70,8 +71,9 @@ static void tick_do_update_jiffies64(ktime_t now)
        if (delta >= tick_period) {
 
                delta = ktime_sub(delta, tick_period);
-               last_jiffies_update = ktime_add(last_jiffies_update,
-                                               tick_period);
+               /* Pairs with the lockless read in this function. */
+               WRITE_ONCE(last_jiffies_update,
+                          ktime_add(last_jiffies_update, tick_period));
 
                /* Slow path for long timeouts */
                if (unlikely(delta >= tick_period)) {
@@ -79,8 +81,10 @@ static void tick_do_update_jiffies64(ktime_t now)
 
                        ticks = ktime_divns(delta, incr);
 
-                       last_jiffies_update = ktime_add_ns(last_jiffies_update,
-                                                          incr * ticks);
+                       /* Pairs with the lockless read in this function. */
+                       WRITE_ONCE(last_jiffies_update,
+                                  ktime_add_ns(last_jiffies_update,
+                                               incr * ticks));
                }
                do_timer(++ticks);
 
index 9ecfd3b..42bd8ab 100644 (file)
@@ -221,6 +221,7 @@ int __cvdso_clock_getres_common(clockid_t clock, struct __kernel_timespec *res)
        return 0;
 }
 
+static __maybe_unused
 int __cvdso_clock_getres(clockid_t clock, struct __kernel_timespec *res)
 {
        int ret = __cvdso_clock_getres_common(clock, res);
index 41a0fbd..a880932 100644 (file)
@@ -527,13 +527,13 @@ void prep_transhuge_page(struct page *page)
        set_compound_page_dtor(page, TRANSHUGE_PAGE_DTOR);
 }
 
-static unsigned long __thp_get_unmapped_area(struct file *filp, unsigned long len,
+static unsigned long __thp_get_unmapped_area(struct file *filp,
+               unsigned long addr, unsigned long len,
                loff_t off, unsigned long flags, unsigned long size)
 {
-       unsigned long addr;
        loff_t off_end = off + len;
        loff_t off_align = round_up(off, size);
-       unsigned long len_pad;
+       unsigned long len_pad, ret;
 
        if (off_end <= off_align || (off_end - off_align) < size)
                return 0;
@@ -542,30 +542,40 @@ static unsigned long __thp_get_unmapped_area(struct file *filp, unsigned long le
        if (len_pad < len || (off + len_pad) < off)
                return 0;
 
-       addr = current->mm->get_unmapped_area(filp, 0, len_pad,
+       ret = current->mm->get_unmapped_area(filp, addr, len_pad,
                                              off >> PAGE_SHIFT, flags);
-       if (IS_ERR_VALUE(addr))
+
+       /*
+        * The failure might be due to length padding. The caller will retry
+        * without the padding.
+        */
+       if (IS_ERR_VALUE(ret))
                return 0;
 
-       addr += (off - addr) & (size - 1);
-       return addr;
+       /*
+        * Do not try to align to THP boundary if allocation at the address
+        * hint succeeds.
+        */
+       if (ret == addr)
+               return addr;
+
+       ret += (off - ret) & (size - 1);
+       return ret;
 }
 
 unsigned long thp_get_unmapped_area(struct file *filp, unsigned long addr,
                unsigned long len, unsigned long pgoff, unsigned long flags)
 {
+       unsigned long ret;
        loff_t off = (loff_t)pgoff << PAGE_SHIFT;
 
-       if (addr)
-               goto out;
        if (!IS_DAX(filp->f_mapping->host) || !IS_ENABLED(CONFIG_FS_DAX_PMD))
                goto out;
 
-       addr = __thp_get_unmapped_area(filp, len, off, flags, PMD_SIZE);
-       if (addr)
-               return addr;
-
- out:
+       ret = __thp_get_unmapped_area(filp, addr, len, off, flags, PMD_SIZE);
+       if (ret)
+               return ret;
+out:
        return current->mm->get_unmapped_area(filp, addr, len, pgoff, flags);
 }
 EXPORT_SYMBOL_GPL(thp_get_unmapped_area);
index c5b5f74..6c83cf4 100644 (file)
@@ -3287,49 +3287,34 @@ static u64 mem_cgroup_read_u64(struct cgroup_subsys_state *css,
        }
 }
 
-static void memcg_flush_percpu_vmstats(struct mem_cgroup *memcg, bool slab_only)
+static void memcg_flush_percpu_vmstats(struct mem_cgroup *memcg)
 {
-       unsigned long stat[MEMCG_NR_STAT];
+       unsigned long stat[MEMCG_NR_STAT] = {0};
        struct mem_cgroup *mi;
        int node, cpu, i;
-       int min_idx, max_idx;
-
-       if (slab_only) {
-               min_idx = NR_SLAB_RECLAIMABLE;
-               max_idx = NR_SLAB_UNRECLAIMABLE;
-       } else {
-               min_idx = 0;
-               max_idx = MEMCG_NR_STAT;
-       }
-
-       for (i = min_idx; i < max_idx; i++)
-               stat[i] = 0;
 
        for_each_online_cpu(cpu)
-               for (i = min_idx; i < max_idx; i++)
+               for (i = 0; i < MEMCG_NR_STAT; i++)
                        stat[i] += per_cpu(memcg->vmstats_percpu->stat[i], cpu);
 
        for (mi = memcg; mi; mi = parent_mem_cgroup(mi))
-               for (i = min_idx; i < max_idx; i++)
+               for (i = 0; i < MEMCG_NR_STAT; i++)
                        atomic_long_add(stat[i], &mi->vmstats[i]);
 
-       if (!slab_only)
-               max_idx = NR_VM_NODE_STAT_ITEMS;
-
        for_each_node(node) {
                struct mem_cgroup_per_node *pn = memcg->nodeinfo[node];
                struct mem_cgroup_per_node *pi;
 
-               for (i = min_idx; i < max_idx; i++)
+               for (i = 0; i < NR_VM_NODE_STAT_ITEMS; i++)
                        stat[i] = 0;
 
                for_each_online_cpu(cpu)
-                       for (i = min_idx; i < max_idx; i++)
+                       for (i = 0; i < NR_VM_NODE_STAT_ITEMS; i++)
                                stat[i] += per_cpu(
                                        pn->lruvec_stat_cpu->count[i], cpu);
 
                for (pi = pn; pi; pi = parent_nodeinfo(pi, node))
-                       for (i = min_idx; i < max_idx; i++)
+                       for (i = 0; i < NR_VM_NODE_STAT_ITEMS; i++)
                                atomic_long_add(stat[i], &pi->lruvec_stat[i]);
        }
 }
@@ -3403,13 +3388,9 @@ static void memcg_offline_kmem(struct mem_cgroup *memcg)
                parent = root_mem_cgroup;
 
        /*
-        * Deactivate and reparent kmem_caches. Then flush percpu
-        * slab statistics to have precise values at the parent and
-        * all ancestor levels. It's required to keep slab stats
-        * accurate after the reparenting of kmem_caches.
+        * Deactivate and reparent kmem_caches.
         */
        memcg_deactivate_kmem_caches(memcg, parent);
-       memcg_flush_percpu_vmstats(memcg, true);
 
        kmemcg_id = memcg->kmemcg_id;
        BUG_ON(kmemcg_id < 0);
@@ -4913,7 +4894,7 @@ static void mem_cgroup_free(struct mem_cgroup *memcg)
         * Flush percpu vmstats and vmevents to guarantee the value correctness
         * on parent's and all ancestor levels.
         */
-       memcg_flush_percpu_vmstats(memcg, false);
+       memcg_flush_percpu_vmstats(memcg);
        memcg_flush_percpu_vmevents(memcg);
        __mem_cgroup_free(memcg);
 }
index 067cf7d..b2920ae 100644 (file)
@@ -2148,18 +2148,22 @@ alloc_pages_vma(gfp_t gfp, int order, struct vm_area_struct *vma,
                nmask = policy_nodemask(gfp, pol);
                if (!nmask || node_isset(hpage_node, *nmask)) {
                        mpol_cond_put(pol);
+                       /*
+                        * First, try to allocate THP only on local node, but
+                        * don't reclaim unnecessarily, just compact.
+                        */
                        page = __alloc_pages_node(hpage_node,
-                                               gfp | __GFP_THISNODE, order);
+                               gfp | __GFP_THISNODE | __GFP_NORETRY, order);
 
                        /*
                         * If hugepage allocations are configured to always
                         * synchronous compact or the vma has been madvised
                         * to prefer hugepage backing, retry allowing remote
-                        * memory as well.
+                        * memory with both reclaim and compact as well.
                         */
                        if (!page && (gfp & __GFP_DIRECT_RECLAIM))
                                page = __alloc_pages_node(hpage_node,
-                                               gfp | __GFP_NORETRY, order);
+                                                               gfp, order);
 
                        goto out;
                }
index 50055d2..2caf780 100644 (file)
@@ -201,11 +201,11 @@ static void wb_min_max_ratio(struct bdi_writeback *wb,
        if (this_bw < tot_bw) {
                if (min) {
                        min *= this_bw;
-                       do_div(min, tot_bw);
+                       min = div64_ul(min, tot_bw);
                }
                if (max < 100) {
                        max *= this_bw;
-                       do_div(max, tot_bw);
+                       max = div64_ul(max, tot_bw);
                }
        }
 
@@ -766,7 +766,7 @@ static unsigned long __wb_calc_thresh(struct dirty_throttle_control *dtc)
        struct wb_domain *dom = dtc_dom(dtc);
        unsigned long thresh = dtc->thresh;
        u64 wb_thresh;
-       long numerator, denominator;
+       unsigned long numerator, denominator;
        unsigned long wb_min_ratio, wb_max_ratio;
 
        /*
@@ -777,7 +777,7 @@ static unsigned long __wb_calc_thresh(struct dirty_throttle_control *dtc)
 
        wb_thresh = (thresh * (100 - bdi_min_ratio)) / 100;
        wb_thresh *= numerator;
-       do_div(wb_thresh, denominator);
+       wb_thresh = div64_ul(wb_thresh, denominator);
 
        wb_min_max_ratio(dtc->wb, &wb_min_ratio, &wb_max_ratio);
 
@@ -1102,7 +1102,7 @@ static void wb_update_write_bandwidth(struct bdi_writeback *wb,
        bw = written - min(written, wb->written_stamp);
        bw *= HZ;
        if (unlikely(elapsed > period)) {
-               do_div(bw, elapsed);
+               bw = div64_ul(bw, elapsed);
                avg = bw;
                goto out;
        }
index 4785a8a..d047bf7 100644 (file)
@@ -694,34 +694,27 @@ void prep_compound_page(struct page *page, unsigned int order)
 #ifdef CONFIG_DEBUG_PAGEALLOC
 unsigned int _debug_guardpage_minorder;
 
-#ifdef CONFIG_DEBUG_PAGEALLOC_ENABLE_DEFAULT
-DEFINE_STATIC_KEY_TRUE(_debug_pagealloc_enabled);
-#else
+bool _debug_pagealloc_enabled_early __read_mostly
+                       = IS_ENABLED(CONFIG_DEBUG_PAGEALLOC_ENABLE_DEFAULT);
+EXPORT_SYMBOL(_debug_pagealloc_enabled_early);
 DEFINE_STATIC_KEY_FALSE(_debug_pagealloc_enabled);
-#endif
 EXPORT_SYMBOL(_debug_pagealloc_enabled);
 
 DEFINE_STATIC_KEY_FALSE(_debug_guardpage_enabled);
 
 static int __init early_debug_pagealloc(char *buf)
 {
-       bool enable = false;
-
-       if (kstrtobool(buf, &enable))
-               return -EINVAL;
-
-       if (enable)
-               static_branch_enable(&_debug_pagealloc_enabled);
-
-       return 0;
+       return kstrtobool(buf, &_debug_pagealloc_enabled_early);
 }
 early_param("debug_pagealloc", early_debug_pagealloc);
 
-static void init_debug_guardpage(void)
+void init_debug_pagealloc(void)
 {
        if (!debug_pagealloc_enabled())
                return;
 
+       static_branch_enable(&_debug_pagealloc_enabled);
+
        if (!debug_guardpage_minorder())
                return;
 
@@ -1186,7 +1179,7 @@ static __always_inline bool free_pages_prepare(struct page *page,
         */
        arch_free_page(page, order);
 
-       if (debug_pagealloc_enabled())
+       if (debug_pagealloc_enabled_static())
                kernel_map_pages(page, 1 << order, 0);
 
        kasan_free_nondeferred_pages(page, order);
@@ -1207,7 +1200,7 @@ static bool free_pcp_prepare(struct page *page)
 
 static bool bulkfree_pcp_prepare(struct page *page)
 {
-       if (debug_pagealloc_enabled())
+       if (debug_pagealloc_enabled_static())
                return free_pages_check(page);
        else
                return false;
@@ -1221,7 +1214,7 @@ static bool bulkfree_pcp_prepare(struct page *page)
  */
 static bool free_pcp_prepare(struct page *page)
 {
-       if (debug_pagealloc_enabled())
+       if (debug_pagealloc_enabled_static())
                return free_pages_prepare(page, 0, true);
        else
                return free_pages_prepare(page, 0, false);
@@ -1973,10 +1966,6 @@ void __init page_alloc_init_late(void)
 
        for_each_populated_zone(zone)
                set_zone_contiguous(zone);
-
-#ifdef CONFIG_DEBUG_PAGEALLOC
-       init_debug_guardpage();
-#endif
 }
 
 #ifdef CONFIG_CMA
@@ -2106,7 +2095,7 @@ static inline bool free_pages_prezeroed(void)
  */
 static inline bool check_pcp_refill(struct page *page)
 {
-       if (debug_pagealloc_enabled())
+       if (debug_pagealloc_enabled_static())
                return check_new_page(page);
        else
                return false;
@@ -2128,7 +2117,7 @@ static inline bool check_pcp_refill(struct page *page)
 }
 static inline bool check_new_pcp(struct page *page)
 {
-       if (debug_pagealloc_enabled())
+       if (debug_pagealloc_enabled_static())
                return check_new_page(page);
        else
                return false;
@@ -2155,7 +2144,7 @@ inline void post_alloc_hook(struct page *page, unsigned int order,
        set_page_refcounted(page);
 
        arch_alloc_page(page, order);
-       if (debug_pagealloc_enabled())
+       if (debug_pagealloc_enabled_static())
                kernel_map_pages(page, 1 << order, 1);
        kasan_alloc_pages(page, order);
        kernel_poison_pages(page, 1 << order, 1);
@@ -4476,8 +4465,11 @@ retry_cpuset:
                if (page)
                        goto got_pg;
 
-                if (order >= pageblock_order && (gfp_mask & __GFP_IO) &&
-                    !(gfp_mask & __GFP_RETRY_MAYFAIL)) {
+               /*
+                * Checks for costly allocations with __GFP_NORETRY, which
+                * includes some THP page fault allocations
+                */
+               if (costly_order && (gfp_mask & __GFP_NORETRY)) {
                        /*
                         * If allocating entire pageblock(s) and compaction
                         * failed because all zones are below low watermarks
@@ -4498,23 +4490,6 @@ retry_cpuset:
                        if (compact_result == COMPACT_SKIPPED ||
                            compact_result == COMPACT_DEFERRED)
                                goto nopage;
-               }
-
-               /*
-                * Checks for costly allocations with __GFP_NORETRY, which
-                * includes THP page fault allocations
-                */
-               if (costly_order && (gfp_mask & __GFP_NORETRY)) {
-                       /*
-                        * If compaction is deferred for high-order allocations,
-                        * it is because sync compaction recently failed. If
-                        * this is the case and the caller requested a THP
-                        * allocation, we do not want to heavily disrupt the
-                        * system, so we fail the allocation instead of entering
-                        * direct reclaim.
-                        */
-                       if (compact_result == COMPACT_DEFERRED)
-                               goto nopage;
 
                        /*
                         * Looks like reclaim/compaction is worth trying, but
index 165fa63..8793e8c 100644 (file)
@@ -2107,9 +2107,10 @@ unsigned long shmem_get_unmapped_area(struct file *file,
        /*
         * Our priority is to support MAP_SHARED mapped hugely;
         * and support MAP_PRIVATE mapped hugely too, until it is COWed.
-        * But if caller specified an address hint, respect that as before.
+        * But if caller specified an address hint and we allocated area there
+        * successfully, respect that as before.
         */
-       if (uaddr)
+       if (uaddr == addr)
                return addr;
 
        if (shmem_huge != SHMEM_HUGE_FORCE) {
@@ -2143,7 +2144,7 @@ unsigned long shmem_get_unmapped_area(struct file *file,
        if (inflated_len < len)
                return addr;
 
-       inflated_addr = get_area(NULL, 0, inflated_len, 0, flags);
+       inflated_addr = get_area(NULL, uaddr, inflated_len, 0, flags);
        if (IS_ERR_VALUE(inflated_addr))
                return addr;
        if (inflated_addr & ~PAGE_MASK)
index f1e1840..a896336 100644 (file)
--- a/mm/slab.c
+++ b/mm/slab.c
@@ -1416,7 +1416,7 @@ static void kmem_rcu_free(struct rcu_head *head)
 #if DEBUG
 static bool is_debug_pagealloc_cache(struct kmem_cache *cachep)
 {
-       if (debug_pagealloc_enabled() && OFF_SLAB(cachep) &&
+       if (debug_pagealloc_enabled_static() && OFF_SLAB(cachep) &&
                (cachep->size % PAGE_SIZE) == 0)
                return true;
 
@@ -2008,7 +2008,7 @@ int __kmem_cache_create(struct kmem_cache *cachep, slab_flags_t flags)
         * to check size >= 256. It guarantees that all necessary small
         * sized slab is initialized in current slab initialization sequence.
         */
-       if (debug_pagealloc_enabled() && (flags & SLAB_POISON) &&
+       if (debug_pagealloc_enabled_static() && (flags & SLAB_POISON) &&
                size >= 256 && cachep->object_size > cache_line_size()) {
                if (size < PAGE_SIZE || size % PAGE_SIZE == 0) {
                        size_t tmp_size = ALIGN(size, PAGE_SIZE);
index f0ab6d4..0d95dde 100644 (file)
@@ -903,7 +903,8 @@ static void flush_memcg_workqueue(struct kmem_cache *s)
         * deactivates the memcg kmem_caches through workqueue. Make sure all
         * previous workitems on workqueue are processed.
         */
-       flush_workqueue(memcg_kmem_cache_wq);
+       if (likely(memcg_kmem_cache_wq))
+               flush_workqueue(memcg_kmem_cache_wq);
 
        /*
         * If we're racing with children kmem_cache deactivation, it might
index d113897..8eafccf 100644 (file)
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -288,7 +288,7 @@ static inline void *get_freepointer_safe(struct kmem_cache *s, void *object)
        unsigned long freepointer_addr;
        void *p;
 
-       if (!debug_pagealloc_enabled())
+       if (!debug_pagealloc_enabled_static())
                return get_freepointer(s, object);
 
        freepointer_addr = (unsigned long)object + s->offset;
index b20ab7c..3822ecb 100644 (file)
@@ -777,7 +777,14 @@ static void section_deactivate(unsigned long pfn, unsigned long nr_pages,
        if (bitmap_empty(subsection_map, SUBSECTIONS_PER_SECTION)) {
                unsigned long section_nr = pfn_to_section_nr(pfn);
 
-               if (!section_is_early) {
+               /*
+                * When removing an early section, the usage map is kept (as the
+                * usage maps of other sections fall into the same page). It
+                * will be re-used when re-adding the section - which is then no
+                * longer an early section. If the usage map is PageReserved, it
+                * was allocated during boot.
+                */
+               if (!PageReserved(virt_to_page(ms->usage))) {
                        kfree(ms->usage);
                        ms->usage = NULL;
                }
index e9681dc..b29ad17 100644 (file)
@@ -1383,7 +1383,7 @@ static void free_unmap_vmap_area(struct vmap_area *va)
 {
        flush_cache_vunmap(va->va_start, va->va_end);
        unmap_vmap_area(va);
-       if (debug_pagealloc_enabled())
+       if (debug_pagealloc_enabled_static())
                flush_tlb_kernel_range(va->va_start, va->va_end);
 
        free_vmap_area_noflush(va);
@@ -1681,7 +1681,7 @@ static void vb_free(const void *addr, unsigned long size)
 
        vunmap_page_range((unsigned long)addr, (unsigned long)addr + size);
 
-       if (debug_pagealloc_enabled())
+       if (debug_pagealloc_enabled_static())
                flush_tlb_kernel_range((unsigned long)addr,
                                        (unsigned long)addr + size);
 
index 77c7dd7..fda3889 100644 (file)
@@ -77,7 +77,7 @@
 static void rpcrdma_sendctx_put_locked(struct rpcrdma_xprt *r_xprt,
                                       struct rpcrdma_sendctx *sc);
 static void rpcrdma_reqs_reset(struct rpcrdma_xprt *r_xprt);
-static void rpcrdma_reps_destroy(struct rpcrdma_buffer *buf);
+static void rpcrdma_reps_unmap(struct rpcrdma_xprt *r_xprt);
 static void rpcrdma_mrs_create(struct rpcrdma_xprt *r_xprt);
 static void rpcrdma_mrs_destroy(struct rpcrdma_xprt *r_xprt);
 static struct rpcrdma_regbuf *
@@ -244,6 +244,7 @@ rpcrdma_cm_event_handler(struct rdma_cm_id *id, struct rdma_cm_event *event)
                        ia->ri_id->device->name,
                        rpcrdma_addrstr(r_xprt), rpcrdma_portstr(r_xprt));
 #endif
+               init_completion(&ia->ri_remove_done);
                set_bit(RPCRDMA_IAF_REMOVING, &ia->ri_flags);
                ep->rep_connected = -ENODEV;
                xprt_force_disconnect(xprt);
@@ -297,7 +298,6 @@ rpcrdma_create_id(struct rpcrdma_xprt *xprt, struct rpcrdma_ia *ia)
        int rc;
 
        init_completion(&ia->ri_done);
-       init_completion(&ia->ri_remove_done);
 
        id = rdma_create_id(xprt->rx_xprt.xprt_net, rpcrdma_cm_event_handler,
                            xprt, RDMA_PS_TCP, IB_QPT_RC);
@@ -421,7 +421,7 @@ rpcrdma_ia_remove(struct rpcrdma_ia *ia)
        /* The ULP is responsible for ensuring all DMA
         * mappings and MRs are gone.
         */
-       rpcrdma_reps_destroy(buf);
+       rpcrdma_reps_unmap(r_xprt);
        list_for_each_entry(req, &buf->rb_allreqs, rl_all) {
                rpcrdma_regbuf_dma_unmap(req->rl_rdmabuf);
                rpcrdma_regbuf_dma_unmap(req->rl_sendbuf);
@@ -599,6 +599,7 @@ static int rpcrdma_ep_recreate_xprt(struct rpcrdma_xprt *r_xprt,
                                    struct ib_qp_init_attr *qp_init_attr)
 {
        struct rpcrdma_ia *ia = &r_xprt->rx_ia;
+       struct rpcrdma_ep *ep = &r_xprt->rx_ep;
        int rc, err;
 
        trace_xprtrdma_reinsert(r_xprt);
@@ -613,6 +614,7 @@ static int rpcrdma_ep_recreate_xprt(struct rpcrdma_xprt *r_xprt,
                pr_err("rpcrdma: rpcrdma_ep_create returned %d\n", err);
                goto out2;
        }
+       memcpy(qp_init_attr, &ep->rep_attr, sizeof(*qp_init_attr));
 
        rc = -ENETUNREACH;
        err = rdma_create_qp(ia->ri_id, ia->ri_pd, qp_init_attr);
@@ -1090,6 +1092,7 @@ static struct rpcrdma_rep *rpcrdma_rep_create(struct rpcrdma_xprt *r_xprt,
        rep->rr_recv_wr.sg_list = &rep->rr_rdmabuf->rg_iov;
        rep->rr_recv_wr.num_sge = 1;
        rep->rr_temp = temp;
+       list_add(&rep->rr_all, &r_xprt->rx_buf.rb_all_reps);
        return rep;
 
 out_free:
@@ -1100,6 +1103,7 @@ out:
 
 static void rpcrdma_rep_destroy(struct rpcrdma_rep *rep)
 {
+       list_del(&rep->rr_all);
        rpcrdma_regbuf_free(rep->rr_rdmabuf);
        kfree(rep);
 }
@@ -1118,10 +1122,16 @@ static struct rpcrdma_rep *rpcrdma_rep_get_locked(struct rpcrdma_buffer *buf)
 static void rpcrdma_rep_put(struct rpcrdma_buffer *buf,
                            struct rpcrdma_rep *rep)
 {
-       if (!rep->rr_temp)
-               llist_add(&rep->rr_node, &buf->rb_free_reps);
-       else
-               rpcrdma_rep_destroy(rep);
+       llist_add(&rep->rr_node, &buf->rb_free_reps);
+}
+
+static void rpcrdma_reps_unmap(struct rpcrdma_xprt *r_xprt)
+{
+       struct rpcrdma_buffer *buf = &r_xprt->rx_buf;
+       struct rpcrdma_rep *rep;
+
+       list_for_each_entry(rep, &buf->rb_all_reps, rr_all)
+               rpcrdma_regbuf_dma_unmap(rep->rr_rdmabuf);
 }
 
 static void rpcrdma_reps_destroy(struct rpcrdma_buffer *buf)
@@ -1152,6 +1162,7 @@ int rpcrdma_buffer_create(struct rpcrdma_xprt *r_xprt)
 
        INIT_LIST_HEAD(&buf->rb_send_bufs);
        INIT_LIST_HEAD(&buf->rb_allreqs);
+       INIT_LIST_HEAD(&buf->rb_all_reps);
 
        rc = -ENOMEM;
        for (i = 0; i < buf->rb_max_requests; i++) {
@@ -1504,6 +1515,10 @@ void rpcrdma_post_recvs(struct rpcrdma_xprt *r_xprt, bool temp)
        wr = NULL;
        while (needed) {
                rep = rpcrdma_rep_get_locked(buf);
+               if (rep && rep->rr_temp) {
+                       rpcrdma_rep_destroy(rep);
+                       continue;
+               }
                if (!rep)
                        rep = rpcrdma_rep_create(r_xprt, temp);
                if (!rep)
index 5d15140..d796d68 100644 (file)
@@ -203,6 +203,7 @@ struct rpcrdma_rep {
        struct xdr_stream       rr_stream;
        struct llist_node       rr_node;
        struct ib_recv_wr       rr_recv_wr;
+       struct list_head        rr_all;
 };
 
 /* To reduce the rate at which a transport invokes ib_post_recv
@@ -368,6 +369,7 @@ struct rpcrdma_buffer {
 
        struct list_head        rb_allreqs;
        struct list_head        rb_all_mrs;
+       struct list_head        rb_all_reps;
 
        struct llist_head       rb_free_reps;
 
index 63dc7bd..be59b59 100644 (file)
@@ -471,15 +471,19 @@ void snd_seq_info_timer_read(struct snd_info_entry *entry,
                q = queueptr(idx);
                if (q == NULL)
                        continue;
-               if ((tmr = q->timer) == NULL ||
-                   (ti = tmr->timeri) == NULL) {
-                       queuefree(q);
-                       continue;
-               }
+               mutex_lock(&q->timer_mutex);
+               tmr = q->timer;
+               if (!tmr)
+                       goto unlock;
+               ti = tmr->timeri;
+               if (!ti)
+                       goto unlock;
                snd_iprintf(buffer, "Timer for queue %i : %s\n", q->queue, ti->timer->name);
                resolution = snd_timer_resolution(ti) * tmr->ticks;
                snd_iprintf(buffer, "  Period time : %lu.%09lu\n", resolution / 1000000000, resolution % 1000000000);
                snd_iprintf(buffer, "  Skew : %u / %u\n", tmr->skew, tmr->skew_base);
+unlock:
+               mutex_unlock(&q->timer_mutex);
                queuefree(q);
        }
 }
index a63fcbc..02f4a83 100644 (file)
@@ -159,8 +159,11 @@ int snd_dice_detect_extension_formats(struct snd_dice *dice)
                int j;
 
                for (j = i + 1; j < 9; ++j) {
-                       if (pointers[i * 2] == pointers[j * 2])
+                       if (pointers[i * 2] == pointers[j * 2]) {
+                               // Fallback to limited functionality.
+                               err = -ENXIO;
                                goto end;
+                       }
                }
        }
 
index e80bb84..f823a2a 100644 (file)
@@ -157,14 +157,15 @@ static void read_status_messages(struct amdtp_stream *s,
                        if ((before ^ after) & mask) {
                                struct snd_firewire_tascam_change *entry =
                                                &tscm->queue[tscm->push_pos];
+                               unsigned long flag;
 
-                               spin_lock_irq(&tscm->lock);
+                               spin_lock_irqsave(&tscm->lock, flag);
                                entry->index = index;
                                entry->before = before;
                                entry->after = after;
                                if (++tscm->push_pos >= SND_TSCM_QUEUE_COUNT)
                                        tscm->push_pos = 0;
-                               spin_unlock_irq(&tscm->lock);
+                               spin_unlock_irqrestore(&tscm->lock, flag);
 
                                wake_up(&tscm->hwdep_wait);
                        }
index 906b1e2..286361e 100644 (file)
@@ -363,7 +363,6 @@ static const struct regmap_config hda_regmap_cfg = {
        .reg_write = hda_reg_write,
        .use_single_read = true,
        .use_single_write = true,
-       .disable_locking = true,
 };
 
 /**
index 5b92f29..8ef223a 100644 (file)
@@ -125,7 +125,7 @@ static char *patch[SNDRV_CARDS];
 static bool beep_mode[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] =
                                        CONFIG_SND_HDA_INPUT_BEEP_MODE};
 #endif
-static bool dsp_driver = 1;
+static bool dmic_detect = 1;
 
 module_param_array(index, int, NULL, 0444);
 MODULE_PARM_DESC(index, "Index value for Intel HD audio interface.");
@@ -160,9 +160,10 @@ module_param_array(beep_mode, bool, NULL, 0444);
 MODULE_PARM_DESC(beep_mode, "Select HDA Beep registration mode "
                            "(0=off, 1=on) (default=1).");
 #endif
-module_param(dsp_driver, bool, 0444);
-MODULE_PARM_DESC(dsp_driver, "Allow DSP driver selection (bypass this driver) "
-                            "(0=off, 1=on) (default=1)");
+module_param(dmic_detect, bool, 0444);
+MODULE_PARM_DESC(dmic_detect, "Allow DSP driver selection (bypass this driver) "
+                            "(0=off, 1=on) (default=1); "
+                "deprecated, use snd-intel-dspcfg.dsp_driver option instead");
 
 #ifdef CONFIG_PM
 static int param_set_xint(const char *val, const struct kernel_param *kp);
@@ -2099,11 +2100,13 @@ static int azx_probe(struct pci_dev *pci,
        /*
         * stop probe if another Intel's DSP driver should be activated
         */
-       if (dsp_driver) {
+       if (dmic_detect) {
                err = snd_intel_dsp_driver_probe(pci);
                if (err != SND_INTEL_DSP_DRIVER_ANY &&
                    err != SND_INTEL_DSP_DRIVER_LEGACY)
                        return -ENODEV;
+       } else {
+               dev_warn(&pci->dev, "dmic_detect option is deprecated, pass snd-intel-dspcfg.dsp_driver=1 option instead\n");
        }
 
        err = snd_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE,
index 1cd4906..f2ea352 100644 (file)
@@ -412,6 +412,7 @@ static void alc_fill_eapd_coef(struct hda_codec *codec)
        case 0x10ec0672:
                alc_update_coef_idx(codec, 0xd, 0, 1<<14); /* EAPD Ctrl */
                break;
+       case 0x10ec0222:
        case 0x10ec0623:
                alc_update_coef_idx(codec, 0x19, 1<<13, 0);
                break;
@@ -430,6 +431,7 @@ static void alc_fill_eapd_coef(struct hda_codec *codec)
                break;
        case 0x10ec0899:
        case 0x10ec0900:
+       case 0x10ec0b00:
        case 0x10ec1168:
        case 0x10ec1220:
                alc_update_coef_idx(codec, 0x7, 1<<1, 0);
@@ -2526,6 +2528,7 @@ static int patch_alc882(struct hda_codec *codec)
        case 0x10ec0882:
        case 0x10ec0885:
        case 0x10ec0900:
+       case 0x10ec0b00:
        case 0x10ec1220:
                break;
        default:
@@ -7257,6 +7260,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
        SND_PCI_QUIRK(0x17aa, 0x224c, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
        SND_PCI_QUIRK(0x17aa, 0x224d, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
        SND_PCI_QUIRK(0x17aa, 0x225d, "Thinkpad T480", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
+       SND_PCI_QUIRK(0x17aa, 0x2292, "Thinkpad X1 Yoga 7th", ALC285_FIXUP_SPEAKER2_TO_DAC1),
        SND_PCI_QUIRK(0x17aa, 0x2293, "Thinkpad X1 Carbon 7th", ALC285_FIXUP_SPEAKER2_TO_DAC1),
        SND_PCI_QUIRK(0x17aa, 0x30bb, "ThinkCentre AIO", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY),
        SND_PCI_QUIRK(0x17aa, 0x30e2, "ThinkCentre AIO", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY),
@@ -9255,6 +9259,7 @@ static const struct hda_device_id snd_hda_id_realtek[] = {
        HDA_CODEC_ENTRY(0x10ec0892, "ALC892", patch_alc662),
        HDA_CODEC_ENTRY(0x10ec0899, "ALC898", patch_alc882),
        HDA_CODEC_ENTRY(0x10ec0900, "ALC1150", patch_alc882),
+       HDA_CODEC_ENTRY(0x10ec0b00, "ALCS1200A", patch_alc882),
        HDA_CODEC_ENTRY(0x10ec1168, "ALC1220", patch_alc882),
        HDA_CODEC_ENTRY(0x10ec1220, "ALC1220", patch_alc882),
        {} /* terminator */
index 7b17f39..ce3ed05 100644 (file)
@@ -10,6 +10,7 @@
 
 #include <crypto/hash.h>
 #include <crypto/sha.h>
+#include <linux/acpi.h>
 #include <linux/delay.h>
 #include <linux/device.h>
 #include <linux/io.h>
@@ -1047,10 +1048,17 @@ static const struct of_device_id cros_ec_codec_of_match[] = {
 MODULE_DEVICE_TABLE(of, cros_ec_codec_of_match);
 #endif
 
+static const struct acpi_device_id cros_ec_codec_acpi_id[] = {
+       { "GOOG0013", 0 },
+       { }
+};
+MODULE_DEVICE_TABLE(acpi, cros_ec_codec_acpi_id);
+
 static struct platform_driver cros_ec_codec_platform_driver = {
        .driver = {
                .name = "cros-ec-codec",
                .of_match_table = of_match_ptr(cros_ec_codec_of_match),
+               .acpi_match_table = ACPI_PTR(cros_ec_codec_acpi_id),
        },
        .probe = cros_ec_codec_platform_probe,
 };
index 6803d39..4311015 100644 (file)
@@ -588,7 +588,9 @@ static int hdac_hda_dev_remove(struct hdac_device *hdev)
        struct hdac_hda_priv *hda_pvt;
 
        hda_pvt = dev_get_drvdata(&hdev->dev);
-       cancel_delayed_work_sync(&hda_pvt->codec.jackpoll_work);
+       if (hda_pvt && hda_pvt->codec.registered)
+               cancel_delayed_work_sync(&hda_pvt->codec.jackpoll_work);
+
        return 0;
 }
 
index f53235b..1f7964b 100644 (file)
@@ -396,9 +396,6 @@ static int pm8916_wcd_analog_enable_micbias_int(struct snd_soc_component
 
        switch (event) {
        case SND_SOC_DAPM_PRE_PMU:
-               snd_soc_component_update_bits(component, CDC_A_MICB_1_INT_RBIAS,
-                                   MICB_1_INT_TX2_INT_RBIAS_EN_MASK,
-                                   MICB_1_INT_TX2_INT_RBIAS_EN_ENABLE);
                snd_soc_component_update_bits(component, reg, MICB_1_EN_PULL_DOWN_EN_MASK, 0);
                snd_soc_component_update_bits(component, CDC_A_MICB_1_EN,
                                    MICB_1_EN_OPA_STG2_TAIL_CURR_MASK,
@@ -448,6 +445,14 @@ static int pm8916_wcd_analog_enable_micbias_int1(struct
        struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
        struct pm8916_wcd_analog_priv *wcd = snd_soc_component_get_drvdata(component);
 
+       switch (event) {
+       case SND_SOC_DAPM_PRE_PMU:
+               snd_soc_component_update_bits(component, CDC_A_MICB_1_INT_RBIAS,
+                                   MICB_1_INT_TX1_INT_RBIAS_EN_MASK,
+                                   MICB_1_INT_TX1_INT_RBIAS_EN_ENABLE);
+               break;
+       }
+
        return pm8916_wcd_analog_enable_micbias_int(component, event, w->reg,
                                                     wcd->micbias1_cap_mode);
 }
@@ -558,6 +563,11 @@ static int pm8916_wcd_analog_enable_micbias_int2(struct
        struct pm8916_wcd_analog_priv *wcd = snd_soc_component_get_drvdata(component);
 
        switch (event) {
+       case SND_SOC_DAPM_PRE_PMU:
+               snd_soc_component_update_bits(component, CDC_A_MICB_1_INT_RBIAS,
+                                   MICB_1_INT_TX2_INT_RBIAS_EN_MASK,
+                                   MICB_1_INT_TX2_INT_RBIAS_EN_ENABLE);
+               break;
        case SND_SOC_DAPM_POST_PMU:
                pm8916_mbhc_configure_bias(wcd, true);
                break;
@@ -938,10 +948,10 @@ static const struct snd_soc_dapm_widget pm8916_wcd_analog_dapm_widgets[] = {
 
        SND_SOC_DAPM_SUPPLY("MIC BIAS External1", CDC_A_MICB_1_EN, 7, 0,
                            pm8916_wcd_analog_enable_micbias_ext1,
-                           SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+                           SND_SOC_DAPM_POST_PMU),
        SND_SOC_DAPM_SUPPLY("MIC BIAS External2", CDC_A_MICB_2_EN, 7, 0,
                            pm8916_wcd_analog_enable_micbias_ext2,
-                           SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+                           SND_SOC_DAPM_POST_PMU),
 
        SND_SOC_DAPM_ADC_E("ADC1", NULL, CDC_A_TX_1_EN, 7, 0,
                           pm8916_wcd_analog_enable_adc,
index 58b2468..09fccac 100644 (file)
@@ -586,6 +586,12 @@ static int msm8916_wcd_digital_enable_interpolator(
                snd_soc_component_write(component, rx_gain_reg[w->shift],
                              snd_soc_component_read32(component, rx_gain_reg[w->shift]));
                break;
+       case SND_SOC_DAPM_POST_PMD:
+               snd_soc_component_update_bits(component, LPASS_CDC_CLK_RX_RESET_CTL,
+                                             1 << w->shift, 1 << w->shift);
+               snd_soc_component_update_bits(component, LPASS_CDC_CLK_RX_RESET_CTL,
+                                             1 << w->shift, 0x0);
+               break;
        }
        return 0;
 }
index adbae1f..747ca24 100644 (file)
@@ -2432,6 +2432,13 @@ static void rt5640_disable_jack_detect(struct snd_soc_component *component)
 {
        struct rt5640_priv *rt5640 = snd_soc_component_get_drvdata(component);
 
+       /*
+        * soc_remove_component() force-disables jack and thus rt5640->jack
+        * could be NULL at the time of driver's module unloading.
+        */
+       if (!rt5640->jack)
+               return;
+
        disable_irq(rt5640->irq);
        rt5640_cancel_work(rt5640);
 
index a1db1bc..5faecbe 100644 (file)
@@ -505,15 +505,20 @@ static int fsl_audmix_probe(struct platform_device *pdev)
                                              ARRAY_SIZE(fsl_audmix_dai));
        if (ret) {
                dev_err(dev, "failed to register ASoC DAI\n");
-               return ret;
+               goto err_disable_pm;
        }
 
        priv->pdev = platform_device_register_data(dev, mdrv, 0, NULL, 0);
        if (IS_ERR(priv->pdev)) {
                ret = PTR_ERR(priv->pdev);
                dev_err(dev, "failed to register platform %s: %d\n", mdrv, ret);
+               goto err_disable_pm;
        }
 
+       return 0;
+
+err_disable_pm:
+       pm_runtime_disable(dev);
        return ret;
 }
 
@@ -521,6 +526,8 @@ static int fsl_audmix_remove(struct platform_device *pdev)
 {
        struct fsl_audmix *priv = dev_get_drvdata(&pdev->dev);
 
+       pm_runtime_disable(&pdev->dev);
+
        if (priv->pdev)
                platform_device_unregister(priv->pdev);
 
index 4661233..54e9745 100644 (file)
@@ -442,7 +442,8 @@ static const struct dmi_system_id byt_cht_es8316_quirk_table[] = {
                        DMI_MATCH(DMI_SYS_VENDOR, "IRBIS"),
                        DMI_MATCH(DMI_PRODUCT_NAME, "NB41"),
                },
-               .driver_data = (void *)(BYT_CHT_ES8316_INTMIC_IN2_MAP
+               .driver_data = (void *)(BYT_CHT_ES8316_SSP0
+                                       | BYT_CHT_ES8316_INTMIC_IN2_MAP
                                        | BYT_CHT_ES8316_JD_INVERTED),
        },
        {       /* Teclast X98 Plus II */
index a22f972..5f1bf6d 100644 (file)
@@ -11,7 +11,6 @@
 #include <linux/clk.h>
 #include <linux/dmi.h>
 #include <linux/slab.h>
-#include <asm/cpu_device_id.h>
 #include <linux/acpi.h>
 #include <sound/core.h>
 #include <sound/jack.h>
index 9054558..b94680f 100644 (file)
@@ -539,6 +539,9 @@ void snd_soc_pcm_component_free(struct snd_soc_pcm_runtime *rtd)
        struct snd_soc_rtdcom_list *rtdcom;
        struct snd_soc_component *component;
 
+       if (!rtd->pcm)
+               return;
+
        for_each_rtd_components(rtd, rtdcom, component)
                if (component->driver->pcm_destruct)
                        component->driver->pcm_destruct(component, rtd->pcm);
index 1c84ff1..8ef0efe 100644 (file)
@@ -479,6 +479,12 @@ static struct snd_soc_pcm_runtime *soc_new_pcm_runtime(
                goto free_rtd;
 
        rtd->dev = dev;
+       INIT_LIST_HEAD(&rtd->list);
+       INIT_LIST_HEAD(&rtd->component_list);
+       INIT_LIST_HEAD(&rtd->dpcm[SNDRV_PCM_STREAM_PLAYBACK].be_clients);
+       INIT_LIST_HEAD(&rtd->dpcm[SNDRV_PCM_STREAM_CAPTURE].be_clients);
+       INIT_LIST_HEAD(&rtd->dpcm[SNDRV_PCM_STREAM_PLAYBACK].fe_clients);
+       INIT_LIST_HEAD(&rtd->dpcm[SNDRV_PCM_STREAM_CAPTURE].fe_clients);
        dev_set_drvdata(dev, rtd);
        INIT_DELAYED_WORK(&rtd->delayed_work, close_delayed_work);
 
@@ -494,12 +500,6 @@ static struct snd_soc_pcm_runtime *soc_new_pcm_runtime(
        /*
         * rtd remaining settings
         */
-       INIT_LIST_HEAD(&rtd->component_list);
-       INIT_LIST_HEAD(&rtd->dpcm[SNDRV_PCM_STREAM_PLAYBACK].be_clients);
-       INIT_LIST_HEAD(&rtd->dpcm[SNDRV_PCM_STREAM_CAPTURE].be_clients);
-       INIT_LIST_HEAD(&rtd->dpcm[SNDRV_PCM_STREAM_PLAYBACK].fe_clients);
-       INIT_LIST_HEAD(&rtd->dpcm[SNDRV_PCM_STREAM_CAPTURE].fe_clients);
-
        rtd->card = card;
        rtd->dai_link = dai_link;
        if (!rtd->dai_link->ops)
@@ -1871,6 +1871,8 @@ match:
 
                        /* convert non BE into BE */
                        dai_link->no_pcm = 1;
+                       dai_link->dpcm_playback = 1;
+                       dai_link->dpcm_capture = 1;
 
                        /* override any BE fixups */
                        dai_link->be_hw_params_fixup =
index b286131..92e4f4d 100644 (file)
@@ -548,12 +548,12 @@ static void remove_link(struct snd_soc_component *comp,
        if (dobj->ops && dobj->ops->link_unload)
                dobj->ops->link_unload(comp, dobj);
 
+       list_del(&dobj->list);
+       snd_soc_remove_dai_link(comp->card, link);
+
        kfree(link->name);
        kfree(link->stream_name);
        kfree(link->cpus->dai_name);
-
-       list_del(&dobj->list);
-       snd_soc_remove_dai_link(comp->card, link);
        kfree(link);
 }
 
index cfefcfd..aef6ca1 100644 (file)
@@ -209,7 +209,7 @@ static int imx8_probe(struct snd_sof_dev *sdev)
 
        priv->pd_dev = devm_kmalloc_array(&pdev->dev, priv->num_domains,
                                          sizeof(*priv->pd_dev), GFP_KERNEL);
-       if (!priv)
+       if (!priv->pd_dev)
                return -ENOMEM;
 
        priv->link = devm_kmalloc_array(&pdev->dev, priv->num_domains,
@@ -304,6 +304,9 @@ static int imx8_probe(struct snd_sof_dev *sdev)
        }
        sdev->mailbox_bar = SOF_FW_BLK_TYPE_SRAM;
 
+       /* set default mailbox offset for FW ready message */
+       sdev->dsp_box.offset = MBOX_OFFSET;
+
        return 0;
 
 exit_pdev_unregister:
index 827f84a..fbfa225 100644 (file)
 #define IDISP_VID_INTEL        0x80860000
 
 /* load the legacy HDA codec driver */
-#ifdef MODULE
-static void hda_codec_load_module(struct hda_codec *codec)
+static int hda_codec_load_module(struct hda_codec *codec)
 {
+#ifdef MODULE
        char alias[MODULE_NAME_LEN];
        const char *module = alias;
 
        snd_hdac_codec_modalias(&codec->core, alias, sizeof(alias));
        dev_dbg(&codec->core.dev, "loading codec module: %s\n", module);
        request_module(module);
-}
-#else
-static void hda_codec_load_module(struct hda_codec *codec) {}
 #endif
+       return device_attach(hda_codec_dev(codec));
+}
 
 /* enable controller wake up event for all codecs with jack connectors */
 void hda_codec_jack_wake_enable(struct snd_sof_dev *sdev)
@@ -129,10 +128,16 @@ static int hda_codec_probe(struct snd_sof_dev *sdev, int address)
        if ((mach_params && mach_params->common_hdmi_codec_drv) ||
            (resp & 0xFFFF0000) != IDISP_VID_INTEL) {
                hdev->type = HDA_DEV_LEGACY;
-               hda_codec_load_module(&hda_priv->codec);
+               ret = hda_codec_load_module(&hda_priv->codec);
+               /*
+                * handle ret==0 (no driver bound) as an error, but pass
+                * other return codes without modification
+                */
+               if (ret == 0)
+                       ret = -ENOENT;
        }
 
-       return 0;
+       return ret;
 #else
        hdev = devm_kzalloc(sdev->dev, sizeof(*hdev), GFP_KERNEL);
        if (!hdev)
index 8796f38..896d219 100644 (file)
@@ -216,6 +216,8 @@ static int hda_link_hw_params(struct snd_pcm_substream *substream,
                link_dev = hda_link_stream_assign(bus, substream);
                if (!link_dev)
                        return -EBUSY;
+
+               snd_soc_dai_set_dma_data(dai, substream, (void *)link_dev);
        }
 
        stream_tag = hdac_stream(link_dev)->stream_tag;
@@ -228,8 +230,6 @@ static int hda_link_hw_params(struct snd_pcm_substream *substream,
        if (ret < 0)
                return ret;
 
-       snd_soc_dai_set_dma_data(dai, substream, (void *)link_dev);
-
        link = snd_hdac_ext_bus_get_link(bus, codec_dai->component->name);
        if (!link)
                return -EINVAL;
@@ -361,6 +361,13 @@ static int hda_link_hw_free(struct snd_pcm_substream *substream,
        bus = hstream->bus;
        rtd = snd_pcm_substream_chip(substream);
        link_dev = snd_soc_dai_get_dma_data(dai, substream);
+
+       if (!link_dev) {
+               dev_dbg(dai->dev,
+                       "%s: link_dev is not assigned\n", __func__);
+               return -EINVAL;
+       }
+
        hda_stream = hstream_to_sof_hda_stream(link_dev);
 
        /* free the link DMA channel in the FW */
index b178336..bae7ac3 100644 (file)
@@ -329,13 +329,13 @@ int hda_dsp_cl_boot_firmware(struct snd_sof_dev *sdev)
                if (!ret)
                        break;
 
-               dev_err(sdev->dev, "error: Error code=0x%x: FW status=0x%x\n",
+               dev_dbg(sdev->dev, "iteration %d of Core En/ROM load failed: %d\n",
+                       i, ret);
+               dev_dbg(sdev->dev, "Error code=0x%x: FW status=0x%x\n",
                        snd_sof_dsp_read(sdev, HDA_DSP_BAR,
                                         HDA_DSP_SRAM_REG_ROM_ERROR),
                        snd_sof_dsp_read(sdev, HDA_DSP_BAR,
                                         HDA_DSP_SRAM_REG_ROM_STATUS));
-               dev_err(sdev->dev, "error: iteration %d of Core En/ROM load failed: %d\n",
-                       i, ret);
        }
 
        if (i == HDA_FW_BOOT_ATTEMPTS) {
index 5994e10..5fdfbaa 100644 (file)
@@ -826,6 +826,9 @@ void snd_sof_ipc_free(struct snd_sof_dev *sdev)
 {
        struct snd_sof_ipc *ipc = sdev->ipc;
 
+       if (!ipc)
+               return;
+
        /* disable sending of ipc's */
        mutex_lock(&ipc->tx_mutex);
        ipc->disable_ipc_tx = true;
index 48ea915..2ed92c9 100644 (file)
@@ -226,7 +226,6 @@ static void uni_player_set_channel_status(struct uniperif *player,
         * sampling frequency. If no sample rate is already specified, then
         * set one.
         */
-       mutex_lock(&player->ctrl_lock);
        if (runtime) {
                switch (runtime->rate) {
                case 22050:
@@ -303,7 +302,6 @@ static void uni_player_set_channel_status(struct uniperif *player,
                player->stream_settings.iec958.status[3 + (n * 4)] << 24;
                SET_UNIPERIF_CHANNEL_STA_REGN(player, n, status);
        }
-       mutex_unlock(&player->ctrl_lock);
 
        /* Update the channel status */
        if (player->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0)
@@ -365,8 +363,10 @@ static int uni_player_prepare_iec958(struct uniperif *player,
 
        SET_UNIPERIF_CTRL_ZERO_STUFF_HW(player);
 
+       mutex_lock(&player->ctrl_lock);
        /* Update the channel status */
        uni_player_set_channel_status(player, runtime);
+       mutex_unlock(&player->ctrl_lock);
 
        /* Clear the user validity user bits */
        SET_UNIPERIF_USER_VALIDITY_VALIDITY_LR(player, 0);
@@ -598,7 +598,6 @@ static int uni_player_ctl_iec958_put(struct snd_kcontrol *kcontrol,
        iec958->status[1] = ucontrol->value.iec958.status[1];
        iec958->status[2] = ucontrol->value.iec958.status[2];
        iec958->status[3] = ucontrol->value.iec958.status[3];
-       mutex_unlock(&player->ctrl_lock);
 
        spin_lock_irqsave(&player->irq_lock, flags);
        if (player->substream && player->substream->runtime)
@@ -608,6 +607,8 @@ static int uni_player_ctl_iec958_put(struct snd_kcontrol *kcontrol,
                uni_player_set_channel_status(player, NULL);
 
        spin_unlock_irqrestore(&player->irq_lock, flags);
+       mutex_unlock(&player->ctrl_lock);
+
        return 0;
 }
 
index 81c407d..08696a4 100644 (file)
@@ -153,13 +153,13 @@ static const struct snd_soc_component_driver stm32_adfsdm_dai_component = {
        .name = "stm32_dfsdm_audio",
 };
 
-static void memcpy_32to16(void *dest, const void *src, size_t n)
+static void stm32_memcpy_32to16(void *dest, const void *src, size_t n)
 {
        unsigned int i = 0;
        u16 *d = (u16 *)dest, *s = (u16 *)src;
 
        s++;
-       for (i = n; i > 0; i--) {
+       for (i = n >> 1; i > 0; i--) {
                *d++ = *s++;
                s++;
        }
@@ -186,8 +186,8 @@ static int stm32_afsdm_pcm_cb(const void *data, size_t size, void *private)
 
        if ((priv->pos + src_size) > buff_size) {
                if (format == SNDRV_PCM_FORMAT_S16_LE)
-                       memcpy_32to16(&pcm_buff[priv->pos], src_buff,
-                                     buff_size - priv->pos);
+                       stm32_memcpy_32to16(&pcm_buff[priv->pos], src_buff,
+                                           buff_size - priv->pos);
                else
                        memcpy(&pcm_buff[priv->pos], src_buff,
                               buff_size - priv->pos);
@@ -196,8 +196,8 @@ static int stm32_afsdm_pcm_cb(const void *data, size_t size, void *private)
        }
 
        if (format == SNDRV_PCM_FORMAT_S16_LE)
-               memcpy_32to16(&pcm_buff[priv->pos],
-                             &src_buff[src_size - cur_size], cur_size);
+               stm32_memcpy_32to16(&pcm_buff[priv->pos],
+                                   &src_buff[src_size - cur_size], cur_size);
        else
                memcpy(&pcm_buff[priv->pos], &src_buff[src_size - cur_size],
                       cur_size);
index 48e629a..30bcd5d 100644 (file)
@@ -184,6 +184,56 @@ static bool stm32_sai_sub_writeable_reg(struct device *dev, unsigned int reg)
        }
 }
 
+static int stm32_sai_sub_reg_up(struct stm32_sai_sub_data *sai,
+                               unsigned int reg, unsigned int mask,
+                               unsigned int val)
+{
+       int ret;
+
+       ret = clk_enable(sai->pdata->pclk);
+       if (ret < 0)
+               return ret;
+
+       ret = regmap_update_bits(sai->regmap, reg, mask, val);
+
+       clk_disable(sai->pdata->pclk);
+
+       return ret;
+}
+
+static int stm32_sai_sub_reg_wr(struct stm32_sai_sub_data *sai,
+                               unsigned int reg, unsigned int mask,
+                               unsigned int val)
+{
+       int ret;
+
+       ret = clk_enable(sai->pdata->pclk);
+       if (ret < 0)
+               return ret;
+
+       ret = regmap_write_bits(sai->regmap, reg, mask, val);
+
+       clk_disable(sai->pdata->pclk);
+
+       return ret;
+}
+
+static int stm32_sai_sub_reg_rd(struct stm32_sai_sub_data *sai,
+                               unsigned int reg, unsigned int *val)
+{
+       int ret;
+
+       ret = clk_enable(sai->pdata->pclk);
+       if (ret < 0)
+               return ret;
+
+       ret = regmap_read(sai->regmap, reg, val);
+
+       clk_disable(sai->pdata->pclk);
+
+       return ret;
+}
+
 static const struct regmap_config stm32_sai_sub_regmap_config_f4 = {
        .reg_bits = 32,
        .reg_stride = 4,
@@ -295,7 +345,7 @@ static int stm32_sai_set_clk_div(struct stm32_sai_sub_data *sai,
 
        mask = SAI_XCR1_MCKDIV_MASK(SAI_XCR1_MCKDIV_WIDTH(version));
        cr1 = SAI_XCR1_MCKDIV_SET(div);
-       ret = regmap_update_bits(sai->regmap, STM_SAI_CR1_REGX, mask, cr1);
+       ret = stm32_sai_sub_reg_up(sai, STM_SAI_CR1_REGX, mask, cr1);
        if (ret < 0)
                dev_err(&sai->pdev->dev, "Failed to update CR1 register\n");
 
@@ -372,8 +422,8 @@ static int stm32_sai_mclk_enable(struct clk_hw *hw)
 
        dev_dbg(&sai->pdev->dev, "Enable master clock\n");
 
-       return regmap_update_bits(sai->regmap, STM_SAI_CR1_REGX,
-                                 SAI_XCR1_MCKEN, SAI_XCR1_MCKEN);
+       return stm32_sai_sub_reg_up(sai, STM_SAI_CR1_REGX,
+                                   SAI_XCR1_MCKEN, SAI_XCR1_MCKEN);
 }
 
 static void stm32_sai_mclk_disable(struct clk_hw *hw)
@@ -383,7 +433,7 @@ static void stm32_sai_mclk_disable(struct clk_hw *hw)
 
        dev_dbg(&sai->pdev->dev, "Disable master clock\n");
 
-       regmap_update_bits(sai->regmap, STM_SAI_CR1_REGX, SAI_XCR1_MCKEN, 0);
+       stm32_sai_sub_reg_up(sai, STM_SAI_CR1_REGX, SAI_XCR1_MCKEN, 0);
 }
 
 static const struct clk_ops mclk_ops = {
@@ -446,15 +496,15 @@ static irqreturn_t stm32_sai_isr(int irq, void *devid)
        unsigned int sr, imr, flags;
        snd_pcm_state_t status = SNDRV_PCM_STATE_RUNNING;
 
-       regmap_read(sai->regmap, STM_SAI_IMR_REGX, &imr);
-       regmap_read(sai->regmap, STM_SAI_SR_REGX, &sr);
+       stm32_sai_sub_reg_rd(sai, STM_SAI_IMR_REGX, &imr);
+       stm32_sai_sub_reg_rd(sai, STM_SAI_SR_REGX, &sr);
 
        flags = sr & imr;
        if (!flags)
                return IRQ_NONE;
 
-       regmap_write_bits(sai->regmap, STM_SAI_CLRFR_REGX, SAI_XCLRFR_MASK,
-                         SAI_XCLRFR_MASK);
+       stm32_sai_sub_reg_wr(sai, STM_SAI_CLRFR_REGX, SAI_XCLRFR_MASK,
+                            SAI_XCLRFR_MASK);
 
        if (!sai->substream) {
                dev_err(&pdev->dev, "Device stopped. Spurious IRQ 0x%x\n", sr);
@@ -503,8 +553,8 @@ static int stm32_sai_set_sysclk(struct snd_soc_dai *cpu_dai,
        int ret;
 
        if (dir == SND_SOC_CLOCK_OUT && sai->sai_mclk) {
-               ret = regmap_update_bits(sai->regmap, STM_SAI_CR1_REGX,
-                                        SAI_XCR1_NODIV,
+               ret = stm32_sai_sub_reg_up(sai, STM_SAI_CR1_REGX,
+                                          SAI_XCR1_NODIV,
                                         freq ? 0 : SAI_XCR1_NODIV);
                if (ret < 0)
                        return ret;
@@ -583,7 +633,7 @@ static int stm32_sai_set_dai_tdm_slot(struct snd_soc_dai *cpu_dai, u32 tx_mask,
 
        slotr_mask |= SAI_XSLOTR_SLOTEN_MASK;
 
-       regmap_update_bits(sai->regmap, STM_SAI_SLOTR_REGX, slotr_mask, slotr);
+       stm32_sai_sub_reg_up(sai, STM_SAI_SLOTR_REGX, slotr_mask, slotr);
 
        sai->slot_width = slot_width;
        sai->slots = slots;
@@ -665,7 +715,7 @@ static int stm32_sai_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt)
        cr1_mask |= SAI_XCR1_CKSTR;
        frcr_mask |= SAI_XFRCR_FSPOL;
 
-       regmap_update_bits(sai->regmap, STM_SAI_FRCR_REGX, frcr_mask, frcr);
+       stm32_sai_sub_reg_up(sai, STM_SAI_FRCR_REGX, frcr_mask, frcr);
 
        /* DAI clock master masks */
        switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
@@ -693,7 +743,7 @@ static int stm32_sai_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt)
        cr1_mask |= SAI_XCR1_SLAVE;
 
 conf_update:
-       ret = regmap_update_bits(sai->regmap, STM_SAI_CR1_REGX, cr1_mask, cr1);
+       ret = stm32_sai_sub_reg_up(sai, STM_SAI_CR1_REGX, cr1_mask, cr1);
        if (ret < 0) {
                dev_err(cpu_dai->dev, "Failed to update CR1 register\n");
                return ret;
@@ -730,12 +780,12 @@ static int stm32_sai_startup(struct snd_pcm_substream *substream,
        }
 
        /* Enable ITs */
-       regmap_write_bits(sai->regmap, STM_SAI_CLRFR_REGX,
-                         SAI_XCLRFR_MASK, SAI_XCLRFR_MASK);
+       stm32_sai_sub_reg_wr(sai, STM_SAI_CLRFR_REGX,
+                            SAI_XCLRFR_MASK, SAI_XCLRFR_MASK);
 
        imr = SAI_XIMR_OVRUDRIE;
        if (STM_SAI_IS_CAPTURE(sai)) {
-               regmap_read(sai->regmap, STM_SAI_CR2_REGX, &cr2);
+               stm32_sai_sub_reg_rd(sai, STM_SAI_CR2_REGX, &cr2);
                if (cr2 & SAI_XCR2_MUTECNT_MASK)
                        imr |= SAI_XIMR_MUTEDETIE;
        }
@@ -745,8 +795,8 @@ static int stm32_sai_startup(struct snd_pcm_substream *substream,
        else
                imr |= SAI_XIMR_AFSDETIE | SAI_XIMR_LFSDETIE;
 
-       regmap_update_bits(sai->regmap, STM_SAI_IMR_REGX,
-                          SAI_XIMR_MASK, imr);
+       stm32_sai_sub_reg_up(sai, STM_SAI_IMR_REGX,
+                            SAI_XIMR_MASK, imr);
 
        return 0;
 }
@@ -763,10 +813,10 @@ static int stm32_sai_set_config(struct snd_soc_dai *cpu_dai,
         * SAI fifo threshold is set to half fifo, to keep enough space
         * for DMA incoming bursts.
         */
-       regmap_write_bits(sai->regmap, STM_SAI_CR2_REGX,
-                         SAI_XCR2_FFLUSH | SAI_XCR2_FTH_MASK,
-                         SAI_XCR2_FFLUSH |
-                         SAI_XCR2_FTH_SET(STM_SAI_FIFO_TH_HALF));
+       stm32_sai_sub_reg_wr(sai, STM_SAI_CR2_REGX,
+                            SAI_XCR2_FFLUSH | SAI_XCR2_FTH_MASK,
+                            SAI_XCR2_FFLUSH |
+                            SAI_XCR2_FTH_SET(STM_SAI_FIFO_TH_HALF));
 
        /* DS bits in CR1 not set for SPDIF (size forced to 24 bits).*/
        if (STM_SAI_PROTOCOL_IS_SPDIF(sai)) {
@@ -795,7 +845,7 @@ static int stm32_sai_set_config(struct snd_soc_dai *cpu_dai,
        if ((sai->slots == 2) && (params_channels(params) == 1))
                cr1 |= SAI_XCR1_MONO;
 
-       ret = regmap_update_bits(sai->regmap, STM_SAI_CR1_REGX, cr1_mask, cr1);
+       ret = stm32_sai_sub_reg_up(sai, STM_SAI_CR1_REGX, cr1_mask, cr1);
        if (ret < 0) {
                dev_err(cpu_dai->dev, "Failed to update CR1 register\n");
                return ret;
@@ -809,7 +859,7 @@ static int stm32_sai_set_slots(struct snd_soc_dai *cpu_dai)
        struct stm32_sai_sub_data *sai = snd_soc_dai_get_drvdata(cpu_dai);
        int slotr, slot_sz;
 
-       regmap_read(sai->regmap, STM_SAI_SLOTR_REGX, &slotr);
+       stm32_sai_sub_reg_rd(sai, STM_SAI_SLOTR_REGX, &slotr);
 
        /*
         * If SLOTSZ is set to auto in SLOTR, align slot width on data size
@@ -831,16 +881,16 @@ static int stm32_sai_set_slots(struct snd_soc_dai *cpu_dai)
                sai->slots = 2;
 
        /* The number of slots in the audio frame is equal to NBSLOT[3:0] + 1*/
-       regmap_update_bits(sai->regmap, STM_SAI_SLOTR_REGX,
-                          SAI_XSLOTR_NBSLOT_MASK,
-                          SAI_XSLOTR_NBSLOT_SET((sai->slots - 1)));
+       stm32_sai_sub_reg_up(sai, STM_SAI_SLOTR_REGX,
+                            SAI_XSLOTR_NBSLOT_MASK,
+                            SAI_XSLOTR_NBSLOT_SET((sai->slots - 1)));
 
        /* Set default slots mask if not already set from DT */
        if (!(slotr & SAI_XSLOTR_SLOTEN_MASK)) {
                sai->slot_mask = (1 << sai->slots) - 1;
-               regmap_update_bits(sai->regmap,
-                                  STM_SAI_SLOTR_REGX, SAI_XSLOTR_SLOTEN_MASK,
-                                  SAI_XSLOTR_SLOTEN_SET(sai->slot_mask));
+               stm32_sai_sub_reg_up(sai,
+                                    STM_SAI_SLOTR_REGX, SAI_XSLOTR_SLOTEN_MASK,
+                                    SAI_XSLOTR_SLOTEN_SET(sai->slot_mask));
        }
 
        dev_dbg(cpu_dai->dev, "Slots %d, slot width %d\n",
@@ -870,14 +920,14 @@ static void stm32_sai_set_frame(struct snd_soc_dai *cpu_dai)
        dev_dbg(cpu_dai->dev, "Frame length %d, frame active %d\n",
                sai->fs_length, fs_active);
 
-       regmap_update_bits(sai->regmap, STM_SAI_FRCR_REGX, frcr_mask, frcr);
+       stm32_sai_sub_reg_up(sai, STM_SAI_FRCR_REGX, frcr_mask, frcr);
 
        if ((sai->fmt & SND_SOC_DAIFMT_FORMAT_MASK) == SND_SOC_DAIFMT_LSB) {
                offset = sai->slot_width - sai->data_size;
 
-               regmap_update_bits(sai->regmap, STM_SAI_SLOTR_REGX,
-                                  SAI_XSLOTR_FBOFF_MASK,
-                                  SAI_XSLOTR_FBOFF_SET(offset));
+               stm32_sai_sub_reg_up(sai, STM_SAI_SLOTR_REGX,
+                                    SAI_XSLOTR_FBOFF_MASK,
+                                    SAI_XSLOTR_FBOFF_SET(offset));
        }
 }
 
@@ -994,9 +1044,9 @@ static int stm32_sai_configure_clock(struct snd_soc_dai *cpu_dai,
                                        return -EINVAL;
                                }
 
-                               regmap_update_bits(sai->regmap,
-                                                  STM_SAI_CR1_REGX,
-                                                  SAI_XCR1_OSR, cr1);
+                               stm32_sai_sub_reg_up(sai,
+                                                    STM_SAI_CR1_REGX,
+                                                    SAI_XCR1_OSR, cr1);
 
                                div = stm32_sai_get_clk_div(sai, sai_clk_rate,
                                                            sai->mclk_rate);
@@ -1058,12 +1108,12 @@ static int stm32_sai_trigger(struct snd_pcm_substream *substream, int cmd,
        case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
                dev_dbg(cpu_dai->dev, "Enable DMA and SAI\n");
 
-               regmap_update_bits(sai->regmap, STM_SAI_CR1_REGX,
-                                  SAI_XCR1_DMAEN, SAI_XCR1_DMAEN);
+               stm32_sai_sub_reg_up(sai, STM_SAI_CR1_REGX,
+                                    SAI_XCR1_DMAEN, SAI_XCR1_DMAEN);
 
                /* Enable SAI */
-               ret = regmap_update_bits(sai->regmap, STM_SAI_CR1_REGX,
-                                        SAI_XCR1_SAIEN, SAI_XCR1_SAIEN);
+               ret = stm32_sai_sub_reg_up(sai, STM_SAI_CR1_REGX,
+                                          SAI_XCR1_SAIEN, SAI_XCR1_SAIEN);
                if (ret < 0)
                        dev_err(cpu_dai->dev, "Failed to update CR1 register\n");
                break;
@@ -1072,16 +1122,16 @@ static int stm32_sai_trigger(struct snd_pcm_substream *substream, int cmd,
        case SNDRV_PCM_TRIGGER_STOP:
                dev_dbg(cpu_dai->dev, "Disable DMA and SAI\n");
 
-               regmap_update_bits(sai->regmap, STM_SAI_IMR_REGX,
-                                  SAI_XIMR_MASK, 0);
+               stm32_sai_sub_reg_up(sai, STM_SAI_IMR_REGX,
+                                    SAI_XIMR_MASK, 0);
 
-               regmap_update_bits(sai->regmap, STM_SAI_CR1_REGX,
-                                  SAI_XCR1_SAIEN,
-                                  (unsigned int)~SAI_XCR1_SAIEN);
+               stm32_sai_sub_reg_up(sai, STM_SAI_CR1_REGX,
+                                    SAI_XCR1_SAIEN,
+                                    (unsigned int)~SAI_XCR1_SAIEN);
 
-               ret = regmap_update_bits(sai->regmap, STM_SAI_CR1_REGX,
-                                        SAI_XCR1_DMAEN,
-                                        (unsigned int)~SAI_XCR1_DMAEN);
+               ret = stm32_sai_sub_reg_up(sai, STM_SAI_CR1_REGX,
+                                          SAI_XCR1_DMAEN,
+                                          (unsigned int)~SAI_XCR1_DMAEN);
                if (ret < 0)
                        dev_err(cpu_dai->dev, "Failed to update CR1 register\n");
 
@@ -1101,7 +1151,7 @@ static void stm32_sai_shutdown(struct snd_pcm_substream *substream,
        struct stm32_sai_sub_data *sai = snd_soc_dai_get_drvdata(cpu_dai);
        unsigned long flags;
 
-       regmap_update_bits(sai->regmap, STM_SAI_IMR_REGX, SAI_XIMR_MASK, 0);
+       stm32_sai_sub_reg_up(sai, STM_SAI_IMR_REGX, SAI_XIMR_MASK, 0);
 
        clk_disable_unprepare(sai->sai_ck);
 
@@ -1169,7 +1219,7 @@ static int stm32_sai_dai_probe(struct snd_soc_dai *cpu_dai)
        cr1_mask |= SAI_XCR1_SYNCEN_MASK;
        cr1 |= SAI_XCR1_SYNCEN_SET(sai->sync);
 
-       return regmap_update_bits(sai->regmap, STM_SAI_CR1_REGX, cr1_mask, cr1);
+       return stm32_sai_sub_reg_up(sai, STM_SAI_CR1_REGX, cr1_mask, cr1);
 }
 
 static const struct snd_soc_dai_ops stm32_sai_pcm_dai_ops = {
@@ -1322,8 +1372,13 @@ static int stm32_sai_sub_parse_of(struct platform_device *pdev,
        if (STM_SAI_HAS_PDM(sai) && STM_SAI_IS_SUB_A(sai))
                sai->regmap_config = &stm32_sai_sub_regmap_config_h7;
 
-       sai->regmap = devm_regmap_init_mmio_clk(&pdev->dev, "sai_ck",
-                                               base, sai->regmap_config);
+       /*
+        * Do not manage peripheral clock through regmap framework as this
+        * can lead to circular locking issue with sai master clock provider.
+        * Manage peripheral clock directly in driver instead.
+        */
+       sai->regmap = devm_regmap_init_mmio(&pdev->dev, base,
+                                           sai->regmap_config);
        if (IS_ERR(sai->regmap)) {
                dev_err(&pdev->dev, "Failed to initialize MMIO\n");
                return PTR_ERR(sai->regmap);
@@ -1420,6 +1475,10 @@ static int stm32_sai_sub_parse_of(struct platform_device *pdev,
                return PTR_ERR(sai->sai_ck);
        }
 
+       ret = clk_prepare(sai->pdata->pclk);
+       if (ret < 0)
+               return ret;
+
        if (STM_SAI_IS_F4(sai->pdata))
                return 0;
 
@@ -1501,22 +1560,48 @@ static int stm32_sai_sub_probe(struct platform_device *pdev)
        return 0;
 }
 
+static int stm32_sai_sub_remove(struct platform_device *pdev)
+{
+       struct stm32_sai_sub_data *sai = dev_get_drvdata(&pdev->dev);
+
+       clk_unprepare(sai->pdata->pclk);
+
+       return 0;
+}
+
 #ifdef CONFIG_PM_SLEEP
 static int stm32_sai_sub_suspend(struct device *dev)
 {
        struct stm32_sai_sub_data *sai = dev_get_drvdata(dev);
+       int ret;
+
+       ret = clk_enable(sai->pdata->pclk);
+       if (ret < 0)
+               return ret;
 
        regcache_cache_only(sai->regmap, true);
        regcache_mark_dirty(sai->regmap);
+
+       clk_disable(sai->pdata->pclk);
+
        return 0;
 }
 
 static int stm32_sai_sub_resume(struct device *dev)
 {
        struct stm32_sai_sub_data *sai = dev_get_drvdata(dev);
+       int ret;
+
+       ret = clk_enable(sai->pdata->pclk);
+       if (ret < 0)
+               return ret;
 
        regcache_cache_only(sai->regmap, false);
-       return regcache_sync(sai->regmap);
+       ret = regcache_sync(sai->regmap);
+
+       clk_disable(sai->pdata->pclk);
+
+       return ret;
 }
 #endif /* CONFIG_PM_SLEEP */
 
@@ -1531,6 +1616,7 @@ static struct platform_driver stm32_sai_sub_driver = {
                .pm = &stm32_sai_sub_pm_ops,
        },
        .probe = stm32_sai_sub_probe,
+       .remove = stm32_sai_sub_remove,
 };
 
 module_platform_driver(stm32_sai_sub_driver);
index 3fd28ee..3769d9c 100644 (file)
@@ -12,7 +12,6 @@
 #include <linux/delay.h>
 #include <linux/module.h>
 #include <linux/of_platform.h>
-#include <linux/pinctrl/consumer.h>
 #include <linux/regmap.h>
 #include <linux/reset.h>
 
  * @slave_config: dma slave channel runtime config pointer
  * @phys_addr: SPDIFRX registers physical base address
  * @lock: synchronization enabling lock
+ * @irq_lock: prevent race condition with IRQ on stream state
  * @cs: channel status buffer
  * @ub: user data buffer
  * @irq: SPDIFRX interrupt line
@@ -240,6 +240,7 @@ struct stm32_spdifrx_data {
        struct dma_slave_config slave_config;
        dma_addr_t phys_addr;
        spinlock_t lock;  /* Sync enabling lock */
+       spinlock_t irq_lock; /* Prevent race condition on stream state */
        unsigned char cs[SPDIFRX_CS_BYTES_NB];
        unsigned char ub[SPDIFRX_UB_BYTES_NB];
        int irq;
@@ -320,6 +321,7 @@ static void stm32_spdifrx_dma_ctrl_stop(struct stm32_spdifrx_data *spdifrx)
 static int stm32_spdifrx_start_sync(struct stm32_spdifrx_data *spdifrx)
 {
        int cr, cr_mask, imr, ret;
+       unsigned long flags;
 
        /* Enable IRQs */
        imr = SPDIFRX_IMR_IFEIE | SPDIFRX_IMR_SYNCDIE | SPDIFRX_IMR_PERRIE;
@@ -327,7 +329,7 @@ static int stm32_spdifrx_start_sync(struct stm32_spdifrx_data *spdifrx)
        if (ret)
                return ret;
 
-       spin_lock(&spdifrx->lock);
+       spin_lock_irqsave(&spdifrx->lock, flags);
 
        spdifrx->refcount++;
 
@@ -362,7 +364,7 @@ static int stm32_spdifrx_start_sync(struct stm32_spdifrx_data *spdifrx)
                                "Failed to start synchronization\n");
        }
 
-       spin_unlock(&spdifrx->lock);
+       spin_unlock_irqrestore(&spdifrx->lock, flags);
 
        return ret;
 }
@@ -370,11 +372,12 @@ static int stm32_spdifrx_start_sync(struct stm32_spdifrx_data *spdifrx)
 static void stm32_spdifrx_stop(struct stm32_spdifrx_data *spdifrx)
 {
        int cr, cr_mask, reg;
+       unsigned long flags;
 
-       spin_lock(&spdifrx->lock);
+       spin_lock_irqsave(&spdifrx->lock, flags);
 
        if (--spdifrx->refcount) {
-               spin_unlock(&spdifrx->lock);
+               spin_unlock_irqrestore(&spdifrx->lock, flags);
                return;
        }
 
@@ -393,7 +396,7 @@ static void stm32_spdifrx_stop(struct stm32_spdifrx_data *spdifrx)
        regmap_read(spdifrx->regmap, STM32_SPDIFRX_DR, &reg);
        regmap_read(spdifrx->regmap, STM32_SPDIFRX_CSR, &reg);
 
-       spin_unlock(&spdifrx->lock);
+       spin_unlock_irqrestore(&spdifrx->lock, flags);
 }
 
 static int stm32_spdifrx_dma_ctrl_register(struct device *dev,
@@ -480,8 +483,6 @@ static int stm32_spdifrx_get_ctrl_data(struct stm32_spdifrx_data *spdifrx)
        memset(spdifrx->cs, 0, SPDIFRX_CS_BYTES_NB);
        memset(spdifrx->ub, 0, SPDIFRX_UB_BYTES_NB);
 
-       pinctrl_pm_select_default_state(&spdifrx->pdev->dev);
-
        ret = stm32_spdifrx_dma_ctrl_start(spdifrx);
        if (ret < 0)
                return ret;
@@ -513,7 +514,6 @@ static int stm32_spdifrx_get_ctrl_data(struct stm32_spdifrx_data *spdifrx)
 
 end:
        clk_disable_unprepare(spdifrx->kclk);
-       pinctrl_pm_select_sleep_state(&spdifrx->pdev->dev);
 
        return ret;
 }
@@ -665,7 +665,6 @@ static const struct regmap_config stm32_h7_spdifrx_regmap_conf = {
 static irqreturn_t stm32_spdifrx_isr(int irq, void *devid)
 {
        struct stm32_spdifrx_data *spdifrx = (struct stm32_spdifrx_data *)devid;
-       struct snd_pcm_substream *substream = spdifrx->substream;
        struct platform_device *pdev = spdifrx->pdev;
        unsigned int cr, mask, sr, imr;
        unsigned int flags, sync_state;
@@ -745,14 +744,19 @@ static irqreturn_t stm32_spdifrx_isr(int irq, void *devid)
                        return IRQ_HANDLED;
                }
 
-               if (substream)
-                       snd_pcm_stop(substream, SNDRV_PCM_STATE_DISCONNECTED);
+               spin_lock(&spdifrx->irq_lock);
+               if (spdifrx->substream)
+                       snd_pcm_stop(spdifrx->substream,
+                                    SNDRV_PCM_STATE_DISCONNECTED);
+               spin_unlock(&spdifrx->irq_lock);
 
                return IRQ_HANDLED;
        }
 
-       if (err_xrun && substream)
-               snd_pcm_stop_xrun(substream);
+       spin_lock(&spdifrx->irq_lock);
+       if (err_xrun && spdifrx->substream)
+               snd_pcm_stop_xrun(spdifrx->substream);
+       spin_unlock(&spdifrx->irq_lock);
 
        return IRQ_HANDLED;
 }
@@ -761,9 +765,12 @@ static int stm32_spdifrx_startup(struct snd_pcm_substream *substream,
                                 struct snd_soc_dai *cpu_dai)
 {
        struct stm32_spdifrx_data *spdifrx = snd_soc_dai_get_drvdata(cpu_dai);
+       unsigned long flags;
        int ret;
 
+       spin_lock_irqsave(&spdifrx->irq_lock, flags);
        spdifrx->substream = substream;
+       spin_unlock_irqrestore(&spdifrx->irq_lock, flags);
 
        ret = clk_prepare_enable(spdifrx->kclk);
        if (ret)
@@ -839,8 +846,12 @@ static void stm32_spdifrx_shutdown(struct snd_pcm_substream *substream,
                                   struct snd_soc_dai *cpu_dai)
 {
        struct stm32_spdifrx_data *spdifrx = snd_soc_dai_get_drvdata(cpu_dai);
+       unsigned long flags;
 
+       spin_lock_irqsave(&spdifrx->irq_lock, flags);
        spdifrx->substream = NULL;
+       spin_unlock_irqrestore(&spdifrx->irq_lock, flags);
+
        clk_disable_unprepare(spdifrx->kclk);
 }
 
@@ -944,6 +955,7 @@ static int stm32_spdifrx_probe(struct platform_device *pdev)
        spdifrx->pdev = pdev;
        init_completion(&spdifrx->cs_completion);
        spin_lock_init(&spdifrx->lock);
+       spin_lock_init(&spdifrx->irq_lock);
 
        platform_set_drvdata(pdev, spdifrx);
 
index a11c815..0e4eab9 100644 (file)
@@ -370,7 +370,7 @@ static int set_sync_ep_implicit_fb_quirk(struct snd_usb_substream *subs,
 add_sync_ep_from_ifnum:
        iface = usb_ifnum_to_if(dev, ifnum);
 
-       if (!iface || iface->num_altsetting == 0)
+       if (!iface || iface->num_altsetting < 2)
                return -EINVAL;
 
        alts = &iface->altsetting[1];
index a81c206..8218403 100644 (file)
@@ -1397,6 +1397,7 @@ bool snd_usb_get_sample_rate_quirk(struct snd_usb_audio *chip)
        case USB_ID(0x04D8, 0xFEEA): /* Benchmark DAC1 Pre */
        case USB_ID(0x0556, 0x0014): /* Phoenix Audio TMX320VC */
        case USB_ID(0x05A3, 0x9420): /* ELP HD USB Camera */
+       case USB_ID(0x05a7, 0x1020): /* Bose Companion 5 */
        case USB_ID(0x074D, 0x3553): /* Outlaw RR2150 (Micronas UAC3553B) */
        case USB_ID(0x1395, 0x740a): /* Sennheiser DECT */
        case USB_ID(0x1901, 0x0191): /* GE B850V3 CP2114 audio interface */
index f3cbf86..20eed71 100644 (file)
@@ -1228,8 +1228,10 @@ filter_event(struct tep_event_filter *filter, struct tep_event *event,
        }
 
        filter_type = add_filter_type(filter, event->id);
-       if (filter_type == NULL)
+       if (filter_type == NULL) {
+               free_arg(arg);
                return TEP_ERRNO__MEM_ALLOC_FAILED;
+       }
 
        if (filter_type->filter)
                free_arg(filter_type->filter);
index 387311c..de98858 100644 (file)
@@ -1076,6 +1076,7 @@ int cmd_report(int argc, const char **argv)
        struct stat st;
        bool has_br_stack = false;
        int branch_mode = -1;
+       int last_key = 0;
        bool branch_call_mode = false;
 #define CALLCHAIN_DEFAULT_OPT  "graph,0.5,caller,function,percent"
        static const char report_callchain_help[] = "Display call graph (stack chain/backtrace):\n\n"
@@ -1450,7 +1451,8 @@ repeat:
                sort_order = sort_tmp;
        }
 
-       if (setup_sorting(session->evlist) < 0) {
+       if ((last_key != K_SWITCH_INPUT_DATA) &&
+           (setup_sorting(session->evlist) < 0)) {
                if (sort_order)
                        parse_options_usage(report_usage, options, "s", 1);
                if (field_order)
@@ -1530,6 +1532,7 @@ repeat:
        ret = __cmd_report(&report);
        if (ret == K_SWITCH_INPUT_DATA) {
                perf_session__delete(session);
+               last_key = K_SWITCH_INPUT_DATA;
                goto repeat;
        } else
                ret = 0;
index 4528690..0aa63ae 100644 (file)
@@ -339,10 +339,10 @@ static inline void perf_hpp__prepend_sort_field(struct perf_hpp_fmt *format)
        list_for_each_entry_safe(format, tmp, &(_list)->sorts, sort_list)
 
 #define hists__for_each_format(hists, format) \
-       perf_hpp_list__for_each_format((hists)->hpp_list, fmt)
+       perf_hpp_list__for_each_format((hists)->hpp_list, format)
 
 #define hists__for_each_sort_list(hists, format) \
-       perf_hpp_list__for_each_sort_list((hists)->hpp_list, fmt)
+       perf_hpp_list__for_each_sort_list((hists)->hpp_list, format)
 
 extern struct perf_hpp_fmt perf_hpp__format[];
 
index 6658fbf..1965aef 100644 (file)
@@ -920,6 +920,9 @@ static int dso__process_kernel_symbol(struct dso *dso, struct map *map,
                if (curr_map == NULL)
                        return -1;
 
+               if (curr_dso->kernel)
+                       map__kmap(curr_map)->kmaps = kmaps;
+
                if (adjust_kernel_syms) {
                        curr_map->start  = shdr->sh_addr + ref_reloc(kmap);
                        curr_map->end    = curr_map->start + shdr->sh_size;