Merge tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dledford/rdma
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 14 Oct 2016 20:43:08 +0000 (13:43 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 14 Oct 2016 20:43:08 +0000 (13:43 -0700)
Pull rdma qedr RoCE driver from Doug Ledford:
 "Early on in the merge window I mentioned I had a backlog of new
  drivers waiting to be reviewed and that, in addition to the hns-roce
  driver, I wanted to get possible a couple more reviewed. I ended up
  only having the time to complete one of the additional drivers.

  During Dave Miller's pull request this go around, there were a series
  of 9 patches to the QLogic qed net driver that add basic support for a
  paired RoCE driver. That support is currently not functional because
  it is missing the matching RoCE driver in the RDMA subsystem. I
  managed to finish that review. However, because it goes against part
  of Dave's net pull, and a part that was accepted a day or two after
  the merge window opened, to apply cleanly it has to be applied to
  either the tip of Dave's net branch, or as I did in this case, I just
  applied it to your master after you had taken Dave's pull request."

* tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dledford/rdma:
  qedr: Add events support and register IB device
  qedr: Add GSI support
  qedr: Add LL2 RoCE interface
  qedr: Add support for data path
  qedr: Add support for memory registeration verbs
  qedr: Add support for QP verbs
  qedr: Add support for PD,PKEY and CQ verbs
  qedr: Add support for user context verbs
  qedr: Add support for RoCE HW init
  qedr: Add RoCE driver framework

131 files changed:
Documentation/devicetree/bindings/i2c/i2c.txt
Documentation/devicetree/bindings/i2c/trivial-devices.txt
Documentation/devicetree/bindings/infiniband/hisilicon-hns-roce.txt
Documentation/devicetree/bindings/input/touchscreen/melfas_mip4.txt [new file with mode: 0644]
Documentation/devicetree/bindings/rtc/dallas,ds1390.txt
Documentation/devicetree/bindings/rtc/epson,rx8900.txt [new file with mode: 0644]
Documentation/devicetree/bindings/rtc/rtc-omap.txt
Documentation/devicetree/bindings/vendor-prefixes.txt
Documentation/input/alps.txt
Documentation/kernel-parameters.txt
Documentation/scsi/g_NCR5380.txt
MAINTAINERS
arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi
arch/arm64/boot/dts/freescale/fsl-ls2080a.dtsi
arch/ia64/include/asm/libata-portmap.h
arch/powerpc/include/asm/libata-portmap.h
arch/x86/include/asm/percpu.h
block/blk-cgroup.c
drivers/acpi/acpi_pad.c
drivers/acpi/ec.c
drivers/acpi/fan.c
drivers/acpi/osl.c
drivers/acpi/property.c
drivers/ata/ahci.c
drivers/ata/ahci.h
drivers/ata/ahci_qoriq.c
drivers/ata/ahci_st.c
drivers/ata/libahci.c
drivers/ata/libata-scsi.c
drivers/ata/pata_at91.c
drivers/ata/pata_octeon_cf.c
drivers/ata/sata_mv.c
drivers/cpufreq/cppc_cpufreq.c
drivers/cpufreq/cpufreq_conservative.c
drivers/cpufreq/intel_pstate.c
drivers/devfreq/devfreq.c
drivers/devfreq/event/Kconfig
drivers/devfreq/event/exynos-nocp.c
drivers/gpio/gpio-pca953x.c
drivers/i2c/i2c-core.c
drivers/infiniband/hw/hns/hns_roce_cq.c
drivers/infiniband/hw/hns/hns_roce_device.h
drivers/infiniband/hw/hns/hns_roce_eq.c
drivers/infiniband/hw/hns/hns_roce_eq.h
drivers/infiniband/hw/hns/hns_roce_hem.c
drivers/infiniband/hw/hns/hns_roce_hem.h
drivers/infiniband/hw/hns/hns_roce_hw_v1.c
drivers/infiniband/hw/hns/hns_roce_hw_v1.h
drivers/infiniband/hw/hns/hns_roce_main.c
drivers/infiniband/hw/hns/hns_roce_mr.c
drivers/infiniband/hw/hns/hns_roce_pd.c
drivers/infiniband/hw/hns/hns_roce_qp.c
drivers/input/mouse/alps.c
drivers/input/mouse/alps.h
drivers/input/mouse/elantech.c
drivers/input/rmi4/rmi_i2c.c
drivers/input/rmi4/rmi_spi.c
drivers/input/serio/i8042-io.h
drivers/input/serio/i8042-ip22io.h
drivers/input/serio/i8042-ppcio.h
drivers/input/serio/i8042-sparcio.h
drivers/input/serio/i8042-unicore32io.h
drivers/input/serio/i8042-x86ia64io.h
drivers/input/serio/i8042.c
drivers/input/touchscreen/melfas_mip4.c
drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c
drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c
drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.h
drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c
drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.h
drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.c
drivers/net/ethernet/hisilicon/hns/hns_dsaf_reg.h
drivers/net/ethernet/hisilicon/hns/hns_enet.c
drivers/net/ethernet/hisilicon/hns/hns_ethtool.c
drivers/rtc/Kconfig
drivers/rtc/Makefile
drivers/rtc/rtc-ac100.c
drivers/rtc/rtc-asm9260.c
drivers/rtc/rtc-at32ap700x.c
drivers/rtc/rtc-bq32k.c
drivers/rtc/rtc-cmos.c
drivers/rtc/rtc-coh901331.c
drivers/rtc/rtc-davinci.c
drivers/rtc/rtc-digicolor.c
drivers/rtc/rtc-ds1302.c
drivers/rtc/rtc-ds1307.c
drivers/rtc/rtc-ds1347.c
drivers/rtc/rtc-gemini.c
drivers/rtc/rtc-isl12057.c [deleted file]
drivers/rtc/rtc-jz4740.c
drivers/rtc/rtc-mcp795.c
drivers/rtc/rtc-mt6397.c
drivers/rtc/rtc-nuc900.c
drivers/rtc/rtc-omap.c
drivers/rtc/rtc-palmas.c
drivers/rtc/rtc-pcf2123.c
drivers/rtc/rtc-pcf50633.c
drivers/rtc/rtc-pic32.c
drivers/rtc/rtc-rv8803.c
drivers/rtc/rtc-rx6110.c
drivers/rtc/rtc-rx8025.c
drivers/rtc/rtc-spear.c
drivers/rtc/rtc-stmp3xxx.c
drivers/rtc/rtc-sysfs.c
drivers/rtc/rtc-tegra.c
drivers/rtc/rtc-twl.c
drivers/scsi/be2iscsi/be_main.c
drivers/scsi/cxgbi/cxgb4i/cxgb4i.c
drivers/scsi/g_NCR5380.c
drivers/scsi/g_NCR5380.h
drivers/scsi/ufs/Kconfig
drivers/scsi/ufs/ufs_quirks.h
drivers/scsi/ufs/ufshcd.c
fs/kernfs/dir.c
fs/sysfs/dir.c
include/asm-generic/libata-portmap.h [deleted file]
include/asm-generic/percpu.h
include/linux/acpi.h
include/linux/ata.h
include/linux/blk-cgroup.h
include/linux/cgroup.h
include/linux/cpufreq.h
include/linux/kernfs.h
include/linux/libata.h
include/linux/pkeys.h
include/trace/events/cgroup.h [new file with mode: 0644]
kernel/cgroup.c
kernel/cpuset.c
kernel/sched/debug.c
lib/percpu-refcount.c
mm/percpu.c

index f31b2ad1552bd425c232c05b8ae3ed431b030260..5fa691e6f6388320acd4199995ef0072e9e70faa 100644 (file)
@@ -32,6 +32,14 @@ wants to support one of the below features, it should adapt the bindings below.
 - clock-frequency
        frequency of bus clock in Hz.
 
+- i2c-bus
+       For I2C adapters that have child nodes that are a mixture of both I2C
+       devices and non-I2C devices, the 'i2c-bus' subnode can be used for
+       populating I2C devices. If the 'i2c-bus' subnode is present, only
+       subnodes of this will be considered as I2C slaves. The properties,
+       '#address-cells' and '#size-cells' must be defined under this subnode
+       if present.
+
 - i2c-scl-falling-time-ns
        Number of nanoseconds the SCL signal takes to fall; t(f) in the I2C
        specification.
index 1416c6a0d2cd8c198944f5c4b2718e27263be44f..fbbad6446741e53fc9a4e65ec74ffd793e2fc44d 100644 (file)
@@ -51,7 +51,6 @@ fsl,sgtl5000          SGTL5000: Ultra Low-Power Audio Codec
 gmt,g751               G751: Digital Temperature Sensor and Thermal Watchdog with Two-Wire Interface
 infineon,slb9635tt     Infineon SLB9635 (Soft-) I2C TPM (old protocol, max 100khz)
 infineon,slb9645tt     Infineon SLB9645 I2C TPM (new protocol, max 400khz)
-isil,isl12057          Intersil ISL12057 I2C RTC Chip
 isil,isl29028          Intersil ISL29028 Ambient Light and Proximity Sensor
 maxim,ds1050           5 Bit Programmable, Pulse-Width Modulator
 maxim,max1237          Low-Power, 4-/12-Channel, 2-Wire Serial, 12-Bit ADCs
index f97993be2dcbdc82dee8866e3510b18f6e121d54..d3b273e4336a72623263d9e62e50a9c39f45c178 100644 (file)
@@ -14,6 +14,7 @@ length of memory mapped region.
 representing a ethernet device.
 - dsaf-handle: phandle, specifies a reference to a node
 representing a dsaf device.
+- node_guid: a number that uniquely identifies a device or component
 - #address-cells: must be 2
 - #size-cells: must be 2
 Optional properties:
@@ -32,6 +33,7 @@ Example:
                        dma-coherent;
                        eth-handle = <&eth2 &eth3 &eth4 &eth5 &eth6 &eth7>;
                        dsaf-handle = <&soc0_dsa>;
+                       node-guid = [00 9A CD 00 00 01 02 03];
                        #address-cells = <2>;
                        #size-cells = <2>;
                        interrupt-parent = <&mbigen_dsa>;
diff --git a/Documentation/devicetree/bindings/input/touchscreen/melfas_mip4.txt b/Documentation/devicetree/bindings/input/touchscreen/melfas_mip4.txt
new file mode 100644 (file)
index 0000000..7b8944c
--- /dev/null
@@ -0,0 +1,21 @@
+* MELFAS MIP4 Touchscreen
+
+Required properties:
+- compatible: must be "melfas,mip4_ts"
+- reg: I2C slave address of the chip (0x48 or 0x34)
+- interrupt-parent: interrupt controller to which the chip is connected
+- interrupts: interrupt to which the chip is connected
+
+Optional properties:
+- ce-gpios: GPIO connected to the CE (chip enable) pin of the chip
+
+Example:
+       i2c@00000000 {
+               touchscreen: melfas_mip4@48 {
+                       compatible = "melfas,mip4_ts";
+                       reg = <0x48>;
+                       interrupt-parent = <&gpio>;
+                       interrupts = <0 IRQ_TYPE_EDGE_FALLING>;
+                       ce-gpios = <&gpio 0 GPIO_ACTIVE_HIGH>;
+               };
+       };
index 8e76f26487966b40d3041b948624b91bfacfe883..9882b819f173f3277e55b73cbbcffa4b89f4e1cc 100644 (file)
@@ -11,7 +11,7 @@ Optional properties:
 - trickle-diode-disable : Do not use internal trickle charger diode
        Should be given if internal trickle charger diode should be disabled
 Example:
-       ds1390: rtc@68 {
+       ds1390: rtc@0 {
                compatible = "dallas,ds1390";
                trickle-resistor-ohms = <250>;
                reg = <0>;
diff --git a/Documentation/devicetree/bindings/rtc/epson,rx8900.txt b/Documentation/devicetree/bindings/rtc/epson,rx8900.txt
new file mode 100644 (file)
index 0000000..3f61e51
--- /dev/null
@@ -0,0 +1,22 @@
+Real Time Clock driver for:
+  - Epson RX8900
+  - Micro Crystal rv8803
+
+Required properties:
+- compatible: should be: "microcrystal,rv8803" or "epson,rx8900"
+- reg : the I2C address of the device for I2C
+
+Optional properties:
+- epson,vdet-disable : boolean, if present will disable voltage detector.
+  Should be set if no backup battery is used.
+- trickle-diode-disable : boolean, if present will disable internal trickle
+  charger diode
+
+Example:
+
+       rtc: rtc@32 {
+               compatible = "epson,rx8900"
+               reg = <0x32>;
+               epson,vdet-disable;
+               trickle-diode-disable;
+       };
index bf7d11ae9bea68f107936211d8256203f89a6157..bee41f97044e11606bc451c8fa29b0b49c2b202a 100644 (file)
@@ -18,6 +18,18 @@ Optional properties:
   through pmic_power_en
 - clocks: Any internal or external clocks feeding in to rtc
 - clock-names: Corresponding names of the clocks
+- pinctrl-0: a phandle pointing to the pin settings for the device
+- pinctrl-names: should be "default"
+
+Optional subnodes:
+- generic pinctrl node
+
+Required pinctrl subnodes properties:
+- pins - Names of ext_wakeup pins to configure
+
+Optional pinctrl subnodes properties:
+- input-enable - Enables ext_wakeup
+- ti,active-high - Set input active high (by default active low)
 
 Example:
 
@@ -30,4 +42,13 @@ rtc@1c23000 {
        system-power-controller;
        clocks = <&clk_32k_rtc>, <&clk_32768_ck>;
        clock-names = "ext-clk", "int-clk";
+
+       pinctrl-0 = <&ext_wakeup>;
+       pinctrl-names = "default";
+
+       ext_wakeup: ext-wakeup {
+               pins = "ext_wakeup0";
+               input-enable;
+               ti,active-high;
+       };
 };
index 24c6f658bce147162d92f2009c1a4d319c490be3..f0a48ea78659c933839554ca879babb1b621b264 100644 (file)
@@ -163,9 +163,11 @@ maxim      Maxim Integrated Products
 meas   Measurement Specialties
 mediatek       MediaTek Inc.
 melexis        Melexis N.V.
+melfas MELFAS Inc.
 merrii Merrii Technology Co., Ltd.
 micrel Micrel Inc.
 microchip      Microchip Technology Inc.
+microcrystal   Micro Crystal AG
 micron Micron Technology Inc.
 minix  MINIX Technology Ltd.
 mitsubishi     Mitsubishi Electric Corporation
index 1fec1135791d98c987105872c63b5e96589633d3..8d1341ccde6498bebc534bcd7c1ef4560560a96f 100644 (file)
@@ -319,3 +319,60 @@ For touchpad packet, the format is:
                otherwise byte 0 bit 4 must be set and byte 0/4/5 are
                in NEW fmt
  F:         Number of fingers - 3, 0 means 3 fingers, 1 means 4 ...
+
+
+ALPS Absolute Mode - Protocol Version 8
+---------------------------------------
+
+Spoken by SS4 (73 03 14) and SS5 (73 03 28) hardware.
+
+The packet type is given by the APD field, bits 4-5 of byte 3.
+
+Touchpad packet (APD = 0x2):
+
+           b7   b6   b5   b4   b3   b2   b1   b0
+ byte 0:  SWM  SWR  SWL    1    1    0    0   X7
+ byte 1:    0   X6   X5   X4   X3   X2   X1   X0
+ byte 2:    0   Y6   Y5   Y4   Y3   Y2   Y1   Y0
+ byte 3:    0  T&P    1    0    1    0    0   Y7
+ byte 4:    0   Z6   Z5   Z4   Z3   Z2   Z1   Z0
+ byte 5:    0    0    0    0    0    0    0    0
+
+SWM, SWR, SWL: Middle, Right, and Left button states
+
+Touchpad 1 Finger packet (APD = 0x0):
+
+           b7   b6   b5   b4   b3   b2   b1   b0
+ byte 0:  SWM  SWR  SWL    1    1   X2   X1   X0
+ byte 1:   X9   X8   X7    1   X6   X5   X4   X3
+ byte 2:    0  X11  X10  LFB   Y3   Y2   Y1   Y0
+ byte 3:   Y5   Y4    0    0    1 TAPF2 TAPF1 TAPF0
+ byte 4:  Zv7  Y11  Y10    1   Y9   Y8   Y7   Y6
+ byte 5:  Zv6  Zv5  Zv4    0  Zv3  Zv2  Zv1  Zv0
+
+TAPF: ???
+LFB:  ???
+
+Touchpad 2 Finger packet (APD = 0x1):
+
+           b7   b6   b5   b4   b3   b2   b1   b0
+ byte 0:  SWM  SWR  SWL    1    1  AX6  AX5  AX4
+ byte 1: AX11 AX10  AX9  AX8  AX7  AZ1  AY4  AZ0
+ byte 2: AY11 AY10  AY9  CONT AY8  AY7  AY6  AY5
+ byte 3:    0    0    0    1    1  BX6  BX5  BX4
+ byte 4: BX11 BX10  BX9  BX8  BX7  BZ1  BY4  BZ0
+ byte 5: BY11 BY10  BY9    0  BY8  BY7  BY5  BY5
+
+CONT: A 3-or-4 Finger packet is to follow
+
+Touchpad 3-or-4 Finger packet (APD = 0x3):
+
+           b7   b6   b5   b4   b3   b2   b1   b0
+ byte 0:  SWM  SWR  SWL    1    1  AX6  AX5  AX4
+ byte 1: AX11 AX10  AX9  AX8  AX7  AZ1  AY4  AZ0
+ byte 2: AY11 AY10  AY9  OVF  AY8  AY7  AY6  AY5
+ byte 3:    0    0    1    1    1  BX6  BX5  BX4
+ byte 4: BX11 BX10  BX9  BX8  BX7  BZ1  BY4  BZ0
+ byte 5: BY11 BY10  BY9    0  BY8  BY7  BY5  BY5
+
+OVF: 5th finger detected
index 58f3c10417593eca0ec09c7ae1686d44b61b105b..37babf91f2cb6de20e0b1a66843d1636d65c71fb 100644 (file)
@@ -1511,7 +1511,14 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
        i8042.nopnp     [HW] Don't use ACPIPnP / PnPBIOS to discover KBD/AUX
                             controllers
        i8042.notimeout [HW] Ignore timeout condition signalled by controller
-       i8042.reset     [HW] Reset the controller during init and cleanup
+       i8042.reset     [HW] Reset the controller during init, cleanup and
+                            suspend-to-ram transitions, only during s2r
+                            transitions, or never reset
+                       Format: { 1 | Y | y | 0 | N | n }
+                       1, Y, y: always reset controller
+                       0, N, n: don't ever reset controller
+                       Default: only on s2r transitions on x86; most other
+                       architectures force reset to be always executed
        i8042.unlock    [HW] Unlock (ignore) the keylock
        i8042.kbdreset  [HW] Reset device connected to KBD port
 
index fd880150aeead89920e75758f7194a1ae48eee2d..e2c187947e588d6146c464852e07735966f95145 100644 (file)
@@ -21,16 +21,6 @@ NCR53c400 card, the Trantor T130B in its default configuration:
 The NCR53c400 does not support DMA but it does have Pseudo-DMA which is
 supported by the driver.
 
-If the default configuration does not work for you, you can use the kernel
-command lines (eg using the lilo append command):
-       ncr5380=addr,irq
-       ncr53c400=addr,irq
-       ncr53c400a=addr,irq
-       dtc3181e=addr,irq
-
-The driver does not probe for any addresses or ports other than those in
-the OVERRIDE or given to the kernel as above.
-
 This driver provides some information on what it has detected in
 /proc/scsi/g_NCR5380/x where x is the scsi card number as detected at boot
 time. More info to come in the future.
@@ -38,6 +28,16 @@ time. More info to come in the future.
 This driver works as a module.
 When included as a module, parameters can be passed on the insmod/modprobe
 command line:
+  irq=xx[,...] the interrupt(s)
+  base=xx[,...]        the port or base address(es) (for port or memory mapped, resp.)
+  card=xx[,...]        card type(s):
+               0 = NCR5380,
+               1 = NCR53C400,
+               2 = NCR53C400A,
+               3 = Domex Technology Corp 3181E (DTC3181E)
+               4 = Hewlett Packard C2502
+
+These old-style parameters can support only one card:
   ncr_irq=xx   the interrupt
   ncr_addr=xx  the port or base address (for port or memory
                mapped, resp.)
@@ -46,11 +46,19 @@ command line:
   ncr_53c400a=1 to set up for a NCR53C400A board
   dtc_3181e=1  to set up for a Domex Technology Corp 3181E board
   hp_c2502=1   to set up for a Hewlett Packard C2502 board
+
 e.g.
-modprobe g_NCR5380 ncr_irq=5 ncr_addr=0x350 ncr_5380=1
+OLD: modprobe g_NCR5380 ncr_irq=5 ncr_addr=0x350 ncr_5380=1
+NEW: modprobe g_NCR5380 irq=5 base=0x350 card=0
   for a port mapped NCR5380 board or
-modprobe g_NCR5380 ncr_irq=255 ncr_addr=0xc8000 ncr_53c400=1
-  for a memory mapped NCR53C400 board with interrupts disabled.
+
+OLD: modprobe g_NCR5380 ncr_irq=255 ncr_addr=0xc8000 ncr_53c400=1
+NEW: modprobe g_NCR5380 irq=255 base=0xc8000 card=1
+  for a memory mapped NCR53C400 board with interrupts disabled or
+
+NEW: modprobe g_NCR5380 irq=0,7 base=0x240,0x300 card=3,4
+  for two cards: DTC3181 (in non-PnP mode) at 0x240 with no IRQ
+             and HP C2502 at 0x300 with IRQ 7
 
 (255 should be specified for no or DMA interrupt, 254 to autoprobe for an 
      IRQ line if overridden on the command line.)
index a5ae0f21a8cb4fd317ec0ec514be106e35e25ba3..a452c404141dfc4607b6cf96bc600ddf7ca33b94 100644 (file)
@@ -316,6 +316,14 @@ W: https://01.org/linux-acpi
 S:     Supported
 F:     drivers/acpi/fan.c
 
+ACPI FOR ARM64 (ACPI/arm64)
+M:     Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
+M:     Hanjun Guo <hanjun.guo@linaro.org>
+M:     Sudeep Holla <sudeep.holla@arm.com>
+L:     linux-acpi@vger.kernel.org
+S:     Maintained
+F:     drivers/acpi/arm64
+
 ACPI THERMAL DRIVER
 M:     Zhang Rui <rui.zhang@intel.com>
 L:     linux-acpi@vger.kernel.org
@@ -6620,10 +6628,10 @@ S:      Maintained
 F:     drivers/firmware/iscsi_ibft*
 
 ISCSI
-M:     Mike Christie <michaelc@cs.wisc.edu>
+M:     Lee Duncan <lduncan@suse.com>
+M:     Chris Leech <cleech@redhat.com>
 L:     open-iscsi@googlegroups.com
-W:     www.open-iscsi.org
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/mnc/linux-2.6-iscsi.git
+W:     www.open-iscsi.com
 S:     Maintained
 F:     drivers/scsi/*iscsi*
 F:     include/scsi/*iscsi*
@@ -7821,6 +7829,13 @@ F:       Documentation/scsi/megaraid.txt
 F:     drivers/scsi/megaraid.*
 F:     drivers/scsi/megaraid/
 
+MELFAS MIP4 TOUCHSCREEN DRIVER
+M:     Sangwon Jee <jeesw@melfas.com>
+W:     http://www.melfas.com
+S:     Supported
+F:     drivers/input/touchscreen/melfas_mip4.c
+F:     Documentation/devicetree/bindings/input/touchscreen/melfas_mip4.txt
+
 MELLANOX ETHERNET DRIVER (mlx4_en)
 M:     Tariq Toukan <tariqt@mellanox.com>
 L:     netdev@vger.kernel.org
index 58635f7f4668abbc8ebfd52ba96abafe63d817db..220ac7057d1284fa97d5ccf1787e09a2aafd60a4 100644 (file)
                };
 
                sata: sata@3200000 {
-                       compatible = "fsl,ls1043a-ahci", "fsl,ls1021a-ahci";
+                       compatible = "fsl,ls1043a-ahci";
                        reg = <0x0 0x3200000 0x0 0x10000>;
                        interrupts = <0 69 0x4>;
                        clocks = <&clockgen 4 0>;
+                       dma-coherent;
                };
 
                msi1: msi-controller1@1571000 {
index d1059765dfee4ac41831ff5faf1f2d71df9fc241..337da90bd7dade6df0d74d49a9794b6b20cc8510 100644 (file)
                        reg = <0x0 0x3200000 0x0 0x10000>;
                        interrupts = <0 133 0x4>; /* Level high type */
                        clocks = <&clockgen 4 3>;
+                       dma-coherent;
                };
 
                sata1: sata@3210000 {
                        reg = <0x0 0x3210000 0x0 0x10000>;
                        interrupts = <0 136 0x4>; /* Level high type */
                        clocks = <&clockgen 4 3>;
+                       dma-coherent;
                };
 
                usb0: usb3@3100000 {
index 0e00c9a9f4100b48e0302c13c43c90962c38d631..7a1f8310596bede26f78d60a2bee0a4ac97a9242 100644 (file)
@@ -1,12 +1,8 @@
 #ifndef __ASM_IA64_LIBATA_PORTMAP_H
 #define __ASM_IA64_LIBATA_PORTMAP_H
 
-#define ATA_PRIMARY_CMD                0x1F0
-#define ATA_PRIMARY_CTL                0x3F6
 #define ATA_PRIMARY_IRQ(dev)   isa_irq_to_vector(14)
 
-#define ATA_SECONDARY_CMD      0x170
-#define ATA_SECONDARY_CTL      0x376
 #define ATA_SECONDARY_IRQ(dev) isa_irq_to_vector(15)
 
 #endif
index 4d8518049f4df569a24a10437afd3aff1c2df873..4396db57b8be19bbe12377c6c6babc6a99c6b6e8 100644 (file)
@@ -1,12 +1,8 @@
 #ifndef __ASM_POWERPC_LIBATA_PORTMAP_H
 #define __ASM_POWERPC_LIBATA_PORTMAP_H
 
-#define ATA_PRIMARY_CMD        0x1F0
-#define ATA_PRIMARY_CTL        0x3F6
 #define ATA_PRIMARY_IRQ(dev)   pci_get_legacy_ide_irq(dev, 0)
 
-#define ATA_SECONDARY_CMD      0x170
-#define ATA_SECONDARY_CTL      0x376
 #define ATA_SECONDARY_IRQ(dev) pci_get_legacy_ide_irq(dev, 1)
 
 #endif
index e02e3f80d363bbb87d8db6c74b2a0d5370818419..84f58de08c2bdbff7ce98119ff2e360d7d5175a1 100644 (file)
@@ -521,7 +521,8 @@ do {                                                                        \
 static __always_inline bool x86_this_cpu_constant_test_bit(unsigned int nr,
                         const unsigned long __percpu *addr)
 {
-       unsigned long __percpu *a = (unsigned long *)addr + nr / BITS_PER_LONG;
+       unsigned long __percpu *a =
+               (unsigned long __percpu *)addr + nr / BITS_PER_LONG;
 
 #ifdef CONFIG_X86_64
        return ((1UL << (nr % BITS_PER_LONG)) & raw_cpu_read_8(*a)) != 0;
@@ -538,7 +539,7 @@ static inline bool x86_this_cpu_variable_test_bit(int nr,
        asm volatile("bt "__percpu_arg(2)",%1\n\t"
                        CC_SET(c)
                        : CC_OUT(c) (oldbit)
-                       : "m" (*(unsigned long *)addr), "Ir" (nr));
+                       : "m" (*(unsigned long __percpu *)addr), "Ir" (nr));
 
        return oldbit;
 }
index dd38e5ced4a3fa7510f00c2ee7ff9dc636b2a7fc..b08ccbb9393a75800a3299f90537f6ee881b00f0 100644 (file)
@@ -1340,10 +1340,8 @@ int blkcg_policy_register(struct blkcg_policy *pol)
                        struct blkcg_policy_data *cpd;
 
                        cpd = pol->cpd_alloc_fn(GFP_KERNEL);
-                       if (!cpd) {
-                               mutex_unlock(&blkcg_pol_mutex);
+                       if (!cpd)
                                goto err_free_cpds;
-                       }
 
                        blkcg->cpd[pol->plid] = cpd;
                        cpd->blkcg = blkcg;
index 8ea8211b2d589c6618d5037e40d653a3771edc55..eb76a4c10dbfb170e43680d8b3f836bec169ad01 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/slab.h>
 #include <linux/acpi.h>
 #include <asm/mwait.h>
+#include <xen/xen.h>
 
 #define ACPI_PROCESSOR_AGGREGATOR_CLASS        "acpi_pad"
 #define ACPI_PROCESSOR_AGGREGATOR_DEVICE_NAME "Processor Aggregator"
@@ -477,6 +478,10 @@ static struct acpi_driver acpi_pad_driver = {
 
 static int __init acpi_pad_init(void)
 {
+       /* Xen ACPI PAD is used when running as Xen Dom0. */
+       if (xen_initial_domain())
+               return -ENODEV;
+
        power_saving_mwait_init();
        if (power_saving_mwait_eax == 0)
                return -EINVAL;
index 6805310621607335a2cf14763acc48f629d3ba31..48e19d013170936ef494d0fa88d275d37f25071a 100644 (file)
@@ -526,6 +526,7 @@ static void acpi_ec_enable_event(struct acpi_ec *ec)
                acpi_ec_clear(ec);
 }
 
+#ifdef CONFIG_PM_SLEEP
 static bool acpi_ec_query_flushed(struct acpi_ec *ec)
 {
        bool flushed;
@@ -557,6 +558,7 @@ static void acpi_ec_disable_event(struct acpi_ec *ec)
        spin_unlock_irqrestore(&ec->lock, flags);
        __acpi_ec_flush_event(ec);
 }
+#endif /* CONFIG_PM_SLEEP */
 
 static bool acpi_ec_guard_event(struct acpi_ec *ec)
 {
index 384cfc3083e1d98c544918b49ec517a9399c27a3..6cf4988206f24e8292099ae7141914ced024affd 100644 (file)
@@ -129,8 +129,18 @@ static int fan_get_state_acpi4(struct acpi_device *device, unsigned long *state)
 
        control = obj->package.elements[1].integer.value;
        for (i = 0; i < fan->fps_count; i++) {
-               if (control == fan->fps[i].control)
+               /*
+                * When Fine Grain Control is set, return the state
+                * corresponding to maximum fan->fps[i].control
+                * value compared to the current speed. Here the
+                * fan->fps[] is sorted array with increasing speed.
+                */
+               if (fan->fif.fine_grain_ctrl && control < fan->fps[i].control) {
+                       i = (i > 0) ? i - 1 : 0;
                        break;
+               } else if (control == fan->fps[i].control) {
+                       break;
+               }
        }
        if (i == fan->fps_count) {
                dev_dbg(&device->dev, "Invalid control value returned\n");
index 4305ee9db4b2d880faaf6314cde028546b5207a6..416953a4251094ce2066d724c1d88583b8e89705 100644 (file)
@@ -162,11 +162,18 @@ void acpi_os_vprintf(const char *fmt, va_list args)
        if (acpi_in_debugger) {
                kdb_printf("%s", buffer);
        } else {
-               printk(KERN_CONT "%s", buffer);
+               if (printk_get_level(buffer))
+                       printk("%s", buffer);
+               else
+                       printk(KERN_CONT "%s", buffer);
        }
 #else
-       if (acpi_debugger_write_log(buffer) < 0)
-               printk(KERN_CONT "%s", buffer);
+       if (acpi_debugger_write_log(buffer) < 0) {
+               if (printk_get_level(buffer))
+                       printk("%s", buffer);
+               else
+                       printk(KERN_CONT "%s", buffer);
+       }
 #endif
 }
 
index f2fd3fee588a8233a80bdc5da3549fea5703b9f8..03f5ec11ab3197de66ced4e7f09d39dbab6b8232 100644 (file)
@@ -468,10 +468,11 @@ static int acpi_data_get_property_array(struct acpi_device_data *data,
 }
 
 /**
- * acpi_data_get_property_reference - returns handle to the referenced object
- * @data: ACPI device data object containing the property
+ * __acpi_node_get_property_reference - returns handle to the referenced object
+ * @fwnode: Firmware node to get the property from
  * @propname: Name of the property
  * @index: Index of the reference to return
+ * @num_args: Maximum number of arguments after each reference
  * @args: Location to store the returned reference with optional arguments
  *
  * Find property with @name, verifify that it is a package containing at least
@@ -482,17 +483,40 @@ static int acpi_data_get_property_array(struct acpi_device_data *data,
  * If there's more than one reference in the property value package, @index is
  * used to select the one to return.
  *
+ * It is possible to leave holes in the property value set like in the
+ * example below:
+ *
+ * Package () {
+ *     "cs-gpios",
+ *     Package () {
+ *        ^GPIO, 19, 0, 0,
+ *        ^GPIO, 20, 0, 0,
+ *        0,
+ *        ^GPIO, 21, 0, 0,
+ *     }
+ * }
+ *
+ * Calling this function with index %2 return %-ENOENT and with index %3
+ * returns the last entry. If the property does not contain any more values
+ * %-ENODATA is returned. The NULL entry must be single integer and
+ * preferably contain value %0.
+ *
  * Return: %0 on success, negative error code on failure.
  */
-static int acpi_data_get_property_reference(struct acpi_device_data *data,
-                                           const char *propname, size_t index,
-                                           struct acpi_reference_args *args)
+int __acpi_node_get_property_reference(struct fwnode_handle *fwnode,
+       const char *propname, size_t index, size_t num_args,
+       struct acpi_reference_args *args)
 {
        const union acpi_object *element, *end;
        const union acpi_object *obj;
+       struct acpi_device_data *data;
        struct acpi_device *device;
        int ret, idx = 0;
 
+       data = acpi_device_data_of_node(fwnode);
+       if (!data)
+               return -EINVAL;
+
        ret = acpi_data_get_property(data, propname, ACPI_TYPE_ANY, &obj);
        if (ret)
                return ret;
@@ -532,59 +556,54 @@ static int acpi_data_get_property_reference(struct acpi_device_data *data,
        while (element < end) {
                u32 nargs, i;
 
-               if (element->type != ACPI_TYPE_LOCAL_REFERENCE)
-                       return -EPROTO;
-
-               ret = acpi_bus_get_device(element->reference.handle, &device);
-               if (ret)
-                       return -ENODEV;
-
-               element++;
-               nargs = 0;
-
-               /* assume following integer elements are all args */
-               for (i = 0; element + i < end; i++) {
-                       int type = element[i].type;
+               if (element->type == ACPI_TYPE_LOCAL_REFERENCE) {
+                       ret = acpi_bus_get_device(element->reference.handle,
+                                                 &device);
+                       if (ret)
+                               return -ENODEV;
+
+                       nargs = 0;
+                       element++;
+
+                       /* assume following integer elements are all args */
+                       for (i = 0; element + i < end && i < num_args; i++) {
+                               int type = element[i].type;
+
+                               if (type == ACPI_TYPE_INTEGER)
+                                       nargs++;
+                               else if (type == ACPI_TYPE_LOCAL_REFERENCE)
+                                       break;
+                               else
+                                       return -EPROTO;
+                       }
 
-                       if (type == ACPI_TYPE_INTEGER)
-                               nargs++;
-                       else if (type == ACPI_TYPE_LOCAL_REFERENCE)
-                               break;
-                       else
+                       if (nargs > MAX_ACPI_REFERENCE_ARGS)
                                return -EPROTO;
-               }
 
-               if (idx++ == index) {
-                       args->adev = device;
-                       args->nargs = nargs;
-                       for (i = 0; i < nargs; i++)
-                               args->args[i] = element[i].integer.value;
+                       if (idx == index) {
+                               args->adev = device;
+                               args->nargs = nargs;
+                               for (i = 0; i < nargs; i++)
+                                       args->args[i] = element[i].integer.value;
 
-                       return 0;
+                               return 0;
+                       }
+
+                       element += nargs;
+               } else if (element->type == ACPI_TYPE_INTEGER) {
+                       if (idx == index)
+                               return -ENOENT;
+                       element++;
+               } else {
+                       return -EPROTO;
                }
 
-               element += nargs;
+               idx++;
        }
 
-       return -EPROTO;
-}
-
-/**
- * acpi_node_get_property_reference - get a handle to the referenced object.
- * @fwnode: Firmware node to get the property from.
- * @propname: Name of the property.
- * @index: Index of the reference to return.
- * @args: Location to store the returned reference with optional arguments.
- */
-int acpi_node_get_property_reference(struct fwnode_handle *fwnode,
-                                    const char *name, size_t index,
-                                    struct acpi_reference_args *args)
-{
-       struct acpi_device_data *data = acpi_device_data_of_node(fwnode);
-
-       return data ? acpi_data_get_property_reference(data, name, index, args) : -EINVAL;
+       return -ENODATA;
 }
-EXPORT_SYMBOL_GPL(acpi_node_get_property_reference);
+EXPORT_SYMBOL_GPL(__acpi_node_get_property_reference);
 
 static int acpi_data_prop_read_single(struct acpi_device_data *data,
                                      const char *propname,
index 90eabaf812150dbfcff32e173f4c48f2cfcd801c..ba5f11cebee2a1ce6528116cdc9af25b7a25af44 100644 (file)
@@ -1400,142 +1400,56 @@ static irqreturn_t ahci_thunderx_irq_handler(int irq, void *dev_instance)
 }
 #endif
 
-/*
- * ahci_init_msix() - optionally enable per-port MSI-X otherwise defer
- * to single msi.
- */
-static int ahci_init_msix(struct pci_dev *pdev, unsigned int n_ports,
-                         struct ahci_host_priv *hpriv, unsigned long flags)
+static int ahci_get_irq_vector(struct ata_host *host, int port)
 {
-       int nvec, i, rc;
-
-       /* Do not init MSI-X if MSI is disabled for the device */
-       if (hpriv->flags & AHCI_HFLAG_NO_MSI)
-               return -ENODEV;
-
-       nvec = pci_msix_vec_count(pdev);
-       if (nvec < 0)
-               return nvec;
-
-       /*
-        * Proper MSI-X implementations will have a vector per-port.
-        * Barring that, we prefer single-MSI over single-MSIX.  If this
-        * check fails (not enough MSI-X vectors for all ports) we will
-        * be called again with the flag clear iff ahci_init_msi()
-        * fails.
-        */
-       if (flags & AHCI_HFLAG_MULTI_MSIX) {
-               if (nvec < n_ports)
-                       return -ENODEV;
-               nvec = n_ports;
-       } else if (nvec) {
-               nvec = 1;
-       } else {
-               /*
-                * Emit dev_err() since this was the non-legacy irq
-                * method of last resort.
-                */
-               rc = -ENODEV;
-               goto fail;
-       }
-
-       for (i = 0; i < nvec; i++)
-               hpriv->msix[i].entry = i;
-       rc = pci_enable_msix_exact(pdev, hpriv->msix, nvec);
-       if (rc < 0)
-               goto fail;
-
-       if (nvec > 1)
-               hpriv->flags |= AHCI_HFLAG_MULTI_MSIX;
-       hpriv->irq = hpriv->msix[0].vector; /* for single msi-x */
-
-       return nvec;
-fail:
-       dev_err(&pdev->dev,
-               "failed to enable MSI-X with error %d, # of vectors: %d\n",
-               rc, nvec);
-
-       return rc;
+       return pci_irq_vector(to_pci_dev(host->dev), port);
 }
 
 static int ahci_init_msi(struct pci_dev *pdev, unsigned int n_ports,
                        struct ahci_host_priv *hpriv)
 {
-       int rc, nvec;
+       int nvec;
 
        if (hpriv->flags & AHCI_HFLAG_NO_MSI)
                return -ENODEV;
 
-       nvec = pci_msi_vec_count(pdev);
-       if (nvec < 0)
-               return nvec;
-
        /*
         * If number of MSIs is less than number of ports then Sharing Last
         * Message mode could be enforced. In this case assume that advantage
         * of multipe MSIs is negated and use single MSI mode instead.
         */
-       if (nvec < n_ports)
-               goto single_msi;
-
-       rc = pci_enable_msi_exact(pdev, nvec);
-       if (rc == -ENOSPC)
-               goto single_msi;
-       if (rc < 0)
-               return rc;
+       nvec = pci_alloc_irq_vectors(pdev, n_ports, INT_MAX,
+                       PCI_IRQ_MSIX | PCI_IRQ_MSI);
+       if (nvec > 0) {
+               if (!(readl(hpriv->mmio + HOST_CTL) & HOST_MRSM)) {
+                       hpriv->get_irq_vector = ahci_get_irq_vector;
+                       hpriv->flags |= AHCI_HFLAG_MULTI_MSI;
+                       return nvec;
+               }
 
-       /* fallback to single MSI mode if the controller enforced MRSM mode */
-       if (readl(hpriv->mmio + HOST_CTL) & HOST_MRSM) {
-               pci_disable_msi(pdev);
+               /*
+                * Fallback to single MSI mode if the controller enforced MRSM
+                * mode.
+                */
                printk(KERN_INFO "ahci: MRSM is on, fallback to single MSI\n");
-               goto single_msi;
+               pci_free_irq_vectors(pdev);
        }
 
-       if (nvec > 1)
-               hpriv->flags |= AHCI_HFLAG_MULTI_MSI;
-
-       goto out;
-
-single_msi:
-       nvec = 1;
-
-       rc = pci_enable_msi(pdev);
-       if (rc < 0)
-               return rc;
-out:
-       hpriv->irq = pdev->irq;
-
-       return nvec;
-}
-
-static int ahci_init_interrupts(struct pci_dev *pdev, unsigned int n_ports,
-                               struct ahci_host_priv *hpriv)
-{
-       int nvec;
-
        /*
-        * Try to enable per-port MSI-X.  If the host is not capable
-        * fall back to single MSI before finally attempting single
-        * MSI-X.
+        * -ENOSPC indicated we don't have enough vectors.  Don't bother trying
+        * a single vectors for any other error:
         */
-       nvec = ahci_init_msix(pdev, n_ports, hpriv, AHCI_HFLAG_MULTI_MSIX);
-       if (nvec >= 0)
+       if (nvec < 0 && nvec != -ENOSPC)
                return nvec;
 
-       nvec = ahci_init_msi(pdev, n_ports, hpriv);
-       if (nvec >= 0)
-               return nvec;
-
-       /* try single-msix */
-       nvec = ahci_init_msix(pdev, n_ports, hpriv, 0);
-       if (nvec >= 0)
+       /*
+        * If the host is not capable of supporting per-port vectors, fall
+        * back to single MSI before finally attempting single MSI-X.
+        */
+       nvec = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_MSI);
+       if (nvec == 1)
                return nvec;
-
-       /* legacy intx interrupts */
-       pci_intx(pdev, 1);
-       hpriv->irq = pdev->irq;
-
-       return 0;
+       return pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_MSIX);
 }
 
 static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
@@ -1698,11 +1612,12 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
        if (!host)
                return -ENOMEM;
        host->private_data = hpriv;
-       hpriv->msix = devm_kzalloc(&pdev->dev,
-                       sizeof(struct msix_entry) * n_ports, GFP_KERNEL);
-       if (!hpriv->msix)
-               return -ENOMEM;
-       ahci_init_interrupts(pdev, n_ports, hpriv);
+
+       if (ahci_init_msi(pdev, n_ports, hpriv) < 0) {
+               /* legacy intx interrupts */
+               pci_intx(pdev, 1);
+       }
+       hpriv->irq = pdev->irq;
 
        if (!(hpriv->cap & HOST_CAP_SSS) || ahci_ignore_sss)
                host->flags |= ATA_HOST_PARALLEL_SCAN;
index 70b06bcfb7e3535b47e02a913da680f67595888e..0cc08f892feaeeacf1915df8588d236e32e8960d 100644 (file)
@@ -242,12 +242,10 @@ enum {
        AHCI_HFLAG_NO_FBS               = (1 << 18), /* no FBS */
 
 #ifdef CONFIG_PCI_MSI
-       AHCI_HFLAG_MULTI_MSI            = (1 << 20), /* multiple PCI MSIs */
-       AHCI_HFLAG_MULTI_MSIX           = (1 << 21), /* per-port MSI-X */
+       AHCI_HFLAG_MULTI_MSI            = (1 << 20), /* per-port MSI(-X) */
 #else
        /* compile out MSI infrastructure */
        AHCI_HFLAG_MULTI_MSI            = 0,
-       AHCI_HFLAG_MULTI_MSIX           = 0,
 #endif
        AHCI_HFLAG_WAKE_BEFORE_STOP     = (1 << 22), /* wake before DMA stop */
 
@@ -351,7 +349,6 @@ struct ahci_host_priv {
         * the PHY position in this array.
         */
        struct phy              **phys;
-       struct msix_entry       *msix;          /* Optional MSI-X support */
        unsigned                nports;         /* Number of ports */
        void                    *plat_data;     /* Other platform data */
        unsigned int            irq;            /* interrupt line */
@@ -362,22 +359,11 @@ struct ahci_host_priv {
         */
        void                    (*start_engine)(struct ata_port *ap);
        irqreturn_t             (*irq_handler)(int irq, void *dev_instance);
-};
 
-#ifdef CONFIG_PCI_MSI
-static inline int ahci_irq_vector(struct ahci_host_priv *hpriv, int port)
-{
-       if (hpriv->flags & AHCI_HFLAG_MULTI_MSIX)
-               return hpriv->msix[port].vector;
-       else
-               return hpriv->irq + port;
-}
-#else
-static inline int ahci_irq_vector(struct ahci_host_priv *hpriv, int port)
-{
-       return hpriv->irq;
-}
-#endif
+       /* only required for per-port MSI(-X) support */
+       int                     (*get_irq_vector)(struct ata_host *host,
+                                                 int port);
+};
 
 extern int ahci_ignore_sss;
 
index 7bdee9bd8786638049c51d952520f2fe298df694..1eba8dff875eb6d45566779baab68aef4ba412e2 100644 (file)
 #define PORT_PHY3      0xB0
 #define PORT_PHY4      0xB4
 #define PORT_PHY5      0xB8
+#define PORT_AXICC     0xBC
 #define PORT_TRANS     0xC8
 
 /* port register default value */
 #define AHCI_PORT_PHY_1_CFG    0xa003fffe
 #define AHCI_PORT_TRANS_CFG    0x08000029
+#define AHCI_PORT_AXICC_CFG    0x3fffffff
 
 /* for ls1021a */
 #define LS1021A_PORT_PHY2      0x28183414
 #define LS1021A_PORT_PHY3      0x0e080e06
 #define LS1021A_PORT_PHY4      0x064a080b
 #define LS1021A_PORT_PHY5      0x2aa86470
+#define LS1021A_AXICC_ADDR     0xC0
 
 #define SATA_ECC_DISABLE       0x00020000
 
-/* for ls1043a */
-#define LS1043A_PORT_PHY2      0x28184d1f
-#define LS1043A_PORT_PHY3      0x0e081509
-
 enum ahci_qoriq_type {
        AHCI_LS1021A,
        AHCI_LS1043A,
@@ -137,7 +136,7 @@ static struct ata_port_operations ahci_qoriq_ops = {
        .hardreset      = ahci_qoriq_hardreset,
 };
 
-static struct ata_port_info ahci_qoriq_port_info = {
+static const struct ata_port_info ahci_qoriq_port_info = {
        .flags          = AHCI_FLAG_COMMON | ATA_FLAG_NCQ,
        .pio_mask       = ATA_PIO4,
        .udma_mask      = ATA_UDMA6,
@@ -162,18 +161,19 @@ static int ahci_qoriq_phy_init(struct ahci_host_priv *hpriv)
                writel(LS1021A_PORT_PHY4, reg_base + PORT_PHY4);
                writel(LS1021A_PORT_PHY5, reg_base + PORT_PHY5);
                writel(AHCI_PORT_TRANS_CFG, reg_base + PORT_TRANS);
+               writel(AHCI_PORT_AXICC_CFG, reg_base + LS1021A_AXICC_ADDR);
                break;
 
        case AHCI_LS1043A:
                writel(AHCI_PORT_PHY_1_CFG, reg_base + PORT_PHY1);
-               writel(LS1043A_PORT_PHY2, reg_base + PORT_PHY2);
-               writel(LS1043A_PORT_PHY3, reg_base + PORT_PHY3);
                writel(AHCI_PORT_TRANS_CFG, reg_base + PORT_TRANS);
+               writel(AHCI_PORT_AXICC_CFG, reg_base + PORT_AXICC);
                break;
 
        case AHCI_LS2080A:
                writel(AHCI_PORT_PHY_1_CFG, reg_base + PORT_PHY1);
                writel(AHCI_PORT_TRANS_CFG, reg_base + PORT_TRANS);
+               writel(AHCI_PORT_AXICC_CFG, reg_base + PORT_AXICC);
                break;
        }
 
@@ -221,12 +221,6 @@ static int ahci_qoriq_probe(struct platform_device *pdev)
        if (rc)
                goto disable_resources;
 
-       /* Workaround for ls2080a */
-       if (qoriq_priv->type == AHCI_LS2080A) {
-               hpriv->flags |= AHCI_HFLAG_NO_NCQ;
-               ahci_qoriq_port_info.flags &= ~ATA_FLAG_NCQ;
-       }
-
        rc = ahci_platform_init_host(pdev, hpriv, &ahci_qoriq_port_info,
                                     &ahci_qoriq_sht);
        if (rc)
index 8ff428fe8e0fa00659218f58f041cf948ae8327c..bc345f24955531fba69e36e1bc0233da3bb6fc88 100644 (file)
@@ -147,6 +147,7 @@ static struct scsi_host_template ahci_platform_sht = {
 
 static int st_ahci_probe(struct platform_device *pdev)
 {
+       struct device *dev = &pdev->dev;
        struct st_ahci_drv_data *drv_data;
        struct ahci_host_priv *hpriv;
        int err;
@@ -170,6 +171,9 @@ static int st_ahci_probe(struct platform_device *pdev)
 
        st_ahci_configure_oob(hpriv->mmio);
 
+       of_property_read_u32(dev->of_node,
+                            "ports-implemented", &hpriv->force_port_map);
+
        err = ahci_platform_init_host(pdev, hpriv, &st_ahci_port_info,
                                      &ahci_platform_sht);
        if (err) {
index dcf2c724fd066c33cf74a3f502d2ae6ba3d276bc..0d028ead99e85b632d1802af0f438287bc5a7c54 100644 (file)
@@ -2520,7 +2520,7 @@ static int ahci_host_activate_multi_irqs(struct ata_host *host,
         */
        for (i = 0; i < host->n_ports; i++) {
                struct ahci_port_priv *pp = host->ports[i]->private_data;
-               int irq = ahci_irq_vector(hpriv, i);
+               int irq = hpriv->get_irq_vector(host, i);
 
                /* Do not receive interrupts sent by dummy ports */
                if (!pp) {
@@ -2556,10 +2556,15 @@ int ahci_host_activate(struct ata_host *host, struct scsi_host_template *sht)
        int irq = hpriv->irq;
        int rc;
 
-       if (hpriv->flags & (AHCI_HFLAG_MULTI_MSI | AHCI_HFLAG_MULTI_MSIX)) {
+       if (hpriv->flags & AHCI_HFLAG_MULTI_MSI) {
                if (hpriv->irq_handler)
                        dev_warn(host->dev,
                                 "both AHCI_HFLAG_MULTI_MSI flag set and custom irq handler implemented\n");
+               if (!hpriv->get_irq_vector) {
+                       dev_err(host->dev,
+                               "AHCI_HFLAG_MULTI_MSI requires ->get_irq_vector!\n");
+                       return -EIO;
+               }
 
                rc = ahci_host_activate_multi_irqs(host, sht);
        } else {
index e207b33e4ce9d602ca5d72144a7332c91f2515c9..9cceb4a875a58caa19fdd809ad82181f22676fc2 100644 (file)
@@ -1159,8 +1159,6 @@ static void ata_scsi_sdev_config(struct scsi_device *sdev)
 {
        sdev->use_10_for_rw = 1;
        sdev->use_10_for_ms = 1;
-       sdev->no_report_opcodes = 1;
-       sdev->no_write_same = 1;
 
        /* Schedule policy is determined by ->qc_defer() callback and
         * it needs to see every deferred qc.  Set dev_blocked to 1 to
@@ -3282,18 +3280,125 @@ static unsigned int ata_scsi_pass_thru(struct ata_queued_cmd *qc)
        return 1;
 }
 
+/**
+ * ata_format_dsm_trim_descr() - SATL Write Same to DSM Trim
+ * @cmd: SCSI command being translated
+ * @trmax: Maximum number of entries that will fit in sector_size bytes.
+ * @sector: Starting sector
+ * @count: Total Range of request in logical sectors
+ *
+ * Rewrite the WRITE SAME descriptor to be a DSM TRIM little-endian formatted
+ * descriptor.
+ *
+ * Upto 64 entries of the format:
+ *   63:48 Range Length
+ *   47:0  LBA
+ *
+ *  Range Length of 0 is ignored.
+ *  LBA's should be sorted order and not overlap.
+ *
+ * NOTE: this is the same format as ADD LBA(S) TO NV CACHE PINNED SET
+ *
+ * Return: Number of bytes copied into sglist.
+ */
+static size_t ata_format_dsm_trim_descr(struct scsi_cmnd *cmd, u32 trmax,
+                                       u64 sector, u32 count)
+{
+       struct scsi_device *sdp = cmd->device;
+       size_t len = sdp->sector_size;
+       size_t r;
+       __le64 *buf;
+       u32 i = 0;
+       unsigned long flags;
+
+       WARN_ON(len > ATA_SCSI_RBUF_SIZE);
+
+       if (len > ATA_SCSI_RBUF_SIZE)
+               len = ATA_SCSI_RBUF_SIZE;
+
+       spin_lock_irqsave(&ata_scsi_rbuf_lock, flags);
+       buf = ((void *)ata_scsi_rbuf);
+       memset(buf, 0, len);
+       while (i < trmax) {
+               u64 entry = sector |
+                       ((u64)(count > 0xffff ? 0xffff : count) << 48);
+               buf[i++] = __cpu_to_le64(entry);
+               if (count <= 0xffff)
+                       break;
+               count -= 0xffff;
+               sector += 0xffff;
+       }
+       r = sg_copy_from_buffer(scsi_sglist(cmd), scsi_sg_count(cmd), buf, len);
+       spin_unlock_irqrestore(&ata_scsi_rbuf_lock, flags);
+
+       return r;
+}
+
+/**
+ * ata_format_dsm_trim_descr() - SATL Write Same to ATA SCT Write Same
+ * @cmd: SCSI command being translated
+ * @lba: Starting sector
+ * @num: Number of sectors to be zero'd.
+ *
+ * Rewrite the WRITE SAME payload to be an SCT Write Same formatted
+ * descriptor.
+ * NOTE: Writes a pattern (0's) in the foreground.
+ *
+ * Return: Number of bytes copied into sglist.
+ */
+static size_t ata_format_sct_write_same(struct scsi_cmnd *cmd, u64 lba, u64 num)
+{
+       struct scsi_device *sdp = cmd->device;
+       size_t len = sdp->sector_size;
+       size_t r;
+       u16 *buf;
+       unsigned long flags;
+
+       spin_lock_irqsave(&ata_scsi_rbuf_lock, flags);
+       buf = ((void *)ata_scsi_rbuf);
+
+       put_unaligned_le16(0x0002,  &buf[0]); /* SCT_ACT_WRITE_SAME */
+       put_unaligned_le16(0x0101,  &buf[1]); /* WRITE PTRN FG */
+       put_unaligned_le64(lba,     &buf[2]);
+       put_unaligned_le64(num,     &buf[6]);
+       put_unaligned_le32(0u,      &buf[10]); /* pattern */
+
+       WARN_ON(len > ATA_SCSI_RBUF_SIZE);
+
+       if (len > ATA_SCSI_RBUF_SIZE)
+               len = ATA_SCSI_RBUF_SIZE;
+
+       r = sg_copy_from_buffer(scsi_sglist(cmd), scsi_sg_count(cmd), buf, len);
+       spin_unlock_irqrestore(&ata_scsi_rbuf_lock, flags);
+
+       return r;
+}
+
+/**
+ * ata_scsi_write_same_xlat() - SATL Write Same to ATA SCT Write Same
+ * @qc: Command to be translated
+ *
+ * Translate a SCSI WRITE SAME command to be either a DSM TRIM command or
+ * an SCT Write Same command.
+ * Based on WRITE SAME has the UNMAP flag
+ *   When set translate to DSM TRIM
+ *   When clear translate to SCT Write Same
+ */
 static unsigned int ata_scsi_write_same_xlat(struct ata_queued_cmd *qc)
 {
        struct ata_taskfile *tf = &qc->tf;
        struct scsi_cmnd *scmd = qc->scsicmd;
+       struct scsi_device *sdp = scmd->device;
+       size_t len = sdp->sector_size;
        struct ata_device *dev = qc->dev;
        const u8 *cdb = scmd->cmnd;
        u64 block;
        u32 n_block;
+       const u32 trmax = len >> 3;
        u32 size;
-       void *buf;
        u16 fp;
        u8 bp = 0xff;
+       u8 unmap = cdb[1] & 0x8;
 
        /* we may not issue DMA commands if no DMA mode is set */
        if (unlikely(!dev->dma_mode))
@@ -3305,11 +3410,26 @@ static unsigned int ata_scsi_write_same_xlat(struct ata_queued_cmd *qc)
        }
        scsi_16_lba_len(cdb, &block, &n_block);
 
-       /* for now we only support WRITE SAME with the unmap bit set */
-       if (unlikely(!(cdb[1] & 0x8))) {
-               fp = 1;
-               bp = 3;
-               goto invalid_fld;
+       if (unmap) {
+               /* If trim is not enabled the cmd is invalid. */
+               if ((dev->horkage & ATA_HORKAGE_NOTRIM) ||
+                   !ata_id_has_trim(dev->id)) {
+                       fp = 1;
+                       bp = 3;
+                       goto invalid_fld;
+               }
+               /* If the request is too large the cmd is invalid */
+               if (n_block > 0xffff * trmax) {
+                       fp = 2;
+                       goto invalid_fld;
+               }
+       } else {
+               /* If write same is not available the cmd is invalid */
+               if (!ata_id_sct_write_same(dev->id)) {
+                       fp = 1;
+                       bp = 3;
+                       goto invalid_fld;
+               }
        }
 
        /*
@@ -3319,32 +3439,54 @@ static unsigned int ata_scsi_write_same_xlat(struct ata_queued_cmd *qc)
        if (!scsi_sg_count(scmd))
                goto invalid_param_len;
 
-       buf = page_address(sg_page(scsi_sglist(scmd)));
-
-       if (n_block <= 65535 * ATA_MAX_TRIM_RNUM) {
-               size = ata_set_lba_range_entries(buf, ATA_MAX_TRIM_RNUM, block, n_block);
-       } else {
-               fp = 2;
-               goto invalid_fld;
-       }
+       /*
+        * size must match sector size in bytes
+        * For DATA SET MANAGEMENT TRIM in ACS-2 nsect (aka count)
+        * is defined as number of 512 byte blocks to be transferred.
+        */
+       if (unmap) {
+               size = ata_format_dsm_trim_descr(scmd, trmax, block, n_block);
+               if (size != len)
+                       goto invalid_param_len;
 
-       if (ata_ncq_enabled(dev) && ata_fpdma_dsm_supported(dev)) {
-               /* Newer devices support queued TRIM commands */
-               tf->protocol = ATA_PROT_NCQ;
-               tf->command = ATA_CMD_FPDMA_SEND;
-               tf->hob_nsect = ATA_SUBCMD_FPDMA_SEND_DSM & 0x1f;
-               tf->nsect = qc->tag << 3;
-               tf->hob_feature = (size / 512) >> 8;
-               tf->feature = size / 512;
+               if (ata_ncq_enabled(dev) && ata_fpdma_dsm_supported(dev)) {
+                       /* Newer devices support queued TRIM commands */
+                       tf->protocol = ATA_PROT_NCQ;
+                       tf->command = ATA_CMD_FPDMA_SEND;
+                       tf->hob_nsect = ATA_SUBCMD_FPDMA_SEND_DSM & 0x1f;
+                       tf->nsect = qc->tag << 3;
+                       tf->hob_feature = (size / 512) >> 8;
+                       tf->feature = size / 512;
 
-               tf->auxiliary = 1;
+                       tf->auxiliary = 1;
+               } else {
+                       tf->protocol = ATA_PROT_DMA;
+                       tf->hob_feature = 0;
+                       tf->feature = ATA_DSM_TRIM;
+                       tf->hob_nsect = (size / 512) >> 8;
+                       tf->nsect = size / 512;
+                       tf->command = ATA_CMD_DSM;
+               }
        } else {
-               tf->protocol = ATA_PROT_DMA;
+               size = ata_format_sct_write_same(scmd, block, n_block);
+               if (size != len)
+                       goto invalid_param_len;
+
                tf->hob_feature = 0;
-               tf->feature = ATA_DSM_TRIM;
-               tf->hob_nsect = (size / 512) >> 8;
-               tf->nsect = size / 512;
-               tf->command = ATA_CMD_DSM;
+               tf->feature = 0;
+               tf->hob_nsect = 0;
+               tf->nsect = 1;
+               tf->lbah = 0;
+               tf->lbam = 0;
+               tf->lbal = ATA_CMD_STANDBYNOW1;
+               tf->hob_lbah = 0;
+               tf->hob_lbam = 0;
+               tf->hob_lbal = 0;
+               tf->device = ATA_CMD_STANDBYNOW1;
+               tf->protocol = ATA_PROT_DMA;
+               tf->command = ATA_CMD_WRITE_LOG_DMA_EXT;
+               if (unlikely(dev->flags & ATA_DFLAG_PIO))
+                       tf->command = ATA_CMD_WRITE_LOG_EXT;
        }
 
        tf->flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE | ATA_TFLAG_LBA48 |
@@ -3367,6 +3509,76 @@ invalid_opcode:
        return 1;
 }
 
+/**
+ *     ata_scsiop_maint_in - Simulate a subset of MAINTENANCE_IN
+ *     @args: device MAINTENANCE_IN data / SCSI command of interest.
+ *     @rbuf: Response buffer, to which simulated SCSI cmd output is sent.
+ *
+ *     Yields a subset to satisfy scsi_report_opcode()
+ *
+ *     LOCKING:
+ *     spin_lock_irqsave(host lock)
+ */
+static unsigned int ata_scsiop_maint_in(struct ata_scsi_args *args, u8 *rbuf)
+{
+       struct ata_device *dev = args->dev;
+       u8 *cdb = args->cmd->cmnd;
+       u8 supported = 0;
+       unsigned int err = 0;
+
+       if (cdb[2] != 1) {
+               ata_dev_warn(dev, "invalid command format %d\n", cdb[2]);
+               err = 2;
+               goto out;
+       }
+       switch (cdb[3]) {
+       case INQUIRY:
+       case MODE_SENSE:
+       case MODE_SENSE_10:
+       case READ_CAPACITY:
+       case SERVICE_ACTION_IN_16:
+       case REPORT_LUNS:
+       case REQUEST_SENSE:
+       case SYNCHRONIZE_CACHE:
+       case REZERO_UNIT:
+       case SEEK_6:
+       case SEEK_10:
+       case TEST_UNIT_READY:
+       case SEND_DIAGNOSTIC:
+       case MAINTENANCE_IN:
+       case READ_6:
+       case READ_10:
+       case READ_16:
+       case WRITE_6:
+       case WRITE_10:
+       case WRITE_16:
+       case ATA_12:
+       case ATA_16:
+       case VERIFY:
+       case VERIFY_16:
+       case MODE_SELECT:
+       case MODE_SELECT_10:
+       case START_STOP:
+               supported = 3;
+               break;
+       case WRITE_SAME_16:
+               if (!ata_id_sct_write_same(dev->id))
+                       break;
+               /* fallthrough: if SCT ... only enable for ZBC */
+       case ZBC_IN:
+       case ZBC_OUT:
+               if (ata_id_zoned_cap(dev->id) ||
+                   dev->class == ATA_DEV_ZAC)
+                       supported = 3;
+               break;
+       default:
+               break;
+       }
+out:
+       rbuf[1] = supported; /* supported */
+       return err;
+}
+
 /**
  *     ata_scsi_report_zones_complete - convert ATA output
  *     @qc: command structure returning the data
@@ -3610,7 +3822,7 @@ static int ata_mselect_caching(struct ata_queued_cmd *qc,
 {
        struct ata_taskfile *tf = &qc->tf;
        struct ata_device *dev = qc->dev;
-       char mpage[CACHE_MPAGE_LEN];
+       u8 mpage[CACHE_MPAGE_LEN];
        u8 wce;
        int i;
 
@@ -3666,7 +3878,7 @@ static int ata_mselect_control(struct ata_queued_cmd *qc,
                               const u8 *buf, int len, u16 *fp)
 {
        struct ata_device *dev = qc->dev;
-       char mpage[CONTROL_MPAGE_LEN];
+       u8 mpage[CONTROL_MPAGE_LEN];
        u8 d_sense;
        int i;
 
@@ -3701,8 +3913,6 @@ static int ata_mselect_control(struct ata_queued_cmd *qc,
                dev->flags |= ATA_DFLAG_D_SENSE;
        else
                dev->flags &= ~ATA_DFLAG_D_SENSE;
-       qc->scsicmd->result = SAM_STAT_GOOD;
-       qc->scsicmd->scsi_done(qc->scsicmd);
        return 0;
 }
 
@@ -3829,6 +4039,8 @@ static unsigned int ata_scsi_mode_select_xlat(struct ata_queued_cmd *qc)
                if (ata_mselect_control(qc, p, pg_len, &fp) < 0) {
                        fp += hdr_len + bd_len;
                        goto invalid_param;
+               } else {
+                       goto skip; /* No ATA command to send */
                }
                break;
        default:                /* invalid page code */
@@ -4147,6 +4359,13 @@ void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd)
                        ata_scsi_invalid_field(dev, cmd, 1);
                break;
 
+       case MAINTENANCE_IN:
+               if (scsicmd[1] == MI_REPORT_SUPPORTED_OPERATION_CODES)
+                       ata_scsi_rbuf_fill(&args, ata_scsiop_maint_in);
+               else
+                       ata_scsi_invalid_field(dev, cmd, 1);
+               break;
+
        /* all other commands */
        default:
                ata_scsi_set_sense(dev, cmd, ILLEGAL_REQUEST, 0x20, 0x0);
@@ -4179,7 +4398,6 @@ int ata_scsi_add_hosts(struct ata_host *host, struct scsi_host_template *sht)
                shost->max_lun = 1;
                shost->max_channel = 1;
                shost->max_cmd_len = 16;
-               shost->no_write_same = 1;
 
                /* Schedule policy is determined by ->qc_defer()
                 * callback and it needs to see every deferred qc.
index 9f27b14009f9e0f9b34b095b99dfeae76f5d72c4..1611e0e8d767816d86127f007f36818ab8a04434 100644 (file)
@@ -347,10 +347,8 @@ static int at91sam9_smc_fields_init(struct device *dev)
 
        field.reg = AT91SAM9_SMC_MODE(AT91SAM9_SMC_GENERIC);
        fields.mode = devm_regmap_field_alloc(dev, smc, field);
-       if (IS_ERR(fields.mode))
-               return PTR_ERR(fields.mode);
 
-       return 0;
+       return PTR_ERR_OR_ZERO(fields.mode);
 }
 
 static int pata_at91_probe(struct platform_device *pdev)
index 27245957eee3cd906f546d67853d2ebd6ce54d30..475a006694273bed1262dd457e8a9f683ba0367e 100644 (file)
@@ -152,8 +152,7 @@ static void octeon_cf_set_piomode(struct ata_port *ap, struct ata_device *dev)
                div = 8;
        T = (int)((1000000000000LL * div) / octeon_get_io_clock_rate());
 
-       if (ata_timing_compute(dev, dev->pio_mode, &timing, T, T))
-               BUG();
+       BUG_ON(ata_timing_compute(dev, dev->pio_mode, &timing, T, T));
 
        t1 = timing.setup;
        if (t1)
index 745489a1c86ab2c11701b124f8998126608c398a..efc48bf89d5182a6b4b4150b522fabc2cc1844ee 100644 (file)
@@ -1727,15 +1727,13 @@ static int mv_port_start(struct ata_port *ap)
                return -ENOMEM;
        ap->private_data = pp;
 
-       pp->crqb = dma_pool_alloc(hpriv->crqb_pool, GFP_KERNEL, &pp->crqb_dma);
+       pp->crqb = dma_pool_zalloc(hpriv->crqb_pool, GFP_KERNEL, &pp->crqb_dma);
        if (!pp->crqb)
                return -ENOMEM;
-       memset(pp->crqb, 0, MV_CRQB_Q_SZ);
 
-       pp->crpb = dma_pool_alloc(hpriv->crpb_pool, GFP_KERNEL, &pp->crpb_dma);
+       pp->crpb = dma_pool_zalloc(hpriv->crpb_pool, GFP_KERNEL, &pp->crpb_dma);
        if (!pp->crpb)
                goto out_port_free_dma_mem;
-       memset(pp->crpb, 0, MV_CRPB_Q_SZ);
 
        /* 6041/6081 Rev. "C0" (and newer) are okay with async notify */
        if (hpriv->hp_flags & MV_HP_ERRATA_60X1C0)
index 1b2f28f69a8142fce5edcd02c2f85f2e4f0c4a72..4852d9efe74e7c470169b25babbb3355e8a5a0b6 100644 (file)
@@ -80,11 +80,17 @@ static int cppc_cpufreq_set_target(struct cpufreq_policy *policy,
 {
        struct cppc_cpudata *cpu;
        struct cpufreq_freqs freqs;
+       u32 desired_perf;
        int ret = 0;
 
        cpu = all_cpu_data[policy->cpu];
 
-       cpu->perf_ctrls.desired_perf = (u64)target_freq * policy->max / cppc_dmi_max_khz;
+       desired_perf = (u64)target_freq * cpu->perf_caps.highest_perf / cppc_dmi_max_khz;
+       /* Return if it is exactly the same perf */
+       if (desired_perf == cpu->perf_ctrls.desired_perf)
+               return ret;
+
+       cpu->perf_ctrls.desired_perf = desired_perf;
        freqs.old = policy->cur;
        freqs.new = target_freq;
 
index 18da4f8051d372d06eb74e68e591f57e40569c82..13475890d792d7bb24209a8fa8617f011883e660 100644 (file)
@@ -17,6 +17,7 @@
 struct cs_policy_dbs_info {
        struct policy_dbs_info policy_dbs;
        unsigned int down_skip;
+       unsigned int requested_freq;
 };
 
 static inline struct cs_policy_dbs_info *to_dbs_info(struct policy_dbs_info *policy_dbs)
@@ -61,6 +62,7 @@ static unsigned int cs_dbs_timer(struct cpufreq_policy *policy)
 {
        struct policy_dbs_info *policy_dbs = policy->governor_data;
        struct cs_policy_dbs_info *dbs_info = to_dbs_info(policy_dbs);
+       unsigned int requested_freq = dbs_info->requested_freq;
        struct dbs_data *dbs_data = policy_dbs->dbs_data;
        struct cs_dbs_tuners *cs_tuners = dbs_data->tuners;
        unsigned int load = dbs_update(policy);
@@ -72,10 +74,16 @@ static unsigned int cs_dbs_timer(struct cpufreq_policy *policy)
        if (cs_tuners->freq_step == 0)
                goto out;
 
+       /*
+        * If requested_freq is out of range, it is likely that the limits
+        * changed in the meantime, so fall back to current frequency in that
+        * case.
+        */
+       if (requested_freq > policy->max || requested_freq < policy->min)
+               requested_freq = policy->cur;
+
        /* Check for frequency increase */
        if (load > dbs_data->up_threshold) {
-               unsigned int requested_freq = policy->cur;
-
                dbs_info->down_skip = 0;
 
                /* if we are already at full speed then break out early */
@@ -83,8 +91,11 @@ static unsigned int cs_dbs_timer(struct cpufreq_policy *policy)
                        goto out;
 
                requested_freq += get_freq_target(cs_tuners, policy);
+               if (requested_freq > policy->max)
+                       requested_freq = policy->max;
 
                __cpufreq_driver_target(policy, requested_freq, CPUFREQ_RELATION_H);
+               dbs_info->requested_freq = requested_freq;
                goto out;
        }
 
@@ -95,7 +106,7 @@ static unsigned int cs_dbs_timer(struct cpufreq_policy *policy)
 
        /* Check for frequency decrease */
        if (load < cs_tuners->down_threshold) {
-               unsigned int freq_target, requested_freq = policy->cur;
+               unsigned int freq_target;
                /*
                 * if we cannot reduce the frequency anymore, break out early
                 */
@@ -109,6 +120,7 @@ static unsigned int cs_dbs_timer(struct cpufreq_policy *policy)
                        requested_freq = policy->min;
 
                __cpufreq_driver_target(policy, requested_freq, CPUFREQ_RELATION_L);
+               dbs_info->requested_freq = requested_freq;
        }
 
  out:
@@ -287,6 +299,7 @@ static void cs_start(struct cpufreq_policy *policy)
        struct cs_policy_dbs_info *dbs_info = to_dbs_info(policy->governor_data);
 
        dbs_info->down_skip = 0;
+       dbs_info->requested_freq = policy->cur;
 }
 
 static struct dbs_governor cs_governor = {
index 806f2039571e56ec69bd2cad697f788821826c1a..f535f812325841a683d5691fc61bd89860681229 100644 (file)
@@ -225,7 +225,7 @@ struct cpudata {
 static struct cpudata **all_cpu_data;
 
 /**
- * struct pid_adjust_policy - Stores static PID configuration data
+ * struct pstate_adjust_policy - Stores static PID configuration data
  * @sample_rate_ms:    PID calculation sample rate in ms
  * @sample_rate_ns:    Sample rate calculation in ns
  * @deadband:          PID deadband
@@ -562,12 +562,12 @@ static void intel_pstate_hwp_set(const struct cpumask *cpumask)
        int min, hw_min, max, hw_max, cpu, range, adj_range;
        u64 value, cap;
 
-       rdmsrl(MSR_HWP_CAPABILITIES, cap);
-       hw_min = HWP_LOWEST_PERF(cap);
-       hw_max = HWP_HIGHEST_PERF(cap);
-       range = hw_max - hw_min;
-
        for_each_cpu(cpu, cpumask) {
+               rdmsrl_on_cpu(cpu, MSR_HWP_CAPABILITIES, &cap);
+               hw_min = HWP_LOWEST_PERF(cap);
+               hw_max = HWP_HIGHEST_PERF(cap);
+               range = hw_max - hw_min;
+
                rdmsrl_on_cpu(cpu, MSR_HWP_REQUEST, &value);
                adj_range = limits->min_perf_pct * range / 100;
                min = hw_min + adj_range;
@@ -1232,6 +1232,7 @@ static inline int32_t get_target_pstate_use_cpu_load(struct cpudata *cpu)
 {
        struct sample *sample = &cpu->sample;
        int32_t busy_frac, boost;
+       int target, avg_pstate;
 
        busy_frac = div_fp(sample->mperf, sample->tsc);
 
@@ -1242,7 +1243,26 @@ static inline int32_t get_target_pstate_use_cpu_load(struct cpudata *cpu)
                busy_frac = boost;
 
        sample->busy_scaled = busy_frac * 100;
-       return get_avg_pstate(cpu) - pid_calc(&cpu->pid, sample->busy_scaled);
+
+       target = limits->no_turbo || limits->turbo_disabled ?
+                       cpu->pstate.max_pstate : cpu->pstate.turbo_pstate;
+       target += target >> 2;
+       target = mul_fp(target, busy_frac);
+       if (target < cpu->pstate.min_pstate)
+               target = cpu->pstate.min_pstate;
+
+       /*
+        * If the average P-state during the previous cycle was higher than the
+        * current target, add 50% of the difference to the target to reduce
+        * possible performance oscillations and offset possible performance
+        * loss related to moving the workload from one CPU to another within
+        * a package/module.
+        */
+       avg_pstate = get_avg_pstate(cpu);
+       if (avg_pstate > target)
+               target += (avg_pstate - target) >> 1;
+
+       return target;
 }
 
 static inline int32_t get_target_pstate_use_performance(struct cpudata *cpu)
@@ -1251,10 +1271,11 @@ static inline int32_t get_target_pstate_use_performance(struct cpudata *cpu)
        u64 duration_ns;
 
        /*
-        * perf_scaled is the average performance during the last sampling
-        * period scaled by the ratio of the maximum P-state to the P-state
-        * requested last time (in percent).  That measures the system's
-        * response to the previous P-state selection.
+        * perf_scaled is the ratio of the average P-state during the last
+        * sampling period to the P-state requested last time (in percent).
+        *
+        * That measures the system's response to the previous P-state
+        * selection.
         */
        max_pstate = cpu->pstate.max_pstate_physical;
        current_pstate = cpu->pstate.current_pstate;
index 478006b7764a5919259e8b582dedfd3a1f5358f5..bf3ea7603a58a9705d51feb271a61507f5c779e9 100644 (file)
@@ -137,6 +137,10 @@ static int devfreq_update_status(struct devfreq *devfreq, unsigned long freq)
 
        cur_time = jiffies;
 
+       /* Immediately exit if previous_freq is not initialized yet. */
+       if (!devfreq->previous_freq)
+               goto out;
+
        prev_lev = devfreq_get_freq_level(devfreq, devfreq->previous_freq);
        if (prev_lev < 0) {
                ret = prev_lev;
@@ -594,17 +598,19 @@ struct devfreq *devfreq_add_device(struct device *dev,
        if (devfreq->governor)
                err = devfreq->governor->event_handler(devfreq,
                                        DEVFREQ_GOV_START, NULL);
-       mutex_unlock(&devfreq_list_lock);
        if (err) {
                dev_err(dev, "%s: Unable to start governor for the device\n",
                        __func__);
                goto err_init;
        }
+       mutex_unlock(&devfreq_list_lock);
 
        return devfreq;
 
 err_init:
        list_del(&devfreq->node);
+       mutex_unlock(&devfreq_list_lock);
+
        device_unregister(&devfreq->dev);
 err_out:
        return ERR_PTR(err);
index 0fdae86089613fe130d35246318fe75d41a755c5..cd949800eed962cffa34b599d3ce66f386763d11 100644 (file)
@@ -17,6 +17,7 @@ config DEVFREQ_EVENT_EXYNOS_NOCP
        tristate "EXYNOS NoC (Network On Chip) Probe DEVFREQ event Driver"
        depends on ARCH_EXYNOS || COMPILE_TEST
        select PM_OPP
+       select REGMAP_MMIO
        help
          This add the devfreq-event driver for Exynos SoC. It provides NoC
          (Network on Chip) Probe counters to measure the bandwidth of AXI bus.
index a5841403bde8b64c314c921148b6189d7dcef82f..49e712aca0c15367e2168d91a3542cdb6ff2ff5b 100644 (file)
@@ -176,9 +176,6 @@ static int exynos_nocp_get_event(struct devfreq_event_dev *edev,
        return 0;
 
 out:
-       edata->load_count = 0;
-       edata->total_count = 0;
-
        dev_err(nocp->dev, "Failed to read the counter of NoC probe device\n");
 
        return ret;
index 45c8817d068c60649ee9e5648dbf9451f3bf5667..e422568e14ad19273c277fc1565d068ab2819c53 100644 (file)
@@ -794,6 +794,22 @@ static int pca953x_probe(struct i2c_client *client,
        }
 
        mutex_init(&chip->i2c_lock);
+       /*
+        * In case we have an i2c-mux controlled by a GPIO provided by an
+        * expander using the same driver higher on the device tree, read the
+        * i2c adapter nesting depth and use the retrieved value as lockdep
+        * subclass for chip->i2c_lock.
+        *
+        * REVISIT: This solution is not complete. It protects us from lockdep
+        * false positives when the expander controlling the i2c-mux is on
+        * a different level on the device tree, but not when it's on the same
+        * level on a different branch (in which case the subclass number
+        * would be the same).
+        *
+        * TODO: Once a correct solution is developed, a similar fix should be
+        * applied to all other i2c-controlled GPIO expanders (and potentially
+        * regmap-i2c).
+        */
        lockdep_set_subclass(&chip->i2c_lock,
                             i2c_adapter_depth(client->adapter));
 
index 98fffa3a09f7fe5e716415c79963b7ac15587b9c..5ab67219f71e64a95c926e20b4c45cb1edce68bf 100644 (file)
@@ -1680,7 +1680,7 @@ static struct i2c_client *of_i2c_register_device(struct i2c_adapter *adap,
 
 static void of_i2c_register_devices(struct i2c_adapter *adap)
 {
-       struct device_node *node;
+       struct device_node *bus, *node;
 
        /* Only register child devices if the adapter has a node pointer set */
        if (!adap->dev.of_node)
@@ -1688,11 +1688,17 @@ static void of_i2c_register_devices(struct i2c_adapter *adap)
 
        dev_dbg(&adap->dev, "of_i2c: walking child nodes\n");
 
-       for_each_available_child_of_node(adap->dev.of_node, node) {
+       bus = of_get_child_by_name(adap->dev.of_node, "i2c-bus");
+       if (!bus)
+               bus = of_node_get(adap->dev.of_node);
+
+       for_each_available_child_of_node(bus, node) {
                if (of_node_test_and_set_flag(node, OF_POPULATED))
                        continue;
                of_i2c_register_device(adap, node);
        }
+
+       of_node_put(bus);
 }
 
 static int of_dev_node_match(struct device *dev, void *data)
index 875597b0e69c59196e666e958e7b25404779eb20..097365932b0961f578fe27c7c8b650d564317476 100644 (file)
@@ -83,8 +83,7 @@ static int hns_roce_sw2hw_cq(struct hns_roce_dev *dev,
 static int hns_roce_cq_alloc(struct hns_roce_dev *hr_dev, int nent,
                             struct hns_roce_mtt *hr_mtt,
                             struct hns_roce_uar *hr_uar,
-                            struct hns_roce_cq *hr_cq, int vector,
-                            int collapsed)
+                            struct hns_roce_cq *hr_cq, int vector)
 {
        struct hns_roce_cmd_mailbox *mailbox = NULL;
        struct hns_roce_cq_table *cq_table = NULL;
@@ -153,6 +152,9 @@ static int hns_roce_cq_alloc(struct hns_roce_dev *hr_dev, int nent,
        hr_cq->cons_index = 0;
        hr_cq->uar = hr_uar;
 
+       atomic_set(&hr_cq->refcount, 1);
+       init_completion(&hr_cq->free);
+
        return 0;
 
 err_radix:
@@ -192,6 +194,11 @@ static void hns_roce_free_cq(struct hns_roce_dev *hr_dev,
        /* Waiting interrupt process procedure carried out */
        synchronize_irq(hr_dev->eq_table.eq[hr_cq->vector].irq);
 
+       /* wait for all interrupt processed */
+       if (atomic_dec_and_test(&hr_cq->refcount))
+               complete(&hr_cq->free);
+       wait_for_completion(&hr_cq->free);
+
        spin_lock_irq(&cq_table->lock);
        radix_tree_delete(&cq_table->tree, hr_cq->cqn);
        spin_unlock_irq(&cq_table->lock);
@@ -300,10 +307,7 @@ struct ib_cq *hns_roce_ib_create_cq(struct ib_device *ib_dev,
 
        cq_entries = roundup_pow_of_two((unsigned int)cq_entries);
        hr_cq->ib_cq.cqe = cq_entries - 1;
-       mutex_init(&hr_cq->resize_mutex);
        spin_lock_init(&hr_cq->lock);
-       hr_cq->hr_resize_buf = NULL;
-       hr_cq->resize_umem = NULL;
 
        if (context) {
                if (ib_copy_from_udata(&ucmd, udata, sizeof(ucmd))) {
@@ -338,8 +342,8 @@ struct ib_cq *hns_roce_ib_create_cq(struct ib_device *ib_dev,
        }
 
        /* Allocate cq index, fill cq_context */
-       ret = hns_roce_cq_alloc(hr_dev, cq_entries, &hr_cq->hr_buf.hr_mtt,
-                               uar, hr_cq, vector, 0);
+       ret = hns_roce_cq_alloc(hr_dev, cq_entries, &hr_cq->hr_buf.hr_mtt, uar,
+                               hr_cq, vector);
        if (ret) {
                dev_err(dev, "Creat CQ .Failed to cq_alloc.\n");
                goto err_mtt;
@@ -353,12 +357,15 @@ struct ib_cq *hns_roce_ib_create_cq(struct ib_device *ib_dev,
        if (context) {
                if (ib_copy_to_udata(udata, &hr_cq->cqn, sizeof(u64))) {
                        ret = -EFAULT;
-                       goto err_mtt;
+                       goto err_cqc;
                }
        }
 
        return &hr_cq->ib_cq;
 
+err_cqc:
+       hns_roce_free_cq(hr_dev, hr_cq);
+
 err_mtt:
        hns_roce_mtt_cleanup(hr_dev, &hr_cq->hr_buf.hr_mtt);
        if (context)
index ea735800eb18e8c6c5962349aa94152b13d636bf..341731553a60167d4fff793edb49dc8958371422 100644 (file)
@@ -62,7 +62,7 @@
 #define HNS_ROCE_AEQE_OF_VEC_NUM               1
 
 /* 4G/4K = 1M */
-#define HNS_ROCE_SL_SHIFT                      29
+#define HNS_ROCE_SL_SHIFT                      28
 #define HNS_ROCE_TCLASS_SHIFT                  20
 #define HNS_ROCE_FLOW_LABLE_MASK               0xfffff
 
@@ -74,7 +74,9 @@
 #define MR_TYPE_DMA                            0x03
 
 #define PKEY_ID                                        0xffff
+#define GUID_LEN                               8
 #define NODE_DESC_SIZE                         64
+#define DB_REG_OFFSET                          0x1000
 
 #define SERV_TYPE_RC                           0
 #define SERV_TYPE_RD                           1
@@ -282,20 +284,11 @@ struct hns_roce_cq_buf {
        struct hns_roce_mtt hr_mtt;
 };
 
-struct hns_roce_cq_resize {
-       struct hns_roce_cq_buf  hr_buf;
-       int                     cqe;
-};
-
 struct hns_roce_cq {
        struct ib_cq                    ib_cq;
        struct hns_roce_cq_buf          hr_buf;
-       /* pointer to store information after resize*/
-       struct hns_roce_cq_resize       *hr_resize_buf;
        spinlock_t                      lock;
-       struct mutex                    resize_mutex;
        struct ib_umem                  *umem;
-       struct ib_umem                  *resize_umem;
        void (*comp)(struct hns_roce_cq *);
        void (*event)(struct hns_roce_cq *, enum hns_roce_event);
 
@@ -408,6 +401,7 @@ struct hns_roce_qp {
        u32                     buff_size;
        struct mutex            mutex;
        u8                      port;
+       u8                      phy_port;
        u8                      sl;
        u8                      resp_depth;
        u8                      state;
@@ -471,7 +465,6 @@ struct hns_roce_caps {
        u32             max_rq_desc_sz; /* 64 */
        int             max_qp_init_rdma;
        int             max_qp_dest_rdma;
-       int             sqp_start;
        int             num_cqs;
        int             max_cqes;
        int             reserved_cqs;
@@ -512,6 +505,8 @@ struct hns_roce_hw {
        void (*write_cqc)(struct hns_roce_dev *hr_dev,
                          struct hns_roce_cq *hr_cq, void *mb_buf, u64 *mtts,
                          dma_addr_t dma_handle, int nent, u32 vector);
+       int (*clear_hem)(struct hns_roce_dev *hr_dev,
+                        struct hns_roce_hem_table *table, int obj);
        int (*query_qp)(struct ib_qp *ibqp, struct ib_qp_attr *qp_attr,
                        int qp_attr_mask, struct ib_qp_init_attr *qp_init_attr);
        int (*modify_qp)(struct ib_qp *ibqp, const struct ib_qp_attr *attr,
@@ -533,7 +528,6 @@ struct hns_roce_dev {
        struct hns_roce_uar     priv_uar;
        const char              *irq_names[HNS_ROCE_MAX_IRQ_NUM];
        spinlock_t              sm_lock;
-       spinlock_t              cq_db_lock;
        spinlock_t              bt_cmd_lock;
        struct hns_roce_ib_iboe iboe;
 
index 98af7fecf2f1e9d42d92fec1a776c1e1bc6d3080..21e21b03cfb52a966f1412e65b2ec4709975ecae 100644 (file)
@@ -66,9 +66,6 @@ static void hns_roce_wq_catas_err_handle(struct hns_roce_dev *hr_dev,
 {
        struct device *dev = &hr_dev->pdev->dev;
 
-       qpn = roce_get_field(aeqe->event.qp_event.qp,
-                            HNS_ROCE_AEQE_EVENT_QP_EVENT_QP_QPN_M,
-                            HNS_ROCE_AEQE_EVENT_QP_EVENT_QP_QPN_S);
        dev_warn(dev, "Local Work Queue Catastrophic Error.\n");
        switch (roce_get_field(aeqe->asyn, HNS_ROCE_AEQE_U32_4_EVENT_SUB_TYPE_M,
                               HNS_ROCE_AEQE_U32_4_EVENT_SUB_TYPE_S)) {
@@ -96,13 +93,6 @@ static void hns_roce_wq_catas_err_handle(struct hns_roce_dev *hr_dev,
        default:
                break;
        }
-
-       hns_roce_qp_event(hr_dev, roce_get_field(aeqe->event.qp_event.qp,
-                                       HNS_ROCE_AEQE_EVENT_QP_EVENT_QP_QPN_M,
-                                       HNS_ROCE_AEQE_EVENT_QP_EVENT_QP_QPN_S),
-                         roce_get_field(aeqe->asyn,
-                                       HNS_ROCE_AEQE_U32_4_EVENT_TYPE_M,
-                                       HNS_ROCE_AEQE_U32_4_EVENT_TYPE_S));
 }
 
 static void hns_roce_local_wq_access_err_handle(struct hns_roce_dev *hr_dev,
@@ -111,9 +101,6 @@ static void hns_roce_local_wq_access_err_handle(struct hns_roce_dev *hr_dev,
 {
        struct device *dev = &hr_dev->pdev->dev;
 
-       qpn = roce_get_field(aeqe->event.qp_event.qp,
-                            HNS_ROCE_AEQE_EVENT_QP_EVENT_QP_QPN_M,
-                            HNS_ROCE_AEQE_EVENT_QP_EVENT_QP_QPN_S);
        dev_warn(dev, "Local Access Violation Work Queue Error.\n");
        switch (roce_get_field(aeqe->asyn, HNS_ROCE_AEQE_U32_4_EVENT_SUB_TYPE_M,
                               HNS_ROCE_AEQE_U32_4_EVENT_SUB_TYPE_S)) {
@@ -141,13 +128,69 @@ static void hns_roce_local_wq_access_err_handle(struct hns_roce_dev *hr_dev,
        default:
                break;
        }
+}
+
+static void hns_roce_qp_err_handle(struct hns_roce_dev *hr_dev,
+                                  struct hns_roce_aeqe *aeqe,
+                                  int event_type)
+{
+       struct device *dev = &hr_dev->pdev->dev;
+       int phy_port;
+       int qpn;
+
+       qpn = roce_get_field(aeqe->event.qp_event.qp,
+                            HNS_ROCE_AEQE_EVENT_QP_EVENT_QP_QPN_M,
+                            HNS_ROCE_AEQE_EVENT_QP_EVENT_QP_QPN_S);
+       phy_port = roce_get_field(aeqe->event.qp_event.qp,
+                       HNS_ROCE_AEQE_EVENT_QP_EVENT_PORT_NUM_M,
+                       HNS_ROCE_AEQE_EVENT_QP_EVENT_PORT_NUM_S);
+       if (qpn <= 1)
+               qpn = HNS_ROCE_MAX_PORTS * qpn + phy_port;
+
+       switch (event_type) {
+       case HNS_ROCE_EVENT_TYPE_INV_REQ_LOCAL_WQ_ERROR:
+               dev_warn(dev, "Invalid Req Local Work Queue Error.\n"
+                             "QP %d, phy_port %d.\n", qpn, phy_port);
+               break;
+       case HNS_ROCE_EVENT_TYPE_WQ_CATAS_ERROR:
+               hns_roce_wq_catas_err_handle(hr_dev, aeqe, qpn);
+               break;
+       case HNS_ROCE_EVENT_TYPE_LOCAL_WQ_ACCESS_ERROR:
+               hns_roce_local_wq_access_err_handle(hr_dev, aeqe, qpn);
+               break;
+       default:
+               break;
+       }
+
+       hns_roce_qp_event(hr_dev, qpn, event_type);
+}
+
+static void hns_roce_cq_err_handle(struct hns_roce_dev *hr_dev,
+                                  struct hns_roce_aeqe *aeqe,
+                                  int event_type)
+{
+       struct device *dev = &hr_dev->pdev->dev;
+       u32 cqn;
+
+       cqn = le32_to_cpu(roce_get_field(aeqe->event.cq_event.cq,
+                   HNS_ROCE_AEQE_EVENT_CQ_EVENT_CQ_CQN_M,
+                   HNS_ROCE_AEQE_EVENT_CQ_EVENT_CQ_CQN_S));
+
+       switch (event_type) {
+       case HNS_ROCE_EVENT_TYPE_CQ_ACCESS_ERROR:
+               dev_warn(dev, "CQ 0x%x access err.\n", cqn);
+               break;
+       case HNS_ROCE_EVENT_TYPE_CQ_OVERFLOW:
+               dev_warn(dev, "CQ 0x%x overflow\n", cqn);
+               break;
+       case HNS_ROCE_EVENT_TYPE_CQ_ID_INVALID:
+               dev_warn(dev, "CQ 0x%x ID invalid.\n", cqn);
+               break;
+       default:
+               break;
+       }
 
-       hns_roce_qp_event(hr_dev, roce_get_field(aeqe->event.qp_event.qp,
-                                        HNS_ROCE_AEQE_EVENT_QP_EVENT_QP_QPN_M,
-                                        HNS_ROCE_AEQE_EVENT_QP_EVENT_QP_QPN_S),
-                         roce_get_field(aeqe->asyn,
-                                        HNS_ROCE_AEQE_U32_4_EVENT_TYPE_M,
-                                        HNS_ROCE_AEQE_U32_4_EVENT_TYPE_S));
+       hns_roce_cq_event(hr_dev, cqn, event_type);
 }
 
 static void hns_roce_db_overflow_handle(struct hns_roce_dev *hr_dev,
@@ -185,7 +228,7 @@ static int hns_roce_aeq_int(struct hns_roce_dev *hr_dev, struct hns_roce_eq *eq)
        struct device *dev = &hr_dev->pdev->dev;
        struct hns_roce_aeqe *aeqe;
        int aeqes_found = 0;
-       int qpn = 0;
+       int event_type;
 
        while ((aeqe = next_aeqe_sw(eq))) {
                dev_dbg(dev, "aeqe = %p, aeqe->asyn.event_type = 0x%lx\n", aeqe,
@@ -195,9 +238,10 @@ static int hns_roce_aeq_int(struct hns_roce_dev *hr_dev, struct hns_roce_eq *eq)
                /* Memory barrier */
                rmb();
 
-               switch (roce_get_field(aeqe->asyn,
-                       HNS_ROCE_AEQE_U32_4_EVENT_TYPE_M,
-                       HNS_ROCE_AEQE_U32_4_EVENT_TYPE_S)) {
+               event_type = roce_get_field(aeqe->asyn,
+                               HNS_ROCE_AEQE_U32_4_EVENT_TYPE_M,
+                               HNS_ROCE_AEQE_U32_4_EVENT_TYPE_S);
+               switch (event_type) {
                case HNS_ROCE_EVENT_TYPE_PATH_MIG:
                        dev_warn(dev, "PATH MIG not supported\n");
                        break;
@@ -211,23 +255,9 @@ static int hns_roce_aeq_int(struct hns_roce_dev *hr_dev, struct hns_roce_eq *eq)
                        dev_warn(dev, "PATH MIG failed\n");
                        break;
                case HNS_ROCE_EVENT_TYPE_INV_REQ_LOCAL_WQ_ERROR:
-                       dev_warn(dev, "qpn = 0x%lx\n",
-                       roce_get_field(aeqe->event.qp_event.qp,
-                                      HNS_ROCE_AEQE_EVENT_QP_EVENT_QP_QPN_M,
-                                      HNS_ROCE_AEQE_EVENT_QP_EVENT_QP_QPN_S));
-                       hns_roce_qp_event(hr_dev,
-                               roce_get_field(aeqe->event.qp_event.qp,
-                                       HNS_ROCE_AEQE_EVENT_QP_EVENT_QP_QPN_M,
-                                       HNS_ROCE_AEQE_EVENT_QP_EVENT_QP_QPN_S),
-                               roce_get_field(aeqe->asyn,
-                                       HNS_ROCE_AEQE_U32_4_EVENT_TYPE_M,
-                                       HNS_ROCE_AEQE_U32_4_EVENT_TYPE_S));
-                       break;
                case HNS_ROCE_EVENT_TYPE_WQ_CATAS_ERROR:
-                       hns_roce_wq_catas_err_handle(hr_dev, aeqe, qpn);
-                       break;
                case HNS_ROCE_EVENT_TYPE_LOCAL_WQ_ACCESS_ERROR:
-                       hns_roce_local_wq_access_err_handle(hr_dev, aeqe, qpn);
+                       hns_roce_qp_err_handle(hr_dev, aeqe, event_type);
                        break;
                case HNS_ROCE_EVENT_TYPE_SRQ_LIMIT_REACH:
                case HNS_ROCE_EVENT_TYPE_SRQ_CATAS_ERROR:
@@ -235,40 +265,9 @@ static int hns_roce_aeq_int(struct hns_roce_dev *hr_dev, struct hns_roce_eq *eq)
                        dev_warn(dev, "SRQ not support!\n");
                        break;
                case HNS_ROCE_EVENT_TYPE_CQ_ACCESS_ERROR:
-                       dev_warn(dev, "CQ 0x%lx access err.\n",
-                       roce_get_field(aeqe->event.cq_event.cq,
-                                      HNS_ROCE_AEQE_EVENT_CQ_EVENT_CQ_CQN_M,
-                                      HNS_ROCE_AEQE_EVENT_CQ_EVENT_CQ_CQN_S));
-                       hns_roce_cq_event(hr_dev,
-                       le32_to_cpu(roce_get_field(aeqe->event.cq_event.cq,
-                                   HNS_ROCE_AEQE_EVENT_CQ_EVENT_CQ_CQN_M,
-                                   HNS_ROCE_AEQE_EVENT_CQ_EVENT_CQ_CQN_S)),
-                       roce_get_field(aeqe->asyn,
-                                      HNS_ROCE_AEQE_U32_4_EVENT_TYPE_M,
-                                      HNS_ROCE_AEQE_U32_4_EVENT_TYPE_S));
-                       break;
                case HNS_ROCE_EVENT_TYPE_CQ_OVERFLOW:
-                       dev_warn(dev, "CQ 0x%lx overflow\n",
-                       roce_get_field(aeqe->event.cq_event.cq,
-                                      HNS_ROCE_AEQE_EVENT_CQ_EVENT_CQ_CQN_M,
-                                      HNS_ROCE_AEQE_EVENT_CQ_EVENT_CQ_CQN_S));
-                       hns_roce_cq_event(hr_dev,
-                       le32_to_cpu(roce_get_field(aeqe->event.cq_event.cq,
-                                   HNS_ROCE_AEQE_EVENT_CQ_EVENT_CQ_CQN_M,
-                                   HNS_ROCE_AEQE_EVENT_CQ_EVENT_CQ_CQN_S)),
-                       roce_get_field(aeqe->asyn,
-                                      HNS_ROCE_AEQE_U32_4_EVENT_TYPE_M,
-                                      HNS_ROCE_AEQE_U32_4_EVENT_TYPE_S));
-                       break;
                case HNS_ROCE_EVENT_TYPE_CQ_ID_INVALID:
-                       dev_warn(dev, "CQ ID invalid.\n");
-                       hns_roce_cq_event(hr_dev,
-                       le32_to_cpu(roce_get_field(aeqe->event.cq_event.cq,
-                                   HNS_ROCE_AEQE_EVENT_CQ_EVENT_CQ_CQN_M,
-                                   HNS_ROCE_AEQE_EVENT_CQ_EVENT_CQ_CQN_S)),
-                       roce_get_field(aeqe->asyn,
-                                      HNS_ROCE_AEQE_U32_4_EVENT_TYPE_M,
-                                      HNS_ROCE_AEQE_U32_4_EVENT_TYPE_S));
+                       hns_roce_cq_err_handle(hr_dev, aeqe, event_type);
                        break;
                case HNS_ROCE_EVENT_TYPE_PORT_CHANGE:
                        dev_warn(dev, "port change.\n");
@@ -290,11 +289,8 @@ static int hns_roce_aeq_int(struct hns_roce_dev *hr_dev, struct hns_roce_eq *eq)
                                     HNS_ROCE_AEQE_EVENT_CE_EVENT_CEQE_CEQN_S));
                        break;
                default:
-                       dev_warn(dev, "Unhandled event 0x%lx on EQ %d at index %u\n",
-                                roce_get_field(aeqe->asyn,
-                                             HNS_ROCE_AEQE_U32_4_EVENT_TYPE_M,
-                                             HNS_ROCE_AEQE_U32_4_EVENT_TYPE_S),
-                                eq->eqn, eq->cons_index);
+                       dev_warn(dev, "Unhandled event %d on EQ %d at index %u\n",
+                                event_type, eq->eqn, eq->cons_index);
                        break;
                };
 
index fe4388191a3c255c74a3668256a3a5e91f897772..c6d212d12e033372f1c1e99b46c764b8eefcde28 100644 (file)
@@ -107,6 +107,10 @@ struct hns_roce_aeqe {
 #define HNS_ROCE_AEQE_EVENT_QP_EVENT_QP_QPN_M   \
        (((1UL << 24) - 1) << HNS_ROCE_AEQE_EVENT_QP_EVENT_QP_QPN_S)
 
+#define HNS_ROCE_AEQE_EVENT_QP_EVENT_PORT_NUM_S 25
+#define HNS_ROCE_AEQE_EVENT_QP_EVENT_PORT_NUM_M   \
+       (((1UL << 3) - 1) << HNS_ROCE_AEQE_EVENT_QP_EVENT_PORT_NUM_S)
+
 #define HNS_ROCE_AEQE_EVENT_CQ_EVENT_CQ_CQN_S 0
 #define HNS_ROCE_AEQE_EVENT_CQ_EVENT_CQ_CQN_M   \
        (((1UL << 16) - 1) << HNS_ROCE_AEQE_EVENT_CQ_EVENT_CQ_CQN_S)
index d53d643623899e0fdd2eaf771dcb852bb817a6fe..250d8f2803908f4c5fcae2d224baae5df68ed1fb 100644 (file)
 #include "hns_roce_hem.h"
 #include "hns_roce_common.h"
 
-#define HW_SYNC_TIMEOUT_MSECS          500
-#define HW_SYNC_SLEEP_TIME_INTERVAL    20
-
 #define HNS_ROCE_HEM_ALLOC_SIZE                (1 << 17)
 #define HNS_ROCE_TABLE_CHUNK_SIZE      (1 << 17)
 
 #define DMA_ADDR_T_SHIFT               12
-#define BT_CMD_SYNC_SHIFT              31
 #define BT_BA_SHIFT                    32
 
 struct hns_roce_hem *hns_roce_alloc_hem(struct hns_roce_dev *hr_dev, int npages,
@@ -213,74 +209,6 @@ static int hns_roce_set_hem(struct hns_roce_dev *hr_dev,
        return ret;
 }
 
-static int hns_roce_clear_hem(struct hns_roce_dev *hr_dev,
-                             struct hns_roce_hem_table *table,
-                             unsigned long obj)
-{
-       struct device *dev = &hr_dev->pdev->dev;
-       unsigned long end = 0;
-       unsigned long flags;
-       void __iomem *bt_cmd;
-       uint32_t bt_cmd_val[2];
-       u32 bt_cmd_h_val = 0;
-       int ret = 0;
-
-       switch (table->type) {
-       case HEM_TYPE_QPC:
-               roce_set_field(bt_cmd_h_val, ROCEE_BT_CMD_H_ROCEE_BT_CMD_MDF_M,
-                              ROCEE_BT_CMD_H_ROCEE_BT_CMD_MDF_S, HEM_TYPE_QPC);
-               break;
-       case HEM_TYPE_MTPT:
-               roce_set_field(bt_cmd_h_val, ROCEE_BT_CMD_H_ROCEE_BT_CMD_MDF_M,
-                              ROCEE_BT_CMD_H_ROCEE_BT_CMD_MDF_S,
-                              HEM_TYPE_MTPT);
-               break;
-       case HEM_TYPE_CQC:
-               roce_set_field(bt_cmd_h_val, ROCEE_BT_CMD_H_ROCEE_BT_CMD_MDF_M,
-                              ROCEE_BT_CMD_H_ROCEE_BT_CMD_MDF_S, HEM_TYPE_CQC);
-               break;
-       case HEM_TYPE_SRQC:
-               roce_set_field(bt_cmd_h_val, ROCEE_BT_CMD_H_ROCEE_BT_CMD_MDF_M,
-                              ROCEE_BT_CMD_H_ROCEE_BT_CMD_MDF_S,
-                              HEM_TYPE_SRQC);
-               break;
-       default:
-               return ret;
-       }
-       roce_set_field(bt_cmd_h_val, ROCEE_BT_CMD_H_ROCEE_BT_CMD_IN_MDF_M,
-                      ROCEE_BT_CMD_H_ROCEE_BT_CMD_IN_MDF_S, obj);
-       roce_set_bit(bt_cmd_h_val, ROCEE_BT_CMD_H_ROCEE_BT_CMD_S, 0);
-       roce_set_bit(bt_cmd_h_val, ROCEE_BT_CMD_H_ROCEE_BT_CMD_HW_SYNS_S, 1);
-       roce_set_field(bt_cmd_h_val, ROCEE_BT_CMD_H_ROCEE_BT_CMD_BA_H_M,
-                      ROCEE_BT_CMD_H_ROCEE_BT_CMD_BA_H_S, 0);
-
-       spin_lock_irqsave(&hr_dev->bt_cmd_lock, flags);
-
-       bt_cmd = hr_dev->reg_base + ROCEE_BT_CMD_H_REG;
-
-       end = msecs_to_jiffies(HW_SYNC_TIMEOUT_MSECS) + jiffies;
-       while (1) {
-               if (readl(bt_cmd) >> BT_CMD_SYNC_SHIFT) {
-                       if (!(time_before(jiffies, end))) {
-                               dev_err(dev, "Write bt_cmd err,hw_sync is not zero.\n");
-                               spin_unlock_irqrestore(&hr_dev->bt_cmd_lock,
-                                                      flags);
-                               return -EBUSY;
-                       }
-               } else {
-                       break;
-               }
-               msleep(HW_SYNC_SLEEP_TIME_INTERVAL);
-       }
-
-       bt_cmd_val[0] = 0;
-       bt_cmd_val[1] = bt_cmd_h_val;
-       hns_roce_write64_k(bt_cmd_val, hr_dev->reg_base + ROCEE_BT_CMD_L_REG);
-       spin_unlock_irqrestore(&hr_dev->bt_cmd_lock, flags);
-
-       return ret;
-}
-
 int hns_roce_table_get(struct hns_roce_dev *hr_dev,
                       struct hns_roce_hem_table *table, unsigned long obj)
 {
@@ -333,7 +261,7 @@ void hns_roce_table_put(struct hns_roce_dev *hr_dev,
 
        if (--table->hem[i]->refcount == 0) {
                /* Clear HEM base address */
-               if (hns_roce_clear_hem(hr_dev, table, obj))
+               if (hr_dev->hw->clear_hem(hr_dev, table, obj))
                        dev_warn(dev, "Clear HEM base address failed.\n");
 
                hns_roce_free_hem(hr_dev, table->hem[i]);
@@ -456,7 +384,7 @@ void hns_roce_cleanup_hem_table(struct hns_roce_dev *hr_dev,
 
        for (i = 0; i < table->num_hem; ++i)
                if (table->hem[i]) {
-                       if (hns_roce_clear_hem(hr_dev, table,
+                       if (hr_dev->hw->clear_hem(hr_dev, table,
                            i * HNS_ROCE_TABLE_CHUNK_SIZE / table->obj_size))
                                dev_err(dev, "Clear HEM base address failed.\n");
 
index ad6617588fba9a15eee65e12eb948219ba706670..435748858252d756d065315e5ce4347db46c4477 100644 (file)
 #ifndef _HNS_ROCE_HEM_H
 #define _HNS_ROCE_HEM_H
 
+#define HW_SYNC_TIMEOUT_MSECS          500
+#define HW_SYNC_SLEEP_TIME_INTERVAL    20
+#define BT_CMD_SYNC_SHIFT              31
+
 enum {
        /* MAP HEM(Hardware Entry Memory) */
        HEM_TYPE_QPC = 0,
index 399f5dedaf2dd6dfcd075d7875903b943bed4ec3..71232e5fabf6acccf4002f1fedded380f4376274 100644 (file)
@@ -73,8 +73,14 @@ int hns_roce_v1_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
        u32 ind = 0;
        int ret = 0;
 
-       spin_lock_irqsave(&qp->sq.lock, flags);
+       if (unlikely(ibqp->qp_type != IB_QPT_GSI &&
+               ibqp->qp_type != IB_QPT_RC)) {
+               dev_err(dev, "un-supported QP type\n");
+               *bad_wr = NULL;
+               return -EOPNOTSUPP;
+       }
 
+       spin_lock_irqsave(&qp->sq.lock, flags);
        ind = qp->sq_next_wqe;
        for (nreq = 0; wr; ++nreq, wr = wr->next) {
                if (hns_roce_wq_overflow(&qp->sq, nreq, qp->ibqp.send_cq)) {
@@ -162,7 +168,7 @@ int hns_roce_v1_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
                        roce_set_field(ud_sq_wqe->u32_36,
                                       UD_SEND_WQE_U32_36_SGID_INDEX_M,
                                       UD_SEND_WQE_U32_36_SGID_INDEX_S,
-                                      hns_get_gid_index(hr_dev, qp->port,
+                                      hns_get_gid_index(hr_dev, qp->phy_port,
                                                         ah->av.gid_index));
 
                        roce_set_field(ud_sq_wqe->u32_40,
@@ -205,8 +211,7 @@ int hns_roce_v1_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
                                      (wr->send_flags & IB_SEND_FENCE ?
                                      (cpu_to_le32(HNS_ROCE_WQE_FENCE)) : 0);
 
-                       wqe = (struct hns_roce_wqe_ctrl_seg *)wqe +
-                              sizeof(struct hns_roce_wqe_ctrl_seg);
+                       wqe += sizeof(struct hns_roce_wqe_ctrl_seg);
 
                        switch (wr->opcode) {
                        case IB_WR_RDMA_READ:
@@ -235,8 +240,7 @@ int hns_roce_v1_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
                                break;
                        }
                        ctrl->flag |= cpu_to_le32(ps_opcode);
-                       wqe = (struct hns_roce_wqe_raddr_seg *)wqe +
-                              sizeof(struct hns_roce_wqe_raddr_seg);
+                       wqe += sizeof(struct hns_roce_wqe_raddr_seg);
 
                        dseg = wqe;
                        if (wr->send_flags & IB_SEND_INLINE && wr->num_sge) {
@@ -253,8 +257,7 @@ int hns_roce_v1_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
                                        memcpy(wqe, ((void *) (uintptr_t)
                                               wr->sg_list[i].addr),
                                               wr->sg_list[i].length);
-                                       wqe = (struct hns_roce_wqe_raddr_seg *)
-                                              wqe + wr->sg_list[i].length;
+                                       wqe += wr->sg_list[i].length;
                                }
                                ctrl->flag |= HNS_ROCE_WQE_INLINE;
                        } else {
@@ -266,9 +269,6 @@ int hns_roce_v1_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
                                              HNS_ROCE_WQE_SGE_NUM_BIT);
                        }
                        ind++;
-               } else {
-                       dev_dbg(dev, "unSupported QP type\n");
-                       break;
                }
        }
 
@@ -285,7 +285,7 @@ out:
                               SQ_DOORBELL_U32_4_SQ_HEAD_S,
                              (qp->sq.head & ((qp->sq.wqe_cnt << 1) - 1)));
                roce_set_field(sq_db.u32_4, SQ_DOORBELL_U32_4_PORT_M,
-                              SQ_DOORBELL_U32_4_PORT_S, qp->port);
+                              SQ_DOORBELL_U32_4_PORT_S, qp->phy_port);
                roce_set_field(sq_db.u32_8, SQ_DOORBELL_U32_8_QPN_M,
                               SQ_DOORBELL_U32_8_QPN_S, qp->doorbell_qpn);
                roce_set_bit(sq_db.u32_8, SQ_DOORBELL_HW_SYNC_S, 1);
@@ -365,14 +365,14 @@ out:
                        /* SW update GSI rq header */
                        reg_val = roce_read(to_hr_dev(ibqp->device),
                                            ROCEE_QP1C_CFG3_0_REG +
-                                           QP1C_CFGN_OFFSET * hr_qp->port);
+                                           QP1C_CFGN_OFFSET * hr_qp->phy_port);
                        roce_set_field(reg_val,
                                       ROCEE_QP1C_CFG3_0_ROCEE_QP1C_RQ_HEAD_M,
                                       ROCEE_QP1C_CFG3_0_ROCEE_QP1C_RQ_HEAD_S,
                                       hr_qp->rq.head);
                        roce_write(to_hr_dev(ibqp->device),
                                   ROCEE_QP1C_CFG3_0_REG +
-                                  QP1C_CFGN_OFFSET * hr_qp->port, reg_val);
+                                  QP1C_CFGN_OFFSET * hr_qp->phy_port, reg_val);
                } else {
                        rq_db.u32_4 = 0;
                        rq_db.u32_8 = 0;
@@ -789,6 +789,66 @@ static void hns_roce_port_enable(struct hns_roce_dev *hr_dev, int enable_flag)
        }
 }
 
+static int hns_roce_bt_init(struct hns_roce_dev *hr_dev)
+{
+       struct device *dev = &hr_dev->pdev->dev;
+       struct hns_roce_v1_priv *priv;
+       int ret;
+
+       priv = (struct hns_roce_v1_priv *)hr_dev->hw->priv;
+
+       priv->bt_table.qpc_buf.buf = dma_alloc_coherent(dev,
+               HNS_ROCE_BT_RSV_BUF_SIZE, &priv->bt_table.qpc_buf.map,
+               GFP_KERNEL);
+       if (!priv->bt_table.qpc_buf.buf)
+               return -ENOMEM;
+
+       priv->bt_table.mtpt_buf.buf = dma_alloc_coherent(dev,
+               HNS_ROCE_BT_RSV_BUF_SIZE, &priv->bt_table.mtpt_buf.map,
+               GFP_KERNEL);
+       if (!priv->bt_table.mtpt_buf.buf) {
+               ret = -ENOMEM;
+               goto err_failed_alloc_mtpt_buf;
+       }
+
+       priv->bt_table.cqc_buf.buf = dma_alloc_coherent(dev,
+               HNS_ROCE_BT_RSV_BUF_SIZE, &priv->bt_table.cqc_buf.map,
+               GFP_KERNEL);
+       if (!priv->bt_table.cqc_buf.buf) {
+               ret = -ENOMEM;
+               goto err_failed_alloc_cqc_buf;
+       }
+
+       return 0;
+
+err_failed_alloc_cqc_buf:
+       dma_free_coherent(dev, HNS_ROCE_BT_RSV_BUF_SIZE,
+               priv->bt_table.mtpt_buf.buf, priv->bt_table.mtpt_buf.map);
+
+err_failed_alloc_mtpt_buf:
+       dma_free_coherent(dev, HNS_ROCE_BT_RSV_BUF_SIZE,
+               priv->bt_table.qpc_buf.buf, priv->bt_table.qpc_buf.map);
+
+       return ret;
+}
+
+static void hns_roce_bt_free(struct hns_roce_dev *hr_dev)
+{
+       struct device *dev = &hr_dev->pdev->dev;
+       struct hns_roce_v1_priv *priv;
+
+       priv = (struct hns_roce_v1_priv *)hr_dev->hw->priv;
+
+       dma_free_coherent(dev, HNS_ROCE_BT_RSV_BUF_SIZE,
+               priv->bt_table.cqc_buf.buf, priv->bt_table.cqc_buf.map);
+
+       dma_free_coherent(dev, HNS_ROCE_BT_RSV_BUF_SIZE,
+               priv->bt_table.mtpt_buf.buf, priv->bt_table.mtpt_buf.map);
+
+       dma_free_coherent(dev, HNS_ROCE_BT_RSV_BUF_SIZE,
+               priv->bt_table.qpc_buf.buf, priv->bt_table.qpc_buf.map);
+}
+
 /**
  * hns_roce_v1_reset - reset RoCE
  * @hr_dev: RoCE device struct pointer
@@ -879,7 +939,6 @@ void hns_roce_v1_profile(struct hns_roce_dev *hr_dev)
        caps->mtt_entry_sz      = HNS_ROCE_V1_MTT_ENTRY_SIZE;
        caps->cq_entry_sz       = HNS_ROCE_V1_CQE_ENTRY_SIZE;
        caps->page_size_cap     = HNS_ROCE_V1_PAGE_SIZE_SUPPORT;
-       caps->sqp_start         = 0;
        caps->reserved_lkey     = 0;
        caps->reserved_pds      = 0;
        caps->reserved_mrws     = 1;
@@ -944,8 +1003,18 @@ int hns_roce_v1_init(struct hns_roce_dev *hr_dev)
 
        hns_roce_port_enable(hr_dev, HNS_ROCE_PORT_UP);
 
+       ret = hns_roce_bt_init(hr_dev);
+       if (ret) {
+               dev_err(dev, "bt init failed!\n");
+               goto error_failed_bt_init;
+       }
+
        return 0;
 
+error_failed_bt_init:
+       hns_roce_port_enable(hr_dev, HNS_ROCE_PORT_DOWN);
+       hns_roce_raq_free(hr_dev);
+
 error_failed_raq_init:
        hns_roce_db_free(hr_dev);
        return ret;
@@ -953,6 +1022,7 @@ error_failed_raq_init:
 
 void hns_roce_v1_exit(struct hns_roce_dev *hr_dev)
 {
+       hns_roce_bt_free(hr_dev);
        hns_roce_port_enable(hr_dev, HNS_ROCE_PORT_DOWN);
        hns_roce_raq_free(hr_dev);
        hns_roce_db_free(hr_dev);
@@ -1192,9 +1262,7 @@ static struct hns_roce_cqe *next_cqe_sw(struct hns_roce_cq *hr_cq)
        return get_sw_cqe(hr_cq, hr_cq->cons_index);
 }
 
-void hns_roce_v1_cq_set_ci(struct hns_roce_cq *hr_cq, u32 cons_index,
-                          spinlock_t *doorbell_lock)
-
+void hns_roce_v1_cq_set_ci(struct hns_roce_cq *hr_cq, u32 cons_index)
 {
        u32 doorbell[2];
 
@@ -1254,8 +1322,7 @@ static void __hns_roce_v1_cq_clean(struct hns_roce_cq *hr_cq, u32 qpn,
                */
                wmb();
 
-               hns_roce_v1_cq_set_ci(hr_cq, hr_cq->cons_index,
-                                  &to_hr_dev(hr_cq->ib_cq.device)->cq_db_lock);
+               hns_roce_v1_cq_set_ci(hr_cq, hr_cq->cons_index);
        }
 }
 
@@ -1485,7 +1552,8 @@ static int hns_roce_v1_poll_one(struct hns_roce_cq *hr_cq,
                /* SQ conrespond to CQE */
                sq_wqe = get_send_wqe(*cur_qp, roce_get_field(cqe->cqe_byte_4,
                                                CQE_BYTE_4_WQE_INDEX_M,
-                                               CQE_BYTE_4_WQE_INDEX_S));
+                                               CQE_BYTE_4_WQE_INDEX_S)&
+                                               ((*cur_qp)->sq.wqe_cnt-1));
                switch (sq_wqe->flag & HNS_ROCE_WQE_OPCODE_MASK) {
                case HNS_ROCE_WQE_OPCODE_SEND:
                        wc->opcode = IB_WC_SEND;
@@ -1591,10 +1659,8 @@ int hns_roce_v1_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *wc)
                        break;
        }
 
-       if (npolled) {
-               hns_roce_v1_cq_set_ci(hr_cq, hr_cq->cons_index,
-                                     &to_hr_dev(ibcq->device)->cq_db_lock);
-       }
+       if (npolled)
+               hns_roce_v1_cq_set_ci(hr_cq, hr_cq->cons_index);
 
        spin_unlock_irqrestore(&hr_cq->lock, flags);
 
@@ -1604,6 +1670,74 @@ int hns_roce_v1_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *wc)
                return ret;
 }
 
+int hns_roce_v1_clear_hem(struct hns_roce_dev *hr_dev,
+               struct hns_roce_hem_table *table, int obj)
+{
+       struct device *dev = &hr_dev->pdev->dev;
+       struct hns_roce_v1_priv *priv;
+       unsigned long end = 0, flags = 0;
+       uint32_t bt_cmd_val[2] = {0};
+       void __iomem *bt_cmd;
+       u64 bt_ba = 0;
+
+       priv = (struct hns_roce_v1_priv *)hr_dev->hw->priv;
+
+       switch (table->type) {
+       case HEM_TYPE_QPC:
+               roce_set_field(bt_cmd_val[1], ROCEE_BT_CMD_H_ROCEE_BT_CMD_MDF_M,
+                       ROCEE_BT_CMD_H_ROCEE_BT_CMD_MDF_S, HEM_TYPE_QPC);
+               bt_ba = priv->bt_table.qpc_buf.map >> 12;
+               break;
+       case HEM_TYPE_MTPT:
+               roce_set_field(bt_cmd_val[1], ROCEE_BT_CMD_H_ROCEE_BT_CMD_MDF_M,
+                       ROCEE_BT_CMD_H_ROCEE_BT_CMD_MDF_S, HEM_TYPE_MTPT);
+               bt_ba = priv->bt_table.mtpt_buf.map >> 12;
+               break;
+       case HEM_TYPE_CQC:
+               roce_set_field(bt_cmd_val[1], ROCEE_BT_CMD_H_ROCEE_BT_CMD_MDF_M,
+                       ROCEE_BT_CMD_H_ROCEE_BT_CMD_MDF_S, HEM_TYPE_CQC);
+               bt_ba = priv->bt_table.cqc_buf.map >> 12;
+               break;
+       case HEM_TYPE_SRQC:
+               dev_dbg(dev, "HEM_TYPE_SRQC not support.\n");
+               return -EINVAL;
+       default:
+               return 0;
+       }
+       roce_set_field(bt_cmd_val[1], ROCEE_BT_CMD_H_ROCEE_BT_CMD_IN_MDF_M,
+               ROCEE_BT_CMD_H_ROCEE_BT_CMD_IN_MDF_S, obj);
+       roce_set_bit(bt_cmd_val[1], ROCEE_BT_CMD_H_ROCEE_BT_CMD_S, 0);
+       roce_set_bit(bt_cmd_val[1], ROCEE_BT_CMD_H_ROCEE_BT_CMD_HW_SYNS_S, 1);
+
+       spin_lock_irqsave(&hr_dev->bt_cmd_lock, flags);
+
+       bt_cmd = hr_dev->reg_base + ROCEE_BT_CMD_H_REG;
+
+       end = msecs_to_jiffies(HW_SYNC_TIMEOUT_MSECS) + jiffies;
+       while (1) {
+               if (readl(bt_cmd) >> BT_CMD_SYNC_SHIFT) {
+                       if (!(time_before(jiffies, end))) {
+                               dev_err(dev, "Write bt_cmd err,hw_sync is not zero.\n");
+                               spin_unlock_irqrestore(&hr_dev->bt_cmd_lock,
+                                       flags);
+                               return -EBUSY;
+                       }
+               } else {
+                       break;
+               }
+               msleep(HW_SYNC_SLEEP_TIME_INTERVAL);
+       }
+
+       bt_cmd_val[0] = (uint32_t)bt_ba;
+       roce_set_field(bt_cmd_val[1], ROCEE_BT_CMD_H_ROCEE_BT_CMD_BA_H_M,
+               ROCEE_BT_CMD_H_ROCEE_BT_CMD_BA_H_S, bt_ba >> 32);
+       hns_roce_write64_k(bt_cmd_val, hr_dev->reg_base + ROCEE_BT_CMD_L_REG);
+
+       spin_unlock_irqrestore(&hr_dev->bt_cmd_lock, flags);
+
+       return 0;
+}
+
 static int hns_roce_v1_qp_modify(struct hns_roce_dev *hr_dev,
                                 struct hns_roce_mtt *mtt,
                                 enum hns_roce_qp_state cur_state,
@@ -1733,13 +1867,10 @@ static int hns_roce_v1_m_sqp(struct ib_qp *ibqp, const struct ib_qp_attr *attr,
                roce_set_field(context->qp1c_bytes_16, QP1C_BYTES_16_RQ_HEAD_M,
                               QP1C_BYTES_16_RQ_HEAD_S, hr_qp->rq.head);
                roce_set_field(context->qp1c_bytes_16, QP1C_BYTES_16_PORT_NUM_M,
-                              QP1C_BYTES_16_PORT_NUM_S, hr_qp->port);
+                              QP1C_BYTES_16_PORT_NUM_S, hr_qp->phy_port);
                roce_set_bit(context->qp1c_bytes_16,
                             QP1C_BYTES_16_SIGNALING_TYPE_S,
                             hr_qp->sq_signal_bits);
-               roce_set_bit(context->qp1c_bytes_16,
-                            QP1C_BYTES_16_LOCAL_ENABLE_E2E_CREDIT_S,
-                            hr_qp->sq_signal_bits);
                roce_set_bit(context->qp1c_bytes_16, QP1C_BYTES_16_RQ_BA_FLG_S,
                             1);
                roce_set_bit(context->qp1c_bytes_16, QP1C_BYTES_16_SQ_BA_FLG_S,
@@ -1784,7 +1915,7 @@ static int hns_roce_v1_m_sqp(struct ib_qp *ibqp, const struct ib_qp_attr *attr,
 
                /* Copy context to QP1C register */
                addr = (u32 *)(hr_dev->reg_base + ROCEE_QP1C_CFG0_0_REG +
-                       hr_qp->port * sizeof(*context));
+                       hr_qp->phy_port * sizeof(*context));
 
                writel(context->qp1c_bytes_4, addr);
                writel(context->sq_rq_bt_l, addr + 1);
@@ -1795,15 +1926,16 @@ static int hns_roce_v1_m_sqp(struct ib_qp *ibqp, const struct ib_qp_attr *attr,
                writel(context->qp1c_bytes_28, addr + 6);
                writel(context->qp1c_bytes_32, addr + 7);
                writel(context->cur_sq_wqe_ba_l, addr + 8);
+               writel(context->qp1c_bytes_40, addr + 9);
        }
 
        /* Modify QP1C status */
        reg_val = roce_read(hr_dev, ROCEE_QP1C_CFG0_0_REG +
-                           hr_qp->port * sizeof(*context));
+                           hr_qp->phy_port * sizeof(*context));
        roce_set_field(reg_val, ROCEE_QP1C_CFG0_0_ROCEE_QP1C_QP_ST_M,
                       ROCEE_QP1C_CFG0_0_ROCEE_QP1C_QP_ST_S, new_state);
        roce_write(hr_dev, ROCEE_QP1C_CFG0_0_REG +
-                   hr_qp->port * sizeof(*context), reg_val);
+                   hr_qp->phy_port * sizeof(*context), reg_val);
 
        hr_qp->state = new_state;
        if (new_state == IB_QPS_RESET) {
@@ -1836,12 +1968,10 @@ static int hns_roce_v1_m_qp(struct ib_qp *ibqp, const struct ib_qp_attr *attr,
        struct hns_roce_qp *hr_qp = to_hr_qp(ibqp);
        struct device *dev = &hr_dev->pdev->dev;
        struct hns_roce_qp_context *context;
-       struct hns_roce_rq_db rq_db;
        dma_addr_t dma_handle_2 = 0;
        dma_addr_t dma_handle = 0;
        uint32_t doorbell[2] = {0};
        int rq_pa_start = 0;
-       u32 reg_val = 0;
        u64 *mtts_2 = NULL;
        int ret = -EINVAL;
        u64 *mtts = NULL;
@@ -2119,7 +2249,8 @@ static int hns_roce_v1_m_qp(struct ib_qp *ibqp, const struct ib_qp_attr *attr,
 
                roce_set_field(context->qpc_bytes_68,
                               QP_CONTEXT_QPC_BYTES_68_RQ_HEAD_M,
-                              QP_CONTEXT_QPC_BYTES_68_RQ_HEAD_S, 0);
+                              QP_CONTEXT_QPC_BYTES_68_RQ_HEAD_S,
+                              hr_qp->rq.head);
                roce_set_field(context->qpc_bytes_68,
                               QP_CONTEXT_QPC_BYTES_68_RQ_CUR_INDEX_M,
                               QP_CONTEXT_QPC_BYTES_68_RQ_CUR_INDEX_S, 0);
@@ -2186,7 +2317,7 @@ static int hns_roce_v1_m_qp(struct ib_qp *ibqp, const struct ib_qp_attr *attr,
                roce_set_field(context->qpc_bytes_156,
                               QP_CONTEXT_QPC_BYTES_156_PORT_NUM_M,
                               QP_CONTEXT_QPC_BYTES_156_PORT_NUM_S,
-                              hr_qp->port);
+                              hr_qp->phy_port);
                roce_set_field(context->qpc_bytes_156,
                               QP_CONTEXT_QPC_BYTES_156_SL_M,
                               QP_CONTEXT_QPC_BYTES_156_SL_S, attr->ah_attr.sl);
@@ -2257,20 +2388,17 @@ static int hns_roce_v1_m_qp(struct ib_qp *ibqp, const struct ib_qp_attr *attr,
                roce_set_bit(context->qpc_bytes_140,
                             QP_CONTEXT_QPC_BYTES_140_RNR_RETRY_FLG_S, 0);
 
-               roce_set_field(context->qpc_bytes_144,
-                              QP_CONTEXT_QPC_BYTES_144_QP_STATE_M,
-                              QP_CONTEXT_QPC_BYTES_144_QP_STATE_S,
-                              attr->qp_state);
-
                roce_set_field(context->qpc_bytes_148,
                               QP_CONTEXT_QPC_BYTES_148_CHECK_FLAG_M,
                               QP_CONTEXT_QPC_BYTES_148_CHECK_FLAG_S, 0);
                roce_set_field(context->qpc_bytes_148,
                               QP_CONTEXT_QPC_BYTES_148_RETRY_COUNT_M,
-                              QP_CONTEXT_QPC_BYTES_148_RETRY_COUNT_S, 0);
+                              QP_CONTEXT_QPC_BYTES_148_RETRY_COUNT_S,
+                              attr->retry_cnt);
                roce_set_field(context->qpc_bytes_148,
                               QP_CONTEXT_QPC_BYTES_148_RNR_RETRY_COUNT_M,
-                              QP_CONTEXT_QPC_BYTES_148_RNR_RETRY_COUNT_S, 0);
+                              QP_CONTEXT_QPC_BYTES_148_RNR_RETRY_COUNT_S,
+                              attr->rnr_retry);
                roce_set_field(context->qpc_bytes_148,
                               QP_CONTEXT_QPC_BYTES_148_LSN_M,
                               QP_CONTEXT_QPC_BYTES_148_LSN_S, 0x100);
@@ -2281,10 +2409,19 @@ static int hns_roce_v1_m_qp(struct ib_qp *ibqp, const struct ib_qp_attr *attr,
                               QP_CONTEXT_QPC_BYTES_156_RETRY_COUNT_INIT_M,
                               QP_CONTEXT_QPC_BYTES_156_RETRY_COUNT_INIT_S,
                               attr->retry_cnt);
-               roce_set_field(context->qpc_bytes_156,
-                              QP_CONTEXT_QPC_BYTES_156_ACK_TIMEOUT_M,
-                              QP_CONTEXT_QPC_BYTES_156_ACK_TIMEOUT_S,
-                              attr->timeout);
+               if (attr->timeout < 0x12) {
+                       dev_info(dev, "ack timeout value(0x%x) must bigger than 0x12.\n",
+                                attr->timeout);
+                       roce_set_field(context->qpc_bytes_156,
+                                      QP_CONTEXT_QPC_BYTES_156_ACK_TIMEOUT_M,
+                                      QP_CONTEXT_QPC_BYTES_156_ACK_TIMEOUT_S,
+                                      0x12);
+               } else {
+                       roce_set_field(context->qpc_bytes_156,
+                                      QP_CONTEXT_QPC_BYTES_156_ACK_TIMEOUT_M,
+                                      QP_CONTEXT_QPC_BYTES_156_ACK_TIMEOUT_S,
+                                      attr->timeout);
+               }
                roce_set_field(context->qpc_bytes_156,
                               QP_CONTEXT_QPC_BYTES_156_RNR_RETRY_COUNT_INIT_M,
                               QP_CONTEXT_QPC_BYTES_156_RNR_RETRY_COUNT_INIT_S,
@@ -2292,7 +2429,7 @@ static int hns_roce_v1_m_qp(struct ib_qp *ibqp, const struct ib_qp_attr *attr,
                roce_set_field(context->qpc_bytes_156,
                               QP_CONTEXT_QPC_BYTES_156_PORT_NUM_M,
                               QP_CONTEXT_QPC_BYTES_156_PORT_NUM_S,
-                              hr_qp->port);
+                              hr_qp->phy_port);
                roce_set_field(context->qpc_bytes_156,
                               QP_CONTEXT_QPC_BYTES_156_SL_M,
                               QP_CONTEXT_QPC_BYTES_156_SL_S, attr->ah_attr.sl);
@@ -2357,21 +2494,15 @@ static int hns_roce_v1_m_qp(struct ib_qp *ibqp, const struct ib_qp_attr *attr,
                               QP_CONTEXT_QPC_BYTES_188_TX_RETRY_CUR_INDEX_M,
                               QP_CONTEXT_QPC_BYTES_188_TX_RETRY_CUR_INDEX_S,
                               0);
-       } else if ((cur_state == IB_QPS_INIT && new_state == IB_QPS_RESET) ||
+       } else if (!((cur_state == IB_QPS_INIT && new_state == IB_QPS_RESET) ||
                   (cur_state == IB_QPS_INIT && new_state == IB_QPS_ERR) ||
                   (cur_state == IB_QPS_RTR && new_state == IB_QPS_RESET) ||
                   (cur_state == IB_QPS_RTR && new_state == IB_QPS_ERR) ||
                   (cur_state == IB_QPS_RTS && new_state == IB_QPS_RESET) ||
                   (cur_state == IB_QPS_RTS && new_state == IB_QPS_ERR) ||
                   (cur_state == IB_QPS_ERR && new_state == IB_QPS_RESET) ||
-                  (cur_state == IB_QPS_ERR && new_state == IB_QPS_ERR)) {
-               roce_set_field(context->qpc_bytes_144,
-                              QP_CONTEXT_QPC_BYTES_144_QP_STATE_M,
-                              QP_CONTEXT_QPC_BYTES_144_QP_STATE_S,
-                              attr->qp_state);
-
-       } else {
-               dev_err(dev, "not support this modify\n");
+                  (cur_state == IB_QPS_ERR && new_state == IB_QPS_ERR))) {
+               dev_err(dev, "not support this status migration\n");
                goto out;
        }
 
@@ -2397,43 +2528,32 @@ static int hns_roce_v1_m_qp(struct ib_qp *ibqp, const struct ib_qp_attr *attr,
        if (cur_state == IB_QPS_INIT && new_state == IB_QPS_INIT) {
                /* Memory barrier */
                wmb();
-               if (hr_qp->ibqp.qp_type == IB_QPT_GSI) {
-                       /* SW update GSI rq header */
-                       reg_val = roce_read(hr_dev, ROCEE_QP1C_CFG3_0_REG +
-                                           QP1C_CFGN_OFFSET * hr_qp->port);
-                       roce_set_field(reg_val,
-                                      ROCEE_QP1C_CFG3_0_ROCEE_QP1C_RQ_HEAD_M,
-                                      ROCEE_QP1C_CFG3_0_ROCEE_QP1C_RQ_HEAD_S,
-                                      hr_qp->rq.head);
-                       roce_write(hr_dev, ROCEE_QP1C_CFG3_0_REG +
-                                   QP1C_CFGN_OFFSET * hr_qp->port, reg_val);
-               } else {
-                       rq_db.u32_4 = 0;
-                       rq_db.u32_8 = 0;
-
-                       roce_set_field(rq_db.u32_4, RQ_DOORBELL_U32_4_RQ_HEAD_M,
-                                      RQ_DOORBELL_U32_4_RQ_HEAD_S,
-                                      hr_qp->rq.head);
-                       roce_set_field(rq_db.u32_8, RQ_DOORBELL_U32_8_QPN_M,
-                                      RQ_DOORBELL_U32_8_QPN_S, hr_qp->qpn);
-                       roce_set_field(rq_db.u32_8, RQ_DOORBELL_U32_8_CMD_M,
-                                      RQ_DOORBELL_U32_8_CMD_S, 1);
-                       roce_set_bit(rq_db.u32_8, RQ_DOORBELL_U32_8_HW_SYNC_S,
-                                    1);
 
-                       doorbell[0] = rq_db.u32_4;
-                       doorbell[1] = rq_db.u32_8;
-
-                       hns_roce_write64_k(doorbell, hr_qp->rq.db_reg_l);
+               roce_set_field(doorbell[0], RQ_DOORBELL_U32_4_RQ_HEAD_M,
+                              RQ_DOORBELL_U32_4_RQ_HEAD_S, hr_qp->rq.head);
+               roce_set_field(doorbell[1], RQ_DOORBELL_U32_8_QPN_M,
+                              RQ_DOORBELL_U32_8_QPN_S, hr_qp->qpn);
+               roce_set_field(doorbell[1], RQ_DOORBELL_U32_8_CMD_M,
+                              RQ_DOORBELL_U32_8_CMD_S, 1);
+               roce_set_bit(doorbell[1], RQ_DOORBELL_U32_8_HW_SYNC_S, 1);
+
+               if (ibqp->uobject) {
+                       hr_qp->rq.db_reg_l = hr_dev->reg_base +
+                                    ROCEE_DB_OTHERS_L_0_REG +
+                                    DB_REG_OFFSET * hr_dev->priv_uar.index;
                }
+
+               hns_roce_write64_k(doorbell, hr_qp->rq.db_reg_l);
        }
 
        hr_qp->state = new_state;
 
        if (attr_mask & IB_QP_MAX_DEST_RD_ATOMIC)
                hr_qp->resp_depth = attr->max_dest_rd_atomic;
-       if (attr_mask & IB_QP_PORT)
-               hr_qp->port = (attr->port_num - 1);
+       if (attr_mask & IB_QP_PORT) {
+               hr_qp->port = attr->port_num - 1;
+               hr_qp->phy_port = hr_dev->iboe.phy_port[hr_qp->port];
+       }
 
        if (new_state == IB_QPS_RESET && !ibqp->uobject) {
                hns_roce_v1_cq_clean(to_hr_cq(ibqp->recv_cq), hr_qp->qpn,
@@ -2789,6 +2909,7 @@ struct hns_roce_hw hns_roce_hw_v1 = {
        .set_mtu = hns_roce_v1_set_mtu,
        .write_mtpt = hns_roce_v1_write_mtpt,
        .write_cqc = hns_roce_v1_write_cqc,
+       .clear_hem = hns_roce_v1_clear_hem,
        .modify_qp = hns_roce_v1_modify_qp,
        .query_qp = hns_roce_v1_query_qp,
        .destroy_qp = hns_roce_v1_destroy_qp,
index 316b592b1636df29be7939c4d7ca11abbdfce125..539b0a3b92b09a17dd663497c62b2607a8e94878 100644 (file)
 #define HNS_ROCE_V1_EXT_ODB_ALFUL      \
        (HNS_ROCE_V1_EXT_ODB_DEPTH - HNS_ROCE_V1_DB_RSVD)
 
+#define HNS_ROCE_BT_RSV_BUF_SIZE                       (1 << 17)
+
 #define HNS_ROCE_ODB_POLL_MODE                         0
 
 #define HNS_ROCE_SDB_NORMAL_MODE                       0
@@ -971,9 +973,16 @@ struct hns_roce_db_table {
        struct hns_roce_ext_db *ext_db;
 };
 
+struct hns_roce_bt_table {
+       struct hns_roce_buf_list qpc_buf;
+       struct hns_roce_buf_list mtpt_buf;
+       struct hns_roce_buf_list cqc_buf;
+};
+
 struct hns_roce_v1_priv {
        struct hns_roce_db_table  db_table;
        struct hns_roce_raq_table raq_table;
+       struct hns_roce_bt_table  bt_table;
 };
 
 int hns_dsaf_roce_reset(struct fwnode_handle *dsaf_fwnode, bool dereset);
index f64f0dde9a882c7ee697d990e4bf7acae6765610..764e35a54457e7c0c8bfde46577df1e3962d833c 100644 (file)
@@ -355,8 +355,7 @@ static int hns_roce_query_device(struct ib_device *ib_dev,
        props->max_qp = hr_dev->caps.num_qps;
        props->max_qp_wr = hr_dev->caps.max_wqes;
        props->device_cap_flags = IB_DEVICE_PORT_ACTIVE_EVENT |
-                                 IB_DEVICE_RC_RNR_NAK_GEN |
-                                 IB_DEVICE_LOCAL_DMA_LKEY;
+                                 IB_DEVICE_RC_RNR_NAK_GEN;
        props->max_sge = hr_dev->caps.max_sq_sg;
        props->max_sge_rd = 1;
        props->max_cq = hr_dev->caps.num_cqs;
@@ -372,6 +371,25 @@ static int hns_roce_query_device(struct ib_device *ib_dev,
        return 0;
 }
 
+static struct net_device *hns_roce_get_netdev(struct ib_device *ib_dev,
+                                             u8 port_num)
+{
+       struct hns_roce_dev *hr_dev = to_hr_dev(ib_dev);
+       struct net_device *ndev;
+
+       if (port_num < 1 || port_num > hr_dev->caps.num_ports)
+               return NULL;
+
+       rcu_read_lock();
+
+       ndev = hr_dev->iboe.netdevs[port_num - 1];
+       if (ndev)
+               dev_hold(ndev);
+
+       rcu_read_unlock();
+       return ndev;
+}
+
 static int hns_roce_query_port(struct ib_device *ib_dev, u8 port_num,
                               struct ib_port_attr *props)
 {
@@ -584,6 +602,7 @@ static int hns_roce_register_device(struct hns_roce_dev *hr_dev)
        struct device *dev = &hr_dev->pdev->dev;
 
        iboe = &hr_dev->iboe;
+       spin_lock_init(&iboe->lock);
 
        ib_dev = &hr_dev->ib_dev;
        strlcpy(ib_dev->name, "hisi_%d", IB_DEVICE_NAME_MAX);
@@ -618,6 +637,7 @@ static int hns_roce_register_device(struct hns_roce_dev *hr_dev)
        ib_dev->query_port              = hns_roce_query_port;
        ib_dev->modify_port             = hns_roce_modify_port;
        ib_dev->get_link_layer          = hns_roce_get_link_layer;
+       ib_dev->get_netdev              = hns_roce_get_netdev;
        ib_dev->query_gid               = hns_roce_query_gid;
        ib_dev->query_pkey              = hns_roce_query_pkey;
        ib_dev->alloc_ucontext          = hns_roce_alloc_ucontext;
@@ -667,8 +687,6 @@ static int hns_roce_register_device(struct hns_roce_dev *hr_dev)
                goto error_failed_setup_mtu_gids;
        }
 
-       spin_lock_init(&iboe->lock);
-
        iboe->nb.notifier_call = hns_roce_netdev_event;
        ret = register_netdevice_notifier(&iboe->nb);
        if (ret) {
@@ -777,6 +795,15 @@ static int hns_roce_get_cfg(struct hns_roce_dev *hr_dev)
        if (IS_ERR(hr_dev->reg_base))
                return PTR_ERR(hr_dev->reg_base);
 
+       /* read the node_guid of IB device from the DT or ACPI */
+       ret = device_property_read_u8_array(dev, "node-guid",
+                                           (u8 *)&hr_dev->ib_dev.node_guid,
+                                           GUID_LEN);
+       if (ret) {
+               dev_err(dev, "couldn't get node_guid from DT or ACPI!\n");
+               return ret;
+       }
+
        /* get the RoCE associated ethernet ports or netdevices */
        for (i = 0; i < HNS_ROCE_MAX_PORTS; i++) {
                if (dev_of_node(dev)) {
@@ -923,7 +950,6 @@ static int hns_roce_setup_hca(struct hns_roce_dev *hr_dev)
        struct device *dev = &hr_dev->pdev->dev;
 
        spin_lock_init(&hr_dev->sm_lock);
-       spin_lock_init(&hr_dev->cq_db_lock);
        spin_lock_init(&hr_dev->bt_cmd_lock);
 
        ret = hns_roce_init_uar_table(hr_dev);
index 59f5e2be046b326c7a3f0a8a2355f2ac33df4ab5..fb87883ead340423e087e14331487f735ec6e55f 100644 (file)
@@ -564,11 +564,14 @@ struct ib_mr *hns_roce_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
        if (mr->umem->page_size != HNS_ROCE_HEM_PAGE_SIZE) {
                dev_err(dev, "Just support 4K page size but is 0x%x now!\n",
                        mr->umem->page_size);
+               ret = -EINVAL;
+               goto err_umem;
        }
 
        if (n > HNS_ROCE_MAX_MTPT_PBL_NUM) {
                dev_err(dev, " MR len %lld err. MR is limited to 4G at most!\n",
                        length);
+               ret = -EINVAL;
                goto err_umem;
        }
 
index 16271b5bd1701deceaab511e9ad7d8813d555a6d..05db7d59812a6db5eb014a87e0d3566122442719 100644 (file)
 
 static int hns_roce_pd_alloc(struct hns_roce_dev *hr_dev, unsigned long *pdn)
 {
-       struct device *dev = &hr_dev->pdev->dev;
-       unsigned long pd_number;
-       int ret = 0;
-
-       ret = hns_roce_bitmap_alloc(&hr_dev->pd_bitmap, &pd_number);
-       if (ret == -1) {
-               dev_err(dev, "alloc pdn from pdbitmap failed\n");
-               return -ENOMEM;
-       }
-
-       *pdn = pd_number;
-
-       return 0;
+       return hns_roce_bitmap_alloc(&hr_dev->pd_bitmap, pdn);
 }
 
 static void hns_roce_pd_free(struct hns_roce_dev *hr_dev, unsigned long pdn)
@@ -117,9 +105,15 @@ int hns_roce_uar_alloc(struct hns_roce_dev *hr_dev, struct hns_roce_uar *uar)
        if (ret == -1)
                return -ENOMEM;
 
-       uar->index = (uar->index - 1) % hr_dev->caps.phy_num_uars + 1;
+       if (uar->index > 0)
+               uar->index = (uar->index - 1) %
+                            (hr_dev->caps.phy_num_uars - 1) + 1;
 
        res = platform_get_resource(hr_dev->pdev, IORESOURCE_MEM, 0);
+       if (!res) {
+               dev_err(&hr_dev->pdev->dev, "memory resource not found!\n");
+               return -EINVAL;
+       }
        uar->pfn = ((res->start) >> PAGE_SHIFT) + uar->index;
 
        return 0;
index 645c18d809a5de94bfb2120caca67efda242e928..e86dd8d0677760c4aa38432405b9dd977b35c610 100644 (file)
  */
 
 #include <linux/platform_device.h>
+#include <rdma/ib_addr.h>
 #include <rdma/ib_umem.h>
 #include "hns_roce_common.h"
 #include "hns_roce_device.h"
 #include "hns_roce_hem.h"
 #include "hns_roce_user.h"
 
-#define DB_REG_OFFSET                  0x1000
-#define SQP_NUM                                12
+#define SQP_NUM                                (2 * HNS_ROCE_MAX_PORTS)
 
 void hns_roce_qp_event(struct hns_roce_dev *hr_dev, u32 qpn, int event_type)
 {
@@ -113,16 +113,8 @@ static int hns_roce_reserve_range_qp(struct hns_roce_dev *hr_dev, int cnt,
                                     int align, unsigned long *base)
 {
        struct hns_roce_qp_table *qp_table = &hr_dev->qp_table;
-       int ret = 0;
-       unsigned long qpn;
-
-       ret = hns_roce_bitmap_alloc_range(&qp_table->bitmap, cnt, align, &qpn);
-       if (ret == -1)
-               return -ENOMEM;
-
-       *base = qpn;
 
-       return 0;
+       return hns_roce_bitmap_alloc_range(&qp_table->bitmap, cnt, align, base);
 }
 
 enum hns_roce_qp_state to_hns_roce_state(enum ib_qp_state state)
@@ -255,7 +247,7 @@ void hns_roce_release_range_qp(struct hns_roce_dev *hr_dev, int base_qpn,
 {
        struct hns_roce_qp_table *qp_table = &hr_dev->qp_table;
 
-       if (base_qpn < (hr_dev->caps.sqp_start + 2 * hr_dev->caps.num_ports))
+       if (base_qpn < SQP_NUM)
                return;
 
        hns_roce_bitmap_free_range(&qp_table->bitmap, base_qpn, cnt);
@@ -345,12 +337,10 @@ static int hns_roce_set_user_sq_size(struct hns_roce_dev *hr_dev,
 
 static int hns_roce_set_kernel_sq_size(struct hns_roce_dev *hr_dev,
                                       struct ib_qp_cap *cap,
-                                      enum ib_qp_type type,
                                       struct hns_roce_qp *hr_qp)
 {
        struct device *dev = &hr_dev->pdev->dev;
        u32 max_cnt;
-       (void)type;
 
        if (cap->max_send_wr  > hr_dev->caps.max_wqes  ||
            cap->max_send_sge > hr_dev->caps.max_sq_sg ||
@@ -476,7 +466,7 @@ static int hns_roce_create_qp_common(struct hns_roce_dev *hr_dev,
 
                /* Set SQ size */
                ret = hns_roce_set_kernel_sq_size(hr_dev, &init_attr->cap,
-                                                 init_attr->qp_type, hr_qp);
+                                                 hr_qp);
                if (ret) {
                        dev_err(dev, "hns_roce_set_kernel_sq_size error!\n");
                        goto err_out;
@@ -617,21 +607,19 @@ struct ib_qp *hns_roce_create_qp(struct ib_pd *pd,
                        return ERR_PTR(-ENOMEM);
 
                hr_qp = &hr_sqp->hr_qp;
+               hr_qp->port = init_attr->port_num - 1;
+               hr_qp->phy_port = hr_dev->iboe.phy_port[hr_qp->port];
+               hr_qp->ibqp.qp_num = HNS_ROCE_MAX_PORTS +
+                                    hr_dev->iboe.phy_port[hr_qp->port];
 
                ret = hns_roce_create_qp_common(hr_dev, pd, init_attr, udata,
-                                               hr_dev->caps.sqp_start +
-                                               hr_dev->caps.num_ports +
-                                               init_attr->port_num - 1, hr_qp);
+                                               hr_qp->ibqp.qp_num, hr_qp);
                if (ret) {
                        dev_err(dev, "Create GSI QP failed!\n");
                        kfree(hr_sqp);
                        return ERR_PTR(ret);
                }
 
-               hr_qp->port = (init_attr->port_num - 1);
-               hr_qp->ibqp.qp_num = hr_dev->caps.sqp_start +
-                                    hr_dev->caps.num_ports +
-                                    init_attr->port_num - 1;
                break;
        }
        default:{
@@ -670,6 +658,7 @@ int hns_roce_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
        struct device *dev = &hr_dev->pdev->dev;
        int ret = -EINVAL;
        int p;
+       enum ib_mtu active_mtu;
 
        mutex_lock(&hr_qp->mutex);
 
@@ -700,6 +689,19 @@ int hns_roce_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
                }
        }
 
+       if (attr_mask & IB_QP_PATH_MTU) {
+               p = attr_mask & IB_QP_PORT ? (attr->port_num - 1) : hr_qp->port;
+               active_mtu = iboe_get_mtu(hr_dev->iboe.netdevs[p]->mtu);
+
+               if (attr->path_mtu > IB_MTU_2048 ||
+                   attr->path_mtu < IB_MTU_256 ||
+                   attr->path_mtu > active_mtu) {
+                       dev_err(dev, "attr path_mtu(%d)invalid while modify qp",
+                               attr->path_mtu);
+                       goto out;
+               }
+       }
+
        if (attr_mask & IB_QP_MAX_QP_RD_ATOMIC &&
            attr->max_rd_atomic > hr_dev->caps.max_qp_init_rdma) {
                dev_err(dev, "attr max_rd_atomic invalid.attr->max_rd_atomic=%d\n",
@@ -782,29 +784,11 @@ static void *get_wqe(struct hns_roce_qp *hr_qp, int offset)
 
 void *get_recv_wqe(struct hns_roce_qp *hr_qp, int n)
 {
-       struct ib_qp *ibqp = &hr_qp->ibqp;
-       struct hns_roce_dev *hr_dev = to_hr_dev(ibqp->device);
-
-       if ((n < 0) || (n > hr_qp->rq.wqe_cnt)) {
-               dev_err(&hr_dev->pdev->dev, "rq wqe index:%d,rq wqe cnt:%d\r\n",
-                       n, hr_qp->rq.wqe_cnt);
-               return NULL;
-       }
-
        return get_wqe(hr_qp, hr_qp->rq.offset + (n << hr_qp->rq.wqe_shift));
 }
 
 void *get_send_wqe(struct hns_roce_qp *hr_qp, int n)
 {
-       struct ib_qp *ibqp = &hr_qp->ibqp;
-       struct hns_roce_dev *hr_dev = to_hr_dev(ibqp->device);
-
-       if ((n < 0) || (n > hr_qp->sq.wqe_cnt)) {
-               dev_err(&hr_dev->pdev->dev, "sq wqe index:%d,sq wqe cnt:%d\r\n",
-                       n, hr_qp->sq.wqe_cnt);
-               return NULL;
-       }
-
        return get_wqe(hr_qp, hr_qp->sq.offset + (n << hr_qp->sq.wqe_shift));
 }
 
@@ -837,8 +821,7 @@ int hns_roce_init_qp_table(struct hns_roce_dev *hr_dev)
 
        /* A port include two SQP, six port total 12 */
        ret = hns_roce_bitmap_init(&qp_table->bitmap, hr_dev->caps.num_qps,
-                                  hr_dev->caps.num_qps - 1,
-                                  hr_dev->caps.sqp_start + SQP_NUM,
+                                  hr_dev->caps.num_qps - 1, SQP_NUM,
                                   reserved_from_top);
        if (ret) {
                dev_err(&hr_dev->pdev->dev, "qp bitmap init failed!error=%d\n",
index 936f07a4e35f41265de96e84c2bab08f13544ad6..6d7de9bfed9a7f2bdf872474f156613740632539 100644 (file)
@@ -103,6 +103,7 @@ static const struct alps_nibble_commands alps_v6_nibble_commands[] = {
                                           6-byte ALPS packet */
 #define ALPS_STICK_BITS                0x100   /* separate stick button bits */
 #define ALPS_BUTTONPAD         0x200   /* device is a clickpad */
+#define ALPS_DUALPOINT_WITH_PRESSURE   0x400   /* device can report trackpoint pressure */
 
 static const struct alps_model_info alps_model_data[] = {
        { { 0x32, 0x02, 0x14 }, 0x00, { ALPS_PROTO_V2, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT } },      /* Toshiba Salellite Pro M10 */
@@ -1156,15 +1157,28 @@ static unsigned char alps_get_pkt_id_ss4_v2(unsigned char *byte)
 {
        unsigned char pkt_id = SS4_PACKET_ID_IDLE;
 
-       if (byte[0] == 0x18 && byte[1] == 0x10 && byte[2] == 0x00 &&
-           (byte[3] & 0x88) == 0x08 && byte[4] == 0x10 && byte[5] == 0x00) {
-               pkt_id = SS4_PACKET_ID_IDLE;
-       } else if (!(byte[3] & 0x10)) {
-               pkt_id = SS4_PACKET_ID_ONE;
-       } else if (!(byte[3] & 0x20)) {
+       switch (byte[3] & 0x30) {
+       case 0x00:
+               if (byte[0] == 0x18 && byte[1] == 0x10 && byte[2] == 0x00 &&
+                   (byte[3] & 0x88) == 0x08 && byte[4] == 0x10 &&
+                   byte[5] == 0x00) {
+                       pkt_id = SS4_PACKET_ID_IDLE;
+               } else {
+                       pkt_id = SS4_PACKET_ID_ONE;
+               }
+               break;
+       case 0x10:
+               /* two-finger finger positions */
                pkt_id = SS4_PACKET_ID_TWO;
-       } else {
+               break;
+       case 0x20:
+               /* stick pointer */
+               pkt_id = SS4_PACKET_ID_STICK;
+               break;
+       case 0x30:
+               /* third and fourth finger positions */
                pkt_id = SS4_PACKET_ID_MULTI;
+               break;
        }
 
        return pkt_id;
@@ -1185,7 +1199,13 @@ static int alps_decode_ss4_v2(struct alps_fields *f,
                f->mt[0].x = SS4_1F_X_V2(p);
                f->mt[0].y = SS4_1F_Y_V2(p);
                f->pressure = ((SS4_1F_Z_V2(p)) * 2) & 0x7f;
-               f->fingers = 1;
+               /*
+                * When a button is held the device will give us events
+                * with x, y, and pressure of 0. This causes annoying jumps
+                * if a touch is released while the button is held.
+                * Handle this by claiming zero contacts.
+                */
+               f->fingers = f->pressure > 0 ? 1 : 0;
                f->first_mp = 0;
                f->is_mp = 0;
                break;
@@ -1246,16 +1266,40 @@ static int alps_decode_ss4_v2(struct alps_fields *f,
                }
                break;
 
+       case SS4_PACKET_ID_STICK:
+               if (!(priv->flags & ALPS_DUALPOINT)) {
+                       psmouse_warn(psmouse,
+                                    "Rejected trackstick packet from non DualPoint device");
+               } else {
+                       int x = (s8)(((p[0] & 1) << 7) | (p[1] & 0x7f));
+                       int y = (s8)(((p[3] & 1) << 7) | (p[2] & 0x7f));
+                       int pressure = (s8)(p[4] & 0x7f);
+
+                       input_report_rel(priv->dev2, REL_X, x);
+                       input_report_rel(priv->dev2, REL_Y, -y);
+                       input_report_abs(priv->dev2, ABS_PRESSURE, pressure);
+               }
+               break;
+
        case SS4_PACKET_ID_IDLE:
        default:
                memset(f, 0, sizeof(struct alps_fields));
                break;
        }
 
-       f->left = !!(SS4_BTN_V2(p) & 0x01);
-       if (!(priv->flags & ALPS_BUTTONPAD)) {
-               f->right = !!(SS4_BTN_V2(p) & 0x02);
-               f->middle = !!(SS4_BTN_V2(p) & 0x04);
+       /* handle buttons */
+       if (pkt_id == SS4_PACKET_ID_STICK) {
+               f->ts_left = !!(SS4_BTN_V2(p) & 0x01);
+               if (!(priv->flags & ALPS_BUTTONPAD)) {
+                       f->ts_right = !!(SS4_BTN_V2(p) & 0x02);
+                       f->ts_middle = !!(SS4_BTN_V2(p) & 0x04);
+               }
+       } else {
+               f->left = !!(SS4_BTN_V2(p) & 0x01);
+               if (!(priv->flags & ALPS_BUTTONPAD)) {
+                       f->right = !!(SS4_BTN_V2(p) & 0x02);
+                       f->middle = !!(SS4_BTN_V2(p) & 0x04);
+               }
        }
 
        return 0;
@@ -1266,6 +1310,7 @@ static void alps_process_packet_ss4_v2(struct psmouse *psmouse)
        struct alps_data *priv = psmouse->private;
        unsigned char *packet = psmouse->packet;
        struct input_dev *dev = psmouse->dev;
+       struct input_dev *dev2 = priv->dev2;
        struct alps_fields *f = &priv->f;
 
        memset(f, 0, sizeof(struct alps_fields));
@@ -1311,6 +1356,13 @@ static void alps_process_packet_ss4_v2(struct psmouse *psmouse)
 
        input_report_abs(dev, ABS_PRESSURE, f->pressure);
        input_sync(dev);
+
+       if (priv->flags & ALPS_DUALPOINT) {
+               input_report_key(dev2, BTN_LEFT, f->ts_left);
+               input_report_key(dev2, BTN_RIGHT, f->ts_right);
+               input_report_key(dev2, BTN_MIDDLE, f->ts_middle);
+               input_sync(dev2);
+       }
 }
 
 static bool alps_is_valid_package_ss4_v2(struct psmouse *psmouse)
@@ -2695,6 +2747,10 @@ static int alps_set_protocol(struct psmouse *psmouse,
                if (alps_set_defaults_ss4_v2(psmouse, priv))
                        return -EIO;
 
+               if (priv->fw_ver[1] == 0x1)
+                       priv->flags |= ALPS_DUALPOINT |
+                                       ALPS_DUALPOINT_WITH_PRESSURE;
+
                break;
        }
 
@@ -2767,6 +2823,9 @@ static int alps_identify(struct psmouse *psmouse, struct alps_data *priv)
                } else if (e7[0] == 0x73 && e7[1] == 0x03 &&
                           e7[2] == 0x14 && ec[1] == 0x02) {
                        protocol = &alps_v8_protocol_data;
+               } else if (e7[0] == 0x73 && e7[1] == 0x03 &&
+                          e7[2] == 0x28 && ec[1] == 0x01) {
+                       protocol = &alps_v8_protocol_data;
                } else {
                        psmouse_dbg(psmouse,
                                    "Likely not an ALPS touchpad: E7=%3ph, EC=%3ph\n", e7, ec);
@@ -2949,6 +3008,10 @@ int alps_init(struct psmouse *psmouse)
 
                input_set_capability(dev2, EV_REL, REL_X);
                input_set_capability(dev2, EV_REL, REL_Y);
+               if (priv->flags & ALPS_DUALPOINT_WITH_PRESSURE) {
+                       input_set_capability(dev2, EV_ABS, ABS_PRESSURE);
+                       input_set_abs_params(dev2, ABS_PRESSURE, 0, 127, 0, 0);
+               }
                input_set_capability(dev2, EV_KEY, BTN_LEFT);
                input_set_capability(dev2, EV_KEY, BTN_RIGHT);
                input_set_capability(dev2, EV_KEY, BTN_MIDDLE);
index d37f814dc4478186eb3db8694d84bb2b0e7a9175..b9417e2d7ad3a7ba01aff4d7c5504a619090b0b5 100644 (file)
  *  or there's button activities.
  * SS4_PACKET_ID_TWO: There's two or more fingers on touchpad
  * SS4_PACKET_ID_MULTI: There's three or more fingers on touchpad
+ * SS4_PACKET_ID_STICK: A stick pointer packet
 */
 enum SS4_PACKET_ID {
        SS4_PACKET_ID_IDLE = 0,
        SS4_PACKET_ID_ONE,
        SS4_PACKET_ID_TWO,
        SS4_PACKET_ID_MULTI,
+       SS4_PACKET_ID_STICK,
 };
 
 #define SS4_COUNT_PER_ELECTRODE                256
index 08e252a424802df0885711509e3e26528ec7b7ba..db7d1d666ac1092e23806793e3c3b4b8e292a766 100644 (file)
@@ -1134,7 +1134,7 @@ static int elantech_get_resolution_v4(struct psmouse *psmouse,
  * System76 Pangolin       0x250f01        ?               2 hw buttons
  * (*) + 3 trackpoint buttons
  * (**) + 0 trackpoint buttons
- * Note: Lenovo L430 and Lenovo L430 have the same fw_version/caps
+ * Note: Lenovo L430 and Lenovo L530 have the same fw_version/caps
  */
 static void elantech_set_buttonpad_prop(struct psmouse *psmouse)
 {
@@ -1159,6 +1159,13 @@ static const struct dmi_system_id elantech_dmi_has_middle_button[] = {
                        DMI_MATCH(DMI_PRODUCT_NAME, "CELSIUS H730"),
                },
        },
+       {
+               /* Fujitsu H760 also has a middle button */
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "CELSIUS H760"),
+               },
+       },
 #endif
        { }
 };
@@ -1503,10 +1510,10 @@ static const struct dmi_system_id elantech_dmi_force_crc_enabled[] = {
                },
        },
        {
-               /* Fujitsu LIFEBOOK E554  does not work with crc_enabled == 0 */
+               /* Fujitsu H760 does not work with crc_enabled == 0 */
                .matches = {
                        DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK E554"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "CELSIUS H760"),
                },
        },
        {
@@ -1516,6 +1523,20 @@ static const struct dmi_system_id elantech_dmi_force_crc_enabled[] = {
                        DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK E544"),
                },
        },
+       {
+               /* Fujitsu LIFEBOOK E554  does not work with crc_enabled == 0 */
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK E554"),
+               },
+       },
+       {
+               /* Fujitsu LIFEBOOK E556 does not work with crc_enabled == 0 */
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK E556"),
+               },
+       },
        {
                /* Fujitsu LIFEBOOK U745 does not work with crc_enabled == 0 */
                .matches = {
index 6f2e0e4f0296999885a40e382bc319ba15fc0253..1ebc2c1debae31e5d1479466085a9d7fbcfc586f 100644 (file)
@@ -221,6 +221,21 @@ static const struct of_device_id rmi_i2c_of_match[] = {
 MODULE_DEVICE_TABLE(of, rmi_i2c_of_match);
 #endif
 
+static void rmi_i2c_regulator_bulk_disable(void *data)
+{
+       struct rmi_i2c_xport *rmi_i2c = data;
+
+       regulator_bulk_disable(ARRAY_SIZE(rmi_i2c->supplies),
+                              rmi_i2c->supplies);
+}
+
+static void rmi_i2c_unregister_transport(void *data)
+{
+       struct rmi_i2c_xport *rmi_i2c = data;
+
+       rmi_unregister_transport_device(&rmi_i2c->xport);
+}
+
 static int rmi_i2c_probe(struct i2c_client *client,
                         const struct i2c_device_id *id)
 {
@@ -264,6 +279,12 @@ static int rmi_i2c_probe(struct i2c_client *client,
        if (retval < 0)
                return retval;
 
+       retval = devm_add_action_or_reset(&client->dev,
+                                         rmi_i2c_regulator_bulk_disable,
+                                         rmi_i2c);
+       if (retval)
+               return retval;
+
        of_property_read_u32(client->dev.of_node, "syna,startup-delay-ms",
                             &rmi_i2c->startup_delay);
 
@@ -294,6 +315,11 @@ static int rmi_i2c_probe(struct i2c_client *client,
                        client->addr);
                return retval;
        }
+       retval = devm_add_action_or_reset(&client->dev,
+                                         rmi_i2c_unregister_transport,
+                                         rmi_i2c);
+       if (retval)
+               return retval;
 
        retval = rmi_i2c_init_irq(client);
        if (retval < 0)
@@ -304,17 +330,6 @@ static int rmi_i2c_probe(struct i2c_client *client,
        return 0;
 }
 
-static int rmi_i2c_remove(struct i2c_client *client)
-{
-       struct rmi_i2c_xport *rmi_i2c = i2c_get_clientdata(client);
-
-       rmi_unregister_transport_device(&rmi_i2c->xport);
-       regulator_bulk_disable(ARRAY_SIZE(rmi_i2c->supplies),
-                              rmi_i2c->supplies);
-
-       return 0;
-}
-
 #ifdef CONFIG_PM_SLEEP
 static int rmi_i2c_suspend(struct device *dev)
 {
@@ -431,7 +446,6 @@ static struct i2c_driver rmi_i2c_driver = {
        },
        .id_table       = rmi_id,
        .probe          = rmi_i2c_probe,
-       .remove         = rmi_i2c_remove,
 };
 
 module_i2c_driver(rmi_i2c_driver);
index 55bd1b34970c90a62005264e257ed774280cfd22..4ebef607e2141ad574fe161366308c08e101dc68 100644 (file)
@@ -396,6 +396,13 @@ static inline int rmi_spi_of_probe(struct spi_device *spi,
 }
 #endif
 
+static void rmi_spi_unregister_transport(void *data)
+{
+       struct rmi_spi_xport *rmi_spi = data;
+
+       rmi_unregister_transport_device(&rmi_spi->xport);
+}
+
 static int rmi_spi_probe(struct spi_device *spi)
 {
        struct rmi_spi_xport *rmi_spi;
@@ -464,6 +471,11 @@ static int rmi_spi_probe(struct spi_device *spi)
                dev_err(&spi->dev, "failed to register transport.\n");
                return retval;
        }
+       retval = devm_add_action_or_reset(&spi->dev,
+                                         rmi_spi_unregister_transport,
+                                         rmi_spi);
+       if (retval)
+               return retval;
 
        retval = rmi_spi_init_irq(spi);
        if (retval < 0)
@@ -473,15 +485,6 @@ static int rmi_spi_probe(struct spi_device *spi)
        return 0;
 }
 
-static int rmi_spi_remove(struct spi_device *spi)
-{
-       struct rmi_spi_xport *rmi_spi = spi_get_drvdata(spi);
-
-       rmi_unregister_transport_device(&rmi_spi->xport);
-
-       return 0;
-}
-
 #ifdef CONFIG_PM_SLEEP
 static int rmi_spi_suspend(struct device *dev)
 {
@@ -577,7 +580,6 @@ static struct spi_driver rmi_spi_driver = {
        },
        .id_table       = rmi_id,
        .probe          = rmi_spi_probe,
-       .remove         = rmi_spi_remove,
 };
 
 module_spi_driver(rmi_spi_driver);
index a5eed2ade53de3a4e1d06776288ec17baba52530..34da81c006b6d80d3df98feffc7651d8eaa3f2c8 100644 (file)
@@ -81,7 +81,7 @@ static inline int i8042_platform_init(void)
                return -EBUSY;
 #endif
 
-       i8042_reset = 1;
+       i8042_reset = I8042_RESET_ALWAYS;
        return 0;
 }
 
index ee1ad27d6ed06ef70370f3096352b37acb1c1368..08a1c10a1448d12db092a1c3f7525e4f5f1b76a2 100644 (file)
@@ -61,7 +61,7 @@ static inline int i8042_platform_init(void)
                return -EBUSY;
 #endif
 
-       i8042_reset = 1;
+       i8042_reset = I8042_RESET_ALWAYS;
 
        return 0;
 }
index f708c75d16f1d919f4e054c94437fb6e4e587866..1aabea43329edf56f2067c73eafca4d140d3ac4b 100644 (file)
@@ -44,7 +44,7 @@ static inline void i8042_write_command(int val)
 
 static inline int i8042_platform_init(void)
 {
-       i8042_reset = 1;
+       i8042_reset = I8042_RESET_ALWAYS;
        return 0;
 }
 
index afcd1c1a05b272b1d615b481f2de9c0a812a2889..6231d63860ee324031d36e6e1c42dd57407dc27f 100644 (file)
@@ -130,7 +130,7 @@ static int __init i8042_platform_init(void)
                }
        }
 
-       i8042_reset = 1;
+       i8042_reset = I8042_RESET_ALWAYS;
 
        return 0;
 }
index 73f5cc124a3606a5cb73406e207d8a27fd4c339e..455747552f858a8819ec18d03317980352e514ea 100644 (file)
@@ -61,7 +61,7 @@ static inline int i8042_platform_init(void)
        if (!request_mem_region(I8042_REGION_START, I8042_REGION_SIZE, "i8042"))
                return -EBUSY;
 
-       i8042_reset = 1;
+       i8042_reset = I8042_RESET_ALWAYS;
        return 0;
 }
 
index 68f5f4a0f1e72f10b35e45243218e6cfbf3d586e..f4bfb4b2d50a356336fdab08124f52085a82f24f 100644 (file)
@@ -510,6 +510,90 @@ static const struct dmi_system_id __initconst i8042_dmi_nomux_table[] = {
        { }
 };
 
+/*
+ * On some Asus laptops, just running self tests cause problems.
+ */
+static const struct dmi_system_id i8042_dmi_noselftest_table[] = {
+       {
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "A455LD"),
+               },
+       },
+       {
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "K401LB"),
+               },
+       },
+       {
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "K501LB"),
+               },
+       },
+       {
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "K501LX"),
+               },
+       },
+       {
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "R409L"),
+               },
+       },
+       {
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "V502LX"),
+               },
+       },
+       {
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "X302LA"),
+               },
+       },
+       {
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "X450LCP"),
+               },
+       },
+       {
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "X450LD"),
+               },
+       },
+       {
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "X455LAB"),
+               },
+       },
+       {
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "X455LDB"),
+               },
+       },
+       {
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "X455LF"),
+               },
+       },
+       {
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "Z450LA"),
+               },
+       },
+       { }
+};
 static const struct dmi_system_id __initconst i8042_dmi_reset_table[] = {
        {
                /* MSI Wind U-100 */
@@ -1072,12 +1156,18 @@ static int __init i8042_platform_init(void)
                return retval;
 
 #if defined(__ia64__)
-        i8042_reset = true;
+        i8042_reset = I8042_RESET_ALWAYS;
 #endif
 
 #ifdef CONFIG_X86
-       if (dmi_check_system(i8042_dmi_reset_table))
-               i8042_reset = true;
+       /* Honor module parameter when value is not default */
+       if (i8042_reset == I8042_RESET_DEFAULT) {
+               if (dmi_check_system(i8042_dmi_reset_table))
+                       i8042_reset = I8042_RESET_ALWAYS;
+
+               if (dmi_check_system(i8042_dmi_noselftest_table))
+                       i8042_reset = I8042_RESET_NEVER;
+       }
 
        if (dmi_check_system(i8042_dmi_noloop_table))
                i8042_noloop = true;
index 405252a884dd41e233da4399ab109f213becb85a..89abfdb539ac750ff50eca67f77b2fe6898ff6f0 100644 (file)
@@ -48,9 +48,39 @@ static bool i8042_unlock;
 module_param_named(unlock, i8042_unlock, bool, 0);
 MODULE_PARM_DESC(unlock, "Ignore keyboard lock.");
 
-static bool i8042_reset;
-module_param_named(reset, i8042_reset, bool, 0);
-MODULE_PARM_DESC(reset, "Reset controller during init and cleanup.");
+enum i8042_controller_reset_mode {
+       I8042_RESET_NEVER,
+       I8042_RESET_ALWAYS,
+       I8042_RESET_ON_S2RAM,
+#define I8042_RESET_DEFAULT    I8042_RESET_ON_S2RAM
+};
+static enum i8042_controller_reset_mode i8042_reset = I8042_RESET_DEFAULT;
+static int i8042_set_reset(const char *val, const struct kernel_param *kp)
+{
+       enum i8042_controller_reset_mode *arg = kp->arg;
+       int error;
+       bool reset;
+
+       if (val) {
+               error = kstrtobool(val, &reset);
+               if (error)
+                       return error;
+       } else {
+               reset = true;
+       }
+
+       *arg = reset ? I8042_RESET_ALWAYS : I8042_RESET_NEVER;
+       return 0;
+}
+
+static const struct kernel_param_ops param_ops_reset_param = {
+       .flags = KERNEL_PARAM_OPS_FL_NOARG,
+       .set = i8042_set_reset,
+};
+#define param_check_reset_param(name, p)       \
+       __param_check(name, p, enum i8042_controller_reset_mode)
+module_param_named(reset, i8042_reset, reset_param, 0);
+MODULE_PARM_DESC(reset, "Reset controller on resume, cleanup or both");
 
 static bool i8042_direct;
 module_param_named(direct, i8042_direct, bool, 0);
@@ -1019,7 +1049,7 @@ static int i8042_controller_init(void)
  * Reset the controller and reset CRT to the original value set by BIOS.
  */
 
-static void i8042_controller_reset(bool force_reset)
+static void i8042_controller_reset(bool s2r_wants_reset)
 {
        i8042_flush();
 
@@ -1044,8 +1074,10 @@ static void i8042_controller_reset(bool force_reset)
  * Reset the controller if requested.
  */
 
-       if (i8042_reset || force_reset)
+       if (i8042_reset == I8042_RESET_ALWAYS ||
+           (i8042_reset == I8042_RESET_ON_S2RAM && s2r_wants_reset)) {
                i8042_controller_selftest();
+       }
 
 /*
  * Restore the original control register setting.
@@ -1110,7 +1142,7 @@ static void i8042_dritek_enable(void)
  * before suspending.
  */
 
-static int i8042_controller_resume(bool force_reset)
+static int i8042_controller_resume(bool s2r_wants_reset)
 {
        int error;
 
@@ -1118,7 +1150,8 @@ static int i8042_controller_resume(bool force_reset)
        if (error)
                return error;
 
-       if (i8042_reset || force_reset) {
+       if (i8042_reset == I8042_RESET_ALWAYS ||
+           (i8042_reset == I8042_RESET_ON_S2RAM && s2r_wants_reset)) {
                error = i8042_controller_selftest();
                if (error)
                        return error;
@@ -1195,7 +1228,7 @@ static int i8042_pm_resume_noirq(struct device *dev)
 
 static int i8042_pm_resume(struct device *dev)
 {
-       bool force_reset;
+       bool want_reset;
        int i;
 
        for (i = 0; i < I8042_NUM_PORTS; i++) {
@@ -1218,9 +1251,9 @@ static int i8042_pm_resume(struct device *dev)
         * off control to the platform firmware, otherwise we can simply restore
         * the mode.
         */
-       force_reset = pm_resume_via_firmware();
+       want_reset = pm_resume_via_firmware();
 
-       return i8042_controller_resume(force_reset);
+       return i8042_controller_resume(want_reset);
 }
 
 static int i8042_pm_thaw(struct device *dev)
@@ -1482,7 +1515,7 @@ static int __init i8042_probe(struct platform_device *dev)
 
        i8042_platform_device = dev;
 
-       if (i8042_reset) {
+       if (i8042_reset == I8042_RESET_ALWAYS) {
                error = i8042_controller_selftest();
                if (error)
                        return error;
index fb5fb9140ca9536c59f0163ccd4cb5e8b8f4d9ac..552a3773f79d0b7815d6d180f7aabc9083ff6c92 100644 (file)
@@ -157,6 +157,7 @@ struct mip4_ts {
 
        char phys[32];
        char product_name[16];
+       char ic_name[4];
 
        unsigned int max_x;
        unsigned int max_y;
@@ -263,6 +264,18 @@ static int mip4_query_device(struct mip4_ts *ts)
                dev_dbg(&ts->client->dev, "product name: %.*s\n",
                        (int)sizeof(ts->product_name), ts->product_name);
 
+       /* IC name */
+       cmd[0] = MIP4_R0_INFO;
+       cmd[1] = MIP4_R1_INFO_IC_NAME;
+       error = mip4_i2c_xfer(ts, cmd, sizeof(cmd),
+                             ts->ic_name, sizeof(ts->ic_name));
+       if (error)
+               dev_warn(&ts->client->dev,
+                        "Failed to retrieve IC name: %d\n", error);
+       else
+               dev_dbg(&ts->client->dev, "IC name: %.*s\n",
+                       (int)sizeof(ts->ic_name), ts->ic_name);
+
        /* Firmware version */
        error = mip4_get_fw_version(ts);
        if (error)
@@ -1326,7 +1339,7 @@ static ssize_t mip4_sysfs_read_hw_version(struct device *dev,
         * paired with current firmware in the chip.
         */
        count = snprintf(buf, PAGE_SIZE, "%.*s\n",
-               (int)sizeof(ts->product_name), ts->product_name);
+                        (int)sizeof(ts->product_name), ts->product_name);
 
        mutex_unlock(&ts->input->mutex);
 
@@ -1335,9 +1348,30 @@ static ssize_t mip4_sysfs_read_hw_version(struct device *dev,
 
 static DEVICE_ATTR(hw_version, S_IRUGO, mip4_sysfs_read_hw_version, NULL);
 
+static ssize_t mip4_sysfs_read_ic_name(struct device *dev,
+                                         struct device_attribute *attr,
+                                         char *buf)
+{
+       struct i2c_client *client = to_i2c_client(dev);
+       struct mip4_ts *ts = i2c_get_clientdata(client);
+       size_t count;
+
+       mutex_lock(&ts->input->mutex);
+
+       count = snprintf(buf, PAGE_SIZE, "%.*s\n",
+                        (int)sizeof(ts->ic_name), ts->ic_name);
+
+       mutex_unlock(&ts->input->mutex);
+
+       return count;
+}
+
+static DEVICE_ATTR(ic_name, S_IRUGO, mip4_sysfs_read_ic_name, NULL);
+
 static struct attribute *mip4_attrs[] = {
        &dev_attr_fw_version.attr,
        &dev_attr_hw_version.attr,
+       &dev_attr_ic_name.attr,
        &dev_attr_update_fw.attr,
        NULL,
 };
@@ -1538,6 +1572,6 @@ static struct i2c_driver mip4_driver = {
 module_i2c_driver(mip4_driver);
 
 MODULE_DESCRIPTION("MELFAS MIP4 Touchscreen");
-MODULE_VERSION("2016.03.12");
+MODULE_VERSION("2016.09.28");
 MODULE_AUTHOR("Sangwon Jee <jeesw@melfas.com>");
 MODULE_LICENSE("GPL");
index e28d960997af3189885161bd40c355b28aee84af..2d0cb609adc33415ab0c724ff266e1f4a145d694 100644 (file)
@@ -207,6 +207,7 @@ static int hns_ae_set_multicast_one(struct hnae_handle *handle, void *addr)
        int ret;
        char *mac_addr = (char *)addr;
        struct hns_mac_cb *mac_cb = hns_get_mac_cb(handle);
+       u8 port_num;
 
        assert(mac_cb);
 
@@ -221,8 +222,11 @@ static int hns_ae_set_multicast_one(struct hnae_handle *handle, void *addr)
                return ret;
        }
 
-       ret = hns_mac_set_multi(mac_cb, DSAF_BASE_INNER_PORT_NUM,
-                               mac_addr, true);
+       ret = hns_mac_get_inner_port_num(mac_cb, handle->vf_id, &port_num);
+       if (ret)
+               return ret;
+
+       ret = hns_mac_set_multi(mac_cb, port_num, mac_addr, true);
        if (ret)
                dev_err(handle->owner_dev,
                        "mac add mul_mac:%pM port%d  fail, ret = %#x!\n",
@@ -678,9 +682,6 @@ static int hns_ae_config_loopback(struct hnae_handle *handle,
                ret = -EINVAL;
        }
 
-       if (!ret)
-               hns_dsaf_set_inner_lb(mac_cb->dsaf_dev, mac_cb->mac_id, en);
-
        return ret;
 }
 
index 22e141005cd92df0ef615ba30ffbcc4a020150f7..ec8c738af726323e92c2416a639806462f0bfe4b 100644 (file)
@@ -141,9 +141,10 @@ void hns_mac_adjust_link(struct hns_mac_cb *mac_cb, int speed, int duplex)
  *@port_num:port number
  *
  */
-static int hns_mac_get_inner_port_num(struct hns_mac_cb *mac_cb,
-                                     u8 vmid, u8 *port_num)
+int hns_mac_get_inner_port_num(struct hns_mac_cb *mac_cb, u8 vmid, u8 *port_num)
 {
+       int q_num_per_vf, vf_num_per_port;
+       int vm_queue_id;
        u8 tmp_port;
 
        if (mac_cb->dsaf_dev->dsaf_mode <= DSAF_MODE_ENABLE) {
@@ -174,6 +175,12 @@ static int hns_mac_get_inner_port_num(struct hns_mac_cb *mac_cb,
                return -EINVAL;
        }
 
+       q_num_per_vf = mac_cb->dsaf_dev->rcb_common[0]->max_q_per_vf;
+       vf_num_per_port = mac_cb->dsaf_dev->rcb_common[0]->max_vfn;
+
+       vm_queue_id = vmid * q_num_per_vf +
+                       vf_num_per_port * q_num_per_vf * mac_cb->mac_id;
+
        switch (mac_cb->dsaf_dev->dsaf_mode) {
        case DSAF_MODE_ENABLE_FIX:
                tmp_port = 0;
@@ -193,7 +200,7 @@ static int hns_mac_get_inner_port_num(struct hns_mac_cb *mac_cb,
        case DSAF_MODE_DISABLE_6PORT_2VM:
        case DSAF_MODE_DISABLE_6PORT_4VM:
        case DSAF_MODE_DISABLE_6PORT_16VM:
-               tmp_port = vmid;
+               tmp_port = vm_queue_id;
                break;
        default:
                dev_err(mac_cb->dev, "dsaf mode invalid, %s mac%d!\n",
index 4cbdf14f5c163e7405dd323327e8d3dc015a6ae5..d3a1f72ece0e518107de05437fdc4e2a7929ab39 100644 (file)
@@ -461,5 +461,7 @@ void hns_set_led_opt(struct hns_mac_cb *mac_cb);
 int hns_cpld_led_set_id(struct hns_mac_cb *mac_cb,
                        enum hnae_led_state status);
 void hns_mac_set_promisc(struct hns_mac_cb *mac_cb, u8 en);
+int hns_mac_get_inner_port_num(struct hns_mac_cb *mac_cb,
+                              u8 vmid, u8 *port_num);
 
 #endif /* _HNS_DSAF_MAC_H */
index 8e5b3f51b47b80201d7c447a9f061116b69e141c..8d70377f6624cb5d1cd55ae9916af6f75ee934b4 100644 (file)
@@ -760,16 +760,6 @@ void hns_dsaf_set_promisc_mode(struct dsaf_device *dsaf_dev, u32 en)
                                 DSAF_CFG_MIX_MODE_S, !!en);
 }
 
-void hns_dsaf_set_inner_lb(struct dsaf_device *dsaf_dev, u32 mac_id, u32 en)
-{
-       if (AE_IS_VER1(dsaf_dev->dsaf_ver) ||
-           dsaf_dev->mac_cb[mac_id]->mac_type == HNAE_PORT_DEBUG)
-               return;
-
-       dsaf_set_dev_bit(dsaf_dev, DSAFV2_SERDES_LBK_0_REG + 4 * mac_id,
-                        DSAFV2_SERDES_LBK_EN_B, !!en);
-}
-
 /**
  * hns_dsaf_tbl_stat_en - tbl
  * @dsaf_id: dsa fabric id
index 35df187e66f1909185b010289f4b6009b54c2a10..c494fc52be7496382b092d77ea29f26992c1c6bd 100644 (file)
@@ -466,6 +466,5 @@ void hns_dsaf_get_rx_mac_pause_en(struct dsaf_device *dsaf_dev, int mac_id,
                                  u32 *en);
 int hns_dsaf_set_rx_mac_pause_en(struct dsaf_device *dsaf_dev, int mac_id,
                                 u32 en);
-void hns_dsaf_set_inner_lb(struct dsaf_device *dsaf_dev, u32 mac_id, u32 en);
 
 #endif /* __HNS_DSAF_MAIN_H__ */
index ef1107777c08d58117110cf2c5da08c2dcec3e23..f0ed80d6ef9cd45a8408c987ab4315646098f438 100644 (file)
@@ -543,6 +543,22 @@ int hns_rcb_set_coalesce_usecs(
                        "error: coalesce_usecs setting supports 0~1023us\n");
                return -EINVAL;
        }
+
+       if (!AE_IS_VER1(rcb_common->dsaf_dev->dsaf_ver)) {
+               if (timeout == 0)
+                       /* set timeout to 0, Disable gap time */
+                       dsaf_set_reg_field(rcb_common->io_base,
+                                          RCB_INT_GAP_TIME_REG + port_idx * 4,
+                                          PPE_INT_GAPTIME_M, PPE_INT_GAPTIME_B,
+                                          0);
+               else
+                       /* set timeout non 0, restore gap time to 1 */
+                       dsaf_set_reg_field(rcb_common->io_base,
+                                          RCB_INT_GAP_TIME_REG + port_idx * 4,
+                                          PPE_INT_GAPTIME_M, PPE_INT_GAPTIME_B,
+                                          1);
+       }
+
        hns_rcb_set_port_timeout(rcb_common, port_idx, timeout);
        return 0;
 }
index 4b8b803822d1b2ae7d15c599aa7778a728cc3883..878950a42e6c2399a047bf91d3f358aa653d9127 100644 (file)
 #define RCB_CFG_OVERTIME_REG                   0x9300
 #define RCB_CFG_PKTLINE_INT_NUM_REG            0x9304
 #define RCB_CFG_OVERTIME_INT_NUM_REG           0x9308
+#define RCB_INT_GAP_TIME_REG                   0x9400
 #define RCB_PORT_CFG_OVERTIME_REG              0x9430
 
 #define RCB_RING_RX_RING_BASEADDR_L_REG                0x00000
 #define PPE_CNT_CLR_CE_B       0
 #define PPE_CNT_CLR_SNAP_EN_B  1
 
+#define PPE_INT_GAPTIME_B      0
+#define PPE_INT_GAPTIME_M      0x3ff
+
 #define PPE_COMMON_CNT_CLR_CE_B        0
 #define PPE_COMMON_CNT_CLR_SNAP_EN_B   1
 #define RCB_COM_TSO_MODE_B     0
index 059aaeda46b139492b00d645c73e51e4279fb6c6..dff7b60345d8e94b90a53f16d2c9caadde1b449a 100644 (file)
@@ -574,7 +574,6 @@ static int hns_nic_poll_rx_skb(struct hns_nic_ring_data *ring_data,
        struct sk_buff *skb;
        struct hnae_desc *desc;
        struct hnae_desc_cb *desc_cb;
-       struct ethhdr *eh;
        unsigned char *va;
        int bnum, length, i;
        int pull_len;
@@ -600,7 +599,6 @@ static int hns_nic_poll_rx_skb(struct hns_nic_ring_data *ring_data,
                ring->stats.sw_err_cnt++;
                return -ENOMEM;
        }
-       skb_reset_mac_header(skb);
 
        prefetchw(skb->data);
        length = le16_to_cpu(desc->rx.pkt_len);
@@ -682,14 +680,6 @@ out_bnum_err:
                return -EFAULT;
        }
 
-       /* filter out multicast pkt with the same src mac as this port */
-       eh = eth_hdr(skb);
-       if (unlikely(is_multicast_ether_addr(eh->h_dest) &&
-                    ether_addr_equal(ndev->dev_addr, eh->h_source))) {
-               dev_kfree_skb_any(skb);
-               return -EFAULT;
-       }
-
        ring->stats.rx_pkts++;
        ring->stats.rx_bytes += skb->len;
 
@@ -747,25 +737,37 @@ static void hns_nic_rx_up_pro(struct hns_nic_ring_data *ring_data,
        ndev->last_rx = jiffies;
 }
 
+static int hns_desc_unused(struct hnae_ring *ring)
+{
+       int ntc = ring->next_to_clean;
+       int ntu = ring->next_to_use;
+
+       return ((ntc >= ntu) ? 0 : ring->desc_num) + ntc - ntu;
+}
+
 static int hns_nic_rx_poll_one(struct hns_nic_ring_data *ring_data,
                               int budget, void *v)
 {
        struct hnae_ring *ring = ring_data->ring;
        struct sk_buff *skb;
-       int num, bnum, ex_num;
+       int num, bnum;
 #define RCB_NOF_ALLOC_RX_BUFF_ONCE 16
        int recv_pkts, recv_bds, clean_count, err;
+       int unused_count = hns_desc_unused(ring);
 
        num = readl_relaxed(ring->io_base + RCB_REG_FBDNUM);
        rmb(); /* make sure num taken effect before the other data is touched */
 
        recv_pkts = 0, recv_bds = 0, clean_count = 0;
-recv:
+       num -= unused_count;
+
        while (recv_pkts < budget && recv_bds < num) {
                /* reuse or realloc buffers */
-               if (clean_count >= RCB_NOF_ALLOC_RX_BUFF_ONCE) {
-                       hns_nic_alloc_rx_buffers(ring_data, clean_count);
+               if (clean_count + unused_count >= RCB_NOF_ALLOC_RX_BUFF_ONCE) {
+                       hns_nic_alloc_rx_buffers(ring_data,
+                                                clean_count + unused_count);
                        clean_count = 0;
+                       unused_count = hns_desc_unused(ring);
                }
 
                /* poll one pkt */
@@ -786,21 +788,11 @@ recv:
                recv_pkts++;
        }
 
-       /* make all data has been write before submit */
-       if (recv_pkts < budget) {
-               ex_num = readl_relaxed(ring->io_base + RCB_REG_FBDNUM);
-
-               if (ex_num > clean_count) {
-                       num += ex_num - clean_count;
-                       rmb(); /*complete read rx ring bd number*/
-                       goto recv;
-               }
-       }
-
 out:
        /* make all data has been write before submit */
-       if (clean_count > 0)
-               hns_nic_alloc_rx_buffers(ring_data, clean_count);
+       if (clean_count + unused_count > 0)
+               hns_nic_alloc_rx_buffers(ring_data,
+                                        clean_count + unused_count);
 
        return recv_pkts;
 }
@@ -810,6 +802,8 @@ static void hns_nic_rx_fini_pro(struct hns_nic_ring_data *ring_data)
        struct hnae_ring *ring = ring_data->ring;
        int num = 0;
 
+       ring_data->ring->q->handle->dev->ops->toggle_ring_irq(ring, 0);
+
        /* for hardware bug fixed */
        num = readl_relaxed(ring->io_base + RCB_REG_FBDNUM);
 
@@ -821,6 +815,20 @@ static void hns_nic_rx_fini_pro(struct hns_nic_ring_data *ring_data)
        }
 }
 
+static void hns_nic_rx_fini_pro_v2(struct hns_nic_ring_data *ring_data)
+{
+       struct hnae_ring *ring = ring_data->ring;
+       int num = 0;
+
+       num = readl_relaxed(ring->io_base + RCB_REG_FBDNUM);
+
+       if (num == 0)
+               ring_data->ring->q->handle->dev->ops->toggle_ring_irq(
+                       ring, 0);
+       else
+               napi_schedule(&ring_data->napi);
+}
+
 static inline void hns_nic_reclaim_one_desc(struct hnae_ring *ring,
                                            int *bytes, int *pkts)
 {
@@ -922,7 +930,11 @@ static int hns_nic_tx_poll_one(struct hns_nic_ring_data *ring_data,
 static void hns_nic_tx_fini_pro(struct hns_nic_ring_data *ring_data)
 {
        struct hnae_ring *ring = ring_data->ring;
-       int head = readl_relaxed(ring->io_base + RCB_REG_HEAD);
+       int head;
+
+       ring_data->ring->q->handle->dev->ops->toggle_ring_irq(ring, 0);
+
+       head = readl_relaxed(ring->io_base + RCB_REG_HEAD);
 
        if (head != ring->next_to_clean) {
                ring_data->ring->q->handle->dev->ops->toggle_ring_irq(
@@ -932,6 +944,18 @@ static void hns_nic_tx_fini_pro(struct hns_nic_ring_data *ring_data)
        }
 }
 
+static void hns_nic_tx_fini_pro_v2(struct hns_nic_ring_data *ring_data)
+{
+       struct hnae_ring *ring = ring_data->ring;
+       int head = readl_relaxed(ring->io_base + RCB_REG_HEAD);
+
+       if (head == ring->next_to_clean)
+               ring_data->ring->q->handle->dev->ops->toggle_ring_irq(
+                       ring, 0);
+       else
+               napi_schedule(&ring_data->napi);
+}
+
 static void hns_nic_tx_clr_all_bufs(struct hns_nic_ring_data *ring_data)
 {
        struct hnae_ring *ring = ring_data->ring;
@@ -963,10 +987,7 @@ static int hns_nic_common_poll(struct napi_struct *napi, int budget)
 
        if (clean_complete >= 0 && clean_complete < budget) {
                napi_complete(napi);
-               ring_data->ring->q->handle->dev->ops->toggle_ring_irq(
-                       ring_data->ring, 0);
-               if (ring_data->fini_process)
-                       ring_data->fini_process(ring_data);
+               ring_data->fini_process(ring_data);
                return 0;
        }
 
@@ -1562,6 +1583,21 @@ struct rtnl_link_stats64 *hns_nic_get_stats64(struct net_device *ndev,
        return stats;
 }
 
+static u16
+hns_nic_select_queue(struct net_device *ndev, struct sk_buff *skb,
+                    void *accel_priv, select_queue_fallback_t fallback)
+{
+       struct ethhdr *eth_hdr = (struct ethhdr *)skb->data;
+       struct hns_nic_priv *priv = netdev_priv(ndev);
+
+       /* fix hardware broadcast/multicast packets queue loopback */
+       if (!AE_IS_VER1(priv->enet_ver) &&
+           is_multicast_ether_addr(eth_hdr->h_dest))
+               return 0;
+       else
+               return fallback(ndev, skb);
+}
+
 static const struct net_device_ops hns_nic_netdev_ops = {
        .ndo_open = hns_nic_net_open,
        .ndo_stop = hns_nic_net_stop,
@@ -1577,6 +1613,7 @@ static const struct net_device_ops hns_nic_netdev_ops = {
        .ndo_poll_controller = hns_nic_poll_controller,
 #endif
        .ndo_set_rx_mode = hns_nic_set_rx_mode,
+       .ndo_select_queue = hns_nic_select_queue,
 };
 
 static void hns_nic_update_link_status(struct net_device *netdev)
@@ -1738,7 +1775,8 @@ static int hns_nic_init_ring_data(struct hns_nic_priv *priv)
                rd->queue_index = i;
                rd->ring = &h->qs[i]->tx_ring;
                rd->poll_one = hns_nic_tx_poll_one;
-               rd->fini_process = is_ver1 ? hns_nic_tx_fini_pro : NULL;
+               rd->fini_process = is_ver1 ? hns_nic_tx_fini_pro :
+                       hns_nic_tx_fini_pro_v2;
 
                netif_napi_add(priv->netdev, &rd->napi,
                               hns_nic_common_poll, NIC_TX_CLEAN_MAX_NUM);
@@ -1750,7 +1788,8 @@ static int hns_nic_init_ring_data(struct hns_nic_priv *priv)
                rd->ring = &h->qs[i - h->q_num]->rx_ring;
                rd->poll_one = hns_nic_rx_poll_one;
                rd->ex_process = hns_nic_rx_up_pro;
-               rd->fini_process = is_ver1 ? hns_nic_rx_fini_pro : NULL;
+               rd->fini_process = is_ver1 ? hns_nic_rx_fini_pro :
+                       hns_nic_rx_fini_pro_v2;
 
                netif_napi_add(priv->netdev, &rd->napi,
                               hns_nic_common_poll, NIC_RX_CLEAN_MAX_NUM);
index 47e59bbfd061bfe1d9576b8111f92d361be599e1..87d5c94b2810230b334ddef0501644cd291b8bbf 100644 (file)
@@ -352,6 +352,13 @@ static int __lb_setup(struct net_device *ndev,
                break;
        }
 
+       if (!ret) {
+               if (loop == MAC_LOOP_NONE)
+                       h->dev->ops->set_promisc_mode(
+                               h, ndev->flags & IFF_PROMISC);
+               else
+                       h->dev->ops->set_promisc_mode(h, 1);
+       }
        return ret;
 }
 
index d1e080701264f230235668b07aedf0e4936ba4f9..e859d148aba9ecdbcecc47e745209b94ed83dd67 100644 (file)
@@ -208,14 +208,14 @@ config RTC_DRV_AS3722
          will be called rtc-as3722.
 
 config RTC_DRV_DS1307
-       tristate "Dallas/Maxim DS1307/37/38/39/40, ST M41T00, EPSON RX-8025"
+       tristate "Dallas/Maxim DS1307/37/38/39/40, ST M41T00, EPSON RX-8025, ISL12057"
        help
          If you say yes here you get support for various compatible RTC
          chips (often with battery backup) connected with I2C. This driver
          should handle DS1307, DS1337, DS1338, DS1339, DS1340, ST M41T00,
-         EPSON RX-8025 and probably other chips. In some cases the RTC
-         must already have been initialized (by manufacturing or a
-         bootloader).
+         EPSON RX-8025, Intersil ISL12057 and probably other chips. In some
+         cases the RTC must already have been initialized (by manufacturing or
+         bootloader).
 
          The first seven registers on these chips hold an RTC, and other
          registers may add features such as NVRAM, a trickle charger for
@@ -234,6 +234,20 @@ config RTC_DRV_DS1307_HWMON
          Say Y here if you want to expose temperature sensor data on
          rtc-ds1307 (only DS3231)
 
+config RTC_DRV_DS1307_CENTURY
+       bool "Century bit support for rtc-ds1307"
+       depends on RTC_DRV_DS1307
+       default n
+       help
+         The DS1307 driver suffered from a bug where it was enabling the
+         century bit inconditionnally but never used it when reading the time.
+         It made the driver unable to support dates beyond 2099.
+         Setting this option will add proper support for the century bit but if
+         the time was previously set using a kernel predating this option,
+         reading the date will return a date in the next century.
+         To solve that, you could boot a kernel without this option set, set
+         the RTC date and then boot a kernel with this option set.
+
 config RTC_DRV_DS1374
        tristate "Dallas/Maxim DS1374"
        help
@@ -374,16 +388,6 @@ config RTC_DRV_ISL12022
          This driver can also be built as a module. If so, the module
          will be called rtc-isl12022.
 
-config RTC_DRV_ISL12057
-       select REGMAP_I2C
-       tristate "Intersil ISL12057"
-       help
-         If you say yes here you get support for the Intersil ISL12057
-         I2C RTC chip.
-
-         This driver can also be built as a module. If so, the module
-         will be called rtc-isl12057.
-
 config RTC_DRV_X1205
        tristate "Xicor/Intersil X1205"
        help
@@ -661,6 +665,7 @@ config RTC_DRV_DS1343
          will be called rtc-ds1343.
 
 config RTC_DRV_DS1347
+       select REGMAP_SPI
        tristate "Dallas/Maxim DS1347"
        help
          If you say yes here you get support for the
@@ -1201,7 +1206,7 @@ comment "on-CPU RTC drivers"
 
 config RTC_DRV_ASM9260
        tristate "Alphascale asm9260 RTC"
-       depends on MACH_ASM9260
+       depends on MACH_ASM9260 || COMPILE_TEST
        help
          If you say yes here you get support for the RTC on the
          Alphascale asm9260 SoC.
@@ -1241,6 +1246,9 @@ config RTC_DRV_IMXDI
 config RTC_DRV_OMAP
        tristate "TI OMAP Real Time Clock"
        depends on ARCH_OMAP || ARCH_DAVINCI || COMPILE_TEST
+       depends on OF
+       depends on PINCTRL
+       select GENERIC_PINCONF
        help
          Say "yes" here to support the on chip real time clock
          present on TI OMAP1, AM33xx, DA8xx/OMAP-L13x, AM43xx and DRA7xx.
index 8fb994bacdf7f155666d7f690a6f443b478b8fed..1ac694a330c8dadc0cbe78a4f6cd8d7359de2ecc 100644 (file)
@@ -72,7 +72,6 @@ obj-$(CONFIG_RTC_DRV_HID_SENSOR_TIME) += rtc-hid-sensor-time.o
 obj-$(CONFIG_RTC_DRV_HYM8563)  += rtc-hym8563.o
 obj-$(CONFIG_RTC_DRV_IMXDI)    += rtc-imxdi.o
 obj-$(CONFIG_RTC_DRV_ISL12022) += rtc-isl12022.o
-obj-$(CONFIG_RTC_DRV_ISL12057) += rtc-isl12057.o
 obj-$(CONFIG_RTC_DRV_ISL1208)  += rtc-isl1208.o
 obj-$(CONFIG_RTC_DRV_JZ4740)   += rtc-jz4740.o
 obj-$(CONFIG_RTC_DRV_LP8788)   += rtc-lp8788.o
index 70b4fd0f61225485ebe87480037c3562793f09d4..9e336184491cbd1b1e80c47cddbf346c24665a63 100644 (file)
@@ -327,6 +327,8 @@ static int ac100_rtc_register_clks(struct ac100_rtc_dev *chip)
                        .flags = 0,
                };
 
+               of_property_read_string_index(np, "clock-output-names",
+                                             i, &init.name);
                clk->regmap = chip->regmap;
                clk->offset = AC100_CLKOUT_CTRL1 + i;
                clk->hw.init = &init;
@@ -552,6 +554,9 @@ static int ac100_rtc_probe(struct platform_device *pdev)
        int ret;
 
        chip = devm_kzalloc(&pdev->dev, sizeof(*chip), GFP_KERNEL);
+       if (!chip)
+               return -ENOMEM;
+
        platform_set_drvdata(pdev, chip);
        chip->dev = &pdev->dev;
        chip->regmap = ac100->regmap;
index 5219916ce11d2b609bde574a4b99f72d279eb8e9..18a93d3e3f9317286c99f9718ea1d42ea95ebd50 100644 (file)
@@ -112,8 +112,6 @@ struct asm9260_rtc_priv {
        void __iomem            *iobase;
        struct rtc_device       *rtc;
        struct clk              *clk;
-       /* io lock */
-       spinlock_t              lock;
 };
 
 static irqreturn_t asm9260_rtc_irq(int irq, void *dev_id)
@@ -122,11 +120,15 @@ static irqreturn_t asm9260_rtc_irq(int irq, void *dev_id)
        u32 isr;
        unsigned long events = 0;
 
+       mutex_lock(&priv->rtc->ops_lock);
        isr = ioread32(priv->iobase + HW_CIIR);
-       if (!isr)
+       if (!isr) {
+               mutex_unlock(&priv->rtc->ops_lock);
                return IRQ_NONE;
+       }
 
        iowrite32(0, priv->iobase + HW_CIIR);
+       mutex_unlock(&priv->rtc->ops_lock);
 
        events |= RTC_AF | RTC_IRQF;
 
@@ -139,9 +141,7 @@ static int asm9260_rtc_read_time(struct device *dev, struct rtc_time *tm)
 {
        struct asm9260_rtc_priv *priv = dev_get_drvdata(dev);
        u32 ctime0, ctime1, ctime2;
-       unsigned long irq_flags;
 
-       spin_lock_irqsave(&priv->lock, irq_flags);
        ctime0 = ioread32(priv->iobase + HW_CTIME0);
        ctime1 = ioread32(priv->iobase + HW_CTIME1);
        ctime2 = ioread32(priv->iobase + HW_CTIME2);
@@ -155,7 +155,6 @@ static int asm9260_rtc_read_time(struct device *dev, struct rtc_time *tm)
                ctime1 = ioread32(priv->iobase + HW_CTIME1);
                ctime2 = ioread32(priv->iobase + HW_CTIME2);
        }
-       spin_unlock_irqrestore(&priv->lock, irq_flags);
 
        tm->tm_sec  = (ctime0 >> BM_CTIME0_SEC_S)  & BM_CTIME0_SEC_M;
        tm->tm_min  = (ctime0 >> BM_CTIME0_MIN_S)  & BM_CTIME0_MIN_M;
@@ -174,9 +173,7 @@ static int asm9260_rtc_read_time(struct device *dev, struct rtc_time *tm)
 static int asm9260_rtc_set_time(struct device *dev, struct rtc_time *tm)
 {
        struct asm9260_rtc_priv *priv = dev_get_drvdata(dev);
-       unsigned long irq_flags;
 
-       spin_lock_irqsave(&priv->lock, irq_flags);
        /*
         * make sure SEC counter will not flip other counter on write time,
         * real value will be written at the enf of sequence.
@@ -191,7 +188,6 @@ static int asm9260_rtc_set_time(struct device *dev, struct rtc_time *tm)
        iowrite32(tm->tm_hour, priv->iobase + HW_HOUR);
        iowrite32(tm->tm_min,  priv->iobase + HW_MIN);
        iowrite32(tm->tm_sec,  priv->iobase + HW_SEC);
-       spin_unlock_irqrestore(&priv->lock, irq_flags);
 
        return 0;
 }
@@ -199,9 +195,7 @@ static int asm9260_rtc_set_time(struct device *dev, struct rtc_time *tm)
 static int asm9260_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
 {
        struct asm9260_rtc_priv *priv = dev_get_drvdata(dev);
-       unsigned long irq_flags;
 
-       spin_lock_irqsave(&priv->lock, irq_flags);
        alrm->time.tm_year = ioread32(priv->iobase + HW_ALYEAR);
        alrm->time.tm_mon  = ioread32(priv->iobase + HW_ALMON);
        alrm->time.tm_mday = ioread32(priv->iobase + HW_ALDOM);
@@ -213,7 +207,6 @@ static int asm9260_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
 
        alrm->enabled = ioread32(priv->iobase + HW_AMR) ? 1 : 0;
        alrm->pending = ioread32(priv->iobase + HW_CIIR) ? 1 : 0;
-       spin_unlock_irqrestore(&priv->lock, irq_flags);
 
        return rtc_valid_tm(&alrm->time);
 }
@@ -221,9 +214,7 @@ static int asm9260_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
 static int asm9260_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
 {
        struct asm9260_rtc_priv *priv = dev_get_drvdata(dev);
-       unsigned long irq_flags;
 
-       spin_lock_irqsave(&priv->lock, irq_flags);
        iowrite32(alrm->time.tm_year, priv->iobase + HW_ALYEAR);
        iowrite32(alrm->time.tm_mon,  priv->iobase + HW_ALMON);
        iowrite32(alrm->time.tm_mday, priv->iobase + HW_ALDOM);
@@ -234,7 +225,6 @@ static int asm9260_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
        iowrite32(alrm->time.tm_sec,  priv->iobase + HW_ALSEC);
 
        iowrite32(alrm->enabled ? 0 : BM_AMR_OFF, priv->iobase + HW_AMR);
-       spin_unlock_irqrestore(&priv->lock, irq_flags);
 
        return 0;
 }
index 83ac2337c0f732df3cf29a4bca131e39fd37e470..de8bf56a41e7676d47e77bf391030e1adccc26e9 100644 (file)
@@ -187,7 +187,7 @@ static irqreturn_t at32_rtc_interrupt(int irq, void *dev_id)
        return ret;
 }
 
-static struct rtc_class_ops at32_rtc_ops = {
+static const struct rtc_class_ops at32_rtc_ops = {
        .read_time      = at32_rtc_readtime,
        .set_time       = at32_rtc_settime,
        .read_alarm     = at32_rtc_readalarm,
index 0299988b4f136812bad0e35c4943826608d5a114..397742446007aa2479969969c60097ad3edb6889 100644 (file)
@@ -93,8 +93,15 @@ static int bq32k_rtc_read_time(struct device *dev, struct rtc_time *tm)
        if (error)
                return error;
 
+       /*
+        * In case of oscillator failure, the register contents should be
+        * considered invalid. The flag is cleared the next time the RTC is set.
+        */
+       if (regs.minutes & BQ32K_OF)
+               return -EINVAL;
+
        tm->tm_sec = bcd2bin(regs.seconds & BQ32K_SECONDS_MASK);
-       tm->tm_min = bcd2bin(regs.minutes & BQ32K_SECONDS_MASK);
+       tm->tm_min = bcd2bin(regs.minutes & BQ32K_MINUTES_MASK);
        tm->tm_hour = bcd2bin(regs.cent_hours & BQ32K_HOURS_MASK);
        tm->tm_mday = bcd2bin(regs.date);
        tm->tm_wday = bcd2bin(regs.day) - 1;
@@ -204,13 +211,10 @@ static int bq32k_probe(struct i2c_client *client,
 
        /* Check Oscillator Failure flag */
        error = bq32k_read(dev, &reg, BQ32K_MINUTES, 1);
-       if (!error && (reg & BQ32K_OF)) {
-               dev_warn(dev, "Oscillator Failure. Check RTC battery.\n");
-               reg &= ~BQ32K_OF;
-               error = bq32k_write(dev, &reg, BQ32K_MINUTES, 1);
-       }
        if (error)
                return error;
+       if (reg & BQ32K_OF)
+               dev_warn(dev, "Oscillator Failure. Check RTC battery.\n");
 
        if (client->dev.of_node)
                trickle_charger_of_init(dev, client->dev.of_node);
index 43745cac0141a4445dda3abe6a31d8ca172355b0..dd3d59806ffa02ef955660390533881d9f6cee62 100644 (file)
@@ -62,6 +62,8 @@ struct cmos_rtc {
        u8                      day_alrm;
        u8                      mon_alrm;
        u8                      century;
+
+       struct rtc_wkalrm       saved_wkalrm;
 };
 
 /* both platform and pnp busses use negative numbers for invalid irqs */
@@ -707,6 +709,8 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq)
                goto cleanup1;
        }
 
+       hpet_rtc_timer_init();
+
        if (is_valid_irq(rtc_irq)) {
                irq_handler_t rtc_cmos_int_handler;
 
@@ -714,6 +718,7 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq)
                        rtc_cmos_int_handler = hpet_rtc_interrupt;
                        retval = hpet_register_irq_handler(cmos_interrupt);
                        if (retval) {
+                               hpet_mask_rtc_irq_bit(RTC_IRQMASK);
                                dev_warn(dev, "hpet_register_irq_handler "
                                                " failed in rtc_init().");
                                goto cleanup1;
@@ -729,7 +734,6 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq)
                        goto cleanup1;
                }
        }
-       hpet_rtc_timer_init();
 
        /* export at least the first block of NVRAM */
        nvram.size = address_space - NVRAM_OFFSET;
@@ -844,8 +848,6 @@ static int cmos_aie_poweroff(struct device *dev)
        return retval;
 }
 
-#ifdef CONFIG_PM
-
 static int cmos_suspend(struct device *dev)
 {
        struct cmos_rtc *cmos = dev_get_drvdata(dev);
@@ -877,6 +879,8 @@ static int cmos_suspend(struct device *dev)
                        enable_irq_wake(cmos->irq);
        }
 
+       cmos_read_alarm(dev, &cmos->saved_wkalrm);
+
        dev_dbg(dev, "suspend%s, ctrl %02x\n",
                        (tmp & RTC_AIE) ? ", alarm may wake" : "",
                        tmp);
@@ -892,12 +896,32 @@ static int cmos_suspend(struct device *dev)
  */
 static inline int cmos_poweroff(struct device *dev)
 {
+       if (!IS_ENABLED(CONFIG_PM))
+               return -ENOSYS;
+
        return cmos_suspend(dev);
 }
 
-#ifdef CONFIG_PM_SLEEP
+static void cmos_check_wkalrm(struct device *dev)
+{
+       struct cmos_rtc *cmos = dev_get_drvdata(dev);
+       struct rtc_wkalrm current_alarm;
+       time64_t t_current_expires;
+       time64_t t_saved_expires;
+
+       cmos_read_alarm(dev, &current_alarm);
+       t_current_expires = rtc_tm_to_time64(&current_alarm.time);
+       t_saved_expires = rtc_tm_to_time64(&cmos->saved_wkalrm.time);
+       if (t_current_expires != t_saved_expires ||
+           cmos->saved_wkalrm.enabled != current_alarm.enabled) {
+               cmos_set_alarm(dev, &cmos->saved_wkalrm);
+       }
+}
+
+static void cmos_check_acpi_rtc_status(struct device *dev,
+                                      unsigned char *rtc_control);
 
-static int cmos_resume(struct device *dev)
+static int __maybe_unused cmos_resume(struct device *dev)
 {
        struct cmos_rtc *cmos = dev_get_drvdata(dev);
        unsigned char tmp;
@@ -910,6 +934,9 @@ static int cmos_resume(struct device *dev)
                cmos->enabled_wake = 0;
        }
 
+       /* The BIOS might have changed the alarm, restore it */
+       cmos_check_wkalrm(dev);
+
        spin_lock_irq(&rtc_lock);
        tmp = cmos->suspend_ctrl;
        cmos->suspend_ctrl = 0;
@@ -936,6 +963,9 @@ static int cmos_resume(struct device *dev)
                        tmp &= ~RTC_AIE;
                        hpet_mask_rtc_irq_bit(RTC_AIE);
                } while (mask & RTC_AIE);
+
+               if (tmp & RTC_AIE)
+                       cmos_check_acpi_rtc_status(dev, &tmp);
        }
        spin_unlock_irq(&rtc_lock);
 
@@ -944,16 +974,6 @@ static int cmos_resume(struct device *dev)
        return 0;
 }
 
-#endif
-#else
-
-static inline int cmos_poweroff(struct device *dev)
-{
-       return -ENOSYS;
-}
-
-#endif
-
 static SIMPLE_DEV_PM_OPS(cmos_pm_ops, cmos_suspend, cmos_resume);
 
 /*----------------------------------------------------------------*/
@@ -973,6 +993,20 @@ static SIMPLE_DEV_PM_OPS(cmos_pm_ops, cmos_suspend, cmos_resume);
 static u32 rtc_handler(void *context)
 {
        struct device *dev = context;
+       struct cmos_rtc *cmos = dev_get_drvdata(dev);
+       unsigned char rtc_control = 0;
+       unsigned char rtc_intr;
+
+       spin_lock_irq(&rtc_lock);
+       if (cmos_rtc.suspend_ctrl)
+               rtc_control = CMOS_READ(RTC_CONTROL);
+       if (rtc_control & RTC_AIE) {
+               cmos_rtc.suspend_ctrl &= ~RTC_AIE;
+               CMOS_WRITE(rtc_control, RTC_CONTROL);
+               rtc_intr = CMOS_READ(RTC_INTR_FLAGS);
+               rtc_update_irq(cmos->rtc, 1, rtc_intr);
+       }
+       spin_unlock_irq(&rtc_lock);
 
        pm_wakeup_event(dev, 0);
        acpi_clear_event(ACPI_EVENT_RTC);
@@ -1039,12 +1073,39 @@ static void cmos_wake_setup(struct device *dev)
        device_init_wakeup(dev, 1);
 }
 
+static void cmos_check_acpi_rtc_status(struct device *dev,
+                                      unsigned char *rtc_control)
+{
+       struct cmos_rtc *cmos = dev_get_drvdata(dev);
+       acpi_event_status rtc_status;
+       acpi_status status;
+
+       if (acpi_gbl_FADT.flags & ACPI_FADT_FIXED_RTC)
+               return;
+
+       status = acpi_get_event_status(ACPI_EVENT_RTC, &rtc_status);
+       if (ACPI_FAILURE(status)) {
+               dev_err(dev, "Could not get RTC status\n");
+       } else if (rtc_status & ACPI_EVENT_FLAG_SET) {
+               unsigned char mask;
+               *rtc_control &= ~RTC_AIE;
+               CMOS_WRITE(*rtc_control, RTC_CONTROL);
+               mask = CMOS_READ(RTC_INTR_FLAGS);
+               rtc_update_irq(cmos->rtc, 1, mask);
+       }
+}
+
 #else
 
 static void cmos_wake_setup(struct device *dev)
 {
 }
 
+static void cmos_check_acpi_rtc_status(struct device *dev,
+                                      unsigned char *rtc_control)
+{
+}
+
 #endif
 
 #ifdef CONFIG_PNP
@@ -1206,9 +1267,7 @@ static struct platform_driver cmos_platform_driver = {
        .shutdown       = cmos_platform_shutdown,
        .driver = {
                .name           = driver_name,
-#ifdef CONFIG_PM
                .pm             = &cmos_pm_ops,
-#endif
                .of_match_table = of_match_ptr(of_cmos_match),
        }
 };
index 101b7a240e0fa8e482ef140b921c5b31811e829a..cfc4141d99cde18def976813feba11113111a378 100644 (file)
@@ -140,7 +140,7 @@ static int coh901331_alarm_irq_enable(struct device *dev, unsigned int enabled)
        return 0;
 }
 
-static struct rtc_class_ops coh901331_ops = {
+static const struct rtc_class_ops coh901331_ops = {
        .read_time = coh901331_read_time,
        .set_mmss = coh901331_set_mmss,
        .read_alarm = coh901331_read_alarm,
index dba60c1dfce2ee9f71fefc6b023a8eee799e63d2..caf35567e14cbe1966b844ee7d6dd6012690ccdd 100644 (file)
@@ -469,7 +469,7 @@ static int davinci_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm)
        return 0;
 }
 
-static struct rtc_class_ops davinci_rtc_ops = {
+static const struct rtc_class_ops davinci_rtc_ops = {
        .ioctl                  = davinci_rtc_ioctl,
        .read_time              = davinci_rtc_read_time,
        .set_time               = davinci_rtc_set_time,
index 8d05596a6765915373edabfb5048d1e2a2457854..b253bf1b35314776ee3df0b9fc68c7c2f544ce78 100644 (file)
@@ -159,7 +159,7 @@ static int dc_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
        return 0;
 }
 
-static struct rtc_class_ops dc_rtc_ops = {
+static const struct rtc_class_ops dc_rtc_ops = {
        .read_time              = dc_rtc_read_time,
        .set_mmss               = dc_rtc_set_mmss,
        .read_alarm             = dc_rtc_read_alarm,
index f5dd09fe5add5e65a40d9d178f0283a30c9e6548..0ec4be62322bfaf7695eb99aa6efd428264a3771 100644 (file)
@@ -102,7 +102,7 @@ static int ds1302_rtc_get_time(struct device *dev, struct rtc_time *time)
        return rtc_valid_tm(time);
 }
 
-static struct rtc_class_ops ds1302_rtc_ops = {
+static const struct rtc_class_ops ds1302_rtc_ops = {
        .read_time      = ds1302_rtc_get_time,
        .set_time       = ds1302_rtc_set_time,
 };
index 8e1c5cb6ece6f60619e5cafcea4271e056d96778..4e31036ee2596dec93accd26f627c5b95591ae9f 100644 (file)
@@ -186,6 +186,7 @@ static const struct i2c_device_id ds1307_id[] = {
        { "mcp7941x", mcp794xx },
        { "pt7c4338", ds_1307 },
        { "rx8025", rx_8025 },
+       { "isl12057", ds_1337 },
        { }
 };
 MODULE_DEVICE_TABLE(i2c, ds1307_id);
@@ -382,10 +383,25 @@ static int ds1307_get_time(struct device *dev, struct rtc_time *t)
        t->tm_mday = bcd2bin(ds1307->regs[DS1307_REG_MDAY] & 0x3f);
        tmp = ds1307->regs[DS1307_REG_MONTH] & 0x1f;
        t->tm_mon = bcd2bin(tmp) - 1;
-
-       /* assume 20YY not 19YY, and ignore DS1337_BIT_CENTURY */
        t->tm_year = bcd2bin(ds1307->regs[DS1307_REG_YEAR]) + 100;
 
+#ifdef CONFIG_RTC_DRV_DS1307_CENTURY
+       switch (ds1307->type) {
+       case ds_1337:
+       case ds_1339:
+       case ds_3231:
+               if (ds1307->regs[DS1307_REG_MONTH] & DS1337_BIT_CENTURY)
+                       t->tm_year += 100;
+               break;
+       case ds_1340:
+               if (ds1307->regs[DS1307_REG_HOUR] & DS1340_BIT_CENTURY)
+                       t->tm_year += 100;
+               break;
+       default:
+               break;
+       }
+#endif
+
        dev_dbg(dev, "%s secs=%d, mins=%d, "
                "hours=%d, mday=%d, mon=%d, year=%d, wday=%d\n",
                "read", t->tm_sec, t->tm_min,
@@ -409,6 +425,27 @@ static int ds1307_set_time(struct device *dev, struct rtc_time *t)
                t->tm_hour, t->tm_mday,
                t->tm_mon, t->tm_year, t->tm_wday);
 
+#ifdef CONFIG_RTC_DRV_DS1307_CENTURY
+       if (t->tm_year < 100)
+               return -EINVAL;
+
+       switch (ds1307->type) {
+       case ds_1337:
+       case ds_1339:
+       case ds_3231:
+       case ds_1340:
+               if (t->tm_year > 299)
+                       return -EINVAL;
+       default:
+               if (t->tm_year > 199)
+                       return -EINVAL;
+               break;
+       }
+#else
+       if (t->tm_year < 100 || t->tm_year > 199)
+               return -EINVAL;
+#endif
+
        buf[DS1307_REG_SECS] = bin2bcd(t->tm_sec);
        buf[DS1307_REG_MIN] = bin2bcd(t->tm_min);
        buf[DS1307_REG_HOUR] = bin2bcd(t->tm_hour);
@@ -424,11 +461,13 @@ static int ds1307_set_time(struct device *dev, struct rtc_time *t)
        case ds_1337:
        case ds_1339:
        case ds_3231:
-               buf[DS1307_REG_MONTH] |= DS1337_BIT_CENTURY;
+               if (t->tm_year > 199)
+                       buf[DS1307_REG_MONTH] |= DS1337_BIT_CENTURY;
                break;
        case ds_1340:
-               buf[DS1307_REG_HOUR] |= DS1340_BIT_CENTURY_EN
-                               | DS1340_BIT_CENTURY;
+               buf[DS1307_REG_HOUR] |= DS1340_BIT_CENTURY_EN;
+               if (t->tm_year > 199)
+                       buf[DS1307_REG_HOUR] |= DS1340_BIT_CENTURY;
                break;
        case mcp794xx:
                /*
@@ -1295,6 +1334,11 @@ static int ds1307_probe(struct i2c_client *client,
        if (of_property_read_bool(client->dev.of_node, "wakeup-source")) {
                ds1307_can_wakeup_device = true;
        }
+       /* Intersil ISL12057 DT backward compatibility */
+       if (of_property_read_bool(client->dev.of_node,
+                                 "isil,irq2-can-wakeup-machine")) {
+               ds1307_can_wakeup_device = true;
+       }
 #endif
 
        switch (ds1307->type) {
index 641e8e8a0dd7251f677e9146c098e7ce475fa516..ccfc9d43eb1e680956d32892e9bacfaddefafd1a 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/rtc.h>
 #include <linux/spi/spi.h>
 #include <linux/bcd.h>
+#include <linux/regmap.h>
 
 /* Registers in ds1347 rtc */
 
 #define DS1347_STATUS_REG      0x17
 #define DS1347_CLOCK_BURST     0x3F
 
-static int ds1347_read_reg(struct device *dev, unsigned char address,
-                               unsigned char *data)
-{
-       struct spi_device *spi = to_spi_device(dev);
-
-       *data = address | 0x80;
-
-       return spi_write_then_read(spi, data, 1, data, 1);
-}
-
-static int ds1347_write_reg(struct device *dev, unsigned char address,
-                               unsigned char data)
-{
-       struct spi_device *spi = to_spi_device(dev);
-       unsigned char buf[2];
-
-       buf[0] = address & 0x7F;
-       buf[1] = data;
+static const struct regmap_range ds1347_ranges[] = {
+       {
+               .range_min = DS1347_SECONDS_REG,
+               .range_max = DS1347_STATUS_REG,
+       },
+};
 
-       return spi_write_then_read(spi, buf, 2, NULL, 0);
-}
+static const struct regmap_access_table ds1347_access_table = {
+       .yes_ranges = ds1347_ranges,
+       .n_yes_ranges = ARRAY_SIZE(ds1347_ranges),
+};
 
 static int ds1347_read_time(struct device *dev, struct rtc_time *dt)
 {
        struct spi_device *spi = to_spi_device(dev);
+       struct regmap *map;
        int err;
        unsigned char buf[8];
 
-       buf[0] = DS1347_CLOCK_BURST | 0x80;
+       map = spi_get_drvdata(spi);
 
-       err = spi_write_then_read(spi, buf, 1, buf, 8);
+       err = regmap_bulk_read(map, DS1347_CLOCK_BURST, buf, 8);
        if (err)
                return err;
 
@@ -80,25 +72,27 @@ static int ds1347_read_time(struct device *dev, struct rtc_time *dt)
 static int ds1347_set_time(struct device *dev, struct rtc_time *dt)
 {
        struct spi_device *spi = to_spi_device(dev);
-       unsigned char buf[9];
+       struct regmap *map;
+       unsigned char buf[8];
+
+       map = spi_get_drvdata(spi);
 
-       buf[0] = DS1347_CLOCK_BURST & 0x7F;
-       buf[1] = bin2bcd(dt->tm_sec);
-       buf[2] = bin2bcd(dt->tm_min);
-       buf[3] = (bin2bcd(dt->tm_hour) & 0x3F);
-       buf[4] = bin2bcd(dt->tm_mday);
-       buf[5] = bin2bcd(dt->tm_mon + 1);
-       buf[6] = bin2bcd(dt->tm_wday + 1);
+       buf[0] = bin2bcd(dt->tm_sec);
+       buf[1] = bin2bcd(dt->tm_min);
+       buf[2] = (bin2bcd(dt->tm_hour) & 0x3F);
+       buf[3] = bin2bcd(dt->tm_mday);
+       buf[4] = bin2bcd(dt->tm_mon + 1);
+       buf[5] = bin2bcd(dt->tm_wday + 1);
 
        /* year in linux is from 1900 i.e in range of 100
        in rtc it is from 00 to 99 */
        dt->tm_year = dt->tm_year % 100;
 
-       buf[7] = bin2bcd(dt->tm_year);
-       buf[8] = bin2bcd(0x00);
+       buf[6] = bin2bcd(dt->tm_year);
+       buf[7] = bin2bcd(0x00);
 
        /* write the rtc settings */
-       return spi_write_then_read(spi, buf, 9, NULL, 0);
+       return regmap_bulk_write(map, DS1347_CLOCK_BURST, buf, 8);
 }
 
 static const struct rtc_class_ops ds1347_rtc_ops = {
@@ -109,35 +103,53 @@ static const struct rtc_class_ops ds1347_rtc_ops = {
 static int ds1347_probe(struct spi_device *spi)
 {
        struct rtc_device *rtc;
-       unsigned char data;
+       struct regmap_config config;
+       struct regmap *map;
+       unsigned int data;
        int res;
 
+       memset(&config, 0, sizeof(config));
+       config.reg_bits = 8;
+       config.val_bits = 8;
+       config.read_flag_mask = 0x80;
+       config.max_register = 0x3F;
+       config.wr_table = &ds1347_access_table;
+
        /* spi setup with ds1347 in mode 3 and bits per word as 8 */
        spi->mode = SPI_MODE_3;
        spi->bits_per_word = 8;
        spi_setup(spi);
 
+       map = devm_regmap_init_spi(spi, &config);
+
+       if (IS_ERR(map)) {
+               dev_err(&spi->dev, "ds1347 regmap init spi failed\n");
+               return PTR_ERR(map);
+       }
+
+       spi_set_drvdata(spi, map);
+
        /* RTC Settings */
-       res = ds1347_read_reg(&spi->dev, DS1347_SECONDS_REG, &data);
+       res = regmap_read(map, DS1347_SECONDS_REG, &data);
        if (res)
                return res;
 
        /* Disable the write protect of rtc */
-       ds1347_read_reg(&spi->dev, DS1347_CONTROL_REG, &data);
+       regmap_read(map, DS1347_CONTROL_REG, &data);
        data = data & ~(1<<7);
-       ds1347_write_reg(&spi->dev, DS1347_CONTROL_REG, data);
+       regmap_write(map, DS1347_CONTROL_REG, data);
 
        /* Enable the oscillator , disable the oscillator stop flag,
         and glitch filter to reduce current consumption */
-       ds1347_read_reg(&spi->dev, DS1347_STATUS_REG, &data);
+       regmap_read(map, DS1347_STATUS_REG, &data);
        data = data & 0x1B;
-       ds1347_write_reg(&spi->dev, DS1347_STATUS_REG, data);
+       regmap_write(map, DS1347_STATUS_REG, data);
 
        /* display the settings */
-       ds1347_read_reg(&spi->dev, DS1347_CONTROL_REG, &data);
+       regmap_read(map, DS1347_CONTROL_REG, &data);
        dev_info(&spi->dev, "DS1347 RTC CTRL Reg = 0x%02x\n", data);
 
-       ds1347_read_reg(&spi->dev, DS1347_STATUS_REG, &data);
+       regmap_read(map, DS1347_STATUS_REG, &data);
        dev_info(&spi->dev, "DS1347 RTC Status Reg = 0x%02x\n", data);
 
        rtc = devm_rtc_device_register(&spi->dev, "ds1347",
@@ -146,8 +158,6 @@ static int ds1347_probe(struct spi_device *spi)
        if (IS_ERR(rtc))
                return PTR_ERR(rtc);
 
-       spi_set_drvdata(spi, rtc);
-
        return 0;
 }
 
index b57505efadbc85475bea0c6c11fa8c7115694dad..688debc143483ff33aef70c08c85656a093b0fc9 100644 (file)
@@ -110,7 +110,7 @@ static int gemini_rtc_set_time(struct device *dev, struct rtc_time *tm)
        return 0;
 }
 
-static struct rtc_class_ops gemini_rtc_ops = {
+static const struct rtc_class_ops gemini_rtc_ops = {
        .read_time     = gemini_rtc_read_time,
        .set_time      = gemini_rtc_set_time,
 };
diff --git a/drivers/rtc/rtc-isl12057.c b/drivers/rtc/rtc-isl12057.c
deleted file mode 100644 (file)
index 0e7f0f5..0000000
+++ /dev/null
@@ -1,643 +0,0 @@
-/*
- * rtc-isl12057 - Driver for Intersil ISL12057 I2C Real Time Clock
- *
- * Copyright (C) 2013, Arnaud EBALARD <arno@natisbad.org>
- *
- * This work is largely based on Intersil ISL1208 driver developed by
- * Hebert Valerio Riedel <hvr@gnu.org>.
- *
- * Detailed datasheet on which this development is based is available here:
- *
- *  http://natisbad.org/NAS2/refs/ISL12057.pdf
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
-
-#include <linux/module.h>
-#include <linux/mutex.h>
-#include <linux/rtc.h>
-#include <linux/i2c.h>
-#include <linux/bcd.h>
-#include <linux/of.h>
-#include <linux/of_device.h>
-#include <linux/regmap.h>
-
-#define DRV_NAME "rtc-isl12057"
-
-/* RTC section */
-#define ISL12057_REG_RTC_SC    0x00    /* Seconds */
-#define ISL12057_REG_RTC_MN    0x01    /* Minutes */
-#define ISL12057_REG_RTC_HR    0x02    /* Hours */
-#define ISL12057_REG_RTC_HR_PM BIT(5)  /* AM/PM bit in 12h format */
-#define ISL12057_REG_RTC_HR_MIL BIT(6) /* 24h/12h format */
-#define ISL12057_REG_RTC_DW    0x03    /* Day of the Week */
-#define ISL12057_REG_RTC_DT    0x04    /* Date */
-#define ISL12057_REG_RTC_MO    0x05    /* Month */
-#define ISL12057_REG_RTC_MO_CEN        BIT(7)  /* Century bit */
-#define ISL12057_REG_RTC_YR    0x06    /* Year */
-#define ISL12057_RTC_SEC_LEN   7
-
-/* Alarm 1 section */
-#define ISL12057_REG_A1_SC     0x07    /* Alarm 1 Seconds */
-#define ISL12057_REG_A1_MN     0x08    /* Alarm 1 Minutes */
-#define ISL12057_REG_A1_HR     0x09    /* Alarm 1 Hours */
-#define ISL12057_REG_A1_HR_PM  BIT(5)  /* AM/PM bit in 12h format */
-#define ISL12057_REG_A1_HR_MIL BIT(6)  /* 24h/12h format */
-#define ISL12057_REG_A1_DWDT   0x0A    /* Alarm 1 Date / Day of the week */
-#define ISL12057_REG_A1_DWDT_B BIT(6)  /* DW / DT selection bit */
-#define ISL12057_A1_SEC_LEN    4
-
-/* Alarm 2 section */
-#define ISL12057_REG_A2_MN     0x0B    /* Alarm 2 Minutes */
-#define ISL12057_REG_A2_HR     0x0C    /* Alarm 2 Hours */
-#define ISL12057_REG_A2_DWDT   0x0D    /* Alarm 2 Date / Day of the week */
-#define ISL12057_A2_SEC_LEN    3
-
-/* Control/Status registers */
-#define ISL12057_REG_INT       0x0E
-#define ISL12057_REG_INT_A1IE  BIT(0)  /* Alarm 1 interrupt enable bit */
-#define ISL12057_REG_INT_A2IE  BIT(1)  /* Alarm 2 interrupt enable bit */
-#define ISL12057_REG_INT_INTCN BIT(2)  /* Interrupt control enable bit */
-#define ISL12057_REG_INT_RS1   BIT(3)  /* Freq out control bit 1 */
-#define ISL12057_REG_INT_RS2   BIT(4)  /* Freq out control bit 2 */
-#define ISL12057_REG_INT_EOSC  BIT(7)  /* Oscillator enable bit */
-
-#define ISL12057_REG_SR                0x0F
-#define ISL12057_REG_SR_A1F    BIT(0)  /* Alarm 1 interrupt bit */
-#define ISL12057_REG_SR_A2F    BIT(1)  /* Alarm 2 interrupt bit */
-#define ISL12057_REG_SR_OSF    BIT(7)  /* Oscillator failure bit */
-
-/* Register memory map length */
-#define ISL12057_MEM_MAP_LEN   0x10
-
-struct isl12057_rtc_data {
-       struct rtc_device *rtc;
-       struct regmap *regmap;
-       struct mutex lock;
-       int irq;
-};
-
-static void isl12057_rtc_regs_to_tm(struct rtc_time *tm, u8 *regs)
-{
-       tm->tm_sec = bcd2bin(regs[ISL12057_REG_RTC_SC]);
-       tm->tm_min = bcd2bin(regs[ISL12057_REG_RTC_MN]);
-
-       if (regs[ISL12057_REG_RTC_HR] & ISL12057_REG_RTC_HR_MIL) { /* AM/PM */
-               tm->tm_hour = bcd2bin(regs[ISL12057_REG_RTC_HR] & 0x1f);
-               if (regs[ISL12057_REG_RTC_HR] & ISL12057_REG_RTC_HR_PM)
-                       tm->tm_hour += 12;
-       } else {                                            /* 24 hour mode */
-               tm->tm_hour = bcd2bin(regs[ISL12057_REG_RTC_HR] & 0x3f);
-       }
-
-       tm->tm_mday = bcd2bin(regs[ISL12057_REG_RTC_DT]);
-       tm->tm_wday = bcd2bin(regs[ISL12057_REG_RTC_DW]) - 1; /* starts at 1 */
-       tm->tm_mon  = bcd2bin(regs[ISL12057_REG_RTC_MO] & 0x1f) - 1; /* ditto */
-       tm->tm_year = bcd2bin(regs[ISL12057_REG_RTC_YR]) + 100;
-
-       /* Check if years register has overflown from 99 to 00 */
-       if (regs[ISL12057_REG_RTC_MO] & ISL12057_REG_RTC_MO_CEN)
-               tm->tm_year += 100;
-}
-
-static int isl12057_rtc_tm_to_regs(u8 *regs, struct rtc_time *tm)
-{
-       u8 century_bit;
-
-       /*
-        * The clock has an 8 bit wide bcd-coded register for the year.
-        * It also has a century bit encoded in MO flag which provides
-        * information about overflow of year register from 99 to 00.
-        * tm_year is an offset from 1900 and we are interested in the
-        * 2000-2199 range, so any value less than 100 or larger than
-        * 299 is invalid.
-        */
-       if (tm->tm_year < 100 || tm->tm_year > 299)
-               return -EINVAL;
-
-       century_bit = (tm->tm_year > 199) ? ISL12057_REG_RTC_MO_CEN : 0;
-
-       regs[ISL12057_REG_RTC_SC] = bin2bcd(tm->tm_sec);
-       regs[ISL12057_REG_RTC_MN] = bin2bcd(tm->tm_min);
-       regs[ISL12057_REG_RTC_HR] = bin2bcd(tm->tm_hour); /* 24-hour format */
-       regs[ISL12057_REG_RTC_DT] = bin2bcd(tm->tm_mday);
-       regs[ISL12057_REG_RTC_MO] = bin2bcd(tm->tm_mon + 1) | century_bit;
-       regs[ISL12057_REG_RTC_YR] = bin2bcd(tm->tm_year % 100);
-       regs[ISL12057_REG_RTC_DW] = bin2bcd(tm->tm_wday + 1);
-
-       return 0;
-}
-
-/*
- * Try and match register bits w/ fixed null values to see whether we
- * are dealing with an ISL12057. Note: this function is called early
- * during init and hence does need mutex protection.
- */
-static int isl12057_i2c_validate_chip(struct regmap *regmap)
-{
-       u8 regs[ISL12057_MEM_MAP_LEN];
-       static const u8 mask[ISL12057_MEM_MAP_LEN] = { 0x80, 0x80, 0x80, 0xf8,
-                                                      0xc0, 0x60, 0x00, 0x00,
-                                                      0x00, 0x00, 0x00, 0x00,
-                                                      0x00, 0x00, 0x60, 0x7c };
-       int ret, i;
-
-       ret = regmap_bulk_read(regmap, 0, regs, ISL12057_MEM_MAP_LEN);
-       if (ret)
-               return ret;
-
-       for (i = 0; i < ISL12057_MEM_MAP_LEN; ++i) {
-               if (regs[i] & mask[i])  /* check if bits are cleared */
-                       return -ENODEV;
-       }
-
-       return 0;
-}
-
-static int _isl12057_rtc_clear_alarm(struct device *dev)
-{
-       struct isl12057_rtc_data *data = dev_get_drvdata(dev);
-       int ret;
-
-       ret = regmap_update_bits(data->regmap, ISL12057_REG_SR,
-                                ISL12057_REG_SR_A1F, 0);
-       if (ret)
-               dev_err(dev, "%s: clearing alarm failed (%d)\n", __func__, ret);
-
-       return ret;
-}
-
-static int _isl12057_rtc_update_alarm(struct device *dev, int enable)
-{
-       struct isl12057_rtc_data *data = dev_get_drvdata(dev);
-       int ret;
-
-       ret = regmap_update_bits(data->regmap, ISL12057_REG_INT,
-                                ISL12057_REG_INT_A1IE,
-                                enable ? ISL12057_REG_INT_A1IE : 0);
-       if (ret)
-               dev_err(dev, "%s: changing alarm interrupt flag failed (%d)\n",
-                       __func__, ret);
-
-       return ret;
-}
-
-/*
- * Note: as we only read from device and do not perform any update, there is
- * no need for an equivalent function which would try and get driver's main
- * lock. Here, it is safe for everyone if we just use regmap internal lock
- * on the device when reading.
- */
-static int _isl12057_rtc_read_time(struct device *dev, struct rtc_time *tm)
-{
-       struct isl12057_rtc_data *data = dev_get_drvdata(dev);
-       u8 regs[ISL12057_RTC_SEC_LEN];
-       unsigned int sr;
-       int ret;
-
-       ret = regmap_read(data->regmap, ISL12057_REG_SR, &sr);
-       if (ret) {
-               dev_err(dev, "%s: unable to read oscillator status flag (%d)\n",
-                       __func__, ret);
-               goto out;
-       } else {
-               if (sr & ISL12057_REG_SR_OSF) {
-                       ret = -ENODATA;
-                       goto out;
-               }
-       }
-
-       ret = regmap_bulk_read(data->regmap, ISL12057_REG_RTC_SC, regs,
-                              ISL12057_RTC_SEC_LEN);
-       if (ret)
-               dev_err(dev, "%s: unable to read RTC time section (%d)\n",
-                       __func__, ret);
-
-out:
-       if (ret)
-               return ret;
-
-       isl12057_rtc_regs_to_tm(tm, regs);
-
-       return rtc_valid_tm(tm);
-}
-
-static int isl12057_rtc_update_alarm(struct device *dev, int enable)
-{
-       struct isl12057_rtc_data *data = dev_get_drvdata(dev);
-       int ret;
-
-       mutex_lock(&data->lock);
-       ret = _isl12057_rtc_update_alarm(dev, enable);
-       mutex_unlock(&data->lock);
-
-       return ret;
-}
-
-static int isl12057_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
-{
-       struct isl12057_rtc_data *data = dev_get_drvdata(dev);
-       struct rtc_time *alarm_tm = &alarm->time;
-       u8 regs[ISL12057_A1_SEC_LEN];
-       unsigned int ir;
-       int ret;
-
-       mutex_lock(&data->lock);
-       ret = regmap_bulk_read(data->regmap, ISL12057_REG_A1_SC, regs,
-                              ISL12057_A1_SEC_LEN);
-       if (ret) {
-               dev_err(dev, "%s: reading alarm section failed (%d)\n",
-                       __func__, ret);
-               goto err_unlock;
-       }
-
-       alarm_tm->tm_sec  = bcd2bin(regs[0] & 0x7f);
-       alarm_tm->tm_min  = bcd2bin(regs[1] & 0x7f);
-       alarm_tm->tm_hour = bcd2bin(regs[2] & 0x3f);
-       alarm_tm->tm_mday = bcd2bin(regs[3] & 0x3f);
-
-       ret = regmap_read(data->regmap, ISL12057_REG_INT, &ir);
-       if (ret) {
-               dev_err(dev, "%s: reading alarm interrupt flag failed (%d)\n",
-                       __func__, ret);
-               goto err_unlock;
-       }
-
-       alarm->enabled = !!(ir & ISL12057_REG_INT_A1IE);
-
-err_unlock:
-       mutex_unlock(&data->lock);
-
-       return ret;
-}
-
-static int isl12057_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
-{
-       struct isl12057_rtc_data *data = dev_get_drvdata(dev);
-       struct rtc_time *alarm_tm = &alarm->time;
-       unsigned long rtc_secs, alarm_secs;
-       u8 regs[ISL12057_A1_SEC_LEN];
-       struct rtc_time rtc_tm;
-       int ret, enable = 1;
-
-       mutex_lock(&data->lock);
-       ret = _isl12057_rtc_read_time(dev, &rtc_tm);
-       if (ret)
-               goto err_unlock;
-
-       ret = rtc_tm_to_time(&rtc_tm, &rtc_secs);
-       if (ret)
-               goto err_unlock;
-
-       ret = rtc_tm_to_time(alarm_tm, &alarm_secs);
-       if (ret)
-               goto err_unlock;
-
-       /* If alarm time is before current time, disable the alarm */
-       if (!alarm->enabled || alarm_secs <= rtc_secs) {
-               enable = 0;
-       } else {
-               /*
-                * Chip only support alarms up to one month in the future. Let's
-                * return an error if we get something after that limit.
-                * Comparison is done by incrementing rtc_tm month field by one
-                * and checking alarm value is still below.
-                */
-               if (rtc_tm.tm_mon == 11) { /* handle year wrapping */
-                       rtc_tm.tm_mon = 0;
-                       rtc_tm.tm_year += 1;
-               } else {
-                       rtc_tm.tm_mon += 1;
-               }
-
-               ret = rtc_tm_to_time(&rtc_tm, &rtc_secs);
-               if (ret)
-                       goto err_unlock;
-
-               if (alarm_secs > rtc_secs) {
-                       dev_err(dev, "%s: max for alarm is one month (%d)\n",
-                               __func__, ret);
-                       ret = -EINVAL;
-                       goto err_unlock;
-               }
-       }
-
-       /* Disable the alarm before modifying it */
-       ret = _isl12057_rtc_update_alarm(dev, 0);
-       if (ret < 0) {
-               dev_err(dev, "%s: unable to disable the alarm (%d)\n",
-                       __func__, ret);
-               goto err_unlock;
-       }
-
-       /* Program alarm registers */
-       regs[0] = bin2bcd(alarm_tm->tm_sec) & 0x7f;
-       regs[1] = bin2bcd(alarm_tm->tm_min) & 0x7f;
-       regs[2] = bin2bcd(alarm_tm->tm_hour) & 0x3f;
-       regs[3] = bin2bcd(alarm_tm->tm_mday) & 0x3f;
-
-       ret = regmap_bulk_write(data->regmap, ISL12057_REG_A1_SC, regs,
-                               ISL12057_A1_SEC_LEN);
-       if (ret < 0) {
-               dev_err(dev, "%s: writing alarm section failed (%d)\n",
-                       __func__, ret);
-               goto err_unlock;
-       }
-
-       /* Enable or disable alarm */
-       ret = _isl12057_rtc_update_alarm(dev, enable);
-
-err_unlock:
-       mutex_unlock(&data->lock);
-
-       return ret;
-}
-
-static int isl12057_rtc_set_time(struct device *dev, struct rtc_time *tm)
-{
-       struct isl12057_rtc_data *data = dev_get_drvdata(dev);
-       u8 regs[ISL12057_RTC_SEC_LEN];
-       int ret;
-
-       ret = isl12057_rtc_tm_to_regs(regs, tm);
-       if (ret)
-               return ret;
-
-       mutex_lock(&data->lock);
-       ret = regmap_bulk_write(data->regmap, ISL12057_REG_RTC_SC, regs,
-                               ISL12057_RTC_SEC_LEN);
-       if (ret) {
-               dev_err(dev, "%s: unable to write RTC time section (%d)\n",
-                       __func__, ret);
-               goto out;
-       }
-
-       /*
-        * Now that RTC time has been updated, let's clear oscillator
-        * failure flag, if needed.
-        */
-       ret = regmap_update_bits(data->regmap, ISL12057_REG_SR,
-                                ISL12057_REG_SR_OSF, 0);
-       if (ret < 0)
-               dev_err(dev, "%s: unable to clear osc. failure bit (%d)\n",
-                       __func__, ret);
-
-out:
-       mutex_unlock(&data->lock);
-
-       return ret;
-}
-
-/*
- * Check current RTC status and enable/disable what needs to be. Return 0 if
- * everything went ok and a negative value upon error. Note: this function
- * is called early during init and hence does need mutex protection.
- */
-static int isl12057_check_rtc_status(struct device *dev, struct regmap *regmap)
-{
-       int ret;
-
-       /* Enable oscillator if not already running */
-       ret = regmap_update_bits(regmap, ISL12057_REG_INT,
-                                ISL12057_REG_INT_EOSC, 0);
-       if (ret < 0) {
-               dev_err(dev, "%s: unable to enable oscillator (%d)\n",
-                       __func__, ret);
-               return ret;
-       }
-
-       /* Clear alarm bit if needed */
-       ret = regmap_update_bits(regmap, ISL12057_REG_SR,
-                                ISL12057_REG_SR_A1F, 0);
-       if (ret < 0) {
-               dev_err(dev, "%s: unable to clear alarm bit (%d)\n",
-                       __func__, ret);
-               return ret;
-       }
-
-       return 0;
-}
-
-#ifdef CONFIG_OF
-/*
- * One would expect the device to be marked as a wakeup source only
- * when an IRQ pin of the RTC is routed to an interrupt line of the
- * CPU. In practice, such an IRQ pin can be connected to a PMIC and
- * this allows the device to be powered up when RTC alarm rings. This
- * is for instance the case on ReadyNAS 102, 104 and 2120. On those
- * devices with no IRQ driectly connected to the SoC, the RTC chip
- * can be forced as a wakeup source by stating that explicitly in
- * the device's .dts file using the "wakeup-source" boolean property.
- * This will guarantee 'wakealarm' sysfs entry is available on the device.
- *
- * The function below returns 1, i.e. the capability of the chip to
- * wakeup the device, based on IRQ availability or if the boolean
- * property has been set in the .dts file. Otherwise, it returns 0.
- */
-
-static bool isl12057_can_wakeup_machine(struct device *dev)
-{
-       struct isl12057_rtc_data *data = dev_get_drvdata(dev);
-
-       return data->irq || of_property_read_bool(dev->of_node, "wakeup-source")
-               || of_property_read_bool(dev->of_node, /* legacy */
-                                        "isil,irq2-can-wakeup-machine");
-}
-#else
-static bool isl12057_can_wakeup_machine(struct device *dev)
-{
-       struct isl12057_rtc_data *data = dev_get_drvdata(dev);
-
-       return !!data->irq;
-}
-#endif
-
-static int isl12057_rtc_alarm_irq_enable(struct device *dev,
-                                        unsigned int enable)
-{
-       struct isl12057_rtc_data *rtc_data = dev_get_drvdata(dev);
-       int ret = -ENOTTY;
-
-       if (rtc_data->irq)
-               ret = isl12057_rtc_update_alarm(dev, enable);
-
-       return ret;
-}
-
-static irqreturn_t isl12057_rtc_interrupt(int irq, void *data)
-{
-       struct i2c_client *client = data;
-       struct isl12057_rtc_data *rtc_data = dev_get_drvdata(&client->dev);
-       struct rtc_device *rtc = rtc_data->rtc;
-       int ret, handled = IRQ_NONE;
-       unsigned int sr;
-
-       ret = regmap_read(rtc_data->regmap, ISL12057_REG_SR, &sr);
-       if (!ret && (sr & ISL12057_REG_SR_A1F)) {
-               dev_dbg(&client->dev, "RTC alarm!\n");
-
-               rtc_update_irq(rtc, 1, RTC_IRQF | RTC_AF);
-
-               /* Acknowledge and disable the alarm */
-               _isl12057_rtc_clear_alarm(&client->dev);
-               _isl12057_rtc_update_alarm(&client->dev, 0);
-
-               handled = IRQ_HANDLED;
-       }
-
-       return handled;
-}
-
-static const struct rtc_class_ops rtc_ops = {
-       .read_time = _isl12057_rtc_read_time,
-       .set_time = isl12057_rtc_set_time,
-       .read_alarm = isl12057_rtc_read_alarm,
-       .set_alarm = isl12057_rtc_set_alarm,
-       .alarm_irq_enable = isl12057_rtc_alarm_irq_enable,
-};
-
-static const struct regmap_config isl12057_rtc_regmap_config = {
-       .reg_bits = 8,
-       .val_bits = 8,
-};
-
-static int isl12057_probe(struct i2c_client *client,
-                         const struct i2c_device_id *id)
-{
-       struct device *dev = &client->dev;
-       struct isl12057_rtc_data *data;
-       struct regmap *regmap;
-       int ret;
-
-       if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C |
-                                    I2C_FUNC_SMBUS_BYTE_DATA |
-                                    I2C_FUNC_SMBUS_I2C_BLOCK))
-               return -ENODEV;
-
-       regmap = devm_regmap_init_i2c(client, &isl12057_rtc_regmap_config);
-       if (IS_ERR(regmap)) {
-               ret = PTR_ERR(regmap);
-               dev_err(dev, "%s: regmap allocation failed (%d)\n",
-                       __func__, ret);
-               return ret;
-       }
-
-       ret = isl12057_i2c_validate_chip(regmap);
-       if (ret)
-               return ret;
-
-       ret = isl12057_check_rtc_status(dev, regmap);
-       if (ret)
-               return ret;
-
-       data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
-       if (!data)
-               return -ENOMEM;
-
-       mutex_init(&data->lock);
-       data->regmap = regmap;
-       dev_set_drvdata(dev, data);
-
-       if (client->irq > 0) {
-               ret = devm_request_threaded_irq(dev, client->irq, NULL,
-                                               isl12057_rtc_interrupt,
-                                               IRQF_SHARED|IRQF_ONESHOT,
-                                               DRV_NAME, client);
-               if (!ret)
-                       data->irq = client->irq;
-               else
-                       dev_err(dev, "%s: irq %d unavailable (%d)\n", __func__,
-                               client->irq, ret);
-       }
-
-       if (isl12057_can_wakeup_machine(dev))
-               device_init_wakeup(dev, true);
-
-       data->rtc = devm_rtc_device_register(dev, DRV_NAME, &rtc_ops,
-                                            THIS_MODULE);
-       ret = PTR_ERR_OR_ZERO(data->rtc);
-       if (ret) {
-               dev_err(dev, "%s: unable to register RTC device (%d)\n",
-                       __func__, ret);
-               goto err;
-       }
-
-       /* We cannot support UIE mode if we do not have an IRQ line */
-       if (!data->irq)
-               data->rtc->uie_unsupported = 1;
-
-err:
-       return ret;
-}
-
-static int isl12057_remove(struct i2c_client *client)
-{
-       if (isl12057_can_wakeup_machine(&client->dev))
-               device_init_wakeup(&client->dev, false);
-
-       return 0;
-}
-
-#ifdef CONFIG_PM_SLEEP
-static int isl12057_rtc_suspend(struct device *dev)
-{