Merge tag 'nfs-for-5.8-3' of git://git.linux-nfs.org/projects/anna/linux-nfs into...
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 17 Jul 2020 23:37:52 +0000 (16:37 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 17 Jul 2020 23:37:52 +0000 (16:37 -0700)
Pull NFS client fixes from Anna Schumaker:
 "A few more NFS client bugfixes for Linux 5.8:

  NFS:
   - Fix interrupted slots by using the SEQUENCE operation

  SUNRPC:
   - revert d03727b248d0 to fix unkillable IOs

  xprtrdma:
   - Fix double-free in rpcrdma_ep_create()
   - Fix recursion into rpcrdma_xprt_disconnect()
   - Fix return code from rpcrdma_xprt_connect()
   - Fix handling of connect errors
   - Fix incorrect header size calculations"

* tag 'nfs-for-5.8-3' of git://git.linux-nfs.org/projects/anna/linux-nfs:
  SUNRPC reverting d03727b248d0 ("NFSv4 fix CLOSE not waiting for direct IO compeletion")
  xprtrdma: fix incorrect header size calculations
  NFS: Fix interrupted slots by sending a solo SEQUENCE operation
  xprtrdma: Fix handling of connect errors
  xprtrdma: Fix return code from rpcrdma_xprt_connect()
  xprtrdma: Fix recursion into rpcrdma_xprt_disconnect()
  xprtrdma: Fix double-free in rpcrdma_ep_create()

197 files changed:
Documentation/filesystems/overlayfs.rst
MAINTAINERS
arch/arm/boot/dts/am437x-l4.dtsi
arch/arm/boot/dts/imx6qdl-gw551x.dtsi
arch/arm/boot/dts/meson.dtsi
arch/arm/boot/dts/omap3-n900.dts
arch/arm/boot/dts/socfpga.dtsi
arch/arm/boot/dts/socfpga_arria10.dtsi
arch/arm/mach-imx/devices/devices-common.h
arch/arm/mach-imx/devices/platform-gpio-mxc.c
arch/arm/mach-imx/devices/platform-imx-dma.c
arch/arm/mach-imx/mm-imx21.c
arch/arm/mach-imx/mm-imx27.c
arch/arm/mach-omap2/omap_hwmod.c
arch/arm64/boot/dts/altera/socfpga_stratix10.dtsi
arch/arm64/boot/dts/altera/socfpga_stratix10_socdk.dts
arch/arm64/boot/dts/altera/socfpga_stratix10_socdk_nand.dts
arch/arm64/boot/dts/amlogic/meson-gxl-s805x-libretech-ac.dts
arch/arm64/boot/dts/amlogic/meson-gxl-s805x-p241.dts
arch/arm64/boot/dts/amlogic/meson-gxl-s805x.dtsi [new file with mode: 0644]
arch/arm64/boot/dts/amlogic/meson-gxl.dtsi
arch/arm64/boot/dts/intel/socfpga_agilex_socdk.dts
arch/arm64/configs/defconfig
arch/arm64/include/asm/debug-monitors.h
arch/arm64/include/asm/syscall.h
arch/arm64/include/asm/thread_info.h
arch/arm64/kernel/debug-monitors.c
arch/arm64/kernel/ptrace.c
arch/arm64/kernel/signal.c
arch/arm64/kernel/syscall.c
crypto/asymmetric_keys/public_key.c
drivers/base/base.h
drivers/base/core.c
drivers/base/dd.c
drivers/base/regmap/Kconfig
drivers/base/regmap/regmap-debugfs.c
drivers/base/regmap/regmap.c
drivers/block/zram/zram_drv.c
drivers/bus/ti-sysc.c
drivers/char/virtio_console.c
drivers/clk/Kconfig
drivers/clk/clk-ast2600.c
drivers/clk/mvebu/Kconfig
drivers/counter/104-quad-8.c
drivers/cpufreq/intel_pstate.c
drivers/dma-buf/dma-buf.c
drivers/dma/dmatest.c
drivers/dma/dw/core.c
drivers/dma/fsl-edma-common.c
drivers/dma/fsl-edma-common.h
drivers/dma/fsl-edma.c
drivers/dma/idxd/cdev.c
drivers/dma/idxd/device.c
drivers/dma/idxd/idxd.h
drivers/dma/idxd/irq.c
drivers/dma/idxd/sysfs.c
drivers/dma/imx-sdma.c
drivers/dma/ioat/dma.c
drivers/dma/ioat/dma.h
drivers/dma/mcf-edma.c
drivers/dma/sh/usb-dmac.c
drivers/dma/tegra210-adma.c
drivers/dma/ti/k3-udma-private.c
drivers/dma/ti/k3-udma.c
drivers/firmware/efi/libstub/arm64-stub.c
drivers/firmware/efi/libstub/efi-stub-helper.c
drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c
drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c
drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.h
drivers/gpu/drm/amd/display/dc/core/dc_stream.c
drivers/gpu/drm/amd/powerplay/renoir_ppt.c
drivers/gpu/drm/aspeed/aspeed_gfx_drv.c
drivers/gpu/drm/i915/display/intel_fbc.c
drivers/gpu/drm/i915/display/intel_hdmi.c
drivers/gpu/drm/i915/gt/intel_lrc.c
drivers/gpu/drm/i915/gt/selftest_rps.c
drivers/gpu/drm/i915/i915_drv.h
drivers/gpu/drm/i915/i915_perf.c
drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c
drivers/hid/hid-alps.c
drivers/hid/hid-apple.c
drivers/hid/hid-ids.h
drivers/hid/hid-logitech-dj.c
drivers/hid/hid-logitech-hidpp.c
drivers/hid/hid-magicmouse.c
drivers/hid/hid-quirks.c
drivers/hid/hid-steam.c
drivers/hid/i2c-hid/i2c-hid-dmi-quirks.c
drivers/hwtracing/coresight/coresight-cti.c
drivers/hwtracing/coresight/coresight-etm4x.c
drivers/hwtracing/intel_th/core.c
drivers/hwtracing/intel_th/pci.c
drivers/hwtracing/intel_th/sth.c
drivers/iio/accel/mma8452.c
drivers/iio/adc/ad7780.c
drivers/iio/adc/adi-axi-adc.c
drivers/iio/health/afe4403.c
drivers/iio/health/afe4404.c
drivers/iio/humidity/hdc100x.c
drivers/iio/humidity/hts221.h
drivers/iio/humidity/hts221_buffer.c
drivers/iio/industrialio-core.c
drivers/iio/magnetometer/ak8974.c
drivers/iio/pressure/ms5611_core.c
drivers/iio/pressure/zpa2326.c
drivers/input/mouse/elan_i2c_core.c
drivers/input/mouse/synaptics.c
drivers/input/serio/i8042-x86ia64io.h
drivers/input/touchscreen/elants_i2c.c
drivers/iommu/Kconfig
drivers/iommu/amd/amd_iommu.h
drivers/iommu/arm-smmu-qcom.c
drivers/iommu/iommu.c
drivers/iommu/sun50i-iommu.c
drivers/misc/atmel-ssc.c
drivers/misc/mei/bus.c
drivers/nvme/host/core.c
drivers/nvme/host/nvme.h
drivers/opp/of.c
drivers/perf/arm-cci.c
drivers/perf/arm-ccn.c
drivers/perf/arm_dsu_pmu.c
drivers/perf/arm_smmuv3_pmu.c
drivers/perf/arm_spe_pmu.c
drivers/perf/fsl_imx8_ddr_perf.c
drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
drivers/perf/hisilicon/hisi_uncore_hha_pmu.c
drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c
drivers/perf/qcom_l2_pmu.c
drivers/perf/qcom_l3_pmu.c
drivers/perf/thunderx2_pmu.c
drivers/perf/xgene_pmu.c
drivers/phy/allwinner/phy-sun4i-usb.c
drivers/phy/intel/phy-intel-combo.c
drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c
drivers/phy/ti/phy-am654-serdes.c
drivers/phy/ti/phy-j721e-wiz.c
drivers/platform/x86/asus-wmi.c
drivers/platform/x86/intel_speed_select_if/isst_if_common.h
drivers/platform/x86/intel_speed_select_if/isst_if_mbox_pci.c
drivers/platform/x86/intel_speed_select_if/isst_if_mmio.c
drivers/platform/x86/thinkpad_acpi.c
drivers/regulator/Makefile
drivers/regulator/da903x-regulator.c [new file with mode: 0644]
drivers/regulator/da903x.c [deleted file]
drivers/regulator/qcom_smd-regulator.c
drivers/soc/amlogic/meson-gx-socinfo.c
drivers/soc/imx/soc-imx.c
drivers/soundwire/intel.c
drivers/spi/spi-mt65xx.c
drivers/spi/spi-sun6i.c
drivers/staging/comedi/drivers/addi_apci_1500.c
drivers/thermal/intel/int340x_thermal/int3400_thermal.c
drivers/thermal/intel/int340x_thermal/int3403_thermal.c
drivers/thermal/mtk_thermal.c
drivers/tty/serial/cpm_uart/cpm_uart_core.c
drivers/tty/serial/mxs-auart.c
drivers/tty/serial/serial_core.c
drivers/tty/serial/sh-sci.c
drivers/tty/serial/xilinx_uartps.c
drivers/uio/uio_pdrv_genirq.c
drivers/virt/vboxguest/vboxguest_core.c
drivers/virt/vboxguest/vboxguest_core.h
drivers/virt/vboxguest/vboxguest_linux.c
drivers/virt/vboxguest/vmmdev.h
fs/afs/fs_operation.c
fs/afs/write.c
fs/fuse/file.c
fs/fuse/inode.c
fs/io_uring.c
fs/namespace.c
fs/overlayfs/copy_up.c
fs/overlayfs/export.c
fs/overlayfs/file.c
fs/overlayfs/namei.c
fs/overlayfs/overlayfs.h
fs/overlayfs/super.c
include/asm-generic/mmiowb.h
include/linux/device.h
include/linux/dma-buf.h
include/linux/fs_context.h
include/linux/input/elan-i2c-ids.h
include/linux/mod_devicetable.h
include/linux/serial_core.h
include/uapi/linux/idxd.h
include/uapi/linux/input-event-codes.h
include/uapi/linux/vboxguest.h
mm/mremap.c
sound/pci/hda/patch_realtek.c
sound/usb/line6/capture.c
sound/usb/line6/driver.c
sound/usb/line6/playback.c
sound/usb/midi.c

index 660dbaf..fcda5d6 100644 (file)
@@ -560,8 +560,8 @@ When the NFS export feature is enabled, all directory index entries are
 verified on mount time to check that upper file handles are not stale.
 This verification may cause significant overhead in some cases.
 
-Note: the mount options index=off,nfs_export=on are conflicting and will
-result in an error.
+Note: the mount options index=off,nfs_export=on are conflicting for a
+read-write mount and will result in an error.
 
 
 Testsuite
index b4a43a9..d53db30 100644 (file)
@@ -5022,7 +5022,6 @@ F:        drivers/mfd/da91??-*.c
 F:     drivers/pinctrl/pinctrl-da90??.c
 F:     drivers/power/supply/da9052-battery.c
 F:     drivers/power/supply/da91??-*.c
-F:     drivers/regulator/da903x.c
 F:     drivers/regulator/da9???-regulator.[ch]
 F:     drivers/regulator/slg51000-regulator.[ch]
 F:     drivers/rtc/rtc-da90??.c
@@ -5112,7 +5111,7 @@ M:        Vinod Koul <vkoul@kernel.org>
 L:     dmaengine@vger.kernel.org
 S:     Maintained
 Q:     https://patchwork.kernel.org/project/linux-dmaengine/list/
-T:     git git://git.infradead.org/users/vkoul/slave-dma.git
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/vkoul/dmaengine.git
 F:     Documentation/devicetree/bindings/dma/
 F:     Documentation/driver-api/dmaengine/
 F:     drivers/dma/
@@ -17514,7 +17513,7 @@ F:      Documentation/admin-guide/ufs.rst
 F:     fs/ufs/
 
 UHID USERSPACE HID IO DRIVER
-M:     David Herrmann <dh.herrmann@googlemail.com>
+M:     David Rheinsberg <david.rheinsberg@gmail.com>
 L:     linux-input@vger.kernel.org
 S:     Maintained
 F:     drivers/hid/uhid.c
@@ -18473,7 +18472,7 @@ S:      Maintained
 F:     drivers/rtc/rtc-sd3078.c
 
 WIIMOTE HID DRIVER
-M:     David Herrmann <dh.herrmann@googlemail.com>
+M:     David Rheinsberg <david.rheinsberg@gmail.com>
 L:     linux-input@vger.kernel.org
 S:     Maintained
 F:     drivers/hid/hid-wiimote*
index 7d19395..906ac29 100644 (file)
                        reg = <0xcc020 0x4>;
                        reg-names = "rev";
                        /* Domains (P, C): per_pwrdm, l4ls_clkdm */
-                       clocks = <&l4ls_clkctrl AM4_L4LS_D_CAN0_CLKCTRL 0>;
-                       clock-names = "fck";
+                       clocks = <&l4ls_clkctrl AM4_L4LS_D_CAN0_CLKCTRL 0>,
+                       <&dcan0_fck>;
+                       clock-names = "fck", "osc";
                        #address-cells = <1>;
                        #size-cells = <1>;
                        ranges = <0x0 0xcc000 0x2000>;
                        dcan0: can@0 {
                                compatible = "ti,am4372-d_can", "ti,am3352-d_can";
                                reg = <0x0 0x2000>;
+                               clocks = <&dcan0_fck>;
+                               clock-names = "fck";
                                syscon-raminit = <&scm_conf 0x644 0>;
                                interrupts = <GIC_SPI 52 IRQ_TYPE_LEVEL_HIGH>;
                                status = "disabled";
                        reg = <0xd0020 0x4>;
                        reg-names = "rev";
                        /* Domains (P, C): per_pwrdm, l4ls_clkdm */
-                       clocks = <&l4ls_clkctrl AM4_L4LS_D_CAN1_CLKCTRL 0>;
-                       clock-names = "fck";
+                       clocks = <&l4ls_clkctrl AM4_L4LS_D_CAN1_CLKCTRL 0>,
+                       <&dcan1_fck>;
+                       clock-names = "fck", "osc";
                        #address-cells = <1>;
                        #size-cells = <1>;
                        ranges = <0x0 0xd0000 0x2000>;
                        dcan1: can@0 {
                                compatible = "ti,am4372-d_can", "ti,am3352-d_can";
                                reg = <0x0 0x2000>;
+                               clocks = <&dcan1_fck>;
+                               clock-name = "fck";
                                syscon-raminit = <&scm_conf 0x644 1>;
                                interrupts = <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>;
                                status = "disabled";
index c38e86e..8c33510 100644 (file)
                simple-audio-card,frame-master = <&sound_codec>;
 
                sound_cpu: simple-audio-card,cpu {
-                       sound-dai = <&ssi2>;
+                       sound-dai = <&ssi1>;
                };
 
                sound_codec: simple-audio-card,codec {
index ae89dea..91129dc 100644 (file)
@@ -11,7 +11,7 @@
        #size-cells = <1>;
        interrupt-parent = <&gic>;
 
-       L2: l2-cache-controller@c4200000 {
+       L2: cache-controller@c4200000 {
                compatible = "arm,pl310-cache";
                reg = <0xc4200000 0x1000>;
                cache-unified;
index 4089d97..3dbcae3 100644 (file)
                        linux,code = <SW_FRONT_PROXIMITY>;
                        linux,can-disable;
                };
+
+               machine_cover {
+                       label = "Machine Cover";
+                       gpios = <&gpio6 0 GPIO_ACTIVE_LOW>; /* 160 */
+                       linux,input-type = <EV_SW>;
+                       linux,code = <SW_MACHINE_COVER>;
+                       linux,can-disable;
+               };
        };
 
        isp1707: isp1707 {
        pinctrl-0 = <&mmc1_pins>;
        vmmc-supply = <&vmmc1>;
        bus-width = <4>;
-       /* For debugging, it is often good idea to remove this GPIO.
-          It means you can remove back cover (to reboot by removing
-          battery) and still use the MMC card. */
-       cd-gpios = <&gpio6 0 GPIO_ACTIVE_LOW>; /* 160 */
 };
 
 /* most boards use vaux3, only some old versions use vmmc2 instead */
index c2b54af..78f3267 100644 (file)
                        };
                };
 
-               L2: l2-cache@fffef000 {
+               L2: cache-controller@fffef000 {
                        compatible = "arm,pl310-cache";
                        reg = <0xfffef000 0x1000>;
                        interrupts = <0 38 0x04>;
index 3b8571b..8f614c4 100644 (file)
                        reg = <0xffcfb100 0x80>;
                };
 
-               L2: l2-cache@fffff000 {
+               L2: cache-controller@fffff000 {
                        compatible = "arm,pl310-cache";
                        reg = <0xfffff000 0x1000>;
                        interrupts = <0 18 IRQ_TYPE_LEVEL_HIGH>;
index 2a685ad..ae84c08 100644 (file)
@@ -289,6 +289,6 @@ struct platform_device *__init imx_add_spi_imx(
                const struct spi_imx_master *pdata);
 
 struct platform_device *imx_add_imx_dma(char *name, resource_size_t iobase,
-                                       int irq, int irq_err);
+                                       int irq);
 struct platform_device *imx_add_imx_sdma(char *name,
        resource_size_t iobase, int irq, struct sdma_platform_data *pdata);
index 78628ef..355de84 100644 (file)
@@ -24,7 +24,8 @@ struct platform_device *__init mxc_register_gpio(char *name, int id,
                        .flags = IORESOURCE_IRQ,
                },
        };
+       unsigned int nres;
 
-       return platform_device_register_resndata(&mxc_aips_bus,
-                       name, id, res, ARRAY_SIZE(res), NULL, 0);
+       nres = irq_high ? ARRAY_SIZE(res) : ARRAY_SIZE(res) - 1;
+       return platform_device_register_resndata(&mxc_aips_bus, name, id, res, nres, NULL, 0);
 }
index 26b47b3..12656f2 100644 (file)
@@ -6,7 +6,7 @@
 #include "devices-common.h"
 
 struct platform_device __init __maybe_unused *imx_add_imx_dma(char *name,
-       resource_size_t iobase, int irq, int irq_err)
+       resource_size_t iobase, int irq)
 {
        struct resource res[] = {
                {
@@ -17,10 +17,6 @@ struct platform_device __init __maybe_unused *imx_add_imx_dma(char *name,
                        .start = irq,
                        .end = irq,
                        .flags = IORESOURCE_IRQ,
-               }, {
-                       .start = irq_err,
-                       .end = irq_err,
-                       .flags = IORESOURCE_IRQ,
                },
        };
 
index 50a2eda..b834026 100644 (file)
@@ -78,8 +78,7 @@ void __init imx21_soc_init(void)
        mxc_register_gpio("imx21-gpio", 5, MX21_GPIO6_BASE_ADDR, SZ_256, MX21_INT_GPIO, 0);
 
        pinctrl_provide_dummies();
-       imx_add_imx_dma("imx21-dma", MX21_DMA_BASE_ADDR,
-                       MX21_INT_DMACH0, 0); /* No ERR irq */
+       imx_add_imx_dma("imx21-dma", MX21_DMA_BASE_ADDR, MX21_INT_DMACH0);
        platform_device_register_simple("imx21-audmux", 0, imx21_audmux_res,
                                        ARRAY_SIZE(imx21_audmux_res));
 }
index 4e41251..2717614 100644 (file)
@@ -79,8 +79,7 @@ void __init imx27_soc_init(void)
        mxc_register_gpio("imx21-gpio", 5, MX27_GPIO6_BASE_ADDR, SZ_256, MX27_INT_GPIO, 0);
 
        pinctrl_provide_dummies();
-       imx_add_imx_dma("imx27-dma", MX27_DMA_BASE_ADDR,
-                       MX27_INT_DMACH0, 0); /* No ERR irq */
+       imx_add_imx_dma("imx27-dma", MX27_DMA_BASE_ADDR, MX27_INT_DMACH0);
        /* imx27 has the imx21 type audmux */
        platform_device_register_simple("imx21-audmux", 0, imx27_audmux_res,
                                        ARRAY_SIZE(imx27_audmux_res));
index c630457..15b29a1 100644 (file)
@@ -3435,7 +3435,7 @@ static int omap_hwmod_allocate_module(struct device *dev, struct omap_hwmod *oh,
                regs = ioremap(data->module_pa,
                               data->module_size);
                if (!regs)
-                       return -ENOMEM;
+                       goto out_free_sysc;
        }
 
        /*
@@ -3445,13 +3445,13 @@ static int omap_hwmod_allocate_module(struct device *dev, struct omap_hwmod *oh,
        if (oh->class->name && strcmp(oh->class->name, data->name)) {
                class = kmemdup(oh->class, sizeof(*oh->class), GFP_KERNEL);
                if (!class)
-                       return -ENOMEM;
+                       goto out_unmap;
        }
 
        if (list_empty(&oh->slave_ports)) {
                oi = kcalloc(1, sizeof(*oi), GFP_KERNEL);
                if (!oi)
-                       return -ENOMEM;
+                       goto out_free_class;
 
                /*
                 * Note that we assume interconnect interface clocks will be
@@ -3478,6 +3478,14 @@ static int omap_hwmod_allocate_module(struct device *dev, struct omap_hwmod *oh,
        spin_unlock_irqrestore(&oh->_lock, flags);
 
        return 0;
+
+out_free_class:
+       kfree(class);
+out_unmap:
+       iounmap(regs);
+out_free_sysc:
+       kfree(sysc);
+       return -ENOMEM;
 }
 
 static const struct omap_hwmod_reset omap24xx_reset_quirks[] = {
index d1fc9c2..9498d1d 100644 (file)
@@ -77,7 +77,7 @@
                method = "smc";
        };
 
-       intc: intc@fffc1000 {
+       intc: interrupt-controller@fffc1000 {
                compatible = "arm,gic-400", "arm,cortex-a15-gic";
                #interrupt-cells = <3>;
                interrupt-controller;
                        status = "disabled";
                };
 
-               nand: nand@ffb90000 {
+               nand: nand-controller@ffb90000 {
                        #address-cells = <1>;
                        #size-cells = <0>;
                        compatible = "altr,socfpga-denali-nand";
                        clock-names = "timer";
                };
 
-               uart0: serial0@ffc02000 {
+               uart0: serial@ffc02000 {
                        compatible = "snps,dw-apb-uart";
                        reg = <0xffc02000 0x100>;
                        interrupts = <0 108 4>;
                        status = "disabled";
                };
 
-               uart1: serial1@ffc02100 {
+               uart1: serial@ffc02100 {
                        compatible = "snps,dw-apb-uart";
                        reg = <0xffc02100 0x100>;
                        interrupts = <0 109 4>;
index f6c4a15..feadd21 100644 (file)
 };
 
 &qspi {
+       status = "okay";
        flash@0 {
                #address-cells = <1>;
                #size-cells = <1>;
index 9946515..c079667 100644 (file)
 };
 
 &qspi {
+       status = "okay";
        flash@0 {
                #address-cells = <1>;
                #size-cells = <1>;
 
                        qspi_boot: partition@0 {
                                label = "Boot and fpga data";
-                               reg = <0x0 0x034B0000>;
+                               reg = <0x0 0x03FE0000>;
                        };
 
-                       qspi_rootfs: partition@4000000 {
+                       qspi_rootfs: partition@3FE0000 {
                                label = "Root Filesystem - JFFS2";
-                               reg = <0x034B0000 0x0EB50000>;
+                               reg = <0x03FE0000 0x0C020000>;
                        };
                };
        };
index 6a226fa..9e43f4d 100644 (file)
@@ -10,7 +10,7 @@
 #include <dt-bindings/input/input.h>
 #include <dt-bindings/sound/meson-aiu.h>
 
-#include "meson-gxl-s905x.dtsi"
+#include "meson-gxl-s805x.dtsi"
 
 / {
        compatible = "libretech,aml-s805x-ac", "amlogic,s805x",
index 867e30f..eb7f5a3 100644 (file)
@@ -9,7 +9,7 @@
 
 #include <dt-bindings/input/input.h>
 
-#include "meson-gxl-s905x.dtsi"
+#include "meson-gxl-s805x.dtsi"
 
 / {
        compatible = "amlogic,p241", "amlogic,s805x", "amlogic,meson-gxl";
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s805x.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxl-s805x.dtsi
new file mode 100644 (file)
index 0000000..f9d7056
--- /dev/null
@@ -0,0 +1,24 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2020 BayLibre SAS
+ * Author: Neil Armstrong <narmstrong@baylibre.com>
+ */
+
+#include "meson-gxl-s905x.dtsi"
+
+/ {
+       compatible = "amlogic,s805x", "amlogic,meson-gxl";
+};
+
+/* The S805X Package doesn't seem to handle the 744MHz OPP correctly */
+&mali {
+       assigned-clocks = <&clkc CLKID_MALI_0_SEL>,
+                         <&clkc CLKID_MALI_0>,
+                         <&clkc CLKID_MALI>; /* Glitch free mux */
+       assigned-clock-parents = <&clkc CLKID_FCLK_DIV3>,
+                                <0>, /* Do Nothing */
+                                <&clkc CLKID_MALI_0>;
+       assigned-clock-rates = <0>, /* Do Nothing */
+                              <666666666>,
+                              <0>; /* Do Nothing */
+};
index fc59c85..6c8b189 100644 (file)
        };
 };
 
+&hwrng {
+       clocks = <&clkc CLKID_RNG0>;
+       clock-names = "core";
+};
+
 &i2c_A {
        clocks = <&clkc CLKID_I2C>;
 };
index 51d9483..92f478d 100644 (file)
@@ -98,6 +98,7 @@
 };
 
 &qspi {
+       status = "okay";
        flash@0 {
                #address-cells = <1>;
                #size-cells = <1>;
index 883e8ba..2ca7ba6 100644 (file)
@@ -194,7 +194,7 @@ CONFIG_HOTPLUG_PCI=y
 CONFIG_HOTPLUG_PCI_ACPI=y
 CONFIG_PCI_AARDVARK=y
 CONFIG_PCI_TEGRA=y
-CONFIG_PCIE_RCAR=y
+CONFIG_PCIE_RCAR_HOST=y
 CONFIG_PCI_HOST_GENERIC=y
 CONFIG_PCI_XGENE=y
 CONFIG_PCIE_ALTERA=y
index e5ceea2..0b298f4 100644 (file)
@@ -109,6 +109,8 @@ void disable_debug_monitors(enum dbg_active_el el);
 
 void user_rewind_single_step(struct task_struct *task);
 void user_fastforward_single_step(struct task_struct *task);
+void user_regs_reset_single_step(struct user_pt_regs *regs,
+                                struct task_struct *task);
 
 void kernel_enable_single_step(struct pt_regs *regs);
 void kernel_disable_single_step(void);
index 65299a2..cfc0672 100644 (file)
@@ -34,6 +34,10 @@ static inline long syscall_get_error(struct task_struct *task,
                                     struct pt_regs *regs)
 {
        unsigned long error = regs->regs[0];
+
+       if (is_compat_thread(task_thread_info(task)))
+               error = sign_extend64(error, 31);
+
        return IS_ERR_VALUE(error) ? error : 0;
 }
 
@@ -47,7 +51,13 @@ static inline void syscall_set_return_value(struct task_struct *task,
                                            struct pt_regs *regs,
                                            int error, long val)
 {
-       regs->regs[0] = (long) error ? error : val;
+       if (error)
+               val = error;
+
+       if (is_compat_thread(task_thread_info(task)))
+               val = lower_32_bits(val);
+
+       regs->regs[0] = val;
 }
 
 #define SYSCALL_MAX_ARGS 6
index 6ea8b6a..5e784e1 100644 (file)
@@ -93,6 +93,7 @@ void arch_release_task_struct(struct task_struct *tsk);
 #define _TIF_SYSCALL_EMU       (1 << TIF_SYSCALL_EMU)
 #define _TIF_UPROBE            (1 << TIF_UPROBE)
 #define _TIF_FSCHECK           (1 << TIF_FSCHECK)
+#define _TIF_SINGLESTEP                (1 << TIF_SINGLESTEP)
 #define _TIF_32BIT             (1 << TIF_32BIT)
 #define _TIF_SVE               (1 << TIF_SVE)
 
index 5df4936..7310a4f 100644 (file)
@@ -141,17 +141,20 @@ postcore_initcall(debug_monitors_init);
 /*
  * Single step API and exception handling.
  */
-static void set_regs_spsr_ss(struct pt_regs *regs)
+static void set_user_regs_spsr_ss(struct user_pt_regs *regs)
 {
        regs->pstate |= DBG_SPSR_SS;
 }
-NOKPROBE_SYMBOL(set_regs_spsr_ss);
+NOKPROBE_SYMBOL(set_user_regs_spsr_ss);
 
-static void clear_regs_spsr_ss(struct pt_regs *regs)
+static void clear_user_regs_spsr_ss(struct user_pt_regs *regs)
 {
        regs->pstate &= ~DBG_SPSR_SS;
 }
-NOKPROBE_SYMBOL(clear_regs_spsr_ss);
+NOKPROBE_SYMBOL(clear_user_regs_spsr_ss);
+
+#define set_regs_spsr_ss(r)    set_user_regs_spsr_ss(&(r)->user_regs)
+#define clear_regs_spsr_ss(r)  clear_user_regs_spsr_ss(&(r)->user_regs)
 
 static DEFINE_SPINLOCK(debug_hook_lock);
 static LIST_HEAD(user_step_hook);
@@ -391,17 +394,26 @@ void user_rewind_single_step(struct task_struct *task)
         * If single step is active for this thread, then set SPSR.SS
         * to 1 to avoid returning to the active-pending state.
         */
-       if (test_ti_thread_flag(task_thread_info(task), TIF_SINGLESTEP))
+       if (test_tsk_thread_flag(task, TIF_SINGLESTEP))
                set_regs_spsr_ss(task_pt_regs(task));
 }
 NOKPROBE_SYMBOL(user_rewind_single_step);
 
 void user_fastforward_single_step(struct task_struct *task)
 {
-       if (test_ti_thread_flag(task_thread_info(task), TIF_SINGLESTEP))
+       if (test_tsk_thread_flag(task, TIF_SINGLESTEP))
                clear_regs_spsr_ss(task_pt_regs(task));
 }
 
+void user_regs_reset_single_step(struct user_pt_regs *regs,
+                                struct task_struct *task)
+{
+       if (test_tsk_thread_flag(task, TIF_SINGLESTEP))
+               set_user_regs_spsr_ss(regs);
+       else
+               clear_user_regs_spsr_ss(regs);
+}
+
 /* Kernel API */
 void kernel_enable_single_step(struct pt_regs *regs)
 {
index 68b7f34..1e02e98 100644 (file)
@@ -1811,19 +1811,42 @@ static void tracehook_report_syscall(struct pt_regs *regs,
        unsigned long saved_reg;
 
        /*
-        * A scratch register (ip(r12) on AArch32, x7 on AArch64) is
-        * used to denote syscall entry/exit:
+        * We have some ABI weirdness here in the way that we handle syscall
+        * exit stops because we indicate whether or not the stop has been
+        * signalled from syscall entry or syscall exit by clobbering a general
+        * purpose register (ip/r12 for AArch32, x7 for AArch64) in the tracee
+        * and restoring its old value after the stop. This means that:
+        *
+        * - Any writes by the tracer to this register during the stop are
+        *   ignored/discarded.
+        *
+        * - The actual value of the register is not available during the stop,
+        *   so the tracer cannot save it and restore it later.
+        *
+        * - Syscall stops behave differently to seccomp and pseudo-step traps
+        *   (the latter do not nobble any registers).
         */
        regno = (is_compat_task() ? 12 : 7);
        saved_reg = regs->regs[regno];
        regs->regs[regno] = dir;
 
-       if (dir == PTRACE_SYSCALL_EXIT)
+       if (dir == PTRACE_SYSCALL_ENTER) {
+               if (tracehook_report_syscall_entry(regs))
+                       forget_syscall(regs);
+               regs->regs[regno] = saved_reg;
+       } else if (!test_thread_flag(TIF_SINGLESTEP)) {
                tracehook_report_syscall_exit(regs, 0);
-       else if (tracehook_report_syscall_entry(regs))
-               forget_syscall(regs);
+               regs->regs[regno] = saved_reg;
+       } else {
+               regs->regs[regno] = saved_reg;
 
-       regs->regs[regno] = saved_reg;
+               /*
+                * Signal a pseudo-step exception since we are stepping but
+                * tracer modifications to the registers may have rewound the
+                * state machine.
+                */
+               tracehook_report_syscall_exit(regs, 1);
+       }
 }
 
 int syscall_trace_enter(struct pt_regs *regs)
@@ -1833,12 +1856,12 @@ int syscall_trace_enter(struct pt_regs *regs)
        if (flags & (_TIF_SYSCALL_EMU | _TIF_SYSCALL_TRACE)) {
                tracehook_report_syscall(regs, PTRACE_SYSCALL_ENTER);
                if (!in_syscall(regs) || (flags & _TIF_SYSCALL_EMU))
-                       return -1;
+                       return NO_SYSCALL;
        }
 
        /* Do the secure computing after ptrace; failures should be fast. */
        if (secure_computing() == -1)
-               return -1;
+               return NO_SYSCALL;
 
        if (test_thread_flag(TIF_SYSCALL_TRACEPOINT))
                trace_sys_enter(regs, regs->syscallno);
@@ -1851,12 +1874,14 @@ int syscall_trace_enter(struct pt_regs *regs)
 
 void syscall_trace_exit(struct pt_regs *regs)
 {
+       unsigned long flags = READ_ONCE(current_thread_info()->flags);
+
        audit_syscall_exit(regs);
 
-       if (test_thread_flag(TIF_SYSCALL_TRACEPOINT))
+       if (flags & _TIF_SYSCALL_TRACEPOINT)
                trace_sys_exit(regs, regs_return_value(regs));
 
-       if (test_thread_flag(TIF_SYSCALL_TRACE))
+       if (flags & (_TIF_SYSCALL_TRACE | _TIF_SINGLESTEP))
                tracehook_report_syscall(regs, PTRACE_SYSCALL_EXIT);
 
        rseq_syscall(regs);
@@ -1934,8 +1959,8 @@ static int valid_native_regs(struct user_pt_regs *regs)
  */
 int valid_user_regs(struct user_pt_regs *regs, struct task_struct *task)
 {
-       if (!test_tsk_thread_flag(task, TIF_SINGLESTEP))
-               regs->pstate &= ~DBG_SPSR_SS;
+       /* https://lore.kernel.org/lkml/20191118131525.GA4180@willie-the-truck */
+       user_regs_reset_single_step(regs, task);
 
        if (is_compat_thread(task_thread_info(task)))
                return valid_compat_regs(regs);
index 801d56c..3b4f31f 100644 (file)
@@ -800,7 +800,6 @@ static void setup_restart_syscall(struct pt_regs *regs)
  */
 static void handle_signal(struct ksignal *ksig, struct pt_regs *regs)
 {
-       struct task_struct *tsk = current;
        sigset_t *oldset = sigmask_to_save();
        int usig = ksig->sig;
        int ret;
@@ -824,14 +823,8 @@ static void handle_signal(struct ksignal *ksig, struct pt_regs *regs)
         */
        ret |= !valid_user_regs(&regs->user_regs, current);
 
-       /*
-        * Fast forward the stepping logic so we step into the signal
-        * handler.
-        */
-       if (!ret)
-               user_fastforward_single_step(tsk);
-
-       signal_setup_done(ret, ksig, 0);
+       /* Step into the signal handler if we are stepping */
+       signal_setup_done(ret, ksig, test_thread_flag(TIF_SINGLESTEP));
 }
 
 /*
index 5f5b868..5f0c048 100644 (file)
@@ -50,6 +50,9 @@ static void invoke_syscall(struct pt_regs *regs, unsigned int scno,
                ret = do_ni_syscall(regs, scno);
        }
 
+       if (is_compat_task())
+               ret = lower_32_bits(ret);
+
        regs->regs[0] = ret;
 }
 
@@ -121,7 +124,21 @@ static void el0_svc_common(struct pt_regs *regs, int scno, int sc_nr,
        user_exit();
 
        if (has_syscall_work(flags)) {
-               /* set default errno for user-issued syscall(-1) */
+               /*
+                * The de-facto standard way to skip a system call using ptrace
+                * is to set the system call to -1 (NO_SYSCALL) and set x0 to a
+                * suitable error code for consumption by userspace. However,
+                * this cannot be distinguished from a user-issued syscall(-1)
+                * and so we must set x0 to -ENOSYS here in case the tracer doesn't
+                * issue the skip and we fall into trace_exit with x0 preserved.
+                *
+                * This is slightly odd because it also means that if a tracer
+                * sets the system call number to -1 but does not initialise x0,
+                * then x0 will be preserved for all system calls apart from a
+                * user-issued syscall(-1). However, requesting a skip and not
+                * setting the return value is unlikely to do anything sensible
+                * anyway.
+                */
                if (scno == NO_SYSCALL)
                        regs->regs[0] = -ENOSYS;
                scno = syscall_trace_enter(regs);
@@ -139,7 +156,7 @@ static void el0_svc_common(struct pt_regs *regs, int scno, int sc_nr,
        if (!has_syscall_work(flags) && !IS_ENABLED(CONFIG_DEBUG_RSEQ)) {
                local_daif_mask();
                flags = current_thread_info()->flags;
-               if (!has_syscall_work(flags)) {
+               if (!has_syscall_work(flags) && !(flags & _TIF_SINGLESTEP)) {
                        /*
                         * We're off to userspace, where interrupts are
                         * always enabled after we restore the flags from
index d7f43d4..e5fae4e 100644 (file)
@@ -119,6 +119,7 @@ static int software_key_query(const struct kernel_pkey_params *params,
        if (IS_ERR(tfm))
                return PTR_ERR(tfm);
 
+       ret = -ENOMEM;
        key = kmalloc(pkey->keylen + sizeof(u32) * 2 + pkey->paramlen,
                      GFP_KERNEL);
        if (!key)
index 95c22c0..40fb069 100644 (file)
@@ -153,7 +153,6 @@ extern char *make_class_name(const char *name, struct kobject *kobj);
 extern int devres_release_all(struct device *dev);
 extern void device_block_probing(void);
 extern void device_unblock_probing(void);
-extern void driver_deferred_probe_force_trigger(void);
 
 /* /sys/devices directory */
 extern struct kset *devices_kset;
index 67d39a9..05d414e 100644 (file)
@@ -50,6 +50,7 @@ static DEFINE_MUTEX(wfs_lock);
 static LIST_HEAD(deferred_sync);
 static unsigned int defer_sync_state_count = 1;
 static unsigned int defer_fw_devlink_count;
+static LIST_HEAD(deferred_fw_devlink);
 static DEFINE_MUTEX(defer_fw_devlink_lock);
 static bool fw_devlink_is_permissive(void);
 
@@ -754,11 +755,11 @@ static void __device_links_queue_sync_state(struct device *dev,
         */
        dev->state_synced = true;
 
-       if (WARN_ON(!list_empty(&dev->links.defer_sync)))
+       if (WARN_ON(!list_empty(&dev->links.defer_hook)))
                return;
 
        get_device(dev);
-       list_add_tail(&dev->links.defer_sync, list);
+       list_add_tail(&dev->links.defer_hook, list);
 }
 
 /**
@@ -776,8 +777,8 @@ static void device_links_flush_sync_list(struct list_head *list,
 {
        struct device *dev, *tmp;
 
-       list_for_each_entry_safe(dev, tmp, list, links.defer_sync) {
-               list_del_init(&dev->links.defer_sync);
+       list_for_each_entry_safe(dev, tmp, list, links.defer_hook) {
+               list_del_init(&dev->links.defer_hook);
 
                if (dev != dont_lock_dev)
                        device_lock(dev);
@@ -815,12 +816,12 @@ void device_links_supplier_sync_state_resume(void)
        if (defer_sync_state_count)
                goto out;
 
-       list_for_each_entry_safe(dev, tmp, &deferred_sync, links.defer_sync) {
+       list_for_each_entry_safe(dev, tmp, &deferred_sync, links.defer_hook) {
                /*
                 * Delete from deferred_sync list before queuing it to
-                * sync_list because defer_sync is used for both lists.
+                * sync_list because defer_hook is used for both lists.
                 */
-               list_del_init(&dev->links.defer_sync);
+               list_del_init(&dev->links.defer_hook);
                __device_links_queue_sync_state(dev, &sync_list);
        }
 out:
@@ -838,8 +839,8 @@ late_initcall(sync_state_resume_initcall);
 
 static void __device_links_supplier_defer_sync(struct device *sup)
 {
-       if (list_empty(&sup->links.defer_sync) && dev_has_sync_state(sup))
-               list_add_tail(&sup->links.defer_sync, &deferred_sync);
+       if (list_empty(&sup->links.defer_hook) && dev_has_sync_state(sup))
+               list_add_tail(&sup->links.defer_hook, &deferred_sync);
 }
 
 static void device_link_drop_managed(struct device_link *link)
@@ -1052,7 +1053,7 @@ void device_links_driver_cleanup(struct device *dev)
                WRITE_ONCE(link->status, DL_STATE_DORMANT);
        }
 
-       list_del_init(&dev->links.defer_sync);
+       list_del_init(&dev->links.defer_hook);
        __device_links_no_driver(dev);
 
        device_links_write_unlock();
@@ -1244,6 +1245,12 @@ static void fw_devlink_link_device(struct device *dev)
                        fw_ret = -EAGAIN;
        } else {
                fw_ret = -ENODEV;
+               /*
+                * defer_hook is not used to add device to deferred_sync list
+                * until device is bound. Since deferred fw devlink also blocks
+                * probing, same list hook can be used for deferred_fw_devlink.
+                */
+               list_add_tail(&dev->links.defer_hook, &deferred_fw_devlink);
        }
 
        if (fw_ret == -ENODEV)
@@ -1312,6 +1319,9 @@ void fw_devlink_pause(void)
  */
 void fw_devlink_resume(void)
 {
+       struct device *dev, *tmp;
+       LIST_HEAD(probe_list);
+
        mutex_lock(&defer_fw_devlink_lock);
        if (!defer_fw_devlink_count) {
                WARN(true, "Unmatched fw_devlink pause/resume!");
@@ -1323,9 +1333,19 @@ void fw_devlink_resume(void)
                goto out;
 
        device_link_add_missing_supplier_links();
-       driver_deferred_probe_force_trigger();
+       list_splice_tail_init(&deferred_fw_devlink, &probe_list);
 out:
        mutex_unlock(&defer_fw_devlink_lock);
+
+       /*
+        * bus_probe_device() can cause new devices to get added and they'll
+        * try to grab defer_fw_devlink_lock. So, this needs to be done outside
+        * the defer_fw_devlink_lock.
+        */
+       list_for_each_entry_safe(dev, tmp, &probe_list, links.defer_hook) {
+               list_del_init(&dev->links.defer_hook);
+               bus_probe_device(dev);
+       }
 }
 /* Device links support end. */
 
@@ -2172,7 +2192,7 @@ void device_initialize(struct device *dev)
        INIT_LIST_HEAD(&dev->links.consumers);
        INIT_LIST_HEAD(&dev->links.suppliers);
        INIT_LIST_HEAD(&dev->links.needs_suppliers);
-       INIT_LIST_HEAD(&dev->links.defer_sync);
+       INIT_LIST_HEAD(&dev->links.defer_hook);
        dev->links.status = DL_DEV_NO_DRIVER;
 }
 EXPORT_SYMBOL_GPL(device_initialize);
index 9a1d940..48ca81c 100644 (file)
@@ -164,11 +164,6 @@ static void driver_deferred_probe_trigger(void)
        if (!driver_deferred_probe_enable)
                return;
 
-       driver_deferred_probe_force_trigger();
-}
-
-void driver_deferred_probe_force_trigger(void)
-{
        /*
         * A successful probe means that all the devices in the pending list
         * should be triggered to be reprobed.  Move all the deferred devices
index 0fd6f97..1d1d26b 100644 (file)
@@ -4,7 +4,7 @@
 # subsystems should select the appropriate symbols.
 
 config REGMAP
-       default y if (REGMAP_I2C || REGMAP_SPI || REGMAP_SPMI || REGMAP_W1 || REGMAP_AC97 || REGMAP_MMIO || REGMAP_IRQ || REGMAP_SCCB || REGMAP_I3C)
+       default y if (REGMAP_I2C || REGMAP_SPI || REGMAP_SPMI || REGMAP_W1 || REGMAP_AC97 || REGMAP_MMIO || REGMAP_IRQ || REGMAP_SOUNDWIRE || REGMAP_SCCB || REGMAP_I3C)
        select IRQ_DOMAIN if REGMAP_IRQ
        bool
 
index 089e5dc..f58baff 100644 (file)
@@ -463,29 +463,31 @@ static ssize_t regmap_cache_only_write_file(struct file *file,
 {
        struct regmap *map = container_of(file->private_data,
                                          struct regmap, cache_only);
-       ssize_t result;
-       bool was_enabled, require_sync = false;
+       bool new_val, require_sync = false;
        int err;
 
-       map->lock(map->lock_arg);
+       err = kstrtobool_from_user(user_buf, count, &new_val);
+       /* Ignore malforned data like debugfs_write_file_bool() */
+       if (err)
+               return count;
 
-       was_enabled = map->cache_only;
+       err = debugfs_file_get(file->f_path.dentry);
+       if (err)
+               return err;
 
-       result = debugfs_write_file_bool(file, user_buf, count, ppos);
-       if (result < 0) {
-               map->unlock(map->lock_arg);
-               return result;
-       }
+       map->lock(map->lock_arg);
 
-       if (map->cache_only && !was_enabled) {
+       if (new_val && !map->cache_only) {
                dev_warn(map->dev, "debugfs cache_only=Y forced\n");
                add_taint(TAINT_USER, LOCKDEP_STILL_OK);
-       } else if (!map->cache_only && was_enabled) {
+       } else if (!new_val && map->cache_only) {
                dev_warn(map->dev, "debugfs cache_only=N forced: syncing cache\n");
                require_sync = true;
        }
+       map->cache_only = new_val;
 
        map->unlock(map->lock_arg);
+       debugfs_file_put(file->f_path.dentry);
 
        if (require_sync) {
                err = regcache_sync(map);
@@ -493,7 +495,7 @@ static ssize_t regmap_cache_only_write_file(struct file *file,
                        dev_err(map->dev, "Failed to sync cache %d\n", err);
        }
 
-       return result;
+       return count;
 }
 
 static const struct file_operations regmap_cache_only_fops = {
@@ -508,28 +510,32 @@ static ssize_t regmap_cache_bypass_write_file(struct file *file,
 {
        struct regmap *map = container_of(file->private_data,
                                          struct regmap, cache_bypass);
-       ssize_t result;
-       bool was_enabled;
+       bool new_val;
+       int err;
 
-       map->lock(map->lock_arg);
+       err = kstrtobool_from_user(user_buf, count, &new_val);
+       /* Ignore malforned data like debugfs_write_file_bool() */
+       if (err)
+               return count;
 
-       was_enabled = map->cache_bypass;
+       err = debugfs_file_get(file->f_path.dentry);
+       if (err)
+               return err;
 
-       result = debugfs_write_file_bool(file, user_buf, count, ppos);
-       if (result < 0)
-               goto out;
+       map->lock(map->lock_arg);
 
-       if (map->cache_bypass && !was_enabled) {
+       if (new_val && !map->cache_bypass) {
                dev_warn(map->dev, "debugfs cache_bypass=Y forced\n");
                add_taint(TAINT_USER, LOCKDEP_STILL_OK);
-       } else if (!map->cache_bypass && was_enabled) {
+       } else if (!new_val && map->cache_bypass) {
                dev_warn(map->dev, "debugfs cache_bypass=N forced\n");
        }
+       map->cache_bypass = new_val;
 
-out:
        map->unlock(map->lock_arg);
+       debugfs_file_put(file->f_path.dentry);
 
-       return result;
+       return count;
 }
 
 static const struct file_operations regmap_cache_bypass_fops = {
index 06a7968..795a62a 100644 (file)
@@ -1364,7 +1364,7 @@ static int dev_get_regmap_match(struct device *dev, void *res, void *data)
 
        /* If the user didn't specify a name match any */
        if (data)
-               return (*r)->name == data;
+               return !strcmp((*r)->name, data);
        else
                return 1;
 }
index 6e2ad90..270dd81 100644 (file)
@@ -2021,7 +2021,8 @@ static ssize_t hot_add_show(struct class *class,
                return ret;
        return scnprintf(buf, PAGE_SIZE, "%d\n", ret);
 }
-static CLASS_ATTR_RO(hot_add);
+static struct class_attribute class_attr_hot_add =
+       __ATTR(hot_add, 0400, hot_add_show, NULL);
 
 static ssize_t hot_remove_store(struct class *class,
                        struct class_attribute *attr,
index bb54fb5..4f513fa 100644 (file)
@@ -236,15 +236,14 @@ static int sysc_wait_softreset(struct sysc *ddata)
                syss_done = ddata->cfg.syss_mask;
 
        if (syss_offset >= 0) {
-               error = readx_poll_timeout(sysc_read_sysstatus, ddata, rstval,
-                                          (rstval & ddata->cfg.syss_mask) ==
-                                          syss_done,
-                                          100, MAX_MODULE_SOFTRESET_WAIT);
+               error = readx_poll_timeout_atomic(sysc_read_sysstatus, ddata,
+                               rstval, (rstval & ddata->cfg.syss_mask) ==
+                               syss_done, 100, MAX_MODULE_SOFTRESET_WAIT);
 
        } else if (ddata->cfg.quirks & SYSC_QUIRK_RESET_STATUS) {
-               error = readx_poll_timeout(sysc_read_sysconfig, ddata, rstval,
-                                          !(rstval & sysc_mask),
-                                          100, MAX_MODULE_SOFTRESET_WAIT);
+               error = readx_poll_timeout_atomic(sysc_read_sysconfig, ddata,
+                               rstval, !(rstval & sysc_mask),
+                               100, MAX_MODULE_SOFTRESET_WAIT);
        }
 
        return error;
@@ -1279,7 +1278,8 @@ static int __maybe_unused sysc_noirq_suspend(struct device *dev)
 
        ddata = dev_get_drvdata(dev);
 
-       if (ddata->cfg.quirks & SYSC_QUIRK_LEGACY_IDLE)
+       if (ddata->cfg.quirks &
+           (SYSC_QUIRK_LEGACY_IDLE | SYSC_QUIRK_NO_IDLE))
                return 0;
 
        return pm_runtime_force_suspend(dev);
@@ -1291,7 +1291,8 @@ static int __maybe_unused sysc_noirq_resume(struct device *dev)
 
        ddata = dev_get_drvdata(dev);
 
-       if (ddata->cfg.quirks & SYSC_QUIRK_LEGACY_IDLE)
+       if (ddata->cfg.quirks &
+           (SYSC_QUIRK_LEGACY_IDLE | SYSC_QUIRK_NO_IDLE))
                return 0;
 
        return pm_runtime_force_resume(dev);
@@ -1728,8 +1729,8 @@ static void sysc_quirk_rtc(struct sysc *ddata, bool lock)
 
        local_irq_save(flags);
        /* RTC_STATUS BUSY bit may stay active for 1/32768 seconds (~30 usec) */
-       error = readl_poll_timeout(ddata->module_va + 0x44, val,
-                                  !(val & BIT(0)), 100, 50);
+       error = readl_poll_timeout_atomic(ddata->module_va + 0x44, val,
+                                         !(val & BIT(0)), 100, 50);
        if (error)
                dev_warn(ddata->dev, "rtc busy timeout\n");
        /* Now we have ~15 microseconds to read/write various registers */
index 00c5e3a..ca691bc 100644 (file)
@@ -2116,6 +2116,7 @@ static struct virtio_device_id id_table[] = {
        { VIRTIO_ID_CONSOLE, VIRTIO_DEV_ANY_ID },
        { 0 },
 };
+MODULE_DEVICE_TABLE(virtio, id_table);
 
 static unsigned int features[] = {
        VIRTIO_CONSOLE_F_SIZE,
@@ -2128,6 +2129,7 @@ static struct virtio_device_id rproc_serial_id_table[] = {
 #endif
        { 0 },
 };
+MODULE_DEVICE_TABLE(virtio, rproc_serial_id_table);
 
 static unsigned int rproc_serial_features[] = {
 };
@@ -2280,6 +2282,5 @@ static void __exit fini(void)
 module_init(init);
 module_exit(fini);
 
-MODULE_DEVICE_TABLE(virtio, id_table);
 MODULE_DESCRIPTION("Virtio console driver");
 MODULE_LICENSE("GPL");
index 69934c0..326f91b 100644 (file)
@@ -50,6 +50,7 @@ source "drivers/clk/versatile/Kconfig"
 config CLK_HSDK
        bool "PLL Driver for HSDK platform"
        depends on OF || COMPILE_TEST
+       depends on IOMEM
        help
          This driver supports the HSDK core, system, ddr, tunnel and hdmi PLLs
          control.
index 99afc94..177368c 100644 (file)
@@ -131,6 +131,18 @@ static const struct clk_div_table ast2600_eclk_div_table[] = {
        { 0 }
 };
 
+static const struct clk_div_table ast2600_emmc_extclk_div_table[] = {
+       { 0x0, 2 },
+       { 0x1, 4 },
+       { 0x2, 6 },
+       { 0x3, 8 },
+       { 0x4, 10 },
+       { 0x5, 12 },
+       { 0x6, 14 },
+       { 0x7, 16 },
+       { 0 }
+};
+
 static const struct clk_div_table ast2600_mac_div_table[] = {
        { 0x0, 4 },
        { 0x1, 4 },
@@ -390,6 +402,11 @@ static struct clk_hw *aspeed_g6_clk_hw_register_gate(struct device *dev,
        return hw;
 }
 
+static const char *const emmc_extclk_parent_names[] = {
+       "emmc_extclk_hpll_in",
+       "mpll",
+};
+
 static const char * const vclk_parent_names[] = {
        "dpll",
        "d1pll",
@@ -459,16 +476,32 @@ static int aspeed_g6_clk_probe(struct platform_device *pdev)
                return PTR_ERR(hw);
        aspeed_g6_clk_data->hws[ASPEED_CLK_UARTX] = hw;
 
-       /* EMMC ext clock divider */
-       hw = clk_hw_register_gate(dev, "emmc_extclk_gate", "hpll", 0,
-                       scu_g6_base + ASPEED_G6_CLK_SELECTION1, 15, 0,
-                       &aspeed_g6_clk_lock);
+       /* EMMC ext clock */
+       hw = clk_hw_register_fixed_factor(dev, "emmc_extclk_hpll_in", "hpll",
+                                         0, 1, 2);
        if (IS_ERR(hw))
                return PTR_ERR(hw);
-       hw = clk_hw_register_divider_table(dev, "emmc_extclk", "emmc_extclk_gate", 0,
-                       scu_g6_base + ASPEED_G6_CLK_SELECTION1, 12, 3, 0,
-                       ast2600_div_table,
-                       &aspeed_g6_clk_lock);
+
+       hw = clk_hw_register_mux(dev, "emmc_extclk_mux",
+                                emmc_extclk_parent_names,
+                                ARRAY_SIZE(emmc_extclk_parent_names), 0,
+                                scu_g6_base + ASPEED_G6_CLK_SELECTION1, 11, 1,
+                                0, &aspeed_g6_clk_lock);
+       if (IS_ERR(hw))
+               return PTR_ERR(hw);
+
+       hw = clk_hw_register_gate(dev, "emmc_extclk_gate", "emmc_extclk_mux",
+                                 0, scu_g6_base + ASPEED_G6_CLK_SELECTION1,
+                                 15, 0, &aspeed_g6_clk_lock);
+       if (IS_ERR(hw))
+               return PTR_ERR(hw);
+
+       hw = clk_hw_register_divider_table(dev, "emmc_extclk",
+                                          "emmc_extclk_gate", 0,
+                                          scu_g6_base +
+                                               ASPEED_G6_CLK_SELECTION1, 12,
+                                          3, 0, ast2600_emmc_extclk_div_table,
+                                          &aspeed_g6_clk_lock);
        if (IS_ERR(hw))
                return PTR_ERR(hw);
        aspeed_g6_clk_data->hws[ASPEED_CLK_EMMC] = hw;
index ded07b0..557d621 100644 (file)
@@ -42,6 +42,7 @@ config ARMADA_AP806_SYSCON
 
 config ARMADA_AP_CPU_CLK
        bool
+       select ARMADA_AP_CP_HELPER
 
 config ARMADA_CP110_SYSCON
        bool
index aa13708..d22cfae 100644 (file)
@@ -1274,18 +1274,26 @@ static ssize_t quad8_signal_cable_fault_read(struct counter_device *counter,
                                             struct counter_signal *signal,
                                             void *private, char *buf)
 {
-       const struct quad8_iio *const priv = counter->priv;
+       struct quad8_iio *const priv = counter->priv;
        const size_t channel_id = signal->id / 2;
-       const bool disabled = !(priv->cable_fault_enable & BIT(channel_id));
+       bool disabled;
        unsigned int status;
        unsigned int fault;
 
-       if (disabled)
+       mutex_lock(&priv->lock);
+
+       disabled = !(priv->cable_fault_enable & BIT(channel_id));
+
+       if (disabled) {
+               mutex_unlock(&priv->lock);
                return -EINVAL;
+       }
 
        /* Logic 0 = cable fault */
        status = inb(priv->base + QUAD8_DIFF_ENCODER_CABLE_STATUS);
 
+       mutex_unlock(&priv->lock);
+
        /* Mask respective channel and invert logic */
        fault = !(status & BIT(channel_id));
 
@@ -1317,6 +1325,8 @@ static ssize_t quad8_signal_cable_fault_enable_write(
        if (ret)
                return ret;
 
+       mutex_lock(&priv->lock);
+
        if (enable)
                priv->cable_fault_enable |= BIT(channel_id);
        else
@@ -1327,6 +1337,8 @@ static ssize_t quad8_signal_cable_fault_enable_write(
 
        outb(cable_fault_enable, priv->base + QUAD8_DIFF_ENCODER_CABLE_STATUS);
 
+       mutex_unlock(&priv->lock);
+
        return len;
 }
 
@@ -1353,6 +1365,8 @@ static ssize_t quad8_signal_fck_prescaler_write(struct counter_device *counter,
        if (ret)
                return ret;
 
+       mutex_lock(&priv->lock);
+
        priv->fck_prescaler[channel_id] = prescaler;
 
        /* Reset Byte Pointer */
@@ -1363,6 +1377,8 @@ static ssize_t quad8_signal_fck_prescaler_write(struct counter_device *counter,
        outb(QUAD8_CTR_RLD | QUAD8_RLD_RESET_BP | QUAD8_RLD_PRESET_PSC,
             base_offset + 1);
 
+       mutex_unlock(&priv->lock);
+
        return len;
 }
 
index e771e8b..7e0f788 100644 (file)
@@ -2464,7 +2464,7 @@ static struct cpufreq_driver intel_cpufreq = {
        .name           = "intel_cpufreq",
 };
 
-static struct cpufreq_driver *default_driver = &intel_pstate;
+static struct cpufreq_driver *default_driver;
 
 static void intel_pstate_driver_cleanup(void)
 {
@@ -2758,6 +2758,7 @@ static int __init intel_pstate_init(void)
                        hwp_active++;
                        hwp_mode_bdw = id->driver_data;
                        intel_pstate.attr = hwp_cpufreq_attrs;
+                       default_driver = &intel_pstate;
                        goto hwp_cpu_matched;
                }
        } else {
@@ -2775,7 +2776,8 @@ static int __init intel_pstate_init(void)
                return -ENODEV;
        }
        /* Without HWP start in the passive mode. */
-       default_driver = &intel_cpufreq;
+       if (!default_driver)
+               default_driver = &intel_cpufreq;
 
 hwp_cpu_matched:
        /*
@@ -2820,6 +2822,8 @@ static int __init intel_pstate_setup(char *str)
 
        if (!strcmp(str, "disable")) {
                no_load = 1;
+       } else if (!strcmp(str, "active")) {
+               default_driver = &intel_pstate;
        } else if (!strcmp(str, "passive")) {
                default_driver = &intel_cpufreq;
                no_hwp = 1;
index 4126296..1ca609f 100644 (file)
@@ -45,10 +45,10 @@ static char *dmabuffs_dname(struct dentry *dentry, char *buffer, int buflen)
        size_t ret = 0;
 
        dmabuf = dentry->d_fsdata;
-       dma_resv_lock(dmabuf->resv, NULL);
+       spin_lock(&dmabuf->name_lock);
        if (dmabuf->name)
                ret = strlcpy(name, dmabuf->name, DMA_BUF_NAME_LEN);
-       dma_resv_unlock(dmabuf->resv);
+       spin_unlock(&dmabuf->name_lock);
 
        return dynamic_dname(dentry, buffer, buflen, "/%s:%s",
                             dentry->d_name.name, ret > 0 ? name : "");
@@ -338,8 +338,10 @@ static long dma_buf_set_name(struct dma_buf *dmabuf, const char __user *buf)
                kfree(name);
                goto out_unlock;
        }
+       spin_lock(&dmabuf->name_lock);
        kfree(dmabuf->name);
        dmabuf->name = name;
+       spin_unlock(&dmabuf->name_lock);
 
 out_unlock:
        dma_resv_unlock(dmabuf->resv);
@@ -402,10 +404,10 @@ static void dma_buf_show_fdinfo(struct seq_file *m, struct file *file)
        /* Don't count the temporary reference taken inside procfs seq_show */
        seq_printf(m, "count:\t%ld\n", file_count(dmabuf->file) - 1);
        seq_printf(m, "exp_name:\t%s\n", dmabuf->exp_name);
-       dma_resv_lock(dmabuf->resv, NULL);
+       spin_lock(&dmabuf->name_lock);
        if (dmabuf->name)
                seq_printf(m, "name:\t%s\n", dmabuf->name);
-       dma_resv_unlock(dmabuf->resv);
+       spin_unlock(&dmabuf->name_lock);
 }
 
 static const struct file_operations dma_buf_fops = {
@@ -542,6 +544,7 @@ struct dma_buf *dma_buf_export(const struct dma_buf_export_info *exp_info)
        dmabuf->size = exp_info->size;
        dmabuf->exp_name = exp_info->exp_name;
        dmabuf->owner = exp_info->owner;
+       spin_lock_init(&dmabuf->name_lock);
        init_waitqueue_head(&dmabuf->poll);
        dmabuf->cb_excl.poll = dmabuf->cb_shared.poll = &dmabuf->poll;
        dmabuf->cb_excl.active = dmabuf->cb_shared.active = 0;
index b175229..604f803 100644 (file)
@@ -1176,6 +1176,8 @@ static int dmatest_run_set(const char *val, const struct kernel_param *kp)
        } else if (dmatest_run) {
                if (!is_threaded_test_pending(info)) {
                        pr_info("No channels configured, continue with any\n");
+                       if (!is_threaded_test_run(info))
+                               stop_threaded_test(info);
                        add_threaded_test(info);
                }
                start_threaded_tests(info);
index 21cb2a5..a1b56f5 100644 (file)
@@ -118,16 +118,11 @@ static void dwc_initialize(struct dw_dma_chan *dwc)
 {
        struct dw_dma *dw = to_dw_dma(dwc->chan.device);
 
-       if (test_bit(DW_DMA_IS_INITIALIZED, &dwc->flags))
-               return;
-
        dw->initialize_chan(dwc);
 
        /* Enable interrupts */
        channel_set_bit(dw, MASK.XFER, dwc->mask);
        channel_set_bit(dw, MASK.ERROR, dwc->mask);
-
-       set_bit(DW_DMA_IS_INITIALIZED, &dwc->flags);
 }
 
 /*----------------------------------------------------------------------*/
@@ -954,8 +949,6 @@ static void dwc_issue_pending(struct dma_chan *chan)
 
 void do_dw_dma_off(struct dw_dma *dw)
 {
-       unsigned int i;
-
        dma_writel(dw, CFG, 0);
 
        channel_clear_bit(dw, MASK.XFER, dw->all_chan_mask);
@@ -966,9 +959,6 @@ void do_dw_dma_off(struct dw_dma *dw)
 
        while (dma_readl(dw, CFG) & DW_CFG_DMA_EN)
                cpu_relax();
-
-       for (i = 0; i < dw->dma.chancnt; i++)
-               clear_bit(DW_DMA_IS_INITIALIZED, &dw->chan[i].flags);
 }
 
 void do_dw_dma_on(struct dw_dma *dw)
@@ -1032,8 +1022,6 @@ static void dwc_free_chan_resources(struct dma_chan *chan)
        /* Clear custom channel configuration */
        memset(&dwc->dws, 0, sizeof(struct dw_dma_slave));
 
-       clear_bit(DW_DMA_IS_INITIALIZED, &dwc->flags);
-
        /* Disable interrupts */
        channel_clear_bit(dw, MASK.XFER, dwc->mask);
        channel_clear_bit(dw, MASK.BLOCK, dwc->mask);
index 5697c36..930ae26 100644 (file)
@@ -352,26 +352,28 @@ static void fsl_edma_set_tcd_regs(struct fsl_edma_chan *fsl_chan,
        /*
         * TCD parameters are stored in struct fsl_edma_hw_tcd in little
         * endian format. However, we need to load the TCD registers in
-        * big- or little-endian obeying the eDMA engine model endian.
+        * big- or little-endian obeying the eDMA engine model endian,
+        * and this is performed from specific edma_write functions
         */
        edma_writew(edma, 0,  &regs->tcd[ch].csr);
-       edma_writel(edma, le32_to_cpu(tcd->saddr), &regs->tcd[ch].saddr);
-       edma_writel(edma, le32_to_cpu(tcd->daddr), &regs->tcd[ch].daddr);
 
-       edma_writew(edma, le16_to_cpu(tcd->attr), &regs->tcd[ch].attr);
-       edma_writew(edma, le16_to_cpu(tcd->soff), &regs->tcd[ch].soff);
+       edma_writel(edma, (s32)tcd->saddr, &regs->tcd[ch].saddr);
+       edma_writel(edma, (s32)tcd->daddr, &regs->tcd[ch].daddr);
 
-       edma_writel(edma, le32_to_cpu(tcd->nbytes), &regs->tcd[ch].nbytes);
-       edma_writel(edma, le32_to_cpu(tcd->slast), &regs->tcd[ch].slast);
+       edma_writew(edma, (s16)tcd->attr, &regs->tcd[ch].attr);
+       edma_writew(edma, tcd->soff, &regs->tcd[ch].soff);
 
-       edma_writew(edma, le16_to_cpu(tcd->citer), &regs->tcd[ch].citer);
-       edma_writew(edma, le16_to_cpu(tcd->biter), &regs->tcd[ch].biter);
-       edma_writew(edma, le16_to_cpu(tcd->doff), &regs->tcd[ch].doff);
+       edma_writel(edma, (s32)tcd->nbytes, &regs->tcd[ch].nbytes);
+       edma_writel(edma, (s32)tcd->slast, &regs->tcd[ch].slast);
 
-       edma_writel(edma, le32_to_cpu(tcd->dlast_sga),
+       edma_writew(edma, (s16)tcd->citer, &regs->tcd[ch].citer);
+       edma_writew(edma, (s16)tcd->biter, &regs->tcd[ch].biter);
+       edma_writew(edma, (s16)tcd->doff, &regs->tcd[ch].doff);
+
+       edma_writel(edma, (s32)tcd->dlast_sga,
                        &regs->tcd[ch].dlast_sga);
 
-       edma_writew(edma, le16_to_cpu(tcd->csr), &regs->tcd[ch].csr);
+       edma_writew(edma, (s16)tcd->csr, &regs->tcd[ch].csr);
 }
 
 static inline
@@ -589,6 +591,8 @@ void fsl_edma_xfer_desc(struct fsl_edma_chan *fsl_chan)
 {
        struct virt_dma_desc *vdesc;
 
+       lockdep_assert_held(&fsl_chan->vchan.lock);
+
        vdesc = vchan_next_desc(&fsl_chan->vchan);
        if (!vdesc)
                return;
index 67e4225..ec11697 100644 (file)
@@ -33,7 +33,7 @@
 #define EDMA_TCD_ATTR_DSIZE_16BIT      BIT(0)
 #define EDMA_TCD_ATTR_DSIZE_32BIT      BIT(1)
 #define EDMA_TCD_ATTR_DSIZE_64BIT      (BIT(0) | BIT(1))
-#define EDMA_TCD_ATTR_DSIZE_32BYTE     (BIT(3) | BIT(0))
+#define EDMA_TCD_ATTR_DSIZE_32BYTE     (BIT(2) | BIT(0))
 #define EDMA_TCD_ATTR_SSIZE_8BIT       0
 #define EDMA_TCD_ATTR_SSIZE_16BIT      (EDMA_TCD_ATTR_DSIZE_16BIT << 8)
 #define EDMA_TCD_ATTR_SSIZE_32BIT      (EDMA_TCD_ATTR_DSIZE_32BIT << 8)
index eff7ebd..90bb72a 100644 (file)
@@ -45,6 +45,13 @@ static irqreturn_t fsl_edma_tx_handler(int irq, void *dev_id)
                        fsl_chan = &fsl_edma->chans[ch];
 
                        spin_lock(&fsl_chan->vchan.lock);
+
+                       if (!fsl_chan->edesc) {
+                               /* terminate_all called before */
+                               spin_unlock(&fsl_chan->vchan.lock);
+                               continue;
+                       }
+
                        if (!fsl_chan->edesc->iscyclic) {
                                list_del(&fsl_chan->edesc->vdesc.node);
                                vchan_cookie_complete(&fsl_chan->edesc->vdesc);
index ff49847..cb376cf 100644 (file)
@@ -74,6 +74,7 @@ static int idxd_cdev_open(struct inode *inode, struct file *filp)
        struct idxd_device *idxd;
        struct idxd_wq *wq;
        struct device *dev;
+       int rc = 0;
 
        wq = inode_wq(inode);
        idxd = wq->idxd;
@@ -81,17 +82,27 @@ static int idxd_cdev_open(struct inode *inode, struct file *filp)
 
        dev_dbg(dev, "%s called: %d\n", __func__, idxd_wq_refcount(wq));
 
-       if (idxd_wq_refcount(wq) > 0 && wq_dedicated(wq))
-               return -EBUSY;
-
        ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
        if (!ctx)
                return -ENOMEM;
 
+       mutex_lock(&wq->wq_lock);
+
+       if (idxd_wq_refcount(wq) > 0 && wq_dedicated(wq)) {
+               rc = -EBUSY;
+               goto failed;
+       }
+
        ctx->wq = wq;
        filp->private_data = ctx;
        idxd_wq_get(wq);
+       mutex_unlock(&wq->wq_lock);
        return 0;
+
+ failed:
+       mutex_unlock(&wq->wq_lock);
+       kfree(ctx);
+       return rc;
 }
 
 static int idxd_cdev_release(struct inode *node, struct file *filep)
@@ -105,7 +116,9 @@ static int idxd_cdev_release(struct inode *node, struct file *filep)
        filep->private_data = NULL;
 
        kfree(ctx);
+       mutex_lock(&wq->wq_lock);
        idxd_wq_put(wq);
+       mutex_unlock(&wq->wq_lock);
        return 0;
 }
 
index 8d79a87..8d2718c 100644 (file)
@@ -320,6 +320,31 @@ void idxd_wq_unmap_portal(struct idxd_wq *wq)
        devm_iounmap(dev, wq->dportal);
 }
 
+void idxd_wq_disable_cleanup(struct idxd_wq *wq)
+{
+       struct idxd_device *idxd = wq->idxd;
+       struct device *dev = &idxd->pdev->dev;
+       int i, wq_offset;
+
+       lockdep_assert_held(&idxd->dev_lock);
+       memset(&wq->wqcfg, 0, sizeof(wq->wqcfg));
+       wq->type = IDXD_WQT_NONE;
+       wq->size = 0;
+       wq->group = NULL;
+       wq->threshold = 0;
+       wq->priority = 0;
+       clear_bit(WQ_FLAG_DEDICATED, &wq->flags);
+       memset(wq->name, 0, WQ_NAME_SIZE);
+
+       for (i = 0; i < 8; i++) {
+               wq_offset = idxd->wqcfg_offset + wq->id * 32 + i * sizeof(u32);
+               iowrite32(0, idxd->reg_base + wq_offset);
+               dev_dbg(dev, "WQ[%d][%d][%#x]: %#x\n",
+                       wq->id, i, wq_offset,
+                       ioread32(idxd->reg_base + wq_offset));
+       }
+}
+
 /* Device control bits */
 static inline bool idxd_is_enabled(struct idxd_device *idxd)
 {
index b8f8a36..908c8d0 100644 (file)
@@ -290,6 +290,7 @@ int idxd_wq_enable(struct idxd_wq *wq);
 int idxd_wq_disable(struct idxd_wq *wq);
 int idxd_wq_map_portal(struct idxd_wq *wq);
 void idxd_wq_unmap_portal(struct idxd_wq *wq);
+void idxd_wq_disable_cleanup(struct idxd_wq *wq);
 
 /* submission */
 int idxd_submit_desc(struct idxd_wq *wq, struct idxd_desc *desc);
index 6510791..8a35f58 100644 (file)
@@ -141,7 +141,7 @@ irqreturn_t idxd_misc_thread(int vec, void *data)
 
        iowrite32(cause, idxd->reg_base + IDXD_INTCAUSE_OFFSET);
        if (!err)
-               return IRQ_HANDLED;
+               goto out;
 
        gensts.bits = ioread32(idxd->reg_base + IDXD_GENSTATS_OFFSET);
        if (gensts.state == IDXD_DEVICE_STATE_HALT) {
@@ -162,6 +162,7 @@ irqreturn_t idxd_misc_thread(int vec, void *data)
                spin_unlock_bh(&idxd->dev_lock);
        }
 
+ out:
        idxd_unmask_msix_vector(idxd, irq_entry->id);
        return IRQ_HANDLED;
 }
index 052dae5..2e2c508 100644 (file)
@@ -315,6 +315,11 @@ static int idxd_config_bus_remove(struct device *dev)
                idxd_unregister_dma_device(idxd);
                spin_lock_irqsave(&idxd->dev_lock, flags);
                rc = idxd_device_disable(idxd);
+               for (i = 0; i < idxd->max_wqs; i++) {
+                       struct idxd_wq *wq = &idxd->wqs[i];
+
+                       idxd_wq_disable_cleanup(wq);
+               }
                spin_unlock_irqrestore(&idxd->dev_lock, flags);
                module_put(THIS_MODULE);
                if (rc < 0)
index 9177403..270992c 100644 (file)
@@ -1331,8 +1331,7 @@ static void sdma_free_chan_resources(struct dma_chan *chan)
 
        sdma_channel_synchronize(chan);
 
-       if (sdmac->event_id0 >= 0)
-               sdma_event_disable(sdmac, sdmac->event_id0);
+       sdma_event_disable(sdmac, sdmac->event_id0);
        if (sdmac->event_id1)
                sdma_event_disable(sdmac, sdmac->event_id1);
 
@@ -1632,11 +1631,9 @@ static int sdma_config(struct dma_chan *chan,
        memcpy(&sdmac->slave_config, dmaengine_cfg, sizeof(*dmaengine_cfg));
 
        /* Set ENBLn earlier to make sure dma request triggered after that */
-       if (sdmac->event_id0 >= 0) {
-               if (sdmac->event_id0 >= sdmac->sdma->drvdata->num_events)
-                       return -EINVAL;
-               sdma_event_enable(sdmac, sdmac->event_id0);
-       }
+       if (sdmac->event_id0 >= sdmac->sdma->drvdata->num_events)
+               return -EINVAL;
+       sdma_event_enable(sdmac, sdmac->event_id0);
 
        if (sdmac->event_id1) {
                if (sdmac->event_id1 >= sdmac->sdma->drvdata->num_events)
index 8ad0ad8..fd782ae 100644 (file)
 
 #include "../dmaengine.h"
 
+int completion_timeout = 200;
+module_param(completion_timeout, int, 0644);
+MODULE_PARM_DESC(completion_timeout,
+               "set ioat completion timeout [msec] (default 200 [msec])");
+int idle_timeout = 2000;
+module_param(idle_timeout, int, 0644);
+MODULE_PARM_DESC(idle_timeout,
+               "set ioat idel timeout [msec] (default 2000 [msec])");
+
+#define IDLE_TIMEOUT msecs_to_jiffies(idle_timeout)
+#define COMPLETION_TIMEOUT msecs_to_jiffies(completion_timeout)
+
 static char *chanerr_str[] = {
        "DMA Transfer Source Address Error",
        "DMA Transfer Destination Address Error",
index e6b622e..f7f31fd 100644 (file)
@@ -104,8 +104,6 @@ struct ioatdma_chan {
        #define IOAT_RUN 5
        #define IOAT_CHAN_ACTIVE 6
        struct timer_list timer;
-       #define COMPLETION_TIMEOUT msecs_to_jiffies(100)
-       #define IDLE_TIMEOUT msecs_to_jiffies(2000)
        #define RESET_DELAY msecs_to_jiffies(100)
        struct ioatdma_device *ioat_dma;
        dma_addr_t completion_dma;
index e15bd15..e12b754 100644 (file)
@@ -35,6 +35,13 @@ static irqreturn_t mcf_edma_tx_handler(int irq, void *dev_id)
                        mcf_chan = &mcf_edma->chans[ch];
 
                        spin_lock(&mcf_chan->vchan.lock);
+
+                       if (!mcf_chan->edesc) {
+                               /* terminate_all called before */
+                               spin_unlock(&mcf_chan->vchan.lock);
+                               continue;
+                       }
+
                        if (!mcf_chan->edesc->iscyclic) {
                                list_del(&mcf_chan->edesc->vdesc.node);
                                vchan_cookie_complete(&mcf_chan->edesc->vdesc);
index b218a01..8f7ceb6 100644 (file)
@@ -586,6 +586,8 @@ static void usb_dmac_isr_transfer_end(struct usb_dmac_chan *chan)
                desc->residue = usb_dmac_get_current_residue(chan, desc,
                                                        desc->sg_index - 1);
                desc->done_cookie = desc->vd.tx.cookie;
+               desc->vd.tx_result.result = DMA_TRANS_NOERROR;
+               desc->vd.tx_result.residue = desc->residue;
                vchan_cookie_complete(&desc->vd);
 
                /* Restart the next transfer if this driver has a next desc */
index db58d7e..c5fa2ef 100644 (file)
@@ -658,6 +658,7 @@ static int tegra_adma_alloc_chan_resources(struct dma_chan *dc)
 
        ret = pm_runtime_get_sync(tdc2dev(tdc));
        if (ret < 0) {
+               pm_runtime_put_noidle(tdc2dev(tdc));
                free_irq(tdc->irq, tdc);
                return ret;
        }
@@ -869,8 +870,10 @@ static int tegra_adma_probe(struct platform_device *pdev)
        pm_runtime_enable(&pdev->dev);
 
        ret = pm_runtime_get_sync(&pdev->dev);
-       if (ret < 0)
+       if (ret < 0) {
+               pm_runtime_put_noidle(&pdev->dev);
                goto rpm_disable;
+       }
 
        ret = tegra_adma_init(tdma);
        if (ret)
index 0b8f3dd..77e8e67 100644 (file)
@@ -42,6 +42,7 @@ struct udma_dev *of_xudma_dev_get(struct device_node *np, const char *property)
        ud = platform_get_drvdata(pdev);
        if (!ud) {
                pr_debug("UDMA has not been probed\n");
+               put_device(&pdev->dev);
                return ERR_PTR(-EPROBE_DEFER);
        }
 
index c91e2dc..6c879a7 100644 (file)
@@ -1753,7 +1753,8 @@ static int udma_alloc_chan_resources(struct dma_chan *chan)
                        dev_err(ud->ddev.dev,
                                "Descriptor pool allocation failed\n");
                        uc->use_dma_pool = false;
-                       return -ENOMEM;
+                       ret = -ENOMEM;
+                       goto err_cleanup;
                }
        }
 
@@ -1773,16 +1774,18 @@ static int udma_alloc_chan_resources(struct dma_chan *chan)
 
                ret = udma_get_chan_pair(uc);
                if (ret)
-                       return ret;
+                       goto err_cleanup;
 
                ret = udma_alloc_tx_resources(uc);
-               if (ret)
-                       return ret;
+               if (ret) {
+                       udma_put_rchan(uc);
+                       goto err_cleanup;
+               }
 
                ret = udma_alloc_rx_resources(uc);
                if (ret) {
                        udma_free_tx_resources(uc);
-                       return ret;
+                       goto err_cleanup;
                }
 
                uc->config.src_thread = ud->psil_base + uc->tchan->id;
@@ -1800,10 +1803,8 @@ static int udma_alloc_chan_resources(struct dma_chan *chan)
                        uc->id);
 
                ret = udma_alloc_tx_resources(uc);
-               if (ret) {
-                       uc->config.remote_thread_id = -1;
-                       return ret;
-               }
+               if (ret)
+                       goto err_cleanup;
 
                uc->config.src_thread = ud->psil_base + uc->tchan->id;
                uc->config.dst_thread = uc->config.remote_thread_id;
@@ -1820,10 +1821,8 @@ static int udma_alloc_chan_resources(struct dma_chan *chan)
                        uc->id);
 
                ret = udma_alloc_rx_resources(uc);
-               if (ret) {
-                       uc->config.remote_thread_id = -1;
-                       return ret;
-               }
+               if (ret)
+                       goto err_cleanup;
 
                uc->config.src_thread = uc->config.remote_thread_id;
                uc->config.dst_thread = (ud->psil_base + uc->rchan->id) |
@@ -1838,7 +1837,9 @@ static int udma_alloc_chan_resources(struct dma_chan *chan)
                /* Can not happen */
                dev_err(uc->ud->dev, "%s: chan%d invalid direction (%u)\n",
                        __func__, uc->id, uc->config.dir);
-               return -EINVAL;
+               ret = -EINVAL;
+               goto err_cleanup;
+
        }
 
        /* check if the channel configuration was successful */
@@ -1847,7 +1848,7 @@ static int udma_alloc_chan_resources(struct dma_chan *chan)
 
        if (udma_is_chan_running(uc)) {
                dev_warn(ud->dev, "chan%d: is running!\n", uc->id);
-               udma_stop(uc);
+               udma_reset_chan(uc, false);
                if (udma_is_chan_running(uc)) {
                        dev_err(ud->dev, "chan%d: won't stop!\n", uc->id);
                        ret = -EBUSY;
@@ -1906,8 +1907,6 @@ static int udma_alloc_chan_resources(struct dma_chan *chan)
 
        udma_reset_rings(uc);
 
-       INIT_DELAYED_WORK_ONSTACK(&uc->tx_drain.work,
-                                 udma_check_tx_completion);
        return 0;
 
 err_irq_free:
@@ -1919,7 +1918,7 @@ err_psi_free:
 err_res_free:
        udma_free_tx_resources(uc);
        udma_free_rx_resources(uc);
-
+err_cleanup:
        udma_reset_uchan(uc);
 
        if (uc->use_dma_pool) {
@@ -3019,7 +3018,6 @@ static void udma_free_chan_resources(struct dma_chan *chan)
        }
 
        cancel_delayed_work_sync(&uc->tx_drain.work);
-       destroy_delayed_work_on_stack(&uc->tx_drain.work);
 
        if (uc->irq_num_ring > 0) {
                free_irq(uc->irq_num_ring, uc);
@@ -3593,7 +3591,7 @@ static int udma_probe(struct platform_device *pdev)
                return ret;
        }
 
-       ret = of_property_read_u32(navss_node, "ti,udma-atype", &ud->atype);
+       ret = of_property_read_u32(dev->of_node, "ti,udma-atype", &ud->atype);
        if (!ret && ud->atype > 2) {
                dev_err(dev, "Invalid atype: %u\n", ud->atype);
                return -EINVAL;
@@ -3711,6 +3709,7 @@ static int udma_probe(struct platform_device *pdev)
                tasklet_init(&uc->vc.task, udma_vchan_complete,
                             (unsigned long)&uc->vc);
                init_completion(&uc->teardown_completed);
+               INIT_DELAYED_WORK(&uc->tx_drain.work, udma_check_tx_completion);
        }
 
        ret = dma_async_device_register(&ud->ddev);
index 7f6a57d..e5bfac7 100644 (file)
@@ -35,13 +35,16 @@ efi_status_t check_platform_features(void)
 }
 
 /*
- * Relocatable kernels can fix up the misalignment with respect to
- * MIN_KIMG_ALIGN, so they only require a minimum alignment of EFI_KIMG_ALIGN
- * (which accounts for the alignment of statically allocated objects such as
- * the swapper stack.)
+ * Although relocatable kernels can fix up the misalignment with respect to
+ * MIN_KIMG_ALIGN, the resulting virtual text addresses are subtly out of
+ * sync with those recorded in the vmlinux when kaslr is disabled but the
+ * image required relocation anyway. Therefore retain 2M alignment unless
+ * KASLR is in use.
  */
-static const u64 min_kimg_align = IS_ENABLED(CONFIG_RELOCATABLE) ? EFI_KIMG_ALIGN
-                                                                : MIN_KIMG_ALIGN;
+static u64 min_kimg_align(void)
+{
+       return efi_nokaslr ? MIN_KIMG_ALIGN : EFI_KIMG_ALIGN;
+}
 
 efi_status_t handle_kernel_image(unsigned long *image_addr,
                                 unsigned long *image_size,
@@ -74,21 +77,21 @@ efi_status_t handle_kernel_image(unsigned long *image_addr,
 
        kernel_size = _edata - _text;
        kernel_memsize = kernel_size + (_end - _edata);
-       *reserve_size = kernel_memsize + TEXT_OFFSET % min_kimg_align;
+       *reserve_size = kernel_memsize + TEXT_OFFSET % min_kimg_align();
 
        if (IS_ENABLED(CONFIG_RANDOMIZE_BASE) && phys_seed != 0) {
                /*
                 * If KASLR is enabled, and we have some randomness available,
                 * locate the kernel at a randomized offset in physical memory.
                 */
-               status = efi_random_alloc(*reserve_size, min_kimg_align,
+               status = efi_random_alloc(*reserve_size, min_kimg_align(),
                                          reserve_addr, phys_seed);
        } else {
                status = EFI_OUT_OF_RESOURCES;
        }
 
        if (status != EFI_SUCCESS) {
-               if (IS_ALIGNED((u64)_text - TEXT_OFFSET, min_kimg_align)) {
+               if (IS_ALIGNED((u64)_text - TEXT_OFFSET, min_kimg_align())) {
                        /*
                         * Just execute from wherever we were loaded by the
                         * UEFI PE/COFF loader if the alignment is suitable.
@@ -99,7 +102,7 @@ efi_status_t handle_kernel_image(unsigned long *image_addr,
                }
 
                status = efi_allocate_pages_aligned(*reserve_size, reserve_addr,
-                                                   ULONG_MAX, min_kimg_align);
+                                                   ULONG_MAX, min_kimg_align());
 
                if (status != EFI_SUCCESS) {
                        efi_err("Failed to relocate kernel\n");
@@ -108,7 +111,7 @@ efi_status_t handle_kernel_image(unsigned long *image_addr,
                }
        }
 
-       *image_addr = *reserve_addr + TEXT_OFFSET % min_kimg_align;
+       *image_addr = *reserve_addr + TEXT_OFFSET % min_kimg_align();
        memcpy((void *)*image_addr, _text, kernel_size);
 
        return EFI_SUCCESS;
index d40fd68..6bca70b 100644 (file)
@@ -19,7 +19,7 @@
 #include "efistub.h"
 
 bool efi_nochunk;
-bool efi_nokaslr;
+bool efi_nokaslr = !IS_ENABLED(CONFIG_RANDOMIZE_BASE);
 bool efi_noinitrd;
 int efi_loglevel = CONSOLE_LOGLEVEL_DEFAULT;
 bool efi_novamap;
index d33cb34..a414da2 100644 (file)
@@ -1295,27 +1295,37 @@ static void amdgpu_ib_preempt_job_recovery(struct drm_gpu_scheduler *sched)
 static void amdgpu_ib_preempt_mark_partial_job(struct amdgpu_ring *ring)
 {
        struct amdgpu_job *job;
-       struct drm_sched_job *s_job;
+       struct drm_sched_job *s_job, *tmp;
        uint32_t preempt_seq;
        struct dma_fence *fence, **ptr;
        struct amdgpu_fence_driver *drv = &ring->fence_drv;
        struct drm_gpu_scheduler *sched = &ring->sched;
+       bool preempted = true;
 
        if (ring->funcs->type != AMDGPU_RING_TYPE_GFX)
                return;
 
        preempt_seq = le32_to_cpu(*(drv->cpu_addr + 2));
-       if (preempt_seq <= atomic_read(&drv->last_seq))
-               return;
+       if (preempt_seq <= atomic_read(&drv->last_seq)) {
+               preempted = false;
+               goto no_preempt;
+       }
 
        preempt_seq &= drv->num_fences_mask;
        ptr = &drv->fences[preempt_seq];
        fence = rcu_dereference_protected(*ptr, 1);
 
+no_preempt:
        spin_lock(&sched->job_list_lock);
-       list_for_each_entry(s_job, &sched->ring_mirror_list, node) {
+       list_for_each_entry_safe(s_job, tmp, &sched->ring_mirror_list, node) {
+               if (dma_fence_is_signaled(&s_job->s_fence->finished)) {
+                       /* remove job from ring_mirror_list */
+                       list_del_init(&s_job->node);
+                       sched->ops->free_job(s_job);
+                       continue;
+               }
                job = to_amdgpu_job(s_job);
-               if (job->fence == fence)
+               if (preempted && job->fence == fence)
                        /* mark the job as preempted */
                        job->preemption_status |= AMDGPU_IB_PREEMPTED;
        }
index bd5dd4f..fac77a8 100644 (file)
@@ -7513,12 +7513,17 @@ static int gfx_v10_0_ring_preempt_ib(struct amdgpu_ring *ring)
        struct amdgpu_device *adev = ring->adev;
        struct amdgpu_kiq *kiq = &adev->gfx.kiq;
        struct amdgpu_ring *kiq_ring = &kiq->ring;
+       unsigned long flags;
 
        if (!kiq->pmf || !kiq->pmf->kiq_unmap_queues)
                return -EINVAL;
 
-       if (amdgpu_ring_alloc(kiq_ring, kiq->pmf->unmap_queues_size))
+       spin_lock_irqsave(&kiq->ring_lock, flags);
+
+       if (amdgpu_ring_alloc(kiq_ring, kiq->pmf->unmap_queues_size)) {
+               spin_unlock_irqrestore(&kiq->ring_lock, flags);
                return -ENOMEM;
+       }
 
        /* assert preemption condition */
        amdgpu_ring_set_preempt_cond_exec(ring, false);
@@ -7529,6 +7534,8 @@ static int gfx_v10_0_ring_preempt_ib(struct amdgpu_ring *ring)
                                   ++ring->trail_seq);
        amdgpu_ring_commit(kiq_ring);
 
+       spin_unlock_irqrestore(&kiq->ring_lock, flags);
+
        /* poll the trailing fence */
        for (i = 0; i < adev->usec_timeout; i++) {
                if (ring->trail_seq ==
index 5d71c23..8fb66e5 100644 (file)
@@ -314,30 +314,20 @@ static uint64_t sdma_v5_0_ring_get_rptr(struct amdgpu_ring *ring)
 static uint64_t sdma_v5_0_ring_get_wptr(struct amdgpu_ring *ring)
 {
        struct amdgpu_device *adev = ring->adev;
-       u64 *wptr = NULL;
-       uint64_t local_wptr = 0;
+       u64 wptr;
 
        if (ring->use_doorbell) {
                /* XXX check if swapping is necessary on BE */
-               wptr = ((u64 *)&adev->wb.wb[ring->wptr_offs]);
-               DRM_DEBUG("wptr/doorbell before shift == 0x%016llx\n", *wptr);
-               *wptr = (*wptr) >> 2;
-               DRM_DEBUG("wptr/doorbell after shift == 0x%016llx\n", *wptr);
+               wptr = READ_ONCE(*((u64 *)&adev->wb.wb[ring->wptr_offs]));
+               DRM_DEBUG("wptr/doorbell before shift == 0x%016llx\n", wptr);
        } else {
-               u32 lowbit, highbit;
-
-               wptr = &local_wptr;
-               lowbit = RREG32(sdma_v5_0_get_reg_offset(adev, ring->me, mmSDMA0_GFX_RB_WPTR)) >> 2;
-               highbit = RREG32(sdma_v5_0_get_reg_offset(adev, ring->me, mmSDMA0_GFX_RB_WPTR_HI)) >> 2;
-
-               DRM_DEBUG("wptr [%i]high== 0x%08x low==0x%08x\n",
-                               ring->me, highbit, lowbit);
-               *wptr = highbit;
-               *wptr = (*wptr) << 32;
-               *wptr |= lowbit;
+               wptr = RREG32(sdma_v5_0_get_reg_offset(adev, ring->me, mmSDMA0_GFX_RB_WPTR_HI));
+               wptr = wptr << 32;
+               wptr |= RREG32(sdma_v5_0_get_reg_offset(adev, ring->me, mmSDMA0_GFX_RB_WPTR));
+               DRM_DEBUG("wptr before shift [%i] wptr == 0x%016llx\n", ring->me, wptr);
        }
 
-       return *wptr;
+       return wptr >> 2;
 }
 
 /**
index db5e0bb..86ffa0c 100644 (file)
@@ -974,6 +974,9 @@ static int amdgpu_dm_init(struct amdgpu_device *adev)
        /* Update the actual used number of crtc */
        adev->mode_info.num_crtc = adev->dm.display_indexes_num;
 
+       /* create fake encoders for MST */
+       dm_dp_create_fake_mst_encoders(adev);
+
        /* TODO: Add_display_info? */
 
        /* TODO use dynamic cursor width */
@@ -997,6 +1000,12 @@ error:
 
 static void amdgpu_dm_fini(struct amdgpu_device *adev)
 {
+       int i;
+
+       for (i = 0; i < adev->dm.display_indexes_num; i++) {
+               drm_encoder_cleanup(&adev->dm.mst_encoders[i].base);
+       }
+
        amdgpu_dm_audio_fini(adev);
 
        amdgpu_dm_destroy_drm_device(&adev->dm);
@@ -2010,6 +2019,7 @@ static void update_connector_ext_caps(struct amdgpu_dm_connector *aconnector)
        struct amdgpu_display_manager *dm;
        struct drm_connector *conn_base;
        struct amdgpu_device *adev;
+       struct dc_link *link = NULL;
        static const u8 pre_computed_values[] = {
                50, 51, 52, 53, 55, 56, 57, 58, 59, 61, 62, 63, 65, 66, 68, 69,
                71, 72, 74, 75, 77, 79, 81, 82, 84, 86, 88, 90, 92, 94, 96, 98};
@@ -2017,6 +2027,10 @@ static void update_connector_ext_caps(struct amdgpu_dm_connector *aconnector)
        if (!aconnector || !aconnector->dc_link)
                return;
 
+       link = aconnector->dc_link;
+       if (link->connector_signal != SIGNAL_TYPE_EDP)
+               return;
+
        conn_base = &aconnector->base;
        adev = conn_base->dev->dev_private;
        dm = &adev->dm;
index d61186f..648180c 100644 (file)
@@ -43,6 +43,9 @@
  */
 
 #define AMDGPU_DM_MAX_DISPLAY_INDEX 31
+
+#define AMDGPU_DM_MAX_CRTC 6
+
 /*
 #include "include/amdgpu_dal_power_if.h"
 #include "amdgpu_dm_irq.h"
@@ -328,6 +331,13 @@ struct amdgpu_display_manager {
         * available in FW
         */
        const struct gpu_info_soc_bounding_box_v1_0 *soc_bounding_box;
+
+       /**
+        * @mst_encoders:
+        *
+        * fake encoders used for DP MST.
+        */
+       struct amdgpu_encoder mst_encoders[AMDGPU_DM_MAX_CRTC];
 };
 
 struct amdgpu_dm_connector {
@@ -356,7 +366,6 @@ struct amdgpu_dm_connector {
        struct amdgpu_dm_dp_aux dm_dp_aux;
        struct drm_dp_mst_port *port;
        struct amdgpu_dm_connector *mst_port;
-       struct amdgpu_encoder *mst_encoder;
        struct drm_dp_aux *dsc_aux;
 
        /* TODO see if we can merge with ddc_bus or make a dm_connector */
index ae0a7ef..e5ecc5a 100644 (file)
@@ -95,7 +95,6 @@ dm_dp_mst_connector_destroy(struct drm_connector *connector)
 {
        struct amdgpu_dm_connector *aconnector =
                to_amdgpu_dm_connector(connector);
-       struct amdgpu_encoder *amdgpu_encoder = aconnector->mst_encoder;
 
        if (aconnector->dc_sink) {
                dc_link_remove_remote_sink(aconnector->dc_link,
@@ -105,8 +104,6 @@ dm_dp_mst_connector_destroy(struct drm_connector *connector)
 
        kfree(aconnector->edid);
 
-       drm_encoder_cleanup(&amdgpu_encoder->base);
-       kfree(amdgpu_encoder);
        drm_connector_cleanup(connector);
        drm_dp_mst_put_port_malloc(aconnector->port);
        kfree(aconnector);
@@ -243,7 +240,11 @@ static struct drm_encoder *
 dm_mst_atomic_best_encoder(struct drm_connector *connector,
                           struct drm_connector_state *connector_state)
 {
-       return &to_amdgpu_dm_connector(connector)->mst_encoder->base;
+       struct drm_device *dev = connector->dev;
+       struct amdgpu_device *adev = dev->dev_private;
+       struct amdgpu_crtc *acrtc = to_amdgpu_crtc(connector_state->crtc);
+
+       return &adev->dm.mst_encoders[acrtc->crtc_id].base;
 }
 
 static int
@@ -306,31 +307,27 @@ static const struct drm_encoder_funcs amdgpu_dm_encoder_funcs = {
        .destroy = amdgpu_dm_encoder_destroy,
 };
 
-static struct amdgpu_encoder *
-dm_dp_create_fake_mst_encoder(struct amdgpu_dm_connector *connector)
+void
+dm_dp_create_fake_mst_encoders(struct amdgpu_device *adev)
 {
-       struct drm_device *dev = connector->base.dev;
-       struct amdgpu_device *adev = dev->dev_private;
-       struct amdgpu_encoder *amdgpu_encoder;
-       struct drm_encoder *encoder;
-
-       amdgpu_encoder = kzalloc(sizeof(*amdgpu_encoder), GFP_KERNEL);
-       if (!amdgpu_encoder)
-               return NULL;
+       struct drm_device *dev = adev->ddev;
+       int i;
 
-       encoder = &amdgpu_encoder->base;
-       encoder->possible_crtcs = amdgpu_dm_get_encoder_crtc_mask(adev);
+       for (i = 0; i < adev->dm.display_indexes_num; i++) {
+               struct amdgpu_encoder *amdgpu_encoder = &adev->dm.mst_encoders[i];
+               struct drm_encoder *encoder = &amdgpu_encoder->base;
 
-       drm_encoder_init(
-               dev,
-               &amdgpu_encoder->base,
-               &amdgpu_dm_encoder_funcs,
-               DRM_MODE_ENCODER_DPMST,
-               NULL);
+               encoder->possible_crtcs = amdgpu_dm_get_encoder_crtc_mask(adev);
 
-       drm_encoder_helper_add(encoder, &amdgpu_dm_encoder_helper_funcs);
+               drm_encoder_init(
+                       dev,
+                       &amdgpu_encoder->base,
+                       &amdgpu_dm_encoder_funcs,
+                       DRM_MODE_ENCODER_DPMST,
+                       NULL);
 
-       return amdgpu_encoder;
+               drm_encoder_helper_add(encoder, &amdgpu_dm_encoder_helper_funcs);
+       }
 }
 
 static struct drm_connector *
@@ -343,6 +340,7 @@ dm_dp_add_mst_connector(struct drm_dp_mst_topology_mgr *mgr,
        struct amdgpu_device *adev = dev->dev_private;
        struct amdgpu_dm_connector *aconnector;
        struct drm_connector *connector;
+       int i;
 
        aconnector = kzalloc(sizeof(*aconnector), GFP_KERNEL);
        if (!aconnector)
@@ -369,9 +367,10 @@ dm_dp_add_mst_connector(struct drm_dp_mst_topology_mgr *mgr,
                master->dc_link,
                master->connector_id);
 
-       aconnector->mst_encoder = dm_dp_create_fake_mst_encoder(master);
-       drm_connector_attach_encoder(&aconnector->base,
-                                    &aconnector->mst_encoder->base);
+       for (i = 0; i < adev->dm.display_indexes_num; i++) {
+               drm_connector_attach_encoder(&aconnector->base,
+                                            &adev->dm.mst_encoders[i].base);
+       }
 
        connector->max_bpc_property = master->base.max_bpc_property;
        if (connector->max_bpc_property)
index d2c5657..b38bd68 100644 (file)
@@ -35,6 +35,9 @@ void amdgpu_dm_initialize_dp_connector(struct amdgpu_display_manager *dm,
                                       struct amdgpu_dm_connector *aconnector,
                                       int link_index);
 
+void
+dm_dp_create_fake_mst_encoders(struct amdgpu_device *adev);
+
 #if defined(CONFIG_DRM_AMD_DC_DCN)
 bool compute_mst_dsc_configs_for_state(struct drm_atomic_state *state,
                                       struct dc_state *dc_state);
index 4f0e720..470c827 100644 (file)
@@ -56,7 +56,7 @@ void update_stream_signal(struct dc_stream_state *stream, struct dc_sink *sink)
        }
 }
 
-static void dc_stream_construct(struct dc_stream_state *stream,
+static bool dc_stream_construct(struct dc_stream_state *stream,
        struct dc_sink *dc_sink_data)
 {
        uint32_t i = 0;
@@ -118,11 +118,17 @@ static void dc_stream_construct(struct dc_stream_state *stream,
        update_stream_signal(stream, dc_sink_data);
 
        stream->out_transfer_func = dc_create_transfer_func();
+       if (stream->out_transfer_func == NULL) {
+               dc_sink_release(dc_sink_data);
+               return false;
+       }
        stream->out_transfer_func->type = TF_TYPE_BYPASS;
        stream->out_transfer_func->ctx = stream->ctx;
 
        stream->stream_id = stream->ctx->dc_stream_id_count;
        stream->ctx->dc_stream_id_count++;
+
+       return true;
 }
 
 static void dc_stream_destruct(struct dc_stream_state *stream)
@@ -164,13 +170,20 @@ struct dc_stream_state *dc_create_stream_for_sink(
 
        stream = kzalloc(sizeof(struct dc_stream_state), GFP_KERNEL);
        if (stream == NULL)
-               return NULL;
+               goto alloc_fail;
 
-       dc_stream_construct(stream, sink);
+       if (dc_stream_construct(stream, sink) == false)
+               goto construct_fail;
 
        kref_init(&stream->refcount);
 
        return stream;
+
+construct_fail:
+       kfree(stream);
+
+alloc_fail:
+       return NULL;
 }
 
 struct dc_stream_state *dc_copy_stream(const struct dc_stream_state *stream)
index 6747604..fbb3f3a 100644 (file)
@@ -689,7 +689,7 @@ static int renoir_set_power_profile_mode(struct smu_context *smu, long *input, u
                return -EINVAL;
        }
 
-       ret = smu_send_smc_msg_with_param(smu, SMU_MSG_SetWorkloadMask,
+       ret = smu_send_smc_msg_with_param(smu, SMU_MSG_ActiveProcessNotify,
                                    1 << workload_type,
                                    NULL);
        if (ret) {
index 6b27242..bca3fcf 100644 (file)
@@ -173,8 +173,6 @@ static int aspeed_gfx_load(struct drm_device *drm)
 
        drm_mode_config_reset(drm);
 
-       drm_fbdev_generic_setup(drm, 32);
-
        return 0;
 }
 
@@ -225,6 +223,7 @@ static int aspeed_gfx_probe(struct platform_device *pdev)
        if (ret)
                goto err_unload;
 
+       drm_fbdev_generic_setup(&priv->drm, 32);
        return 0;
 
 err_unload:
index a65d9d8..412572f 100644 (file)
@@ -719,6 +719,25 @@ static bool intel_fbc_cfb_size_changed(struct drm_i915_private *dev_priv)
                fbc->compressed_fb.size * fbc->threshold;
 }
 
+static u16 intel_fbc_gen9_wa_cfb_stride(struct drm_i915_private *dev_priv)
+{
+       struct intel_fbc *fbc = &dev_priv->fbc;
+       struct intel_fbc_state_cache *cache = &fbc->state_cache;
+
+       if ((IS_GEN9_BC(dev_priv) || IS_BROXTON(dev_priv)) &&
+           cache->fb.modifier != I915_FORMAT_MOD_X_TILED)
+               return DIV_ROUND_UP(cache->plane.src_w, 32 * fbc->threshold) * 8;
+       else
+               return 0;
+}
+
+static bool intel_fbc_gen9_wa_cfb_stride_changed(struct drm_i915_private *dev_priv)
+{
+       struct intel_fbc *fbc = &dev_priv->fbc;
+
+       return fbc->params.gen9_wa_cfb_stride != intel_fbc_gen9_wa_cfb_stride(dev_priv);
+}
+
 static bool intel_fbc_can_enable(struct drm_i915_private *dev_priv)
 {
        struct intel_fbc *fbc = &dev_priv->fbc;
@@ -877,6 +896,7 @@ static void intel_fbc_get_reg_params(struct intel_crtc *crtc,
        params->crtc.i9xx_plane = to_intel_plane(crtc->base.primary)->i9xx_plane;
 
        params->fb.format = cache->fb.format;
+       params->fb.modifier = cache->fb.modifier;
        params->fb.stride = cache->fb.stride;
 
        params->cfb_size = intel_fbc_calculate_cfb_size(dev_priv, cache);
@@ -906,6 +926,9 @@ static bool intel_fbc_can_flip_nuke(const struct intel_crtc_state *crtc_state)
        if (params->fb.format != cache->fb.format)
                return false;
 
+       if (params->fb.modifier != cache->fb.modifier)
+               return false;
+
        if (params->fb.stride != cache->fb.stride)
                return false;
 
@@ -1185,7 +1208,8 @@ void intel_fbc_enable(struct intel_atomic_state *state,
 
        if (fbc->crtc) {
                if (fbc->crtc != crtc ||
-                   !intel_fbc_cfb_size_changed(dev_priv))
+                   (!intel_fbc_cfb_size_changed(dev_priv) &&
+                    !intel_fbc_gen9_wa_cfb_stride_changed(dev_priv)))
                        goto out;
 
                __intel_fbc_disable(dev_priv);
@@ -1207,12 +1231,7 @@ void intel_fbc_enable(struct intel_atomic_state *state,
                goto out;
        }
 
-       if ((IS_GEN9_BC(dev_priv) || IS_BROXTON(dev_priv)) &&
-           plane_state->hw.fb->modifier != I915_FORMAT_MOD_X_TILED)
-               cache->gen9_wa_cfb_stride =
-                       DIV_ROUND_UP(cache->plane.src_w, 32 * fbc->threshold) * 8;
-       else
-               cache->gen9_wa_cfb_stride = 0;
+       cache->gen9_wa_cfb_stride = intel_fbc_gen9_wa_cfb_stride(dev_priv);
 
        drm_dbg_kms(&dev_priv->drm, "Enabling FBC on pipe %c\n",
                    pipe_name(crtc->pipe));
index 010f372..95b6d94 100644 (file)
@@ -2867,19 +2867,13 @@ intel_hdmi_connector_register(struct drm_connector *connector)
        return ret;
 }
 
-static void intel_hdmi_destroy(struct drm_connector *connector)
+static void intel_hdmi_connector_unregister(struct drm_connector *connector)
 {
        struct cec_notifier *n = intel_attached_hdmi(to_intel_connector(connector))->cec_notifier;
 
        cec_notifier_conn_unregister(n);
 
-       intel_connector_destroy(connector);
-}
-
-static void intel_hdmi_connector_unregister(struct drm_connector *connector)
-{
        intel_hdmi_remove_i2c_symlink(connector);
-
        intel_connector_unregister(connector);
 }
 
@@ -2891,7 +2885,7 @@ static const struct drm_connector_funcs intel_hdmi_connector_funcs = {
        .atomic_set_property = intel_digital_connector_atomic_set_property,
        .late_register = intel_hdmi_connector_register,
        .early_unregister = intel_hdmi_connector_unregister,
-       .destroy = intel_hdmi_destroy,
+       .destroy = intel_connector_destroy,
        .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
        .atomic_duplicate_state = intel_digital_connector_duplicate_state,
 };
index 7c3d8ef..cb07e1d 100644 (file)
@@ -5396,13 +5396,8 @@ static void virtual_engine_initial_hint(struct virtual_engine *ve)
         * typically be the first we inspect for submission.
         */
        swp = prandom_u32_max(ve->num_siblings);
-       if (!swp)
-               return;
-
-       swap(ve->siblings[swp], ve->siblings[0]);
-       if (!intel_engine_has_relative_mmio(ve->siblings[0]))
-               virtual_update_register_offsets(ve->context.lrc_reg_state,
-                                               ve->siblings[0]);
+       if (swp)
+               swap(ve->siblings[swp], ve->siblings[0]);
 }
 
 static int virtual_context_alloc(struct intel_context *ce)
@@ -5415,15 +5410,9 @@ static int virtual_context_alloc(struct intel_context *ce)
 static int virtual_context_pin(struct intel_context *ce)
 {
        struct virtual_engine *ve = container_of(ce, typeof(*ve), context);
-       int err;
 
        /* Note: we must use a real engine class for setting up reg state */
-       err = __execlists_context_pin(ce, ve->siblings[0]);
-       if (err)
-               return err;
-
-       virtual_engine_initial_hint(ve);
-       return 0;
+       return __execlists_context_pin(ce, ve->siblings[0]);
 }
 
 static void virtual_context_enter(struct intel_context *ce)
@@ -5688,6 +5677,7 @@ intel_execlists_create_virtual(struct intel_engine_cs **siblings,
        intel_engine_init_active(&ve->base, ENGINE_VIRTUAL);
        intel_engine_init_breadcrumbs(&ve->base);
        intel_engine_init_execlists(&ve->base);
+       ve->base.breadcrumbs.irq_armed = true; /* fake HW, used for irq_work */
 
        ve->base.cops = &virtual_context_ops;
        ve->base.request_alloc = execlists_request_alloc;
@@ -5769,6 +5759,7 @@ intel_execlists_create_virtual(struct intel_engine_cs **siblings,
 
        ve->base.flags |= I915_ENGINE_IS_VIRTUAL;
 
+       virtual_engine_initial_hint(ve);
        return &ve->context;
 
 err_put:
index 5049c3d..c91981e 100644 (file)
@@ -44,9 +44,9 @@ static int cmp_u64(const void *A, const void *B)
 {
        const u64 *a = A, *b = B;
 
-       if (a < b)
+       if (*a < *b)
                return -1;
-       else if (a > b)
+       else if (*a > *b)
                return 1;
        else
                return 0;
@@ -56,9 +56,9 @@ static int cmp_u32(const void *A, const void *B)
 {
        const u32 *a = A, *b = B;
 
-       if (a < b)
+       if (*a < *b)
                return -1;
-       else if (a > b)
+       else if (*a > *b)
                return 1;
        else
                return 0;
index f79f118..ae99a91 100644 (file)
@@ -440,6 +440,7 @@ struct intel_fbc {
                struct {
                        const struct drm_format_info *format;
                        unsigned int stride;
+                       u64 modifier;
                } fb;
 
                int cfb_size;
index 25329b7..014f34c 100644 (file)
@@ -1592,6 +1592,7 @@ static u32 *save_restore_register(struct i915_perf_stream *stream, u32 *cs,
        u32 d;
 
        cmd = save ? MI_STORE_REGISTER_MEM : MI_LOAD_REGISTER_MEM;
+       cmd |= MI_SRM_LRM_GLOBAL_GTT;
        if (INTEL_GEN(stream->perf->i915) >= 8)
                cmd++;
 
index 9ffa9c7..16b3856 100644 (file)
@@ -1069,10 +1069,6 @@ vmw_stdu_primary_plane_prepare_fb(struct drm_plane *plane,
        if (new_content_type != SAME_AS_DISPLAY) {
                struct vmw_surface_metadata metadata = {0};
 
-               metadata.base_size.width = hdisplay;
-               metadata.base_size.height = vdisplay;
-               metadata.base_size.depth = 1;
-
                /*
                 * If content buffer is a buffer object, then we have to
                 * construct surface info
@@ -1104,6 +1100,10 @@ vmw_stdu_primary_plane_prepare_fb(struct drm_plane *plane,
                        metadata = new_vfbs->surface->metadata;
                }
 
+               metadata.base_size.width = hdisplay;
+               metadata.base_size.height = vdisplay;
+               metadata.base_size.depth = 1;
+
                if (vps->surf) {
                        struct drm_vmw_size cur_base_size =
                                vps->surf->metadata.base_size;
index 6f1fe72..a9c2de9 100644 (file)
@@ -25,6 +25,7 @@
 
 #define U1_MOUSE_REPORT_ID                     0x01 /* Mouse data ReportID */
 #define U1_ABSOLUTE_REPORT_ID          0x03 /* Absolute data ReportID */
+#define U1_ABSOLUTE_REPORT_ID_SECD  0x02 /* FW-PTP Absolute data ReportID */
 #define U1_FEATURE_REPORT_ID           0x05 /* Feature ReportID */
 #define U1_SP_ABSOLUTE_REPORT_ID       0x06 /* Feature ReportID */
 
@@ -368,6 +369,7 @@ static int u1_raw_event(struct alps_dev *hdata, u8 *data, int size)
        case U1_FEATURE_REPORT_ID:
                break;
        case U1_ABSOLUTE_REPORT_ID:
+       case U1_ABSOLUTE_REPORT_ID_SECD:
                for (i = 0; i < hdata->max_fingers; i++) {
                        u8 *contact = &data[i * 5];
 
index 359bdfb..e82f604 100644 (file)
@@ -60,6 +60,7 @@ MODULE_PARM_DESC(swap_fn_leftctrl, "Swap the Fn and left Control keys. "
 struct apple_sc {
        unsigned long quirks;
        unsigned int fn_on;
+       unsigned int fn_found;
        DECLARE_BITMAP(pressed_numlock, KEY_CNT);
 };
 
@@ -365,12 +366,15 @@ static int apple_input_mapping(struct hid_device *hdev, struct hid_input *hi,
                struct hid_field *field, struct hid_usage *usage,
                unsigned long **bit, int *max)
 {
+       struct apple_sc *asc = hid_get_drvdata(hdev);
+
        if (usage->hid == (HID_UP_CUSTOM | 0x0003) ||
                        usage->hid == (HID_UP_MSVENDOR | 0x0003) ||
                        usage->hid == (HID_UP_HPVENDOR2 | 0x0003)) {
                /* The fn key on Apple USB keyboards */
                set_bit(EV_REP, hi->input->evbit);
                hid_map_usage_clear(hi, usage, bit, max, EV_KEY, KEY_FN);
+               asc->fn_found = true;
                apple_setup_input(hi->input);
                return 1;
        }
@@ -397,6 +401,19 @@ static int apple_input_mapped(struct hid_device *hdev, struct hid_input *hi,
        return 0;
 }
 
+static int apple_input_configured(struct hid_device *hdev,
+               struct hid_input *hidinput)
+{
+       struct apple_sc *asc = hid_get_drvdata(hdev);
+
+       if ((asc->quirks & APPLE_HAS_FN) && !asc->fn_found) {
+               hid_info(hdev, "Fn key not found (Apple Wireless Keyboard clone?), disabling Fn key handling\n");
+               asc->quirks = 0;
+       }
+
+       return 0;
+}
+
 static int apple_probe(struct hid_device *hdev,
                const struct hid_device_id *id)
 {
@@ -611,6 +628,7 @@ static struct hid_driver apple_driver = {
        .event = apple_event,
        .input_mapping = apple_input_mapping,
        .input_mapped = apple_input_mapped,
+       .input_configured = apple_input_configured,
 };
 module_hid_driver(apple_driver);
 
index 874fc37..6f370e0 100644 (file)
 #define USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A081    0xa081
 #define USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A0C2    0xa0c2
 #define USB_DEVICE_ID_HOLTEK_ALT_KEYBOARD_A096 0xa096
+#define USB_DEVICE_ID_HOLTEK_ALT_KEYBOARD_A293 0xa293
 
 #define USB_VENDOR_ID_IMATION          0x0718
 #define USB_DEVICE_ID_DISC_STAKKA      0xd000
 #define USB_DEVICE_ID_ROCCAT_RYOS_MK_PRO       0x3232
 #define USB_DEVICE_ID_ROCCAT_SAVU      0x2d5a
 
+#define USB_VENDOR_ID_SAI              0x17dd
+
 #define USB_VENDOR_ID_SAITEK           0x06a3
 #define USB_DEVICE_ID_SAITEK_RUMBLEPAD 0xff17
 #define USB_DEVICE_ID_SAITEK_PS1000    0x0621
index 48dff5d..a78c13c 100644 (file)
@@ -1153,7 +1153,7 @@ static int logi_dj_recv_query_paired_devices(struct dj_receiver_dev *djrcv_dev)
        if (!dj_report)
                return -ENOMEM;
        dj_report->report_id = REPORT_ID_DJ_SHORT;
-       dj_report->device_index = 0xFF;
+       dj_report->device_index = HIDPP_RECEIVER_INDEX;
        dj_report->report_type = REPORT_TYPE_CMD_GET_PAIRED_DEVICES;
        retval = logi_dj_recv_send_report(djrcv_dev, dj_report);
        kfree(dj_report);
@@ -1175,7 +1175,7 @@ static int logi_dj_recv_switch_to_dj_mode(struct dj_receiver_dev *djrcv_dev,
 
        if (djrcv_dev->type == recvr_type_dj) {
                dj_report->report_id = REPORT_ID_DJ_SHORT;
-               dj_report->device_index = 0xFF;
+               dj_report->device_index = HIDPP_RECEIVER_INDEX;
                dj_report->report_type = REPORT_TYPE_CMD_SWITCH;
                dj_report->report_params[CMD_SWITCH_PARAM_DEVBITFIELD] = 0x3F;
                dj_report->report_params[CMD_SWITCH_PARAM_TIMEOUT_SECONDS] =
@@ -1204,7 +1204,7 @@ static int logi_dj_recv_switch_to_dj_mode(struct dj_receiver_dev *djrcv_dev,
        memset(buf, 0, HIDPP_REPORT_SHORT_LENGTH);
 
        buf[0] = REPORT_ID_HIDPP_SHORT;
-       buf[1] = 0xFF;
+       buf[1] = HIDPP_RECEIVER_INDEX;
        buf[2] = 0x80;
        buf[3] = 0x00;
        buf[4] = 0x00;
index 1e1cf8e..b8b53dc 100644 (file)
@@ -3146,7 +3146,7 @@ static int hi_res_scroll_enable(struct hidpp_device *hidpp)
                multiplier = 1;
 
        hidpp->vertical_wheel_counter.wheel_multiplier = multiplier;
-       hid_info(hidpp->hid_dev, "multiplier = %d\n", multiplier);
+       hid_dbg(hidpp->hid_dev, "wheel multiplier = %d\n", multiplier);
        return 0;
 }
 
index 3413866..abd8690 100644 (file)
@@ -535,6 +535,12 @@ static int magicmouse_setup_input(struct input_dev *input, struct hid_device *hd
                __set_bit(MSC_RAW, input->mscbit);
        }
 
+       /*
+        * hid-input may mark device as using autorepeat, but neither
+        * the trackpad, nor the mouse actually want it.
+        */
+       __clear_bit(EV_REP, input->evbit);
+
        return 0;
 }
 
index ca8b5c2..934fc0a 100644 (file)
@@ -88,6 +88,7 @@ static const struct hid_device_id hid_quirks[] = {
        { HID_USB_DEVICE(USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_FIGHTING), HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT },
        { HID_USB_DEVICE(USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_FLYING), HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT },
        { HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_KEYBOARD_A096), HID_QUIRK_NO_INIT_REPORTS },
+       { HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_KEYBOARD_A293), HID_QUIRK_ALWAYS_POLL },
        { HID_USB_DEVICE(USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_LOGITECH_OEM_USB_OPTICAL_MOUSE_0A4A), HID_QUIRK_ALWAYS_POLL },
        { HID_USB_DEVICE(USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_LOGITECH_OEM_USB_OPTICAL_MOUSE_0B4A), HID_QUIRK_ALWAYS_POLL },
        { HID_USB_DEVICE(USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_PIXART_OEM_USB_OPTICAL_MOUSE), HID_QUIRK_ALWAYS_POLL },
@@ -832,6 +833,7 @@ static const struct hid_device_id hid_ignore_list[] = {
        { HID_USB_DEVICE(USB_VENDOR_ID_PETZL, USB_DEVICE_ID_PETZL_HEADLAMP) },
        { HID_USB_DEVICE(USB_VENDOR_ID_PHILIPS, USB_DEVICE_ID_PHILIPS_IEEE802154_DONGLE) },
        { HID_USB_DEVICE(USB_VENDOR_ID_POWERCOM, USB_DEVICE_ID_POWERCOM_UPS) },
+       { HID_USB_DEVICE(USB_VENDOR_ID_SAI, USB_DEVICE_ID_CYPRESS_HIDCOM) },
 #if IS_ENABLED(CONFIG_MOUSE_SYNAPTICS_USB)
        { HID_USB_DEVICE(USB_VENDOR_ID_SYNAPTICS, USB_DEVICE_ID_SYNAPTICS_TP) },
        { HID_USB_DEVICE(USB_VENDOR_ID_SYNAPTICS, USB_DEVICE_ID_SYNAPTICS_INT_TP) },
index 6286204..a3b151b 100644 (file)
@@ -526,7 +526,8 @@ static int steam_register(struct steam_device *steam)
                        steam_battery_register(steam);
 
                mutex_lock(&steam_devices_lock);
-               list_add(&steam->list, &steam_devices);
+               if (list_empty(&steam->list))
+                       list_add(&steam->list, &steam_devices);
                mutex_unlock(&steam_devices_lock);
        }
 
@@ -552,7 +553,7 @@ static void steam_unregister(struct steam_device *steam)
                hid_info(steam->hdev, "Steam Controller '%s' disconnected",
                                steam->serial_no);
                mutex_lock(&steam_devices_lock);
-               list_del(&steam->list);
+               list_del_init(&steam->list);
                mutex_unlock(&steam_devices_lock);
                steam->serial_no[0] = 0;
        }
@@ -738,6 +739,7 @@ static int steam_probe(struct hid_device *hdev,
        mutex_init(&steam->mutex);
        steam->quirks = id->driver_data;
        INIT_WORK(&steam->work_connect, steam_work_connect_cb);
+       INIT_LIST_HEAD(&steam->list);
 
        steam->client_hdev = steam_create_client_hid(hdev);
        if (IS_ERR(steam->client_hdev)) {
index ec142bc..35f3bfc 100644 (file)
@@ -373,6 +373,14 @@ static const struct dmi_system_id i2c_hid_dmi_desc_override_table[] = {
                },
                .driver_data = (void *)&sipodev_desc
        },
+       {
+               .ident = "Mediacom FlexBook edge 13",
+               .matches = {
+                       DMI_EXACT_MATCH(DMI_SYS_VENDOR, "MEDIACOM"),
+                       DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "FlexBook_edge13-M-FBE13"),
+               },
+               .driver_data = (void *)&sipodev_desc
+       },
        {
                .ident = "Odys Winbook 13",
                .matches = {
index 40387d5..3ccc703 100644 (file)
@@ -747,17 +747,50 @@ static int cti_dying_cpu(unsigned int cpu)
        return 0;
 }
 
+static int cti_pm_setup(struct cti_drvdata *drvdata)
+{
+       int ret;
+
+       if (drvdata->ctidev.cpu == -1)
+               return 0;
+
+       if (nr_cti_cpu)
+               goto done;
+
+       cpus_read_lock();
+       ret = cpuhp_setup_state_nocalls_cpuslocked(
+                       CPUHP_AP_ARM_CORESIGHT_CTI_STARTING,
+                       "arm/coresight_cti:starting",
+                       cti_starting_cpu, cti_dying_cpu);
+       if (ret) {
+               cpus_read_unlock();
+               return ret;
+       }
+
+       ret = cpu_pm_register_notifier(&cti_cpu_pm_nb);
+       cpus_read_unlock();
+       if (ret) {
+               cpuhp_remove_state_nocalls(CPUHP_AP_ARM_CORESIGHT_CTI_STARTING);
+               return ret;
+       }
+
+done:
+       nr_cti_cpu++;
+       cti_cpu_drvdata[drvdata->ctidev.cpu] = drvdata;
+
+       return 0;
+}
+
 /* release PM registrations */
 static void cti_pm_release(struct cti_drvdata *drvdata)
 {
-       if (drvdata->ctidev.cpu >= 0) {
-               if (--nr_cti_cpu == 0) {
-                       cpu_pm_unregister_notifier(&cti_cpu_pm_nb);
+       if (drvdata->ctidev.cpu == -1)
+               return;
 
-                       cpuhp_remove_state_nocalls(
-                               CPUHP_AP_ARM_CORESIGHT_CTI_STARTING);
-               }
-               cti_cpu_drvdata[drvdata->ctidev.cpu] = NULL;
+       cti_cpu_drvdata[drvdata->ctidev.cpu] = NULL;
+       if (--nr_cti_cpu == 0) {
+               cpu_pm_unregister_notifier(&cti_cpu_pm_nb);
+               cpuhp_remove_state_nocalls(CPUHP_AP_ARM_CORESIGHT_CTI_STARTING);
        }
 }
 
@@ -823,19 +856,14 @@ static int cti_probe(struct amba_device *adev, const struct amba_id *id)
 
        /* driver data*/
        drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL);
-       if (!drvdata) {
-               ret = -ENOMEM;
-               dev_info(dev, "%s, mem err\n", __func__);
-               goto err_out;
-       }
+       if (!drvdata)
+               return -ENOMEM;
 
        /* Validity for the resource is already checked by the AMBA core */
        base = devm_ioremap_resource(dev, res);
-       if (IS_ERR(base)) {
-               ret = PTR_ERR(base);
-               dev_err(dev, "%s, remap err\n", __func__);
-               goto err_out;
-       }
+       if (IS_ERR(base))
+               return PTR_ERR(base);
+
        drvdata->base = base;
 
        dev_set_drvdata(dev, drvdata);
@@ -854,8 +882,7 @@ static int cti_probe(struct amba_device *adev, const struct amba_id *id)
        pdata = coresight_cti_get_platform_data(dev);
        if (IS_ERR(pdata)) {
                dev_err(dev, "coresight_cti_get_platform_data err\n");
-               ret =  PTR_ERR(pdata);
-               goto err_out;
+               return  PTR_ERR(pdata);
        }
 
        /* default to powered - could change on PM notifications */
@@ -867,35 +894,20 @@ static int cti_probe(struct amba_device *adev, const struct amba_id *id)
                                               drvdata->ctidev.cpu);
        else
                cti_desc.name = coresight_alloc_device_name(&cti_sys_devs, dev);
-       if (!cti_desc.name) {
-               ret = -ENOMEM;
-               goto err_out;
-       }
+       if (!cti_desc.name)
+               return -ENOMEM;
 
        /* setup CPU power management handling for CPU bound CTI devices. */
-       if (drvdata->ctidev.cpu >= 0) {
-               cti_cpu_drvdata[drvdata->ctidev.cpu] = drvdata;
-               if (!nr_cti_cpu++) {
-                       cpus_read_lock();
-                       ret = cpuhp_setup_state_nocalls_cpuslocked(
-                               CPUHP_AP_ARM_CORESIGHT_CTI_STARTING,
-                               "arm/coresight_cti:starting",
-                               cti_starting_cpu, cti_dying_cpu);
-
-                       if (!ret)
-                               ret = cpu_pm_register_notifier(&cti_cpu_pm_nb);
-                       cpus_read_unlock();
-                       if (ret)
-                               goto err_out;
-               }
-       }
+       ret = cti_pm_setup(drvdata);
+       if (ret)
+               return ret;
 
        /* create dynamic attributes for connections */
        ret = cti_create_cons_sysfs(dev, drvdata);
        if (ret) {
                dev_err(dev, "%s: create dynamic sysfs entries failed\n",
                        cti_desc.name);
-               goto err_out;
+               goto pm_release;
        }
 
        /* set up coresight component description */
@@ -908,7 +920,7 @@ static int cti_probe(struct amba_device *adev, const struct amba_id *id)
        drvdata->csdev = coresight_register(&cti_desc);
        if (IS_ERR(drvdata->csdev)) {
                ret = PTR_ERR(drvdata->csdev);
-               goto err_out;
+               goto pm_release;
        }
 
        /* add to list of CTI devices */
@@ -927,7 +939,7 @@ static int cti_probe(struct amba_device *adev, const struct amba_id *id)
        dev_info(&drvdata->csdev->dev, "CTI initialized\n");
        return 0;
 
-err_out:
+pm_release:
        cti_pm_release(drvdata);
        return ret;
 }
index 747afc8..0c35cd5 100644 (file)
@@ -1388,18 +1388,57 @@ static struct notifier_block etm4_cpu_pm_nb = {
        .notifier_call = etm4_cpu_pm_notify,
 };
 
-static int etm4_cpu_pm_register(void)
+/* Setup PM. Called with cpus locked. Deals with error conditions and counts */
+static int etm4_pm_setup_cpuslocked(void)
 {
-       if (IS_ENABLED(CONFIG_CPU_PM))
-               return cpu_pm_register_notifier(&etm4_cpu_pm_nb);
+       int ret;
 
-       return 0;
+       if (etm4_count++)
+               return 0;
+
+       ret = cpu_pm_register_notifier(&etm4_cpu_pm_nb);
+       if (ret)
+               goto reduce_count;
+
+       ret = cpuhp_setup_state_nocalls_cpuslocked(CPUHP_AP_ARM_CORESIGHT_STARTING,
+                                                  "arm/coresight4:starting",
+                                                  etm4_starting_cpu, etm4_dying_cpu);
+
+       if (ret)
+               goto unregister_notifier;
+
+       ret = cpuhp_setup_state_nocalls_cpuslocked(CPUHP_AP_ONLINE_DYN,
+                                                  "arm/coresight4:online",
+                                                  etm4_online_cpu, NULL);
+
+       /* HP dyn state ID returned in ret on success */
+       if (ret > 0) {
+               hp_online = ret;
+               return 0;
+       }
+
+       /* failed dyn state - remove others */
+       cpuhp_remove_state_nocalls_cpuslocked(CPUHP_AP_ARM_CORESIGHT_STARTING);
+
+unregister_notifier:
+       cpu_pm_unregister_notifier(&etm4_cpu_pm_nb);
+
+reduce_count:
+       --etm4_count;
+       return ret;
 }
 
-static void etm4_cpu_pm_unregister(void)
+static void etm4_pm_clear(void)
 {
-       if (IS_ENABLED(CONFIG_CPU_PM))
-               cpu_pm_unregister_notifier(&etm4_cpu_pm_nb);
+       if (--etm4_count != 0)
+               return;
+
+       cpu_pm_unregister_notifier(&etm4_cpu_pm_nb);
+       cpuhp_remove_state_nocalls(CPUHP_AP_ARM_CORESIGHT_STARTING);
+       if (hp_online) {
+               cpuhp_remove_state_nocalls(hp_online);
+               hp_online = 0;
+       }
 }
 
 static int etm4_probe(struct amba_device *adev, const struct amba_id *id)
@@ -1453,24 +1492,15 @@ static int etm4_probe(struct amba_device *adev, const struct amba_id *id)
                                etm4_init_arch_data,  drvdata, 1))
                dev_err(dev, "ETM arch init failed\n");
 
-       if (!etm4_count++) {
-               cpuhp_setup_state_nocalls_cpuslocked(CPUHP_AP_ARM_CORESIGHT_STARTING,
-                                                    "arm/coresight4:starting",
-                                                    etm4_starting_cpu, etm4_dying_cpu);
-               ret = cpuhp_setup_state_nocalls_cpuslocked(CPUHP_AP_ONLINE_DYN,
-                                                          "arm/coresight4:online",
-                                                          etm4_online_cpu, NULL);
-               if (ret < 0)
-                       goto err_arch_supported;
-               hp_online = ret;
+       ret = etm4_pm_setup_cpuslocked();
+       cpus_read_unlock();
 
-               ret = etm4_cpu_pm_register();
-               if (ret)
-                       goto err_arch_supported;
+       /* etm4_pm_setup_cpuslocked() does its own cleanup - exit on error */
+       if (ret) {
+               etmdrvdata[drvdata->cpu] = NULL;
+               return ret;
        }
 
-       cpus_read_unlock();
-
        if (etm4_arch_supported(drvdata->arch) == false) {
                ret = -EINVAL;
                goto err_arch_supported;
@@ -1517,13 +1547,7 @@ static int etm4_probe(struct amba_device *adev, const struct amba_id *id)
 
 err_arch_supported:
        etmdrvdata[drvdata->cpu] = NULL;
-       if (--etm4_count == 0) {
-               etm4_cpu_pm_unregister();
-
-               cpuhp_remove_state_nocalls(CPUHP_AP_ARM_CORESIGHT_STARTING);
-               if (hp_online)
-                       cpuhp_remove_state_nocalls(hp_online);
-       }
+       etm4_pm_clear();
        return ret;
 }
 
index ca232ec..c9ac3dc 100644 (file)
@@ -1021,15 +1021,30 @@ int intel_th_set_output(struct intel_th_device *thdev,
 {
        struct intel_th_device *hub = to_intel_th_hub(thdev);
        struct intel_th_driver *hubdrv = to_intel_th_driver(hub->dev.driver);
+       int ret;
 
        /* In host mode, this is up to the external debugger, do nothing. */
        if (hub->host_mode)
                return 0;
 
-       if (!hubdrv->set_output)
-               return -ENOTSUPP;
+       /*
+        * hub is instantiated together with the source device that
+        * calls here, so guaranteed to be present.
+        */
+       hubdrv = to_intel_th_driver(hub->dev.driver);
+       if (!hubdrv || !try_module_get(hubdrv->driver.owner))
+               return -EINVAL;
+
+       if (!hubdrv->set_output) {
+               ret = -ENOTSUPP;
+               goto out;
+       }
+
+       ret = hubdrv->set_output(hub, master);
 
-       return hubdrv->set_output(hub, master);
+out:
+       module_put(hubdrv->driver.owner);
+       return ret;
 }
 EXPORT_SYMBOL_GPL(intel_th_set_output);
 
index 7ccac74..21fdf0b 100644 (file)
@@ -233,11 +233,21 @@ static const struct pci_device_id intel_th_pci_id_table[] = {
                PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xa0a6),
                .driver_data = (kernel_ulong_t)&intel_th_2x,
        },
+       {
+               /* Tiger Lake PCH-H */
+               PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x43a6),
+               .driver_data = (kernel_ulong_t)&intel_th_2x,
+       },
        {
                /* Jasper Lake PCH */
                PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x4da6),
                .driver_data = (kernel_ulong_t)&intel_th_2x,
        },
+       {
+               /* Jasper Lake CPU */
+               PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x4e29),
+               .driver_data = (kernel_ulong_t)&intel_th_2x,
+       },
        {
                /* Elkhart Lake CPU */
                PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x4529),
@@ -248,6 +258,11 @@ static const struct pci_device_id intel_th_pci_id_table[] = {
                PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x4b26),
                .driver_data = (kernel_ulong_t)&intel_th_2x,
        },
+       {
+               /* Emmitsburg PCH */
+               PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x1bcc),
+               .driver_data = (kernel_ulong_t)&intel_th_2x,
+       },
        { 0 },
 };
 
index 3a1f4e6..a1529f5 100644 (file)
@@ -161,9 +161,7 @@ static int sth_stm_link(struct stm_data *stm_data, unsigned int master,
 {
        struct sth_device *sth = container_of(stm_data, struct sth_device, stm);
 
-       intel_th_set_output(to_intel_th_device(sth->dev), master);
-
-       return 0;
+       return intel_th_set_output(to_intel_th_device(sth->dev), master);
 }
 
 static int intel_th_sw_init(struct sth_device *sth)
index 00e100f..813bca7 100644 (file)
@@ -1685,10 +1685,13 @@ static int mma8452_probe(struct i2c_client *client,
 
        ret = mma8452_set_freefall_mode(data, false);
        if (ret < 0)
-               goto buffer_cleanup;
+               goto unregister_device;
 
        return 0;
 
+unregister_device:
+       iio_device_unregister(indio_dev);
+
 buffer_cleanup:
        iio_triggered_buffer_cleanup(indio_dev);
 
index f47606e..b33fe6c 100644 (file)
@@ -329,7 +329,7 @@ static int ad7780_probe(struct spi_device *spi)
 
        ret = ad7780_init_gpios(&spi->dev, st);
        if (ret)
-               goto error_cleanup_buffer_and_trigger;
+               return ret;
 
        st->reg = devm_regulator_get(&spi->dev, "avdd");
        if (IS_ERR(st->reg))
index c24c8da..7af8f05 100644 (file)
@@ -332,12 +332,12 @@ static struct adi_axi_adc_client *adi_axi_adc_attach_client(struct device *dev)
                if (cl->dev->of_node != cln)
                        continue;
 
-               if (!try_module_get(dev->driver->owner)) {
+               if (!try_module_get(cl->dev->driver->owner)) {
                        mutex_unlock(&registered_clients_lock);
                        return ERR_PTR(-ENODEV);
                }
 
-               get_device(dev);
+               get_device(cl->dev);
                cl->info = info;
                mutex_unlock(&registered_clients_lock);
                return cl;
index e9f87e4..a350762 100644 (file)
@@ -65,6 +65,7 @@ static const struct reg_field afe4403_reg_fields[] = {
  * @regulator: Pointer to the regulator for the IC
  * @trig: IIO trigger for this device
  * @irq: ADC_RDY line interrupt number
+ * @buffer: Used to construct data layout to push into IIO buffer.
  */
 struct afe4403_data {
        struct device *dev;
@@ -74,6 +75,8 @@ struct afe4403_data {
        struct regulator *regulator;
        struct iio_trigger *trig;
        int irq;
+       /* Ensure suitable alignment for timestamp */
+       s32 buffer[8] __aligned(8);
 };
 
 enum afe4403_chan_id {
@@ -309,7 +312,6 @@ static irqreturn_t afe4403_trigger_handler(int irq, void *private)
        struct iio_dev *indio_dev = pf->indio_dev;
        struct afe4403_data *afe = iio_priv(indio_dev);
        int ret, bit, i = 0;
-       s32 buffer[8];
        u8 tx[4] = {AFE440X_CONTROL0, 0x0, 0x0, AFE440X_CONTROL0_READ};
        u8 rx[3];
 
@@ -326,7 +328,7 @@ static irqreturn_t afe4403_trigger_handler(int irq, void *private)
                if (ret)
                        goto err;
 
-               buffer[i++] = get_unaligned_be24(&rx[0]);
+               afe->buffer[i++] = get_unaligned_be24(&rx[0]);
        }
 
        /* Disable reading from the device */
@@ -335,7 +337,8 @@ static irqreturn_t afe4403_trigger_handler(int irq, void *private)
        if (ret)
                goto err;
 
-       iio_push_to_buffers_with_timestamp(indio_dev, buffer, pf->timestamp);
+       iio_push_to_buffers_with_timestamp(indio_dev, afe->buffer,
+                                          pf->timestamp);
 err:
        iio_trigger_notify_done(indio_dev->trig);
 
index e728bbb..cebb1fd 100644 (file)
@@ -83,6 +83,7 @@ static const struct reg_field afe4404_reg_fields[] = {
  * @regulator: Pointer to the regulator for the IC
  * @trig: IIO trigger for this device
  * @irq: ADC_RDY line interrupt number
+ * @buffer: Used to construct a scan to push to the iio buffer.
  */
 struct afe4404_data {
        struct device *dev;
@@ -91,6 +92,7 @@ struct afe4404_data {
        struct regulator *regulator;
        struct iio_trigger *trig;
        int irq;
+       s32 buffer[10] __aligned(8);
 };
 
 enum afe4404_chan_id {
@@ -328,17 +330,17 @@ static irqreturn_t afe4404_trigger_handler(int irq, void *private)
        struct iio_dev *indio_dev = pf->indio_dev;
        struct afe4404_data *afe = iio_priv(indio_dev);
        int ret, bit, i = 0;
-       s32 buffer[10];
 
        for_each_set_bit(bit, indio_dev->active_scan_mask,
                         indio_dev->masklength) {
                ret = regmap_read(afe->regmap, afe4404_channel_values[bit],
-                                 &buffer[i++]);
+                                 &afe->buffer[i++]);
                if (ret)
                        goto err;
        }
 
-       iio_push_to_buffers_with_timestamp(indio_dev, buffer, pf->timestamp);
+       iio_push_to_buffers_with_timestamp(indio_dev, afe->buffer,
+                                          pf->timestamp);
 err:
        iio_trigger_notify_done(indio_dev->trig);
 
index 7ecd2ff..665eb7e 100644 (file)
@@ -38,6 +38,11 @@ struct hdc100x_data {
 
        /* integration time of the sensor */
        int adc_int_us[2];
+       /* Ensure natural alignment of timestamp */
+       struct {
+               __be16 channels[2];
+               s64 ts __aligned(8);
+       } scan;
 };
 
 /* integration time in us */
@@ -322,7 +327,6 @@ static irqreturn_t hdc100x_trigger_handler(int irq, void *p)
        struct i2c_client *client = data->client;
        int delay = data->adc_int_us[0] + data->adc_int_us[1];
        int ret;
-       s16 buf[8];  /* 2x s16 + padding + 8 byte timestamp */
 
        /* dual read starts at temp register */
        mutex_lock(&data->lock);
@@ -333,13 +337,13 @@ static irqreturn_t hdc100x_trigger_handler(int irq, void *p)
        }
        usleep_range(delay, delay + 1000);
 
-       ret = i2c_master_recv(client, (u8 *)buf, 4);
+       ret = i2c_master_recv(client, (u8 *)data->scan.channels, 4);
        if (ret < 0) {
                dev_err(&client->dev, "cannot read sensor data\n");
                goto err;
        }
 
-       iio_push_to_buffers_with_timestamp(indio_dev, buf,
+       iio_push_to_buffers_with_timestamp(indio_dev, &data->scan,
                                           iio_get_time_ns(indio_dev));
 err:
        mutex_unlock(&data->lock);
index 7d6771f..b2eb5ab 100644 (file)
@@ -14,8 +14,6 @@
 
 #include <linux/iio/iio.h>
 
-#define HTS221_DATA_SIZE       2
-
 enum hts221_sensor_type {
        HTS221_SENSOR_H,
        HTS221_SENSOR_T,
@@ -39,6 +37,11 @@ struct hts221_hw {
 
        bool enabled;
        u8 odr;
+       /* Ensure natural alignment of timestamp */
+       struct {
+               __le16 channels[2];
+               s64 ts __aligned(8);
+       } scan;
 };
 
 extern const struct dev_pm_ops hts221_pm_ops;
index 9fb3f33..ba7d413 100644 (file)
@@ -160,7 +160,6 @@ static const struct iio_buffer_setup_ops hts221_buffer_ops = {
 
 static irqreturn_t hts221_buffer_handler_thread(int irq, void *p)
 {
-       u8 buffer[ALIGN(2 * HTS221_DATA_SIZE, sizeof(s64)) + sizeof(s64)];
        struct iio_poll_func *pf = p;
        struct iio_dev *iio_dev = pf->indio_dev;
        struct hts221_hw *hw = iio_priv(iio_dev);
@@ -170,18 +169,20 @@ static irqreturn_t hts221_buffer_handler_thread(int irq, void *p)
        /* humidity data */
        ch = &iio_dev->channels[HTS221_SENSOR_H];
        err = regmap_bulk_read(hw->regmap, ch->address,
-                              buffer, HTS221_DATA_SIZE);
+                              &hw->scan.channels[0],
+                              sizeof(hw->scan.channels[0]));
        if (err < 0)
                goto out;
 
        /* temperature data */
        ch = &iio_dev->channels[HTS221_SENSOR_T];
        err = regmap_bulk_read(hw->regmap, ch->address,
-                              buffer + HTS221_DATA_SIZE, HTS221_DATA_SIZE);
+                              &hw->scan.channels[1],
+                              sizeof(hw->scan.channels[1]));
        if (err < 0)
                goto out;
 
-       iio_push_to_buffers_with_timestamp(iio_dev, buffer,
+       iio_push_to_buffers_with_timestamp(iio_dev, &hw->scan,
                                           iio_get_time_ns(iio_dev));
 
 out:
index 1527f01..3525333 100644 (file)
@@ -130,6 +130,8 @@ static const char * const iio_modifier_names[] = {
        [IIO_MOD_PM2P5] = "pm2p5",
        [IIO_MOD_PM4] = "pm4",
        [IIO_MOD_PM10] = "pm10",
+       [IIO_MOD_ETHANOL] = "ethanol",
+       [IIO_MOD_H2] = "h2",
 };
 
 /* relies on pairs of these shared then separate */
index 810fdfd..91c3935 100644 (file)
@@ -192,6 +192,11 @@ struct ak8974 {
        bool drdy_irq;
        struct completion drdy_complete;
        bool drdy_active_low;
+       /* Ensure timestamp is naturally aligned */
+       struct {
+               __le16 channels[3];
+               s64 ts __aligned(8);
+       } scan;
 };
 
 static const char ak8974_reg_avdd[] = "avdd";
@@ -657,7 +662,6 @@ static void ak8974_fill_buffer(struct iio_dev *indio_dev)
 {
        struct ak8974 *ak8974 = iio_priv(indio_dev);
        int ret;
-       __le16 hw_values[8]; /* Three axes + 64bit padding */
 
        pm_runtime_get_sync(&ak8974->i2c->dev);
        mutex_lock(&ak8974->lock);
@@ -667,13 +671,13 @@ static void ak8974_fill_buffer(struct iio_dev *indio_dev)
                dev_err(&ak8974->i2c->dev, "error triggering measure\n");
                goto out_unlock;
        }
-       ret = ak8974_getresult(ak8974, hw_values);
+       ret = ak8974_getresult(ak8974, ak8974->scan.channels);
        if (ret) {
                dev_err(&ak8974->i2c->dev, "error getting measures\n");
                goto out_unlock;
        }
 
-       iio_push_to_buffers_with_timestamp(indio_dev, hw_values,
+       iio_push_to_buffers_with_timestamp(indio_dev, &ak8974->scan,
                                           iio_get_time_ns(indio_dev));
 
  out_unlock:
@@ -862,19 +866,21 @@ static int ak8974_probe(struct i2c_client *i2c,
        ak8974->map = devm_regmap_init_i2c(i2c, &ak8974_regmap_config);
        if (IS_ERR(ak8974->map)) {
                dev_err(&i2c->dev, "failed to allocate register map\n");
+               pm_runtime_put_noidle(&i2c->dev);
+               pm_runtime_disable(&i2c->dev);
                return PTR_ERR(ak8974->map);
        }
 
        ret = ak8974_set_power(ak8974, AK8974_PWR_ON);
        if (ret) {
                dev_err(&i2c->dev, "could not power on\n");
-               goto power_off;
+               goto disable_pm;
        }
 
        ret = ak8974_detect(ak8974);
        if (ret) {
                dev_err(&i2c->dev, "neither AK8974 nor AMI30x found\n");
-               goto power_off;
+               goto disable_pm;
        }
 
        ret = ak8974_selftest(ak8974);
@@ -884,14 +890,9 @@ static int ak8974_probe(struct i2c_client *i2c,
        ret = ak8974_reset(ak8974);
        if (ret) {
                dev_err(&i2c->dev, "AK8974 reset failed\n");
-               goto power_off;
+               goto disable_pm;
        }
 
-       pm_runtime_set_autosuspend_delay(&i2c->dev,
-                                        AK8974_AUTOSUSPEND_DELAY);
-       pm_runtime_use_autosuspend(&i2c->dev);
-       pm_runtime_put(&i2c->dev);
-
        indio_dev->dev.parent = &i2c->dev;
        switch (ak8974->variant) {
        case AK8974_WHOAMI_VALUE_AMI306:
@@ -957,6 +958,11 @@ no_irq:
                goto cleanup_buffer;
        }
 
+       pm_runtime_set_autosuspend_delay(&i2c->dev,
+                                        AK8974_AUTOSUSPEND_DELAY);
+       pm_runtime_use_autosuspend(&i2c->dev);
+       pm_runtime_put(&i2c->dev);
+
        return 0;
 
 cleanup_buffer:
@@ -965,7 +971,6 @@ disable_pm:
        pm_runtime_put_noidle(&i2c->dev);
        pm_runtime_disable(&i2c->dev);
        ak8974_set_power(ak8974, AK8974_PWR_OFF);
-power_off:
        regulator_bulk_disable(ARRAY_SIZE(ak8974->regs), ak8974->regs);
 
        return ret;
index 2f598ad..f5db9fa 100644 (file)
@@ -212,16 +212,21 @@ static irqreturn_t ms5611_trigger_handler(int irq, void *p)
        struct iio_poll_func *pf = p;
        struct iio_dev *indio_dev = pf->indio_dev;
        struct ms5611_state *st = iio_priv(indio_dev);
-       s32 buf[4]; /* s32 (pressure) + s32 (temp) + 2 * s32 (timestamp) */
+       /* Ensure buffer elements are naturally aligned */
+       struct {
+               s32 channels[2];
+               s64 ts __aligned(8);
+       } scan;
        int ret;
 
        mutex_lock(&st->lock);
-       ret = ms5611_read_temp_and_pressure(indio_dev, &buf[1], &buf[0]);
+       ret = ms5611_read_temp_and_pressure(indio_dev, &scan.channels[1],
+                                           &scan.channels[0]);
        mutex_unlock(&st->lock);
        if (ret < 0)
                goto err;
 
-       iio_push_to_buffers_with_timestamp(indio_dev, buf,
+       iio_push_to_buffers_with_timestamp(indio_dev, &scan,
                                           iio_get_time_ns(indio_dev));
 
 err:
index 37fe851..799a8dc 100644 (file)
@@ -665,8 +665,10 @@ static int zpa2326_resume(const struct iio_dev *indio_dev)
        int err;
 
        err = pm_runtime_get_sync(indio_dev->dev.parent);
-       if (err < 0)
+       if (err < 0) {
+               pm_runtime_put(indio_dev->dev.parent);
                return err;
+       }
 
        if (err > 0) {
                /*
index 3f9354b..6291fb5 100644 (file)
@@ -951,6 +951,8 @@ static void elan_report_absolute(struct elan_tp_data *data, u8 *packet)
        u8 hover_info = packet[ETP_HOVER_INFO_OFFSET];
        bool contact_valid, hover_event;
 
+       pm_wakeup_event(&data->client->dev, 0);
+
        hover_event = hover_info & 0x40;
        for (i = 0; i < ETP_MAX_FINGERS; i++) {
                contact_valid = tp_info & (1U << (3 + i));
@@ -974,6 +976,8 @@ static void elan_report_trackpoint(struct elan_tp_data *data, u8 *report)
        u8 *packet = &report[ETP_REPORT_ID_OFFSET + 1];
        int x, y;
 
+       pm_wakeup_event(&data->client->dev, 0);
+
        if (!data->tp_input) {
                dev_warn_once(&data->client->dev,
                              "received a trackpoint report while no trackpoint device has been created. Please report upstream.\n");
@@ -998,7 +1002,6 @@ static void elan_report_trackpoint(struct elan_tp_data *data, u8 *report)
 static irqreturn_t elan_isr(int irq, void *dev_id)
 {
        struct elan_tp_data *data = dev_id;
-       struct device *dev = &data->client->dev;
        int error;
        u8 report[ETP_MAX_REPORT_LEN];
 
@@ -1016,8 +1019,6 @@ static irqreturn_t elan_isr(int irq, void *dev_id)
        if (error)
                goto out;
 
-       pm_wakeup_event(dev, 0);
-
        switch (report[ETP_REPORT_ID_OFFSET]) {
        case ETP_REPORT_ID:
                elan_report_absolute(data, report);
@@ -1026,7 +1027,7 @@ static irqreturn_t elan_isr(int irq, void *dev_id)
                elan_report_trackpoint(data, report);
                break;
        default:
-               dev_err(dev, "invalid report id data (%x)\n",
+               dev_err(&data->client->dev, "invalid report id data (%x)\n",
                        report[ETP_REPORT_ID_OFFSET]);
        }
 
index 758dae8..4b81b2d 100644 (file)
@@ -179,6 +179,7 @@ static const char * const smbus_pnp_ids[] = {
        "LEN0093", /* T480 */
        "LEN0096", /* X280 */
        "LEN0097", /* X280 -> ALPS trackpoint */
+       "LEN0099", /* X1 Extreme 1st */
        "LEN009b", /* T580 */
        "LEN200f", /* T450s */
        "LEN2044", /* L470  */
index 7b08ff8..7d7f737 100644 (file)
@@ -425,6 +425,13 @@ static const struct dmi_system_id __initconst i8042_dmi_nomux_table[] = {
                        DMI_MATCH(DMI_PRODUCT_NAME, "076804U"),
                },
        },
+       {
+               /* Lenovo XiaoXin Air 12 */
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "80UN"),
+               },
+       },
        {
                .matches = {
                        DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
index 233cb10..5477a57 100644 (file)
@@ -1325,7 +1325,6 @@ static int elants_i2c_probe(struct i2c_client *client,
                             0, MT_TOOL_PALM, 0, 0);
        input_abs_set_res(ts->input, ABS_MT_POSITION_X, ts->x_res);
        input_abs_set_res(ts->input, ABS_MT_POSITION_Y, ts->y_res);
-       input_abs_set_res(ts->input, ABS_MT_TOUCH_MAJOR, 1);
 
        touchscreen_parse_properties(ts->input, true, &ts->prop);
 
index 6dc49ed..b0f308c 100644 (file)
@@ -305,6 +305,7 @@ config ROCKCHIP_IOMMU
 
 config SUN50I_IOMMU
        bool "Allwinner H6 IOMMU Support"
+       depends on HAS_DMA
        depends on ARCH_SUNXI || COMPILE_TEST
        select ARM_DMA_USE_IOMMU
        select IOMMU_API
index f892992..5730971 100644 (file)
@@ -102,7 +102,7 @@ extern int __init add_special_device(u8 type, u8 id, u16 *devid,
 #ifdef CONFIG_DMI
 void amd_iommu_apply_ivrs_quirks(void);
 #else
-static void amd_iommu_apply_ivrs_quirks(void) { }
+static inline void amd_iommu_apply_ivrs_quirks(void) { }
 #endif
 
 #endif
index cf01d02..be43180 100644 (file)
@@ -12,7 +12,7 @@ struct qcom_smmu {
        struct arm_smmu_device smmu;
 };
 
-static const struct of_device_id qcom_smmu_client_of_match[] = {
+static const struct of_device_id qcom_smmu_client_of_match[] __maybe_unused = {
        { .compatible = "qcom,adreno" },
        { .compatible = "qcom,mdp4" },
        { .compatible = "qcom,mdss" },
index d43120e..b6858ad 100644 (file)
@@ -295,10 +295,10 @@ void iommu_release_device(struct device *dev)
                return;
 
        iommu_device_unlink(dev->iommu->iommu_dev, dev);
-       iommu_group_remove_device(dev);
 
        ops->release_device(dev);
 
+       iommu_group_remove_device(dev);
        module_put(ops->owner);
        dev_iommu_free(dev);
 }
index fce605e..3b1bf2f 100644 (file)
@@ -313,9 +313,9 @@ static int sun50i_iommu_flush_all_tlb(struct sun50i_iommu *iommu)
                    IOMMU_TLB_FLUSH_MICRO_TLB(1) |
                    IOMMU_TLB_FLUSH_MICRO_TLB(0));
 
-       ret = readl_poll_timeout(iommu->base + IOMMU_TLB_FLUSH_REG,
-                                reg, !reg,
-                                1, 2000);
+       ret = readl_poll_timeout_atomic(iommu->base + IOMMU_TLB_FLUSH_REG,
+                                       reg, !reg,
+                                       1, 2000);
        if (ret)
                dev_warn(iommu->dev, "TLB Flush timed out!\n");
 
@@ -556,7 +556,6 @@ static size_t sun50i_iommu_unmap(struct iommu_domain *domain, unsigned long iova
 {
        struct sun50i_iommu_domain *sun50i_domain = to_sun50i_domain(domain);
        phys_addr_t pt_phys;
-       dma_addr_t pte_dma;
        u32 *pte_addr;
        u32 dte;
 
@@ -566,7 +565,6 @@ static size_t sun50i_iommu_unmap(struct iommu_domain *domain, unsigned long iova
 
        pt_phys = sun50i_dte_get_pt_address(dte);
        pte_addr = (u32 *)phys_to_virt(pt_phys) + sun50i_iova_get_pte_index(iova);
-       pte_dma = pt_phys + sun50i_iova_get_pte_index(iova) * PT_ENTRY_SIZE;
 
        if (!sun50i_pte_is_page_valid(*pte_addr))
                return 0;
index ab4144e..d6cd553 100644 (file)
@@ -10,7 +10,7 @@
 #include <linux/clk.h>
 #include <linux/err.h>
 #include <linux/io.h>
-#include <linux/spinlock.h>
+#include <linux/mutex.h>
 #include <linux/atmel-ssc.h>
 #include <linux/slab.h>
 #include <linux/module.h>
@@ -20,7 +20,7 @@
 #include "../../sound/soc/atmel/atmel_ssc_dai.h"
 
 /* Serialize access to ssc_list and user count */
-static DEFINE_SPINLOCK(user_lock);
+static DEFINE_MUTEX(user_lock);
 static LIST_HEAD(ssc_list);
 
 struct ssc_device *ssc_request(unsigned int ssc_num)
@@ -28,7 +28,7 @@ struct ssc_device *ssc_request(unsigned int ssc_num)
        int ssc_valid = 0;
        struct ssc_device *ssc;
 
-       spin_lock(&user_lock);
+       mutex_lock(&user_lock);
        list_for_each_entry(ssc, &ssc_list, list) {
                if (ssc->pdev->dev.of_node) {
                        if (of_alias_get_id(ssc->pdev->dev.of_node, "ssc")
@@ -44,18 +44,18 @@ struct ssc_device *ssc_request(unsigned int ssc_num)
        }
 
        if (!ssc_valid) {
-               spin_unlock(&user_lock);
+               mutex_unlock(&user_lock);
                pr_err("ssc: ssc%d platform device is missing\n", ssc_num);
                return ERR_PTR(-ENODEV);
        }
 
        if (ssc->user) {
-               spin_unlock(&user_lock);
+               mutex_unlock(&user_lock);
                dev_dbg(&ssc->pdev->dev, "module busy\n");
                return ERR_PTR(-EBUSY);
        }
        ssc->user++;
-       spin_unlock(&user_lock);
+       mutex_unlock(&user_lock);
 
        clk_prepare(ssc->clk);
 
@@ -67,14 +67,14 @@ void ssc_free(struct ssc_device *ssc)
 {
        bool disable_clk = true;
 
-       spin_lock(&user_lock);
+       mutex_lock(&user_lock);
        if (ssc->user)
                ssc->user--;
        else {
                disable_clk = false;
                dev_dbg(&ssc->pdev->dev, "device already free\n");
        }
-       spin_unlock(&user_lock);
+       mutex_unlock(&user_lock);
 
        if (disable_clk)
                clk_unprepare(ssc->clk);
@@ -237,9 +237,9 @@ static int ssc_probe(struct platform_device *pdev)
                return -ENXIO;
        }
 
-       spin_lock(&user_lock);
+       mutex_lock(&user_lock);
        list_add_tail(&ssc->list, &ssc_list);
-       spin_unlock(&user_lock);
+       mutex_unlock(&user_lock);
 
        platform_set_drvdata(pdev, ssc);
 
@@ -258,9 +258,9 @@ static int ssc_remove(struct platform_device *pdev)
 
        ssc_sound_dai_remove(ssc);
 
-       spin_lock(&user_lock);
+       mutex_lock(&user_lock);
        list_del(&ssc->list);
-       spin_unlock(&user_lock);
+       mutex_unlock(&user_lock);
 
        return 0;
 }
index 8d468e0..f476dbc 100644 (file)
@@ -745,9 +745,8 @@ static int mei_cl_device_remove(struct device *dev)
 
        mei_cl_bus_module_put(cldev);
        module_put(THIS_MODULE);
-       dev->driver = NULL;
-       return ret;
 
+       return ret;
 }
 
 static ssize_t name_show(struct device *dev, struct device_attribute *a,
index 8410d03..add0401 100644 (file)
@@ -1980,6 +1980,7 @@ static int __nvme_revalidate_disk(struct gendisk *disk, struct nvme_id_ns *id)
        if (ns->head->disk) {
                nvme_update_disk_info(ns->head->disk, ns, id);
                blk_queue_stack_limits(ns->head->disk->queue, ns->queue);
+               nvme_mpath_update_disk_size(ns->head->disk);
        }
 #endif
        return 0;
index 2ef8d50..1de3f9b 100644 (file)
@@ -604,6 +604,16 @@ static inline void nvme_trace_bio_complete(struct request *req,
                trace_block_bio_complete(ns->head->disk->queue, req->bio);
 }
 
+static inline void nvme_mpath_update_disk_size(struct gendisk *disk)
+{
+       struct block_device *bdev = bdget_disk(disk, 0);
+
+       if (bdev) {
+               bd_set_size(bdev, get_capacity(disk) << SECTOR_SHIFT);
+               bdput(bdev);
+       }
+}
+
 extern struct device_attribute dev_attr_ana_grpid;
 extern struct device_attribute dev_attr_ana_state;
 extern struct device_attribute subsys_attr_iopolicy;
@@ -679,6 +689,9 @@ static inline void nvme_mpath_wait_freeze(struct nvme_subsystem *subsys)
 static inline void nvme_mpath_start_freeze(struct nvme_subsystem *subsys)
 {
 }
+static inline void nvme_mpath_update_disk_size(struct gendisk *disk)
+{
+}
 #endif /* CONFIG_NVME_MULTIPATH */
 
 #ifdef CONFIG_NVM
index 9a58735..314f306 100644 (file)
@@ -902,6 +902,10 @@ static int _of_add_opp_table_v1(struct device *dev, struct opp_table *opp_table)
                return -EINVAL;
        }
 
+       mutex_lock(&opp_table->lock);
+       opp_table->parsed_static_opps = 1;
+       mutex_unlock(&opp_table->lock);
+
        val = prop->value;
        while (nr) {
                unsigned long freq = be32_to_cpup(val++) * 1000;
index 1b8e337..87c4be9 100644 (file)
@@ -1718,6 +1718,7 @@ static struct platform_driver cci_pmu_driver = {
        .driver = {
                   .name = DRIVER_NAME,
                   .of_match_table = arm_cci_pmu_matches,
+                  .suppress_bind_attrs = true,
                  },
        .probe = cci_pmu_probe,
        .remove = cci_pmu_remove,
index d50edef..7b7d23f 100644 (file)
@@ -1545,6 +1545,7 @@ static struct platform_driver arm_ccn_driver = {
        .driver = {
                .name = "arm-ccn",
                .of_match_table = arm_ccn_match,
+               .suppress_bind_attrs = true,
        },
        .probe = arm_ccn_probe,
        .remove = arm_ccn_remove,
index 518d060..96ed93c 100644 (file)
@@ -757,6 +757,7 @@ static struct platform_driver dsu_pmu_driver = {
        .driver = {
                .name   = DRVNAME,
                .of_match_table = of_match_ptr(dsu_pmu_of_match),
+               .suppress_bind_attrs = true,
        },
        .probe = dsu_pmu_device_probe,
        .remove = dsu_pmu_device_remove,
index 48e28ef..4cdb35d 100644 (file)
@@ -742,6 +742,7 @@ static int smmu_pmu_probe(struct platform_device *pdev)
        platform_set_drvdata(pdev, smmu_pmu);
 
        smmu_pmu->pmu = (struct pmu) {
+               .module         = THIS_MODULE,
                .task_ctx_nr    = perf_invalid_context,
                .pmu_enable     = smmu_pmu_enable,
                .pmu_disable    = smmu_pmu_disable,
@@ -859,6 +860,7 @@ static void smmu_pmu_shutdown(struct platform_device *pdev)
 static struct platform_driver smmu_pmu_driver = {
        .driver = {
                .name = "arm-smmu-v3-pmcg",
+               .suppress_bind_attrs = true,
        },
        .probe = smmu_pmu_probe,
        .remove = smmu_pmu_remove,
index d80f487..e51ddb6 100644 (file)
@@ -1226,6 +1226,7 @@ static struct platform_driver arm_spe_pmu_driver = {
        .driver = {
                .name           = DRVNAME,
                .of_match_table = of_match_ptr(arm_spe_pmu_of_match),
+               .suppress_bind_attrs = true,
        },
        .probe  = arm_spe_pmu_device_probe,
        .remove = arm_spe_pmu_device_remove,
index 90884d1..397540a 100644 (file)
@@ -512,6 +512,7 @@ static int ddr_perf_init(struct ddr_pmu *pmu, void __iomem *base,
 {
        *pmu = (struct ddr_pmu) {
                .pmu = (struct pmu) {
+                       .module       = THIS_MODULE,
                        .capabilities = PERF_PMU_CAP_NO_EXCLUDE,
                        .task_ctx_nr = perf_invalid_context,
                        .attr_groups = attr_groups,
@@ -706,6 +707,7 @@ static struct platform_driver imx_ddr_pmu_driver = {
        .driver         = {
                .name   = "imx-ddr-pmu",
                .of_match_table = imx_ddr_pmu_dt_ids,
+               .suppress_bind_attrs = true,
        },
        .probe          = ddr_perf_probe,
        .remove         = ddr_perf_remove,
index 15713fa..5e3645c 100644 (file)
@@ -378,6 +378,7 @@ static int hisi_ddrc_pmu_probe(struct platform_device *pdev)
                              ddrc_pmu->sccl_id, ddrc_pmu->index_id);
        ddrc_pmu->pmu = (struct pmu) {
                .name           = name,
+               .module         = THIS_MODULE,
                .task_ctx_nr    = perf_invalid_context,
                .event_init     = hisi_uncore_pmu_event_init,
                .pmu_enable     = hisi_uncore_pmu_enable,
@@ -418,6 +419,7 @@ static struct platform_driver hisi_ddrc_pmu_driver = {
        .driver = {
                .name = "hisi_ddrc_pmu",
                .acpi_match_table = ACPI_PTR(hisi_ddrc_pmu_acpi_match),
+               .suppress_bind_attrs = true,
        },
        .probe = hisi_ddrc_pmu_probe,
        .remove = hisi_ddrc_pmu_remove,
index dcc5600..5eb8168 100644 (file)
@@ -390,6 +390,7 @@ static int hisi_hha_pmu_probe(struct platform_device *pdev)
                              hha_pmu->sccl_id, hha_pmu->index_id);
        hha_pmu->pmu = (struct pmu) {
                .name           = name,
+               .module         = THIS_MODULE,
                .task_ctx_nr    = perf_invalid_context,
                .event_init     = hisi_uncore_pmu_event_init,
                .pmu_enable     = hisi_uncore_pmu_enable,
@@ -430,6 +431,7 @@ static struct platform_driver hisi_hha_pmu_driver = {
        .driver = {
                .name = "hisi_hha_pmu",
                .acpi_match_table = ACPI_PTR(hisi_hha_pmu_acpi_match),
+               .suppress_bind_attrs = true,
        },
        .probe = hisi_hha_pmu_probe,
        .remove = hisi_hha_pmu_remove,
index 7719ae4..3e8b5ea 100644 (file)
@@ -380,6 +380,7 @@ static int hisi_l3c_pmu_probe(struct platform_device *pdev)
                              l3c_pmu->sccl_id, l3c_pmu->index_id);
        l3c_pmu->pmu = (struct pmu) {
                .name           = name,
+               .module         = THIS_MODULE,
                .task_ctx_nr    = perf_invalid_context,
                .event_init     = hisi_uncore_pmu_event_init,
                .pmu_enable     = hisi_uncore_pmu_enable,
@@ -420,6 +421,7 @@ static struct platform_driver hisi_l3c_pmu_driver = {
        .driver = {
                .name = "hisi_l3c_pmu",
                .acpi_match_table = ACPI_PTR(hisi_l3c_pmu_acpi_match),
+               .suppress_bind_attrs = true,
        },
        .probe = hisi_l3c_pmu_probe,
        .remove = hisi_l3c_pmu_remove,
index 21d6991..4da37f6 100644 (file)
@@ -1028,6 +1028,7 @@ static struct platform_driver l2_cache_pmu_driver = {
        .driver = {
                .name = "qcom-l2cache-pmu",
                .acpi_match_table = ACPI_PTR(l2_cache_pmu_acpi_match),
+               .suppress_bind_attrs = true,
        },
        .probe = l2_cache_pmu_probe,
        .remove = l2_cache_pmu_remove,
index 656e830..9ddb577 100644 (file)
@@ -814,6 +814,7 @@ static struct platform_driver qcom_l3_cache_pmu_driver = {
        .driver = {
                .name = "qcom-l3cache-pmu",
                .acpi_match_table = ACPI_PTR(qcom_l3_cache_pmu_acpi_match),
+               .suppress_bind_attrs = true,
        },
        .probe = qcom_l3_cache_pmu_probe,
 };
index 51b31d6..aac9823 100644 (file)
@@ -1017,6 +1017,7 @@ static struct platform_driver tx2_uncore_driver = {
        .driver = {
                .name           = "tx2-uncore-pmu",
                .acpi_match_table = ACPI_PTR(tx2_uncore_acpi_match),
+               .suppress_bind_attrs = true,
        },
        .probe = tx2_uncore_probe,
        .remove = tx2_uncore_remove,
index 46ee680..edac28c 100644 (file)
@@ -1975,6 +1975,7 @@ static struct platform_driver xgene_pmu_driver = {
                .name           = "xgene-pmu",
                .of_match_table = xgene_pmu_of_match,
                .acpi_match_table = ACPI_PTR(xgene_pmu_acpi_match),
+               .suppress_bind_attrs = true,
        },
 };
 
index 8569273..e5842e4 100644 (file)
@@ -545,13 +545,14 @@ static void sun4i_usb_phy0_id_vbus_det_scan(struct work_struct *work)
        struct sun4i_usb_phy_data *data =
                container_of(work, struct sun4i_usb_phy_data, detect.work);
        struct phy *phy0 = data->phys[0].phy;
-       struct sun4i_usb_phy *phy = phy_get_drvdata(phy0);
+       struct sun4i_usb_phy *phy;
        bool force_session_end, id_notify = false, vbus_notify = false;
        int id_det, vbus_det;
 
-       if (phy0 == NULL)
+       if (!phy0)
                return;
 
+       phy = phy_get_drvdata(phy0);
        id_det = sun4i_usb_phy0_get_id_det(data);
        vbus_det = sun4i_usb_phy0_get_vbus_det(data);
 
index c2a35be..360b1eb 100644 (file)
@@ -134,7 +134,7 @@ static inline void combo_phy_w32_off_mask(void __iomem *base, unsigned int reg,
 
        reg_val = readl(base + reg);
        reg_val &= ~mask;
-       reg_val |= FIELD_PREP(mask, val);
+       reg_val |= val;
        writel(reg_val, base + reg);
 }
 
@@ -169,7 +169,7 @@ static int intel_cbphy_pcie_en_pad_refclk(struct intel_cbphy_iphy *iphy)
                return 0;
 
        combo_phy_w32_off_mask(cbphy->app_base, PCIE_PHY_GEN_CTRL,
-                              PCIE_PHY_CLK_PAD, 0);
+                              PCIE_PHY_CLK_PAD, FIELD_PREP(PCIE_PHY_CLK_PAD, 0));
 
        /* Delay for stable clock PLL */
        usleep_range(50, 100);
@@ -192,14 +192,14 @@ static int intel_cbphy_pcie_dis_pad_refclk(struct intel_cbphy_iphy *iphy)
                return 0;
 
        combo_phy_w32_off_mask(cbphy->app_base, PCIE_PHY_GEN_CTRL,
-                              PCIE_PHY_CLK_PAD, 1);
+                              PCIE_PHY_CLK_PAD, FIELD_PREP(PCIE_PHY_CLK_PAD, 1));
 
        return 0;
 }
 
 static int intel_cbphy_set_mode(struct intel_combo_phy *cbphy)
 {
-       enum intel_combo_mode cb_mode = PHY_PCIE_MODE;
+       enum intel_combo_mode cb_mode;
        enum aggregated_mode aggr = cbphy->aggr_mode;
        struct device *dev = cbphy->dev;
        enum intel_phy_mode mode;
@@ -224,6 +224,8 @@ static int intel_cbphy_set_mode(struct intel_combo_phy *cbphy)
 
                cb_mode = SATA0_SATA1_MODE;
                break;
+       default:
+               return -EINVAL;
        }
 
        ret = regmap_write(cbphy->hsiocfg, REG_COMBO_MODE(cbphy->bid), cb_mode);
@@ -385,7 +387,7 @@ static int intel_cbphy_calibrate(struct phy *phy)
 
        /* trigger auto RX adaptation */
        combo_phy_w32_off_mask(cr_base, CR_ADDR(PCS_XF_ATE_OVRD_IN_2, id),
-                              ADAPT_REQ_MSK, 3);
+                              ADAPT_REQ_MSK, FIELD_PREP(ADAPT_REQ_MSK, 3));
        /* Wait RX adaptation to finish */
        ret = readl_poll_timeout(cr_base + CR_ADDR(PCS_XF_RX_ADAPT_ACK, id),
                                 val, val & RX_ADAPT_ACK_BIT, 10, 5000);
@@ -396,7 +398,7 @@ static int intel_cbphy_calibrate(struct phy *phy)
 
        /* Stop RX adaptation */
        combo_phy_w32_off_mask(cr_base, CR_ADDR(PCS_XF_ATE_OVRD_IN_2, id),
-                              ADAPT_REQ_MSK, 0);
+                              ADAPT_REQ_MSK, FIELD_PREP(ADAPT_REQ_MSK, 0));
 
        return ret;
 }
index a7c6c94..8af8c6c 100644 (file)
@@ -607,8 +607,8 @@ static int inno_dsidphy_probe(struct platform_device *pdev)
        platform_set_drvdata(pdev, inno);
 
        inno->phy_base = devm_platform_ioremap_resource(pdev, 0);
-       if (!inno->phy_base)
-               return -ENOMEM;
+       if (IS_ERR(inno->phy_base))
+               return PTR_ERR(inno->phy_base);
 
        inno->ref_clk = devm_clk_get(dev, "ref");
        if (IS_ERR(inno->ref_clk)) {
index 0a166d5..a174b3c 100644 (file)
@@ -72,7 +72,7 @@ struct serdes_am654_clk_mux {
 #define to_serdes_am654_clk_mux(_hw)   \
                container_of(_hw, struct serdes_am654_clk_mux, hw)
 
-static struct regmap_config serdes_am654_regmap_config = {
+static const struct regmap_config serdes_am654_regmap_config = {
        .reg_bits = 32,
        .val_bits = 32,
        .reg_stride = 4,
index 30ea5b2..33c4cf0 100644 (file)
@@ -117,7 +117,7 @@ struct wiz_clk_mux {
 struct wiz_clk_divider {
        struct clk_hw           hw;
        struct regmap_field     *field;
-       struct clk_div_table    *table;
+       const struct clk_div_table      *table;
        struct clk_init_data    clk_data;
 };
 
@@ -131,7 +131,7 @@ struct wiz_clk_mux_sel {
 
 struct wiz_clk_div_sel {
        struct regmap_field     *field;
-       struct clk_div_table    *table;
+       const struct clk_div_table      *table;
        const char              *node_name;
 };
 
@@ -173,7 +173,7 @@ static struct wiz_clk_mux_sel clk_mux_sel_10g[] = {
        },
 };
 
-static struct clk_div_table clk_div_table[] = {
+static const struct clk_div_table clk_div_table[] = {
        { .val = 0, .div = 1, },
        { .val = 1, .div = 2, },
        { .val = 2, .div = 4, },
@@ -559,7 +559,7 @@ static const struct clk_ops wiz_clk_div_ops = {
 
 static int wiz_div_clk_register(struct wiz *wiz, struct device_node *node,
                                struct regmap_field *field,
-                               struct clk_div_table *table)
+                               const struct clk_div_table *table)
 {
        struct device *dev = wiz->dev;
        struct wiz_clk_divider *div;
@@ -756,7 +756,7 @@ static const struct reset_control_ops wiz_phy_reset_ops = {
        .deassert = wiz_phy_reset_deassert,
 };
 
-static struct regmap_config wiz_regmap_config = {
+static const struct regmap_config wiz_regmap_config = {
        .reg_bits = 32,
        .val_bits = 32,
        .reg_stride = 4,
index 877aade..8f4acdc 100644 (file)
@@ -441,6 +441,7 @@ static int asus_wmi_battery_add(struct power_supply *battery)
         * battery is named BATT.
         */
        if (strcmp(battery->desc->name, "BAT0") != 0 &&
+           strcmp(battery->desc->name, "BAT1") != 0 &&
            strcmp(battery->desc->name, "BATT") != 0)
                return -ENODEV;
 
index 1409a5b..4f6f7f0 100644 (file)
@@ -13,6 +13,9 @@
 #define INTEL_RAPL_PRIO_DEVID_0        0x3451
 #define INTEL_CFG_MBOX_DEVID_0 0x3459
 
+#define INTEL_RAPL_PRIO_DEVID_1 0x3251
+#define INTEL_CFG_MBOX_DEVID_1  0x3259
+
 /*
  * Validate maximum commands in a single request.
  * This is enough to handle command to every core in one ioctl, or all
index d84e217..95f01e7 100644 (file)
@@ -147,6 +147,7 @@ static long isst_if_mbox_proc_cmd(u8 *cmd_ptr, int *write_only, int resume)
 
 static const struct pci_device_id isst_if_mbox_ids[] = {
        { PCI_DEVICE(PCI_VENDOR_ID_INTEL, INTEL_CFG_MBOX_DEVID_0)},
+       { PCI_DEVICE(PCI_VENDOR_ID_INTEL, INTEL_CFG_MBOX_DEVID_1)},
        { 0 },
 };
 MODULE_DEVICE_TABLE(pci, isst_if_mbox_ids);
index 3584859..aa17fd7 100644 (file)
@@ -72,6 +72,7 @@ static long isst_if_mmio_rd_wr(u8 *cmd_ptr, int *write_only, int resume)
 
 static const struct pci_device_id isst_if_ids[] = {
        { PCI_DEVICE(PCI_VENDOR_ID_INTEL, INTEL_RAPL_PRIO_DEVID_0)},
+       { PCI_DEVICE(PCI_VENDOR_ID_INTEL, INTEL_RAPL_PRIO_DEVID_1)},
        { 0 },
 };
 MODULE_DEVICE_TABLE(pci, isst_if_ids);
index ff7f0a4..0f6fced 100644 (file)
@@ -885,11 +885,19 @@ static ssize_t dispatch_proc_write(struct file *file,
 
        if (!ibm || !ibm->write)
                return -EINVAL;
+       if (count > PAGE_SIZE - 1)
+               return -EINVAL;
+
+       kernbuf = kmalloc(count + 1, GFP_KERNEL);
+       if (!kernbuf)
+               return -ENOMEM;
 
-       kernbuf = strndup_user(userbuf, PAGE_SIZE);
-       if (IS_ERR(kernbuf))
-               return PTR_ERR(kernbuf);
+       if (copy_from_user(kernbuf, userbuf, count)) {
+               kfree(kernbuf);
+               return -EFAULT;
+       }
 
+       kernbuf[count] = 0;
        ret = ibm->write(kernbuf);
        if (ret == 0)
                ret = count;
index e8f1633..0796e4a 100644 (file)
@@ -31,7 +31,7 @@ obj-$(CONFIG_REGULATOR_BD70528) += bd70528-regulator.o
 obj-$(CONFIG_REGULATOR_BD71828) += bd71828-regulator.o
 obj-$(CONFIG_REGULATOR_BD718XX) += bd718x7-regulator.o
 obj-$(CONFIG_REGULATOR_BD9571MWV) += bd9571mwv-regulator.o
-obj-$(CONFIG_REGULATOR_DA903X) += da903x.o
+obj-$(CONFIG_REGULATOR_DA903X) += da903x-regulator.o
 obj-$(CONFIG_REGULATOR_DA9052) += da9052-regulator.o
 obj-$(CONFIG_REGULATOR_DA9055) += da9055-regulator.o
 obj-$(CONFIG_REGULATOR_DA9062) += da9062-regulator.o
diff --git a/drivers/regulator/da903x-regulator.c b/drivers/regulator/da903x-regulator.c
new file mode 100644 (file)
index 0000000..770e694
--- /dev/null
@@ -0,0 +1,494 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Regulators driver for Dialog Semiconductor DA903x
+//
+// Copyright (C) 2006-2008 Marvell International Ltd.
+// Copyright (C) 2008 Compulab Ltd.
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/err.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/machine.h>
+#include <linux/mfd/da903x.h>
+
+/* DA9030 Registers */
+#define DA9030_INVAL           (-1)
+#define DA9030_LDO1011         (0x10)
+#define DA9030_LDO15           (0x11)
+#define DA9030_LDO1416         (0x12)
+#define DA9030_LDO1819         (0x13)
+#define DA9030_LDO17           (0x14)
+#define DA9030_BUCK2DVM1       (0x15)
+#define DA9030_BUCK2DVM2       (0x16)
+#define DA9030_RCTL11          (0x17)
+#define DA9030_RCTL21          (0x18)
+#define DA9030_LDO1            (0x90)
+#define DA9030_LDO23           (0x91)
+#define DA9030_LDO45           (0x92)
+#define DA9030_LDO6            (0x93)
+#define DA9030_LDO78           (0x94)
+#define DA9030_LDO912          (0x95)
+#define DA9030_BUCK            (0x96)
+#define DA9030_RCTL12          (0x97)
+#define DA9030_RCTL22          (0x98)
+#define DA9030_LDO_UNLOCK      (0xa0)
+#define DA9030_LDO_UNLOCK_MASK (0xe0)
+#define DA9034_OVER1           (0x10)
+
+/* DA9034 Registers */
+#define DA9034_INVAL           (-1)
+#define DA9034_OVER2           (0x11)
+#define DA9034_OVER3           (0x12)
+#define DA9034_LDO643          (0x13)
+#define DA9034_LDO987          (0x14)
+#define DA9034_LDO1110         (0x15)
+#define DA9034_LDO1312         (0x16)
+#define DA9034_LDO1514         (0x17)
+#define DA9034_VCC1            (0x20)
+#define DA9034_ADTV1           (0x23)
+#define DA9034_ADTV2           (0x24)
+#define DA9034_AVRC            (0x25)
+#define DA9034_CDTV1           (0x26)
+#define DA9034_CDTV2           (0x27)
+#define DA9034_CVRC            (0x28)
+#define DA9034_SDTV1           (0x29)
+#define DA9034_SDTV2           (0x2a)
+#define DA9034_SVRC            (0x2b)
+#define DA9034_MDTV1           (0x32)
+#define DA9034_MDTV2           (0x33)
+#define DA9034_MVRC            (0x34)
+
+/* DA9035 Registers. DA9034 Registers are comptabile to DA9035. */
+#define DA9035_OVER3           (0x12)
+#define DA9035_VCC2            (0x1f)
+#define DA9035_3DTV1           (0x2c)
+#define DA9035_3DTV2           (0x2d)
+#define DA9035_3VRC            (0x2e)
+#define DA9035_AUTOSKIP                (0x2f)
+
+struct da903x_regulator_info {
+       struct regulator_desc desc;
+
+       int     max_uV;
+       int     vol_reg;
+       int     vol_shift;
+       int     vol_nbits;
+       int     update_reg;
+       int     update_bit;
+       int     enable_reg;
+       int     enable_bit;
+};
+
+static inline struct device *to_da903x_dev(struct regulator_dev *rdev)
+{
+       return rdev_get_dev(rdev)->parent->parent;
+}
+
+static inline int check_range(struct da903x_regulator_info *info,
+                               int min_uV, int max_uV)
+{
+       if (min_uV < info->desc.min_uV || min_uV > info->max_uV)
+               return -EINVAL;
+
+       return 0;
+}
+
+/* DA9030/DA9034 common operations */
+static int da903x_set_voltage_sel(struct regulator_dev *rdev, unsigned selector)
+{
+       struct da903x_regulator_info *info = rdev_get_drvdata(rdev);
+       struct device *da9034_dev = to_da903x_dev(rdev);
+       uint8_t val, mask;
+
+       if (rdev->desc->n_voltages == 1)
+               return -EINVAL;
+
+       val = selector << info->vol_shift;
+       mask = ((1 << info->vol_nbits) - 1)  << info->vol_shift;
+
+       return da903x_update(da9034_dev, info->vol_reg, val, mask);
+}
+
+static int da903x_get_voltage_sel(struct regulator_dev *rdev)
+{
+       struct da903x_regulator_info *info = rdev_get_drvdata(rdev);
+       struct device *da9034_dev = to_da903x_dev(rdev);
+       uint8_t val, mask;
+       int ret;
+
+       if (rdev->desc->n_voltages == 1)
+               return 0;
+
+       ret = da903x_read(da9034_dev, info->vol_reg, &val);
+       if (ret)
+               return ret;
+
+       mask = ((1 << info->vol_nbits) - 1)  << info->vol_shift;
+       val = (val & mask) >> info->vol_shift;
+
+       return val;
+}
+
+static int da903x_enable(struct regulator_dev *rdev)
+{
+       struct da903x_regulator_info *info = rdev_get_drvdata(rdev);
+       struct device *da9034_dev = to_da903x_dev(rdev);
+
+       return da903x_set_bits(da9034_dev, info->enable_reg,
+                                       1 << info->enable_bit);
+}
+
+static int da903x_disable(struct regulator_dev *rdev)
+{
+       struct da903x_regulator_info *info = rdev_get_drvdata(rdev);
+       struct device *da9034_dev = to_da903x_dev(rdev);
+
+       return da903x_clr_bits(da9034_dev, info->enable_reg,
+                                       1 << info->enable_bit);
+}
+
+static int da903x_is_enabled(struct regulator_dev *rdev)
+{
+       struct da903x_regulator_info *info = rdev_get_drvdata(rdev);
+       struct device *da9034_dev = to_da903x_dev(rdev);
+       uint8_t reg_val;
+       int ret;
+
+       ret = da903x_read(da9034_dev, info->enable_reg, &reg_val);
+       if (ret)
+               return ret;
+
+       return !!(reg_val & (1 << info->enable_bit));
+}
+
+/* DA9030 specific operations */
+static int da9030_set_ldo1_15_voltage_sel(struct regulator_dev *rdev,
+                                         unsigned selector)
+{
+       struct da903x_regulator_info *info = rdev_get_drvdata(rdev);
+       struct device *da903x_dev = to_da903x_dev(rdev);
+       uint8_t val, mask;
+       int ret;
+
+       val = selector << info->vol_shift;
+       mask = ((1 << info->vol_nbits) - 1)  << info->vol_shift;
+       val |= DA9030_LDO_UNLOCK; /* have to set UNLOCK bits */
+       mask |= DA9030_LDO_UNLOCK_MASK;
+
+       /* write twice */
+       ret = da903x_update(da903x_dev, info->vol_reg, val, mask);
+       if (ret)
+               return ret;
+
+       return da903x_update(da903x_dev, info->vol_reg, val, mask);
+}
+
+static int da9030_map_ldo14_voltage(struct regulator_dev *rdev,
+                                   int min_uV, int max_uV)
+{
+       struct da903x_regulator_info *info = rdev_get_drvdata(rdev);
+       int thresh, sel;
+
+       if (check_range(info, min_uV, max_uV)) {
+               pr_err("invalid voltage range (%d, %d) uV\n", min_uV, max_uV);
+               return -EINVAL;
+       }
+
+       thresh = (info->max_uV + info->desc.min_uV) / 2;
+       if (min_uV < thresh) {
+               sel = DIV_ROUND_UP(thresh - min_uV, info->desc.uV_step);
+               sel |= 0x4;
+       } else {
+               sel = DIV_ROUND_UP(min_uV - thresh, info->desc.uV_step);
+       }
+
+       return sel;
+}
+
+static int da9030_list_ldo14_voltage(struct regulator_dev *rdev,
+                                    unsigned selector)
+{
+       struct da903x_regulator_info *info = rdev_get_drvdata(rdev);
+       int volt;
+
+       if (selector & 0x4)
+               volt = rdev->desc->min_uV +
+                      rdev->desc->uV_step * (3 - (selector & ~0x4));
+       else
+               volt = (info->max_uV + rdev->desc->min_uV) / 2 +
+                      rdev->desc->uV_step * (selector & ~0x4);
+
+       if (volt > info->max_uV)
+               return -EINVAL;
+
+       return volt;
+}
+
+/* DA9034 specific operations */
+static int da9034_set_dvc_voltage_sel(struct regulator_dev *rdev,
+                                     unsigned selector)
+{
+       struct da903x_regulator_info *info = rdev_get_drvdata(rdev);
+       struct device *da9034_dev = to_da903x_dev(rdev);
+       uint8_t val, mask;
+       int ret;
+
+       val = selector << info->vol_shift;
+       mask = ((1 << info->vol_nbits) - 1)  << info->vol_shift;
+
+       ret = da903x_update(da9034_dev, info->vol_reg, val, mask);
+       if (ret)
+               return ret;
+
+       ret = da903x_set_bits(da9034_dev, info->update_reg,
+                                       1 << info->update_bit);
+       return ret;
+}
+
+static const struct linear_range da9034_ldo12_ranges[] = {
+       REGULATOR_LINEAR_RANGE(1700000, 0, 7, 50000),
+       REGULATOR_LINEAR_RANGE(2700000, 8, 15, 50000),
+};
+
+static const struct regulator_ops da903x_regulator_ldo_ops = {
+       .set_voltage_sel = da903x_set_voltage_sel,
+       .get_voltage_sel = da903x_get_voltage_sel,
+       .list_voltage   = regulator_list_voltage_linear,
+       .map_voltage    = regulator_map_voltage_linear,
+       .enable         = da903x_enable,
+       .disable        = da903x_disable,
+       .is_enabled     = da903x_is_enabled,
+};
+
+/* NOTE: this is dedicated for the insane DA9030 LDO14 */
+static const struct regulator_ops da9030_regulator_ldo14_ops = {
+       .set_voltage_sel = da903x_set_voltage_sel,
+       .get_voltage_sel = da903x_get_voltage_sel,
+       .list_voltage   = da9030_list_ldo14_voltage,
+       .map_voltage    = da9030_map_ldo14_voltage,
+       .enable         = da903x_enable,
+       .disable        = da903x_disable,
+       .is_enabled     = da903x_is_enabled,
+};
+
+/* NOTE: this is dedicated for the DA9030 LDO1 and LDO15 that have locks  */
+static const struct regulator_ops da9030_regulator_ldo1_15_ops = {
+       .set_voltage_sel = da9030_set_ldo1_15_voltage_sel,
+       .get_voltage_sel = da903x_get_voltage_sel,
+       .list_voltage   = regulator_list_voltage_linear,
+       .map_voltage    = regulator_map_voltage_linear,
+       .enable         = da903x_enable,
+       .disable        = da903x_disable,
+       .is_enabled     = da903x_is_enabled,
+};
+
+static const struct regulator_ops da9034_regulator_dvc_ops = {
+       .set_voltage_sel = da9034_set_dvc_voltage_sel,
+       .get_voltage_sel = da903x_get_voltage_sel,
+       .list_voltage   = regulator_list_voltage_linear,
+       .map_voltage    = regulator_map_voltage_linear,
+       .enable         = da903x_enable,
+       .disable        = da903x_disable,
+       .is_enabled     = da903x_is_enabled,
+};
+
+/* NOTE: this is dedicated for the insane LDO12 */
+static const struct regulator_ops da9034_regulator_ldo12_ops = {
+       .set_voltage_sel = da903x_set_voltage_sel,
+       .get_voltage_sel = da903x_get_voltage_sel,
+       .list_voltage   = regulator_list_voltage_linear_range,
+       .map_voltage    = regulator_map_voltage_linear_range,
+       .enable         = da903x_enable,
+       .disable        = da903x_disable,
+       .is_enabled     = da903x_is_enabled,
+};
+
+#define DA903x_LDO(_pmic, _id, min, max, step, vreg, shift, nbits, ereg, ebit) \
+{                                                                      \
+       .desc   = {                                                     \
+               .name   = "LDO" #_id,                                   \
+               .ops    = &da903x_regulator_ldo_ops,                    \
+               .type   = REGULATOR_VOLTAGE,                            \
+               .id     = _pmic##_ID_LDO##_id,                          \
+               .n_voltages = (step) ? ((max - min) / step + 1) : 1,    \
+               .owner  = THIS_MODULE,                                  \
+               .min_uV  = (min) * 1000,                                \
+               .uV_step = (step) * 1000,                               \
+       },                                                              \
+       .max_uV         = (max) * 1000,                                 \
+       .vol_reg        = _pmic##_##vreg,                               \
+       .vol_shift      = (shift),                                      \
+       .vol_nbits      = (nbits),                                      \
+       .enable_reg     = _pmic##_##ereg,                               \
+       .enable_bit     = (ebit),                                       \
+}
+
+#define DA903x_DVC(_pmic, _id, min, max, step, vreg, nbits, ureg, ubit, ereg, ebit) \
+{                                                                      \
+       .desc   = {                                                     \
+               .name   = #_id,                                         \
+               .ops    = &da9034_regulator_dvc_ops,                    \
+               .type   = REGULATOR_VOLTAGE,                            \
+               .id     = _pmic##_ID_##_id,                             \
+               .n_voltages = (step) ? ((max - min) / step + 1) : 1,    \
+               .owner  = THIS_MODULE,                                  \
+               .min_uV = (min) * 1000,                                 \
+               .uV_step = (step) * 1000,                               \
+       },                                                              \
+       .max_uV         = (max) * 1000,                                 \
+       .vol_reg        = _pmic##_##vreg,                               \
+       .vol_shift      = (0),                                          \
+       .vol_nbits      = (nbits),                                      \
+       .update_reg     = _pmic##_##ureg,                               \
+       .update_bit     = (ubit),                                       \
+       .enable_reg     = _pmic##_##ereg,                               \
+       .enable_bit     = (ebit),                                       \
+}
+
+#define DA9034_LDO(_id, min, max, step, vreg, shift, nbits, ereg, ebit)        \
+       DA903x_LDO(DA9034, _id, min, max, step, vreg, shift, nbits, ereg, ebit)
+
+#define DA9030_LDO(_id, min, max, step, vreg, shift, nbits, ereg, ebit)        \
+       DA903x_LDO(DA9030, _id, min, max, step, vreg, shift, nbits, ereg, ebit)
+
+#define DA9030_DVC(_id, min, max, step, vreg, nbits, ureg, ubit, ereg, ebit) \
+       DA903x_DVC(DA9030, _id, min, max, step, vreg, nbits, ureg, ubit, \
+                  ereg, ebit)
+
+#define DA9034_DVC(_id, min, max, step, vreg, nbits, ureg, ubit, ereg, ebit) \
+       DA903x_DVC(DA9034, _id, min, max, step, vreg, nbits, ureg, ubit, \
+                  ereg, ebit)
+
+#define DA9035_DVC(_id, min, max, step, vreg, nbits, ureg, ubit, ereg, ebit) \
+       DA903x_DVC(DA9035, _id, min, max, step, vreg, nbits, ureg, ubit, \
+                  ereg, ebit)
+
+static struct da903x_regulator_info da903x_regulator_info[] = {
+       /* DA9030 */
+       DA9030_DVC(BUCK2, 850, 1625, 25, BUCK2DVM1, 5, BUCK2DVM1, 7, RCTL11, 0),
+
+       DA9030_LDO( 1, 1200, 3200, 100,    LDO1, 0, 5, RCTL12, 1),
+       DA9030_LDO( 2, 1800, 3200, 100,   LDO23, 0, 4, RCTL12, 2),
+       DA9030_LDO( 3, 1800, 3200, 100,   LDO23, 4, 4, RCTL12, 3),
+       DA9030_LDO( 4, 1800, 3200, 100,   LDO45, 0, 4, RCTL12, 4),
+       DA9030_LDO( 5, 1800, 3200, 100,   LDO45, 4, 4, RCTL12, 5),
+       DA9030_LDO( 6, 1800, 3200, 100,    LDO6, 0, 4, RCTL12, 6),
+       DA9030_LDO( 7, 1800, 3200, 100,   LDO78, 0, 4, RCTL12, 7),
+       DA9030_LDO( 8, 1800, 3200, 100,   LDO78, 4, 4, RCTL22, 0),
+       DA9030_LDO( 9, 1800, 3200, 100,  LDO912, 0, 4, RCTL22, 1),
+       DA9030_LDO(10, 1800, 3200, 100, LDO1011, 0, 4, RCTL22, 2),
+       DA9030_LDO(11, 1800, 3200, 100, LDO1011, 4, 4, RCTL22, 3),
+       DA9030_LDO(12, 1800, 3200, 100,  LDO912, 4, 4, RCTL22, 4),
+       DA9030_LDO(14, 2760, 2940,  30, LDO1416, 0, 3, RCTL11, 4),
+       DA9030_LDO(15, 1100, 2650,  50,   LDO15, 0, 5, RCTL11, 5),
+       DA9030_LDO(16, 1100, 2650,  50, LDO1416, 3, 5, RCTL11, 6),
+       DA9030_LDO(17, 1800, 3200, 100,   LDO17, 0, 4, RCTL11, 7),
+       DA9030_LDO(18, 1800, 3200, 100, LDO1819, 0, 4, RCTL21, 2),
+       DA9030_LDO(19, 1800, 3200, 100, LDO1819, 4, 4, RCTL21, 1),
+       DA9030_LDO(13, 2100, 2100, 0, INVAL, 0, 0, RCTL11, 3), /* fixed @2.1V */
+
+       /* DA9034 */
+       DA9034_DVC(BUCK1, 725, 1500, 25, ADTV2, 5, VCC1, 0, OVER1, 0),
+       DA9034_DVC(BUCK2, 725, 1500, 25, CDTV2, 5, VCC1, 2, OVER1, 1),
+       DA9034_DVC(LDO2,  725, 1500, 25, SDTV2, 5, VCC1, 4, OVER1, 2),
+       DA9034_DVC(LDO1, 1700, 2075, 25, MDTV1, 4, VCC1, 6, OVER3, 4),
+
+       DA9034_LDO( 3, 1800, 3300, 100,  LDO643, 0, 4, OVER3, 5),
+       DA9034_LDO( 4, 1800, 2900,1100,  LDO643, 4, 1, OVER3, 6),
+       DA9034_LDO( 6, 2500, 2850,  50,  LDO643, 5, 3, OVER2, 0),
+       DA9034_LDO( 7, 2700, 3050,  50,  LDO987, 0, 3, OVER2, 1),
+       DA9034_LDO( 8, 2700, 2850,  50,  LDO987, 3, 2, OVER2, 2),
+       DA9034_LDO( 9, 2700, 3050,  50,  LDO987, 5, 3, OVER2, 3),
+       DA9034_LDO(10, 2700, 3050,  50, LDO1110, 0, 3, OVER2, 4),
+       DA9034_LDO(11, 1800, 3300, 100, LDO1110, 4, 4, OVER2, 5),
+       DA9034_LDO(12, 1700, 3050,  50, LDO1312, 0, 4, OVER3, 6),
+       DA9034_LDO(13, 1800, 3300, 100, LDO1312, 4, 4, OVER2, 7),
+       DA9034_LDO(14, 1800, 3300, 100, LDO1514, 0, 4, OVER3, 0),
+       DA9034_LDO(15, 1800, 3300, 100, LDO1514, 4, 4, OVER3, 1),
+       DA9034_LDO(5, 3100, 3100, 0, INVAL, 0, 0, OVER3, 7), /* fixed @3.1V */
+
+       /* DA9035 */
+       DA9035_DVC(BUCK3, 1800, 2200, 100, 3DTV1, 3, VCC2, 0, OVER3, 3),
+};
+
+static inline struct da903x_regulator_info *find_regulator_info(int id)
+{
+       struct da903x_regulator_info *ri;
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(da903x_regulator_info); i++) {
+               ri = &da903x_regulator_info[i];
+               if (ri->desc.id == id)
+                       return ri;
+       }
+       return NULL;
+}
+
+static int da903x_regulator_probe(struct platform_device *pdev)
+{
+       struct da903x_regulator_info *ri = NULL;
+       struct regulator_dev *rdev;
+       struct regulator_config config = { };
+
+       ri = find_regulator_info(pdev->id);
+       if (ri == NULL) {
+               dev_err(&pdev->dev, "invalid regulator ID specified\n");
+               return -EINVAL;
+       }
+
+       /* Workaround for the weird LDO12 voltage setting */
+       if (ri->desc.id == DA9034_ID_LDO12) {
+               ri->desc.ops = &da9034_regulator_ldo12_ops;
+               ri->desc.n_voltages = 16;
+               ri->desc.linear_ranges = da9034_ldo12_ranges;
+               ri->desc.n_linear_ranges = ARRAY_SIZE(da9034_ldo12_ranges);
+       }
+
+       if (ri->desc.id == DA9030_ID_LDO14)
+               ri->desc.ops = &da9030_regulator_ldo14_ops;
+
+       if (ri->desc.id == DA9030_ID_LDO1 || ri->desc.id == DA9030_ID_LDO15)
+               ri->desc.ops = &da9030_regulator_ldo1_15_ops;
+
+       config.dev = &pdev->dev;
+       config.init_data = dev_get_platdata(&pdev->dev);
+       config.driver_data = ri;
+
+       rdev = devm_regulator_register(&pdev->dev, &ri->desc, &config);
+       if (IS_ERR(rdev)) {
+               dev_err(&pdev->dev, "failed to register regulator %s\n",
+                               ri->desc.name);
+               return PTR_ERR(rdev);
+       }
+
+       platform_set_drvdata(pdev, rdev);
+       return 0;
+}
+
+static struct platform_driver da903x_regulator_driver = {
+       .driver = {
+               .name   = "da903x-regulator",
+       },
+       .probe          = da903x_regulator_probe,
+};
+
+static int __init da903x_regulator_init(void)
+{
+       return platform_driver_register(&da903x_regulator_driver);
+}
+subsys_initcall(da903x_regulator_init);
+
+static void __exit da903x_regulator_exit(void)
+{
+       platform_driver_unregister(&da903x_regulator_driver);
+}
+module_exit(da903x_regulator_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Eric Miao <eric.miao@marvell.com>"
+             "Mike Rapoport <mike@compulab.co.il>");
+MODULE_DESCRIPTION("Regulator Driver for Dialog Semiconductor DA903X PMIC");
+MODULE_ALIAS("platform:da903x-regulator");
diff --git a/drivers/regulator/da903x.c b/drivers/regulator/da903x.c
deleted file mode 100644 (file)
index 770e694..0000000
+++ /dev/null
@@ -1,494 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-//
-// Regulators driver for Dialog Semiconductor DA903x
-//
-// Copyright (C) 2006-2008 Marvell International Ltd.
-// Copyright (C) 2008 Compulab Ltd.
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/err.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/regulator/driver.h>
-#include <linux/regulator/machine.h>
-#include <linux/mfd/da903x.h>
-
-/* DA9030 Registers */
-#define DA9030_INVAL           (-1)
-#define DA9030_LDO1011         (0x10)
-#define DA9030_LDO15           (0x11)
-#define DA9030_LDO1416         (0x12)
-#define DA9030_LDO1819         (0x13)
-#define DA9030_LDO17           (0x14)
-#define DA9030_BUCK2DVM1       (0x15)
-#define DA9030_BUCK2DVM2       (0x16)
-#define DA9030_RCTL11          (0x17)
-#define DA9030_RCTL21          (0x18)
-#define DA9030_LDO1            (0x90)
-#define DA9030_LDO23           (0x91)
-#define DA9030_LDO45           (0x92)
-#define DA9030_LDO6            (0x93)
-#define DA9030_LDO78           (0x94)
-#define DA9030_LDO912          (0x95)
-#define DA9030_BUCK            (0x96)
-#define DA9030_RCTL12          (0x97)
-#define DA9030_RCTL22          (0x98)
-#define DA9030_LDO_UNLOCK      (0xa0)
-#define DA9030_LDO_UNLOCK_MASK (0xe0)
-#define DA9034_OVER1           (0x10)
-
-/* DA9034 Registers */
-#define DA9034_INVAL           (-1)
-#define DA9034_OVER2           (0x11)
-#define DA9034_OVER3           (0x12)
-#define DA9034_LDO643          (0x13)
-#define DA9034_LDO987          (0x14)
-#define DA9034_LDO1110         (0x15)
-#define DA9034_LDO1312         (0x16)
-#define DA9034_LDO1514         (0x17)
-#define DA9034_VCC1            (0x20)
-#define DA9034_ADTV1           (0x23)
-#define DA9034_ADTV2           (0x24)
-#define DA9034_AVRC            (0x25)
-#define DA9034_CDTV1           (0x26)
-#define DA9034_CDTV2           (0x27)
-#define DA9034_CVRC            (0x28)
-#define DA9034_SDTV1           (0x29)
-#define DA9034_SDTV2           (0x2a)
-#define DA9034_SVRC            (0x2b)
-#define DA9034_MDTV1           (0x32)
-#define DA9034_MDTV2           (0x33)
-#define DA9034_MVRC            (0x34)
-
-/* DA9035 Registers. DA9034 Registers are comptabile to DA9035. */
-#define DA9035_OVER3           (0x12)
-#define DA9035_VCC2            (0x1f)
-#define DA9035_3DTV1           (0x2c)
-#define DA9035_3DTV2           (0x2d)
-#define DA9035_3VRC            (0x2e)
-#define DA9035_AUTOSKIP                (0x2f)
-
-struct da903x_regulator_info {
-       struct regulator_desc desc;
-
-       int     max_uV;
-       int     vol_reg;
-       int     vol_shift;
-       int     vol_nbits;
-       int     update_reg;
-       int     update_bit;
-       int     enable_reg;
-       int     enable_bit;
-};
-
-static inline struct device *to_da903x_dev(struct regulator_dev *rdev)
-{
-       return rdev_get_dev(rdev)->parent->parent;
-}
-
-static inline int check_range(struct da903x_regulator_info *info,
-                               int min_uV, int max_uV)
-{
-       if (min_uV < info->desc.min_uV || min_uV > info->max_uV)
-               return -EINVAL;
-
-       return 0;
-}
-
-/* DA9030/DA9034 common operations */
-static int da903x_set_voltage_sel(struct regulator_dev *rdev, unsigned selector)
-{
-       struct da903x_regulator_info *info = rdev_get_drvdata(rdev);
-       struct device *da9034_dev = to_da903x_dev(rdev);
-       uint8_t val, mask;
-
-       if (rdev->desc->n_voltages == 1)
-               return -EINVAL;
-
-       val = selector << info->vol_shift;
-       mask = ((1 << info->vol_nbits) - 1)  << info->vol_shift;
-
-       return da903x_update(da9034_dev, info->vol_reg, val, mask);
-}
-
-static int da903x_get_voltage_sel(struct regulator_dev *rdev)
-{
-       struct da903x_regulator_info *info = rdev_get_drvdata(rdev);
-       struct device *da9034_dev = to_da903x_dev(rdev);
-       uint8_t val, mask;
-       int ret;
-
-       if (rdev->desc->n_voltages == 1)
-               return 0;
-
-       ret = da903x_read(da9034_dev, info->vol_reg, &val);
-       if (ret)
-               return ret;
-
-       mask = ((1 << info->vol_nbits) - 1)  << info->vol_shift;
-       val = (val & mask) >> info->vol_shift;
-
-       return val;
-}
-
-static int da903x_enable(struct regulator_dev *rdev)
-{
-       struct da903x_regulator_info *info = rdev_get_drvdata(rdev);
-       struct device *da9034_dev = to_da903x_dev(rdev);
-
-       return da903x_set_bits(da9034_dev, info->enable_reg,
-                                       1 << info->enable_bit);
-}
-
-static int da903x_disable(struct regulator_dev *rdev)
-{
-       struct da903x_regulator_info *info = rdev_get_drvdata(rdev);
-       struct device *da9034_dev = to_da903x_dev(rdev);
-
-       return da903x_clr_bits(da9034_dev, info->enable_reg,
-                                       1 << info->enable_bit);
-}
-
-static int da903x_is_enabled(struct regulator_dev *rdev)
-{
-       struct da903x_regulator_info *info = rdev_get_drvdata(rdev);
-       struct device *da9034_dev = to_da903x_dev(rdev);
-       uint8_t reg_val;
-       int ret;
-
-       ret = da903x_read(da9034_dev, info->enable_reg, &reg_val);
-       if (ret)
-               return ret;
-
-       return !!(reg_val & (1 << info->enable_bit));
-}
-
-/* DA9030 specific operations */
-static int da9030_set_ldo1_15_voltage_sel(struct regulator_dev *rdev,
-                                         unsigned selector)
-{
-       struct da903x_regulator_info *info = rdev_get_drvdata(rdev);
-       struct device *da903x_dev = to_da903x_dev(rdev);
-       uint8_t val, mask;
-       int ret;
-
-       val = selector << info->vol_shift;
-       mask = ((1 << info->vol_nbits) - 1)  << info->vol_shift;
-       val |= DA9030_LDO_UNLOCK; /* have to set UNLOCK bits */
-       mask |= DA9030_LDO_UNLOCK_MASK;
-
-       /* write twice */
-       ret = da903x_update(da903x_dev, info->vol_reg, val, mask);
-       if (ret)
-               return ret;
-
-       return da903x_update(da903x_dev, info->vol_reg, val, mask);
-}
-
-static int da9030_map_ldo14_voltage(struct regulator_dev *rdev,
-                                   int min_uV, int max_uV)
-{
-       struct da903x_regulator_info *info = rdev_get_drvdata(rdev);
-       int thresh, sel;
-
-       if (check_range(info, min_uV, max_uV)) {
-               pr_err("invalid voltage range (%d, %d) uV\n", min_uV, max_uV);
-               return -EINVAL;
-       }
-
-       thresh = (info->max_uV + info->desc.min_uV) / 2;
-       if (min_uV < thresh) {
-               sel = DIV_ROUND_UP(thresh - min_uV, info->desc.uV_step);
-               sel |= 0x4;
-       } else {
-               sel = DIV_ROUND_UP(min_uV - thresh, info->desc.uV_step);
-       }
-
-       return sel;
-}
-
-static int da9030_list_ldo14_voltage(struct regulator_dev *rdev,
-                                    unsigned selector)
-{
-       struct da903x_regulator_info *info = rdev_get_drvdata(rdev);
-       int volt;
-
-       if (selector & 0x4)
-               volt = rdev->desc->min_uV +
-                      rdev->desc->uV_step * (3 - (selector & ~0x4));
-       else
-               volt = (info->max_uV + rdev->desc->min_uV) / 2 +
-                      rdev->desc->uV_step * (selector & ~0x4);
-
-       if (volt > info->max_uV)
-               return -EINVAL;
-
-       return volt;
-}
-
-/* DA9034 specific operations */
-static int da9034_set_dvc_voltage_sel(struct regulator_dev *rdev,
-                                     unsigned selector)
-{
-       struct da903x_regulator_info *info = rdev_get_drvdata(rdev);
-       struct device *da9034_dev = to_da903x_dev(rdev);
-       uint8_t val, mask;
-       int ret;
-
-       val = selector << info->vol_shift;
-       mask = ((1 << info->vol_nbits) - 1)  << info->vol_shift;
-
-       ret = da903x_update(da9034_dev, info->vol_reg, val, mask);
-       if (ret)
-               return ret;
-
-       ret = da903x_set_bits(da9034_dev, info->update_reg,
-                                       1 << info->update_bit);
-       return ret;
-}
-
-static const struct linear_range da9034_ldo12_ranges[] = {
-       REGULATOR_LINEAR_RANGE(1700000, 0, 7, 50000),
-       REGULATOR_LINEAR_RANGE(2700000, 8, 15, 50000),
-};
-
-static const struct regulator_ops da903x_regulator_ldo_ops = {
-       .set_voltage_sel = da903x_set_voltage_sel,
-       .get_voltage_sel = da903x_get_voltage_sel,
-       .list_voltage   = regulator_list_voltage_linear,
-       .map_voltage    = regulator_map_voltage_linear,
-       .enable         = da903x_enable,
-       .disable        = da903x_disable,
-       .is_enabled     = da903x_is_enabled,
-};
-
-/* NOTE: this is dedicated for the insane DA9030 LDO14 */
-static const struct regulator_ops da9030_regulator_ldo14_ops = {
-       .set_voltage_sel = da903x_set_voltage_sel,
-       .get_voltage_sel = da903x_get_voltage_sel,
-       .list_voltage   = da9030_list_ldo14_voltage,
-       .map_voltage    = da9030_map_ldo14_voltage,
-       .enable         = da903x_enable,
-       .disable        = da903x_disable,
-       .is_enabled     = da903x_is_enabled,
-};
-
-/* NOTE: this is dedicated for the DA9030 LDO1 and LDO15 that have locks  */
-static const struct regulator_ops da9030_regulator_ldo1_15_ops = {
-       .set_voltage_sel = da9030_set_ldo1_15_voltage_sel,
-       .get_voltage_sel = da903x_get_voltage_sel,
-       .list_voltage   = regulator_list_voltage_linear,
-       .map_voltage    = regulator_map_voltage_linear,
-       .enable         = da903x_enable,
-       .disable        = da903x_disable,
-       .is_enabled     = da903x_is_enabled,
-};
-
-static const struct regulator_ops da9034_regulator_dvc_ops = {
-       .set_voltage_sel = da9034_set_dvc_voltage_sel,
-       .get_voltage_sel = da903x_get_voltage_sel,
-       .list_voltage   = regulator_list_voltage_linear,
-       .map_voltage    = regulator_map_voltage_linear,
-       .enable         = da903x_enable,
-       .disable        = da903x_disable,
-       .is_enabled     = da903x_is_enabled,
-};
-
-/* NOTE: this is dedicated for the insane LDO12 */
-static const struct regulator_ops da9034_regulator_ldo12_ops = {
-       .set_voltage_sel = da903x_set_voltage_sel,
-       .get_voltage_sel = da903x_get_voltage_sel,
-       .list_voltage   = regulator_list_voltage_linear_range,
-       .map_voltage    = regulator_map_voltage_linear_range,
-       .enable         = da903x_enable,
-       .disable        = da903x_disable,
-       .is_enabled     = da903x_is_enabled,
-};
-
-#define DA903x_LDO(_pmic, _id, min, max, step, vreg, shift, nbits, ereg, ebit) \
-{                                                                      \
-       .desc   = {                                                     \
-               .name   = "LDO" #_id,                                   \
-               .ops    = &da903x_regulator_ldo_ops,                    \
-               .type   = REGULATOR_VOLTAGE,                            \
-               .id     = _pmic##_ID_LDO##_id,                          \
-               .n_voltages = (step) ? ((max - min) / step + 1) : 1,    \
-               .owner  = THIS_MODULE,                                  \
-               .min_uV  = (min) * 1000,                                \
-               .uV_step = (step) * 1000,                               \
-       },                                                              \
-       .max_uV         = (max) * 1000,                                 \
-       .vol_reg        = _pmic##_##vreg,                               \
-       .vol_shift      = (shift),                                      \
-       .vol_nbits      = (nbits),                                      \
-       .enable_reg     = _pmic##_##ereg,                               \
-       .enable_bit     = (ebit),                                       \
-}
-
-#define DA903x_DVC(_pmic, _id, min, max, step, vreg, nbits, ureg, ubit, ereg, ebit) \
-{                                                                      \
-       .desc   = {                                                     \
-               .name   = #_id,                                         \
-               .ops    = &da9034_regulator_dvc_ops,                    \
-               .type   = REGULATOR_VOLTAGE,                            \
-               .id     = _pmic##_ID_##_id,                             \
-               .n_voltages = (step) ? ((max - min) / step + 1) : 1,    \
-               .owner  = THIS_MODULE,                                  \
-               .min_uV = (min) * 1000,                                 \
-               .uV_step = (step) * 1000,                               \
-       },                                                              \
-       .max_uV         = (max) * 1000,                                 \
-       .vol_reg        = _pmic##_##vreg,                               \
-       .vol_shift      = (0),                                          \
-       .vol_nbits      = (nbits),                                      \
-       .update_reg     = _pmic##_##ureg,                               \
-       .update_bit     = (ubit),                                       \
-       .enable_reg     = _pmic##_##ereg,                               \
-       .enable_bit     = (ebit),                                       \
-}
-
-#define DA9034_LDO(_id, min, max, step, vreg, shift, nbits, ereg, ebit)        \
-       DA903x_LDO(DA9034, _id, min, max, step, vreg, shift, nbits, ereg, ebit)
-
-#define DA9030_LDO(_id, min, max, step, vreg, shift, nbits, ereg, ebit)        \
-       DA903x_LDO(DA9030, _id, min, max, step, vreg, shift, nbits, ereg, ebit)
-
-#define DA9030_DVC(_id, min, max, step, vreg, nbits, ureg, ubit, ereg, ebit) \
-       DA903x_DVC(DA9030, _id, min, max, step, vreg, nbits, ureg, ubit, \
-                  ereg, ebit)
-
-#define DA9034_DVC(_id, min, max, step, vreg, nbits, ureg, ubit, ereg, ebit) \
-       DA903x_DVC(DA9034, _id, min, max, step, vreg, nbits, ureg, ubit, \
-                  ereg, ebit)
-
-#define DA9035_DVC(_id, min, max, step, vreg, nbits, ureg, ubit, ereg, ebit) \
-       DA903x_DVC(DA9035, _id, min, max, step, vreg, nbits, ureg, ubit, \
-                  ereg, ebit)
-
-static struct da903x_regulator_info da903x_regulator_info[] = {
-       /* DA9030 */
-       DA9030_DVC(BUCK2, 850, 1625, 25, BUCK2DVM1, 5, BUCK2DVM1, 7, RCTL11, 0),
-
-       DA9030_LDO( 1, 1200, 3200, 100,    LDO1, 0, 5, RCTL12, 1),
-       DA9030_LDO( 2, 1800, 3200, 100,   LDO23, 0, 4, RCTL12, 2),
-       DA9030_LDO( 3, 1800, 3200, 100,   LDO23, 4, 4, RCTL12, 3),
-       DA9030_LDO( 4, 1800, 3200, 100,   LDO45, 0, 4, RCTL12, 4),
-       DA9030_LDO( 5, 1800, 3200, 100,   LDO45, 4, 4, RCTL12, 5),
-       DA9030_LDO( 6, 1800, 3200, 100,    LDO6, 0, 4, RCTL12, 6),
-       DA9030_LDO( 7, 1800, 3200, 100,   LDO78, 0, 4, RCTL12, 7),
-       DA9030_LDO( 8, 1800, 3200, 100,   LDO78, 4, 4, RCTL22, 0),
-       DA9030_LDO( 9, 1800, 3200, 100,  LDO912, 0, 4, RCTL22, 1),
-       DA9030_LDO(10, 1800, 3200, 100, LDO1011, 0, 4, RCTL22, 2),
-       DA9030_LDO(11, 1800, 3200, 100, LDO1011, 4, 4, RCTL22, 3),
-       DA9030_LDO(12, 1800, 3200, 100,  LDO912, 4, 4, RCTL22, 4),
-       DA9030_LDO(14, 2760, 2940,  30, LDO1416, 0, 3, RCTL11, 4),
-       DA9030_LDO(15, 1100, 2650,  50,   LDO15, 0, 5, RCTL11, 5),
-       DA9030_LDO(16, 1100, 2650,  50, LDO1416, 3, 5, RCTL11, 6),
-       DA9030_LDO(17, 1800, 3200, 100,   LDO17, 0, 4, RCTL11, 7),
-       DA9030_LDO(18, 1800, 3200, 100, LDO1819, 0, 4, RCTL21, 2),
-       DA9030_LDO(19, 1800, 3200, 100, LDO1819, 4, 4, RCTL21, 1),
-       DA9030_LDO(13, 2100, 2100, 0, INVAL, 0, 0, RCTL11, 3), /* fixed @2.1V */
-
-       /* DA9034 */
-       DA9034_DVC(BUCK1, 725, 1500, 25, ADTV2, 5, VCC1, 0, OVER1, 0),
-       DA9034_DVC(BUCK2, 725, 1500, 25, CDTV2, 5, VCC1, 2, OVER1, 1),
-       DA9034_DVC(LDO2,  725, 1500, 25, SDTV2, 5, VCC1, 4, OVER1, 2),
-       DA9034_DVC(LDO1, 1700, 2075, 25, MDTV1, 4, VCC1, 6, OVER3, 4),
-
-       DA9034_LDO( 3, 1800, 3300, 100,  LDO643, 0, 4, OVER3, 5),
-       DA9034_LDO( 4, 1800, 2900,1100,  LDO643, 4, 1, OVER3, 6),
-       DA9034_LDO( 6, 2500, 2850,  50,  LDO643, 5, 3, OVER2, 0),
-       DA9034_LDO( 7, 2700, 3050,  50,  LDO987, 0, 3, OVER2, 1),
-       DA9034_LDO( 8, 2700, 2850,  50,  LDO987, 3, 2, OVER2, 2),
-       DA9034_LDO( 9, 2700, 3050,  50,  LDO987, 5, 3, OVER2, 3),
-       DA9034_LDO(10, 2700, 3050,  50, LDO1110, 0, 3, OVER2, 4),
-       DA9034_LDO(11, 1800, 3300, 100, LDO1110, 4, 4, OVER2, 5),
-       DA9034_LDO(12, 1700, 3050,  50, LDO1312, 0, 4, OVER3, 6),
-       DA9034_LDO(13, 1800, 3300, 100, LDO1312, 4, 4, OVER2, 7),
-       DA9034_LDO(14, 1800, 3300, 100, LDO1514, 0, 4, OVER3, 0),
-       DA9034_LDO(15, 1800, 3300, 100, LDO1514, 4, 4, OVER3, 1),
-       DA9034_LDO(5, 3100, 3100, 0, INVAL, 0, 0, OVER3, 7), /* fixed @3.1V */
-
-       /* DA9035 */
-       DA9035_DVC(BUCK3, 1800, 2200, 100, 3DTV1, 3, VCC2, 0, OVER3, 3),
-};
-
-static inline struct da903x_regulator_info *find_regulator_info(int id)
-{
-       struct da903x_regulator_info *ri;
-       int i;
-
-       for (i = 0; i < ARRAY_SIZE(da903x_regulator_info); i++) {
-               ri = &da903x_regulator_info[i];
-               if (ri->desc.id == id)
-                       return ri;
-       }
-       return NULL;
-}
-
-static int da903x_regulator_probe(struct platform_device *pdev)
-{
-       struct da903x_regulator_info *ri = NULL;
-       struct regulator_dev *rdev;
-       struct regulator_config config = { };
-
-       ri = find_regulator_info(pdev->id);
-       if (ri == NULL) {
-               dev_err(&pdev->dev, "invalid regulator ID specified\n");
-               return -EINVAL;
-       }
-
-       /* Workaround for the weird LDO12 voltage setting */
-       if (ri->desc.id == DA9034_ID_LDO12) {
-               ri->desc.ops = &da9034_regulator_ldo12_ops;
-               ri->desc.n_voltages = 16;
-               ri->desc.linear_ranges = da9034_ldo12_ranges;
-               ri->desc.n_linear_ranges = ARRAY_SIZE(da9034_ldo12_ranges);
-       }
-
-       if (ri->desc.id == DA9030_ID_LDO14)
-               ri->desc.ops = &da9030_regulator_ldo14_ops;
-
-       if (ri->desc.id == DA9030_ID_LDO1 || ri->desc.id == DA9030_ID_LDO15)
-               ri->desc.ops = &da9030_regulator_ldo1_15_ops;
-
-       config.dev = &pdev->dev;
-       config.init_data = dev_get_platdata(&pdev->dev);
-       config.driver_data = ri;
-
-       rdev = devm_regulator_register(&pdev->dev, &ri->desc, &config);
-       if (IS_ERR(rdev)) {
-               dev_err(&pdev->dev, "failed to register regulator %s\n",
-                               ri->desc.name);
-               return PTR_ERR(rdev);
-       }
-
-       platform_set_drvdata(pdev, rdev);
-       return 0;
-}
-
-static struct platform_driver da903x_regulator_driver = {
-       .driver = {
-               .name   = "da903x-regulator",
-       },
-       .probe          = da903x_regulator_probe,
-};
-
-static int __init da903x_regulator_init(void)
-{
-       return platform_driver_register(&da903x_regulator_driver);
-}
-subsys_initcall(da903x_regulator_init);
-
-static void __exit da903x_regulator_exit(void)
-{
-       platform_driver_unregister(&da903x_regulator_driver);
-}
-module_exit(da903x_regulator_exit);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Eric Miao <eric.miao@marvell.com>"
-             "Mike Rapoport <mike@compulab.co.il>");
-MODULE_DESCRIPTION("Regulator Driver for Dialog Semiconductor DA903X PMIC");
-MODULE_ALIAS("platform:da903x-regulator");
index 53a64d8..7f5c318 100644 (file)
@@ -821,7 +821,7 @@ static const struct rpm_regulator_data rpm_pm8994_regulators[] = {
 static const struct rpm_regulator_data rpm_pmi8994_regulators[] = {
        { "s1", QCOM_SMD_RPM_SMPB, 1, &pmi8994_ftsmps, "vdd_s1" },
        { "s2", QCOM_SMD_RPM_SMPB, 2, &pmi8994_hfsmps, "vdd_s2" },
-       { "s2", QCOM_SMD_RPM_SMPB, 3, &pmi8994_hfsmps, "vdd_s3" },
+       { "s3", QCOM_SMD_RPM_SMPB, 3, &pmi8994_hfsmps, "vdd_s3" },
        { "boost-bypass", QCOM_SMD_RPM_BBYB, 1, &pmi8994_bby, "vdd_bst_byp" },
        {}
 };
index 01fc0d2..6f54bd8 100644 (file)
@@ -66,10 +66,12 @@ static const struct meson_gx_package_id {
        { "A113D", 0x25, 0x22, 0xff },
        { "S905D2", 0x28, 0x10, 0xf0 },
        { "S905X2", 0x28, 0x40, 0xf0 },
-       { "S922X", 0x29, 0x40, 0xf0 },
        { "A311D", 0x29, 0x10, 0xf0 },
-       { "S905X3", 0x2b, 0x5, 0xf },
-       { "S905D3", 0x2b, 0xb0, 0xf0 },
+       { "S922X", 0x29, 0x40, 0xf0 },
+       { "S905D3", 0x2b, 0x4, 0xf5 },
+       { "S905X3", 0x2b, 0x5, 0xf5 },
+       { "S905X3", 0x2b, 0x10, 0x3f },
+       { "S905D3", 0x2b, 0x30, 0x3f },
        { "A113L", 0x2c, 0x0, 0xf8 },
 };
 
index fec3d67..01bfea1 100644 (file)
@@ -33,6 +33,9 @@ static int __init imx_soc_device_init(void)
        u32 val;
        int ret;
 
+       if (of_machine_is_compatible("fsl,ls1021a"))
+               return 0;
+
        soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL);
        if (!soc_dev_attr)
                return -ENOMEM;
index 4cfdd07..c742274 100644 (file)
@@ -930,8 +930,9 @@ static int intel_create_dai(struct sdw_cdns *cdns,
 
         /* TODO: Read supported rates/formats from hardware */
        for (i = off; i < (off + num); i++) {
-               dais[i].name = kasprintf(GFP_KERNEL, "SDW%d Pin%d",
-                                        cdns->instance, i);
+               dais[i].name = devm_kasprintf(cdns->dev, GFP_KERNEL,
+                                             "SDW%d Pin%d",
+                                             cdns->instance, i);
                if (!dais[i].name)
                        return -ENOMEM;
 
index 6783e12..a556795 100644 (file)
@@ -36,7 +36,6 @@
 #define SPI_CFG0_SCK_LOW_OFFSET           8
 #define SPI_CFG0_CS_HOLD_OFFSET           16
 #define SPI_CFG0_CS_SETUP_OFFSET          24
-#define SPI_ADJUST_CFG0_SCK_LOW_OFFSET    16
 #define SPI_ADJUST_CFG0_CS_HOLD_OFFSET    0
 #define SPI_ADJUST_CFG0_CS_SETUP_OFFSET   16
 
@@ -48,6 +47,8 @@
 #define SPI_CFG1_CS_IDLE_MASK             0xff
 #define SPI_CFG1_PACKET_LOOP_MASK         0xff00
 #define SPI_CFG1_PACKET_LENGTH_MASK       0x3ff0000
+#define SPI_CFG2_SCK_HIGH_OFFSET          0
+#define SPI_CFG2_SCK_LOW_OFFSET           16
 
 #define SPI_CMD_ACT                  BIT(0)
 #define SPI_CMD_RESUME               BIT(1)
@@ -283,7 +284,7 @@ static void mtk_spi_set_cs(struct spi_device *spi, bool enable)
 static void mtk_spi_prepare_transfer(struct spi_master *master,
                                     struct spi_transfer *xfer)
 {
-       u32 spi_clk_hz, div, sck_time, cs_time, reg_val = 0;
+       u32 spi_clk_hz, div, sck_time, cs_time, reg_val;
        struct mtk_spi *mdata = spi_master_get_devdata(master);
 
        spi_clk_hz = clk_get_rate(mdata->spi_clk);
@@ -296,18 +297,18 @@ static void mtk_spi_prepare_transfer(struct spi_master *master,
        cs_time = sck_time * 2;
 
        if (mdata->dev_comp->enhance_timing) {
+               reg_val = (((sck_time - 1) & 0xffff)
+                          << SPI_CFG2_SCK_HIGH_OFFSET);
                reg_val |= (((sck_time - 1) & 0xffff)
-                          << SPI_CFG0_SCK_HIGH_OFFSET);
-               reg_val |= (((sck_time - 1) & 0xffff)
-                          << SPI_ADJUST_CFG0_SCK_LOW_OFFSET);
+                          << SPI_CFG2_SCK_LOW_OFFSET);
                writel(reg_val, mdata->base + SPI_CFG2_REG);
-               reg_val |= (((cs_time - 1) & 0xffff)
+               reg_val = (((cs_time - 1) & 0xffff)
                           << SPI_ADJUST_CFG0_CS_HOLD_OFFSET);
                reg_val |= (((cs_time - 1) & 0xffff)
                           << SPI_ADJUST_CFG0_CS_SETUP_OFFSET);
                writel(reg_val, mdata->base + SPI_CFG0_REG);
        } else {
-               reg_val |= (((sck_time - 1) & 0xff)
+               reg_val = (((sck_time - 1) & 0xff)
                           << SPI_CFG0_SCK_HIGH_OFFSET);
                reg_val |= (((sck_time - 1) & 0xff) << SPI_CFG0_SCK_LOW_OFFSET);
                reg_val |= (((cs_time - 1) & 0xff) << SPI_CFG0_CS_HOLD_OFFSET);
index ecea155..fa11cc0 100644 (file)
@@ -198,7 +198,7 @@ static int sun6i_spi_transfer_one(struct spi_master *master,
                                  struct spi_transfer *tfr)
 {
        struct sun6i_spi *sspi = spi_master_get_devdata(master);
-       unsigned int mclk_rate, div, timeout;
+       unsigned int mclk_rate, div, div_cdr1, div_cdr2, timeout;
        unsigned int start, end, tx_time;
        unsigned int trig_level;
        unsigned int tx_len = 0;
@@ -287,14 +287,12 @@ static int sun6i_spi_transfer_one(struct spi_master *master,
         * First try CDR2, and if we can't reach the expected
         * frequency, fall back to CDR1.
         */
-       div = mclk_rate / (2 * tfr->speed_hz);
-       if (div <= (SUN6I_CLK_CTL_CDR2_MASK + 1)) {
-               if (div > 0)
-                       div--;
-
-               reg = SUN6I_CLK_CTL_CDR2(div) | SUN6I_CLK_CTL_DRS;
+       div_cdr1 = DIV_ROUND_UP(mclk_rate, tfr->speed_hz);
+       div_cdr2 = DIV_ROUND_UP(div_cdr1, 2);
+       if (div_cdr2 <= (SUN6I_CLK_CTL_CDR2_MASK + 1)) {
+               reg = SUN6I_CLK_CTL_CDR2(div_cdr2 - 1) | SUN6I_CLK_CTL_DRS;
        } else {
-               div = ilog2(mclk_rate) - ilog2(tfr->speed_hz);
+               div = min(SUN6I_CLK_CTL_CDR1_MASK, order_base_2(div_cdr1));
                reg = SUN6I_CLK_CTL_CDR1(div);
        }
 
index 45ad4ba..689acd6 100644 (file)
@@ -456,9 +456,9 @@ static int apci1500_di_cfg_trig(struct comedi_device *dev,
        unsigned int lo_mask = data[5] << shift;
        unsigned int chan_mask = hi_mask | lo_mask;
        unsigned int old_mask = (1 << shift) - 1;
-       unsigned int pm = devpriv->pm[trig] & old_mask;
-       unsigned int pt = devpriv->pt[trig] & old_mask;
-       unsigned int pp = devpriv->pp[trig] & old_mask;
+       unsigned int pm;
+       unsigned int pt;
+       unsigned int pp;
 
        if (trig > 1) {
                dev_dbg(dev->class_dev,
@@ -471,6 +471,10 @@ static int apci1500_di_cfg_trig(struct comedi_device *dev,
                return -EINVAL;
        }
 
+       pm = devpriv->pm[trig] & old_mask;
+       pt = devpriv->pt[trig] & old_mask;
+       pp = devpriv->pp[trig] & old_mask;
+
        switch (data[2]) {
        case COMEDI_DIGITAL_TRIG_DISABLE:
                /* clear trigger configuration */
index 0b3a626..12448cc 100644 (file)
@@ -216,11 +216,16 @@ static int int3400_thermal_run_osc(acpi_handle handle,
        acpi_status status;
        int result = 0;
        struct acpi_osc_context context = {
-               .uuid_str = int3400_thermal_uuids[uuid],
+               .uuid_str = NULL,
                .rev = 1,
                .cap.length = 8,
        };
 
+       if (uuid < 0 || uuid >= INT3400_THERMAL_MAXIMUM_UUID)
+               return -EINVAL;
+
+       context.uuid_str = int3400_thermal_uuids[uuid];
+
        buf[OSC_QUERY_DWORD] = 0;
        buf[OSC_SUPPORT_DWORD] = enable;
 
index f86cbb1..ec1d58c 100644 (file)
@@ -74,7 +74,7 @@ static void int3403_notify(acpi_handle handle,
                                                   THERMAL_TRIP_CHANGED);
                break;
        default:
-               dev_err(&priv->pdev->dev, "Unsupported event [0x%x]\n", event);
+               dev_dbg(&priv->pdev->dev, "Unsupported event [0x%x]\n", event);
                break;
        }
 }
index 6b7ef19..42c9cd0 100644 (file)
@@ -594,8 +594,7 @@ static int mtk_thermal_bank_temperature(struct mtk_thermal_bank *bank)
        u32 raw;
 
        for (i = 0; i < conf->bank_data[bank->id].num_sensors; i++) {
-               raw = readl(mt->thermal_base +
-                           conf->msr[conf->bank_data[bank->id].sensors[i]]);
+               raw = readl(mt->thermal_base + conf->msr[i]);
 
                temp = raw_to_mcelsius(mt,
                                       conf->bank_data[bank->id].sensors[i],
@@ -736,8 +735,7 @@ static void mtk_thermal_init_bank(struct mtk_thermal *mt, int num,
 
        for (i = 0; i < conf->bank_data[num].num_sensors; i++)
                writel(conf->sensor_mux_values[conf->bank_data[num].sensors[i]],
-                      mt->thermal_base +
-                      conf->adcpnp[conf->bank_data[num].sensors[i]]);
+                      mt->thermal_base + conf->adcpnp[i]);
 
        writel((1 << conf->bank_data[num].num_sensors) - 1,
               controller_base + TEMP_MONCTL0);
index a04f74d..4df47d0 100644 (file)
@@ -1215,7 +1215,12 @@ static int cpm_uart_init_port(struct device_node *np,
 
                pinfo->gpios[i] = NULL;
 
-               gpiod = devm_gpiod_get_index(dev, NULL, i, GPIOD_ASIS);
+               gpiod = devm_gpiod_get_index_optional(dev, NULL, i, GPIOD_ASIS);
+
+               if (IS_ERR(gpiod)) {
+                       ret = PTR_ERR(gpiod);
+                       goto out_irq;
+               }
 
                if (gpiod) {
                        if (i == GPIO_RTS || i == GPIO_DTR)
@@ -1237,6 +1242,8 @@ static int cpm_uart_init_port(struct device_node *np,
 
        return cpm_uart_request_port(&pinfo->port);
 
+out_irq:
+       irq_dispose_mapping(pinfo->port.irq);
 out_pram:
        cpm_uart_unmap_pram(pinfo, pram);
 out_mem:
index b4f835e..b784323 100644 (file)
@@ -1698,21 +1698,21 @@ static int mxs_auart_probe(struct platform_device *pdev)
        irq = platform_get_irq(pdev, 0);
        if (irq < 0) {
                ret = irq;
-               goto out_disable_clks;
+               goto out_iounmap;
        }
 
        s->port.irq = irq;
        ret = devm_request_irq(&pdev->dev, irq, mxs_auart_irq_handle, 0,
                               dev_name(&pdev->dev), s);
        if (ret)
-               goto out_disable_clks;
+               goto out_iounmap;
 
        platform_set_drvdata(pdev, s);
 
        ret = mxs_auart_init_gpios(s, &pdev->dev);
        if (ret) {
                dev_err(&pdev->dev, "Failed to initialize GPIOs.\n");
-               goto out_disable_clks;
+               goto out_iounmap;
        }
 
        /*
@@ -1720,7 +1720,7 @@ static int mxs_auart_probe(struct platform_device *pdev)
         */
        ret = mxs_auart_request_gpio_irq(s);
        if (ret)
-               goto out_disable_clks;
+               goto out_iounmap;
 
        auart_port[s->port.line] = s;
 
@@ -1746,6 +1746,9 @@ out_free_qpio_irq:
        mxs_auart_free_gpio_irq(s);
        auart_port[pdev->id] = NULL;
 
+out_iounmap:
+       iounmap(s->port.membase);
+
 out_disable_clks:
        if (is_asm9260_auart(s)) {
                clk_disable_unprepare(s->clk);
@@ -1761,6 +1764,7 @@ static int mxs_auart_remove(struct platform_device *pdev)
        uart_remove_one_port(&auart_driver, &s->port);
        auart_port[pdev->id] = NULL;
        mxs_auart_free_gpio_irq(s);
+       iounmap(s->port.membase);
        if (is_asm9260_auart(s)) {
                clk_disable_unprepare(s->clk);
                clk_disable_unprepare(s->clk_ahb);
index 57840cf..5f3daab 100644 (file)
@@ -41,8 +41,6 @@ static struct lock_class_key port_lock_key;
 
 #define HIGH_BITS_OFFSET       ((sizeof(long)-sizeof(int))*8)
 
-#define SYSRQ_TIMEOUT  (HZ * 5)
-
 static void uart_change_speed(struct tty_struct *tty, struct uart_state *state,
                                        struct ktermios *old_termios);
 static void uart_wait_until_sent(struct tty_struct *tty, int timeout);
@@ -1916,6 +1914,12 @@ static inline bool uart_console_enabled(struct uart_port *port)
        return uart_console(port) && (port->cons->flags & CON_ENABLED);
 }
 
+static void __uart_port_spin_lock_init(struct uart_port *port)
+{
+       spin_lock_init(&port->lock);
+       lockdep_set_class(&port->lock, &port_lock_key);
+}
+
 /*
  * Ensure that the serial console lock is initialised early.
  * If this port is a console, then the spinlock is already initialised.
@@ -1925,8 +1929,7 @@ static inline void uart_port_spin_lock_init(struct uart_port *port)
        if (uart_console(port))
                return;
 
-       spin_lock_init(&port->lock);
-       lockdep_set_class(&port->lock, &port_lock_key);
+       __uart_port_spin_lock_init(port);
 }
 
 #if defined(CONFIG_SERIAL_CORE_CONSOLE) || defined(CONFIG_CONSOLE_POLL)
@@ -2372,6 +2375,13 @@ uart_configure_port(struct uart_driver *drv, struct uart_state *state,
                /* Power up port for set_mctrl() */
                uart_change_pm(state, UART_PM_STATE_ON);
 
+               /*
+                * If this driver supports console, and it hasn't been
+                * successfully registered yet, initialise spin lock for it.
+                */
+               if (port->cons && !(port->cons->flags & CON_ENABLED))
+                       __uart_port_spin_lock_init(port);
+
                /*
                 * Ensure that the modem control lines are de-activated.
                 * keep the DTR setting that is set in uart_set_options()
@@ -3163,7 +3173,7 @@ static DECLARE_WORK(sysrq_enable_work, uart_sysrq_on);
  *     Returns false if @ch is out of enabling sequence and should be
  *     handled some other way, true if @ch was consumed.
  */
-static bool uart_try_toggle_sysrq(struct uart_port *port, unsigned int ch)
+bool uart_try_toggle_sysrq(struct uart_port *port, unsigned int ch)
 {
        int sysrq_toggle_seq_len = strlen(sysrq_toggle_seq);
 
@@ -3186,99 +3196,9 @@ static bool uart_try_toggle_sysrq(struct uart_port *port, unsigned int ch)
        port->sysrq = 0;
        return true;
 }
-#else
-static inline bool uart_try_toggle_sysrq(struct uart_port *port, unsigned int ch)
-{
-       return false;
-}
+EXPORT_SYMBOL_GPL(uart_try_toggle_sysrq);
 #endif
 
-int uart_handle_sysrq_char(struct uart_port *port, unsigned int ch)
-{
-       if (!IS_ENABLED(CONFIG_MAGIC_SYSRQ_SERIAL))
-               return 0;
-
-       if (!port->has_sysrq || !port->sysrq)
-               return 0;
-
-       if (ch && time_before(jiffies, port->sysrq)) {
-               if (sysrq_mask()) {
-                       handle_sysrq(ch);
-                       port->sysrq = 0;
-                       return 1;
-               }
-               if (uart_try_toggle_sysrq(port, ch))
-                       return 1;
-       }
-       port->sysrq = 0;
-
-       return 0;
-}
-EXPORT_SYMBOL_GPL(uart_handle_sysrq_char);
-
-int uart_prepare_sysrq_char(struct uart_port *port, unsigned int ch)
-{
-       if (!IS_ENABLED(CONFIG_MAGIC_SYSRQ_SERIAL))
-               return 0;
-
-       if (!port->has_sysrq || !port->sysrq)
-               return 0;
-
-       if (ch && time_before(jiffies, port->sysrq)) {
-               if (sysrq_mask()) {
-                       port->sysrq_ch = ch;
-                       port->sysrq = 0;
-                       return 1;
-               }
-               if (uart_try_toggle_sysrq(port, ch))
-                       return 1;
-       }
-       port->sysrq = 0;
-
-       return 0;
-}
-EXPORT_SYMBOL_GPL(uart_prepare_sysrq_char);
-
-void uart_unlock_and_check_sysrq(struct uart_port *port, unsigned long flags)
-__releases(&port->lock)
-{
-       if (port->has_sysrq) {
-               int sysrq_ch = port->sysrq_ch;
-
-               port->sysrq_ch = 0;
-               spin_unlock_irqrestore(&port->lock, flags);
-               if (sysrq_ch)
-                       handle_sysrq(sysrq_ch);
-       } else {
-               spin_unlock_irqrestore(&port->lock, flags);
-       }
-}
-EXPORT_SYMBOL_GPL(uart_unlock_and_check_sysrq);
-
-/*
- * We do the SysRQ and SAK checking like this...
- */
-int uart_handle_break(struct uart_port *port)
-{
-       struct uart_state *state = port->state;
-
-       if (port->handle_break)
-               port->handle_break(port);
-
-       if (port->has_sysrq && uart_console(port)) {
-               if (!port->sysrq) {
-                       port->sysrq = jiffies + SYSRQ_TIMEOUT;
-                       return 1;
-               }
-               port->sysrq = 0;
-       }
-
-       if (port->flags & UPF_SAK)
-               do_SAK(state->port.tty);
-       return 0;
-}
-EXPORT_SYMBOL_GPL(uart_handle_break);
-
 EXPORT_SYMBOL(uart_write_wakeup);
 EXPORT_SYMBOL(uart_register_driver);
 EXPORT_SYMBOL(uart_unregister_driver);
@@ -3289,8 +3209,7 @@ EXPORT_SYMBOL(uart_remove_one_port);
 
 /**
  * uart_get_rs485_mode() - retrieve rs485 properties for given uart
- * @dev: uart device
- * @rs485conf: output parameter
+ * @port: uart device's target port
  *
  * This function implements the device tree binding described in
  * Documentation/devicetree/bindings/serial/rs485.txt.
index e1179e7..204bb68 100644 (file)
@@ -3301,6 +3301,9 @@ static int sci_probe_single(struct platform_device *dev,
                sciport->port.flags |= UPF_HARD_FLOW;
        }
 
+       if (sci_uart_driver.cons->index == sciport->port.line)
+               spin_lock_init(&sciport->port.lock);
+
        ret = uart_add_one_port(&sci_uart_driver, &sciport->port);
        if (ret) {
                sci_cleanup_single(sciport);
index b9d672a..672cfa0 100644 (file)
@@ -1465,7 +1465,6 @@ static int cdns_uart_probe(struct platform_device *pdev)
                cdns_uart_uart_driver.nr = CDNS_UART_NR_PORTS;
 #ifdef CONFIG_SERIAL_XILINX_PS_UART_CONSOLE
                cdns_uart_uart_driver.cons = &cdns_uart_console;
-               cdns_uart_console.index = id;
 #endif
 
                rc = uart_register_driver(&cdns_uart_uart_driver);
index ae319ef..b60173b 100644 (file)
@@ -159,9 +159,9 @@ static int uio_pdrv_genirq_probe(struct platform_device *pdev)
        priv->pdev = pdev;
 
        if (!uioinfo->irq) {
-               ret = platform_get_irq(pdev, 0);
+               ret = platform_get_irq_optional(pdev, 0);
                uioinfo->irq = ret;
-               if (ret == -ENXIO && pdev->dev.of_node)
+               if (ret == -ENXIO)
                        uioinfo->irq = UIO_IRQ_NONE;
                else if (ret == -EPROBE_DEFER)
                        return ret;
index b690a8a..18ebd7a 100644 (file)
@@ -1444,7 +1444,7 @@ static int vbg_ioctl_change_guest_capabilities(struct vbg_dev *gdev,
        or_mask = caps->u.in.or_mask;
        not_mask = caps->u.in.not_mask;
 
-       if ((or_mask | not_mask) & ~VMMDEV_EVENT_VALID_EVENT_MASK)
+       if ((or_mask | not_mask) & ~VMMDEV_GUEST_CAPABILITIES_MASK)
                return -EINVAL;
 
        ret = vbg_set_session_capabilities(gdev, session, or_mask, not_mask,
@@ -1520,7 +1520,8 @@ int vbg_core_ioctl(struct vbg_session *session, unsigned int req, void *data)
 
        /* For VMMDEV_REQUEST hdr->type != VBG_IOCTL_HDR_TYPE_DEFAULT */
        if (req_no_size == VBG_IOCTL_VMMDEV_REQUEST(0) ||
-           req == VBG_IOCTL_VMMDEV_REQUEST_BIG)
+           req == VBG_IOCTL_VMMDEV_REQUEST_BIG ||
+           req == VBG_IOCTL_VMMDEV_REQUEST_BIG_ALT)
                return vbg_ioctl_vmmrequest(gdev, session, data);
 
        if (hdr->type != VBG_IOCTL_HDR_TYPE_DEFAULT)
@@ -1558,6 +1559,7 @@ int vbg_core_ioctl(struct vbg_session *session, unsigned int req, void *data)
        case VBG_IOCTL_HGCM_CALL(0):
                return vbg_ioctl_hgcm_call(gdev, session, f32bit, data);
        case VBG_IOCTL_LOG(0):
+       case VBG_IOCTL_LOG_ALT(0):
                return vbg_ioctl_log(data);
        }
 
index 4188c12..77c3a9c 100644 (file)
 #include <linux/vboxguest.h>
 #include "vmmdev.h"
 
+/*
+ * The mainline kernel version (this version) of the vboxguest module
+ * contained a bug where it defined VBGL_IOCTL_VMMDEV_REQUEST_BIG and
+ * VBGL_IOCTL_LOG using _IOC(_IOC_READ | _IOC_WRITE, 'V', ...) instead
+ * of _IO(V, ...) as the out of tree VirtualBox upstream version does.
+ *
+ * These _ALT definitions keep compatibility with the wrong defines the
+ * mainline kernel version used for a while.
+ * Note the VirtualBox userspace bits have always been built against
+ * VirtualBox upstream's headers, so this is likely not necessary. But
+ * we must never break our ABI so we keep these around to be 100% sure.
+ */
+#define VBG_IOCTL_VMMDEV_REQUEST_BIG_ALT _IOC(_IOC_READ | _IOC_WRITE, 'V', 3, 0)
+#define VBG_IOCTL_LOG_ALT(s)             _IOC(_IOC_READ | _IOC_WRITE, 'V', 9, s)
+
 struct vbg_session;
 
 /** VBox guest memory balloon. */
index 6e8c0f1..32c2c52 100644 (file)
@@ -131,7 +131,8 @@ static long vbg_misc_device_ioctl(struct file *filp, unsigned int req,
         * the need for a bounce-buffer and another copy later on.
         */
        is_vmmdev_req = (req & ~IOCSIZE_MASK) == VBG_IOCTL_VMMDEV_REQUEST(0) ||
-                        req == VBG_IOCTL_VMMDEV_REQUEST_BIG;
+                        req == VBG_IOCTL_VMMDEV_REQUEST_BIG ||
+                        req == VBG_IOCTL_VMMDEV_REQUEST_BIG_ALT;
 
        if (is_vmmdev_req)
                buf = vbg_req_alloc(size, VBG_IOCTL_HDR_TYPE_DEFAULT,
index 6337b8d..21f4081 100644 (file)
@@ -206,6 +206,8 @@ VMMDEV_ASSERT_SIZE(vmmdev_mask, 24 + 8);
  * not.
  */
 #define VMMDEV_GUEST_SUPPORTS_GRAPHICS                      BIT(2)
+/* The mask of valid capabilities, for sanity checking. */
+#define VMMDEV_GUEST_CAPABILITIES_MASK                      0x00000007U
 
 /** struct vmmdev_hypervisorinfo - Hypervisor info structure. */
 struct vmmdev_hypervisorinfo {
index c264839..24fd163 100644 (file)
@@ -71,7 +71,7 @@ static bool afs_get_io_locks(struct afs_operation *op)
                swap(vnode, vnode2);
 
        if (mutex_lock_interruptible(&vnode->io_lock) < 0) {
-               op->error = -EINTR;
+               op->error = -ERESTARTSYS;
                op->flags |= AFS_OPERATION_STOP;
                _leave(" = f [I 0]");
                return false;
@@ -80,7 +80,7 @@ static bool afs_get_io_locks(struct afs_operation *op)
 
        if (vnode2) {
                if (mutex_lock_interruptible_nested(&vnode2->io_lock, 1) < 0) {
-                       op->error = -EINTR;
+                       op->error = -ERESTARTSYS;
                        op->flags |= AFS_OPERATION_STOP;
                        mutex_unlock(&vnode->io_lock);
                        op->flags &= ~AFS_OPERATION_LOCK_0;
index 7437806..a121c24 100644 (file)
@@ -449,6 +449,7 @@ static int afs_store_data(struct address_space *mapping,
        op->store.first_offset = offset;
        op->store.last_to = to;
        op->mtime = vnode->vfs_inode.i_mtime;
+       op->flags |= AFS_OPERATION_UNINTR;
        op->ops = &afs_store_data_operation;
 
 try_next_key:
index e573b0c..83d917f 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/swap.h>
 #include <linux/falloc.h>
 #include <linux/uio.h>
+#include <linux/fs.h>
 
 static struct page **fuse_pages_alloc(unsigned int npages, gfp_t flags,
                                      struct fuse_page_desc **desc)
@@ -1586,7 +1587,6 @@ static void fuse_writepage_finish(struct fuse_conn *fc,
        struct backing_dev_info *bdi = inode_to_bdi(inode);
        int i;
 
-       rb_erase(&wpa->writepages_entry, &fi->writepages);
        for (i = 0; i < ap->num_pages; i++) {
                dec_wb_stat(&bdi->wb, WB_WRITEBACK);
                dec_node_page_state(ap->pages[i], NR_WRITEBACK_TEMP);
@@ -1637,6 +1637,7 @@ __acquires(fi->lock)
 
  out_free:
        fi->writectr--;
+       rb_erase(&wpa->writepages_entry, &fi->writepages);
        fuse_writepage_finish(fc, wpa);
        spin_unlock(&fi->lock);
 
@@ -1674,7 +1675,8 @@ __acquires(fi->lock)
        }
 }
 
-static void tree_insert(struct rb_root *root, struct fuse_writepage_args *wpa)
+static struct fuse_writepage_args *fuse_insert_writeback(struct rb_root *root,
+                                               struct fuse_writepage_args *wpa)
 {
        pgoff_t idx_from = wpa->ia.write.in.offset >> PAGE_SHIFT;
        pgoff_t idx_to = idx_from + wpa->ia.ap.num_pages - 1;
@@ -1697,11 +1699,17 @@ static void tree_insert(struct rb_root *root, struct fuse_writepage_args *wpa)
                else if (idx_to < curr_index)
                        p = &(*p)->rb_left;
                else
-                       return (void) WARN_ON(true);
+                       return curr;
        }
 
        rb_link_node(&wpa->writepages_entry, parent, p);
        rb_insert_color(&wpa->writepages_entry, root);
+       return NULL;
+}
+
+static void tree_insert(struct rb_root *root, struct fuse_writepage_args *wpa)
+{
+       WARN_ON(fuse_insert_writeback(root, wpa));
 }
 
 static void fuse_writepage_end(struct fuse_conn *fc, struct fuse_args *args,
@@ -1714,6 +1722,7 @@ static void fuse_writepage_end(struct fuse_conn *fc, struct fuse_args *args,
 
        mapping_set_error(inode->i_mapping, error);
        spin_lock(&fi->lock);
+       rb_erase(&wpa->writepages_entry, &fi->writepages);
        while (wpa->next) {
                struct fuse_conn *fc = get_fuse_conn(inode);
                struct fuse_write_in *inarg = &wpa->ia.write.in;
@@ -1952,14 +1961,14 @@ static void fuse_writepages_send(struct fuse_fill_wb_data *data)
 }
 
 /*
- * First recheck under fi->lock if the offending offset is still under
- * writeback.  If yes, then iterate auxiliary write requests, to see if there's
+ * Check under fi->lock if the page is under writeback, and insert it onto the
+ * rb_tree if not. Otherwise iterate auxiliary write requests, to see if there's
  * one already added for a page at this offset.  If there's none, then insert
  * this new request onto the auxiliary list, otherwise reuse the existing one by
- * copying the new page contents over to the old temporary page.
+ * swapping the new temp page with the old one.
  */
-static bool fuse_writepage_in_flight(struct fuse_writepage_args *new_wpa,
-                                    struct page *page)
+static bool fuse_writepage_add(struct fuse_writepage_args *new_wpa,
+                              struct page *page)
 {
        struct fuse_inode *fi = get_fuse_inode(new_wpa->inode);
        struct fuse_writepage_args *tmp;
@@ -1967,17 +1976,15 @@ static bool fuse_writepage_in_flight(struct fuse_writepage_args *new_wpa,
        struct fuse_args_pages *new_ap = &new_wpa->ia.ap;
 
        WARN_ON(new_ap->num_pages != 0);
+       new_ap->num_pages = 1;
 
        spin_lock(&fi->lock);
-       rb_erase(&new_wpa->writepages_entry, &fi->writepages);
-       old_wpa = fuse_find_writeback(fi, page->index, page->index);
+       old_wpa = fuse_insert_writeback(&fi->writepages, new_wpa);
        if (!old_wpa) {
-               tree_insert(&fi->writepages, new_wpa);
                spin_unlock(&fi->lock);
-               return false;
+               return true;
        }
 
-       new_ap->num_pages = 1;
        for (tmp = old_wpa->next; tmp; tmp = tmp->next) {
                pgoff_t curr_index;
 
@@ -2006,7 +2013,41 @@ static bool fuse_writepage_in_flight(struct fuse_writepage_args *new_wpa,
                fuse_writepage_free(new_wpa);
        }
 
-       return true;
+       return false;
+}
+
+static bool fuse_writepage_need_send(struct fuse_conn *fc, struct page *page,
+                                    struct fuse_args_pages *ap,
+                                    struct fuse_fill_wb_data *data)
+{
+       WARN_ON(!ap->num_pages);
+
+       /*
+        * Being under writeback is unlikely but possible.  For example direct
+        * read to an mmaped fuse file will set the page dirty twice; once when
+        * the pages are faulted with get_user_pages(), and then after the read
+        * completed.
+        */
+       if (fuse_page_is_writeback(data->inode, page->index))
+               return true;
+
+       /* Reached max pages */
+       if (ap->num_pages == fc->max_pages)
+               return true;
+
+       /* Reached max write bytes */
+       if ((ap->num_pages + 1) * PAGE_SIZE > fc->max_write)
+               return true;
+
+       /* Discontinuity */
+       if (data->orig_pages[ap->num_pages - 1]->index + 1 != page->index)
+               return true;
+
+       /* Need to grow the pages array?  If so, did the expansion fail? */
+       if (ap->num_pages == data->max_pages && !fuse_pages_realloc(data))
+               return true;
+
+       return false;
 }
 
 static int fuse_writepages_fill(struct page *page,
@@ -2019,7 +2060,6 @@ static int fuse_writepages_fill(struct page *page,
        struct fuse_inode *fi = get_fuse_inode(inode);
        struct fuse_conn *fc = get_fuse_conn(inode);
        struct page *tmp_page;
-       bool is_writeback;
        int err;
 
        if (!data->ff) {
@@ -2029,25 +2069,9 @@ static int fuse_writepages_fill(struct page *page,
                        goto out_unlock;
        }
 
-       /*
-        * Being under writeback is unlikely but possible.  For example direct
-        * read to an mmaped fuse file will set the page dirty twice; once when
-        * the pages are faulted with get_user_pages(), and then after the read
-        * completed.
-        */
-       is_writeback = fuse_page_is_writeback(inode, page->index);
-
-       if (wpa && ap->num_pages &&
-           (is_writeback || ap->num_pages == fc->max_pages ||
-            (ap->num_pages + 1) * PAGE_SIZE > fc->max_write ||
-            data->orig_pages[ap->num_pages - 1]->index + 1 != page->index)) {
+       if (wpa && fuse_writepage_need_send(fc, page, ap, data)) {
                fuse_writepages_send(data);
                data->wpa = NULL;
-       } else if (wpa && ap->num_pages == data->max_pages) {
-               if (!fuse_pages_realloc(data)) {
-                       fuse_writepages_send(data);
-                       data->wpa = NULL;
-               }
        }
 
        err = -ENOMEM;
@@ -2085,12 +2109,6 @@ static int fuse_writepages_fill(struct page *page,
                ap->args.end = fuse_writepage_end;
                ap->num_pages = 0;
                wpa->inode = inode;
-
-               spin_lock(&fi->lock);
-               tree_insert(&fi->writepages, wpa);
-               spin_unlock(&fi->lock);
-
-               data->wpa = wpa;
        }
        set_page_writeback(page);
 
@@ -2098,26 +2116,25 @@ static int fuse_writepages_fill(struct page *page,
        ap->pages[ap->num_pages] = tmp_page;
        ap->descs[ap->num_pages].offset = 0;
        ap->descs[ap->num_pages].length = PAGE_SIZE;
+       data->orig_pages[ap->num_pages] = page;
 
        inc_wb_stat(&inode_to_bdi(inode)->wb, WB_WRITEBACK);
        inc_node_page_state(tmp_page, NR_WRITEBACK_TEMP);
 
        err = 0;
-       if (is_writeback && fuse_writepage_in_flight(wpa, page)) {
+       if (data->wpa) {
+               /*
+                * Protected by fi->lock against concurrent access by
+                * fuse_page_is_writeback().
+                */
+               spin_lock(&fi->lock);
+               ap->num_pages++;
+               spin_unlock(&fi->lock);
+       } else if (fuse_writepage_add(wpa, page)) {
+               data->wpa = wpa;
+       } else {
                end_page_writeback(page);
-               data->wpa = NULL;
-               goto out_unlock;
        }
-       data->orig_pages[ap->num_pages] = page;
-
-       /*
-        * Protected by fi->lock against concurrent access by
-        * fuse_page_is_writeback().
-        */
-       spin_lock(&fi->lock);
-       ap->num_pages++;
-       spin_unlock(&fi->lock);
-
 out_unlock:
        unlock_page(page);
 
@@ -2149,10 +2166,8 @@ static int fuse_writepages(struct address_space *mapping,
 
        err = write_cache_pages(mapping, wbc, fuse_writepages_fill, &data);
        if (data.wpa) {
-               /* Ignore errors if we can write at least one page */
                WARN_ON(!data.wpa->ia.ap.num_pages);
                fuse_writepages_send(&data);
-               err = 0;
        }
        if (data.ff)
                fuse_file_put(data.ff, false, false);
@@ -2761,7 +2776,16 @@ long fuse_do_ioctl(struct file *file, unsigned int cmd, unsigned long arg,
                struct iovec *iov = iov_page;
 
                iov->iov_base = (void __user *)arg;
-               iov->iov_len = _IOC_SIZE(cmd);
+
+               switch (cmd) {
+               case FS_IOC_GETFLAGS:
+               case FS_IOC_SETFLAGS:
+                       iov->iov_len = sizeof(int);
+                       break;
+               default:
+                       iov->iov_len = _IOC_SIZE(cmd);
+                       break;
+               }
 
                if (_IOC_DIR(cmd) & _IOC_WRITE) {
                        in_iov = iov;
index 5b4aebf..bba7475 100644 (file)
@@ -121,10 +121,12 @@ static void fuse_evict_inode(struct inode *inode)
        }
 }
 
-static int fuse_remount_fs(struct super_block *sb, int *flags, char *data)
+static int fuse_reconfigure(struct fs_context *fc)
 {
+       struct super_block *sb = fc->root->d_sb;
+
        sync_filesystem(sb);
-       if (*flags & SB_MANDLOCK)
+       if (fc->sb_flags & SB_MANDLOCK)
                return -EINVAL;
 
        return 0;
@@ -475,6 +477,17 @@ static int fuse_parse_param(struct fs_context *fc, struct fs_parameter *param)
        struct fuse_fs_context *ctx = fc->fs_private;
        int opt;
 
+       if (fc->purpose == FS_CONTEXT_FOR_RECONFIGURE) {
+               /*
+                * Ignore options coming from mount(MS_REMOUNT) for backward
+                * compatibility.
+                */
+               if (fc->oldapi)
+                       return 0;
+
+               return invalfc(fc, "No changes allowed in reconfigure");
+       }
+
        opt = fs_parse(fc, fuse_fs_parameters, param, &result);
        if (opt < 0)
                return opt;
@@ -817,7 +830,6 @@ static const struct super_operations fuse_super_operations = {
        .evict_inode    = fuse_evict_inode,
        .write_inode    = fuse_write_inode,
        .drop_inode     = generic_delete_inode,
-       .remount_fs     = fuse_remount_fs,
        .put_super      = fuse_put_super,
        .umount_begin   = fuse_umount_begin,
        .statfs         = fuse_statfs,
@@ -1296,6 +1308,7 @@ static int fuse_get_tree(struct fs_context *fc)
 static const struct fs_context_operations fuse_context_ops = {
        .free           = fuse_free_fc,
        .parse_param    = fuse_parse_param,
+       .reconfigure    = fuse_reconfigure,
        .get_tree       = fuse_get_tree,
 };
 
index 9fd7e69..74bc4a0 100644 (file)
@@ -3845,10 +3845,16 @@ static int io_recvmsg(struct io_kiocb *req, bool force_nonblock)
 
                ret = __sys_recvmsg_sock(sock, &kmsg->msg, req->sr_msg.msg,
                                                kmsg->uaddr, flags);
-               if (force_nonblock && ret == -EAGAIN)
-                       return io_setup_async_msg(req, kmsg);
+               if (force_nonblock && ret == -EAGAIN) {
+                       ret = io_setup_async_msg(req, kmsg);
+                       if (ret != -EAGAIN)
+                               kfree(kbuf);
+                       return ret;
+               }
                if (ret == -ERESTARTSYS)
                        ret = -EINTR;
+               if (kbuf)
+                       kfree(kbuf);
        }
 
        if (kmsg && kmsg->iov != kmsg->fast_iov)
index f30ed40..4a0f600 100644 (file)
@@ -2603,6 +2603,7 @@ static int do_remount(struct path *path, int ms_flags, int sb_flags,
        if (IS_ERR(fc))
                return PTR_ERR(fc);
 
+       fc->oldapi = true;
        err = parse_monolithic_mount_data(fc, data);
        if (!err) {
                down_write(&sb->s_umount);
index 79dd052..5e0cde8 100644 (file)
@@ -895,7 +895,7 @@ static int ovl_copy_up_one(struct dentry *parent, struct dentry *dentry,
        return err;
 }
 
-int ovl_copy_up_flags(struct dentry *dentry, int flags)
+static int ovl_copy_up_flags(struct dentry *dentry, int flags)
 {
        int err = 0;
        const struct cred *old_cred = ovl_override_creds(dentry->d_sb);
index 8f42864..0e696f7 100644 (file)
@@ -476,7 +476,7 @@ static struct dentry *ovl_lookup_real_inode(struct super_block *sb,
        if (IS_ERR_OR_NULL(this))
                return this;
 
-       if (WARN_ON(ovl_dentry_real_at(this, layer->idx) != real)) {
+       if (ovl_dentry_real_at(this, layer->idx) != real) {
                dput(this);
                this = ERR_PTR(-EIO);
        }
index 01820e6..0d940e2 100644 (file)
@@ -33,13 +33,16 @@ static char ovl_whatisit(struct inode *inode, struct inode *realinode)
                return 'm';
 }
 
+/* No atime modificaton nor notify on underlying */
+#define OVL_OPEN_FLAGS (O_NOATIME | FMODE_NONOTIFY)
+
 static struct file *ovl_open_realfile(const struct file *file,
                                      struct inode *realinode)
 {
        struct inode *inode = file_inode(file);
        struct file *realfile;
        const struct cred *old_cred;
-       int flags = file->f_flags | O_NOATIME | FMODE_NONOTIFY;
+       int flags = file->f_flags | OVL_OPEN_FLAGS;
        int acc_mode = ACC_MODE(flags);
        int err;
 
@@ -72,8 +75,7 @@ static int ovl_change_flags(struct file *file, unsigned int flags)
        struct inode *inode = file_inode(file);
        int err;
 
-       /* No atime modificaton on underlying */
-       flags |= O_NOATIME | FMODE_NONOTIFY;
+       flags |= OVL_OPEN_FLAGS;
 
        /* If some flag changed that cannot be changed then something's amiss */
        if (WARN_ON((file->f_flags ^ flags) & ~OVL_SETFL_MASK))
@@ -126,7 +128,7 @@ static int ovl_real_fdget_meta(const struct file *file, struct fd *real,
        }
 
        /* Did the flags change since open? */
-       if (unlikely((file->f_flags ^ real->file->f_flags) & ~O_NOATIME))
+       if (unlikely((file->f_flags ^ real->file->f_flags) & ~OVL_OPEN_FLAGS))
                return ovl_change_flags(real->file, file->f_flags);
 
        return 0;
index 3566282..f7d4358 100644 (file)
@@ -389,7 +389,7 @@ invalid:
 }
 
 static int ovl_check_origin(struct ovl_fs *ofs, struct dentry *upperdentry,
-                           struct ovl_path **stackp, unsigned int *ctrp)
+                           struct ovl_path **stackp)
 {
        struct ovl_fh *fh = ovl_get_fh(upperdentry, OVL_XATTR_ORIGIN);
        int err;
@@ -406,10 +406,6 @@ static int ovl_check_origin(struct ovl_fs *ofs, struct dentry *upperdentry,
                return err;
        }
 
-       if (WARN_ON(*ctrp))
-               return -EIO;
-
-       *ctrp = 1;
        return 0;
 }
 
@@ -861,8 +857,6 @@ struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry,
                        goto out;
                }
                if (upperdentry && !d.is_dir) {
-                       unsigned int origin_ctr = 0;
-
                        /*
                         * Lookup copy up origin by decoding origin file handle.
                         * We may get a disconnected dentry, which is fine,
@@ -873,8 +867,7 @@ struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry,
                         * number - it's the same as if we held a reference
                         * to a dentry in lower layer that was moved under us.
                         */
-                       err = ovl_check_origin(ofs, upperdentry, &origin_path,
-                                              &origin_ctr);
+                       err = ovl_check_origin(ofs, upperdentry, &origin_path);
                        if (err)
                                goto out_put_upper;
 
@@ -1073,6 +1066,10 @@ struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry,
                        upperredirect = NULL;
                        goto out_free_oe;
                }
+               err = ovl_check_metacopy_xattr(upperdentry);
+               if (err < 0)
+                       goto out_free_oe;
+               uppermetacopy = err;
        }
 
        if (upperdentry || ctr) {
index b725c7f..29bc1ec 100644 (file)
@@ -483,7 +483,6 @@ void ovl_aio_request_cache_destroy(void);
 /* copy_up.c */
 int ovl_copy_up(struct dentry *dentry);
 int ovl_copy_up_with_data(struct dentry *dentry);
-int ovl_copy_up_flags(struct dentry *dentry, int flags);
 int ovl_maybe_copy_up(struct dentry *dentry, int flags);
 int ovl_copy_xattr(struct dentry *old, struct dentry *new);
 int ovl_set_attr(struct dentry *upper, struct kstat *stat);
index 91476bc..4b38141 100644 (file)
@@ -580,12 +580,19 @@ static int ovl_parse_opt(char *opt, struct ovl_config *config)
                }
        }
 
-       /* Workdir is useless in non-upper mount */
-       if (!config->upperdir && config->workdir) {
-               pr_info("option \"workdir=%s\" is useless in a non-upper mount, ignore\n",
-                       config->workdir);
-               kfree(config->workdir);
-               config->workdir = NULL;
+       /* Workdir/index are useless in non-upper mount */
+       if (!config->upperdir) {
+               if (config->workdir) {
+                       pr_info("option \"workdir=%s\" is useless in a non-upper mount, ignore\n",
+                               config->workdir);
+                       kfree(config->workdir);
+                       config->workdir = NULL;
+               }
+               if (config->index && index_opt) {
+                       pr_info("option \"index=on\" is useless in a non-upper mount, ignore\n");
+                       index_opt = false;
+               }
+               config->index = false;
        }
 
        err = ovl_parse_redirect_mode(config, config->redirect_mode);
@@ -622,11 +629,13 @@ static int ovl_parse_opt(char *opt, struct ovl_config *config)
 
        /* Resolve nfs_export -> index dependency */
        if (config->nfs_export && !config->index) {
-               if (nfs_export_opt && index_opt) {
+               if (!config->upperdir && config->redirect_follow) {
+                       pr_info("NFS export requires \"redirect_dir=nofollow\" on non-upper mount, falling back to nfs_export=off.\n");
+                       config->nfs_export = false;
+               } else if (nfs_export_opt && index_opt) {
                        pr_err("conflicting options: nfs_export=on,index=off\n");
                        return -EINVAL;
-               }
-               if (index_opt) {
+               } else if (index_opt) {
                        /*
                         * There was an explicit index=off that resulted
                         * in this conflict.
@@ -1352,8 +1361,15 @@ static int ovl_get_indexdir(struct super_block *sb, struct ovl_fs *ofs,
                goto out;
        }
 
+       /* index dir will act also as workdir */
+       iput(ofs->workdir_trap);
+       ofs->workdir_trap = NULL;
+       dput(ofs->workdir);
+       ofs->workdir = NULL;
        ofs->indexdir = ovl_workdir_create(ofs, OVL_INDEXDIR_NAME, true);
        if (ofs->indexdir) {
+               ofs->workdir = dget(ofs->indexdir);
+
                err = ovl_setup_trap(sb, ofs->indexdir, &ofs->indexdir_trap,
                                     "indexdir");
                if (err)
@@ -1396,6 +1412,18 @@ static bool ovl_lower_uuid_ok(struct ovl_fs *ofs, const uuid_t *uuid)
        if (!ofs->config.nfs_export && !ovl_upper_mnt(ofs))
                return true;
 
+       /*
+        * We allow using single lower with null uuid for index and nfs_export
+        * for example to support those features with single lower squashfs.
+        * To avoid regressions in setups of overlay with re-formatted lower
+        * squashfs, do not allow decoding origin with lower null uuid unless
+        * user opted-in to one of the new features that require following the
+        * lower inode of non-dir upper.
+        */
+       if (!ofs->config.index && !ofs->config.metacopy && !ofs->config.xino &&
+           uuid_is_null(uuid))
+               return false;
+
        for (i = 0; i < ofs->numfs; i++) {
                /*
                 * We use uuid to associate an overlay lower file handle with a
@@ -1493,14 +1521,23 @@ static int ovl_get_layers(struct super_block *sb, struct ovl_fs *ofs,
                if (err < 0)
                        goto out;
 
+               /*
+                * Check if lower root conflicts with this overlay layers before
+                * checking if it is in-use as upperdir/workdir of "another"
+                * mount, because we do not bother to check in ovl_is_inuse() if
+                * the upperdir/workdir is in fact in-use by our
+                * upperdir/workdir.
+                */
                err = ovl_setup_trap(sb, stack[i].dentry, &trap, "lowerdir");
                if (err)
                        goto out;
 
                if (ovl_is_inuse(stack[i].dentry)) {
                        err = ovl_report_in_use(ofs, "lowerdir");
-                       if (err)
+                       if (err) {
+                               iput(trap);
                                goto out;
+                       }
                }
 
                mnt = clone_private_mount(&stack[i]);
@@ -1575,10 +1612,6 @@ static struct ovl_entry *ovl_get_lowerstack(struct super_block *sb,
        if (!ofs->config.upperdir && numlower == 1) {
                pr_err("at least 2 lowerdir are needed while upperdir nonexistent\n");
                return ERR_PTR(-EINVAL);
-       } else if (!ofs->config.upperdir && ofs->config.nfs_export &&
-                  ofs->config.redirect_follow) {
-               pr_warn("NFS export requires \"redirect_dir=nofollow\" on non-upper mount, falling back to nfs_export=off.\n");
-               ofs->config.nfs_export = false;
        }
 
        stack = kcalloc(numlower, sizeof(struct path), GFP_KERNEL);
@@ -1842,21 +1875,13 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent)
        if (!ovl_upper_mnt(ofs))
                sb->s_flags |= SB_RDONLY;
 
-       if (!(ovl_force_readonly(ofs)) && ofs->config.index) {
-               /* index dir will act also as workdir */
-               dput(ofs->workdir);
-               ofs->workdir = NULL;
-               iput(ofs->workdir_trap);
-               ofs->workdir_trap = NULL;
-
+       if (!ovl_force_readonly(ofs) && ofs->config.index) {
                err = ovl_get_indexdir(sb, ofs, oe, &upperpath);
                if (err)
                        goto out_free_oe;
 
                /* Force r/o mount with no index dir */
-               if (ofs->indexdir)
-                       ofs->workdir = dget(ofs->indexdir);
-               else
+               if (!ofs->indexdir)
                        sb->s_flags |= SB_RDONLY;
        }
 
index 9439ff0..5698fca 100644 (file)
@@ -27,7 +27,7 @@
 #include <asm/smp.h>
 
 DECLARE_PER_CPU(struct mmiowb_state, __mmiowb_state);
-#define __mmiowb_state()       this_cpu_ptr(&__mmiowb_state)
+#define __mmiowb_state()       raw_cpu_ptr(&__mmiowb_state)
 #else
 #define __mmiowb_state()       arch_mmiowb_state()
 #endif /* arch_mmiowb_state */
@@ -35,7 +35,9 @@ DECLARE_PER_CPU(struct mmiowb_state, __mmiowb_state);
 static inline void mmiowb_set_pending(void)
 {
        struct mmiowb_state *ms = __mmiowb_state();
-       ms->mmiowb_pending = ms->nesting_count;
+
+       if (likely(ms->nesting_count))
+               ms->mmiowb_pending = ms->nesting_count;
 }
 
 static inline void mmiowb_spin_lock(void)
index 15460a5..5efed86 100644 (file)
@@ -433,7 +433,8 @@ enum dl_dev_state {
  * @suppliers: List of links to supplier devices.
  * @consumers: List of links to consumer devices.
  * @needs_suppliers: Hook to global list of devices waiting for suppliers.
- * @defer_sync: Hook to global list of devices that have deferred sync_state.
+ * @defer_hook: Hook to global list of devices that have deferred sync_state or
+ *             deferred fw_devlink.
  * @need_for_probe: If needs_suppliers is on a list, this indicates if the
  *                 suppliers are needed for probe or not.
  * @status: Driver status information.
@@ -442,7 +443,7 @@ struct dev_links_info {
        struct list_head suppliers;
        struct list_head consumers;
        struct list_head needs_suppliers;
-       struct list_head defer_sync;
+       struct list_head defer_hook;
        bool need_for_probe;
        enum dl_dev_state status;
 };
index ab0c156..a2ca294 100644 (file)
@@ -311,6 +311,7 @@ struct dma_buf {
        void *vmap_ptr;
        const char *exp_name;
        const char *name;
+       spinlock_t name_lock; /* spinlock to protect name access */
        struct module *owner;
        struct list_head list_node;
        void *priv;
index 5f24fcb..37e1e8f 100644 (file)
@@ -109,6 +109,7 @@ struct fs_context {
        enum fs_context_phase   phase:8;        /* The phase the context is in */
        bool                    need_free:1;    /* Need to call ops->free() */
        bool                    global:1;       /* Goes into &init_user_ns */
+       bool                    oldapi:1;       /* Coming from mount(2) */
 };
 
 struct fs_context_operations {
index 1ecb6b4..520858d 100644 (file)
@@ -67,8 +67,15 @@ static const struct acpi_device_id elan_acpi_id[] = {
        { "ELAN062B", 0 },
        { "ELAN062C", 0 },
        { "ELAN062D", 0 },
+       { "ELAN062E", 0 }, /* Lenovo V340 Whiskey Lake U */
+       { "ELAN062F", 0 }, /* Lenovo V340 Comet Lake U */
        { "ELAN0631", 0 },
        { "ELAN0632", 0 },
+       { "ELAN0633", 0 }, /* Lenovo S145 */
+       { "ELAN0634", 0 }, /* Lenovo V340 Ice lake */
+       { "ELAN0635", 0 }, /* Lenovo V1415-IIL */
+       { "ELAN0636", 0 }, /* Lenovo V1415-Dali */
+       { "ELAN0637", 0 }, /* Lenovo V1415-IGLR */
        { "ELAN1000", 0 },
        { }
 };
index 8d764aa..e14cbe4 100644 (file)
@@ -318,7 +318,7 @@ struct pcmcia_device_id {
 #define INPUT_DEVICE_ID_LED_MAX                0x0f
 #define INPUT_DEVICE_ID_SND_MAX                0x07
 #define INPUT_DEVICE_ID_FF_MAX         0x7f
-#define INPUT_DEVICE_ID_SW_MAX         0x0f
+#define INPUT_DEVICE_ID_SW_MAX         0x10
 #define INPUT_DEVICE_ID_PROP_MAX       0x1f
 
 #define INPUT_DEVICE_ID_MATCH_BUS      1
index 9fd550e..791f484 100644 (file)
@@ -462,10 +462,104 @@ extern void uart_handle_cts_change(struct uart_port *uport,
 extern void uart_insert_char(struct uart_port *port, unsigned int status,
                 unsigned int overrun, unsigned int ch, unsigned int flag);
 
-extern int uart_handle_sysrq_char(struct uart_port *port, unsigned int ch);
-extern int uart_prepare_sysrq_char(struct uart_port *port, unsigned int ch);
-extern void uart_unlock_and_check_sysrq(struct uart_port *port, unsigned long flags);
-extern int uart_handle_break(struct uart_port *port);
+#ifdef CONFIG_MAGIC_SYSRQ_SERIAL
+#define SYSRQ_TIMEOUT  (HZ * 5)
+
+bool uart_try_toggle_sysrq(struct uart_port *port, unsigned int ch);
+
+static inline int uart_handle_sysrq_char(struct uart_port *port, unsigned int ch)
+{
+       if (!port->sysrq)
+               return 0;
+
+       if (ch && time_before(jiffies, port->sysrq)) {
+               if (sysrq_mask()) {
+                       handle_sysrq(ch);
+                       port->sysrq = 0;
+                       return 1;
+               }
+               if (uart_try_toggle_sysrq(port, ch))
+                       return 1;
+       }
+       port->sysrq = 0;
+
+       return 0;
+}
+
+static inline int uart_prepare_sysrq_char(struct uart_port *port, unsigned int ch)
+{
+       if (!port->sysrq)
+               return 0;
+
+       if (ch && time_before(jiffies, port->sysrq)) {
+               if (sysrq_mask()) {
+                       port->sysrq_ch = ch;
+                       port->sysrq = 0;
+                       return 1;
+               }
+               if (uart_try_toggle_sysrq(port, ch))
+                       return 1;
+       }
+       port->sysrq = 0;
+
+       return 0;
+}
+
+static inline void uart_unlock_and_check_sysrq(struct uart_port *port, unsigned long irqflags)
+{
+       int sysrq_ch;
+
+       if (!port->has_sysrq) {
+               spin_unlock_irqrestore(&port->lock, irqflags);
+               return;
+       }
+
+       sysrq_ch = port->sysrq_ch;
+       port->sysrq_ch = 0;
+
+       spin_unlock_irqrestore(&port->lock, irqflags);
+
+       if (sysrq_ch)
+               handle_sysrq(sysrq_ch);
+}
+#else  /* CONFIG_MAGIC_SYSRQ_SERIAL */
+static inline int uart_handle_sysrq_char(struct uart_port *port, unsigned int ch)
+{
+       return 0;
+}
+static inline int uart_prepare_sysrq_char(struct uart_port *port, unsigned int ch)
+{
+       return 0;
+}
+static inline void uart_unlock_and_check_sysrq(struct uart_port *port, unsigned long irqflags)
+{
+       spin_unlock_irqrestore(&port->lock, irqflags);
+}
+#endif /* CONFIG_MAGIC_SYSRQ_SERIAL */
+
+/*
+ * We do the SysRQ and SAK checking like this...
+ */
+static inline int uart_handle_break(struct uart_port *port)
+{
+       struct uart_state *state = port->state;
+
+       if (port->handle_break)
+               port->handle_break(port);
+
+#ifdef CONFIG_MAGIC_SYSRQ_SERIAL
+       if (port->has_sysrq && uart_console(port)) {
+               if (!port->sysrq) {
+                       port->sysrq = jiffies + SYSRQ_TIMEOUT;
+                       return 1;
+               }
+               port->sysrq = 0;
+       }
+#endif
+       if (port->flags & UPF_SAK)
+               do_SAK(state->port.tty);
+       return 0;
+}
 
 /*
  *     UART_ENABLE_MS - determine if port should enable modem status irqs
index 1f412fb..e103c14 100644 (file)
@@ -110,9 +110,12 @@ struct dsa_hw_desc {
        uint16_t        rsvd1;
        union {
                uint8_t         expected_res;
+               /* create delta record */
                struct {
                        uint64_t        delta_addr;
                        uint32_t        max_delta_size;
+                       uint32_t        delt_rsvd;
+                       uint8_t         expected_res_mask;
                };
                uint32_t        delta_rec_size;
                uint64_t        dest2;
index b6a835d..0c2e27d 100644 (file)
 #define SW_LINEIN_INSERT       0x0d  /* set = inserted */
 #define SW_MUTE_DEVICE         0x0e  /* set = device disabled */
 #define SW_PEN_INSERTED                0x0f  /* set = pen inserted */
-#define SW_MAX                 0x0f
+#define SW_MACHINE_COVER       0x10  /* set = cover closed */
+#define SW_MAX                 0x10
 #define SW_CNT                 (SW_MAX+1)
 
 /*
index 9cec58a..f79d7ab 100644 (file)
@@ -103,7 +103,7 @@ VMMDEV_ASSERT_SIZE(vbg_ioctl_driver_version_info, 24 + 20);
 
 
 /* IOCTL to perform a VMM Device request larger then 1KB. */
-#define VBG_IOCTL_VMMDEV_REQUEST_BIG   _IOC(_IOC_READ | _IOC_WRITE, 'V', 3, 0)
+#define VBG_IOCTL_VMMDEV_REQUEST_BIG   _IO('V', 3)
 
 
 /** VBG_IOCTL_HGCM_CONNECT data structure. */
@@ -198,7 +198,7 @@ struct vbg_ioctl_log {
        } u;
 };
 
-#define VBG_IOCTL_LOG(s)               _IOC(_IOC_READ | _IOC_WRITE, 'V', 9, s)
+#define VBG_IOCTL_LOG(s)               _IO('V', 9)
 
 
 /** VBG_IOCTL_WAIT_FOR_EVENTS data structure. */
index 5dd572d..6b153dc 100644 (file)
@@ -206,9 +206,28 @@ static bool move_normal_pmd(struct vm_area_struct *vma, unsigned long old_addr,
 
        /*
         * The destination pmd shouldn't be established, free_pgtables()
-        * should have release it.
+        * should have released it.
+        *
+        * However, there's a case during execve() where we use mremap
+        * to move the initial stack, and in that case the target area
+        * may overlap the source area (always moving down).
+        *
+        * If everything is PMD-aligned, that works fine, as moving
+        * each pmd down will clear the source pmd. But if we first
+        * have a few 4kB-only pages that get moved down, and then
+        * hit the "now the rest is PMD-aligned, let's do everything
+        * one pmd at a time", we will still have the old (now empty
+        * of any 4kB pages, but still there) PMD in the page table
+        * tree.
+        *
+        * Warn on it once - because we really should try to figure
+        * out how to do this better - but then say "I won't move
+        * this pmd".
+        *
+        * One alternative might be to just unmap the target pmd at
+        * this point, and verify that it really is empty. We'll see.
         */
-       if (WARN_ON(!pmd_none(*new_pmd)))
+       if (WARN_ON_ONCE(!pmd_none(*new_pmd)))
                return false;
 
        /*
index 194ffa8..1b06c42 100644 (file)
@@ -6152,6 +6152,8 @@ enum {
        ALC269VC_FIXUP_ACER_VCOPPERBOX_PINS,
        ALC269VC_FIXUP_ACER_HEADSET_MIC,
        ALC269VC_FIXUP_ACER_MIC_NO_PRESENCE,
+       ALC289_FIXUP_ASUS_G401,
+       ALC256_FIXUP_ACER_MIC_NO_PRESENCE,
 };
 
 static const struct hda_fixup alc269_fixups[] = {
@@ -7117,7 +7119,7 @@ static const struct hda_fixup alc269_fixups[] = {
                        { }
                },
                .chained = true,
-               .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC
+               .chain_id = ALC269_FIXUP_HEADSET_MIC
        },
        [ALC294_FIXUP_ASUS_HEADSET_MIC] = {
                .type = HDA_FIXUP_PINS,
@@ -7126,7 +7128,7 @@ static const struct hda_fixup alc269_fixups[] = {
                        { }
                },
                .chained = true,
-               .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC
+               .chain_id = ALC269_FIXUP_HEADSET_MIC
        },
        [ALC294_FIXUP_ASUS_SPK] = {
                .type = HDA_FIXUP_VERBS,
@@ -7134,6 +7136,8 @@ static const struct hda_fixup alc269_fixups[] = {
                        /* Set EAPD high */
                        { 0x20, AC_VERB_SET_COEF_INDEX, 0x40 },
                        { 0x20, AC_VERB_SET_PROC_COEF, 0x8800 },
+                       { 0x20, AC_VERB_SET_COEF_INDEX, 0x0f },
+                       { 0x20, AC_VERB_SET_PROC_COEF, 0x7774 },
                        { }
                },
                .chained = true,
@@ -7359,6 +7363,22 @@ static const struct hda_fixup alc269_fixups[] = {
                .chained = true,
                .chain_id = ALC269_FIXUP_HEADSET_MIC
        },
+       [ALC289_FIXUP_ASUS_G401] = {
+               .type = HDA_FIXUP_PINS,
+               .v.pins = (const struct hda_pintbl[]) {
+                       { 0x19, 0x03a11020 }, /* headset mic with jack detect */
+                       { }
+               },
+       },
+       [ALC256_FIXUP_ACER_MIC_NO_PRESENCE] = {
+               .type = HDA_FIXUP_PINS,
+               .v.pins = (const struct hda_pintbl[]) {
+                       { 0x19, 0x02a11120 }, /* use as headset mic, without its own jack detect */
+                       { }
+               },
+               .chained = true,
+               .chain_id = ALC256_FIXUP_ASUS_HEADSET_MODE
+       },
 };
 
 static const struct snd_pci_quirk alc269_fixup_tbl[] = {
@@ -7387,6 +7407,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
        SND_PCI_QUIRK(0x1025, 0x1308, "Acer Aspire Z24-890", ALC286_FIXUP_ACER_AIO_HEADSET_MIC),
        SND_PCI_QUIRK(0x1025, 0x132a, "Acer TravelMate B114-21", ALC233_FIXUP_ACER_HEADSET_MIC),
        SND_PCI_QUIRK(0x1025, 0x1330, "Acer TravelMate X514-51T", ALC255_FIXUP_ACER_HEADSET_MIC),
+       SND_PCI_QUIRK(0x1025, 0x1430, "Acer TravelMate B311R-31", ALC256_FIXUP_ACER_MIC_NO_PRESENCE),
        SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z),
        SND_PCI_QUIRK(0x1028, 0x054b, "Dell XPS one 2710", ALC275_FIXUP_DELL_XPS),
        SND_PCI_QUIRK(0x1028, 0x05bd, "Dell Latitude E6440", ALC292_FIXUP_DELL_E7X),
@@ -7530,6 +7551,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
        SND_PCI_QUIRK(0x1043, 0x17d1, "ASUS UX431FL", ALC294_FIXUP_ASUS_DUAL_SPK),
        SND_PCI_QUIRK(0x1043, 0x18b1, "Asus MJ401TA", ALC256_FIXUP_ASUS_HEADSET_MIC),
        SND_PCI_QUIRK(0x1043, 0x18f1, "Asus FX505DT", ALC256_FIXUP_ASUS_HEADSET_MIC),
+       SND_PCI_QUIRK(0x1043, 0x194e, "ASUS UX563FD", ALC294_FIXUP_ASUS_HPE),
        SND_PCI_QUIRK(0x1043, 0x19ce, "ASUS B9450FA", ALC294_FIXUP_ASUS_HPE),
        SND_PCI_QUIRK(0x1043, 0x19e1, "ASUS UX581LV", ALC295_FIXUP_ASUS_MIC_NO_PRESENCE),
        SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW),
@@ -7539,6 +7561,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
        SND_PCI_QUIRK(0x1043, 0x1bbd, "ASUS Z550MA", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE),
        SND_PCI_QUIRK(0x1043, 0x1c23, "Asus X55U", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
        SND_PCI_QUIRK(0x1043, 0x1ccd, "ASUS X555UB", ALC256_FIXUP_ASUS_MIC),
+       SND_PCI_QUIRK(0x1043, 0x1f11, "ASUS Zephyrus G14", ALC289_FIXUP_ASUS_G401),
        SND_PCI_QUIRK(0x1043, 0x3030, "ASUS ZN270IE", ALC256_FIXUP_ASUS_AIO_GPIO2),
        SND_PCI_QUIRK(0x1043, 0x831a, "ASUS P901", ALC269_FIXUP_STEREO_DMIC),
        SND_PCI_QUIRK(0x1043, 0x834a, "ASUS S101", ALC269_FIXUP_STEREO_DMIC),
@@ -7558,6 +7581,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
        SND_PCI_QUIRK(0x10cf, 0x1629, "Lifebook U7x7", ALC255_FIXUP_LIFEBOOK_U7x7_HEADSET_MIC),
        SND_PCI_QUIRK(0x10cf, 0x1845, "Lifebook U904", ALC269_FIXUP_LIFEBOOK_EXTMIC),
        SND_PCI_QUIRK(0x10ec, 0x10f2, "Intel Reference board", ALC700_FIXUP_INTEL_REFERENCE),
+       SND_PCI_QUIRK(0x10ec, 0x1230, "Intel Reference board", ALC225_FIXUP_HEADSET_JACK),
        SND_PCI_QUIRK(0x10f7, 0x8338, "Panasonic CF-SZ6", ALC269_FIXUP_HEADSET_MODE),
        SND_PCI_QUIRK(0x144d, 0xc109, "Samsung Ativ book 9 (NP900X3G)", ALC269_FIXUP_INV_DMIC),
        SND_PCI_QUIRK(0x144d, 0xc169, "Samsung Notebook 9 Pen (NP930SBE-K01US)", ALC298_FIXUP_SAMSUNG_HEADPHONE_VERY_QUIET),
index 663d608..970c9bd 100644 (file)
@@ -286,6 +286,8 @@ int line6_create_audio_in_urbs(struct snd_line6_pcm *line6pcm)
                urb->interval = LINE6_ISO_INTERVAL;
                urb->error_count = 0;
                urb->complete = audio_in_callback;
+               if (usb_urb_ep_type_check(urb))
+                       return -EINVAL;
        }
 
        return 0;
index 7629116..2746d96 100644 (file)
@@ -840,7 +840,7 @@ void line6_disconnect(struct usb_interface *interface)
        if (WARN_ON(usbdev != line6->usbdev))
                return;
 
-       cancel_delayed_work(&line6->startup_work);
+       cancel_delayed_work_sync(&line6->startup_work);
 
        if (line6->urb_listen != NULL)
                line6_stop_listen(line6);
index 01930ce..8233c61 100644 (file)
@@ -431,6 +431,8 @@ int line6_create_audio_out_urbs(struct snd_line6_pcm *line6pcm)
                urb->interval = LINE6_ISO_INTERVAL;
                urb->error_count = 0;
                urb->complete = audio_out_callback;
+               if (usb_urb_ep_type_check(urb))
+                       return -EINVAL;
        }
 
        return 0;
index 047b905..354f576 100644 (file)
@@ -1499,6 +1499,8 @@ void snd_usbmidi_disconnect(struct list_head *p)
        spin_unlock_irq(&umidi->disc_lock);
        up_write(&umidi->disc_rwsem);
 
+       del_timer_sync(&umidi->error_timer);
+
        for (i = 0; i < MIDI_MAX_ENDPOINTS; ++i) {
                struct snd_usb_midi_endpoint *ep = &umidi->endpoints[i];
                if (ep->out)
@@ -1525,7 +1527,6 @@ void snd_usbmidi_disconnect(struct list_head *p)
                        ep->in = NULL;
                }
        }
-       del_timer_sync(&umidi->error_timer);
 }
 EXPORT_SYMBOL(snd_usbmidi_disconnect);
 
@@ -2301,16 +2302,22 @@ void snd_usbmidi_input_stop(struct list_head *p)
 }
 EXPORT_SYMBOL(snd_usbmidi_input_stop);
 
-static void snd_usbmidi_input_start_ep(struct snd_usb_midi_in_endpoint *ep)
+static void snd_usbmidi_input_start_ep(struct snd_usb_midi *umidi,
+                                      struct snd_usb_midi_in_endpoint *ep)
 {
        unsigned int i;
+       unsigned long flags;
 
        if (!ep)
                return;
        for (i = 0; i < INPUT_URBS; ++i) {
                struct urb *urb = ep->urbs[i];
-               urb->dev = ep->umidi->dev;
-               snd_usbmidi_submit_urb(urb, GFP_KERNEL);
+               spin_lock_irqsave(&umidi->disc_lock, flags);
+               if (!atomic_read(&urb->use_count)) {
+                       urb->dev = ep->umidi->dev;
+                       snd_usbmidi_submit_urb(urb, GFP_ATOMIC);
+               }
+               spin_unlock_irqrestore(&umidi->disc_lock, flags);
        }
 }
 
@@ -2326,7 +2333,7 @@ void snd_usbmidi_input_start(struct list_head *p)
        if (umidi->input_running || !umidi->opened[1])
                return;
        for (i = 0; i < MIDI_MAX_ENDPOINTS; ++i)
-               snd_usbmidi_input_start_ep(umidi->endpoints[i].in);
+               snd_usbmidi_input_start_ep(umidi, umidi->endpoints[i].in);
        umidi->input_running = 1;
 }
 EXPORT_SYMBOL(snd_usbmidi_input_start);