Merge branch 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
authorLinus Torvalds <torvalds@linux-foundation.org>
Sun, 22 Oct 2017 10:58:23 +0000 (06:58 -0400)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sun, 22 Oct 2017 10:58:23 +0000 (06:58 -0400)
Pull x86 fixes from Thomas Gleixner:
 "A couple of fixes addressing the following issues:

   - The last polishing for the TLB code, removing the last BUG_ON() and
     the debug file along with tidying up the lazy TLB code.

   - Prevent triple fault on 1st Gen. 486 caused by stupidly calling the
     early IDT setup after the first function which causes a fault which
     should be caught by the exception table.

   - Limit the mmap of /dev/mem to valid addresses

   - Prevent late microcode loading on Broadwell X

   - Remove a redundant assignment in the cache info code"

* 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  x86/mm: Limit mmap() of /dev/mem to valid physical addresses
  x86/mm: Remove debug/x86/tlb_defer_switch_to_init_mm
  x86/mm: Tidy up "x86/mm: Flush more aggressively in lazy TLB mode"
  x86/mm/64: Remove the last VM_BUG_ON() from the TLB code
  x86/microcode/intel: Disable late loading on model 79
  x86/idt: Initialize early IDT before cr4_init_shadow()
  x86/cpu/intel_cacheinfo: Remove redundant assignment to 'this_leaf'

276 files changed:
Documentation/core-api/kernel-api.rst
Documentation/devicetree/bindings/interrupt-controller/arm,gic-v3.txt
Documentation/process/index.rst
Documentation/process/kernel-enforcement-statement.rst [new file with mode: 0644]
MAINTAINERS
arch/arm/Makefile
arch/arm/boot/compressed/debug.S
arch/arm/boot/dts/armada-38x.dtsi
arch/arm/boot/dts/at91-sama5d27_som1.dtsi
arch/arm/boot/dts/at91-sama5d2_xplained.dts
arch/arm/boot/dts/bcm2835-rpi-zero-w.dts
arch/arm/boot/dts/bcm2837-rpi-3-b.dts
arch/arm/boot/dts/bcm283x.dtsi
arch/arm/boot/dts/gemini.dtsi
arch/arm/boot/dts/imx7d.dtsi
arch/arm/boot/dts/moxart.dtsi
arch/arm/boot/dts/sama5d2.dtsi
arch/arm/boot/dts/sun6i-a31.dtsi
arch/arm/kernel/debug.S
arch/arm/mach-ux500/cpu-db8500.c
arch/arm/mach-ux500/pm.c
arch/arm/mm/nommu.c
arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts
arch/arm64/boot/dts/marvell/armada-cp110-master.dtsi
arch/arm64/boot/dts/marvell/armada-cp110-slave.dtsi
arch/arm64/boot/dts/renesas/salvator-common.dtsi
arch/arm64/boot/dts/rockchip/rk3328.dtsi
arch/arm64/boot/dts/rockchip/rk3368.dtsi
arch/arm64/boot/dts/rockchip/rk3399-firefly.dts
arch/arm64/boot/dts/rockchip/rk3399-puma.dtsi
arch/arm64/boot/dts/rockchip/rk3399-sapphire.dtsi
arch/parisc/kernel/parisc_ksyms.c
arch/parisc/kernel/syscall.S
arch/parisc/kernel/time.c
arch/s390/configs/zfcpdump_defconfig
arch/s390/kernel/smp.c
crypto/asymmetric_keys/asymmetric_type.c
crypto/asymmetric_keys/pkcs7_parser.c
drivers/block/nbd.c
drivers/block/skd_main.c
drivers/bus/mvebu-mbus.c
drivers/clocksource/cs5535-clockevt.c
drivers/dma/altera-msgdma.c
drivers/gpu/drm/amd/scheduler/gpu_scheduler.c
drivers/gpu/drm/exynos/exynos_drm_drv.c
drivers/gpu/drm/i915/gvt/sched_policy.c
drivers/gpu/drm/i915/i915_gem.c
drivers/gpu/drm/i915/i915_gem_evict.c
drivers/gpu/drm/i915/i915_reg.h
drivers/gpu/drm/i915/intel_ddi.c
drivers/gpu/drm/i915/intel_dpll_mgr.c
drivers/gpu/drm/i915/intel_engine_cs.c
drivers/gpu/drm/i915/intel_pm.c
drivers/gpu/drm/nouveau/nouveau_fbcon.c
drivers/gpu/drm/nouveau/nv50_display.c
drivers/gpu/drm/nouveau/nvkm/engine/bsp/g84.c
drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c
drivers/i2c/busses/i2c-imx.c
drivers/i2c/busses/i2c-ismt.c
drivers/i2c/busses/i2c-omap.c
drivers/i2c/busses/i2c-piix4.c
drivers/input/input.c
drivers/input/joydev.c
drivers/input/keyboard/tca8418_keypad.c
drivers/input/misc/axp20x-pek.c
drivers/input/misc/ims-pcu.c
drivers/input/mouse/synaptics.c
drivers/input/touchscreen/goodix.c
drivers/input/touchscreen/stmfts.c
drivers/input/touchscreen/ti_am335x_tsc.c
drivers/irqchip/irq-gic-v3-its.c
drivers/irqchip/irq-tango.c
drivers/media/cec/cec-adap.c
drivers/media/dvb-core/dvb_frontend.c
drivers/media/dvb-frontends/dib3000mc.c
drivers/media/dvb-frontends/dvb-pll.c
drivers/media/platform/Kconfig
drivers/media/platform/qcom/camss-8x16/camss-vfe.c
drivers/media/platform/qcom/venus/helpers.c
drivers/media/platform/s5p-cec/exynos_hdmi_cecctrl.c
drivers/media/platform/s5p-cec/s5p_cec.c
drivers/media/platform/s5p-cec/s5p_cec.h
drivers/media/tuners/mt2060.c
drivers/mmc/host/sdhci-pci-core.c
drivers/net/can/flexcan.c
drivers/net/can/usb/esd_usb2.c
drivers/net/can/usb/gs_usb.c
drivers/net/dsa/mv88e6060.c
drivers/net/ethernet/amazon/ena/ena_ethtool.c
drivers/net/ethernet/amazon/ena/ena_netdev.c
drivers/net/ethernet/aquantia/atlantic/aq_cfg.h
drivers/net/ethernet/aquantia/atlantic/aq_ethtool.c
drivers/net/ethernet/aquantia/atlantic/aq_hw.h
drivers/net/ethernet/aquantia/atlantic/aq_nic.c
drivers/net/ethernet/aquantia/atlantic/aq_nic.h
drivers/net/ethernet/aquantia/atlantic/aq_pci_func.c
drivers/net/ethernet/aquantia/atlantic/aq_vec.c
drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c
drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c
drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0_internal.h
drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.c
drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.h
drivers/net/ethernet/broadcom/bnxt/bnxt.c
drivers/net/ethernet/broadcom/bnxt/bnxt.h
drivers/net/ethernet/broadcom/bnxt/bnxt_dcb.c
drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c
drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c
drivers/net/ethernet/cavium/liquidio/lio_main.c
drivers/net/ethernet/ibm/ibmvnic.c
drivers/net/ethernet/intel/i40e/i40e_nvm.c
drivers/net/ethernet/intel/i40e/i40e_txrx.c
drivers/net/ethernet/mellanox/mlxsw/core.c
drivers/net/ethernet/mellanox/mlxsw/reg.h
drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
drivers/net/ethernet/netronome/nfp/nfp_net_common.c
drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c
drivers/net/ethernet/realtek/r8169.c
drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c
drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
drivers/net/geneve.c
drivers/net/macsec.c
drivers/net/tun.c
drivers/net/wimax/i2400m/fw.c
drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c
drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_n.c
drivers/net/wireless/intel/iwlwifi/cfg/7000.c
drivers/net/wireless/intel/iwlwifi/cfg/8000.c
drivers/net/wireless/intel/iwlwifi/cfg/9000.c
drivers/net/wireless/intel/iwlwifi/cfg/a000.c
drivers/net/wireless/intel/iwlwifi/fw/api/nvm-reg.h
drivers/net/wireless/intel/iwlwifi/fw/dbg.c
drivers/net/wireless/intel/iwlwifi/fw/dbg.h
drivers/net/wireless/intel/iwlwifi/iwl-config.h
drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c
drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
drivers/net/wireless/intel/iwlwifi/mvm/nvm.c
drivers/net/wireless/intel/iwlwifi/mvm/rx.c
drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c
drivers/net/wireless/intel/iwlwifi/mvm/tt.c
drivers/net/wireless/realtek/rtlwifi/rtl8821ae/hw.c
drivers/net/xen-netback/interface.c
drivers/net/xen-netfront.c
drivers/of/of_mdio.c
drivers/reset/reset-socfpga.c
drivers/scsi/libfc/fc_rport.c
drivers/scsi/libiscsi.c
drivers/scsi/qla2xxx/qla_os.c
drivers/scsi/scsi_sysfs.c
drivers/scsi/scsi_transport_fc.c
drivers/staging/media/imx/imx-media-dev.c
fs/btrfs/super.c
fs/crypto/keyinfo.c
fs/direct-io.c
fs/ecryptfs/ecryptfs_kernel.h
fs/ecryptfs/keystore.c
fs/exec.c
fs/ext4/super.c
fs/fscache/object-list.c
fs/fuse/inode.c
fs/iomap.c
fs/namespace.c
fs/xfs/libxfs/xfs_bmap.c
fs/xfs/libxfs/xfs_bmap.h
fs/xfs/xfs_aops.c
fs/xfs/xfs_fsmap.c
fs/xfs/xfs_super.c
include/linux/filter.h
include/linux/input.h
include/linux/irq.h
include/linux/irqchip/arm-gic-v3.h
include/linux/key.h
include/linux/mbus.h
include/linux/mm_types.h
include/linux/mod_devicetable.h
include/linux/netdevice.h
include/linux/rculist.h
include/linux/rcupdate.h
include/linux/sched/mm.h
include/linux/srcu.h
include/net/inet_sock.h
include/net/tcp.h
include/sound/control.h
include/uapi/linux/membarrier.h
kernel/bpf/arraymap.c
kernel/bpf/devmap.c
kernel/bpf/hashtab.c
kernel/bpf/sockmap.c
kernel/bpf/verifier.c
kernel/cpu.c
kernel/exit.c
kernel/irq/generic-chip.c
kernel/rcu/srcutree.c
kernel/rcu/sync.c
kernel/rcu/tree.c
kernel/sched/membarrier.c
lib/digsig.c
lib/ts_fsm.c
lib/ts_kmp.c
mm/memcontrol.c
mm/percpu.c
net/bridge/br_netlink.c
net/can/af_can.c
net/can/bcm.c
net/core/dev.c
net/core/dev_ioctl.c
net/core/ethtool.c
net/core/filter.c
net/core/rtnetlink.c
net/core/skbuff.c
net/core/sock.c
net/core/sock_reuseport.c
net/dccp/ipv4.c
net/dns_resolver/dns_key.c
net/ipv4/Kconfig
net/ipv4/cipso_ipv4.c
net/ipv4/inet_connection_sock.c
net/ipv4/inet_hashtables.c
net/ipv4/syncookies.c
net/ipv4/tcp_input.c
net/ipv4/tcp_ipv4.c
net/ipv4/udp.c
net/ipv6/ip6_flowlabel.c
net/ipv6/ip6_output.c
net/l2tp/l2tp_ppp.c
net/mac80211/key.c
net/ncsi/internal.h
net/ncsi/ncsi-aen.c
net/ncsi/ncsi-manage.c
net/ncsi/ncsi-rsp.c
net/netlink/af_netlink.c
net/packet/af_packet.c
net/rxrpc/af_rxrpc.c
net/sched/cls_flower.c
net/sctp/input.c
net/sctp/socket.c
net/vmw_vsock/hyperv_transport.c
samples/sockmap/sockmap_kern.c
samples/trace_events/trace-events-sample.c
scripts/mod/devicetable-offsets.c
scripts/mod/file2alias.c
security/commoncap.c
security/keys/Kconfig
security/keys/big_key.c
security/keys/encrypted-keys/encrypted.c
security/keys/gc.c
security/keys/key.c
security/keys/keyctl.c
security/keys/keyring.c
security/keys/permission.c
security/keys/proc.c
security/keys/process_keys.c
security/keys/request_key.c
security/keys/request_key_auth.c
security/keys/trusted.c
security/keys/user_defined.c
sound/core/seq/seq_lock.c
sound/core/seq/seq_lock.h
sound/core/vmaster.c
sound/hda/hdac_controller.c
sound/pci/hda/hda_codec.c
sound/usb/quirks.c
tools/include/uapi/linux/bpf.h
tools/objtool/check.c
tools/perf/Documentation/perf-record.txt
tools/perf/tests/shell/trace+probe_libc_inet_pton.sh
tools/perf/ui/hist.c
tools/perf/util/parse-events.l
tools/perf/util/session.c
tools/perf/util/xyarray.h
tools/power/x86/turbostat/turbostat.c
tools/testing/selftests/bpf/bpf_helpers.h
tools/testing/selftests/bpf/sockmap_verdict_prog.c
tools/testing/selftests/bpf/test_maps.c
tools/testing/selftests/bpf/test_verifier.c

index 8282099e0cbf446bbebaaf63868ca04610999408..5da10184d9084a77c15e42b56f76a4571193344a 100644 (file)
@@ -352,44 +352,30 @@ Read-Copy Update (RCU)
 ----------------------
 
 .. kernel-doc:: include/linux/rcupdate.h
-   :external:
 
 .. kernel-doc:: include/linux/rcupdate_wait.h
-   :external:
 
 .. kernel-doc:: include/linux/rcutree.h
-   :external:
 
 .. kernel-doc:: kernel/rcu/tree.c
-   :external:
 
 .. kernel-doc:: kernel/rcu/tree_plugin.h
-   :external:
 
 .. kernel-doc:: kernel/rcu/tree_exp.h
-   :external:
 
 .. kernel-doc:: kernel/rcu/update.c
-   :external:
 
 .. kernel-doc:: include/linux/srcu.h
-   :external:
 
 .. kernel-doc:: kernel/rcu/srcutree.c
-   :external:
 
 .. kernel-doc:: include/linux/rculist_bl.h
-   :external:
 
 .. kernel-doc:: include/linux/rculist.h
-   :external:
 
 .. kernel-doc:: include/linux/rculist_nulls.h
-   :external:
 
 .. kernel-doc:: include/linux/rcu_sync.h
-   :external:
 
 .. kernel-doc:: kernel/rcu/sync.c
-   :external:
 
index 4c29cdab0ea5b72985168100891e2422e8dbb252..5eb108e180fa282711a4d448c8353196ae6cadf1 100644 (file)
@@ -99,7 +99,7 @@ Examples:
                        compatible = "arm,gic-v3-its";
                        msi-controller;
                        #msi-cells = <1>;
-                       reg = <0x0 0x2c200000 0 0x200000>;
+                       reg = <0x0 0x2c200000 0 0x20000>;
                };
        };
 
@@ -124,14 +124,14 @@ Examples:
                        compatible = "arm,gic-v3-its";
                        msi-controller;
                        #msi-cells = <1>;
-                       reg = <0x0 0x2c200000 0 0x200000>;
+                       reg = <0x0 0x2c200000 0 0x20000>;
                };
 
                gic-its@2c400000 {
                        compatible = "arm,gic-v3-its";
                        msi-controller;
                        #msi-cells = <1>;
-                       reg = <0x0 0x2c400000 0 0x200000>;
+                       reg = <0x0 0x2c400000 0 0x20000>;
                };
 
                ppi-partitions {
index 82fc399fcd33d1628289ec5ccfeb3193a368c2fc..61e43cc3ed171e2371b6372609533dc16fc9b057 100644 (file)
@@ -25,6 +25,7 @@ Below are the essential guides that every developer should read.
    submitting-patches
    coding-style
    email-clients
+   kernel-enforcement-statement
 
 Other guides to the community that are of interest to most developers are: 
 
diff --git a/Documentation/process/kernel-enforcement-statement.rst b/Documentation/process/kernel-enforcement-statement.rst
new file mode 100644 (file)
index 0000000..1e23d42
--- /dev/null
@@ -0,0 +1,147 @@
+Linux Kernel Enforcement Statement
+----------------------------------
+
+As developers of the Linux kernel, we have a keen interest in how our software
+is used and how the license for our software is enforced.  Compliance with the
+reciprocal sharing obligations of GPL-2.0 is critical to the long-term
+sustainability of our software and community.
+
+Although there is a right to enforce the separate copyright interests in the
+contributions made to our community, we share an interest in ensuring that
+individual enforcement actions are conducted in a manner that benefits our
+community and do not have an unintended negative impact on the health and
+growth of our software ecosystem.  In order to deter unhelpful enforcement
+actions, we agree that it is in the best interests of our development
+community to undertake the following commitment to users of the Linux kernel
+on behalf of ourselves and any successors to our copyright interests:
+
+    Notwithstanding the termination provisions of the GPL-2.0, we agree that
+    it is in the best interests of our development community to adopt the
+    following provisions of GPL-3.0 as additional permissions under our
+    license with respect to any non-defensive assertion of rights under the
+    license.
+
+       However, if you cease all violation of this License, then your license
+       from a particular copyright holder is reinstated (a) provisionally,
+       unless and until the copyright holder explicitly and finally
+       terminates your license, and (b) permanently, if the copyright holder
+       fails to notify you of the violation by some reasonable means prior to
+       60 days after the cessation.
+
+       Moreover, your license from a particular copyright holder is
+       reinstated permanently if the copyright holder notifies you of the
+       violation by some reasonable means, this is the first time you have
+       received notice of violation of this License (for any work) from that
+       copyright holder, and you cure the violation prior to 30 days after
+       your receipt of the notice.
+
+Our intent in providing these assurances is to encourage more use of the
+software.  We want companies and individuals to use, modify and distribute
+this software.  We want to work with users in an open and transparent way to
+eliminate any uncertainty about our expectations regarding compliance or
+enforcement that might limit adoption of our software.  We view legal action
+as a last resort, to be initiated only when other community efforts have
+failed to resolve the problem.
+
+Finally, once a non-compliance issue is resolved, we hope the user will feel
+welcome to join us in our efforts on this project.  Working together, we will
+be stronger.
+
+Except where noted below, we speak only for ourselves, and not for any company
+we might work for today, have in the past, or will in the future.
+
+  - Bjorn Andersson (Linaro)
+  - Andrea Arcangeli (Red Hat)
+  - Neil Armstrong
+  - Jens Axboe
+  - Pablo Neira Ayuso
+  - Khalid Aziz
+  - Ralf Baechle
+  - Felipe Balbi
+  - Arnd Bergmann
+  - Ard Biesheuvel
+  - Paolo Bonzini (Red Hat)
+  - Christian Borntraeger
+  - Mark Brown (Linaro)
+  - Paul Burton
+  - Javier Martinez Canillas
+  - Rob Clark
+  - Jonathan Corbet
+  - Vivien Didelot (Savoir-faire Linux)
+  - Hans de Goede (Red Hat)
+  - Mel Gorman (SUSE)
+  - Sven Eckelmann
+  - Alex Elder (Linaro)
+  - Fabio Estevam
+  - Larry Finger
+  - Bhumika Goyal
+  - Andy Gross
+  - Juergen Gross
+  - Shawn Guo
+  - Ulf Hansson
+  - Tejun Heo
+  - Rob Herring
+  - Masami Hiramatsu
+  - Michal Hocko
+  - Simon Horman
+  - Johan Hovold (Hovold Consulting AB)
+  - Christophe JAILLET
+  - Olof Johansson
+  - Lee Jones (Linaro)
+  - Heiner Kallweit
+  - Srinivas Kandagatla
+  - Jan Kara
+  - Shuah Khan (Samsung)
+  - David Kershner
+  - Jaegeuk Kim
+  - Namhyung Kim
+  - Colin Ian King
+  - Jeff Kirsher
+  - Greg Kroah-Hartman (Linux Foundation)
+  - Christian König
+  - Vinod Koul
+  - Krzysztof Kozlowski
+  - Viresh Kumar
+  - Aneesh Kumar K.V
+  - Julia Lawall
+  - Doug Ledford (Red Hat)
+  - Chuck Lever (Oracle)
+  - Daniel Lezcano
+  - Shaohua Li
+  - Xin Long (Red Hat)
+  - Tony Luck
+  - Mike Marshall
+  - Chris Mason
+  - Paul E. McKenney
+  - David S. Miller
+  - Ingo Molnar
+  - Kuninori Morimoto
+  - Borislav Petkov
+  - Jiri Pirko
+  - Josh Poimboeuf
+  - Sebastian Reichel (Collabora)
+  - Guenter Roeck
+  - Joerg Roedel
+  - Leon Romanovsky
+  - Steven Rostedt (VMware)
+  - Ivan Safonov
+  - Ivan Safonov
+  - Anna Schumaker
+  - Jes Sorensen
+  - K.Y. Srinivasan
+  - Heiko Stuebner
+  - Jiri Kosina (SUSE)
+  - Dmitry Torokhov
+  - Linus Torvalds
+  - Thierry Reding
+  - Rik van Riel
+  - Geert Uytterhoeven (Glider bvba)
+  - Daniel Vetter
+  - Linus Walleij
+  - Richard Weinberger
+  - Dan Williams
+  - Rafael J. Wysocki
+  - Arvind Yadav
+  - Masahiro Yamada
+  - Wei Yongjun
+  - Lv Zheng
index a74227ad082ee84db1f0a0a693d5fe62a007d36a..e652a3e2929df9079337a840f7a7113eb5a911fe 100644 (file)
@@ -10560,6 +10560,8 @@ M:      Peter Zijlstra <peterz@infradead.org>
 M:     Ingo Molnar <mingo@redhat.com>
 M:     Arnaldo Carvalho de Melo <acme@kernel.org>
 R:     Alexander Shishkin <alexander.shishkin@linux.intel.com>
+R:     Jiri Olsa <jolsa@redhat.com>
+R:     Namhyung Kim <namhyung@kernel.org>
 L:     linux-kernel@vger.kernel.org
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git perf/core
 S:     Supported
index 47d3a1ab08d2491aff178040b309180226d131e8..817e5cfef83a933e8d66bfd62a7c908a1af92f2c 100644 (file)
@@ -131,7 +131,7 @@ endif
 KBUILD_CFLAGS  +=$(CFLAGS_ABI) $(CFLAGS_ISA) $(arch-y) $(tune-y) $(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,)) -msoft-float -Uarm
 KBUILD_AFLAGS  +=$(CFLAGS_ABI) $(AFLAGS_ISA) $(arch-y) $(tune-y) -include asm/unified.h -msoft-float
 
-CHECKFLAGS     += -D__arm__
+CHECKFLAGS     += -D__arm__ -m32
 
 #Default value
 head-y         := arch/arm/kernel/head$(MMUEXT).o
index 5392ee63338fac3453f30b125366e03241158133..8f6e37177de132252c560765440698ac08b69408 100644 (file)
@@ -23,7 +23,11 @@ ENTRY(putc)
        strb    r0, [r1]
        mov     r0, #0x03               @ SYS_WRITEC
    ARM(        svc     #0x123456       )
+#ifdef CONFIG_CPU_V7M
+ THUMB(        bkpt    #0xab           )
+#else
  THUMB(        svc     #0xab           )
+#endif
        mov     pc, lr
        .align  2
 1:     .word   _GLOBAL_OFFSET_TABLE_ - .
index 7ff0811e61db3ad73be8f0c9ea8f79ebde1681c7..4960722aab32a1cf644ddb1e69d792845c240d44 100644 (file)
                        };
 
                        i2c0: i2c@11000 {
-                               compatible = "marvell,mv64xxx-i2c";
+                               compatible = "marvell,mv78230-a0-i2c", "marvell,mv64xxx-i2c";
                                reg = <0x11000 0x20>;
                                #address-cells = <1>;
                                #size-cells = <0>;
                        };
 
                        i2c1: i2c@11100 {
-                               compatible = "marvell,mv64xxx-i2c";
+                               compatible = "marvell,mv78230-a0-i2c", "marvell,mv64xxx-i2c";
                                reg = <0x11100 0x20>;
                                #address-cells = <1>;
                                #size-cells = <0>;
index 63a5af8981659fb7f3162323be34e55dbcc345d6..cf0087b4c9e184259eb63667f8322067c80b584b 100644 (file)
@@ -67,8 +67,8 @@
                                pinctrl-0 = <&pinctrl_macb0_default>;
                                phy-mode = "rmii";
 
-                               ethernet-phy@1 {
-                                       reg = <0x1>;
+                               ethernet-phy@0 {
+                                       reg = <0x0>;
                                        interrupt-parent = <&pioA>;
                                        interrupts = <PIN_PD31 IRQ_TYPE_LEVEL_LOW>;
                                        pinctrl-names = "default";
index c7e9ccf2bc8724304f44c574bc901b3e9b3999af..cbc26001247bea2fabcf186ad784f187810dbc63 100644 (file)
                                vddana-supply = <&vdd_3v3_lp_reg>;
                                vref-supply = <&vdd_3v3_lp_reg>;
                                pinctrl-names = "default";
-                               pinctrl-0 = <&pinctrl_adc_default>;
+                               pinctrl-0 = <&pinctrl_adc_default &pinctrl_adtrg_default>;
                                status = "okay";
                        };
 
                                        bias-disable;
                                };
 
+                               /*
+                                * The ADTRG pin can work on any edge type.
+                                * In here it's being pulled up, so need to
+                                * connect it to ground to get an edge e.g.
+                                * Trigger can be configured on falling, rise
+                                * or any edge, and the pull-up can be changed
+                                * to pull-down or left floating according to
+                                * needs.
+                                */
+                               pinctrl_adtrg_default: adtrg_default {
+                                       pinmux = <PIN_PD31__ADTRG>;
+                                       bias-pull-up;
+                               };
+
                                pinctrl_charger_chglev: charger_chglev {
                                        pinmux = <PIN_PA12__GPIO>;
                                        bias-disable;
index 82651c3eb682a749652a31eadbb4f910961151f7..b8565fc33eea6bc18b88ab72cf8774b15f3c678d 100644 (file)
        compatible = "raspberrypi,model-zero-w", "brcm,bcm2835";
        model = "Raspberry Pi Zero W";
 
-       /* Needed by firmware to properly init UARTs */
-       aliases {
-               uart0 = "/soc/serial@7e201000";
-               uart1 = "/soc/serial@7e215040";
-               serial0 = "/soc/serial@7e201000";
-               serial1 = "/soc/serial@7e215040";
+       chosen {
+               /* 8250 auxiliary UART instead of pl011 */
+               stdout-path = "serial1:115200n8";
        };
 
        leds {
index 20725ca487f30afd5e84059fbcb1513d3399cfa8..c71a0d73d2a2e9fd64c1906b0fe42a6cfefbd230 100644 (file)
@@ -8,6 +8,11 @@
        compatible = "raspberrypi,3-model-b", "brcm,bcm2837";
        model = "Raspberry Pi 3 Model B";
 
+       chosen {
+               /* 8250 auxiliary UART instead of pl011 */
+               stdout-path = "serial1:115200n8";
+       };
+
        memory {
                reg = <0 0x40000000>;
        };
index 431dcfc900c024d85a88231d1df007916dafdfeb..013431e3d7c3140d3a0645bdf4f130e9a860f984 100644 (file)
        #address-cells = <1>;
        #size-cells = <1>;
 
+       aliases {
+               serial0 = &uart0;
+               serial1 = &uart1;
+       };
+
        chosen {
-               bootargs = "earlyprintk console=ttyAMA0";
+               stdout-path = "serial0:115200n8";
        };
 
        thermal-zones {
index c68e8d430234c3824198d46b336f0d689cf38611..f0d178c77153fc6a3e4c84ebb798f3720995e066 100644 (file)
                };
 
                watchdog@41000000 {
-                       compatible = "cortina,gemini-watchdog";
+                       compatible = "cortina,gemini-watchdog", "faraday,ftwdt010";
                        reg = <0x41000000 0x1000>;
                        interrupts = <3 IRQ_TYPE_LEVEL_HIGH>;
                        resets = <&syscon GEMINI_RESET_WDOG>;
                        clocks = <&syscon GEMINI_CLK_APB>;
+                       clock-names = "PCLK";
                };
 
                uart0: serial@42000000 {
index f46814a7ea44100ff0dbd44f054bb17ed6c9d740..4d308d17f040c71157db72a8d81abf8de9dd4d8e 100644 (file)
                interrupt-names = "msi";
                #interrupt-cells = <1>;
                interrupt-map-mask = <0 0 0 0x7>;
-               interrupt-map = <0 0 0 1 &intc GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH>,
-                               <0 0 0 2 &intc GIC_SPI 124 IRQ_TYPE_LEVEL_HIGH>,
-                               <0 0 0 3 &intc GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>,
-                               <0 0 0 4 &intc GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>;
+               interrupt-map = <0 0 0 1 &intc GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>,
+                               <0 0 0 2 &intc GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>,
+                               <0 0 0 3 &intc GIC_SPI 124 IRQ_TYPE_LEVEL_HIGH>,
+                               <0 0 0 4 &intc GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH>;
                clocks = <&clks IMX7D_PCIE_CTRL_ROOT_CLK>,
                         <&clks IMX7D_PLL_ENET_MAIN_100M_CLK>,
                         <&clks IMX7D_PCIE_PHY_ROOT_CLK>;
index 1f4c795d3f7210223d7cdab4b5e430affa133a35..da7b3237bfe9811ff9e8908310b8f146f938f21e 100644 (file)
                };
 
                watchdog: watchdog@98500000 {
-                       compatible = "moxa,moxart-watchdog";
+                       compatible = "moxa,moxart-watchdog", "faraday,ftwdt010";
                        reg = <0x98500000 0x10>;
                        clocks = <&clk_apb>;
+                       clock-names = "PCLK";
                };
 
                sdhci: sdhci@98e00000 {
index 38d2216c7ead9ff422cce1e740a820e47977a700..b1a26b42d1904a82817e1986da79fd963b934d2f 100644 (file)
                                atmel,min-sample-rate-hz = <200000>;
                                atmel,max-sample-rate-hz = <20000000>;
                                atmel,startup-time-ms = <4>;
+                               atmel,trigger-edge-type = <IRQ_TYPE_EDGE_RISING>;
                                status = "disabled";
                        };
 
index b147cb0dc14b26ce92db7ea70bba2a8f77bd0d38..eef072a21accaed0c29d6407d076331ad579a987 100644 (file)
                                        #size-cells = <0>;
                                        reg = <0>;
 
-                                       tcon1_in_drc1: endpoint@0 {
-                                               reg = <0>;
+                                       tcon1_in_drc1: endpoint@1 {
+                                               reg = <1>;
                                                remote-endpoint = <&drc1_out_tcon1>;
                                        };
                                };
                                        #size-cells = <0>;
                                        reg = <1>;
 
-                                       be1_out_drc1: endpoint@0 {
-                                               reg = <0>;
+                                       be1_out_drc1: endpoint@1 {
+                                               reg = <1>;
                                                remote-endpoint = <&drc1_in_be1>;
                                        };
                                };
                                        #size-cells = <0>;
                                        reg = <0>;
 
-                                       drc1_in_be1: endpoint@0 {
-                                               reg = <0>;
+                                       drc1_in_be1: endpoint@1 {
+                                               reg = <1>;
                                                remote-endpoint = <&be1_out_drc1>;
                                        };
                                };
                                        #size-cells = <0>;
                                        reg = <1>;
 
-                                       drc1_out_tcon1: endpoint@0 {
-                                               reg = <0>;
+                                       drc1_out_tcon1: endpoint@1 {
+                                               reg = <1>;
                                                remote-endpoint = <&tcon1_in_drc1>;
                                        };
                                };
index ea9646cc2a0ed7eba2fa4f7f7638c0802642edcc..0a498cb3fad88d046c23073a5d1b7785fdfaf1a7 100644 (file)
@@ -115,7 +115,11 @@ ENTRY(printascii)
                mov     r1, r0
                mov     r0, #0x04               @ SYS_WRITE0
        ARM(    svc     #0x123456       )
+#ifdef CONFIG_CPU_V7M
+       THUMB(  bkpt    #0xab           )
+#else
        THUMB(  svc     #0xab           )
+#endif
                ret     lr
 ENDPROC(printascii)
 
@@ -124,7 +128,11 @@ ENTRY(printch)
                strb    r0, [r1]
                mov     r0, #0x03               @ SYS_WRITEC
        ARM(    svc     #0x123456       )
+#ifdef CONFIG_CPU_V7M
+       THUMB(  bkpt    #0xab           )
+#else
        THUMB(  svc     #0xab           )
+#endif
                ret     lr
 ENDPROC(printch)
 
index 71a34e8c345a5b19b98f42cc368f796118d3214f..57058ac46f49733887e439012afa3247f03e1737 100644 (file)
@@ -32,6 +32,7 @@
 #include <asm/mach/arch.h>
 
 #include "db8500-regs.h"
+#include "pm_domains.h"
 
 static int __init ux500_l2x0_unlock(void)
 {
@@ -157,6 +158,9 @@ static const struct of_device_id u8500_local_bus_nodes[] = {
 
 static void __init u8500_init_machine(void)
 {
+       /* Initialize ux500 power domains */
+       ux500_pm_domains_init();
+
        /* automatically probe child nodes of dbx5x0 devices */
        if (of_machine_is_compatible("st-ericsson,u8540"))
                of_platform_populate(NULL, u8500_local_bus_nodes,
index a970e7fcba9e02fe6e2651cd5cfca76321d26314..f6c33a0c1c610cf17881fc276725817acdb4b29d 100644 (file)
@@ -19,7 +19,6 @@
 #include <linux/of_address.h>
 
 #include "db8500-regs.h"
-#include "pm_domains.h"
 
 /* ARM WFI Standby signal register */
 #define PRCM_ARM_WFI_STANDBY    (prcmu_base + 0x130)
@@ -203,7 +202,4 @@ void __init ux500_pm_init(u32 phy_base, u32 size)
 
        /* Set up ux500 suspend callbacks. */
        suspend_set_ops(UX500_SUSPEND_OPS);
-
-       /* Initialize ux500 power domains */
-       ux500_pm_domains_init();
 }
index 3b8e728cc9443975c6cd66c63350a2074df310b7..91537d90f5f526e4e9135b2b0e5403141172a4cb 100644 (file)
@@ -344,6 +344,11 @@ void __init arm_mm_memblock_reserve(void)
         * reserved here.
         */
 #endif
+       /*
+        * In any case, always ensure address 0 is never used as many things
+        * get very confused if 0 is returned as a legitimate address.
+        */
+       memblock_reserve(0, 1);
 }
 
 void __init adjust_lowmem_bounds(void)
index caf8b6fbe5e350de2095d16489f19ce734ca4bc3..d06e34b5d192323ffef69303330e1f37a9a27310 100644 (file)
        chosen {
                stdout-path = "serial0:115200n8";
        };
-
-       reg_vcc3v3: vcc3v3 {
-               compatible = "regulator-fixed";
-               regulator-name = "vcc3v3";
-               regulator-min-microvolt = <3300000>;
-               regulator-max-microvolt = <3300000>;
-       };
 };
 
 &ehci0 {
@@ -91,7 +84,7 @@
 &mmc0 {
        pinctrl-names = "default";
        pinctrl-0 = <&mmc0_pins>;
-       vmmc-supply = <&reg_vcc3v3>;
+       vmmc-supply = <&reg_dcdc1>;
        cd-gpios = <&pio 5 6 GPIO_ACTIVE_HIGH>;
        cd-inverted;
        disable-wp;
index 8263a8a504a8fd11896da6aebc99eabdd4be928a..f2aa2a81de4dd2e982ec1e5fd5ae67f01bb08a63 100644 (file)
                                /* non-prefetchable memory */
                                0x82000000 0 0xf6000000 0  0xf6000000 0 0xf00000>;
                        interrupt-map-mask = <0 0 0 0>;
-                       interrupt-map = <0 0 0 0 &cpm_icu ICU_GRP_NSR 22 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-map = <0 0 0 0 &cpm_icu ICU_GRP_NSR 22 IRQ_TYPE_LEVEL_HIGH>;
                        interrupts = <ICU_GRP_NSR 22 IRQ_TYPE_LEVEL_HIGH>;
                        num-lanes = <1>;
                        clocks = <&cpm_clk 1 13>;
                                /* non-prefetchable memory */
                                0x82000000 0 0xf7000000 0  0xf7000000 0 0xf00000>;
                        interrupt-map-mask = <0 0 0 0>;
-                       interrupt-map = <0 0 0 0 &cpm_icu ICU_GRP_NSR 24 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-map = <0 0 0 0 &cpm_icu ICU_GRP_NSR 24 IRQ_TYPE_LEVEL_HIGH>;
                        interrupts = <ICU_GRP_NSR 24 IRQ_TYPE_LEVEL_HIGH>;
 
                        num-lanes = <1>;
                                /* non-prefetchable memory */
                                0x82000000 0 0xf8000000 0  0xf8000000 0 0xf00000>;
                        interrupt-map-mask = <0 0 0 0>;
-                       interrupt-map = <0 0 0 0 &cpm_icu ICU_GRP_NSR 23 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-map = <0 0 0 0 &cpm_icu ICU_GRP_NSR 23 IRQ_TYPE_LEVEL_HIGH>;
                        interrupts = <ICU_GRP_NSR 23 IRQ_TYPE_LEVEL_HIGH>;
 
                        num-lanes = <1>;
index b71ee6c83668e8900a4a889614ed83e97e718f85..4fe70323abb3a58c374a762607bb63f08b2cb0e0 100644 (file)
                                /* non-prefetchable memory */
                                0x82000000 0 0xfa000000 0  0xfa000000 0 0xf00000>;
                        interrupt-map-mask = <0 0 0 0>;
-                       interrupt-map = <0 0 0 0 &cps_icu ICU_GRP_NSR 22 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-map = <0 0 0 0 &cps_icu ICU_GRP_NSR 22 IRQ_TYPE_LEVEL_HIGH>;
                        interrupts = <ICU_GRP_NSR 22 IRQ_TYPE_LEVEL_HIGH>;
                        num-lanes = <1>;
                        clocks = <&cps_clk 1 13>;
                                /* non-prefetchable memory */
                                0x82000000 0 0xfb000000 0  0xfb000000 0 0xf00000>;
                        interrupt-map-mask = <0 0 0 0>;
-                       interrupt-map = <0 0 0 0 &cps_icu ICU_GRP_NSR 24 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-map = <0 0 0 0 &cps_icu ICU_GRP_NSR 24 IRQ_TYPE_LEVEL_HIGH>;
                        interrupts = <ICU_GRP_NSR 24 IRQ_TYPE_LEVEL_HIGH>;
 
                        num-lanes = <1>;
                                /* non-prefetchable memory */
                                0x82000000 0 0xfc000000 0  0xfc000000 0 0xf00000>;
                        interrupt-map-mask = <0 0 0 0>;
-                       interrupt-map = <0 0 0 0 &cps_icu ICU_GRP_NSR 23 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-map = <0 0 0 0 &cps_icu ICU_GRP_NSR 23 IRQ_TYPE_LEVEL_HIGH>;
                        interrupts = <ICU_GRP_NSR 23 IRQ_TYPE_LEVEL_HIGH>;
 
                        num-lanes = <1>;
index 4786c67b5e6527fd99d27aa969ef0b2d4274b4ad..d9d885006a8e8c9a6630f635132b6d0c24370ccc 100644 (file)
@@ -62,6 +62,7 @@
                brightness-levels = <256 128 64 16 8 4 0>;
                default-brightness-level = <6>;
 
+               power-supply = <&reg_12v>;
                enable-gpios = <&gpio6 7 GPIO_ACTIVE_HIGH>;
        };
 
                regulator-always-on;
        };
 
+       reg_12v: regulator2 {
+               compatible = "regulator-fixed";
+               regulator-name = "fixed-12V";
+               regulator-min-microvolt = <12000000>;
+               regulator-max-microvolt = <12000000>;
+               regulator-boot-on;
+               regulator-always-on;
+       };
+
        rsnd_ak4613: sound {
                compatible = "simple-audio-card";
 
index 6d615cb6e64d07cebcfa0a7ecebf04b8afb152b2..41d61840fb99ce52ec553c94e119ab63bb79cdbe 100644 (file)
        vop_mmu: iommu@ff373f00 {
                compatible = "rockchip,iommu";
                reg = <0x0 0xff373f00 0x0 0x100>;
-               interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH 0>;
+               interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
                interrupt-names = "vop_mmu";
                #iommu-cells = <0>;
                status = "disabled";
index 19fbaa5e7bdd573e6ba6959be9c72ccbb0a388a6..1070c8264c13376a578338e95421f71321825243 100644 (file)
        iep_mmu: iommu@ff900800 {
                compatible = "rockchip,iommu";
                reg = <0x0 0xff900800 0x0 0x100>;
-               interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH 0>;
+               interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
                interrupt-names = "iep_mmu";
                #iommu-cells = <0>;
                status = "disabled";
index 7fd4bfcaa38e33c8b58ef60dc7adb99772b04cc1..fef82274a39dac27fc6e293affc81b4ff5d5d64b 100644 (file)
                                regulator-always-on;
                                regulator-boot-on;
                                regulator-min-microvolt = <1800000>;
-                               regulator-max-microvolt = <3300000>;
+                               regulator-max-microvolt = <3000000>;
                                regulator-state-mem {
                                        regulator-on-in-suspend;
-                                       regulator-suspend-microvolt = <3300000>;
+                                       regulator-suspend-microvolt = <3000000>;
                                };
                        };
 
index 53ff3d191a1d176cc0d7c6d380894b48e42ec7da..910628d18add07d9a39974bc6ce2ac4a403adb81 100644 (file)
                        vcc_sd: LDO_REG4 {
                                regulator-name = "vcc_sd";
                                regulator-min-microvolt = <1800000>;
-                               regulator-max-microvolt = <3300000>;
+                               regulator-max-microvolt = <3000000>;
                                regulator-always-on;
                                regulator-boot-on;
                                regulator-state-mem {
                                        regulator-on-in-suspend;
-                                       regulator-suspend-microvolt = <3300000>;
+                                       regulator-suspend-microvolt = <3000000>;
                                };
                        };
 
index 6c30bb02210d80a2d78843cccaca7a3d83f971cd..0f873c897d0de5a75f9d4e4d90d7c658b7a173d3 100644 (file)
                                regulator-always-on;
                                regulator-boot-on;
                                regulator-min-microvolt = <1800000>;
-                               regulator-max-microvolt = <3300000>;
+                               regulator-max-microvolt = <3000000>;
                                regulator-state-mem {
                                        regulator-on-in-suspend;
-                                       regulator-suspend-microvolt = <3300000>;
+                                       regulator-suspend-microvolt = <3000000>;
                                };
                        };
 
index c6d6272a934f03823b655cf07b38e7bbc01ca12e..7baa2265d43927fd7e5a24269e627486c60c6b35 100644 (file)
@@ -35,12 +35,12 @@ EXPORT_SYMBOL(memset);
 EXPORT_SYMBOL(__xchg8);
 EXPORT_SYMBOL(__xchg32);
 EXPORT_SYMBOL(__cmpxchg_u32);
+EXPORT_SYMBOL(__cmpxchg_u64);
 #ifdef CONFIG_SMP
 EXPORT_SYMBOL(__atomic_hash);
 #endif
 #ifdef CONFIG_64BIT
 EXPORT_SYMBOL(__xchg64);
-EXPORT_SYMBOL(__cmpxchg_u64);
 #endif
 
 #include <linux/uaccess.h>
index 23de307c3052aa9ecac21fd6c294657fb53de447..41e60a9c7db23b8384b18bf8ddd45f188ef4a0c3 100644 (file)
@@ -742,7 +742,7 @@ lws_compare_and_swap_2:
 10:    ldd     0(%r25), %r25
 11:    ldd     0(%r24), %r24
 #else
-       /* Load new value into r22/r23 - high/low */
+       /* Load old value into r22/r23 - high/low */
 10:    ldw     0(%r25), %r22
 11:    ldw     4(%r25), %r23
        /* Load new value into fr4 for atomic store later */
@@ -834,11 +834,11 @@ cas2_action:
        copy    %r0, %r28
 #else
        /* Compare first word */
-19:    ldw,ma  0(%r26), %r29
+19:    ldw     0(%r26), %r29
        sub,=   %r29, %r22, %r0
        b,n     cas2_end
        /* Compare second word */
-20:    ldw,ma  4(%r26), %r29
+20:    ldw     4(%r26), %r29
        sub,=   %r29, %r23, %r0
        b,n     cas2_end
        /* Perform the store */
index 2d956aa0a38abbc3829757bab4749dd6a0037490..8c0105a49839cf018a80108f76dadccb5e793ee1 100644 (file)
@@ -253,7 +253,10 @@ static int __init init_cr16_clocksource(void)
                cpu0_loc = per_cpu(cpu_data, 0).cpu_loc;
 
                for_each_online_cpu(cpu) {
-                       if (cpu0_loc == per_cpu(cpu_data, cpu).cpu_loc)
+                       if (cpu == 0)
+                               continue;
+                       if ((cpu0_loc != 0) &&
+                           (cpu0_loc == per_cpu(cpu_data, cpu).cpu_loc))
                                continue;
 
                        clocksource_cr16.name = "cr16_unstable";
index afa46a7406eaeddbbf70bbaf384f49ffa0535874..04e042edbab760f13a2da86a0cab071346bf2ab5 100644 (file)
@@ -27,6 +27,7 @@ CONFIG_NET=y
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 CONFIG_DEVTMPFS=y
 # CONFIG_FIRMWARE_IN_KERNEL is not set
+CONFIG_BLK_DEV_RAM=y
 # CONFIG_BLK_DEV_XPRAM is not set
 # CONFIG_DCSSBLK is not set
 # CONFIG_DASD is not set
@@ -59,6 +60,7 @@ CONFIG_CONFIGFS_FS=y
 # CONFIG_NETWORK_FILESYSTEMS is not set
 CONFIG_PRINTK_TIME=y
 CONFIG_DEBUG_INFO=y
+CONFIG_DEBUG_FS=y
 CONFIG_DEBUG_KERNEL=y
 CONFIG_PANIC_ON_OOPS=y
 # CONFIG_SCHED_DEBUG is not set
index 1cee6753d47a5cba115730cb73cef4324e8d3ed1..495ff6959dec76a904ee2f6ccc30f8ef7809960d 100644 (file)
@@ -293,7 +293,10 @@ static void pcpu_attach_task(struct pcpu *pcpu, struct task_struct *tsk)
        lc->lpp = LPP_MAGIC;
        lc->current_pid = tsk->pid;
        lc->user_timer = tsk->thread.user_timer;
+       lc->guest_timer = tsk->thread.guest_timer;
        lc->system_timer = tsk->thread.system_timer;
+       lc->hardirq_timer = tsk->thread.hardirq_timer;
+       lc->softirq_timer = tsk->thread.softirq_timer;
        lc->steal_timer = 0;
 }
 
index e4b0ed386bc82f339829fea2dcedd42fe2f0aff5..39aecad286fe482ff3f44fe08b286c2edbf3553b 100644 (file)
@@ -57,6 +57,8 @@ struct key *find_asymmetric_key(struct key *keyring,
        char *req, *p;
        int len;
 
+       BUG_ON(!id_0 && !id_1);
+
        if (id_0) {
                lookup = id_0->data;
                len = id_0->len;
@@ -105,7 +107,7 @@ struct key *find_asymmetric_key(struct key *keyring,
        if (id_0 && id_1) {
                const struct asymmetric_key_ids *kids = asymmetric_key_ids(key);
 
-               if (!kids->id[0]) {
+               if (!kids->id[1]) {
                        pr_debug("First ID matches, but second is missing\n");
                        goto reject;
                }
index af4cd864911752478ba5f3c2732273f9624d434f..d140d8bb2c96140c408b1e3450f288e562372743 100644 (file)
@@ -88,6 +88,9 @@ static int pkcs7_check_authattrs(struct pkcs7_message *msg)
        bool want = false;
 
        sinfo = msg->signed_infos;
+       if (!sinfo)
+               goto inconsistent;
+
        if (sinfo->authattrs) {
                want = true;
                msg->have_authattrs = true;
index 883dfebd3014b506a0861aed0640dc313fd8b0cc..baebbdfd74d54f4969fac84e06c8b1741b831c0c 100644 (file)
@@ -243,7 +243,6 @@ static void nbd_size_set(struct nbd_device *nbd, loff_t blocksize,
        struct nbd_config *config = nbd->config;
        config->blksize = blocksize;
        config->bytesize = blocksize * nr_blocks;
-       nbd_size_update(nbd);
 }
 
 static void nbd_complete_rq(struct request *req)
@@ -1094,6 +1093,7 @@ static int nbd_start_device(struct nbd_device *nbd)
                args->index = i;
                queue_work(recv_workqueue, &args->work);
        }
+       nbd_size_update(nbd);
        return error;
 }
 
index 7cedb4295e9d325343e296b8b299cb407b7b2a55..64d0fc17c1742ab74aa232da503d08e344b594b2 100644 (file)
@@ -2604,7 +2604,7 @@ static void *skd_alloc_dma(struct skd_device *skdev, struct kmem_cache *s,
                return NULL;
        *dma_handle = dma_map_single(dev, buf, s->size, dir);
        if (dma_mapping_error(dev, *dma_handle)) {
-               kfree(buf);
+               kmem_cache_free(s, buf);
                buf = NULL;
        }
        return buf;
index c7f39690318473d4b75bca11c0c3fd4830f4d084..70db4d5638a6338632a916e4ee07f0f4b3ca5e04 100644 (file)
@@ -720,7 +720,7 @@ mvebu_mbus_default_setup_cpu_target(struct mvebu_mbus_state *mbus)
                        if (mbus->hw_io_coherency)
                                w->mbus_attr |= ATTR_HW_COHERENCY;
                        w->base = base & DDR_BASE_CS_LOW_MASK;
-                       w->size = (size | ~DDR_SIZE_MASK) + 1;
+                       w->size = (u64)(size | ~DDR_SIZE_MASK) + 1;
                }
        }
        mvebu_mbus_dram_info.num_cs = cs;
index a1df588343f2dac1fb1c6acb8f579f3688ad6938..1de8cac99a0e93b21d38f5c23f29739ec06caab7 100644 (file)
@@ -117,7 +117,8 @@ static irqreturn_t mfgpt_tick(int irq, void *dev_id)
        /* Turn off the clock (and clear the event) */
        disable_timer(cs5535_event_clock);
 
-       if (clockevent_state_shutdown(&cs5535_clockevent))
+       if (clockevent_state_detached(&cs5535_clockevent) ||
+           clockevent_state_shutdown(&cs5535_clockevent))
                return IRQ_HANDLED;
 
        /* Clear the counter */
index 339186f25a2ae529c447bd8359a9c55e0049d2ea..55f9c62ee54b063521bfbf0d4b19627b43e8c155 100644 (file)
@@ -344,7 +344,7 @@ msgdma_prep_memcpy(struct dma_chan *dchan, dma_addr_t dma_dst,
 
        spin_lock_irqsave(&mdev->lock, irqflags);
        if (desc_cnt > mdev->desc_free_cnt) {
-               spin_unlock_bh(&mdev->lock);
+               spin_unlock_irqrestore(&mdev->lock, irqflags);
                dev_dbg(mdev->dev, "mdev %p descs are not available\n", mdev);
                return NULL;
        }
@@ -407,7 +407,7 @@ msgdma_prep_slave_sg(struct dma_chan *dchan, struct scatterlist *sgl,
 
        spin_lock_irqsave(&mdev->lock, irqflags);
        if (desc_cnt > mdev->desc_free_cnt) {
-               spin_unlock_bh(&mdev->lock);
+               spin_unlock_irqrestore(&mdev->lock, irqflags);
                dev_dbg(mdev->dev, "mdev %p descs are not available\n", mdev);
                return NULL;
        }
index 97c94f9683fa047392ba62f128586e0b7e4492bc..38cea6fb25a8b9221d64b43da04c4268a2c986b8 100644 (file)
@@ -205,32 +205,17 @@ void amd_sched_entity_fini(struct amd_gpu_scheduler *sched,
                           struct amd_sched_entity *entity)
 {
        struct amd_sched_rq *rq = entity->rq;
-       int r;
 
        if (!amd_sched_entity_is_initialized(sched, entity))
                return;
+
        /**
         * The client will not queue more IBs during this fini, consume existing
-        * queued IBs or discard them on SIGKILL
+        * queued IBs
        */
-       if ((current->flags & PF_SIGNALED) && current->exit_code == SIGKILL)
-               r = -ERESTARTSYS;
-       else
-               r = wait_event_killable(sched->job_scheduled,
-                                       amd_sched_entity_is_idle(entity));
-       amd_sched_rq_remove_entity(rq, entity);
-       if (r) {
-               struct amd_sched_job *job;
+       wait_event(sched->job_scheduled, amd_sched_entity_is_idle(entity));
 
-               /* Park the kernel for a moment to make sure it isn't processing
-                * our enity.
-                */
-               kthread_park(sched->thread);
-               kthread_unpark(sched->thread);
-               while (kfifo_out(&entity->job_queue, &job, sizeof(job)))
-                       sched->ops->free_job(job);
-
-       }
+       amd_sched_rq_remove_entity(rq, entity);
        kfifo_free(&entity->job_queue);
 }
 
index e651a58c18cf2d5b743439776dd62d50b64f8a7a..82b72425a42f7977c993134a2142434d8689227f 100644 (file)
@@ -168,11 +168,13 @@ static struct drm_driver exynos_drm_driver = {
 static int exynos_drm_suspend(struct device *dev)
 {
        struct drm_device *drm_dev = dev_get_drvdata(dev);
-       struct exynos_drm_private *private = drm_dev->dev_private;
+       struct exynos_drm_private *private;
 
        if (pm_runtime_suspended(dev) || !drm_dev)
                return 0;
 
+       private = drm_dev->dev_private;
+
        drm_kms_helper_poll_disable(drm_dev);
        exynos_drm_fbdev_suspend(drm_dev);
        private->suspend_state = drm_atomic_helper_suspend(drm_dev);
@@ -188,11 +190,12 @@ static int exynos_drm_suspend(struct device *dev)
 static int exynos_drm_resume(struct device *dev)
 {
        struct drm_device *drm_dev = dev_get_drvdata(dev);
-       struct exynos_drm_private *private = drm_dev->dev_private;
+       struct exynos_drm_private *private;
 
        if (pm_runtime_suspended(dev) || !drm_dev)
                return 0;
 
+       private = drm_dev->dev_private;
        drm_atomic_helper_resume(drm_dev, private->suspend_state);
        exynos_drm_fbdev_resume(drm_dev);
        drm_kms_helper_poll_enable(drm_dev);
@@ -427,6 +430,7 @@ static void exynos_drm_unbind(struct device *dev)
 
        kfree(drm->dev_private);
        drm->dev_private = NULL;
+       dev_set_drvdata(dev, NULL);
 
        drm_dev_unref(drm);
 }
index 436377da41baced8e81352587cc3e035d0dc1ba3..03532dfc0cd51b8342e50da61524024dafc8ac34 100644 (file)
@@ -308,20 +308,8 @@ static int tbs_sched_init_vgpu(struct intel_vgpu *vgpu)
 
 static void tbs_sched_clean_vgpu(struct intel_vgpu *vgpu)
 {
-       struct intel_gvt_workload_scheduler *scheduler = &vgpu->gvt->scheduler;
-       int ring_id;
-
        kfree(vgpu->sched_data);
        vgpu->sched_data = NULL;
-
-       spin_lock_bh(&scheduler->mmio_context_lock);
-       for (ring_id = 0; ring_id < I915_NUM_ENGINES; ring_id++) {
-               if (scheduler->engine_owner[ring_id] == vgpu) {
-                       intel_gvt_switch_mmio(vgpu, NULL, ring_id);
-                       scheduler->engine_owner[ring_id] = NULL;
-               }
-       }
-       spin_unlock_bh(&scheduler->mmio_context_lock);
 }
 
 static void tbs_sched_start_schedule(struct intel_vgpu *vgpu)
@@ -388,6 +376,7 @@ void intel_vgpu_stop_schedule(struct intel_vgpu *vgpu)
 {
        struct intel_gvt_workload_scheduler *scheduler =
                &vgpu->gvt->scheduler;
+       int ring_id;
 
        gvt_dbg_core("vgpu%d: stop schedule\n", vgpu->id);
 
@@ -401,4 +390,13 @@ void intel_vgpu_stop_schedule(struct intel_vgpu *vgpu)
                scheduler->need_reschedule = true;
                scheduler->current_vgpu = NULL;
        }
+
+       spin_lock_bh(&scheduler->mmio_context_lock);
+       for (ring_id = 0; ring_id < I915_NUM_ENGINES; ring_id++) {
+               if (scheduler->engine_owner[ring_id] == vgpu) {
+                       intel_gvt_switch_mmio(vgpu, NULL, ring_id);
+                       scheduler->engine_owner[ring_id] = NULL;
+               }
+       }
+       spin_unlock_bh(&scheduler->mmio_context_lock);
 }
index af289d35b77a249c8fa9a7aab4a9672592399d51..32e857dc507cf9b1a9247f3bab497616d82e60a9 100644 (file)
@@ -2657,6 +2657,9 @@ i915_gem_object_pwrite_gtt(struct drm_i915_gem_object *obj,
        if (READ_ONCE(obj->mm.pages))
                return -ENODEV;
 
+       if (obj->mm.madv != I915_MADV_WILLNEED)
+               return -EFAULT;
+
        /* Before the pages are instantiated the object is treated as being
         * in the CPU domain. The pages will be clflushed as required before
         * use, and we can freely write into the pages directly. If userspace
index 4df039ef2ce316509ecc6faa04e707d135acf507..e161d383b526757a79097eadb9e65260392befe1 100644 (file)
 #include "intel_drv.h"
 #include "i915_trace.h"
 
-static bool ggtt_is_idle(struct drm_i915_private *dev_priv)
+static bool ggtt_is_idle(struct drm_i915_private *i915)
 {
-       struct i915_ggtt *ggtt = &dev_priv->ggtt;
-       struct intel_engine_cs *engine;
-       enum intel_engine_id id;
+       struct intel_engine_cs *engine;
+       enum intel_engine_id id;
 
-       for_each_engine(engine, dev_priv, id) {
-               struct intel_timeline *tl;
+       if (i915->gt.active_requests)
+              return false;
 
-               tl = &ggtt->base.timeline.engine[engine->id];
-               if (i915_gem_active_isset(&tl->last_request))
-                       return false;
-       }
+       for_each_engine(engine, i915, id) {
+              if (engine->last_retired_context != i915->kernel_context)
+                      return false;
+       }
 
-       return true;
+       return true;
 }
 
 static int ggtt_flush(struct drm_i915_private *i915)
@@ -157,7 +156,8 @@ i915_gem_evict_something(struct i915_address_space *vm,
                                    min_size, alignment, cache_level,
                                    start, end, mode);
 
-       /* Retire before we search the active list. Although we have
+       /*
+        * Retire before we search the active list. Although we have
         * reasonable accuracy in our retirement lists, we may have
         * a stray pin (preventing eviction) that can only be resolved by
         * retiring.
@@ -182,7 +182,8 @@ search_again:
                BUG_ON(ret);
        }
 
-       /* Can we unpin some objects such as idle hw contents,
+       /*
+        * Can we unpin some objects such as idle hw contents,
         * or pending flips? But since only the GGTT has global entries
         * such as scanouts, rinbuffers and contexts, we can skip the
         * purge when inspecting per-process local address spaces.
@@ -190,19 +191,33 @@ search_again:
        if (!i915_is_ggtt(vm) || flags & PIN_NONBLOCK)
                return -ENOSPC;
 
-       if (ggtt_is_idle(dev_priv)) {
-               /* If we still have pending pageflip completions, drop
-                * back to userspace to give our workqueues time to
-                * acquire our locks and unpin the old scanouts.
-                */
-               return intel_has_pending_fb_unpin(dev_priv) ? -EAGAIN : -ENOSPC;
-       }
+       /*
+        * Not everything in the GGTT is tracked via VMA using
+        * i915_vma_move_to_active(), otherwise we could evict as required
+        * with minimal stalling. Instead we are forced to idle the GPU and
+        * explicitly retire outstanding requests which will then remove
+        * the pinning for active objects such as contexts and ring,
+        * enabling us to evict them on the next iteration.
+        *
+        * To ensure that all user contexts are evictable, we perform
+        * a switch to the perma-pinned kernel context. This all also gives
+        * us a termination condition, when the last retired context is
+        * the kernel's there is no more we can evict.
+        */
+       if (!ggtt_is_idle(dev_priv)) {
+               ret = ggtt_flush(dev_priv);
+               if (ret)
+                       return ret;
 
-       ret = ggtt_flush(dev_priv);
-       if (ret)
-               return ret;
+               goto search_again;
+       }
 
-       goto search_again;
+       /*
+        * If we still have pending pageflip completions, drop
+        * back to userspace to give our workqueues time to
+        * acquire our locks and unpin the old scanouts.
+        */
+       return intel_has_pending_fb_unpin(dev_priv) ? -EAGAIN : -ENOSPC;
 
 found:
        /* drm_mm doesn't allow any other other operations while
index ed7cd9ee2c2af89737b2cc4618317c4d2fc9bedd..c9bcc6c450126e7cf638ba1c872a55938660add8 100644 (file)
@@ -6998,6 +6998,7 @@ enum {
  */
 #define  L3_GENERAL_PRIO_CREDITS(x)            (((x) >> 1) << 19)
 #define  L3_HIGH_PRIO_CREDITS(x)               (((x) >> 1) << 14)
+#define  L3_PRIO_CREDITS_MASK                  ((0x1f << 19) | (0x1f << 14))
 
 #define GEN7_L3CNTLREG1                                _MMIO(0xB01C)
 #define  GEN7_WA_FOR_GEN7_L3_CONTROL                   0x3C47FF8C
index 476681d5940c7d381c2d48f2c4a1202054e79845..5e5fe03b638cbf2ee17206ccd4c6ee985134645e 100644 (file)
@@ -664,8 +664,8 @@ intel_ddi_get_buf_trans_fdi(struct drm_i915_private *dev_priv,
                            int *n_entries)
 {
        if (IS_BROADWELL(dev_priv)) {
-               *n_entries = ARRAY_SIZE(hsw_ddi_translations_fdi);
-               return hsw_ddi_translations_fdi;
+               *n_entries = ARRAY_SIZE(bdw_ddi_translations_fdi);
+               return bdw_ddi_translations_fdi;
        } else if (IS_HASWELL(dev_priv)) {
                *n_entries = ARRAY_SIZE(hsw_ddi_translations_fdi);
                return hsw_ddi_translations_fdi;
@@ -2102,8 +2102,7 @@ static void intel_ddi_clk_select(struct intel_encoder *encoder,
                 * register writes.
                 */
                val = I915_READ(DPCLKA_CFGCR0);
-               val &= ~(DPCLKA_CFGCR0_DDI_CLK_OFF(port) |
-                        DPCLKA_CFGCR0_DDI_CLK_SEL_MASK(port));
+               val &= ~DPCLKA_CFGCR0_DDI_CLK_OFF(port);
                I915_WRITE(DPCLKA_CFGCR0, val);
        } else if (IS_GEN9_BC(dev_priv)) {
                /* DDI -> PLL mapping  */
index a2a3d93d67bd252a3c9d137bedb66be26816bd23..df808a94c51194a886d8664ff8b8118ad05870ef 100644 (file)
@@ -1996,7 +1996,7 @@ static void cnl_ddi_pll_enable(struct drm_i915_private *dev_priv,
 
        /* 3. Configure DPLL_CFGCR0 */
        /* Avoid touch CFGCR1 if HDMI mode is not enabled */
-       if (pll->state.hw_state.cfgcr0 & DPLL_CTRL1_HDMI_MODE(pll->id)) {
+       if (pll->state.hw_state.cfgcr0 & DPLL_CFGCR0_HDMI_MODE) {
                val = pll->state.hw_state.cfgcr1;
                I915_WRITE(CNL_DPLL_CFGCR1(pll->id), val);
                /* 4. Reab back to ensure writes completed */
index 9ab5969413722a5999a4266629ea2ba0fc2305f0..3c2d9cf22ed5a537253a14c2fe85ee200ce7b24c 100644 (file)
@@ -1048,9 +1048,12 @@ static int bxt_init_workarounds(struct intel_engine_cs *engine)
        }
 
        /* WaProgramL3SqcReg1DefaultForPerf:bxt */
-       if (IS_BXT_REVID(dev_priv, BXT_REVID_B0, REVID_FOREVER))
-               I915_WRITE(GEN8_L3SQCREG1, L3_GENERAL_PRIO_CREDITS(62) |
-                                          L3_HIGH_PRIO_CREDITS(2));
+       if (IS_BXT_REVID(dev_priv, BXT_REVID_B0, REVID_FOREVER)) {
+               u32 val = I915_READ(GEN8_L3SQCREG1);
+               val &= ~L3_PRIO_CREDITS_MASK;
+               val |= L3_GENERAL_PRIO_CREDITS(62) | L3_HIGH_PRIO_CREDITS(2);
+               I915_WRITE(GEN8_L3SQCREG1, val);
+       }
 
        /* WaToEnableHwFixForPushConstHWBug:bxt */
        if (IS_BXT_REVID(dev_priv, BXT_REVID_C0, REVID_FOREVER))
index ed662937ec3c85685b7fed049f381c6d1cb5654c..0a09f8ff6aff6710ea3580329d83646a67593b8c 100644 (file)
@@ -8245,14 +8245,17 @@ static void gen8_set_l3sqc_credits(struct drm_i915_private *dev_priv,
                                   int high_prio_credits)
 {
        u32 misccpctl;
+       u32 val;
 
        /* WaTempDisableDOPClkGating:bdw */
        misccpctl = I915_READ(GEN7_MISCCPCTL);
        I915_WRITE(GEN7_MISCCPCTL, misccpctl & ~GEN7_DOP_CLOCK_GATE_ENABLE);
 
-       I915_WRITE(GEN8_L3SQCREG1,
-                  L3_GENERAL_PRIO_CREDITS(general_prio_credits) |
-                  L3_HIGH_PRIO_CREDITS(high_prio_credits));
+       val = I915_READ(GEN8_L3SQCREG1);
+       val &= ~L3_PRIO_CREDITS_MASK;
+       val |= L3_GENERAL_PRIO_CREDITS(general_prio_credits);
+       val |= L3_HIGH_PRIO_CREDITS(high_prio_credits);
+       I915_WRITE(GEN8_L3SQCREG1, val);
 
        /*
         * Wait at least 100 clocks before re-enabling clock gating.
index f7707849bb538697009ca3b68c8296100a67b2a4..2b12d82aac1509f7023b24e15d5f04fe7ecc8290 100644 (file)
@@ -223,7 +223,7 @@ void
 nouveau_fbcon_accel_save_disable(struct drm_device *dev)
 {
        struct nouveau_drm *drm = nouveau_drm(dev);
-       if (drm->fbcon) {
+       if (drm->fbcon && drm->fbcon->helper.fbdev) {
                drm->fbcon->saved_flags = drm->fbcon->helper.fbdev->flags;
                drm->fbcon->helper.fbdev->flags |= FBINFO_HWACCEL_DISABLED;
        }
@@ -233,7 +233,7 @@ void
 nouveau_fbcon_accel_restore(struct drm_device *dev)
 {
        struct nouveau_drm *drm = nouveau_drm(dev);
-       if (drm->fbcon) {
+       if (drm->fbcon && drm->fbcon->helper.fbdev) {
                drm->fbcon->helper.fbdev->flags = drm->fbcon->saved_flags;
        }
 }
@@ -245,7 +245,8 @@ nouveau_fbcon_accel_fini(struct drm_device *dev)
        struct nouveau_fbdev *fbcon = drm->fbcon;
        if (fbcon && drm->channel) {
                console_lock();
-               fbcon->helper.fbdev->flags |= FBINFO_HWACCEL_DISABLED;
+               if (fbcon->helper.fbdev)
+                       fbcon->helper.fbdev->flags |= FBINFO_HWACCEL_DISABLED;
                console_unlock();
                nouveau_channel_idle(drm->channel);
                nvif_object_fini(&fbcon->twod);
index 2dbf62a2ac413081f7a15cb7c8779667447015d4..e4751f92b342d60f44c7d1a73a981940f15cb400 100644 (file)
@@ -3265,11 +3265,14 @@ nv50_mstm = {
 void
 nv50_mstm_service(struct nv50_mstm *mstm)
 {
-       struct drm_dp_aux *aux = mstm->mgr.aux;
+       struct drm_dp_aux *aux = mstm ? mstm->mgr.aux : NULL;
        bool handled = true;
        int ret;
        u8 esi[8] = {};
 
+       if (!aux)
+               return;
+
        while (handled) {
                ret = drm_dp_dpcd_read(aux, DP_SINK_COUNT_ESI, esi, 8);
                if (ret != 8) {
index 8e2e24a7477458d0ad2361885e79fca4f936068a..44e116f7880dd02e6754d3d328f1d909a0a7041a 100644 (file)
@@ -39,5 +39,5 @@ int
 g84_bsp_new(struct nvkm_device *device, int index, struct nvkm_engine **pengine)
 {
        return nvkm_xtensa_new_(&g84_bsp, device, index,
-                               true, 0x103000, pengine);
+                               device->chipset != 0x92, 0x103000, pengine);
 }
index d06ad2c372bf30efb6b8ecc5978776def5721222..455da298227f65c2b4c2cfc6a2cedebe12661877 100644 (file)
@@ -241,6 +241,8 @@ nvkm_vm_unmap_pgt(struct nvkm_vm *vm, int big, u32 fpde, u32 lpde)
                        mmu->func->map_pgt(vpgd->obj, pde, vpgt->mem);
                }
 
+               mmu->func->flush(vm);
+
                nvkm_memory_del(&pgt);
        }
 }
index 54a47b40546f69c7ea0d3dbf033c22c95f106516..f96830ffd9f1c1456965810fad723ab365a7f263 100644 (file)
@@ -1021,7 +1021,7 @@ static int i2c_imx_init_recovery_info(struct imx_i2c_struct *i2c_imx,
        }
 
        dev_dbg(&pdev->dev, "using scl-gpio %d and sda-gpio %d for recovery\n",
-                       rinfo->sda_gpio, rinfo->scl_gpio);
+                       rinfo->scl_gpio, rinfo->sda_gpio);
 
        rinfo->prepare_recovery = i2c_imx_prepare_recovery;
        rinfo->unprepare_recovery = i2c_imx_unprepare_recovery;
@@ -1100,7 +1100,7 @@ static int i2c_imx_probe(struct platform_device *pdev)
        }
 
        /* Request IRQ */
-       ret = devm_request_irq(&pdev->dev, irq, i2c_imx_isr, 0,
+       ret = devm_request_irq(&pdev->dev, irq, i2c_imx_isr, IRQF_SHARED,
                                pdev->name, i2c_imx);
        if (ret) {
                dev_err(&pdev->dev, "can't claim irq %d\n", irq);
index 22ffcb73c185f592d8b4e6bdbb1ede45cbeb4951..b51adffa484109efb842bbe75afec593ac8a1731 100644 (file)
@@ -340,12 +340,15 @@ static int ismt_process_desc(const struct ismt_desc *desc,
                        data->word = dma_buffer[0] | (dma_buffer[1] << 8);
                        break;
                case I2C_SMBUS_BLOCK_DATA:
-               case I2C_SMBUS_I2C_BLOCK_DATA:
                        if (desc->rxbytes != dma_buffer[0] + 1)
                                return -EMSGSIZE;
 
                        memcpy(data->block, dma_buffer, desc->rxbytes);
                        break;
+               case I2C_SMBUS_I2C_BLOCK_DATA:
+                       memcpy(&data->block[1], dma_buffer, desc->rxbytes);
+                       data->block[0] = desc->rxbytes;
+                       break;
                }
                return 0;
        }
index 1ebb5e947e0b6625fcf0cda7a71f51e79ac29178..23c2ea2baedc07ee15dfab3e9ea0ce0629587374 100644 (file)
@@ -360,6 +360,7 @@ static int omap_i2c_init(struct omap_i2c_dev *omap)
        unsigned long fclk_rate = 12000000;
        unsigned long internal_clk = 0;
        struct clk *fclk;
+       int error;
 
        if (omap->rev >= OMAP_I2C_REV_ON_3430_3530) {
                /*
@@ -378,6 +379,13 @@ static int omap_i2c_init(struct omap_i2c_dev *omap)
                 * do this bit unconditionally.
                 */
                fclk = clk_get(omap->dev, "fck");
+               if (IS_ERR(fclk)) {
+                       error = PTR_ERR(fclk);
+                       dev_err(omap->dev, "could not get fck: %i\n", error);
+
+                       return error;
+               }
+
                fclk_rate = clk_get_rate(fclk);
                clk_put(fclk);
 
@@ -410,6 +418,12 @@ static int omap_i2c_init(struct omap_i2c_dev *omap)
                else
                        internal_clk = 4000;
                fclk = clk_get(omap->dev, "fck");
+               if (IS_ERR(fclk)) {
+                       error = PTR_ERR(fclk);
+                       dev_err(omap->dev, "could not get fck: %i\n", error);
+
+                       return error;
+               }
                fclk_rate = clk_get_rate(fclk) / 1000;
                clk_put(fclk);
 
index 0ecdb47a23abcbf9691bf809b126d72d6c3a46f8..174579d32e5f39ecdc44d2c230b55fbfb5d073e2 100644 (file)
@@ -85,6 +85,9 @@
 /* SB800 constants */
 #define SB800_PIIX4_SMB_IDX            0xcd6
 
+#define KERNCZ_IMC_IDX                 0x3e
+#define KERNCZ_IMC_DATA                        0x3f
+
 /*
  * SB800 port is selected by bits 2:1 of the smb_en register (0x2c)
  * or the smb_sel register (0x2e), depending on bit 0 of register 0x2f.
 #define SB800_PIIX4_PORT_IDX_ALT       0x2e
 #define SB800_PIIX4_PORT_IDX_SEL       0x2f
 #define SB800_PIIX4_PORT_IDX_MASK      0x06
+#define SB800_PIIX4_PORT_IDX_SHIFT     1
+
+/* On kerncz, SmBus0Sel is at bit 20:19 of PMx00 DecodeEn */
+#define SB800_PIIX4_PORT_IDX_KERNCZ            0x02
+#define SB800_PIIX4_PORT_IDX_MASK_KERNCZ       0x18
+#define SB800_PIIX4_PORT_IDX_SHIFT_KERNCZ      3
 
 /* insmod parameters */
 
@@ -149,6 +158,8 @@ static const struct dmi_system_id piix4_dmi_ibm[] = {
  */
 static DEFINE_MUTEX(piix4_mutex_sb800);
 static u8 piix4_port_sel_sb800;
+static u8 piix4_port_mask_sb800;
+static u8 piix4_port_shift_sb800;
 static const char *piix4_main_port_names_sb800[PIIX4_MAX_ADAPTERS] = {
        " port 0", " port 2", " port 3", " port 4"
 };
@@ -159,6 +170,7 @@ struct i2c_piix4_adapdata {
 
        /* SB800 */
        bool sb800_main;
+       bool notify_imc;
        u8 port;                /* Port number, shifted */
 };
 
@@ -347,7 +359,19 @@ static int piix4_setup_sb800(struct pci_dev *PIIX4_dev,
 
        /* Find which register is used for port selection */
        if (PIIX4_dev->vendor == PCI_VENDOR_ID_AMD) {
-               piix4_port_sel_sb800 = SB800_PIIX4_PORT_IDX_ALT;
+               switch (PIIX4_dev->device) {
+               case PCI_DEVICE_ID_AMD_KERNCZ_SMBUS:
+                       piix4_port_sel_sb800 = SB800_PIIX4_PORT_IDX_KERNCZ;
+                       piix4_port_mask_sb800 = SB800_PIIX4_PORT_IDX_MASK_KERNCZ;
+                       piix4_port_shift_sb800 = SB800_PIIX4_PORT_IDX_SHIFT_KERNCZ;
+                       break;
+               case PCI_DEVICE_ID_AMD_HUDSON2_SMBUS:
+               default:
+                       piix4_port_sel_sb800 = SB800_PIIX4_PORT_IDX_ALT;
+                       piix4_port_mask_sb800 = SB800_PIIX4_PORT_IDX_MASK;
+                       piix4_port_shift_sb800 = SB800_PIIX4_PORT_IDX_SHIFT;
+                       break;
+               }
        } else {
                mutex_lock(&piix4_mutex_sb800);
                outb_p(SB800_PIIX4_PORT_IDX_SEL, SB800_PIIX4_SMB_IDX);
@@ -355,6 +379,8 @@ static int piix4_setup_sb800(struct pci_dev *PIIX4_dev,
                piix4_port_sel_sb800 = (port_sel & 0x01) ?
                                       SB800_PIIX4_PORT_IDX_ALT :
                                       SB800_PIIX4_PORT_IDX;
+               piix4_port_mask_sb800 = SB800_PIIX4_PORT_IDX_MASK;
+               piix4_port_shift_sb800 = SB800_PIIX4_PORT_IDX_SHIFT;
                mutex_unlock(&piix4_mutex_sb800);
        }
 
@@ -572,6 +598,67 @@ static s32 piix4_access(struct i2c_adapter * adap, u16 addr,
        return 0;
 }
 
+static uint8_t piix4_imc_read(uint8_t idx)
+{
+       outb_p(idx, KERNCZ_IMC_IDX);
+       return inb_p(KERNCZ_IMC_DATA);
+}
+
+static void piix4_imc_write(uint8_t idx, uint8_t value)
+{
+       outb_p(idx, KERNCZ_IMC_IDX);
+       outb_p(value, KERNCZ_IMC_DATA);
+}
+
+static int piix4_imc_sleep(void)
+{
+       int timeout = MAX_TIMEOUT;
+
+       if (!request_muxed_region(KERNCZ_IMC_IDX, 2, "smbus_kerncz_imc"))
+               return -EBUSY;
+
+       /* clear response register */
+       piix4_imc_write(0x82, 0x00);
+       /* request ownership flag */
+       piix4_imc_write(0x83, 0xB4);
+       /* kick off IMC Mailbox command 96 */
+       piix4_imc_write(0x80, 0x96);
+
+       while (timeout--) {
+               if (piix4_imc_read(0x82) == 0xfa) {
+                       release_region(KERNCZ_IMC_IDX, 2);
+                       return 0;
+               }
+               usleep_range(1000, 2000);
+       }
+
+       release_region(KERNCZ_IMC_IDX, 2);
+       return -ETIMEDOUT;
+}
+
+static void piix4_imc_wakeup(void)
+{
+       int timeout = MAX_TIMEOUT;
+
+       if (!request_muxed_region(KERNCZ_IMC_IDX, 2, "smbus_kerncz_imc"))
+               return;
+
+       /* clear response register */
+       piix4_imc_write(0x82, 0x00);
+       /* release ownership flag */
+       piix4_imc_write(0x83, 0xB5);
+       /* kick off IMC Mailbox command 96 */
+       piix4_imc_write(0x80, 0x96);
+
+       while (timeout--) {
+               if (piix4_imc_read(0x82) == 0xfa)
+                       break;
+               usleep_range(1000, 2000);
+       }
+
+       release_region(KERNCZ_IMC_IDX, 2);
+}
+
 /*
  * Handles access to multiple SMBus ports on the SB800.
  * The port is selected by bits 2:1 of the smb_en register (0x2c).
@@ -612,12 +699,47 @@ static s32 piix4_access_sb800(struct i2c_adapter *adap, u16 addr,
                return -EBUSY;
        }
 
+       /*
+        * Notify the IMC (Integrated Micro Controller) if required.
+        * Among other responsibilities, the IMC is in charge of monitoring
+        * the System fans and temperature sensors, and act accordingly.
+        * All this is done through SMBus and can/will collide
+        * with our transactions if they are long (BLOCK_DATA).
+        * Therefore we need to request the ownership flag during those
+        * transactions.
+        */
+       if ((size == I2C_SMBUS_BLOCK_DATA) && adapdata->notify_imc) {
+               int ret;
+
+               ret = piix4_imc_sleep();
+               switch (ret) {
+               case -EBUSY:
+                       dev_warn(&adap->dev,
+                                "IMC base address index region 0x%x already in use.\n",
+                                KERNCZ_IMC_IDX);
+                       break;
+               case -ETIMEDOUT:
+                       dev_warn(&adap->dev,
+                                "Failed to communicate with the IMC.\n");
+                       break;
+               default:
+                       break;
+               }
+
+               /* If IMC communication fails do not retry */
+               if (ret) {
+                       dev_warn(&adap->dev,
+                                "Continuing without IMC notification.\n");
+                       adapdata->notify_imc = false;
+               }
+       }
+
        outb_p(piix4_port_sel_sb800, SB800_PIIX4_SMB_IDX);
        smba_en_lo = inb_p(SB800_PIIX4_SMB_IDX + 1);
 
        port = adapdata->port;
-       if ((smba_en_lo & SB800_PIIX4_PORT_IDX_MASK) != port)
-               outb_p((smba_en_lo & ~SB800_PIIX4_PORT_IDX_MASK) | port,
+       if ((smba_en_lo & piix4_port_mask_sb800) != port)
+               outb_p((smba_en_lo & ~piix4_port_mask_sb800) | port,
                       SB800_PIIX4_SMB_IDX + 1);
 
        retval = piix4_access(adap, addr, flags, read_write,
@@ -628,6 +750,9 @@ static s32 piix4_access_sb800(struct i2c_adapter *adap, u16 addr,
        /* Release the semaphore */
        outb_p(smbslvcnt | 0x20, SMBSLVCNT);
 
+       if ((size == I2C_SMBUS_BLOCK_DATA) && adapdata->notify_imc)
+               piix4_imc_wakeup();
+
        mutex_unlock(&piix4_mutex_sb800);
 
        return retval;
@@ -679,7 +804,7 @@ static struct i2c_adapter *piix4_main_adapters[PIIX4_MAX_ADAPTERS];
 static struct i2c_adapter *piix4_aux_adapter;
 
 static int piix4_add_adapter(struct pci_dev *dev, unsigned short smba,
-                            bool sb800_main, u8 port,
+                            bool sb800_main, u8 port, bool notify_imc,
                             const char *name, struct i2c_adapter **padap)
 {
        struct i2c_adapter *adap;
@@ -706,7 +831,8 @@ static int piix4_add_adapter(struct pci_dev *dev, unsigned short smba,
 
        adapdata->smba = smba;
        adapdata->sb800_main = sb800_main;
-       adapdata->port = port << 1;
+       adapdata->port = port << piix4_port_shift_sb800;
+       adapdata->notify_imc = notify_imc;
 
        /* set up the sysfs linkage to our parent device */
        adap->dev.parent = &dev->dev;
@@ -728,14 +854,15 @@ static int piix4_add_adapter(struct pci_dev *dev, unsigned short smba,
        return 0;
 }
 
-static int piix4_add_adapters_sb800(struct pci_dev *dev, unsigned short smba)
+static int piix4_add_adapters_sb800(struct pci_dev *dev, unsigned short smba,
+                                   bool notify_imc)
 {
        struct i2c_piix4_adapdata *adapdata;
        int port;
        int retval;
 
        for (port = 0; port < PIIX4_MAX_ADAPTERS; port++) {
-               retval = piix4_add_adapter(dev, smba, true, port,
+               retval = piix4_add_adapter(dev, smba, true, port, notify_imc,
                                           piix4_main_port_names_sb800[port],
                                           &piix4_main_adapters[port]);
                if (retval < 0)
@@ -769,6 +896,7 @@ static int piix4_probe(struct pci_dev *dev, const struct pci_device_id *id)
             dev->device == PCI_DEVICE_ID_ATI_SBX00_SMBUS &&
             dev->revision >= 0x40) ||
            dev->vendor == PCI_VENDOR_ID_AMD) {
+               bool notify_imc = false;
                is_sb800 = true;
 
                if (!request_region(SB800_PIIX4_SMB_IDX, 2, "smba_idx")) {
@@ -778,6 +906,20 @@ static int piix4_probe(struct pci_dev *dev, const struct pci_device_id *id)
                        return -EBUSY;
                }
 
+               if (dev->vendor == PCI_VENDOR_ID_AMD &&
+                   dev->device == PCI_DEVICE_ID_AMD_KERNCZ_SMBUS) {
+                       u8 imc;
+
+                       /*
+                        * Detect if IMC is active or not, this method is
+                        * described on coreboot's AMD IMC notes
+                        */
+                       pci_bus_read_config_byte(dev->bus, PCI_DEVFN(0x14, 3),
+                                                0x40, &imc);
+                       if (imc & 0x80)
+                               notify_imc = true;
+               }
+
                /* base address location etc changed in SB800 */
                retval = piix4_setup_sb800(dev, id, 0);
                if (retval < 0) {
@@ -789,7 +931,7 @@ static int piix4_probe(struct pci_dev *dev, const struct pci_device_id *id)
                 * Try to register multiplexed main SMBus adapter,
                 * give up if we can't
                 */
-               retval = piix4_add_adapters_sb800(dev, retval);
+               retval = piix4_add_adapters_sb800(dev, retval, notify_imc);
                if (retval < 0) {
                        release_region(SB800_PIIX4_SMB_IDX, 2);
                        return retval;
@@ -800,7 +942,7 @@ static int piix4_probe(struct pci_dev *dev, const struct pci_device_id *id)
                        return retval;
 
                /* Try to register main SMBus adapter, give up if we can't */
-               retval = piix4_add_adapter(dev, retval, false, 0, "",
+               retval = piix4_add_adapter(dev, retval, false, 0, false, "",
                                           &piix4_main_adapters[0]);
                if (retval < 0)
                        return retval;
@@ -827,7 +969,7 @@ static int piix4_probe(struct pci_dev *dev, const struct pci_device_id *id)
        if (retval > 0) {
                /* Try to add the aux adapter if it exists,
                 * piix4_add_adapter will clean up if this fails */
-               piix4_add_adapter(dev, retval, false, 0,
+               piix4_add_adapter(dev, retval, false, 0, false,
                                  is_sb800 ? piix4_aux_port_name_sb800 : "",
                                  &piix4_aux_adapter);
        }
index d268fdc23c6419e2540cc941edb66231be3a900d..762bfb9487dc961cf1c7d12a18a0d10dd3386b4c 100644 (file)
@@ -933,58 +933,52 @@ int input_set_keycode(struct input_dev *dev,
 }
 EXPORT_SYMBOL(input_set_keycode);
 
+bool input_match_device_id(const struct input_dev *dev,
+                          const struct input_device_id *id)
+{
+       if (id->flags & INPUT_DEVICE_ID_MATCH_BUS)
+               if (id->bustype != dev->id.bustype)
+                       return false;
+
+       if (id->flags & INPUT_DEVICE_ID_MATCH_VENDOR)
+               if (id->vendor != dev->id.vendor)
+                       return false;
+
+       if (id->flags & INPUT_DEVICE_ID_MATCH_PRODUCT)
+               if (id->product != dev->id.product)
+                       return false;
+
+       if (id->flags & INPUT_DEVICE_ID_MATCH_VERSION)
+               if (id->version != dev->id.version)
+                       return false;
+
+       if (!bitmap_subset(id->evbit, dev->evbit, EV_MAX) ||
+           !bitmap_subset(id->keybit, dev->keybit, KEY_MAX) ||
+           !bitmap_subset(id->relbit, dev->relbit, REL_MAX) ||
+           !bitmap_subset(id->absbit, dev->absbit, ABS_MAX) ||
+           !bitmap_subset(id->mscbit, dev->mscbit, MSC_MAX) ||
+           !bitmap_subset(id->ledbit, dev->ledbit, LED_MAX) ||
+           !bitmap_subset(id->sndbit, dev->sndbit, SND_MAX) ||
+           !bitmap_subset(id->ffbit, dev->ffbit, FF_MAX) ||
+           !bitmap_subset(id->swbit, dev->swbit, SW_MAX) ||
+           !bitmap_subset(id->propbit, dev->propbit, INPUT_PROP_MAX)) {
+               return false;
+       }
+
+       return true;
+}
+EXPORT_SYMBOL(input_match_device_id);
+
 static const struct input_device_id *input_match_device(struct input_handler *handler,
                                                        struct input_dev *dev)
 {
        const struct input_device_id *id;
 
        for (id = handler->id_table; id->flags || id->driver_info; id++) {
-
-               if (id->flags & INPUT_DEVICE_ID_MATCH_BUS)
-                       if (id->bustype != dev->id.bustype)
-                               continue;
-
-               if (id->flags & INPUT_DEVICE_ID_MATCH_VENDOR)
-                       if (id->vendor != dev->id.vendor)
-                               continue;
-
-               if (id->flags & INPUT_DEVICE_ID_MATCH_PRODUCT)
-                       if (id->product != dev->id.product)
-                               continue;
-
-               if (id->flags & INPUT_DEVICE_ID_MATCH_VERSION)
-                       if (id->version != dev->id.version)
-                               continue;
-
-               if (!bitmap_subset(id->evbit, dev->evbit, EV_MAX))
-                       continue;
-
-               if (!bitmap_subset(id->keybit, dev->keybit, KEY_MAX))
-                       continue;
-
-               if (!bitmap_subset(id->relbit, dev->relbit, REL_MAX))
-                       continue;
-
-               if (!bitmap_subset(id->absbit, dev->absbit, ABS_MAX))
-                       continue;
-
-               if (!bitmap_subset(id->mscbit, dev->mscbit, MSC_MAX))
-                       continue;
-
-               if (!bitmap_subset(id->ledbit, dev->ledbit, LED_MAX))
-                       continue;
-
-               if (!bitmap_subset(id->sndbit, dev->sndbit, SND_MAX))
-                       continue;
-
-               if (!bitmap_subset(id->ffbit, dev->ffbit, FF_MAX))
-                       continue;
-
-               if (!bitmap_subset(id->swbit, dev->swbit, SW_MAX))
-                       continue;
-
-               if (!handler->match || handler->match(handler, dev))
+               if (input_match_device_id(dev, id) &&
+                   (!handler->match || handler->match(handler, dev))) {
                        return id;
+               }
        }
 
        return NULL;
index 29d677c714d25fa2fca5d41713f32a5a9fe3e64f..7b29a894403981c233120fc282f62d93f3d5f71f 100644 (file)
@@ -747,6 +747,68 @@ static void joydev_cleanup(struct joydev *joydev)
                input_close_device(handle);
 }
 
+/*
+ * These codes are copied from from hid-ids.h, unfortunately there is no common
+ * usb_ids/bt_ids.h header.
+ */
+#define USB_VENDOR_ID_SONY                     0x054c
+#define USB_DEVICE_ID_SONY_PS3_CONTROLLER              0x0268
+#define USB_DEVICE_ID_SONY_PS4_CONTROLLER              0x05c4
+#define USB_DEVICE_ID_SONY_PS4_CONTROLLER_2            0x09cc
+#define USB_DEVICE_ID_SONY_PS4_CONTROLLER_DONGLE       0x0ba0
+
+#define USB_VENDOR_ID_THQ                      0x20d6
+#define USB_DEVICE_ID_THQ_PS3_UDRAW                    0xcb17
+
+#define ACCEL_DEV(vnd, prd)                                            \
+       {                                                               \
+               .flags = INPUT_DEVICE_ID_MATCH_VENDOR |                 \
+                               INPUT_DEVICE_ID_MATCH_PRODUCT |         \
+                               INPUT_DEVICE_ID_MATCH_PROPBIT,          \
+               .vendor = (vnd),                                        \
+               .product = (prd),                                       \
+               .propbit = { BIT_MASK(INPUT_PROP_ACCELEROMETER) },      \
+       }
+
+static const struct input_device_id joydev_blacklist[] = {
+       /* Avoid touchpads and touchscreens */
+       {
+               .flags = INPUT_DEVICE_ID_MATCH_EVBIT |
+                               INPUT_DEVICE_ID_MATCH_KEYBIT,
+               .evbit = { BIT_MASK(EV_KEY) },
+               .keybit = { [BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH) },
+       },
+       /* Avoid tablets, digitisers and similar devices */
+       {
+               .flags = INPUT_DEVICE_ID_MATCH_EVBIT |
+                               INPUT_DEVICE_ID_MATCH_KEYBIT,
+               .evbit = { BIT_MASK(EV_KEY) },
+               .keybit = { [BIT_WORD(BTN_DIGI)] = BIT_MASK(BTN_DIGI) },
+       },
+       /* Disable accelerometers on composite devices */
+       ACCEL_DEV(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER),
+       ACCEL_DEV(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS4_CONTROLLER),
+       ACCEL_DEV(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS4_CONTROLLER_2),
+       ACCEL_DEV(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS4_CONTROLLER_DONGLE),
+       ACCEL_DEV(USB_VENDOR_ID_THQ, USB_DEVICE_ID_THQ_PS3_UDRAW),
+       { /* sentinel */ }
+};
+
+static bool joydev_dev_is_blacklisted(struct input_dev *dev)
+{
+       const struct input_device_id *id;
+
+       for (id = joydev_blacklist; id->flags; id++) {
+               if (input_match_device_id(dev, id)) {
+                       dev_dbg(&dev->dev,
+                               "joydev: blacklisting '%s'\n", dev->name);
+                       return true;
+               }
+       }
+
+       return false;
+}
+
 static bool joydev_dev_is_absolute_mouse(struct input_dev *dev)
 {
        DECLARE_BITMAP(jd_scratch, KEY_CNT);
@@ -807,12 +869,8 @@ static bool joydev_dev_is_absolute_mouse(struct input_dev *dev)
 
 static bool joydev_match(struct input_handler *handler, struct input_dev *dev)
 {
-       /* Avoid touchpads and touchscreens */
-       if (test_bit(EV_KEY, dev->evbit) && test_bit(BTN_TOUCH, dev->keybit))
-               return false;
-
-       /* Avoid tablets, digitisers and similar devices */
-       if (test_bit(EV_KEY, dev->evbit) && test_bit(BTN_DIGI, dev->keybit))
+       /* Disable blacklisted devices */
+       if (joydev_dev_is_blacklisted(dev))
                return false;
 
        /* Avoid absolute mice */
index e37e335e406ffbb13d4fa323705373fa2fa58d16..6da607d3b81172a38f95c672e37976bedc8d097d 100644 (file)
@@ -234,14 +234,7 @@ static irqreturn_t tca8418_irq_handler(int irq, void *dev_id)
 static int tca8418_configure(struct tca8418_keypad *keypad_data,
                             u32 rows, u32 cols)
 {
-       int reg, error;
-
-       /* Write config register, if this fails assume device not present */
-       error = tca8418_write_byte(keypad_data, REG_CFG,
-                               CFG_INT_CFG | CFG_OVR_FLOW_IEN | CFG_KE_IEN);
-       if (error < 0)
-               return -ENODEV;
-
+       int reg, error = 0;
 
        /* Assemble a mask for row and column registers */
        reg  =  ~(~0 << rows);
@@ -257,6 +250,12 @@ static int tca8418_configure(struct tca8418_keypad *keypad_data,
        error |= tca8418_write_byte(keypad_data, REG_DEBOUNCE_DIS2, reg >> 8);
        error |= tca8418_write_byte(keypad_data, REG_DEBOUNCE_DIS3, reg >> 16);
 
+       if (error)
+               return error;
+
+       error = tca8418_write_byte(keypad_data, REG_CFG,
+                               CFG_INT_CFG | CFG_OVR_FLOW_IEN | CFG_KE_IEN);
+
        return error;
 }
 
@@ -268,6 +267,7 @@ static int tca8418_keypad_probe(struct i2c_client *client,
        struct input_dev *input;
        u32 rows = 0, cols = 0;
        int error, row_shift, max_keys;
+       u8 reg;
 
        /* Check i2c driver capabilities */
        if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE)) {
@@ -301,10 +301,10 @@ static int tca8418_keypad_probe(struct i2c_client *client,
        keypad_data->client = client;
        keypad_data->row_shift = row_shift;
 
-       /* Initialize the chip or fail if chip isn't present */
-       error = tca8418_configure(keypad_data, rows, cols);
-       if (error < 0)
-               return error;
+       /* Read key lock register, if this fails assume device not present */
+       error = tca8418_read_byte(keypad_data, REG_KEY_LCK_EC, &reg);
+       if (error)
+               return -ENODEV;
 
        /* Configure input device */
        input = devm_input_allocate_device(dev);
@@ -340,6 +340,11 @@ static int tca8418_keypad_probe(struct i2c_client *client,
                return error;
        }
 
+       /* Initialize the chip */
+       error = tca8418_configure(keypad_data, rows, cols);
+       if (error < 0)
+               return error;
+
        error = input_register_device(input);
        if (error) {
                dev_err(dev, "Unable to register input device, error: %d\n",
index 6cee5adc3b5cfa1ec322db10c49d84f1bcbc2ae3..debeeaeb88127baae0a65dba44875084af034945 100644 (file)
@@ -403,6 +403,7 @@ static const struct platform_device_id axp_pek_id_match[] = {
        },
        { /* sentinel */ }
 };
+MODULE_DEVICE_TABLE(platform, axp_pek_id_match);
 
 static struct platform_driver axp20x_pek_driver = {
        .probe          = axp20x_pek_probe,
@@ -417,4 +418,3 @@ module_platform_driver(axp20x_pek_driver);
 MODULE_DESCRIPTION("axp20x Power Button");
 MODULE_AUTHOR("Carlo Caione <carlo@caione.org>");
 MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:axp20x-pek");
index 6bf82ea8c918adcbbba700100ead7d270a60695c..ae473123583bb22bedbb33426f11eb8f802ea368 100644 (file)
@@ -1635,13 +1635,25 @@ ims_pcu_get_cdc_union_desc(struct usb_interface *intf)
                return NULL;
        }
 
-       while (buflen > 0) {
+       while (buflen >= sizeof(*union_desc)) {
                union_desc = (struct usb_cdc_union_desc *)buf;
 
+               if (union_desc->bLength > buflen) {
+                       dev_err(&intf->dev, "Too large descriptor\n");
+                       return NULL;
+               }
+
                if (union_desc->bDescriptorType == USB_DT_CS_INTERFACE &&
                    union_desc->bDescriptorSubType == USB_CDC_UNION_TYPE) {
                        dev_dbg(&intf->dev, "Found union header\n");
-                       return union_desc;
+
+                       if (union_desc->bLength >= sizeof(*union_desc))
+                               return union_desc;
+
+                       dev_err(&intf->dev,
+                               "Union descriptor to short (%d vs %zd\n)",
+                               union_desc->bLength, sizeof(*union_desc));
+                       return NULL;
                }
 
                buflen -= union_desc->bLength;
index 5af0b7d200bc23ff0f2287d6e0b69a631fb8bb22..ee5466a374bf0f370000cf002d94bf2514d02318 100644 (file)
@@ -1709,8 +1709,7 @@ static int synaptics_create_intertouch(struct psmouse *psmouse,
                .sensor_pdata = {
                        .sensor_type = rmi_sensor_touchpad,
                        .axis_align.flip_y = true,
-                       /* to prevent cursors jumps: */
-                       .kernel_tracking = true,
+                       .kernel_tracking = false,
                        .topbuttonpad = topbuttonpad,
                },
                .f30_data = {
index 32d2762448aa24168c9dd0ad38c8c9eb1ec13ff3..b3bbad7d228296118f35a2d4bff7c295b5e9839c 100644 (file)
@@ -72,6 +72,9 @@ struct goodix_ts_data {
 #define GOODIX_REG_CONFIG_DATA         0x8047
 #define GOODIX_REG_ID                  0x8140
 
+#define GOODIX_BUFFER_STATUS_READY     BIT(7)
+#define GOODIX_BUFFER_STATUS_TIMEOUT   20
+
 #define RESOLUTION_LOC         1
 #define MAX_CONTACTS_LOC       5
 #define TRIGGER_LOC            6
@@ -195,35 +198,53 @@ static int goodix_get_cfg_len(u16 id)
 
 static int goodix_ts_read_input_report(struct goodix_ts_data *ts, u8 *data)
 {
+       unsigned long max_timeout;
        int touch_num;
        int error;
 
-       error = goodix_i2c_read(ts->client, GOODIX_READ_COOR_ADDR, data,
-                               GOODIX_CONTACT_SIZE + 1);
-       if (error) {
-               dev_err(&ts->client->dev, "I2C transfer error: %d\n", error);
-               return error;
-       }
+       /*
+        * The 'buffer status' bit, which indicates that the data is valid, is
+        * not set as soon as the interrupt is raised, but slightly after.
+        * This takes around 10 ms to happen, so we poll for 20 ms.
+        */
+       max_timeout = jiffies + msecs_to_jiffies(GOODIX_BUFFER_STATUS_TIMEOUT);
+       do {
+               error = goodix_i2c_read(ts->client, GOODIX_READ_COOR_ADDR,
+                                       data, GOODIX_CONTACT_SIZE + 1);
+               if (error) {
+                       dev_err(&ts->client->dev, "I2C transfer error: %d\n",
+                                       error);
+                       return error;
+               }
 
-       if (!(data[0] & 0x80))
-               return -EAGAIN;
+               if (data[0] & GOODIX_BUFFER_STATUS_READY) {
+                       touch_num = data[0] & 0x0f;
+                       if (touch_num > ts->max_touch_num)
+                               return -EPROTO;
+
+                       if (touch_num > 1) {
+                               data += 1 + GOODIX_CONTACT_SIZE;
+                               error = goodix_i2c_read(ts->client,
+                                               GOODIX_READ_COOR_ADDR +
+                                                       1 + GOODIX_CONTACT_SIZE,
+                                               data,
+                                               GOODIX_CONTACT_SIZE *
+                                                       (touch_num - 1));
+                               if (error)
+                                       return error;
+                       }
+
+                       return touch_num;
+               }
 
-       touch_num = data[0] & 0x0f;
-       if (touch_num > ts->max_touch_num)
-               return -EPROTO;
-
-       if (touch_num > 1) {
-               data += 1 + GOODIX_CONTACT_SIZE;
-               error = goodix_i2c_read(ts->client,
-                                       GOODIX_READ_COOR_ADDR +
-                                               1 + GOODIX_CONTACT_SIZE,
-                                       data,
-                                       GOODIX_CONTACT_SIZE * (touch_num - 1));
-               if (error)
-                       return error;
-       }
+               usleep_range(1000, 2000); /* Poll every 1 - 2 ms */
+       } while (time_before(jiffies, max_timeout));
 
-       return touch_num;
+       /*
+        * The Goodix panel will send spurious interrupts after a
+        * 'finger up' event, which will always cause a timeout.
+        */
+       return 0;
 }
 
 static void goodix_ts_report_touch(struct goodix_ts_data *ts, u8 *coor_data)
index 157fdb4bb2e8ba931697d18281afb3887beceaca..8c6c6178ec12fd26ed9832311419da243ed4c154 100644 (file)
@@ -663,12 +663,10 @@ static int stmfts_probe(struct i2c_client *client,
        sdata->input->open = stmfts_input_open;
        sdata->input->close = stmfts_input_close;
 
+       input_set_capability(sdata->input, EV_ABS, ABS_MT_POSITION_X);
+       input_set_capability(sdata->input, EV_ABS, ABS_MT_POSITION_Y);
        touchscreen_parse_properties(sdata->input, true, &sdata->prop);
 
-       input_set_abs_params(sdata->input, ABS_MT_POSITION_X, 0,
-                                               sdata->prop.max_x, 0, 0);
-       input_set_abs_params(sdata->input, ABS_MT_POSITION_Y, 0,
-                                               sdata->prop.max_y, 0, 0);
        input_set_abs_params(sdata->input, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0);
        input_set_abs_params(sdata->input, ABS_MT_TOUCH_MINOR, 0, 255, 0, 0);
        input_set_abs_params(sdata->input, ABS_MT_ORIENTATION, 0, 255, 0, 0);
index 7953381d939ab49f26f460bf7bac808600cb2549..f1043ae71dccb5c4a10126279ff0b1a3c6142089 100644 (file)
@@ -161,7 +161,7 @@ static void titsc_step_config(struct titsc *ts_dev)
                break;
        case 5:
                config |= ts_dev->bit_xp | STEPCONFIG_INP_AN4 |
-                               ts_dev->bit_xn | ts_dev->bit_yp;
+                               STEPCONFIG_XNP | STEPCONFIG_YPN;
                break;
        case 8:
                config |= ts_dev->bit_yp | STEPCONFIG_INP(ts_dev->inp_xp);
index e8d89343d6139424e2caf0baa112955b7005b2e4..e88395605e32dc32960974a4e8707a30037b107b 100644 (file)
@@ -107,6 +107,10 @@ struct its_node {
 
 #define ITS_ITT_ALIGN          SZ_256
 
+/* The maximum number of VPEID bits supported by VLPI commands */
+#define ITS_MAX_VPEID_BITS     (16)
+#define ITS_MAX_VPEID          (1 << (ITS_MAX_VPEID_BITS))
+
 /* Convert page order to size in bytes */
 #define PAGE_ORDER_TO_SIZE(o)  (PAGE_SIZE << (o))
 
@@ -308,7 +312,7 @@ static void its_encode_size(struct its_cmd_block *cmd, u8 size)
 
 static void its_encode_itt(struct its_cmd_block *cmd, u64 itt_addr)
 {
-       its_mask_encode(&cmd->raw_cmd[2], itt_addr >> 8, 50, 8);
+       its_mask_encode(&cmd->raw_cmd[2], itt_addr >> 8, 51, 8);
 }
 
 static void its_encode_valid(struct its_cmd_block *cmd, int valid)
@@ -318,7 +322,7 @@ static void its_encode_valid(struct its_cmd_block *cmd, int valid)
 
 static void its_encode_target(struct its_cmd_block *cmd, u64 target_addr)
 {
-       its_mask_encode(&cmd->raw_cmd[2], target_addr >> 16, 50, 16);
+       its_mask_encode(&cmd->raw_cmd[2], target_addr >> 16, 51, 16);
 }
 
 static void its_encode_collection(struct its_cmd_block *cmd, u16 col)
@@ -358,7 +362,7 @@ static void its_encode_its_list(struct its_cmd_block *cmd, u16 its_list)
 
 static void its_encode_vpt_addr(struct its_cmd_block *cmd, u64 vpt_pa)
 {
-       its_mask_encode(&cmd->raw_cmd[3], vpt_pa >> 16, 50, 16);
+       its_mask_encode(&cmd->raw_cmd[3], vpt_pa >> 16, 51, 16);
 }
 
 static void its_encode_vpt_size(struct its_cmd_block *cmd, u8 vpt_size)
@@ -1478,9 +1482,9 @@ static int its_setup_baser(struct its_node *its, struct its_baser *baser,
        u64 val = its_read_baser(its, baser);
        u64 esz = GITS_BASER_ENTRY_SIZE(val);
        u64 type = GITS_BASER_TYPE(val);
+       u64 baser_phys, tmp;
        u32 alloc_pages;
        void *base;
-       u64 tmp;
 
 retry_alloc_baser:
        alloc_pages = (PAGE_ORDER_TO_SIZE(order) / psz);
@@ -1496,8 +1500,24 @@ retry_alloc_baser:
        if (!base)
                return -ENOMEM;
 
+       baser_phys = virt_to_phys(base);
+
+       /* Check if the physical address of the memory is above 48bits */
+       if (IS_ENABLED(CONFIG_ARM64_64K_PAGES) && (baser_phys >> 48)) {
+
+               /* 52bit PA is supported only when PageSize=64K */
+               if (psz != SZ_64K) {
+                       pr_err("ITS: no 52bit PA support when psz=%d\n", psz);
+                       free_pages((unsigned long)base, order);
+                       return -ENXIO;
+               }
+
+               /* Convert 52bit PA to 48bit field */
+               baser_phys = GITS_BASER_PHYS_52_to_48(baser_phys);
+       }
+
 retry_baser:
-       val = (virt_to_phys(base)                                |
+       val = (baser_phys                                        |
                (type << GITS_BASER_TYPE_SHIFT)                  |
                ((esz - 1) << GITS_BASER_ENTRY_SIZE_SHIFT)       |
                ((alloc_pages - 1) << GITS_BASER_PAGES_SHIFT)    |
@@ -1582,13 +1602,12 @@ retry_baser:
 
 static bool its_parse_indirect_baser(struct its_node *its,
                                     struct its_baser *baser,
-                                    u32 psz, u32 *order)
+                                    u32 psz, u32 *order, u32 ids)
 {
        u64 tmp = its_read_baser(its, baser);
        u64 type = GITS_BASER_TYPE(tmp);
        u64 esz = GITS_BASER_ENTRY_SIZE(tmp);
        u64 val = GITS_BASER_InnerShareable | GITS_BASER_RaWaWb;
-       u32 ids = its->device_ids;
        u32 new_order = *order;
        bool indirect = false;
 
@@ -1680,9 +1699,13 @@ static int its_alloc_tables(struct its_node *its)
                        continue;
 
                case GITS_BASER_TYPE_DEVICE:
+                       indirect = its_parse_indirect_baser(its, baser,
+                                                           psz, &order,
+                                                           its->device_ids);
                case GITS_BASER_TYPE_VCPU:
                        indirect = its_parse_indirect_baser(its, baser,
-                                                           psz, &order);
+                                                           psz, &order,
+                                                           ITS_MAX_VPEID_BITS);
                        break;
                }
 
@@ -2551,7 +2574,7 @@ static struct irq_chip its_vpe_irq_chip = {
 
 static int its_vpe_id_alloc(void)
 {
-       return ida_simple_get(&its_vpeid_ida, 0, 1 << 16, GFP_KERNEL);
+       return ida_simple_get(&its_vpeid_ida, 0, ITS_MAX_VPEID, GFP_KERNEL);
 }
 
 static void its_vpe_id_free(u16 id)
@@ -2851,7 +2874,7 @@ static int its_init_vpe_domain(void)
                return -ENOMEM;
        }
 
-       BUG_ON(entries != vpe_proxy.dev->nr_ites);
+       BUG_ON(entries > vpe_proxy.dev->nr_ites);
 
        raw_spin_lock_init(&vpe_proxy.lock);
        vpe_proxy.next_victim = 0;
index bdbb5c0ff7fe3bd956c1c9d12364aee4cd8c5eba..0c085303a58302cc982f69e52b0a5ea8e5c60c25 100644 (file)
@@ -141,7 +141,7 @@ static void __init tangox_irq_init_chip(struct irq_chip_generic *gc,
        for (i = 0; i < 2; i++) {
                ct[i].chip.irq_ack = irq_gc_ack_set_bit;
                ct[i].chip.irq_mask = irq_gc_mask_disable_reg;
-               ct[i].chip.irq_mask_ack = irq_gc_mask_disable_reg_and_ack;
+               ct[i].chip.irq_mask_ack = irq_gc_mask_disable_and_ack_set;
                ct[i].chip.irq_unmask = irq_gc_unmask_enable_reg;
                ct[i].chip.irq_set_type = tangox_irq_set_type;
                ct[i].chip.name = gc->domain->name;
index eed6c397d8400b0a25c57feb6ef23dc49eac71df..f8a808d45034e048f9b0bc2c764c51d95e22bdc9 100644 (file)
@@ -1797,12 +1797,19 @@ static int cec_receive_notify(struct cec_adapter *adap, struct cec_msg *msg,
         */
        switch (msg->msg[1]) {
        case CEC_MSG_GET_CEC_VERSION:
-       case CEC_MSG_GIVE_DEVICE_VENDOR_ID:
        case CEC_MSG_ABORT:
        case CEC_MSG_GIVE_DEVICE_POWER_STATUS:
-       case CEC_MSG_GIVE_PHYSICAL_ADDR:
        case CEC_MSG_GIVE_OSD_NAME:
+               /*
+                * These messages reply with a directed message, so ignore if
+                * the initiator is Unregistered.
+                */
+               if (!adap->passthrough && from_unregistered)
+                       return 0;
+               /* Fall through */
+       case CEC_MSG_GIVE_DEVICE_VENDOR_ID:
        case CEC_MSG_GIVE_FEATURES:
+       case CEC_MSG_GIVE_PHYSICAL_ADDR:
                /*
                 * Skip processing these messages if the passthrough mode
                 * is on.
@@ -1810,7 +1817,7 @@ static int cec_receive_notify(struct cec_adapter *adap, struct cec_msg *msg,
                if (adap->passthrough)
                        goto skip_processing;
                /* Ignore if addressing is wrong */
-               if (is_broadcast || from_unregistered)
+               if (is_broadcast)
                        return 0;
                break;
 
index 2fcba16161685888164565bb24e0e917024092eb..9139d01ba7ed6c9470896dea8500a433d9c05240 100644 (file)
@@ -141,22 +141,39 @@ struct dvb_frontend_private {
 static void dvb_frontend_invoke_release(struct dvb_frontend *fe,
                                        void (*release)(struct dvb_frontend *fe));
 
-static void dvb_frontend_free(struct kref *ref)
+static void __dvb_frontend_free(struct dvb_frontend *fe)
 {
-       struct dvb_frontend *fe =
-               container_of(ref, struct dvb_frontend, refcount);
        struct dvb_frontend_private *fepriv = fe->frontend_priv;
 
+       if (!fepriv)
+               return;
+
        dvb_free_device(fepriv->dvbdev);
 
        dvb_frontend_invoke_release(fe, fe->ops.release);
 
        kfree(fepriv);
+       fe->frontend_priv = NULL;
+}
+
+static void dvb_frontend_free(struct kref *ref)
+{
+       struct dvb_frontend *fe =
+               container_of(ref, struct dvb_frontend, refcount);
+
+       __dvb_frontend_free(fe);
 }
 
 static void dvb_frontend_put(struct dvb_frontend *fe)
 {
-       kref_put(&fe->refcount, dvb_frontend_free);
+       /*
+        * Check if the frontend was registered, as otherwise
+        * kref was not initialized yet.
+        */
+       if (fe->frontend_priv)
+               kref_put(&fe->refcount, dvb_frontend_free);
+       else
+               __dvb_frontend_free(fe);
 }
 
 static void dvb_frontend_get(struct dvb_frontend *fe)
index 224283fe100a8fe6f6a3f17f52cfbff2a723b15e..4d086a7248e9b2508905cd026038793dc7882241 100644 (file)
@@ -55,29 +55,57 @@ struct dib3000mc_state {
 
 static u16 dib3000mc_read_word(struct dib3000mc_state *state, u16 reg)
 {
-       u8 wb[2] = { (reg >> 8) | 0x80, reg & 0xff };
-       u8 rb[2];
        struct i2c_msg msg[2] = {
-               { .addr = state->i2c_addr >> 1, .flags = 0,        .buf = wb, .len = 2 },
-               { .addr = state->i2c_addr >> 1, .flags = I2C_M_RD, .buf = rb, .len = 2 },
+               { .addr = state->i2c_addr >> 1, .flags = 0,        .len = 2 },
+               { .addr = state->i2c_addr >> 1, .flags = I2C_M_RD, .len = 2 },
        };
+       u16 word;
+       u8 *b;
+
+       b = kmalloc(4, GFP_KERNEL);
+       if (!b)
+               return 0;
+
+       b[0] = (reg >> 8) | 0x80;
+       b[1] = reg;
+       b[2] = 0;
+       b[3] = 0;
+
+       msg[0].buf = b;
+       msg[1].buf = b + 2;
 
        if (i2c_transfer(state->i2c_adap, msg, 2) != 2)
                dprintk("i2c read error on %d\n",reg);
 
-       return (rb[0] << 8) | rb[1];
+       word = (b[2] << 8) | b[3];
+       kfree(b);
+
+       return word;
 }
 
 static int dib3000mc_write_word(struct dib3000mc_state *state, u16 reg, u16 val)
 {
-       u8 b[4] = {
-               (reg >> 8) & 0xff, reg & 0xff,
-               (val >> 8) & 0xff, val & 0xff,
-       };
        struct i2c_msg msg = {
-               .addr = state->i2c_addr >> 1, .flags = 0, .buf = b, .len = 4
+               .addr = state->i2c_addr >> 1, .flags = 0, .len = 4
        };
-       return i2c_transfer(state->i2c_adap, &msg, 1) != 1 ? -EREMOTEIO : 0;
+       int rc;
+       u8 *b;
+
+       b = kmalloc(4, GFP_KERNEL);
+       if (!b)
+               return -ENOMEM;
+
+       b[0] = reg >> 8;
+       b[1] = reg;
+       b[2] = val >> 8;
+       b[3] = val;
+
+       msg.buf = b;
+
+       rc = i2c_transfer(state->i2c_adap, &msg, 1) != 1 ? -EREMOTEIO : 0;
+       kfree(b);
+
+       return rc;
 }
 
 static int dib3000mc_identify(struct dib3000mc_state *state)
index 7bec3e028beec10e188fea4d9f53cc40556f8ddf..5553b89b804e7d4219d6c767b96fbdb5006cce1b 100644 (file)
@@ -753,13 +753,19 @@ struct dvb_frontend *dvb_pll_attach(struct dvb_frontend *fe, int pll_addr,
                                    struct i2c_adapter *i2c,
                                    unsigned int pll_desc_id)
 {
-       u8 b1 [] = { 0 };
-       struct i2c_msg msg = { .addr = pll_addr, .flags = I2C_M_RD,
-                              .buf = b1, .len = 1 };
+       u8 *b1;
+       struct i2c_msg msg = { .addr = pll_addr, .flags = I2C_M_RD, .len = 1 };
        struct dvb_pll_priv *priv = NULL;
        int ret;
        const struct dvb_pll_desc *desc;
 
+       b1 = kmalloc(1, GFP_KERNEL);
+       if (!b1)
+               return NULL;
+
+       b1[0] = 0;
+       msg.buf = b1;
+
        if ((id[dvb_pll_devcount] > DVB_PLL_UNDEFINED) &&
            (id[dvb_pll_devcount] < ARRAY_SIZE(pll_list)))
                pll_desc_id = id[dvb_pll_devcount];
@@ -773,15 +779,19 @@ struct dvb_frontend *dvb_pll_attach(struct dvb_frontend *fe, int pll_addr,
                        fe->ops.i2c_gate_ctrl(fe, 1);
 
                ret = i2c_transfer (i2c, &msg, 1);
-               if (ret != 1)
+               if (ret != 1) {
+                       kfree(b1);
                        return NULL;
+               }
                if (fe->ops.i2c_gate_ctrl)
                             fe->ops.i2c_gate_ctrl(fe, 0);
        }
 
        priv = kzalloc(sizeof(struct dvb_pll_priv), GFP_KERNEL);
-       if (priv == NULL)
+       if (!priv) {
+               kfree(b1);
                return NULL;
+       }
 
        priv->pll_i2c_address = pll_addr;
        priv->i2c = i2c;
@@ -811,6 +821,8 @@ struct dvb_frontend *dvb_pll_attach(struct dvb_frontend *fe, int pll_addr,
                                "insmod option" : "autodetected");
        }
 
+       kfree(b1);
+
        return fe;
 }
 EXPORT_SYMBOL(dvb_pll_attach);
index 7e7cc49b867400093ba038baf9e14773970f15f4..3c4f7fa7b9d8ea06e7b1455ce3e0172d17322483 100644 (file)
@@ -112,7 +112,7 @@ config VIDEO_PXA27x
 
 config VIDEO_QCOM_CAMSS
        tristate "Qualcomm 8x16 V4L2 Camera Subsystem driver"
-       depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
+       depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API && HAS_DMA
        depends on (ARCH_QCOM && IOMMU_DMA) || COMPILE_TEST
        select VIDEOBUF2_DMA_SG
        select V4L2_FWNODE
index b21b3c2dc77f2bb12f617f198a928a58cc17b592..b22d2dfcd3c29ec85c474948f67d0805571db3ab 100644 (file)
@@ -2660,7 +2660,7 @@ static int vfe_get_selection(struct v4l2_subdev *sd,
  *
  * Return -EINVAL or zero on success
  */
-int vfe_set_selection(struct v4l2_subdev *sd,
+static int vfe_set_selection(struct v4l2_subdev *sd,
                             struct v4l2_subdev_pad_config *cfg,
                             struct v4l2_subdev_selection *sel)
 {
index 68933d20806338629a89bdde9a5b05219ef2f5ac..9b2a401a4891c49e1388783cbf4111bf6df26af6 100644 (file)
@@ -682,6 +682,7 @@ void venus_helper_vb2_stop_streaming(struct vb2_queue *q)
                        hfi_session_abort(inst);
 
                load_scale_clocks(core);
+               INIT_LIST_HEAD(&inst->registeredbufs);
        }
 
        venus_helper_buffers_done(inst, VB2_BUF_STATE_ERROR);
index 1edf667d562a4df64a4806e947f192aa2a24357f..146ae6f25cdbb1eee53837aa1ea28c503163ed28 100644 (file)
@@ -172,7 +172,8 @@ u32 s5p_cec_get_status(struct s5p_cec_dev *cec)
 {
        u32 status = 0;
 
-       status = readb(cec->reg + S5P_CEC_STATUS_0);
+       status = readb(cec->reg + S5P_CEC_STATUS_0) & 0xf;
+       status |= (readb(cec->reg + S5P_CEC_TX_STAT1) & 0xf) << 4;
        status |= readb(cec->reg + S5P_CEC_STATUS_1) << 8;
        status |= readb(cec->reg + S5P_CEC_STATUS_2) << 16;
        status |= readb(cec->reg + S5P_CEC_STATUS_3) << 24;
index 58d200e7c8382de8edc841b17b1022a2c15ddb85..8837e2678bdeb3507e4ebce501e5ee58216334ad 100644 (file)
@@ -92,7 +92,10 @@ static irqreturn_t s5p_cec_irq_handler(int irq, void *priv)
        dev_dbg(cec->dev, "irq received\n");
 
        if (status & CEC_STATUS_TX_DONE) {
-               if (status & CEC_STATUS_TX_ERROR) {
+               if (status & CEC_STATUS_TX_NACK) {
+                       dev_dbg(cec->dev, "CEC_STATUS_TX_NACK set\n");
+                       cec->tx = STATE_NACK;
+               } else if (status & CEC_STATUS_TX_ERROR) {
                        dev_dbg(cec->dev, "CEC_STATUS_TX_ERROR set\n");
                        cec->tx = STATE_ERROR;
                } else {
@@ -135,6 +138,12 @@ static irqreturn_t s5p_cec_irq_handler_thread(int irq, void *priv)
                cec_transmit_done(cec->adap, CEC_TX_STATUS_OK, 0, 0, 0, 0);
                cec->tx = STATE_IDLE;
                break;
+       case STATE_NACK:
+               cec_transmit_done(cec->adap,
+                       CEC_TX_STATUS_MAX_RETRIES | CEC_TX_STATUS_NACK,
+                       0, 1, 0, 0);
+               cec->tx = STATE_IDLE;
+               break;
        case STATE_ERROR:
                cec_transmit_done(cec->adap,
                        CEC_TX_STATUS_MAX_RETRIES | CEC_TX_STATUS_ERROR,
index 8bcd8dc1aeb9fb299d5b821511c9b1eba02d3c6a..86ded522ef27319a27fb72bd9f5285be6ac1ad8f 100644 (file)
@@ -35,6 +35,7 @@
 #define CEC_STATUS_TX_TRANSFERRING     (1 << 1)
 #define CEC_STATUS_TX_DONE             (1 << 2)
 #define CEC_STATUS_TX_ERROR            (1 << 3)
+#define CEC_STATUS_TX_NACK             (1 << 4)
 #define CEC_STATUS_TX_BYTES            (0xFF << 8)
 #define CEC_STATUS_RX_RUNNING          (1 << 16)
 #define CEC_STATUS_RX_RECEIVING                (1 << 17)
@@ -55,6 +56,7 @@ enum cec_state {
        STATE_IDLE,
        STATE_BUSY,
        STATE_DONE,
+       STATE_NACK,
        STATE_ERROR
 };
 
index 2e487f9a2cc3fb678aa173b93a9bb141cc23ba69..4983eeb39f369c961cfdf86b69a870d98727e736 100644 (file)
@@ -38,41 +38,74 @@ MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off).");
 static int mt2060_readreg(struct mt2060_priv *priv, u8 reg, u8 *val)
 {
        struct i2c_msg msg[2] = {
-               { .addr = priv->cfg->i2c_address, .flags = 0,        .buf = &reg, .len = 1 },
-               { .addr = priv->cfg->i2c_address, .flags = I2C_M_RD, .buf = val,  .len = 1 },
+               { .addr = priv->cfg->i2c_address, .flags = 0, .len = 1 },
+               { .addr = priv->cfg->i2c_address, .flags = I2C_M_RD, .len = 1 },
        };
+       int rc = 0;
+       u8 *b;
+
+       b = kmalloc(2, GFP_KERNEL);
+       if (!b)
+               return -ENOMEM;
+
+       b[0] = reg;
+       b[1] = 0;
+
+       msg[0].buf = b;
+       msg[1].buf = b + 1;
 
        if (i2c_transfer(priv->i2c, msg, 2) != 2) {
                printk(KERN_WARNING "mt2060 I2C read failed\n");
-               return -EREMOTEIO;
+               rc = -EREMOTEIO;
        }
-       return 0;
+       *val = b[1];
+       kfree(b);
+
+       return rc;
 }
 
 // Writes a single register
 static int mt2060_writereg(struct mt2060_priv *priv, u8 reg, u8 val)
 {
-       u8 buf[2] = { reg, val };
        struct i2c_msg msg = {
-               .addr = priv->cfg->i2c_address, .flags = 0, .buf = buf, .len = 2
+               .addr = priv->cfg->i2c_address, .flags = 0, .len = 2
        };
+       u8 *buf;
+       int rc = 0;
+
+       buf = kmalloc(2, GFP_KERNEL);
+       if (!buf)
+               return -ENOMEM;
+
+       buf[0] = reg;
+       buf[1] = val;
+
+       msg.buf = buf;
 
        if (i2c_transfer(priv->i2c, &msg, 1) != 1) {
                printk(KERN_WARNING "mt2060 I2C write failed\n");
-               return -EREMOTEIO;
+               rc = -EREMOTEIO;
        }
-       return 0;
+       kfree(buf);
+       return rc;
 }
 
 // Writes a set of consecutive registers
 static int mt2060_writeregs(struct mt2060_priv *priv,u8 *buf, u8 len)
 {
        int rem, val_len;
-       u8 xfer_buf[16];
+       u8 *xfer_buf;
+       int rc = 0;
        struct i2c_msg msg = {
-               .addr = priv->cfg->i2c_address, .flags = 0, .buf = xfer_buf
+               .addr = priv->cfg->i2c_address, .flags = 0
        };
 
+       xfer_buf = kmalloc(16, GFP_KERNEL);
+       if (!xfer_buf)
+               return -ENOMEM;
+
+       msg.buf = xfer_buf;
+
        for (rem = len - 1; rem > 0; rem -= priv->i2c_max_regs) {
                val_len = min_t(int, rem, priv->i2c_max_regs);
                msg.len = 1 + val_len;
@@ -81,11 +114,13 @@ static int mt2060_writeregs(struct mt2060_priv *priv,u8 *buf, u8 len)
 
                if (i2c_transfer(priv->i2c, &msg, 1) != 1) {
                        printk(KERN_WARNING "mt2060 I2C write failed (len=%i)\n", val_len);
-                       return -EREMOTEIO;
+                       rc = -EREMOTEIO;
+                       break;
                }
        }
 
-       return 0;
+       kfree(xfer_buf);
+       return rc;
 }
 
 // Initialisation sequences
index d0ccc6729fd29e734996b28538cd6e8e1745bf2b..67d787fa330651738ce8c2bf4e58fd8eebcf6e2a 100644 (file)
@@ -448,6 +448,8 @@ static void intel_dsm_init(struct intel_host *intel_host, struct device *dev,
        int err;
        u32 val;
 
+       intel_host->d3_retune = true;
+
        err = __intel_dsm(intel_host, dev, INTEL_DSM_FNS, &intel_host->dsm_fns);
        if (err) {
                pr_debug("%s: DSM not supported, error %d\n",
index 13f0f219d8aa83ab0ce52823f6ddb697d58c316b..a13a4896a8bddad19ae48f8c58bbaf2f3c8dce84 100644 (file)
 /* FLEXCAN hardware feature flags
  *
  * Below is some version info we got:
- *    SOC   Version   IP-Version  Glitch- [TR]WRN_INT Memory err RTR re-
- *                                Filter? connected?  detection  ception in MB
- *   MX25  FlexCAN2  03.00.00.00     no        no         no        no
- *   MX28  FlexCAN2  03.00.04.00    yes       yes         no        no
- *   MX35  FlexCAN2  03.00.00.00     no        no         no        no
- *   MX53  FlexCAN2  03.00.00.00    yes        no         no        no
- *   MX6s  FlexCAN3  10.00.12.00    yes       yes         no       yes
- *   VF610 FlexCAN3  ?               no       yes        yes       yes?
+ *    SOC   Version   IP-Version  Glitch- [TR]WRN_INT IRQ Err Memory err RTR re-
+ *                                Filter? connected?  Passive detection  ception in MB
+ *   MX25  FlexCAN2  03.00.00.00     no        no         ?       no        no
+ *   MX28  FlexCAN2  03.00.04.00    yes       yes        no       no        no
+ *   MX35  FlexCAN2  03.00.00.00     no        no         ?       no        no
+ *   MX53  FlexCAN2  03.00.00.00    yes        no        no       no        no
+ *   MX6s  FlexCAN3  10.00.12.00    yes       yes        no       no       yes
+ *   VF610 FlexCAN3  ?               no       yes         ?      yes       yes?
  *
  * Some SOCs do not have the RX_WARN & TX_WARN interrupt line connected.
  */
-#define FLEXCAN_QUIRK_BROKEN_ERR_STATE BIT(1) /* [TR]WRN_INT not connected */
+#define FLEXCAN_QUIRK_BROKEN_WERR_STATE        BIT(1) /* [TR]WRN_INT not connected */
 #define FLEXCAN_QUIRK_DISABLE_RXFG     BIT(2) /* Disable RX FIFO Global mask */
 #define FLEXCAN_QUIRK_ENABLE_EACEN_RRS BIT(3) /* Enable EACEN and RRS bit in ctrl2 */
 #define FLEXCAN_QUIRK_DISABLE_MECR     BIT(4) /* Disable Memory error detection */
 #define FLEXCAN_QUIRK_USE_OFF_TIMESTAMP        BIT(5) /* Use timestamp based offloading */
+#define FLEXCAN_QUIRK_BROKEN_PERR_STATE        BIT(6) /* No interrupt for error passive */
 
 /* Structure of the message buffer */
 struct flexcan_mb {
@@ -281,14 +282,17 @@ struct flexcan_priv {
 };
 
 static const struct flexcan_devtype_data fsl_p1010_devtype_data = {
-       .quirks = FLEXCAN_QUIRK_BROKEN_ERR_STATE,
+       .quirks = FLEXCAN_QUIRK_BROKEN_WERR_STATE |
+               FLEXCAN_QUIRK_BROKEN_PERR_STATE,
 };
 
-static const struct flexcan_devtype_data fsl_imx28_devtype_data;
+static const struct flexcan_devtype_data fsl_imx28_devtype_data = {
+       .quirks = FLEXCAN_QUIRK_BROKEN_PERR_STATE,
+};
 
 static const struct flexcan_devtype_data fsl_imx6q_devtype_data = {
        .quirks = FLEXCAN_QUIRK_DISABLE_RXFG | FLEXCAN_QUIRK_ENABLE_EACEN_RRS |
-               FLEXCAN_QUIRK_USE_OFF_TIMESTAMP,
+               FLEXCAN_QUIRK_USE_OFF_TIMESTAMP | FLEXCAN_QUIRK_BROKEN_PERR_STATE,
 };
 
 static const struct flexcan_devtype_data fsl_vf610_devtype_data = {
@@ -335,6 +339,22 @@ static inline void flexcan_write(u32 val, void __iomem *addr)
 }
 #endif
 
+static inline void flexcan_error_irq_enable(const struct flexcan_priv *priv)
+{
+       struct flexcan_regs __iomem *regs = priv->regs;
+       u32 reg_ctrl = (priv->reg_ctrl_default | FLEXCAN_CTRL_ERR_MSK);
+
+       flexcan_write(reg_ctrl, &regs->ctrl);
+}
+
+static inline void flexcan_error_irq_disable(const struct flexcan_priv *priv)
+{
+       struct flexcan_regs __iomem *regs = priv->regs;
+       u32 reg_ctrl = (priv->reg_ctrl_default & ~FLEXCAN_CTRL_ERR_MSK);
+
+       flexcan_write(reg_ctrl, &regs->ctrl);
+}
+
 static inline int flexcan_transceiver_enable(const struct flexcan_priv *priv)
 {
        if (!priv->reg_xceiver)
@@ -713,6 +733,7 @@ static irqreturn_t flexcan_irq(int irq, void *dev_id)
        struct flexcan_regs __iomem *regs = priv->regs;
        irqreturn_t handled = IRQ_NONE;
        u32 reg_iflag1, reg_esr;
+       enum can_state last_state = priv->can.state;
 
        reg_iflag1 = flexcan_read(&regs->iflag1);
 
@@ -765,8 +786,10 @@ static irqreturn_t flexcan_irq(int irq, void *dev_id)
                flexcan_write(reg_esr & FLEXCAN_ESR_ALL_INT, &regs->esr);
        }
 
-       /* state change interrupt */
-       if (reg_esr & FLEXCAN_ESR_ERR_STATE)
+       /* state change interrupt or broken error state quirk fix is enabled */
+       if ((reg_esr & FLEXCAN_ESR_ERR_STATE) ||
+           (priv->devtype_data->quirks & (FLEXCAN_QUIRK_BROKEN_WERR_STATE |
+                                          FLEXCAN_QUIRK_BROKEN_PERR_STATE)))
                flexcan_irq_state(dev, reg_esr);
 
        /* bus error IRQ - handle if bus error reporting is activated */
@@ -774,6 +797,44 @@ static irqreturn_t flexcan_irq(int irq, void *dev_id)
            (priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING))
                flexcan_irq_bus_err(dev, reg_esr);
 
+       /* availability of error interrupt among state transitions in case
+        * bus error reporting is de-activated and
+        * FLEXCAN_QUIRK_BROKEN_PERR_STATE is enabled:
+        *  +--------------------------------------------------------------+
+        *  | +----------------------------------------------+ [stopped /  |
+        *  | |                                              |  sleeping] -+
+        *  +-+-> active <-> warning <-> passive -> bus off -+
+        *        ___________^^^^^^^^^^^^_______________________________
+        *        disabled(1)  enabled             disabled
+        *
+        * (1): enabled if FLEXCAN_QUIRK_BROKEN_WERR_STATE is enabled
+        */
+       if ((last_state != priv->can.state) &&
+           (priv->devtype_data->quirks & FLEXCAN_QUIRK_BROKEN_PERR_STATE) &&
+           !(priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING)) {
+               switch (priv->can.state) {
+               case CAN_STATE_ERROR_ACTIVE:
+                       if (priv->devtype_data->quirks &
+                           FLEXCAN_QUIRK_BROKEN_WERR_STATE)
+                               flexcan_error_irq_enable(priv);
+                       else
+                               flexcan_error_irq_disable(priv);
+                       break;
+
+               case CAN_STATE_ERROR_WARNING:
+                       flexcan_error_irq_enable(priv);
+                       break;
+
+               case CAN_STATE_ERROR_PASSIVE:
+               case CAN_STATE_BUS_OFF:
+                       flexcan_error_irq_disable(priv);
+                       break;
+
+               default:
+                       break;
+               }
+       }
+
        return handled;
 }
 
@@ -887,7 +948,7 @@ static int flexcan_chip_start(struct net_device *dev)
         * on most Flexcan cores, too. Otherwise we don't get
         * any error warning or passive interrupts.
         */
-       if (priv->devtype_data->quirks & FLEXCAN_QUIRK_BROKEN_ERR_STATE ||
+       if (priv->devtype_data->quirks & FLEXCAN_QUIRK_BROKEN_WERR_STATE ||
            priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING)
                reg_ctrl |= FLEXCAN_CTRL_ERR_MSK;
        else
index be928ce62d32e01c9d6ad9ac1fbcb46916f492ec..9fdb0f0bfa06a00a2ade5e74daef15798ab7d4a1 100644 (file)
@@ -333,7 +333,7 @@ static void esd_usb2_rx_can_msg(struct esd_usb2_net_priv *priv,
                }
 
                cf->can_id = id & ESD_IDMASK;
-               cf->can_dlc = get_can_dlc(msg->msg.rx.dlc);
+               cf->can_dlc = get_can_dlc(msg->msg.rx.dlc & ~ESD_RTR);
 
                if (id & ESD_EXTID)
                        cf->can_id |= CAN_EFF_FLAG;
index afcc1312dbaf8f67bce640e17dbc20c06592dc45..68ac3e88a8cecbe5b4a58da8491756ad5c26039a 100644 (file)
@@ -375,6 +375,8 @@ static void gs_usb_receive_bulk_callback(struct urb *urb)
 
                gs_free_tx_context(txc);
 
+               atomic_dec(&dev->active_tx_urbs);
+
                netif_wake_queue(netdev);
        }
 
@@ -463,14 +465,6 @@ static void gs_usb_xmit_callback(struct urb *urb)
                          urb->transfer_buffer_length,
                          urb->transfer_buffer,
                          urb->transfer_dma);
-
-       atomic_dec(&dev->active_tx_urbs);
-
-       if (!netif_device_present(netdev))
-               return;
-
-       if (netif_queue_stopped(netdev))
-               netif_wake_queue(netdev);
 }
 
 static netdev_tx_t gs_can_start_xmit(struct sk_buff *skb,
index dce7fa57eb553a477faadd3f15d6f0e1dcf394af..f123ed57630d59815156c46b750d987bb0171966 100644 (file)
@@ -214,8 +214,14 @@ static int mv88e6060_setup(struct dsa_switch *ds)
 
 static int mv88e6060_set_addr(struct dsa_switch *ds, u8 *addr)
 {
-       /* Use the same MAC Address as FD Pause frames for all ports */
-       REG_WRITE(REG_GLOBAL, GLOBAL_MAC_01, (addr[0] << 9) | addr[1]);
+       u16 val = addr[0] << 8 | addr[1];
+
+       /* The multicast bit is always transmitted as a zero, so the switch uses
+        * bit 8 for "DiffAddr", where 0 means all ports transmit the same SA.
+        */
+       val &= 0xfeff;
+
+       REG_WRITE(REG_GLOBAL, GLOBAL_MAC_01, val);
        REG_WRITE(REG_GLOBAL, GLOBAL_MAC_23, (addr[2] << 8) | addr[3]);
        REG_WRITE(REG_GLOBAL, GLOBAL_MAC_45, (addr[4] << 8) | addr[5]);
 
index b1212debc2e1c993f662ee35dcbbf6b5e5e3ac54..967020fb26ee17a6995a7ae11df668e8ab4fe9f0 100644 (file)
@@ -742,8 +742,8 @@ static void ena_get_channels(struct net_device *netdev,
 {
        struct ena_adapter *adapter = netdev_priv(netdev);
 
-       channels->max_rx = ENA_MAX_NUM_IO_QUEUES;
-       channels->max_tx = ENA_MAX_NUM_IO_QUEUES;
+       channels->max_rx = adapter->num_queues;
+       channels->max_tx = adapter->num_queues;
        channels->max_other = 0;
        channels->max_combined = 0;
        channels->rx_count = adapter->num_queues;
index f7dc22f65d9f64ac50cd641d30e4d83f88fe5bba..c6bd5e24005d02a6c7098cdaf492e5152eac2c08 100644 (file)
@@ -966,7 +966,7 @@ static inline void ena_rx_checksum(struct ena_ring *rx_ring,
                u64_stats_update_begin(&rx_ring->syncp);
                rx_ring->rx_stats.bad_csum++;
                u64_stats_update_end(&rx_ring->syncp);
-               netif_err(rx_ring->adapter, rx_err, rx_ring->netdev,
+               netif_dbg(rx_ring->adapter, rx_err, rx_ring->netdev,
                          "RX IPv4 header checksum error\n");
                return;
        }
@@ -979,7 +979,7 @@ static inline void ena_rx_checksum(struct ena_ring *rx_ring,
                        u64_stats_update_begin(&rx_ring->syncp);
                        rx_ring->rx_stats.bad_csum++;
                        u64_stats_update_end(&rx_ring->syncp);
-                       netif_err(rx_ring->adapter, rx_err, rx_ring->netdev,
+                       netif_dbg(rx_ring->adapter, rx_err, rx_ring->netdev,
                                  "RX L4 checksum error\n");
                        skb->ip_summed = CHECKSUM_NONE;
                        return;
@@ -3064,7 +3064,8 @@ static void ena_release_bars(struct ena_com_dev *ena_dev, struct pci_dev *pdev)
        if (ena_dev->mem_bar)
                devm_iounmap(&pdev->dev, ena_dev->mem_bar);
 
-       devm_iounmap(&pdev->dev, ena_dev->reg_bar);
+       if (ena_dev->reg_bar)
+               devm_iounmap(&pdev->dev, ena_dev->reg_bar);
 
        release_bars = pci_select_bars(pdev, IORESOURCE_MEM) & ENA_BAR_MASK;
        pci_release_selected_regions(pdev, release_bars);
index 0fdaaa643073afabda6d66c9ebe0ef9e3b7695ae..57e796870595bb9a305a7579154b0dbd1cbeec60 100644 (file)
 
 #define AQ_CFG_FORCE_LEGACY_INT 0U
 
-#define AQ_CFG_IS_INTERRUPT_MODERATION_DEF   1U
-#define AQ_CFG_INTERRUPT_MODERATION_RATE_DEF 0xFFFFU
+#define AQ_CFG_INTERRUPT_MODERATION_OFF                0
+#define AQ_CFG_INTERRUPT_MODERATION_ON         1
+#define AQ_CFG_INTERRUPT_MODERATION_AUTO       0xFFFFU
+
+#define AQ_CFG_INTERRUPT_MODERATION_USEC_MAX (0x1FF * 2)
+
 #define AQ_CFG_IRQ_MASK                      0x1FFU
 
 #define AQ_CFG_VECS_MAX   8U
index a761e91471dfd264f3aba944e5324f86d4cd9e12..d5e99b46887061a216652ca150897bba49f16223 100644 (file)
@@ -56,10 +56,6 @@ aq_ethtool_set_link_ksettings(struct net_device *ndev,
        return aq_nic_set_link_ksettings(aq_nic, cmd);
 }
 
-/* there "5U" is number of queue[#] stats lines (InPackets+...+InErrors) */
-static const unsigned int aq_ethtool_stat_queue_lines = 5U;
-static const unsigned int aq_ethtool_stat_queue_chars =
-       5U * ETH_GSTRING_LEN;
 static const char aq_ethtool_stat_names[][ETH_GSTRING_LEN] = {
        "InPackets",
        "InUCast",
@@ -83,56 +79,26 @@ static const char aq_ethtool_stat_names[][ETH_GSTRING_LEN] = {
        "InOctetsDma",
        "OutOctetsDma",
        "InDroppedDma",
-       "Queue[0] InPackets",
-       "Queue[0] OutPackets",
-       "Queue[0] InJumboPackets",
-       "Queue[0] InLroPackets",
-       "Queue[0] InErrors",
-       "Queue[1] InPackets",
-       "Queue[1] OutPackets",
-       "Queue[1] InJumboPackets",
-       "Queue[1] InLroPackets",
-       "Queue[1] InErrors",
-       "Queue[2] InPackets",
-       "Queue[2] OutPackets",
-       "Queue[2] InJumboPackets",
-       "Queue[2] InLroPackets",
-       "Queue[2] InErrors",
-       "Queue[3] InPackets",
-       "Queue[3] OutPackets",
-       "Queue[3] InJumboPackets",
-       "Queue[3] InLroPackets",
-       "Queue[3] InErrors",
-       "Queue[4] InPackets",
-       "Queue[4] OutPackets",
-       "Queue[4] InJumboPackets",
-       "Queue[4] InLroPackets",
-       "Queue[4] InErrors",
-       "Queue[5] InPackets",
-       "Queue[5] OutPackets",
-       "Queue[5] InJumboPackets",
-       "Queue[5] InLroPackets",
-       "Queue[5] InErrors",
-       "Queue[6] InPackets",
-       "Queue[6] OutPackets",
-       "Queue[6] InJumboPackets",
-       "Queue[6] InLroPackets",
-       "Queue[6] InErrors",
-       "Queue[7] InPackets",
-       "Queue[7] OutPackets",
-       "Queue[7] InJumboPackets",
-       "Queue[7] InLroPackets",
-       "Queue[7] InErrors",
+};
+
+static const char aq_ethtool_queue_stat_names[][ETH_GSTRING_LEN] = {
+       "Queue[%d] InPackets",
+       "Queue[%d] OutPackets",
+       "Queue[%d] Restarts",
+       "Queue[%d] InJumboPackets",
+       "Queue[%d] InLroPackets",
+       "Queue[%d] InErrors",
 };
 
 static void aq_ethtool_stats(struct net_device *ndev,
                             struct ethtool_stats *stats, u64 *data)
 {
        struct aq_nic_s *aq_nic = netdev_priv(ndev);
+       struct aq_nic_cfg_s *cfg = aq_nic_get_cfg(aq_nic);
 
-/* ASSERT: Need add lines to aq_ethtool_stat_names if AQ_CFG_VECS_MAX > 8 */
-       BUILD_BUG_ON(AQ_CFG_VECS_MAX > 8);
-       memset(data, 0, ARRAY_SIZE(aq_ethtool_stat_names) * sizeof(u64));
+       memset(data, 0, (ARRAY_SIZE(aq_ethtool_stat_names) +
+                               ARRAY_SIZE(aq_ethtool_queue_stat_names) *
+                               cfg->vecs) * sizeof(u64));
        aq_nic_get_stats(aq_nic, data);
 }
 
@@ -154,8 +120,8 @@ static void aq_ethtool_get_drvinfo(struct net_device *ndev,
 
        strlcpy(drvinfo->bus_info, pdev ? pci_name(pdev) : "",
                sizeof(drvinfo->bus_info));
-       drvinfo->n_stats = ARRAY_SIZE(aq_ethtool_stat_names) -
-               (AQ_CFG_VECS_MAX - cfg->vecs) * aq_ethtool_stat_queue_lines;
+       drvinfo->n_stats = ARRAY_SIZE(aq_ethtool_stat_names) +
+               cfg->vecs * ARRAY_SIZE(aq_ethtool_queue_stat_names);
        drvinfo->testinfo_len = 0;
        drvinfo->regdump_len = regs_count;
        drvinfo->eedump_len = 0;
@@ -164,14 +130,25 @@ static void aq_ethtool_get_drvinfo(struct net_device *ndev,
 static void aq_ethtool_get_strings(struct net_device *ndev,
                                   u32 stringset, u8 *data)
 {
+       int i, si;
        struct aq_nic_s *aq_nic = netdev_priv(ndev);
        struct aq_nic_cfg_s *cfg = aq_nic_get_cfg(aq_nic);
-
-       if (stringset == ETH_SS_STATS)
-               memcpy(data, *aq_ethtool_stat_names,
-                      sizeof(aq_ethtool_stat_names) -
-                      (AQ_CFG_VECS_MAX - cfg->vecs) *
-                      aq_ethtool_stat_queue_chars);
+       u8 *p = data;
+
+       if (stringset == ETH_SS_STATS) {
+               memcpy(p, *aq_ethtool_stat_names,
+                      sizeof(aq_ethtool_stat_names));
+               p = p + sizeof(aq_ethtool_stat_names);
+               for (i = 0; i < cfg->vecs; i++) {
+                       for (si = 0;
+                               si < ARRAY_SIZE(aq_ethtool_queue_stat_names);
+                               si++) {
+                               snprintf(p, ETH_GSTRING_LEN,
+                                        aq_ethtool_queue_stat_names[si], i);
+                               p += ETH_GSTRING_LEN;
+                       }
+               }
+       }
 }
 
 static int aq_ethtool_get_sset_count(struct net_device *ndev, int stringset)
@@ -182,9 +159,8 @@ static int aq_ethtool_get_sset_count(struct net_device *ndev, int stringset)
 
        switch (stringset) {
        case ETH_SS_STATS:
-               ret = ARRAY_SIZE(aq_ethtool_stat_names) -
-                       (AQ_CFG_VECS_MAX - cfg->vecs) *
-                       aq_ethtool_stat_queue_lines;
+               ret = ARRAY_SIZE(aq_ethtool_stat_names) +
+                       cfg->vecs * ARRAY_SIZE(aq_ethtool_queue_stat_names);
                break;
        default:
                ret = -EOPNOTSUPP;
@@ -245,6 +221,69 @@ static int aq_ethtool_get_rxnfc(struct net_device *ndev,
        return err;
 }
 
+int aq_ethtool_get_coalesce(struct net_device *ndev,
+                           struct ethtool_coalesce *coal)
+{
+       struct aq_nic_s *aq_nic = netdev_priv(ndev);
+       struct aq_nic_cfg_s *cfg = aq_nic_get_cfg(aq_nic);
+
+       if (cfg->itr == AQ_CFG_INTERRUPT_MODERATION_ON ||
+           cfg->itr == AQ_CFG_INTERRUPT_MODERATION_AUTO) {
+               coal->rx_coalesce_usecs = cfg->rx_itr;
+               coal->tx_coalesce_usecs = cfg->tx_itr;
+               coal->rx_max_coalesced_frames = 0;
+               coal->tx_max_coalesced_frames = 0;
+       } else {
+               coal->rx_coalesce_usecs = 0;
+               coal->tx_coalesce_usecs = 0;
+               coal->rx_max_coalesced_frames = 1;
+               coal->tx_max_coalesced_frames = 1;
+       }
+       return 0;
+}
+
+int aq_ethtool_set_coalesce(struct net_device *ndev,
+                           struct ethtool_coalesce *coal)
+{
+       struct aq_nic_s *aq_nic = netdev_priv(ndev);
+       struct aq_nic_cfg_s *cfg = aq_nic_get_cfg(aq_nic);
+
+       /* This is not yet supported
+        */
+       if (coal->use_adaptive_rx_coalesce || coal->use_adaptive_tx_coalesce)
+               return -EOPNOTSUPP;
+
+       /* Atlantic only supports timing based coalescing
+        */
+       if (coal->rx_max_coalesced_frames > 1 ||
+           coal->rx_coalesce_usecs_irq ||
+           coal->rx_max_coalesced_frames_irq)
+               return -EOPNOTSUPP;
+
+       if (coal->tx_max_coalesced_frames > 1 ||
+           coal->tx_coalesce_usecs_irq ||
+           coal->tx_max_coalesced_frames_irq)
+               return -EOPNOTSUPP;
+
+       /* We do not support frame counting. Check this
+        */
+       if (!(coal->rx_max_coalesced_frames == !coal->rx_coalesce_usecs))
+               return -EOPNOTSUPP;
+       if (!(coal->tx_max_coalesced_frames == !coal->tx_coalesce_usecs))
+               return -EOPNOTSUPP;
+
+       if (coal->rx_coalesce_usecs > AQ_CFG_INTERRUPT_MODERATION_USEC_MAX ||
+           coal->tx_coalesce_usecs > AQ_CFG_INTERRUPT_MODERATION_USEC_MAX)
+               return -EINVAL;
+
+       cfg->itr = AQ_CFG_INTERRUPT_MODERATION_ON;
+
+       cfg->rx_itr = coal->rx_coalesce_usecs;
+       cfg->tx_itr = coal->tx_coalesce_usecs;
+
+       return aq_nic_update_interrupt_moderation_settings(aq_nic);
+}
+
 const struct ethtool_ops aq_ethtool_ops = {
        .get_link            = aq_ethtool_get_link,
        .get_regs_len        = aq_ethtool_get_regs_len,
@@ -259,4 +298,6 @@ const struct ethtool_ops aq_ethtool_ops = {
        .get_ethtool_stats   = aq_ethtool_stats,
        .get_link_ksettings  = aq_ethtool_get_link_ksettings,
        .set_link_ksettings  = aq_ethtool_set_link_ksettings,
+       .get_coalesce        = aq_ethtool_get_coalesce,
+       .set_coalesce        = aq_ethtool_set_coalesce,
 };
index bf9b3f020e106cb07fd7630073f146d7f54ccfa9..0207927dc8a6ab4ac76c46fb17669b7e50e7ae1e 100644 (file)
@@ -151,8 +151,7 @@ struct aq_hw_ops {
                                     [ETH_ALEN],
                                     u32 count);
 
-       int (*hw_interrupt_moderation_set)(struct aq_hw_s *self,
-                                          bool itr_enabled);
+       int (*hw_interrupt_moderation_set)(struct aq_hw_s *self);
 
        int (*hw_rss_set)(struct aq_hw_s *self,
                          struct aq_rss_parameters *rss_params);
@@ -163,6 +162,8 @@ struct aq_hw_ops {
        int (*hw_get_regs)(struct aq_hw_s *self,
                           struct aq_hw_caps_s *aq_hw_caps, u32 *regs_buff);
 
+       int (*hw_update_stats)(struct aq_hw_s *self);
+
        int (*hw_get_hw_stats)(struct aq_hw_s *self, u64 *data,
                               unsigned int *p_count);
 
index 0a5bb4114eb4ca7529bc7a8164d3d12ffa4e78c8..483e97691eeae2de4604e49cdb8fd8d60fb0dda4 100644 (file)
@@ -16,6 +16,7 @@
 #include "aq_pci_func.h"
 #include "aq_nic_internal.h"
 
+#include <linux/moduleparam.h>
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/timer.h>
 #include <linux/tcp.h>
 #include <net/ip.h>
 
+static unsigned int aq_itr = AQ_CFG_INTERRUPT_MODERATION_AUTO;
+module_param_named(aq_itr, aq_itr, uint, 0644);
+MODULE_PARM_DESC(aq_itr, "Interrupt throttling mode");
+
+static unsigned int aq_itr_tx;
+module_param_named(aq_itr_tx, aq_itr_tx, uint, 0644);
+MODULE_PARM_DESC(aq_itr_tx, "TX interrupt throttle rate");
+
+static unsigned int aq_itr_rx;
+module_param_named(aq_itr_rx, aq_itr_rx, uint, 0644);
+MODULE_PARM_DESC(aq_itr_rx, "RX interrupt throttle rate");
+
 static void aq_nic_rss_init(struct aq_nic_s *self, unsigned int num_rss_queues)
 {
        struct aq_nic_cfg_s *cfg = &self->aq_nic_cfg;
@@ -61,9 +74,9 @@ static void aq_nic_cfg_init_defaults(struct aq_nic_s *self)
 
        cfg->is_polling = AQ_CFG_IS_POLLING_DEF;
 
-       cfg->is_interrupt_moderation = AQ_CFG_IS_INTERRUPT_MODERATION_DEF;
-       cfg->itr = cfg->is_interrupt_moderation ?
-               AQ_CFG_INTERRUPT_MODERATION_RATE_DEF : 0U;
+       cfg->itr = aq_itr;
+       cfg->tx_itr = aq_itr_tx;
+       cfg->rx_itr = aq_itr_rx;
 
        cfg->is_rss = AQ_CFG_IS_RSS_DEF;
        cfg->num_rss_queues = AQ_CFG_NUM_RSS_QUEUES_DEF;
@@ -126,10 +139,12 @@ static int aq_nic_update_link_status(struct aq_nic_s *self)
        if (err)
                return err;
 
-       if (self->link_status.mbps != self->aq_hw->aq_link_status.mbps)
+       if (self->link_status.mbps != self->aq_hw->aq_link_status.mbps) {
                pr_info("%s: link change old %d new %d\n",
                        AQ_CFG_DRV_NAME, self->link_status.mbps,
                        self->aq_hw->aq_link_status.mbps);
+               aq_nic_update_interrupt_moderation_settings(self);
+       }
 
        self->link_status = self->aq_hw->aq_link_status;
        if (!netif_carrier_ok(self->ndev) && self->link_status.mbps) {
@@ -164,8 +179,8 @@ static void aq_nic_service_timer_cb(unsigned long param)
        if (err)
                goto err_exit;
 
-       self->aq_hw_ops.hw_interrupt_moderation_set(self->aq_hw,
-                   self->aq_nic_cfg.is_interrupt_moderation);
+       if (self->aq_hw_ops.hw_update_stats)
+               self->aq_hw_ops.hw_update_stats(self->aq_hw);
 
        memset(&stats_rx, 0U, sizeof(struct aq_ring_stats_rx_s));
        memset(&stats_tx, 0U, sizeof(struct aq_ring_stats_tx_s));
@@ -334,6 +349,7 @@ struct aq_nic_s *aq_nic_alloc_hot(struct net_device *ndev)
        }
        if (netif_running(ndev))
                netif_tx_disable(ndev);
+       netif_carrier_off(self->ndev);
 
        for (self->aq_vecs = 0; self->aq_vecs < self->aq_nic_cfg.vecs;
                self->aq_vecs++) {
@@ -421,9 +437,8 @@ int aq_nic_start(struct aq_nic_s *self)
        if (err < 0)
                goto err_exit;
 
-       err = self->aq_hw_ops.hw_interrupt_moderation_set(self->aq_hw,
-                           self->aq_nic_cfg.is_interrupt_moderation);
-       if (err < 0)
+       err = aq_nic_update_interrupt_moderation_settings(self);
+       if (err)
                goto err_exit;
        setup_timer(&self->service_timer, &aq_nic_service_timer_cb,
                    (unsigned long)self);
@@ -645,6 +660,11 @@ err_exit:
        return err;
 }
 
+int aq_nic_update_interrupt_moderation_settings(struct aq_nic_s *self)
+{
+       return self->aq_hw_ops.hw_interrupt_moderation_set(self->aq_hw);
+}
+
 int aq_nic_set_packet_filter(struct aq_nic_s *self, unsigned int flags)
 {
        int err = 0;
@@ -899,6 +919,7 @@ int aq_nic_stop(struct aq_nic_s *self)
        unsigned int i = 0U;
 
        netif_tx_disable(self->ndev);
+       netif_carrier_off(self->ndev);
 
        del_timer_sync(&self->service_timer);
 
index 0ddd556ff901c25682739a059673fa3a8398aed3..4309983acdd6f7502fa05869f79336fd459dc2fe 100644 (file)
@@ -40,6 +40,8 @@ struct aq_nic_cfg_s {
        u32 vecs;               /* vecs==allocated irqs */
        u32 irq_type;
        u32 itr;
+       u16 rx_itr;
+       u16 tx_itr;
        u32 num_rss_queues;
        u32 mtu;
        u32 ucp_0x364;
@@ -49,7 +51,6 @@ struct aq_nic_cfg_s {
        u16 is_mc_list_enabled;
        u16 mc_list_count;
        bool is_autoneg;
-       bool is_interrupt_moderation;
        bool is_polling;
        bool is_rss;
        bool is_lro;
@@ -104,5 +105,6 @@ int aq_nic_set_link_ksettings(struct aq_nic_s *self,
 struct aq_nic_cfg_s *aq_nic_get_cfg(struct aq_nic_s *self);
 u32 aq_nic_get_fw_version(struct aq_nic_s *self);
 int aq_nic_change_pm_state(struct aq_nic_s *self, pm_message_t *pm_msg);
+int aq_nic_update_interrupt_moderation_settings(struct aq_nic_s *self);
 
 #endif /* AQ_NIC_H */
index 4c6c882c6a1c424238473ea40ecf9f0ebf7cee28..cadaa646c89f4b741382b4beee72c6ec3e3bfc18 100644 (file)
@@ -85,6 +85,7 @@ int aq_pci_func_init(struct aq_pci_func_s *self)
        int err = 0;
        unsigned int bar = 0U;
        unsigned int port = 0U;
+       unsigned int numvecs = 0U;
 
        err = pci_enable_device(self->pdev);
        if (err < 0)
@@ -142,10 +143,12 @@ int aq_pci_func_init(struct aq_pci_func_s *self)
                }
        }
 
-       /*enable interrupts */
+       numvecs = min((u8)AQ_CFG_VECS_DEF, self->aq_hw_caps.msix_irqs);
+       numvecs = min(numvecs, num_online_cpus());
+
+       /* enable interrupts */
 #if !AQ_CFG_FORCE_LEGACY_INT
-       err = pci_alloc_irq_vectors(self->pdev, self->aq_hw_caps.msix_irqs,
-                             self->aq_hw_caps.msix_irqs, PCI_IRQ_MSIX);
+       err = pci_alloc_irq_vectors(self->pdev, numvecs, numvecs, PCI_IRQ_MSIX);
 
        if (err < 0) {
                err = pci_alloc_irq_vectors(self->pdev, 1, 1,
@@ -153,7 +156,7 @@ int aq_pci_func_init(struct aq_pci_func_s *self)
                if (err < 0)
                        goto err_exit;
        }
-#endif
+#endif /* AQ_CFG_FORCE_LEGACY_INT */
 
        /* net device init */
        for (port = 0; port < self->ports; ++port) {
@@ -265,6 +268,9 @@ void aq_pci_func_free(struct aq_pci_func_s *self)
                aq_nic_ndev_free(self->port[port]);
        }
 
+       if (self->mmio)
+               iounmap(self->mmio);
+
        kfree(self);
 
 err_exit:;
index 305ff8ffac2c9acc9633aa4fadde4a33d0392f8d..5fecc9a099ef7fd34d3a36b9ee1eb9c01a3f9fcd 100644 (file)
@@ -373,8 +373,11 @@ int aq_vec_get_sw_stats(struct aq_vec_s *self, u64 *data, unsigned int *p_count)
        memset(&stats_tx, 0U, sizeof(struct aq_ring_stats_tx_s));
        aq_vec_add_stats(self, &stats_rx, &stats_tx);
 
+       /* This data should mimic aq_ethtool_queue_stat_names structure
+        */
        data[count] += stats_rx.packets;
        data[++count] += stats_tx.packets;
+       data[++count] += stats_tx.queue_restarts;
        data[++count] += stats_rx.jumbo_packets;
        data[++count] += stats_rx.lro_packets;
        data[++count] += stats_rx.errors;
index c5a02df7a48b719a65b169938746d777f3f0b5a0..07b3c49a16a4266b4fb312bb79198f9ba0c60f04 100644 (file)
@@ -765,24 +765,23 @@ err_exit:
        return err;
 }
 
-static int hw_atl_a0_hw_interrupt_moderation_set(struct aq_hw_s *self,
-                                                bool itr_enabled)
+static int hw_atl_a0_hw_interrupt_moderation_set(struct aq_hw_s *self)
 {
        unsigned int i = 0U;
+       u32 itr_rx;
 
-       if (itr_enabled && self->aq_nic_cfg->itr) {
-               if (self->aq_nic_cfg->itr != 0xFFFFU) {
+       if (self->aq_nic_cfg->itr) {
+               if (self->aq_nic_cfg->itr != AQ_CFG_INTERRUPT_MODERATION_AUTO) {
                        u32 itr_ = (self->aq_nic_cfg->itr >> 1);
 
                        itr_ = min(AQ_CFG_IRQ_MASK, itr_);
 
-                       PHAL_ATLANTIC_A0->itr_rx = 0x80000000U |
-                                       (itr_ << 0x10);
+                       itr_rx = 0x80000000U | (itr_ << 0x10);
                } else  {
                        u32 n = 0xFFFFU & aq_hw_read_reg(self, 0x00002A00U);
 
                        if (n < self->aq_link_status.mbps) {
-                               PHAL_ATLANTIC_A0->itr_rx = 0U;
+                               itr_rx = 0U;
                        } else {
                                static unsigned int hw_timers_tbl_[] = {
                                        0x01CU, /* 10Gbit */
@@ -797,8 +796,7 @@ static int hw_atl_a0_hw_interrupt_moderation_set(struct aq_hw_s *self,
                                        hw_atl_utils_mbps_2_speed_index(
                                                self->aq_link_status.mbps);
 
-                               PHAL_ATLANTIC_A0->itr_rx =
-                                       0x80000000U |
+                               itr_rx = 0x80000000U |
                                        (hw_timers_tbl_[speed_index] << 0x10U);
                        }
 
@@ -806,11 +804,11 @@ static int hw_atl_a0_hw_interrupt_moderation_set(struct aq_hw_s *self,
                        aq_hw_write_reg(self, 0x00002A00U, 0x8D000000U);
                }
        } else {
-               PHAL_ATLANTIC_A0->itr_rx = 0U;
+               itr_rx = 0U;
        }
 
        for (i = HW_ATL_A0_RINGS_MAX; i--;)
-               reg_irq_thr_set(self, PHAL_ATLANTIC_A0->itr_rx, i);
+               reg_irq_thr_set(self, itr_rx, i);
 
        return aq_hw_err_from_flags(self);
 }
@@ -885,6 +883,7 @@ static struct aq_hw_ops hw_atl_ops_ = {
        .hw_rss_set                  = hw_atl_a0_hw_rss_set,
        .hw_rss_hash_set             = hw_atl_a0_hw_rss_hash_set,
        .hw_get_regs                 = hw_atl_utils_hw_get_regs,
+       .hw_update_stats             = hw_atl_utils_update_stats,
        .hw_get_hw_stats             = hw_atl_utils_get_hw_stats,
        .hw_get_fw_version           = hw_atl_utils_get_fw_version,
 };
index 21784cc39dabdb9005a0c4bff26c64b0ac7a5286..ec68c20efcbdb6079b9dba4b8200ad8f1f450233 100644 (file)
@@ -788,39 +788,45 @@ err_exit:
        return err;
 }
 
-static int hw_atl_b0_hw_interrupt_moderation_set(struct aq_hw_s *self,
-                                                bool itr_enabled)
+static int hw_atl_b0_hw_interrupt_moderation_set(struct aq_hw_s *self)
 {
        unsigned int i = 0U;
+       u32 itr_tx = 2U;
+       u32 itr_rx = 2U;
 
-       if (itr_enabled && self->aq_nic_cfg->itr) {
+       switch (self->aq_nic_cfg->itr) {
+       case  AQ_CFG_INTERRUPT_MODERATION_ON:
+       case  AQ_CFG_INTERRUPT_MODERATION_AUTO:
                tdm_tx_desc_wr_wb_irq_en_set(self, 0U);
                tdm_tdm_intr_moder_en_set(self, 1U);
                rdm_rx_desc_wr_wb_irq_en_set(self, 0U);
                rdm_rdm_intr_moder_en_set(self, 1U);
 
-               PHAL_ATLANTIC_B0->itr_tx = 2U;
-               PHAL_ATLANTIC_B0->itr_rx = 2U;
+               if (self->aq_nic_cfg->itr == AQ_CFG_INTERRUPT_MODERATION_ON) {
+                       /* HW timers are in 2us units */
+                       int tx_max_timer = self->aq_nic_cfg->tx_itr / 2;
+                       int tx_min_timer = tx_max_timer / 2;
 
-               if (self->aq_nic_cfg->itr != 0xFFFFU) {
-                       unsigned int max_timer = self->aq_nic_cfg->itr / 2U;
-                       unsigned int min_timer = self->aq_nic_cfg->itr / 32U;
+                       int rx_max_timer = self->aq_nic_cfg->rx_itr / 2;
+                       int rx_min_timer = rx_max_timer / 2;
 
-                       max_timer = min(0x1FFU, max_timer);
-                       min_timer = min(0xFFU, min_timer);
+                       tx_max_timer = min(HW_ATL_INTR_MODER_MAX, tx_max_timer);
+                       tx_min_timer = min(HW_ATL_INTR_MODER_MIN, tx_min_timer);
+                       rx_max_timer = min(HW_ATL_INTR_MODER_MAX, rx_max_timer);
+                       rx_min_timer = min(HW_ATL_INTR_MODER_MIN, rx_min_timer);
 
-                       PHAL_ATLANTIC_B0->itr_tx |= min_timer << 0x8U;
-                       PHAL_ATLANTIC_B0->itr_tx |= max_timer << 0x10U;
-                       PHAL_ATLANTIC_B0->itr_rx |= min_timer << 0x8U;
-                       PHAL_ATLANTIC_B0->itr_rx |= max_timer << 0x10U;
+                       itr_tx |= tx_min_timer << 0x8U;
+                       itr_tx |= tx_max_timer << 0x10U;
+                       itr_rx |= rx_min_timer << 0x8U;
+                       itr_rx |= rx_max_timer << 0x10U;
                } else {
                        static unsigned int hw_atl_b0_timers_table_tx_[][2] = {
-                               {0xffU, 0xffU}, /* 10Gbit */
-                               {0xffU, 0x1ffU}, /* 5Gbit */
-                               {0xffU, 0x1ffU}, /* 5Gbit 5GS */
-                               {0xffU, 0x1ffU}, /* 2.5Gbit */
-                               {0xffU, 0x1ffU}, /* 1Gbit */
-                               {0xffU, 0x1ffU}, /* 100Mbit */
+                               {0xfU, 0xffU}, /* 10Gbit */
+                               {0xfU, 0x1ffU}, /* 5Gbit */
+                               {0xfU, 0x1ffU}, /* 5Gbit 5GS */
+                               {0xfU, 0x1ffU}, /* 2.5Gbit */
+                               {0xfU, 0x1ffU}, /* 1Gbit */
+                               {0xfU, 0x1ffU}, /* 100Mbit */
                        };
 
                        static unsigned int hw_atl_b0_timers_table_rx_[][2] = {
@@ -836,34 +842,36 @@ static int hw_atl_b0_hw_interrupt_moderation_set(struct aq_hw_s *self,
                                        hw_atl_utils_mbps_2_speed_index(
                                                self->aq_link_status.mbps);
 
-                       PHAL_ATLANTIC_B0->itr_tx |=
-                               hw_atl_b0_timers_table_tx_[speed_index]
-                               [0] << 0x8U; /* set min timer value */
-                       PHAL_ATLANTIC_B0->itr_tx |=
-                               hw_atl_b0_timers_table_tx_[speed_index]
-                               [1] << 0x10U; /* set max timer value */
-
-                       PHAL_ATLANTIC_B0->itr_rx |=
-                               hw_atl_b0_timers_table_rx_[speed_index]
-                               [0] << 0x8U; /* set min timer value */
-                       PHAL_ATLANTIC_B0->itr_rx |=
-                               hw_atl_b0_timers_table_rx_[speed_index]
-                               [1] << 0x10U; /* set max timer value */
+                       /* Update user visible ITR settings */
+                       self->aq_nic_cfg->tx_itr = hw_atl_b0_timers_table_tx_
+                                                       [speed_index][1] * 2;
+                       self->aq_nic_cfg->rx_itr = hw_atl_b0_timers_table_rx_
+                                                       [speed_index][1] * 2;
+
+                       itr_tx |= hw_atl_b0_timers_table_tx_
+                                               [speed_index][0] << 0x8U;
+                       itr_tx |= hw_atl_b0_timers_table_tx_
+                                               [speed_index][1] << 0x10U;
+
+                       itr_rx |= hw_atl_b0_timers_table_rx_
+                                               [speed_index][0] << 0x8U;
+                       itr_rx |= hw_atl_b0_timers_table_rx_
+                                               [speed_index][1] << 0x10U;
                }
-       } else {
+               break;
+       case AQ_CFG_INTERRUPT_MODERATION_OFF:
                tdm_tx_desc_wr_wb_irq_en_set(self, 1U);
                tdm_tdm_intr_moder_en_set(self, 0U);
                rdm_rx_desc_wr_wb_irq_en_set(self, 1U);
                rdm_rdm_intr_moder_en_set(self, 0U);
-               PHAL_ATLANTIC_B0->itr_tx = 0U;
-               PHAL_ATLANTIC_B0->itr_rx = 0U;
+               itr_tx = 0U;
+               itr_rx = 0U;
+               break;
        }
 
        for (i = HW_ATL_B0_RINGS_MAX; i--;) {
-               reg_tx_intr_moder_ctrl_set(self,
-                                          PHAL_ATLANTIC_B0->itr_tx, i);
-               reg_rx_intr_moder_ctrl_set(self,
-                                          PHAL_ATLANTIC_B0->itr_rx, i);
+               reg_tx_intr_moder_ctrl_set(self, itr_tx, i);
+               reg_rx_intr_moder_ctrl_set(self, itr_rx, i);
        }
 
        return aq_hw_err_from_flags(self);
@@ -939,6 +947,7 @@ static struct aq_hw_ops hw_atl_ops_ = {
        .hw_rss_set                  = hw_atl_b0_hw_rss_set,
        .hw_rss_hash_set             = hw_atl_b0_hw_rss_hash_set,
        .hw_get_regs                 = hw_atl_utils_hw_get_regs,
+       .hw_update_stats             = hw_atl_utils_update_stats,
        .hw_get_hw_stats             = hw_atl_utils_get_hw_stats,
        .hw_get_fw_version           = hw_atl_utils_get_fw_version,
 };
index fcf89e25a773ee869b70160a444ab43af076fbf8..9aa2c6edfca23276335cd9c4bf23c8528f9305e1 100644 (file)
 
 #define HW_ATL_B0_FW_VER_EXPECTED 0x01050006U
 
+#define HW_ATL_INTR_MODER_MAX  0x1FF
+#define HW_ATL_INTR_MODER_MIN  0xFF
+
 /* Hardware tx descriptor */
 struct __packed hw_atl_txd_s {
        u64 buf_addr;
index bf734b32e44b6b1638f043a75042e34fc7e8d7e2..1fe016fc4bc704361ca68ee39f3e443715505e8c 100644 (file)
@@ -255,6 +255,15 @@ err_exit:
        return err;
 }
 
+int hw_atl_utils_mpi_read_mbox(struct aq_hw_s *self,
+                              struct hw_aq_atl_utils_mbox_header *pmbox)
+{
+       return hw_atl_utils_fw_downld_dwords(self,
+                                     PHAL_ATLANTIC->mbox_addr,
+                                     (u32 *)(void *)pmbox,
+                                     sizeof(*pmbox) / sizeof(u32));
+}
+
 void hw_atl_utils_mpi_read_stats(struct aq_hw_s *self,
                                 struct hw_aq_atl_utils_mbox *pmbox)
 {
@@ -267,9 +276,6 @@ void hw_atl_utils_mpi_read_stats(struct aq_hw_s *self,
        if (err < 0)
                goto err_exit;
 
-       if (pmbox != &PHAL_ATLANTIC->mbox)
-               memcpy(pmbox, &PHAL_ATLANTIC->mbox, sizeof(*pmbox));
-
        if (IS_CHIP_FEATURE(REVISION_A0)) {
                unsigned int mtu = self->aq_nic_cfg ?
                                        self->aq_nic_cfg->mtu : 1514U;
@@ -299,17 +305,17 @@ void hw_atl_utils_mpi_set(struct aq_hw_s *self,
 {
        int err = 0;
        u32 transaction_id = 0;
+       struct hw_aq_atl_utils_mbox_header mbox;
 
        if (state == MPI_RESET) {
-               hw_atl_utils_mpi_read_stats(self, &PHAL_ATLANTIC->mbox);
+               hw_atl_utils_mpi_read_mbox(self, &mbox);
 
-               transaction_id = PHAL_ATLANTIC->mbox.transaction_id;
+               transaction_id = mbox.transaction_id;
 
                AQ_HW_WAIT_FOR(transaction_id !=
-                               (hw_atl_utils_mpi_read_stats
-                                       (self, &PHAL_ATLANTIC->mbox),
-                                       PHAL_ATLANTIC->mbox.transaction_id),
-                                       1000U, 100U);
+                               (hw_atl_utils_mpi_read_mbox(self, &mbox),
+                                mbox.transaction_id),
+                              1000U, 100U);
                if (err < 0)
                        goto err_exit;
        }
@@ -492,16 +498,51 @@ int hw_atl_utils_hw_set_power(struct aq_hw_s *self,
        return 0;
 }
 
+int hw_atl_utils_update_stats(struct aq_hw_s *self)
+{
+       struct hw_atl_s *hw_self = PHAL_ATLANTIC;
+       struct hw_aq_atl_utils_mbox mbox;
+
+       if (!self->aq_link_status.mbps)
+               return 0;
+
+       hw_atl_utils_mpi_read_stats(self, &mbox);
+
+#define AQ_SDELTA(_N_) (hw_self->curr_stats._N_ += \
+                       mbox.stats._N_ - hw_self->last_stats._N_)
+
+       AQ_SDELTA(uprc);
+       AQ_SDELTA(mprc);
+       AQ_SDELTA(bprc);
+       AQ_SDELTA(erpt);
+
+       AQ_SDELTA(uptc);
+       AQ_SDELTA(mptc);
+       AQ_SDELTA(bptc);
+       AQ_SDELTA(erpr);
+
+       AQ_SDELTA(ubrc);
+       AQ_SDELTA(ubtc);
+       AQ_SDELTA(mbrc);
+       AQ_SDELTA(mbtc);
+       AQ_SDELTA(bbrc);
+       AQ_SDELTA(bbtc);
+       AQ_SDELTA(dpc);
+
+#undef AQ_SDELTA
+
+       memcpy(&hw_self->last_stats, &mbox.stats, sizeof(mbox.stats));
+
+       return 0;
+}
+
 int hw_atl_utils_get_hw_stats(struct aq_hw_s *self,
                              u64 *data, unsigned int *p_count)
 {
-       struct hw_atl_stats_s *stats = NULL;
+       struct hw_atl_s *hw_self = PHAL_ATLANTIC;
+       struct hw_atl_stats_s *stats = &hw_self->curr_stats;
        int i = 0;
 
-       hw_atl_utils_mpi_read_stats(self, &PHAL_ATLANTIC->mbox);
-
-       stats = &PHAL_ATLANTIC->mbox.stats;
-
        data[i] = stats->uprc + stats->mprc + stats->bprc;
        data[++i] = stats->uprc;
        data[++i] = stats->mprc;
index e0360a6b2202ef5b4ac683a44edcde9bf20ebedc..c99cc690e425bb72907df675e04a196819cfec02 100644 (file)
@@ -115,19 +115,22 @@ struct __packed hw_aq_atl_utils_fw_rpc {
        };
 };
 
-struct __packed hw_aq_atl_utils_mbox {
+struct __packed hw_aq_atl_utils_mbox_header {
        u32 version;
        u32 transaction_id;
-       int error;
+       u32 error;
+};
+
+struct __packed hw_aq_atl_utils_mbox {
+       struct hw_aq_atl_utils_mbox_header header;
        struct hw_atl_stats_s stats;
 };
 
 struct __packed hw_atl_s {
        struct aq_hw_s base;
-       struct hw_aq_atl_utils_mbox mbox;
+       struct hw_atl_stats_s last_stats;
+       struct hw_atl_stats_s curr_stats;
        u64 speed;
-       u32 itr_tx;
-       u32 itr_rx;
        unsigned int chip_features;
        u32 fw_ver_actual;
        atomic_t dpc;
@@ -170,6 +173,9 @@ enum hal_atl_utils_fw_state_e {
 
 void hw_atl_utils_hw_chip_features_init(struct aq_hw_s *self, u32 *p);
 
+int hw_atl_utils_mpi_read_mbox(struct aq_hw_s *self,
+                              struct hw_aq_atl_utils_mbox_header *pmbox);
+
 void hw_atl_utils_mpi_read_stats(struct aq_hw_s *self,
                                 struct hw_aq_atl_utils_mbox *pmbox);
 
@@ -199,6 +205,8 @@ int hw_atl_utils_hw_deinit(struct aq_hw_s *self);
 
 int hw_atl_utils_get_fw_version(struct aq_hw_s *self, u32 *fw_version);
 
+int hw_atl_utils_update_stats(struct aq_hw_s *self);
+
 int hw_atl_utils_get_hw_stats(struct aq_hw_s *self,
                              u64 *data,
                              unsigned int *p_count);
index aacec8bc19d5fbf6fe0f007d8a6a59fe2df23c8d..dc5de275352a7f589b0d410b6127bee4ea4b815c 100644 (file)
@@ -214,6 +214,8 @@ static const u16 bnxt_async_events_arr[] = {
        ASYNC_EVENT_CMPL_EVENT_ID_LINK_SPEED_CFG_CHANGE,
 };
 
+static struct workqueue_struct *bnxt_pf_wq;
+
 static bool bnxt_vf_pciid(enum board_idx idx)
 {
        return (idx == NETXTREME_C_VF || idx == NETXTREME_E_VF);
@@ -1024,12 +1026,28 @@ static int bnxt_discard_rx(struct bnxt *bp, struct bnxt_napi *bnapi,
        return 0;
 }
 
+static void bnxt_queue_sp_work(struct bnxt *bp)
+{
+       if (BNXT_PF(bp))
+               queue_work(bnxt_pf_wq, &bp->sp_task);
+       else
+               schedule_work(&bp->sp_task);
+}
+
+static void bnxt_cancel_sp_work(struct bnxt *bp)
+{
+       if (BNXT_PF(bp))
+               flush_workqueue(bnxt_pf_wq);
+       else
+               cancel_work_sync(&bp->sp_task);
+}
+
 static void bnxt_sched_reset(struct bnxt *bp, struct bnxt_rx_ring_info *rxr)
 {
        if (!rxr->bnapi->in_reset) {
                rxr->bnapi->in_reset = true;
                set_bit(BNXT_RESET_TASK_SP_EVENT, &bp->sp_event);
-               schedule_work(&bp->sp_task);
+               bnxt_queue_sp_work(bp);
        }
        rxr->rx_next_cons = 0xffff;
 }
@@ -1717,7 +1735,7 @@ static int bnxt_async_event_process(struct bnxt *bp,
        default:
                goto async_event_process_exit;
        }
-       schedule_work(&bp->sp_task);
+       bnxt_queue_sp_work(bp);
 async_event_process_exit:
        bnxt_ulp_async_events(bp, cmpl);
        return 0;
@@ -1751,7 +1769,7 @@ static int bnxt_hwrm_handler(struct bnxt *bp, struct tx_cmp *txcmp)
 
                set_bit(vf_id - bp->pf.first_vf_id, bp->pf.vf_event_bmap);
                set_bit(BNXT_HWRM_EXEC_FWD_REQ_SP_EVENT, &bp->sp_event);
-               schedule_work(&bp->sp_task);
+               bnxt_queue_sp_work(bp);
                break;
 
        case CMPL_BASE_TYPE_HWRM_ASYNC_EVENT:
@@ -3448,6 +3466,12 @@ int _hwrm_send_message(struct bnxt *bp, void *msg, u32 msg_len, int timeout)
        return bnxt_hwrm_do_send_msg(bp, msg, msg_len, timeout, false);
 }
 
+int _hwrm_send_message_silent(struct bnxt *bp, void *msg, u32 msg_len,
+                             int timeout)
+{
+       return bnxt_hwrm_do_send_msg(bp, msg, msg_len, timeout, true);
+}
+
 int hwrm_send_message(struct bnxt *bp, void *msg, u32 msg_len, int timeout)
 {
        int rc;
@@ -6327,7 +6351,9 @@ static int __bnxt_open_nic(struct bnxt *bp, bool irq_re_init, bool link_re_init)
        }
 
        if (link_re_init) {
+               mutex_lock(&bp->link_lock);
                rc = bnxt_update_phy_setting(bp);
+               mutex_unlock(&bp->link_lock);
                if (rc)
                        netdev_warn(bp->dev, "failed to update phy settings\n");
        }
@@ -6647,7 +6673,7 @@ static void bnxt_set_rx_mode(struct net_device *dev)
                vnic->rx_mask = mask;
 
                set_bit(BNXT_RX_MASK_SP_EVENT, &bp->sp_event);
-               schedule_work(&bp->sp_task);
+               bnxt_queue_sp_work(bp);
        }
 }
 
@@ -6920,7 +6946,7 @@ static void bnxt_tx_timeout(struct net_device *dev)
 
        netdev_err(bp->dev,  "TX timeout detected, starting reset task!\n");
        set_bit(BNXT_RESET_TASK_SP_EVENT, &bp->sp_event);
-       schedule_work(&bp->sp_task);
+       bnxt_queue_sp_work(bp);
 }
 
 #ifdef CONFIG_NET_POLL_CONTROLLER
@@ -6952,7 +6978,7 @@ static void bnxt_timer(unsigned long data)
        if (bp->link_info.link_up && (bp->flags & BNXT_FLAG_PORT_STATS) &&
            bp->stats_coal_ticks) {
                set_bit(BNXT_PERIODIC_STATS_SP_EVENT, &bp->sp_event);
-               schedule_work(&bp->sp_task);
+               bnxt_queue_sp_work(bp);
        }
 bnxt_restart_timer:
        mod_timer(&bp->timer, jiffies + bp->current_interval);
@@ -7025,30 +7051,28 @@ static void bnxt_sp_task(struct work_struct *work)
        if (test_and_clear_bit(BNXT_PERIODIC_STATS_SP_EVENT, &bp->sp_event))
                bnxt_hwrm_port_qstats(bp);
 
-       /* These functions below will clear BNXT_STATE_IN_SP_TASK.  They
-        * must be the last functions to be called before exiting.
-        */
        if (test_and_clear_bit(BNXT_LINK_CHNG_SP_EVENT, &bp->sp_event)) {
-               int rc = 0;
+               int rc;
 
+               mutex_lock(&bp->link_lock);
                if (test_and_clear_bit(BNXT_LINK_SPEED_CHNG_SP_EVENT,
                                       &bp->sp_event))
                        bnxt_hwrm_phy_qcaps(bp);
 
-               bnxt_rtnl_lock_sp(bp);
-               if (test_bit(BNXT_STATE_OPEN, &bp->state))
-                       rc = bnxt_update_link(bp, true);
-               bnxt_rtnl_unlock_sp(bp);
+               rc = bnxt_update_link(bp, true);
+               mutex_unlock(&bp->link_lock);
                if (rc)
                        netdev_err(bp->dev, "SP task can't update link (rc: %x)\n",
                                   rc);
        }
        if (test_and_clear_bit(BNXT_HWRM_PORT_MODULE_SP_EVENT, &bp->sp_event)) {
-               bnxt_rtnl_lock_sp(bp);
-               if (test_bit(BNXT_STATE_OPEN, &bp->state))
-                       bnxt_get_port_module_status(bp);
-               bnxt_rtnl_unlock_sp(bp);
+               mutex_lock(&bp->link_lock);
+               bnxt_get_port_module_status(bp);
+               mutex_unlock(&bp->link_lock);
        }
+       /* These functions below will clear BNXT_STATE_IN_SP_TASK.  They
+        * must be the last functions to be called before exiting.
+        */
        if (test_and_clear_bit(BNXT_RESET_TASK_SP_EVENT, &bp->sp_event))
                bnxt_reset(bp, false);
 
@@ -7433,7 +7457,7 @@ static int bnxt_rx_flow_steer(struct net_device *dev, const struct sk_buff *skb,
        spin_unlock_bh(&bp->ntp_fltr_lock);
 
        set_bit(BNXT_RX_NTP_FLTR_SP_EVENT, &bp->sp_event);
-       schedule_work(&bp->sp_task);
+       bnxt_queue_sp_work(bp);
 
        return new_fltr->sw_id;
 
@@ -7516,7 +7540,7 @@ static void bnxt_udp_tunnel_add(struct net_device *dev,
                if (bp->vxlan_port_cnt == 1) {
                        bp->vxlan_port = ti->port;
                        set_bit(BNXT_VXLAN_ADD_PORT_SP_EVENT, &bp->sp_event);
-                       schedule_work(&bp->sp_task);
+                       bnxt_queue_sp_work(bp);
                }
                break;
        case UDP_TUNNEL_TYPE_GENEVE:
@@ -7533,7 +7557,7 @@ static void bnxt_udp_tunnel_add(struct net_device *dev,
                return;
        }
 
-       schedule_work(&bp->sp_task);
+       bnxt_queue_sp_work(bp);
 }
 
 static void bnxt_udp_tunnel_del(struct net_device *dev,
@@ -7572,7 +7596,7 @@ static void bnxt_udp_tunnel_del(struct net_device *dev,
                return;
        }
 
-       schedule_work(&bp->sp_task);
+       bnxt_queue_sp_work(bp);
 }
 
 static int bnxt_bridge_getlink(struct sk_buff *skb, u32 pid, u32 seq,
@@ -7720,7 +7744,7 @@ static void bnxt_remove_one(struct pci_dev *pdev)
        pci_disable_pcie_error_reporting(pdev);
        unregister_netdev(dev);
        bnxt_shutdown_tc(bp);
-       cancel_work_sync(&bp->sp_task);
+       bnxt_cancel_sp_work(bp);
        bp->sp_event = 0;
 
        bnxt_clear_int_mode(bp);
@@ -7748,6 +7772,7 @@ static int bnxt_probe_phy(struct bnxt *bp)
                           rc);
                return rc;
        }
+       mutex_init(&bp->link_lock);
 
        rc = bnxt_update_link(bp, false);
        if (rc) {
@@ -7946,7 +7971,7 @@ static void bnxt_parse_log_pcie_link(struct bnxt *bp)
        enum pcie_link_width width = PCIE_LNK_WIDTH_UNKNOWN;
        enum pci_bus_speed speed = PCI_SPEED_UNKNOWN;
 
-       if (pcie_get_minimum_link(bp->pdev, &speed, &width) ||
+       if (pcie_get_minimum_link(pci_physfn(bp->pdev), &speed, &width) ||
            speed == PCI_SPEED_UNKNOWN || width == PCIE_LNK_WIDTH_UNKNOWN)
                netdev_info(bp->dev, "Failed to determine PCIe Link Info\n");
        else
@@ -8138,8 +8163,17 @@ static int bnxt_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
        else
                device_set_wakeup_capable(&pdev->dev, false);
 
-       if (BNXT_PF(bp))
+       if (BNXT_PF(bp)) {
+               if (!bnxt_pf_wq) {
+                       bnxt_pf_wq =
+                               create_singlethread_workqueue("bnxt_pf_wq");
+                       if (!bnxt_pf_wq) {
+                               dev_err(&pdev->dev, "Unable to create workqueue.\n");
+                               goto init_err_pci_clean;
+                       }
+               }
                bnxt_init_tc(bp);
+       }
 
        rc = register_netdev(dev);
        if (rc)
@@ -8375,4 +8409,17 @@ static struct pci_driver bnxt_pci_driver = {
 #endif
 };
 
-module_pci_driver(bnxt_pci_driver);
+static int __init bnxt_init(void)
+{
+       return pci_register_driver(&bnxt_pci_driver);
+}
+
+static void __exit bnxt_exit(void)
+{
+       pci_unregister_driver(&bnxt_pci_driver);
+       if (bnxt_pf_wq)
+               destroy_workqueue(bnxt_pf_wq);
+}
+
+module_init(bnxt_init);
+module_exit(bnxt_exit);
index 7b888d4b2b552a406b8157b3f037a299dc7645a4..c911e69ff25f67d0402b1f06e48de7245cea8a88 100644 (file)
@@ -1290,6 +1290,10 @@ struct bnxt {
        unsigned long           *ntp_fltr_bmap;
        int                     ntp_fltr_count;
 
+       /* To protect link related settings during link changes and
+        * ethtool settings changes.
+        */
+       struct mutex            link_lock;
        struct bnxt_link_info   link_info;
        struct ethtool_eee      eee;
        u32                     lpi_tmr_lo;
@@ -1358,6 +1362,7 @@ void bnxt_set_ring_params(struct bnxt *);
 int bnxt_set_rx_skb_mode(struct bnxt *bp, bool page_mode);
 void bnxt_hwrm_cmd_hdr_init(struct bnxt *, void *, u16, u16, u16);
 int _hwrm_send_message(struct bnxt *, void *, u32, int);
+int _hwrm_send_message_silent(struct bnxt *bp, void *msg, u32 len, int timeout);
 int hwrm_send_message(struct bnxt *, void *, u32, int);
 int hwrm_send_message_silent(struct bnxt *, void *, u32, int);
 int bnxt_hwrm_func_rgtr_async_events(struct bnxt *bp, unsigned long *bmap,
index aa1f3a2c7a7865cce7970e2e7b75f74b218d5df7..fed37cd9ae1d464af02335c072b4b3676b024e0b 100644 (file)
@@ -50,7 +50,9 @@ static int bnxt_hwrm_queue_pri2cos_qcfg(struct bnxt *bp, struct ieee_ets *ets)
 
        bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_QUEUE_PRI2COS_QCFG, -1, -1);
        req.flags = cpu_to_le32(QUEUE_PRI2COS_QCFG_REQ_FLAGS_IVLAN);
-       rc = hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT);
+
+       mutex_lock(&bp->hwrm_cmd_lock);
+       rc = _hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT);
        if (!rc) {
                u8 *pri2cos = &resp->pri0_cos_queue_id;
                int i, j;
@@ -66,6 +68,7 @@ static int bnxt_hwrm_queue_pri2cos_qcfg(struct bnxt *bp, struct ieee_ets *ets)
                        }
                }
        }
+       mutex_unlock(&bp->hwrm_cmd_lock);
        return rc;
 }
 
@@ -119,9 +122,13 @@ static int bnxt_hwrm_queue_cos2bw_qcfg(struct bnxt *bp, struct ieee_ets *ets)
        int rc, i;
 
        bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_QUEUE_COS2BW_QCFG, -1, -1);
-       rc = hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT);
-       if (rc)
+
+       mutex_lock(&bp->hwrm_cmd_lock);
+       rc = _hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT);
+       if (rc) {
+               mutex_unlock(&bp->hwrm_cmd_lock);
                return rc;
+       }
 
        data = &resp->queue_id0 + offsetof(struct bnxt_cos2bw_cfg, queue_id);
        for (i = 0; i < bp->max_tc; i++, data += sizeof(cos2bw) - 4) {
@@ -143,6 +150,7 @@ static int bnxt_hwrm_queue_cos2bw_qcfg(struct bnxt *bp, struct ieee_ets *ets)
                        }
                }
        }
+       mutex_unlock(&bp->hwrm_cmd_lock);
        return 0;
 }
 
@@ -240,12 +248,17 @@ static int bnxt_hwrm_queue_pfc_qcfg(struct bnxt *bp, struct ieee_pfc *pfc)
        int rc;
 
        bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_QUEUE_PFCENABLE_QCFG, -1, -1);
-       rc = hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT);
-       if (rc)
+
+       mutex_lock(&bp->hwrm_cmd_lock);
+       rc = _hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT);
+       if (rc) {
+               mutex_unlock(&bp->hwrm_cmd_lock);
                return rc;
+       }
 
        pri_mask = le32_to_cpu(resp->flags);
        pfc->pfc_en = pri_mask;
+       mutex_unlock(&bp->hwrm_cmd_lock);
        return 0;
 }
 
index 8eff05a3e0e4b748c3a0d35661ce7b1901ddef61..3cbe771b335296ce526122e892349e741ddb43b9 100644 (file)
@@ -1052,6 +1052,7 @@ static int bnxt_get_link_ksettings(struct net_device *dev,
        u32 ethtool_speed;
 
        ethtool_link_ksettings_zero_link_mode(lk_ksettings, supported);
+       mutex_lock(&bp->link_lock);
        bnxt_fw_to_ethtool_support_spds(link_info, lk_ksettings);
 
        ethtool_link_ksettings_zero_link_mode(lk_ksettings, advertising);
@@ -1099,6 +1100,7 @@ static int bnxt_get_link_ksettings(struct net_device *dev,
                        base->port = PORT_FIBRE;
        }
        base->phy_address = link_info->phy_addr;
+       mutex_unlock(&bp->link_lock);
 
        return 0;
 }
@@ -1190,6 +1192,7 @@ static int bnxt_set_link_ksettings(struct net_device *dev,
        if (!BNXT_SINGLE_PF(bp))
                return -EOPNOTSUPP;
 
+       mutex_lock(&bp->link_lock);
        if (base->autoneg == AUTONEG_ENABLE) {
                BNXT_ETHTOOL_TO_FW_SPDS(fw_advertising, lk_ksettings,
                                        advertising);
@@ -1234,6 +1237,7 @@ static int bnxt_set_link_ksettings(struct net_device *dev,
                rc = bnxt_hwrm_set_link_setting(bp, set_pause, false);
 
 set_setting_exit:
+       mutex_unlock(&bp->link_lock);
        return rc;
 }
 
@@ -1805,7 +1809,8 @@ static int bnxt_find_nvram_item(struct net_device *dev, u16 type, u16 ordinal,
        req.dir_ordinal = cpu_to_le16(ordinal);
        req.dir_ext = cpu_to_le16(ext);
        req.opt_ordinal = NVM_FIND_DIR_ENTRY_REQ_OPT_ORDINAL_EQ;
-       rc = hwrm_send_message_silent(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT);
+       mutex_lock(&bp->hwrm_cmd_lock);
+       rc = _hwrm_send_message_silent(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT);
        if (rc == 0) {
                if (index)
                        *index = le16_to_cpu(output->dir_idx);
@@ -1814,6 +1819,7 @@ static int bnxt_find_nvram_item(struct net_device *dev, u16 type, u16 ordinal,
                if (data_length)
                        *data_length = le32_to_cpu(output->dir_data_length);
        }
+       mutex_unlock(&bp->hwrm_cmd_lock);
        return rc;
 }
 
index d37925a8a65b6d79d96063d0eabcac9bae8dadd9..5ee18660bc33a2572320ac3210029e883841b044 100644 (file)
@@ -502,6 +502,7 @@ static int bnxt_sriov_enable(struct bnxt *bp, int *num_vfs)
        int rc = 0, vfs_supported;
        int min_rx_rings, min_tx_rings, min_rss_ctxs;
        int tx_ok = 0, rx_ok = 0, rss_ok = 0;
+       int avail_cp, avail_stat;
 
        /* Check if we can enable requested num of vf's. At a mininum
         * we require 1 RX 1 TX rings for each VF. In this minimum conf
@@ -509,6 +510,10 @@ static int bnxt_sriov_enable(struct bnxt *bp, int *num_vfs)
         */
        vfs_supported = *num_vfs;
 
+       avail_cp = bp->pf.max_cp_rings - bp->cp_nr_rings;
+       avail_stat = bp->pf.max_stat_ctxs - bp->num_stat_ctxs;
+       avail_cp = min_t(int, avail_cp, avail_stat);
+
        while (vfs_supported) {
                min_rx_rings = vfs_supported;
                min_tx_rings = vfs_supported;
@@ -523,10 +528,12 @@ static int bnxt_sriov_enable(struct bnxt *bp, int *num_vfs)
                            min_rx_rings)
                                rx_ok = 1;
                }
-               if (bp->pf.max_vnics - bp->nr_vnics < min_rx_rings)
+               if (bp->pf.max_vnics - bp->nr_vnics < min_rx_rings ||
+                   avail_cp < min_rx_rings)
                        rx_ok = 0;
 
-               if (bp->pf.max_tx_rings - bp->tx_nr_rings >= min_tx_rings)
+               if (bp->pf.max_tx_rings - bp->tx_nr_rings >= min_tx_rings &&
+                   avail_cp >= min_tx_rings)
                        tx_ok = 1;
 
                if (bp->pf.max_rsscos_ctxs - bp->rsscos_nr_ctxs >= min_rss_ctxs)
index e7f54948173f7e6764b57ba5b99636ba206ba323..5b19826a7e16c731799a4b1cfc4c66d78d91f72d 100644 (file)
@@ -1847,7 +1847,7 @@ static int liquidio_ptp_settime(struct ptp_clock_info *ptp,
        struct lio *lio = container_of(ptp, struct lio, ptp_info);
        struct octeon_device *oct = (struct octeon_device *)lio->oct_dev;
 
-       ns = timespec_to_ns(ts);
+       ns = timespec64_to_ns(ts);
 
        spin_lock_irqsave(&lio->ptp_lock, flags);
        lio_pci_writeq(oct, ns, CN6XXX_MIO_PTP_CLOCK_HI);
index cb8182f4fdfa1725f8d4024741e00219376d7326..c66abd476023a401b14c53abf7026e3147f13f62 100644 (file)
@@ -1093,11 +1093,12 @@ static int build_hdr_data(u8 hdr_field, struct sk_buff *skb,
  * places them in a descriptor array, scrq_arr
  */
 
-static void create_hdr_descs(u8 hdr_field, u8 *hdr_data, int len, int *hdr_len,
-                            union sub_crq *scrq_arr)
+static int create_hdr_descs(u8 hdr_field, u8 *hdr_data, int len, int *hdr_len,
+                           union sub_crq *scrq_arr)
 {
        union sub_crq hdr_desc;
        int tmp_len = len;
+       int num_descs = 0;
        u8 *data, *cur;
        int tmp;
 
@@ -1126,7 +1127,10 @@ static void create_hdr_descs(u8 hdr_field, u8 *hdr_data, int len, int *hdr_len,
                tmp_len -= tmp;
                *scrq_arr = hdr_desc;
                scrq_arr++;
+               num_descs++;
        }
+
+       return num_descs;
 }
 
 /**
@@ -1144,16 +1148,12 @@ static void build_hdr_descs_arr(struct ibmvnic_tx_buff *txbuff,
                                int *num_entries, u8 hdr_field)
 {
        int hdr_len[3] = {0, 0, 0};
-       int tot_len, len;
+       int tot_len;
        u8 *hdr_data = txbuff->hdr_data;
 
        tot_len = build_hdr_data(hdr_field, txbuff->skb, hdr_len,
                                 txbuff->hdr_data);
-       len = tot_len;
-       len -= 24;
-       if (len > 0)
-               num_entries += len % 29 ? len / 29 + 1 : len / 29;
-       create_hdr_descs(hdr_field, hdr_data, tot_len, hdr_len,
+       *num_entries += create_hdr_descs(hdr_field, hdr_data, tot_len, hdr_len,
                         txbuff->indir_arr + 1);
 }
 
index 57505b1df98dfb65e5033808c05c4cf9954600de..d591b3e6bd7c511d974c20e2a2e27e44816fa84f 100644 (file)
@@ -298,7 +298,7 @@ static i40e_status i40e_read_nvm_word_aq(struct i40e_hw *hw, u16 offset,
 }
 
 /**
- * __i40e_read_nvm_word - Reads nvm word, assumes called does the locking
+ * __i40e_read_nvm_word - Reads nvm word, assumes caller does the locking
  * @hw: pointer to the HW structure
  * @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF)
  * @data: word read from the Shadow RAM
index 1519dfb851d01a3628c3ad8411be96e3c2e0643e..2756131495f07f269f4c7f2e223dda4dcb7153f0 100644 (file)
@@ -1037,6 +1037,32 @@ reset_latency:
        return false;
 }
 
+/**
+ * i40e_reuse_rx_page - page flip buffer and store it back on the ring
+ * @rx_ring: rx descriptor ring to store buffers on
+ * @old_buff: donor buffer to have page reused
+ *
+ * Synchronizes page for reuse by the adapter
+ **/
+static void i40e_reuse_rx_page(struct i40e_ring *rx_ring,
+                              struct i40e_rx_buffer *old_buff)
+{
+       struct i40e_rx_buffer *new_buff;
+       u16 nta = rx_ring->next_to_alloc;
+
+       new_buff = &rx_ring->rx_bi[nta];
+
+       /* update, and store next to alloc */
+       nta++;
+       rx_ring->next_to_alloc = (nta < rx_ring->count) ? nta : 0;
+
+       /* transfer page from old buffer to new buffer */
+       new_buff->dma           = old_buff->dma;
+       new_buff->page          = old_buff->page;
+       new_buff->page_offset   = old_buff->page_offset;
+       new_buff->pagecnt_bias  = old_buff->pagecnt_bias;
+}
+
 /**
  * i40e_rx_is_programming_status - check for programming status descriptor
  * @qw: qword representing status_error_len in CPU ordering
@@ -1071,15 +1097,24 @@ static void i40e_clean_programming_status(struct i40e_ring *rx_ring,
                                          union i40e_rx_desc *rx_desc,
                                          u64 qw)
 {
-       u32 ntc = rx_ring->next_to_clean + 1;
+       struct i40e_rx_buffer *rx_buffer;
+       u32 ntc = rx_ring->next_to_clean;
        u8 id;
 
        /* fetch, update, and store next to clean */
+       rx_buffer = &rx_ring->rx_bi[ntc++];
        ntc = (ntc < rx_ring->count) ? ntc : 0;
        rx_ring->next_to_clean = ntc;
 
        prefetch(I40E_RX_DESC(rx_ring, ntc));
 
+       /* place unused page back on the ring */
+       i40e_reuse_rx_page(rx_ring, rx_buffer);
+       rx_ring->rx_stats.page_reuse_count++;
+
+       /* clear contents of buffer_info */
+       rx_buffer->page = NULL;
+
        id = (qw & I40E_RX_PROG_STATUS_DESC_QW1_PROGID_MASK) >>
                  I40E_RX_PROG_STATUS_DESC_QW1_PROGID_SHIFT;
 
@@ -1638,32 +1673,6 @@ static bool i40e_cleanup_headers(struct i40e_ring *rx_ring, struct sk_buff *skb,
        return false;
 }
 
-/**
- * i40e_reuse_rx_page - page flip buffer and store it back on the ring
- * @rx_ring: rx descriptor ring to store buffers on
- * @old_buff: donor buffer to have page reused
- *
- * Synchronizes page for reuse by the adapter
- **/
-static void i40e_reuse_rx_page(struct i40e_ring *rx_ring,
-                              struct i40e_rx_buffer *old_buff)
-{
-       struct i40e_rx_buffer *new_buff;
-       u16 nta = rx_ring->next_to_alloc;
-
-       new_buff = &rx_ring->rx_bi[nta];
-
-       /* update, and store next to alloc */
-       nta++;
-       rx_ring->next_to_alloc = (nta < rx_ring->count) ? nta : 0;
-
-       /* transfer page from old buffer to new buffer */
-       new_buff->dma           = old_buff->dma;
-       new_buff->page          = old_buff->page;
-       new_buff->page_offset   = old_buff->page_offset;
-       new_buff->pagecnt_bias  = old_buff->pagecnt_bias;
-}
-
 /**
  * i40e_page_is_reusable - check if any reuse is possible
  * @page: page struct to check
index 9d5e7cf288bef2b1eb603843c7b57945918aeb72..f3315bc874adf8228f6277936c961d7afca95353 100644 (file)
@@ -96,6 +96,7 @@ struct mlxsw_core {
        const struct mlxsw_bus *bus;
        void *bus_priv;
        const struct mlxsw_bus_info *bus_info;
+       struct workqueue_struct *emad_wq;
        struct list_head rx_listener_list;
        struct list_head event_listener_list;
        struct {
@@ -465,7 +466,7 @@ static void mlxsw_emad_trans_timeout_schedule(struct mlxsw_reg_trans *trans)
 {
        unsigned long timeout = msecs_to_jiffies(MLXSW_EMAD_TIMEOUT_MS);
 
-       mlxsw_core_schedule_dw(&trans->timeout_dw, timeout);
+       queue_delayed_work(trans->core->emad_wq, &trans->timeout_dw, timeout);
 }
 
 static int mlxsw_emad_transmit(struct mlxsw_core *mlxsw_core,
@@ -587,12 +588,18 @@ static const struct mlxsw_listener mlxsw_emad_rx_listener =
 
 static int mlxsw_emad_init(struct mlxsw_core *mlxsw_core)
 {
+       struct workqueue_struct *emad_wq;
        u64 tid;
        int err;
 
        if (!(mlxsw_core->bus->features & MLXSW_BUS_F_TXRX))
                return 0;
 
+       emad_wq = alloc_workqueue("mlxsw_core_emad", WQ_MEM_RECLAIM, 0);
+       if (!emad_wq)
+               return -ENOMEM;
+       mlxsw_core->emad_wq = emad_wq;
+
        /* Set the upper 32 bits of the transaction ID field to a random
         * number. This allows us to discard EMADs addressed to other
         * devices.
@@ -619,6 +626,7 @@ static int mlxsw_emad_init(struct mlxsw_core *mlxsw_core)
 err_emad_trap_set:
        mlxsw_core_trap_unregister(mlxsw_core, &mlxsw_emad_rx_listener,
                                   mlxsw_core);
+       destroy_workqueue(mlxsw_core->emad_wq);
        return err;
 }
 
@@ -631,6 +639,7 @@ static void mlxsw_emad_fini(struct mlxsw_core *mlxsw_core)
        mlxsw_core->emad.use_emad = false;
        mlxsw_core_trap_unregister(mlxsw_core, &mlxsw_emad_rx_listener,
                                   mlxsw_core);
+       destroy_workqueue(mlxsw_core->emad_wq);
 }
 
 static struct sk_buff *mlxsw_emad_alloc(const struct mlxsw_core *mlxsw_core,
index cc27c5de5a1dd83060508910a9e99b8353a7c2be..4afc8486eb9a7ee5242d58393fbba643e2b75d74 100644 (file)
@@ -6401,6 +6401,36 @@ static inline void mlxsw_reg_mgpc_pack(char *payload, u32 counter_index,
        mlxsw_reg_mgpc_opcode_set(payload, opcode);
 }
 
+/* TIGCR - Tunneling IPinIP General Configuration Register
+ * -------------------------------------------------------
+ * The TIGCR register is used for setting up the IPinIP Tunnel configuration.
+ */
+#define MLXSW_REG_TIGCR_ID 0xA801
+#define MLXSW_REG_TIGCR_LEN 0x10
+
+MLXSW_REG_DEFINE(tigcr, MLXSW_REG_TIGCR_ID, MLXSW_REG_TIGCR_LEN);
+
+/* reg_tigcr_ipip_ttlc
+ * For IPinIP Tunnel encapsulation: whether to copy the ttl from the packet
+ * header.
+ * Access: RW
+ */
+MLXSW_ITEM32(reg, tigcr, ttlc, 0x04, 8, 1);
+
+/* reg_tigcr_ipip_ttl_uc
+ * The TTL for IPinIP Tunnel encapsulation of unicast packets if
+ * reg_tigcr_ipip_ttlc is unset.
+ * Access: RW
+ */
+MLXSW_ITEM32(reg, tigcr, ttl_uc, 0x04, 0, 8);
+
+static inline void mlxsw_reg_tigcr_pack(char *payload, bool ttlc, u8 ttl_uc)
+{
+       MLXSW_REG_ZERO(tigcr, payload);
+       mlxsw_reg_tigcr_ttlc_set(payload, ttlc);
+       mlxsw_reg_tigcr_ttl_uc_set(payload, ttl_uc);
+}
+
 /* SBPR - Shared Buffer Pools Register
  * -----------------------------------
  * The SBPR configures and retrieves the shared buffer pools and configuration.
@@ -6881,6 +6911,7 @@ static const struct mlxsw_reg_info *mlxsw_reg_infos[] = {
        MLXSW_REG(mcc),
        MLXSW_REG(mcda),
        MLXSW_REG(mgpc),
+       MLXSW_REG(tigcr),
        MLXSW_REG(sbpr),
        MLXSW_REG(sbcm),
        MLXSW_REG(sbpm),
index c16718d296d389b0330b8aa7a75f130a5eb4bdbf..5189022a1c8c335c42901b5d288bbdf830512f46 100644 (file)
@@ -5896,11 +5896,20 @@ static void mlxsw_sp_rifs_fini(struct mlxsw_sp *mlxsw_sp)
        kfree(mlxsw_sp->router->rifs);
 }
 
+static int
+mlxsw_sp_ipip_config_tigcr(struct mlxsw_sp *mlxsw_sp)
+{
+       char tigcr_pl[MLXSW_REG_TIGCR_LEN];
+
+       mlxsw_reg_tigcr_pack(tigcr_pl, true, 0);
+       return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(tigcr), tigcr_pl);
+}
+
 static int mlxsw_sp_ipips_init(struct mlxsw_sp *mlxsw_sp)
 {
        mlxsw_sp->router->ipip_ops_arr = mlxsw_sp_ipip_ops_arr;
        INIT_LIST_HEAD(&mlxsw_sp->router->ipip_list);
-       return 0;
+       return mlxsw_sp_ipip_config_tigcr(mlxsw_sp);
 }
 
 static void mlxsw_sp_ipips_fini(struct mlxsw_sp *mlxsw_sp)
index 1c0187f0af51f87b070c21a825b00e4a48887428..e118b5f2399669f172aaf6f80be6f6c221a235d0 100644 (file)
@@ -1180,10 +1180,14 @@ static void *nfp_net_rx_alloc_one(struct nfp_net_dp *dp, dma_addr_t *dma_addr)
 {
        void *frag;
 
-       if (!dp->xdp_prog)
+       if (!dp->xdp_prog) {
                frag = net