Browse Source

Merge tag 'mfd-next-4.18' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd

Pull MFD updates from Lee Jones:
 "New Device Support:
   - Add support for AXP813 ADC to AXP20x
   - Add support for PM8005, PM8998 and PMI8998

  New Functionality:
   - Add support for Battery Power Supply to AXP813
   - Add support for SYSCON to SPARD SC27XX SPI
   - Add support for RTC to ChromeOS Embedded-Controller

  Fix-ups:
   - Remove unused code; exynos{4,5}-pmu, cros_ec, cros_ec_acpi_gpe
   - Remove duplicate error messages (-ENOMEM, etc); htc-i2cpld,
        janz-cmodio, max8997, rc5t583, sm501, smsc-ece1099, abx500-core,
        si476x-i2c, ti_am335x_tscadc, tps65090, tps6586x, tps65910,
        tps80031, twl6030-irq, viperboard
   - Succinctly use ptr to struct in sizeof(); rc5t583, abx500-core,
        sm501, smsc-ece1099
   - Simplify syntax for NULL ptr checking; abx500-core, sm501
   - No not unnecessarily initialise variables; tps65910, tps65910
   - Reorganise and simplify driver data; omap-usb-tll
   - Move to SPDX license statement; tps68470
   - Probe ADCs via DT; axp20x
   - Use new GPIOD API; arizona-core
   - Constify things; axp20x
   - Reduce code-size (use MACROS, etc); axp20x, omap-usb-host
   - Add DT support/docs; motorola-cpcap
   - Remove VLAs; rave-sp
   - Use devm_* managed resources; cros_ec
   - Interrogate HW for firmware version; rave-sp
   - Provide ACPI support for ChromeOS Embedded-Controller

  Bug Fixes:
   - Reorder ordered (enum) device list; tps65218
   - Only accept valid data from the offset; rave-sp
   - Refrain from copying junk from failed SPI read; cros_ec_dev
   - Fix potential memory leaks; pcf50633-core
   - Fix clock initialisation; twl-core
   - Fix build-issue; tps65911
   - Fix off-by-one error; tps65911
   - Fix code ordering issues; intel-lpss
   - Fix COMPILE_TEST related issues; pwm-stm32
   - Fix broken MMC card detection; asic3
   - Fix clocking related issues; intel-lpss-pci"

* tag 'mfd-next-4.18' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd: (84 commits)
  mfd: cros_ec: Remove unused __remove function
  mfd: wm97xx-core: Platform data can be NULL
  mfd: cros_ec_dev: Don't advertise junk features on failure
  mfd: cros_ec: Use devm_kzalloc for private data
  mfd: intel-lpss: Fix Intel Cannon Lake LPSS I2C input clock
  mfd: asic3: Fix broken MMC card detection
  mfd: timberdale: Fix spelling mistake "Uknown" -> "Unknown"
  mfd: omap-usb-host: Use match_string() helper
  mfd: stm32-timers: Fix pwm-stm32 linker issue with COMPILE_TEST
  pwm: stm32: Initialize raw local variables
  mfd: arizona: Update DT doc to support more standard Reset binding
  dt-bindings: mfd: Add bindings for DA9063L
  mfd: intel-lpss: Correct names of RESETS register bits
  mfd: qcom-spmi-pmic: Add support for pm8005, pm8998 and pmi8998
  mfd: intel-lpss: Program REMAP register in PIO mode
  mfd: cros_ec_i2c: Moving the system sleep pm ops to late
  mfd: cros_ec_i2c: Add ACPI module device table
  mfd: cros_ec_dev: Register shutdown function for debugfs
  mfd: cros_ec_dev: Register cros-ec-rtc driver as a subdevice
  mfd: cros_ec: Don't try to grab log when suspended
  ...
Linus Torvalds 7 years ago
parent
commit
883cad5ba8
64 changed files with 1574 additions and 994 deletions
  1. 43 0
      Documentation/devicetree/bindings/input/mtk-pmic-keys.txt
  2. 5 1
      Documentation/devicetree/bindings/mfd/arizona.txt
  3. 17 15
      Documentation/devicetree/bindings/mfd/da9063.txt
  4. 42 0
      Documentation/devicetree/bindings/mfd/motorola-cpcap.txt
  5. 6 0
      Documentation/devicetree/bindings/mfd/mt6397.txt
  6. 3 0
      Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.txt
  7. 10 0
      MAINTAINERS
  8. 9 0
      drivers/input/keyboard/Kconfig
  9. 1 0
      drivers/input/keyboard/Makefile
  10. 339 0
      drivers/input/keyboard/mtk-pmic-keys.c
  11. 0 1
      drivers/mfd/Makefile
  12. 1 2
      drivers/mfd/ab8500-debugfs.c
  13. 11 14
      drivers/mfd/abx500-core.c
  14. 35 18
      drivers/mfd/arizona-core.c
  15. 3 0
      drivers/mfd/asic3.c
  16. 1 0
      drivers/mfd/atmel-smc.c
  17. 67 185
      drivers/mfd/axp20x.c
  18. 14 27
      drivers/mfd/cros_ec.c
  19. 0 103
      drivers/mfd/cros_ec_acpi_gpe.c
  20. 33 12
      drivers/mfd/cros_ec_dev.c
  21. 15 2
      drivers/mfd/cros_ec_i2c.c
  22. 114 348
      drivers/mfd/da9062-core.c
  23. 1 3
      drivers/mfd/htc-i2cpld.c
  24. 15 10
      drivers/mfd/intel-lpss-pci.c
  25. 4 4
      drivers/mfd/intel-lpss.c
  26. 1 3
      drivers/mfd/janz-cmodio.c
  27. 1 3
      drivers/mfd/jz4740-adc.c
  28. 1 3
      drivers/mfd/max8997.c
  29. 23 3
      drivers/mfd/mt6397-core.c
  30. 2 22
      drivers/mfd/omap-usb-host.c
  31. 25 35
      drivers/mfd/omap-usb-tll.c
  32. 5 2
      drivers/mfd/pcf50633-core.c
  33. 6 0
      drivers/mfd/qcom-spmi-pmic.c
  34. 110 8
      drivers/mfd/rave-sp.c
  35. 2 4
      drivers/mfd/rc5t583.c
  36. 2 4
      drivers/mfd/si476x-i2c.c
  37. 13 19
      drivers/mfd/sm501.c
  38. 2 5
      drivers/mfd/smsc-ece1099.c
  39. 3 0
      drivers/mfd/sprd-sc27xx-spi.c
  40. 199 2
      drivers/mfd/stm32-timers.c
  41. 2 0
      drivers/mfd/syscon.c
  42. 2 3
      drivers/mfd/ti_am335x_tscadc.c
  43. 1 1
      drivers/mfd/timberdale.c
  44. 1 3
      drivers/mfd/tps65090.c
  45. 1 3
      drivers/mfd/tps6586x.c
  46. 8 10
      drivers/mfd/tps65910.c
  47. 5 12
      drivers/mfd/tps65911-comparator.c
  48. 1 9
      drivers/mfd/tps68470.c
  49. 1 3
      drivers/mfd/tps80031.c
  50. 1 1
      drivers/mfd/twl-core.c
  51. 1 3
      drivers/mfd/twl6030-irq.c
  52. 1 3
      drivers/mfd/viperboard.c
  53. 1 1
      drivers/mfd/wm97xx-core.c
  54. 20 0
      drivers/platform/chrome/cros_ec_debugfs.c
  55. 257 0
      drivers/pwm/pwm-stm32.c
  56. 3 4
      drivers/rtc/rtc-mt6397.c
  57. 2 1
      include/linux/mfd/arizona/pdata.h
  58. 5 5
      include/linux/mfd/axp20x.h
  59. 2 18
      include/linux/mfd/cros_ec.h
  60. 70 0
      include/linux/mfd/stm32-timers.h
  61. 0 21
      include/linux/mfd/syscon/exynos4-pmu.h
  62. 0 19
      include/linux/mfd/syscon/exynos5-pmu.h
  63. 2 2
      include/linux/mfd/tps65218.h
  64. 3 14
      include/linux/mfd/tps68470.h

+ 43 - 0
Documentation/devicetree/bindings/input/mtk-pmic-keys.txt

@@ -0,0 +1,43 @@
+MediaTek MT6397/MT6323 PMIC Keys Device Driver
+
+There are two key functions provided by MT6397/MT6323 PMIC, pwrkey
+and homekey. The key functions are defined as the subnode of the function
+node provided by MT6397/MT6323 PMIC that is being defined as one kind
+of Muti-Function Device (MFD)
+
+For MT6397/MT6323 MFD bindings see:
+Documentation/devicetree/bindings/mfd/mt6397.txt
+
+Required properties:
+- compatible: "mediatek,mt6397-keys" or "mediatek,mt6323-keys"
+- linux,keycodes: See Documentation/devicetree/bindings/input/keys.txt
+
+Optional Properties:
+- wakeup-source: See Documentation/devicetree/bindings/power/wakeup-source.txt
+- mediatek,long-press-mode: Long press key shutdown setting, 1 for
+	pwrkey only, 2 for pwrkey/homekey together, others for disabled.
+- power-off-time-sec: See Documentation/devicetree/bindings/input/keys.txt
+
+Example:
+
+	pmic: mt6397 {
+		compatible = "mediatek,mt6397";
+
+		...
+
+		mt6397keys: mt6397keys {
+			compatible = "mediatek,mt6397-keys";
+			mediatek,long-press-mode = <1>;
+			power-off-time-sec = <0>;
+
+			power {
+				linux,keycodes = <116>;
+				wakeup-source;
+			};
+
+			home {
+				linux,keycodes = <114>;
+			};
+		};
+
+	};

+ 5 - 1
Documentation/devicetree/bindings/mfd/arizona.txt

@@ -50,7 +50,7 @@ Required properties:
 
 
 Optional properties:
 Optional properties:
 
 
-  - wlf,reset : GPIO specifier for the GPIO controlling /RESET
+  - reset-gpios : GPIO specifier for the GPIO controlling /RESET
 
 
   - clocks: Should reference the clocks supplied on MCLK1 and MCLK2
   - clocks: Should reference the clocks supplied on MCLK1 and MCLK2
   - clock-names: Should contains two strings:
   - clock-names: Should contains two strings:
@@ -70,6 +70,10 @@ Optional properties:
     Documentation/devicetree/bindings/regulator/regulator.txt
     Documentation/devicetree/bindings/regulator/regulator.txt
     (wm5102, wm5110, wm8280, wm8997, wm8998, wm1814)
     (wm5102, wm5110, wm8280, wm8997, wm8998, wm1814)
 
 
+Deprecated properties:
+
+  - wlf,reset : GPIO specifier for the GPIO controlling /RESET
+
 Also see child specific device properties:
 Also see child specific device properties:
   Regulator - ../regulator/arizona-regulator.txt
   Regulator - ../regulator/arizona-regulator.txt
   Extcon    - ../extcon/extcon-arizona.txt
   Extcon    - ../extcon/extcon-arizona.txt

+ 17 - 15
Documentation/devicetree/bindings/mfd/da9063.txt

@@ -1,4 +1,4 @@
-* Dialog DA9063 Power Management Integrated Circuit (PMIC)
+* Dialog DA9063/DA9063L Power Management Integrated Circuit (PMIC)
 
 
 DA9093 consists of a large and varied group of sub-devices (I2C Only):
 DA9093 consists of a large and varied group of sub-devices (I2C Only):
 
 
@@ -6,14 +6,14 @@ Device                   Supply Names    Description
 ------                   ------------    -----------
 ------                   ------------    -----------
 da9063-regulator        :               : LDOs & BUCKs
 da9063-regulator        :               : LDOs & BUCKs
 da9063-onkey            :               : On Key
 da9063-onkey            :               : On Key
-da9063-rtc              :               : Real-Time Clock
+da9063-rtc              :               : Real-Time Clock (DA9063 only)
 da9063-watchdog         :               : Watchdog
 da9063-watchdog         :               : Watchdog
 
 
 ======
 ======
 
 
 Required properties:
 Required properties:
 
 
-- compatible : Should be "dlg,da9063"
+- compatible : Should be "dlg,da9063" or "dlg,da9063l"
 - reg : Specifies the I2C slave address (this defaults to 0x58 but it can be
 - reg : Specifies the I2C slave address (this defaults to 0x58 but it can be
   modified to match the chip's OTP settings).
   modified to match the chip's OTP settings).
 - interrupt-parent : Specifies the reference to the interrupt controller for
 - interrupt-parent : Specifies the reference to the interrupt controller for
@@ -23,8 +23,8 @@ Required properties:
 
 
 Sub-nodes:
 Sub-nodes:
 
 
-- regulators : This node defines the settings for the LDOs and BUCKs. The
-  DA9063 regulators are bound using their names listed below:
+- regulators : This node defines the settings for the LDOs and BUCKs.
+  The DA9063(L) regulators are bound using their names listed below:
 
 
     bcore1    : BUCK CORE1
     bcore1    : BUCK CORE1
     bcore2    : BUCK CORE2
     bcore2    : BUCK CORE2
@@ -32,16 +32,16 @@ Sub-nodes:
     bmem      : BUCK MEM
     bmem      : BUCK MEM
     bio       : BUCK IO
     bio       : BUCK IO
     bperi     : BUCK PERI
     bperi     : BUCK PERI
-    ldo1      : LDO_1
-    ldo2      : LDO_2
+    ldo1      : LDO_1	(DA9063 only)
+    ldo2      : LDO_2	(DA9063 only)
     ldo3      : LDO_3
     ldo3      : LDO_3
-    ldo4      : LDO_4
-    ldo5      : LDO_5
-    ldo6      : LDO_6
+    ldo4      : LDO_4	(DA9063 only)
+    ldo5      : LDO_5	(DA9063 only)
+    ldo6      : LDO_6	(DA9063 only)
     ldo7      : LDO_7
     ldo7      : LDO_7
     ldo8      : LDO_8
     ldo8      : LDO_8
     ldo9      : LDO_9
     ldo9      : LDO_9
-    ldo10     : LDO_10
+    ldo10     : LDO_10	(DA9063 only)
     ldo11     : LDO_11
     ldo11     : LDO_11
 
 
   The component follows the standard regulator framework and the bindings
   The component follows the standard regulator framework and the bindings
@@ -49,8 +49,9 @@ Sub-nodes:
   Documentation/devicetree/bindings/regulator/regulator.txt
   Documentation/devicetree/bindings/regulator/regulator.txt
 
 
 - rtc : This node defines settings for the Real-Time Clock associated with
 - rtc : This node defines settings for the Real-Time Clock associated with
-  the DA9063. There are currently no entries in this binding, however
-  compatible = "dlg,da9063-rtc" should be added if a node is created.
+  the DA9063 only. The RTC is not present in DA9063L. There are currently
+  no entries in this binding, however compatible = "dlg,da9063-rtc" should
+  be added if a node is created.
 
 
 - onkey : This node defines the OnKey settings for controlling the key
 - onkey : This node defines the OnKey settings for controlling the key
   functionality of the device. The node should contain the compatible property
   functionality of the device. The node should contain the compatible property
@@ -65,8 +66,9 @@ Sub-nodes:
     and KEY_SLEEP.
     and KEY_SLEEP.
 
 
 - watchdog : This node defines settings for the Watchdog timer associated
 - watchdog : This node defines settings for the Watchdog timer associated
-  with the DA9063. There are currently no entries in this binding, however
-  compatible = "dlg,da9063-watchdog" should be added if a node is created.
+  with the DA9063 and DA9063L. There are currently no entries in this
+  binding, however compatible = "dlg,da9063-watchdog" should be added
+  if a node is created.
 
 
 
 
 Example:
 Example:

+ 42 - 0
Documentation/devicetree/bindings/mfd/motorola-cpcap.txt

@@ -12,6 +12,30 @@ Required properties:
 - spi-max-frequency	: Typically set to 3000000
 - spi-max-frequency	: Typically set to 3000000
 - spi-cs-high		: SPI chip select direction
 - spi-cs-high		: SPI chip select direction
 
 
+Optional subnodes:
+
+The sub-functions of CPCAP get their own node with their own compatible values,
+which are described in the following files:
+
+- ../power/supply/cpcap-battery.txt
+- ../power/supply/cpcap-charger.txt
+- ../regulator/cpcap-regulator.txt
+- ../phy/phy-cpcap-usb.txt
+- ../input/cpcap-pwrbutton.txt
+- ../rtc/cpcap-rtc.txt
+- ../leds/leds-cpcap.txt
+- ../iio/adc/cpcap-adc.txt
+
+The only exception is the audio codec. Instead of a compatible value its
+node must be named "audio-codec".
+
+Required properties for the audio-codec subnode:
+
+- #sound-dai-cells = <1>;
+
+The audio-codec provides two DAIs. The first one is connected to the
+Stereo HiFi DAC and the second one is connected to the Voice DAC.
+
 Example:
 Example:
 
 
 &mcspi1 {
 &mcspi1 {
@@ -26,6 +50,24 @@ Example:
 		#size-cells = <0>;
 		#size-cells = <0>;
 		spi-max-frequency = <3000000>;
 		spi-max-frequency = <3000000>;
 		spi-cs-high;
 		spi-cs-high;
+
+		audio-codec {
+			#sound-dai-cells = <1>;
+
+			/* HiFi */
+			port@0 {
+				endpoint {
+					remote-endpoint = <&cpu_dai1>;
+				};
+			};
+
+			/* Voice */
+			port@1 {
+				endpoint {
+					remote-endpoint = <&cpu_dai2>;
+				};
+			};
+		};
 	};
 	};
 };
 };
 
 

+ 6 - 0
Documentation/devicetree/bindings/mfd/mt6397.txt

@@ -7,6 +7,7 @@ MT6397/MT6323 is a multifunction device with the following sub modules:
 - GPIO
 - GPIO
 - Clock
 - Clock
 - LED
 - LED
+- Keys
 
 
 It is interfaced to host controller using SPI interface by a proprietary hardware
 It is interfaced to host controller using SPI interface by a proprietary hardware
 called PMIC wrapper or pwrap. MT6397/MT6323 MFD is a child device of pwrap.
 called PMIC wrapper or pwrap. MT6397/MT6323 MFD is a child device of pwrap.
@@ -40,6 +41,11 @@ Optional subnodes:
 		- compatible: "mediatek,mt6323-led"
 		- compatible: "mediatek,mt6323-led"
 	see Documentation/devicetree/bindings/leds/leds-mt6323.txt
 	see Documentation/devicetree/bindings/leds/leds-mt6323.txt
 
 
+- keys
+	Required properties:
+		- compatible: "mediatek,mt6397-keys" or "mediatek,mt6323-keys"
+	see Documentation/devicetree/bindings/input/mtk-pmic-keys.txt
+
 Example:
 Example:
 	pwrap: pwrap@1000f000 {
 	pwrap: pwrap@1000f000 {
 		compatible = "mediatek,mt8135-pwrap";
 		compatible = "mediatek,mt8135-pwrap";

+ 3 - 0
Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.txt

@@ -29,6 +29,9 @@ Required properties:
                    "qcom,pm8916",
                    "qcom,pm8916",
                    "qcom,pm8004",
                    "qcom,pm8004",
                    "qcom,pm8909",
                    "qcom,pm8909",
+                   "qcom,pm8998",
+                   "qcom,pmi8998",
+                   "qcom,pm8005",
                    or generalized "qcom,spmi-pmic".
                    or generalized "qcom,spmi-pmic".
 - reg:             Specifies the SPMI USID slave address for this device.
 - reg:             Specifies the SPMI USID slave address for this device.
                    For more information see:
                    For more information see:

+ 10 - 0
MAINTAINERS

@@ -13562,6 +13562,16 @@ T:	git git://linuxtv.org/media_tree.git
 S:	Maintained
 S:	Maintained
 F:	drivers/media/usb/stk1160/
 F:	drivers/media/usb/stk1160/
 
 
+STM32 TIMER/LPTIMER DRIVERS
+M:	Fabrice Gasnier <fabrice.gasnier@st.com>
+S:	Maintained
+F:	drivers/*/stm32-*timer*
+F:	drivers/pwm/pwm-stm32*
+F:	include/linux/*/stm32-*tim*
+F:	Documentation/ABI/testing/*timer-stm32
+F:	Documentation/devicetree/bindings/*/stm32-*timer
+F:	Documentation/devicetree/bindings/pwm/pwm-stm32*
+
 STMMAC ETHERNET DRIVER
 STMMAC ETHERNET DRIVER
 M:	Giuseppe Cavallaro <peppe.cavallaro@st.com>
 M:	Giuseppe Cavallaro <peppe.cavallaro@st.com>
 M:	Alexandre Torgue <alexandre.torgue@st.com>
 M:	Alexandre Torgue <alexandre.torgue@st.com>

+ 9 - 0
drivers/input/keyboard/Kconfig

@@ -747,4 +747,13 @@ config KEYBOARD_BCM
 	  To compile this driver as a module, choose M here: the
 	  To compile this driver as a module, choose M here: the
 	  module will be called bcm-keypad.
 	  module will be called bcm-keypad.
 
 
+config KEYBOARD_MTK_PMIC
+	tristate "MediaTek PMIC keys support"
+	depends on MFD_MT6397
+	help
+	  Say Y here if you want to use the pmic keys (powerkey/homekey).
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called pmic-keys.
+
 endif
 endif

+ 1 - 0
drivers/input/keyboard/Makefile

@@ -40,6 +40,7 @@ obj-$(CONFIG_KEYBOARD_MATRIX)		+= matrix_keypad.o
 obj-$(CONFIG_KEYBOARD_MAX7359)		+= max7359_keypad.o
 obj-$(CONFIG_KEYBOARD_MAX7359)		+= max7359_keypad.o
 obj-$(CONFIG_KEYBOARD_MCS)		+= mcs_touchkey.o
 obj-$(CONFIG_KEYBOARD_MCS)		+= mcs_touchkey.o
 obj-$(CONFIG_KEYBOARD_MPR121)		+= mpr121_touchkey.o
 obj-$(CONFIG_KEYBOARD_MPR121)		+= mpr121_touchkey.o
+obj-$(CONFIG_KEYBOARD_MTK_PMIC) 	+= mtk-pmic-keys.o
 obj-$(CONFIG_KEYBOARD_NEWTON)		+= newtonkbd.o
 obj-$(CONFIG_KEYBOARD_NEWTON)		+= newtonkbd.o
 obj-$(CONFIG_KEYBOARD_NOMADIK)		+= nomadik-ske-keypad.o
 obj-$(CONFIG_KEYBOARD_NOMADIK)		+= nomadik-ske-keypad.o
 obj-$(CONFIG_KEYBOARD_NSPIRE)		+= nspire-keypad.o
 obj-$(CONFIG_KEYBOARD_NSPIRE)		+= nspire-keypad.o

+ 339 - 0
drivers/input/keyboard/mtk-pmic-keys.c

@@ -0,0 +1,339 @@
+/*
+ * Copyright (C) 2017 MediaTek, Inc.
+ *
+ * Author: Chen Zhong <chen.zhong@mediatek.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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/kernel.h>
+#include <linux/input.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/kernel.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/regmap.h>
+#include <linux/mfd/mt6323/registers.h>
+#include <linux/mfd/mt6397/registers.h>
+#include <linux/mfd/mt6397/core.h>
+
+#define MTK_PMIC_PWRKEY_RST_EN_MASK	0x1
+#define MTK_PMIC_PWRKEY_RST_EN_SHIFT	6
+#define MTK_PMIC_HOMEKEY_RST_EN_MASK	0x1
+#define MTK_PMIC_HOMEKEY_RST_EN_SHIFT	5
+#define MTK_PMIC_RST_DU_MASK		0x3
+#define MTK_PMIC_RST_DU_SHIFT		8
+
+#define MTK_PMIC_PWRKEY_RST		\
+	(MTK_PMIC_PWRKEY_RST_EN_MASK << MTK_PMIC_PWRKEY_RST_EN_SHIFT)
+#define MTK_PMIC_HOMEKEY_RST		\
+	(MTK_PMIC_HOMEKEY_RST_EN_MASK << MTK_PMIC_HOMEKEY_RST_EN_SHIFT)
+
+#define MTK_PMIC_PWRKEY_INDEX	0
+#define MTK_PMIC_HOMEKEY_INDEX	1
+#define MTK_PMIC_MAX_KEY_COUNT	2
+
+struct mtk_pmic_keys_regs {
+	u32 deb_reg;
+	u32 deb_mask;
+	u32 intsel_reg;
+	u32 intsel_mask;
+};
+
+#define MTK_PMIC_KEYS_REGS(_deb_reg, _deb_mask,		\
+	_intsel_reg, _intsel_mask)			\
+{							\
+	.deb_reg		= _deb_reg,		\
+	.deb_mask		= _deb_mask,		\
+	.intsel_reg		= _intsel_reg,		\
+	.intsel_mask		= _intsel_mask,		\
+}
+
+struct mtk_pmic_regs {
+	const struct mtk_pmic_keys_regs keys_regs[MTK_PMIC_MAX_KEY_COUNT];
+	u32 pmic_rst_reg;
+};
+
+static const struct mtk_pmic_regs mt6397_regs = {
+	.keys_regs[MTK_PMIC_PWRKEY_INDEX] =
+		MTK_PMIC_KEYS_REGS(MT6397_CHRSTATUS,
+		0x8, MT6397_INT_RSV, 0x10),
+	.keys_regs[MTK_PMIC_HOMEKEY_INDEX] =
+		MTK_PMIC_KEYS_REGS(MT6397_OCSTATUS2,
+		0x10, MT6397_INT_RSV, 0x8),
+	.pmic_rst_reg = MT6397_TOP_RST_MISC,
+};
+
+static const struct mtk_pmic_regs mt6323_regs = {
+	.keys_regs[MTK_PMIC_PWRKEY_INDEX] =
+		MTK_PMIC_KEYS_REGS(MT6323_CHRSTATUS,
+		0x2, MT6323_INT_MISC_CON, 0x10),
+	.keys_regs[MTK_PMIC_HOMEKEY_INDEX] =
+		MTK_PMIC_KEYS_REGS(MT6323_CHRSTATUS,
+		0x4, MT6323_INT_MISC_CON, 0x8),
+	.pmic_rst_reg = MT6323_TOP_RST_MISC,
+};
+
+struct mtk_pmic_keys_info {
+	struct mtk_pmic_keys *keys;
+	const struct mtk_pmic_keys_regs *regs;
+	unsigned int keycode;
+	int irq;
+	bool wakeup:1;
+};
+
+struct mtk_pmic_keys {
+	struct input_dev *input_dev;
+	struct device *dev;
+	struct regmap *regmap;
+	struct mtk_pmic_keys_info keys[MTK_PMIC_MAX_KEY_COUNT];
+};
+
+enum mtk_pmic_keys_lp_mode {
+	LP_DISABLE,
+	LP_ONEKEY,
+	LP_TWOKEY,
+};
+
+static void mtk_pmic_keys_lp_reset_setup(struct mtk_pmic_keys *keys,
+		u32 pmic_rst_reg)
+{
+	int ret;
+	u32 long_press_mode, long_press_debounce;
+
+	ret = of_property_read_u32(keys->dev->of_node,
+		"power-off-time-sec", &long_press_debounce);
+	if (ret)
+		long_press_debounce = 0;
+
+	regmap_update_bits(keys->regmap, pmic_rst_reg,
+			   MTK_PMIC_RST_DU_MASK << MTK_PMIC_RST_DU_SHIFT,
+			   long_press_debounce << MTK_PMIC_RST_DU_SHIFT);
+
+	ret = of_property_read_u32(keys->dev->of_node,
+		"mediatek,long-press-mode", &long_press_mode);
+	if (ret)
+		long_press_mode = LP_DISABLE;
+
+	switch (long_press_mode) {
+	case LP_ONEKEY:
+		regmap_update_bits(keys->regmap, pmic_rst_reg,
+				   MTK_PMIC_PWRKEY_RST,
+				   MTK_PMIC_PWRKEY_RST);
+		regmap_update_bits(keys->regmap, pmic_rst_reg,
+				   MTK_PMIC_HOMEKEY_RST,
+				   0);
+		break;
+	case LP_TWOKEY:
+		regmap_update_bits(keys->regmap, pmic_rst_reg,
+				   MTK_PMIC_PWRKEY_RST,
+				   MTK_PMIC_PWRKEY_RST);
+		regmap_update_bits(keys->regmap, pmic_rst_reg,
+				   MTK_PMIC_HOMEKEY_RST,
+				   MTK_PMIC_HOMEKEY_RST);
+		break;
+	case LP_DISABLE:
+		regmap_update_bits(keys->regmap, pmic_rst_reg,
+				   MTK_PMIC_PWRKEY_RST,
+				   0);
+		regmap_update_bits(keys->regmap, pmic_rst_reg,
+				   MTK_PMIC_HOMEKEY_RST,
+				   0);
+		break;
+	default:
+		break;
+	}
+}
+
+static irqreturn_t mtk_pmic_keys_irq_handler_thread(int irq, void *data)
+{
+	struct mtk_pmic_keys_info *info = data;
+	u32 key_deb, pressed;
+
+	regmap_read(info->keys->regmap, info->regs->deb_reg, &key_deb);
+
+	key_deb &= info->regs->deb_mask;
+
+	pressed = !key_deb;
+
+	input_report_key(info->keys->input_dev, info->keycode, pressed);
+	input_sync(info->keys->input_dev);
+
+	dev_dbg(info->keys->dev, "(%s) key =%d using PMIC\n",
+		 pressed ? "pressed" : "released", info->keycode);
+
+	return IRQ_HANDLED;
+}
+
+static int mtk_pmic_key_setup(struct mtk_pmic_keys *keys,
+		struct mtk_pmic_keys_info *info)
+{
+	int ret;
+
+	info->keys = keys;
+
+	ret = regmap_update_bits(keys->regmap, info->regs->intsel_reg,
+				 info->regs->intsel_mask,
+				 info->regs->intsel_mask);
+	if (ret < 0)
+		return ret;
+
+	ret = devm_request_threaded_irq(keys->dev, info->irq, NULL,
+					mtk_pmic_keys_irq_handler_thread,
+					IRQF_ONESHOT | IRQF_TRIGGER_HIGH,
+					"mtk-pmic-keys", info);
+	if (ret) {
+		dev_err(keys->dev, "Failed to request IRQ: %d: %d\n",
+			info->irq, ret);
+		return ret;
+	}
+
+	input_set_capability(keys->input_dev, EV_KEY, info->keycode);
+
+	return 0;
+}
+
+static int __maybe_unused mtk_pmic_keys_suspend(struct device *dev)
+{
+	struct mtk_pmic_keys *keys = dev_get_drvdata(dev);
+	int index;
+
+	for (index = 0; index < MTK_PMIC_MAX_KEY_COUNT; index++) {
+		if (keys->keys[index].wakeup)
+			enable_irq_wake(keys->keys[index].irq);
+	}
+
+	return 0;
+}
+
+static int __maybe_unused mtk_pmic_keys_resume(struct device *dev)
+{
+	struct mtk_pmic_keys *keys = dev_get_drvdata(dev);
+	int index;
+
+	for (index = 0; index < MTK_PMIC_MAX_KEY_COUNT; index++) {
+		if (keys->keys[index].wakeup)
+			disable_irq_wake(keys->keys[index].irq);
+	}
+
+	return 0;
+}
+
+static SIMPLE_DEV_PM_OPS(mtk_pmic_keys_pm_ops, mtk_pmic_keys_suspend,
+			mtk_pmic_keys_resume);
+
+static const struct of_device_id of_mtk_pmic_keys_match_tbl[] = {
+	{
+		.compatible = "mediatek,mt6397-keys",
+		.data = &mt6397_regs,
+	}, {
+		.compatible = "mediatek,mt6323-keys",
+		.data = &mt6323_regs,
+	}, {
+		/* sentinel */
+	}
+};
+MODULE_DEVICE_TABLE(of, of_mtk_pmic_keys_match_tbl);
+
+static int mtk_pmic_keys_probe(struct platform_device *pdev)
+{
+	int error, index = 0;
+	unsigned int keycount;
+	struct mt6397_chip *pmic_chip = dev_get_drvdata(pdev->dev.parent);
+	struct device_node *node = pdev->dev.of_node, *child;
+	struct mtk_pmic_keys *keys;
+	const struct mtk_pmic_regs *mtk_pmic_regs;
+	struct input_dev *input_dev;
+	const struct of_device_id *of_id =
+		of_match_device(of_mtk_pmic_keys_match_tbl, &pdev->dev);
+
+	keys = devm_kzalloc(&pdev->dev, sizeof(*keys), GFP_KERNEL);
+	if (!keys)
+		return -ENOMEM;
+
+	keys->dev = &pdev->dev;
+	keys->regmap = pmic_chip->regmap;
+	mtk_pmic_regs = of_id->data;
+
+	keys->input_dev = input_dev = devm_input_allocate_device(keys->dev);
+	if (!input_dev) {
+		dev_err(keys->dev, "input allocate device fail.\n");
+		return -ENOMEM;
+	}
+
+	input_dev->name = "mtk-pmic-keys";
+	input_dev->id.bustype = BUS_HOST;
+	input_dev->id.vendor = 0x0001;
+	input_dev->id.product = 0x0001;
+	input_dev->id.version = 0x0001;
+
+	keycount = of_get_available_child_count(node);
+	if (keycount > MTK_PMIC_MAX_KEY_COUNT) {
+		dev_err(keys->dev, "too many keys defined (%d)\n", keycount);
+		return -EINVAL;
+	}
+
+	for_each_child_of_node(node, child) {
+		keys->keys[index].regs = &mtk_pmic_regs->keys_regs[index];
+
+		keys->keys[index].irq = platform_get_irq(pdev, index);
+		if (keys->keys[index].irq < 0)
+			return keys->keys[index].irq;
+
+		error = of_property_read_u32(child,
+			"linux,keycodes", &keys->keys[index].keycode);
+		if (error) {
+			dev_err(keys->dev,
+				"failed to read key:%d linux,keycode property: %d\n",
+				index, error);
+			return error;
+		}
+
+		if (of_property_read_bool(child, "wakeup-source"))
+			keys->keys[index].wakeup = true;
+
+		error = mtk_pmic_key_setup(keys, &keys->keys[index]);
+		if (error)
+			return error;
+
+		index++;
+	}
+
+	error = input_register_device(input_dev);
+	if (error) {
+		dev_err(&pdev->dev,
+			"register input device failed (%d)\n", error);
+		return error;
+	}
+
+	mtk_pmic_keys_lp_reset_setup(keys, mtk_pmic_regs->pmic_rst_reg);
+
+	platform_set_drvdata(pdev, keys);
+
+	return 0;
+}
+
+static struct platform_driver pmic_keys_pdrv = {
+	.probe = mtk_pmic_keys_probe,
+	.driver = {
+		   .name = "mtk-pmic-keys",
+		   .of_match_table = of_mtk_pmic_keys_match_tbl,
+		   .pm = &mtk_pmic_keys_pm_ops,
+	},
+};
+
+module_platform_driver(pmic_keys_pdrv);
+
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Chen Zhong <chen.zhong@mediatek.com>");
+MODULE_DESCRIPTION("MTK pmic-keys driver v0.1");

+ 0 - 1
drivers/mfd/Makefile

@@ -13,7 +13,6 @@ obj-$(CONFIG_MFD_ASIC3)		+= asic3.o tmio_core.o
 obj-$(CONFIG_MFD_BCM590XX)	+= bcm590xx.o
 obj-$(CONFIG_MFD_BCM590XX)	+= bcm590xx.o
 obj-$(CONFIG_MFD_BD9571MWV)	+= bd9571mwv.o
 obj-$(CONFIG_MFD_BD9571MWV)	+= bd9571mwv.o
 cros_ec_core-objs		:= cros_ec.o
 cros_ec_core-objs		:= cros_ec.o
-cros_ec_core-$(CONFIG_ACPI)	+= cros_ec_acpi_gpe.o
 obj-$(CONFIG_MFD_CROS_EC)	+= cros_ec_core.o
 obj-$(CONFIG_MFD_CROS_EC)	+= cros_ec_core.o
 obj-$(CONFIG_MFD_CROS_EC_I2C)	+= cros_ec_i2c.o
 obj-$(CONFIG_MFD_CROS_EC_I2C)	+= cros_ec_i2c.o
 obj-$(CONFIG_MFD_CROS_EC_SPI)	+= cros_ec_spi.o
 obj-$(CONFIG_MFD_CROS_EC_SPI)	+= cros_ec_spi.o

+ 1 - 2
drivers/mfd/ab8500-debugfs.c

@@ -2519,11 +2519,10 @@ static ssize_t ab8500_subscribe_write(struct file *file,
 	if (!dev_attr[irq_index])
 	if (!dev_attr[irq_index])
 		return -ENOMEM;
 		return -ENOMEM;
 
 
-	event_name[irq_index] = kmalloc(count, GFP_KERNEL);
+	event_name[irq_index] = kasprintf(GFP_KERNEL, "%lu", user_val);
 	if (!event_name[irq_index])
 	if (!event_name[irq_index])
 		return -ENOMEM;
 		return -ENOMEM;
 
 
-	sprintf(event_name[irq_index], "%lu", user_val);
 	dev_attr[irq_index]->show = show_irq;
 	dev_attr[irq_index]->show = show_irq;
 	dev_attr[irq_index]->store = NULL;
 	dev_attr[irq_index]->store = NULL;
 	dev_attr[irq_index]->attr.name = event_name[irq_index];
 	dev_attr[irq_index]->attr.name = event_name[irq_index];

+ 11 - 14
drivers/mfd/abx500-core.c

@@ -37,15 +37,12 @@ int abx500_register_ops(struct device *dev, struct abx500_ops *ops)
 {
 {
 	struct abx500_device_entry *dev_entry;
 	struct abx500_device_entry *dev_entry;
 
 
-	dev_entry = devm_kzalloc(dev,
-				 sizeof(struct abx500_device_entry),
-				 GFP_KERNEL);
-	if (!dev_entry) {
-		dev_err(dev, "register_ops kzalloc failed");
+	dev_entry = devm_kzalloc(dev, sizeof(*dev_entry), GFP_KERNEL);
+	if (!dev_entry)
 		return -ENOMEM;
 		return -ENOMEM;
-	}
+
 	dev_entry->dev = dev;
 	dev_entry->dev = dev;
-	memcpy(&dev_entry->ops, ops, sizeof(struct abx500_ops));
+	memcpy(&dev_entry->ops, ops, sizeof(*ops));
 
 
 	list_add_tail(&dev_entry->list, &abx500_list);
 	list_add_tail(&dev_entry->list, &abx500_list);
 	return 0;
 	return 0;
@@ -68,7 +65,7 @@ int abx500_set_register_interruptible(struct device *dev, u8 bank, u8 reg,
 	struct abx500_ops *ops;
 	struct abx500_ops *ops;
 
 
 	lookup_ops(dev->parent, &ops);
 	lookup_ops(dev->parent, &ops);
-	if ((ops != NULL) && (ops->set_register != NULL))
+	if (ops && ops->set_register)
 		return ops->set_register(dev, bank, reg, value);
 		return ops->set_register(dev, bank, reg, value);
 	else
 	else
 		return -ENOTSUPP;
 		return -ENOTSUPP;
@@ -81,7 +78,7 @@ int abx500_get_register_interruptible(struct device *dev, u8 bank, u8 reg,
 	struct abx500_ops *ops;
 	struct abx500_ops *ops;
 
 
 	lookup_ops(dev->parent, &ops);
 	lookup_ops(dev->parent, &ops);
-	if ((ops != NULL) && (ops->get_register != NULL))
+	if (ops && ops->get_register)
 		return ops->get_register(dev, bank, reg, value);
 		return ops->get_register(dev, bank, reg, value);
 	else
 	else
 		return -ENOTSUPP;
 		return -ENOTSUPP;
@@ -94,7 +91,7 @@ int abx500_get_register_page_interruptible(struct device *dev, u8 bank,
 	struct abx500_ops *ops;
 	struct abx500_ops *ops;
 
 
 	lookup_ops(dev->parent, &ops);
 	lookup_ops(dev->parent, &ops);
-	if ((ops != NULL) && (ops->get_register_page != NULL))
+	if (ops && ops->get_register_page)
 		return ops->get_register_page(dev, bank,
 		return ops->get_register_page(dev, bank,
 			first_reg, regvals, numregs);
 			first_reg, regvals, numregs);
 	else
 	else
@@ -108,7 +105,7 @@ int abx500_mask_and_set_register_interruptible(struct device *dev, u8 bank,
 	struct abx500_ops *ops;
 	struct abx500_ops *ops;
 
 
 	lookup_ops(dev->parent, &ops);
 	lookup_ops(dev->parent, &ops);
-	if ((ops != NULL) && (ops->mask_and_set_register != NULL))
+	if (ops && ops->mask_and_set_register)
 		return ops->mask_and_set_register(dev, bank,
 		return ops->mask_and_set_register(dev, bank,
 			reg, bitmask, bitvalues);
 			reg, bitmask, bitvalues);
 	else
 	else
@@ -121,7 +118,7 @@ int abx500_get_chip_id(struct device *dev)
 	struct abx500_ops *ops;
 	struct abx500_ops *ops;
 
 
 	lookup_ops(dev->parent, &ops);
 	lookup_ops(dev->parent, &ops);
-	if ((ops != NULL) && (ops->get_chip_id != NULL))
+	if (ops && ops->get_chip_id)
 		return ops->get_chip_id(dev);
 		return ops->get_chip_id(dev);
 	else
 	else
 		return -ENOTSUPP;
 		return -ENOTSUPP;
@@ -133,7 +130,7 @@ int abx500_event_registers_startup_state_get(struct device *dev, u8 *event)
 	struct abx500_ops *ops;
 	struct abx500_ops *ops;
 
 
 	lookup_ops(dev->parent, &ops);
 	lookup_ops(dev->parent, &ops);
-	if ((ops != NULL) && (ops->event_registers_startup_state_get != NULL))
+	if (ops && ops->event_registers_startup_state_get)
 		return ops->event_registers_startup_state_get(dev, event);
 		return ops->event_registers_startup_state_get(dev, event);
 	else
 	else
 		return -ENOTSUPP;
 		return -ENOTSUPP;
@@ -145,7 +142,7 @@ int abx500_startup_irq_enabled(struct device *dev, unsigned int irq)
 	struct abx500_ops *ops;
 	struct abx500_ops *ops;
 
 
 	lookup_ops(dev->parent, &ops);
 	lookup_ops(dev->parent, &ops);
-	if ((ops != NULL) && (ops->startup_irq_enabled != NULL))
+	if (ops && ops->startup_irq_enabled)
 		return ops->startup_irq_enabled(dev, irq);
 		return ops->startup_irq_enabled(dev, irq);
 	else
 	else
 		return -ENOTSUPP;
 		return -ENOTSUPP;

+ 35 - 18
drivers/mfd/arizona-core.c

@@ -13,13 +13,12 @@
 #include <linux/clk.h>
 #include <linux/clk.h>
 #include <linux/delay.h>
 #include <linux/delay.h>
 #include <linux/err.h>
 #include <linux/err.h>
-#include <linux/gpio.h>
+#include <linux/gpio/consumer.h>
 #include <linux/interrupt.h>
 #include <linux/interrupt.h>
 #include <linux/mfd/core.h>
 #include <linux/mfd/core.h>
 #include <linux/module.h>
 #include <linux/module.h>
 #include <linux/of.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
 #include <linux/of_device.h>
-#include <linux/of_gpio.h>
 #include <linux/pm_runtime.h>
 #include <linux/pm_runtime.h>
 #include <linux/regmap.h>
 #include <linux/regmap.h>
 #include <linux/regulator/consumer.h>
 #include <linux/regulator/consumer.h>
@@ -279,7 +278,7 @@ static int arizona_wait_for_boot(struct arizona *arizona)
 static inline void arizona_enable_reset(struct arizona *arizona)
 static inline void arizona_enable_reset(struct arizona *arizona)
 {
 {
 	if (arizona->pdata.reset)
 	if (arizona->pdata.reset)
-		gpio_set_value_cansleep(arizona->pdata.reset, 0);
+		gpiod_set_raw_value_cansleep(arizona->pdata.reset, 0);
 }
 }
 
 
 static void arizona_disable_reset(struct arizona *arizona)
 static void arizona_disable_reset(struct arizona *arizona)
@@ -295,7 +294,7 @@ static void arizona_disable_reset(struct arizona *arizona)
 			break;
 			break;
 		}
 		}
 
 
-		gpio_set_value_cansleep(arizona->pdata.reset, 1);
+		gpiod_set_raw_value_cansleep(arizona->pdata.reset, 1);
 		usleep_range(1000, 5000);
 		usleep_range(1000, 5000);
 	}
 	}
 }
 }
@@ -799,14 +798,27 @@ static int arizona_of_get_core_pdata(struct arizona *arizona)
 	struct arizona_pdata *pdata = &arizona->pdata;
 	struct arizona_pdata *pdata = &arizona->pdata;
 	int ret, i;
 	int ret, i;
 
 
-	pdata->reset = of_get_named_gpio(arizona->dev->of_node, "wlf,reset", 0);
-	if (pdata->reset == -EPROBE_DEFER) {
-		return pdata->reset;
-	} else if (pdata->reset < 0) {
-		dev_err(arizona->dev, "Reset GPIO missing/malformed: %d\n",
-			pdata->reset);
+	/* Handle old non-standard DT binding */
+	pdata->reset = devm_gpiod_get_from_of_node(arizona->dev,
+						   arizona->dev->of_node,
+						   "wlf,reset", 0,
+						   GPIOD_OUT_LOW,
+						   "arizona /RESET");
+	if (IS_ERR(pdata->reset)) {
+		ret = PTR_ERR(pdata->reset);
 
 
-		pdata->reset = 0;
+		/*
+		 * Reset missing will be caught when other binding is read
+		 * but all other errors imply this binding is in use but has
+		 * encountered a problem so should be handled.
+		 */
+		if (ret == -EPROBE_DEFER)
+			return ret;
+		else if (ret != -ENOENT && ret != -ENOSYS)
+			dev_err(arizona->dev, "Reset GPIO malformed: %d\n",
+				ret);
+
+		pdata->reset = NULL;
 	}
 	}
 
 
 	ret = of_property_read_u32_array(arizona->dev->of_node,
 	ret = of_property_read_u32_array(arizona->dev->of_node,
@@ -1050,14 +1062,19 @@ int arizona_dev_init(struct arizona *arizona)
 		goto err_early;
 		goto err_early;
 	}
 	}
 
 
-	if (arizona->pdata.reset) {
+	if (!arizona->pdata.reset) {
 		/* Start out with /RESET low to put the chip into reset */
 		/* Start out with /RESET low to put the chip into reset */
-		ret = devm_gpio_request_one(arizona->dev, arizona->pdata.reset,
-					    GPIOF_DIR_OUT | GPIOF_INIT_LOW,
-					    "arizona /RESET");
-		if (ret != 0) {
-			dev_err(dev, "Failed to request /RESET: %d\n", ret);
-			goto err_dcvdd;
+		arizona->pdata.reset = devm_gpiod_get(arizona->dev, "reset",
+						      GPIOD_OUT_LOW);
+		if (IS_ERR(arizona->pdata.reset)) {
+			ret = PTR_ERR(arizona->pdata.reset);
+			if (ret == -EPROBE_DEFER)
+				goto err_dcvdd;
+
+			dev_err(arizona->dev,
+				"Reset GPIO missing/malformed: %d\n", ret);
+
+			arizona->pdata.reset = NULL;
 		}
 		}
 	}
 	}
 
 

+ 3 - 0
drivers/mfd/asic3.c

@@ -31,6 +31,8 @@
 #include <linux/mfd/ds1wm.h>
 #include <linux/mfd/ds1wm.h>
 #include <linux/mfd/tmio.h>
 #include <linux/mfd/tmio.h>
 
 
+#include <linux/mmc/host.h>
+
 enum {
 enum {
 	ASIC3_CLOCK_SPI,
 	ASIC3_CLOCK_SPI,
 	ASIC3_CLOCK_OWM,
 	ASIC3_CLOCK_OWM,
@@ -719,6 +721,7 @@ static void asic3_mmc_clk_div(struct platform_device *pdev, int state)
 
 
 static struct tmio_mmc_data asic3_mmc_data = {
 static struct tmio_mmc_data asic3_mmc_data = {
 	.hclk           = 24576000,
 	.hclk           = 24576000,
+	.ocr_mask	= MMC_VDD_32_33 | MMC_VDD_33_34,
 	.set_pwr        = asic3_mmc_pwr,
 	.set_pwr        = asic3_mmc_pwr,
 	.set_clk_div    = asic3_mmc_clk_div,
 	.set_clk_div    = asic3_mmc_clk_div,
 };
 };

+ 1 - 0
drivers/mfd/atmel-smc.c

@@ -12,6 +12,7 @@
  */
  */
 
 
 #include <linux/mfd/syscon/atmel-smc.h>
 #include <linux/mfd/syscon/atmel-smc.h>
+#include <linux/string.h>
 
 
 /**
 /**
  * atmel_smc_cs_conf_init - initialize a SMC CS conf
  * atmel_smc_cs_conf_init - initialize a SMC CS conf

+ 67 - 185
drivers/mfd/axp20x.c

@@ -169,131 +169,61 @@ static const struct regmap_access_table axp806_volatile_table = {
 	.n_yes_ranges	= ARRAY_SIZE(axp806_volatile_ranges),
 	.n_yes_ranges	= ARRAY_SIZE(axp806_volatile_ranges),
 };
 };
 
 
-static struct resource axp152_pek_resources[] = {
+static const struct resource axp152_pek_resources[] = {
 	DEFINE_RES_IRQ_NAMED(AXP152_IRQ_PEK_RIS_EDGE, "PEK_DBR"),
 	DEFINE_RES_IRQ_NAMED(AXP152_IRQ_PEK_RIS_EDGE, "PEK_DBR"),
 	DEFINE_RES_IRQ_NAMED(AXP152_IRQ_PEK_FAL_EDGE, "PEK_DBF"),
 	DEFINE_RES_IRQ_NAMED(AXP152_IRQ_PEK_FAL_EDGE, "PEK_DBF"),
 };
 };
 
 
-static struct resource axp20x_ac_power_supply_resources[] = {
+static const struct resource axp20x_ac_power_supply_resources[] = {
 	DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_ACIN_PLUGIN, "ACIN_PLUGIN"),
 	DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_ACIN_PLUGIN, "ACIN_PLUGIN"),
 	DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_ACIN_REMOVAL, "ACIN_REMOVAL"),
 	DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_ACIN_REMOVAL, "ACIN_REMOVAL"),
 	DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_ACIN_OVER_V, "ACIN_OVER_V"),
 	DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_ACIN_OVER_V, "ACIN_OVER_V"),
 };
 };
 
 
-static struct resource axp20x_pek_resources[] = {
-	{
-		.name	= "PEK_DBR",
-		.start	= AXP20X_IRQ_PEK_RIS_EDGE,
-		.end	= AXP20X_IRQ_PEK_RIS_EDGE,
-		.flags	= IORESOURCE_IRQ,
-	}, {
-		.name	= "PEK_DBF",
-		.start	= AXP20X_IRQ_PEK_FAL_EDGE,
-		.end	= AXP20X_IRQ_PEK_FAL_EDGE,
-		.flags	= IORESOURCE_IRQ,
-	},
+static const struct resource axp20x_pek_resources[] = {
+	DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_PEK_RIS_EDGE, "PEK_DBR"),
+	DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_PEK_FAL_EDGE, "PEK_DBF"),
 };
 };
 
 
-static struct resource axp20x_usb_power_supply_resources[] = {
+static const struct resource axp20x_usb_power_supply_resources[] = {
 	DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_VBUS_PLUGIN, "VBUS_PLUGIN"),
 	DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_VBUS_PLUGIN, "VBUS_PLUGIN"),
 	DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_VBUS_REMOVAL, "VBUS_REMOVAL"),
 	DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_VBUS_REMOVAL, "VBUS_REMOVAL"),
 	DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_VBUS_VALID, "VBUS_VALID"),
 	DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_VBUS_VALID, "VBUS_VALID"),
 	DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_VBUS_NOT_VALID, "VBUS_NOT_VALID"),
 	DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_VBUS_NOT_VALID, "VBUS_NOT_VALID"),
 };
 };
 
 
-static struct resource axp22x_usb_power_supply_resources[] = {
+static const struct resource axp22x_usb_power_supply_resources[] = {
 	DEFINE_RES_IRQ_NAMED(AXP22X_IRQ_VBUS_PLUGIN, "VBUS_PLUGIN"),
 	DEFINE_RES_IRQ_NAMED(AXP22X_IRQ_VBUS_PLUGIN, "VBUS_PLUGIN"),
 	DEFINE_RES_IRQ_NAMED(AXP22X_IRQ_VBUS_REMOVAL, "VBUS_REMOVAL"),
 	DEFINE_RES_IRQ_NAMED(AXP22X_IRQ_VBUS_REMOVAL, "VBUS_REMOVAL"),
 };
 };
 
 
-static struct resource axp22x_pek_resources[] = {
-	{
-		.name   = "PEK_DBR",
-		.start  = AXP22X_IRQ_PEK_RIS_EDGE,
-		.end    = AXP22X_IRQ_PEK_RIS_EDGE,
-		.flags  = IORESOURCE_IRQ,
-	}, {
-		.name   = "PEK_DBF",
-		.start  = AXP22X_IRQ_PEK_FAL_EDGE,
-		.end    = AXP22X_IRQ_PEK_FAL_EDGE,
-		.flags  = IORESOURCE_IRQ,
-	},
+static const struct resource axp22x_pek_resources[] = {
+	DEFINE_RES_IRQ_NAMED(AXP22X_IRQ_PEK_RIS_EDGE, "PEK_DBR"),
+	DEFINE_RES_IRQ_NAMED(AXP22X_IRQ_PEK_FAL_EDGE, "PEK_DBF"),
 };
 };
 
 
-static struct resource axp288_power_button_resources[] = {
-	{
-		.name	= "PEK_DBR",
-		.start	= AXP288_IRQ_POKP,
-		.end	= AXP288_IRQ_POKP,
-		.flags	= IORESOURCE_IRQ,
-	},
-	{
-		.name	= "PEK_DBF",
-		.start	= AXP288_IRQ_POKN,
-		.end	= AXP288_IRQ_POKN,
-		.flags	= IORESOURCE_IRQ,
-	},
+static const struct resource axp288_power_button_resources[] = {
+	DEFINE_RES_IRQ_NAMED(AXP288_IRQ_POKP, "PEK_DBR"),
+	DEFINE_RES_IRQ_NAMED(AXP288_IRQ_POKN, "PEK_DBF"),
 };
 };
 
 
-static struct resource axp288_fuel_gauge_resources[] = {
-	{
-		.start = AXP288_IRQ_QWBTU,
-		.end   = AXP288_IRQ_QWBTU,
-		.flags = IORESOURCE_IRQ,
-	},
-	{
-		.start = AXP288_IRQ_WBTU,
-		.end   = AXP288_IRQ_WBTU,
-		.flags = IORESOURCE_IRQ,
-	},
-	{
-		.start = AXP288_IRQ_QWBTO,
-		.end   = AXP288_IRQ_QWBTO,
-		.flags = IORESOURCE_IRQ,
-	},
-	{
-		.start = AXP288_IRQ_WBTO,
-		.end   = AXP288_IRQ_WBTO,
-		.flags = IORESOURCE_IRQ,
-	},
-	{
-		.start = AXP288_IRQ_WL2,
-		.end   = AXP288_IRQ_WL2,
-		.flags = IORESOURCE_IRQ,
-	},
-	{
-		.start = AXP288_IRQ_WL1,
-		.end   = AXP288_IRQ_WL1,
-		.flags = IORESOURCE_IRQ,
-	},
+static const struct resource axp288_fuel_gauge_resources[] = {
+	DEFINE_RES_IRQ(AXP288_IRQ_QWBTU),
+	DEFINE_RES_IRQ(AXP288_IRQ_WBTU),
+	DEFINE_RES_IRQ(AXP288_IRQ_QWBTO),
+	DEFINE_RES_IRQ(AXP288_IRQ_WBTO),
+	DEFINE_RES_IRQ(AXP288_IRQ_WL2),
+	DEFINE_RES_IRQ(AXP288_IRQ_WL1),
 };
 };
 
 
-static struct resource axp803_pek_resources[] = {
-	{
-		.name   = "PEK_DBR",
-		.start  = AXP803_IRQ_PEK_RIS_EDGE,
-		.end    = AXP803_IRQ_PEK_RIS_EDGE,
-		.flags  = IORESOURCE_IRQ,
-	}, {
-		.name   = "PEK_DBF",
-		.start  = AXP803_IRQ_PEK_FAL_EDGE,
-		.end    = AXP803_IRQ_PEK_FAL_EDGE,
-		.flags  = IORESOURCE_IRQ,
-	},
+static const struct resource axp803_pek_resources[] = {
+	DEFINE_RES_IRQ_NAMED(AXP803_IRQ_PEK_RIS_EDGE, "PEK_DBR"),
+	DEFINE_RES_IRQ_NAMED(AXP803_IRQ_PEK_FAL_EDGE, "PEK_DBF"),
 };
 };
 
 
-static struct resource axp809_pek_resources[] = {
-	{
-		.name   = "PEK_DBR",
-		.start  = AXP809_IRQ_PEK_RIS_EDGE,
-		.end    = AXP809_IRQ_PEK_RIS_EDGE,
-		.flags  = IORESOURCE_IRQ,
-	}, {
-		.name   = "PEK_DBF",
-		.start  = AXP809_IRQ_PEK_FAL_EDGE,
-		.end    = AXP809_IRQ_PEK_FAL_EDGE,
-		.flags  = IORESOURCE_IRQ,
-	},
+static const struct resource axp809_pek_resources[] = {
+	DEFINE_RES_IRQ_NAMED(AXP809_IRQ_PEK_RIS_EDGE, "PEK_DBR"),
+	DEFINE_RES_IRQ_NAMED(AXP809_IRQ_PEK_FAL_EDGE, "PEK_DBF"),
 };
 };
 
 
 static const struct regmap_config axp152_regmap_config = {
 static const struct regmap_config axp152_regmap_config = {
@@ -520,11 +450,11 @@ static const struct regmap_irq axp806_regmap_irqs[] = {
 	INIT_REGMAP_IRQ(AXP806, DCDCC_V_LOW,		0, 5),
 	INIT_REGMAP_IRQ(AXP806, DCDCC_V_LOW,		0, 5),
 	INIT_REGMAP_IRQ(AXP806, DCDCD_V_LOW,		0, 6),
 	INIT_REGMAP_IRQ(AXP806, DCDCD_V_LOW,		0, 6),
 	INIT_REGMAP_IRQ(AXP806, DCDCE_V_LOW,		0, 7),
 	INIT_REGMAP_IRQ(AXP806, DCDCE_V_LOW,		0, 7),
-	INIT_REGMAP_IRQ(AXP806, PWROK_LONG,		1, 0),
-	INIT_REGMAP_IRQ(AXP806, PWROK_SHORT,		1, 1),
+	INIT_REGMAP_IRQ(AXP806, POK_LONG,		1, 0),
+	INIT_REGMAP_IRQ(AXP806, POK_SHORT,		1, 1),
 	INIT_REGMAP_IRQ(AXP806, WAKEUP,			1, 4),
 	INIT_REGMAP_IRQ(AXP806, WAKEUP,			1, 4),
-	INIT_REGMAP_IRQ(AXP806, PWROK_FALL,		1, 5),
-	INIT_REGMAP_IRQ(AXP806, PWROK_RISE,		1, 6),
+	INIT_REGMAP_IRQ(AXP806, POK_FALL,		1, 5),
+	INIT_REGMAP_IRQ(AXP806, POK_RISE,		1, 6),
 };
 };
 
 
 static const struct regmap_irq axp809_regmap_irqs[] = {
 static const struct regmap_irq axp809_regmap_irqs[] = {
@@ -648,7 +578,7 @@ static const struct regmap_irq_chip axp809_regmap_irq_chip = {
 	.num_regs		= 5,
 	.num_regs		= 5,
 };
 };
 
 
-static struct mfd_cell axp20x_cells[] = {
+static const struct mfd_cell axp20x_cells[] = {
 	{
 	{
 		.name		= "axp20x-gpio",
 		.name		= "axp20x-gpio",
 		.of_compatible	= "x-powers,axp209-gpio",
 		.of_compatible	= "x-powers,axp209-gpio",
@@ -660,6 +590,7 @@ static struct mfd_cell axp20x_cells[] = {
 		.name		= "axp20x-regulator",
 		.name		= "axp20x-regulator",
 	}, {
 	}, {
 		.name		= "axp20x-adc",
 		.name		= "axp20x-adc",
+		.of_compatible	= "x-powers,axp209-adc",
 	}, {
 	}, {
 		.name		= "axp20x-battery-power-supply",
 		.name		= "axp20x-battery-power-supply",
 		.of_compatible	= "x-powers,axp209-battery-power-supply",
 		.of_compatible	= "x-powers,axp209-battery-power-supply",
@@ -676,7 +607,7 @@ static struct mfd_cell axp20x_cells[] = {
 	},
 	},
 };
 };
 
 
-static struct mfd_cell axp221_cells[] = {
+static const struct mfd_cell axp221_cells[] = {
 	{
 	{
 		.name		= "axp221-pek",
 		.name		= "axp221-pek",
 		.num_resources	= ARRAY_SIZE(axp22x_pek_resources),
 		.num_resources	= ARRAY_SIZE(axp22x_pek_resources),
@@ -684,7 +615,8 @@ static struct mfd_cell axp221_cells[] = {
 	}, {
 	}, {
 		.name		= "axp20x-regulator",
 		.name		= "axp20x-regulator",
 	}, {
 	}, {
-		.name		= "axp22x-adc"
+		.name		= "axp22x-adc",
+		.of_compatible	= "x-powers,axp221-adc",
 	}, {
 	}, {
 		.name		= "axp20x-ac-power-supply",
 		.name		= "axp20x-ac-power-supply",
 		.of_compatible	= "x-powers,axp221-ac-power-supply",
 		.of_compatible	= "x-powers,axp221-ac-power-supply",
@@ -701,13 +633,14 @@ static struct mfd_cell axp221_cells[] = {
 	},
 	},
 };
 };
 
 
-static struct mfd_cell axp223_cells[] = {
+static const struct mfd_cell axp223_cells[] = {
 	{
 	{
 		.name			= "axp221-pek",
 		.name			= "axp221-pek",
 		.num_resources		= ARRAY_SIZE(axp22x_pek_resources),
 		.num_resources		= ARRAY_SIZE(axp22x_pek_resources),
 		.resources		= axp22x_pek_resources,
 		.resources		= axp22x_pek_resources,
 	}, {
 	}, {
 		.name		= "axp22x-adc",
 		.name		= "axp22x-adc",
+		.of_compatible	= "x-powers,axp221-adc",
 	}, {
 	}, {
 		.name		= "axp20x-battery-power-supply",
 		.name		= "axp20x-battery-power-supply",
 		.of_compatible	= "x-powers,axp221-battery-power-supply",
 		.of_compatible	= "x-powers,axp221-battery-power-supply",
@@ -726,7 +659,7 @@ static struct mfd_cell axp223_cells[] = {
 	},
 	},
 };
 };
 
 
-static struct mfd_cell axp152_cells[] = {
+static const struct mfd_cell axp152_cells[] = {
 	{
 	{
 		.name			= "axp20x-pek",
 		.name			= "axp20x-pek",
 		.num_resources		= ARRAY_SIZE(axp152_pek_resources),
 		.num_resources		= ARRAY_SIZE(axp152_pek_resources),
@@ -734,87 +667,30 @@ static struct mfd_cell axp152_cells[] = {
 	},
 	},
 };
 };
 
 
-static struct resource axp288_adc_resources[] = {
-	{
-		.name  = "GPADC",
-		.start = AXP288_IRQ_GPADC,
-		.end   = AXP288_IRQ_GPADC,
-		.flags = IORESOURCE_IRQ,
-	},
+static const struct resource axp288_adc_resources[] = {
+	DEFINE_RES_IRQ_NAMED(AXP288_IRQ_GPADC, "GPADC"),
 };
 };
 
 
-static struct resource axp288_extcon_resources[] = {
-	{
-		.start = AXP288_IRQ_VBUS_FALL,
-		.end   = AXP288_IRQ_VBUS_FALL,
-		.flags = IORESOURCE_IRQ,
-	},
-	{
-		.start = AXP288_IRQ_VBUS_RISE,
-		.end   = AXP288_IRQ_VBUS_RISE,
-		.flags = IORESOURCE_IRQ,
-	},
-	{
-		.start = AXP288_IRQ_MV_CHNG,
-		.end   = AXP288_IRQ_MV_CHNG,
-		.flags = IORESOURCE_IRQ,
-	},
-	{
-		.start = AXP288_IRQ_BC_USB_CHNG,
-		.end   = AXP288_IRQ_BC_USB_CHNG,
-		.flags = IORESOURCE_IRQ,
-	},
+static const struct resource axp288_extcon_resources[] = {
+	DEFINE_RES_IRQ(AXP288_IRQ_VBUS_FALL),
+	DEFINE_RES_IRQ(AXP288_IRQ_VBUS_RISE),
+	DEFINE_RES_IRQ(AXP288_IRQ_MV_CHNG),
+	DEFINE_RES_IRQ(AXP288_IRQ_BC_USB_CHNG),
 };
 };
 
 
-static struct resource axp288_charger_resources[] = {
-	{
-		.start = AXP288_IRQ_OV,
-		.end   = AXP288_IRQ_OV,
-		.flags = IORESOURCE_IRQ,
-	},
-	{
-		.start = AXP288_IRQ_DONE,
-		.end   = AXP288_IRQ_DONE,
-		.flags = IORESOURCE_IRQ,
-	},
-	{
-		.start = AXP288_IRQ_CHARGING,
-		.end   = AXP288_IRQ_CHARGING,
-		.flags = IORESOURCE_IRQ,
-	},
-	{
-		.start = AXP288_IRQ_SAFE_QUIT,
-		.end   = AXP288_IRQ_SAFE_QUIT,
-		.flags = IORESOURCE_IRQ,
-	},
-	{
-		.start = AXP288_IRQ_SAFE_ENTER,
-		.end   = AXP288_IRQ_SAFE_ENTER,
-		.flags = IORESOURCE_IRQ,
-	},
-	{
-		.start = AXP288_IRQ_QCBTU,
-		.end   = AXP288_IRQ_QCBTU,
-		.flags = IORESOURCE_IRQ,
-	},
-	{
-		.start = AXP288_IRQ_CBTU,
-		.end   = AXP288_IRQ_CBTU,
-		.flags = IORESOURCE_IRQ,
-	},
-	{
-		.start = AXP288_IRQ_QCBTO,
-		.end   = AXP288_IRQ_QCBTO,
-		.flags = IORESOURCE_IRQ,
-	},
-	{
-		.start = AXP288_IRQ_CBTO,
-		.end   = AXP288_IRQ_CBTO,
-		.flags = IORESOURCE_IRQ,
-	},
+static const struct resource axp288_charger_resources[] = {
+	DEFINE_RES_IRQ(AXP288_IRQ_OV),
+	DEFINE_RES_IRQ(AXP288_IRQ_DONE),
+	DEFINE_RES_IRQ(AXP288_IRQ_CHARGING),
+	DEFINE_RES_IRQ(AXP288_IRQ_SAFE_QUIT),
+	DEFINE_RES_IRQ(AXP288_IRQ_SAFE_ENTER),
+	DEFINE_RES_IRQ(AXP288_IRQ_QCBTU),
+	DEFINE_RES_IRQ(AXP288_IRQ_CBTU),
+	DEFINE_RES_IRQ(AXP288_IRQ_QCBTO),
+	DEFINE_RES_IRQ(AXP288_IRQ_CBTO),
 };
 };
 
 
-static struct mfd_cell axp288_cells[] = {
+static const struct mfd_cell axp288_cells[] = {
 	{
 	{
 		.name = "axp288_adc",
 		.name = "axp288_adc",
 		.num_resources = ARRAY_SIZE(axp288_adc_resources),
 		.num_resources = ARRAY_SIZE(axp288_adc_resources),
@@ -845,7 +721,7 @@ static struct mfd_cell axp288_cells[] = {
 	},
 	},
 };
 };
 
 
-static struct mfd_cell axp803_cells[] = {
+static const struct mfd_cell axp803_cells[] = {
 	{
 	{
 		.name			= "axp221-pek",
 		.name			= "axp221-pek",
 		.num_resources		= ARRAY_SIZE(axp803_pek_resources),
 		.num_resources		= ARRAY_SIZE(axp803_pek_resources),
@@ -854,14 +730,14 @@ static struct mfd_cell axp803_cells[] = {
 	{	.name			= "axp20x-regulator" },
 	{	.name			= "axp20x-regulator" },
 };
 };
 
 
-static struct mfd_cell axp806_cells[] = {
+static const struct mfd_cell axp806_cells[] = {
 	{
 	{
 		.id			= 2,
 		.id			= 2,
 		.name			= "axp20x-regulator",
 		.name			= "axp20x-regulator",
 	},
 	},
 };
 };
 
 
-static struct mfd_cell axp809_cells[] = {
+static const struct mfd_cell axp809_cells[] = {
 	{
 	{
 		.name			= "axp221-pek",
 		.name			= "axp221-pek",
 		.num_resources		= ARRAY_SIZE(axp809_pek_resources),
 		.num_resources		= ARRAY_SIZE(axp809_pek_resources),
@@ -872,7 +748,7 @@ static struct mfd_cell axp809_cells[] = {
 	},
 	},
 };
 };
 
 
-static struct mfd_cell axp813_cells[] = {
+static const struct mfd_cell axp813_cells[] = {
 	{
 	{
 		.name			= "axp221-pek",
 		.name			= "axp221-pek",
 		.num_resources		= ARRAY_SIZE(axp803_pek_resources),
 		.num_resources		= ARRAY_SIZE(axp803_pek_resources),
@@ -882,7 +758,13 @@ static struct mfd_cell axp813_cells[] = {
 	}, {
 	}, {
 		.name			= "axp20x-gpio",
 		.name			= "axp20x-gpio",
 		.of_compatible		= "x-powers,axp813-gpio",
 		.of_compatible		= "x-powers,axp813-gpio",
-	}
+	}, {
+		.name			= "axp813-adc",
+		.of_compatible		= "x-powers,axp813-adc",
+	}, {
+		.name		= "axp20x-battery-power-supply",
+		.of_compatible	= "x-powers,axp813-battery-power-supply",
+	},
 };
 };
 
 
 static struct axp20x_dev *axp20x_pm_power_off;
 static struct axp20x_dev *axp20x_pm_power_off;

+ 14 - 27
drivers/mfd/cros_ec.c

@@ -112,12 +112,16 @@ int cros_ec_register(struct cros_ec_device *ec_dev)
 
 
 	mutex_init(&ec_dev->lock);
 	mutex_init(&ec_dev->lock);
 
 
-	cros_ec_query_all(ec_dev);
+	err = cros_ec_query_all(ec_dev);
+	if (err) {
+		dev_err(dev, "Cannot identify the EC: error %d\n", err);
+		return err;
+	}
 
 
 	if (ec_dev->irq) {
 	if (ec_dev->irq) {
-		err = request_threaded_irq(ec_dev->irq, NULL, ec_irq_thread,
-					   IRQF_TRIGGER_LOW | IRQF_ONESHOT,
-					   "chromeos-ec", ec_dev);
+		err = devm_request_threaded_irq(dev, ec_dev->irq, NULL,
+				ec_irq_thread, IRQF_TRIGGER_LOW | IRQF_ONESHOT,
+				"chromeos-ec", ec_dev);
 		if (err) {
 		if (err) {
 			dev_err(dev, "Failed to request IRQ %d: %d",
 			dev_err(dev, "Failed to request IRQ %d: %d",
 				ec_dev->irq, err);
 				ec_dev->irq, err);
@@ -131,7 +135,7 @@ int cros_ec_register(struct cros_ec_device *ec_dev)
 		dev_err(dev,
 		dev_err(dev,
 			"Failed to register Embedded Controller subdevice %d\n",
 			"Failed to register Embedded Controller subdevice %d\n",
 			err);
 			err);
-		goto fail_mfd;
+		return err;
 	}
 	}
 
 
 	if (ec_dev->max_passthru) {
 	if (ec_dev->max_passthru) {
@@ -149,7 +153,7 @@ int cros_ec_register(struct cros_ec_device *ec_dev)
 			dev_err(dev,
 			dev_err(dev,
 				"Failed to register Power Delivery subdevice %d\n",
 				"Failed to register Power Delivery subdevice %d\n",
 				err);
 				err);
-			goto fail_mfd;
+			return err;
 		}
 		}
 	}
 	}
 
 
@@ -158,7 +162,7 @@ int cros_ec_register(struct cros_ec_device *ec_dev)
 		if (err) {
 		if (err) {
 			mfd_remove_devices(dev);
 			mfd_remove_devices(dev);
 			dev_err(dev, "Failed to register sub-devices\n");
 			dev_err(dev, "Failed to register sub-devices\n");
-			goto fail_mfd;
+			return err;
 		}
 		}
 	}
 	}
 
 
@@ -173,14 +177,7 @@ int cros_ec_register(struct cros_ec_device *ec_dev)
 
 
 	dev_info(dev, "Chrome EC device registered\n");
 	dev_info(dev, "Chrome EC device registered\n");
 
 
-	cros_ec_acpi_install_gpe_handler(dev);
-
 	return 0;
 	return 0;
-
-fail_mfd:
-	if (ec_dev->irq)
-		free_irq(ec_dev->irq, ec_dev);
-	return err;
 }
 }
 EXPORT_SYMBOL(cros_ec_register);
 EXPORT_SYMBOL(cros_ec_register);
 
 
@@ -188,11 +185,6 @@ int cros_ec_remove(struct cros_ec_device *ec_dev)
 {
 {
 	mfd_remove_devices(ec_dev->dev);
 	mfd_remove_devices(ec_dev->dev);
 
 
-	cros_ec_acpi_remove_gpe_handler();
-
-	if (ec_dev->irq)
-		free_irq(ec_dev->irq, ec_dev);
-
 	return 0;
 	return 0;
 }
 }
 EXPORT_SYMBOL(cros_ec_remove);
 EXPORT_SYMBOL(cros_ec_remove);
@@ -204,14 +196,9 @@ int cros_ec_suspend(struct cros_ec_device *ec_dev)
 	int ret;
 	int ret;
 	u8 sleep_event;
 	u8 sleep_event;
 
 
-	if (!IS_ENABLED(CONFIG_ACPI) || pm_suspend_via_firmware()) {
-		sleep_event = HOST_SLEEP_EVENT_S3_SUSPEND;
-	} else {
-		sleep_event = HOST_SLEEP_EVENT_S0IX_SUSPEND;
-
-		/* Clearing the GPE status for any pending event */
-		cros_ec_acpi_clear_gpe();
-	}
+	sleep_event = (!IS_ENABLED(CONFIG_ACPI) || pm_suspend_via_firmware()) ?
+		      HOST_SLEEP_EVENT_S3_SUSPEND :
+		      HOST_SLEEP_EVENT_S0IX_SUSPEND;
 
 
 	ret = cros_ec_sleep_event(ec_dev, sleep_event);
 	ret = cros_ec_sleep_event(ec_dev, sleep_event);
 	if (ret < 0)
 	if (ret < 0)

+ 0 - 103
drivers/mfd/cros_ec_acpi_gpe.c

@@ -1,103 +0,0 @@
-/*
- * ChromeOS EC multi-function device
- *
- * Copyright (C) 2017 Google, Inc
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * 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.
- *
- * The ChromeOS EC multi function device is used to mux all the requests
- * to the EC device for its multiple features: keyboard controller,
- * battery charging and regulator control, firmware update.
- */
-#include <linux/acpi.h>
-
-#define ACPI_LID_DEVICE      "LID0"
-
-static int ec_wake_gpe = -EINVAL;
-
-/*
- * This handler indicates to ACPI core that this GPE should stay enabled for
- * lid to work in suspend to idle path.
- */
-static u32 cros_ec_gpe_handler(acpi_handle gpe_device, u32 gpe_number,
-			       void *data)
-{
-	return ACPI_INTERRUPT_HANDLED | ACPI_REENABLE_GPE;
-}
-
-/*
- * Get ACPI GPE for LID0 device.
- */
-static int cros_ec_get_ec_wake_gpe(struct device *dev)
-{
-	struct acpi_device *cros_acpi_dev;
-	struct acpi_device *adev;
-	acpi_handle handle;
-	acpi_status status;
-	int ret;
-
-	cros_acpi_dev = ACPI_COMPANION(dev);
-
-	if (!cros_acpi_dev || !cros_acpi_dev->parent ||
-	   !cros_acpi_dev->parent->handle)
-		return -EINVAL;
-
-	status = acpi_get_handle(cros_acpi_dev->parent->handle, ACPI_LID_DEVICE,
-				 &handle);
-	if (ACPI_FAILURE(status))
-		return -EINVAL;
-
-	ret = acpi_bus_get_device(handle, &adev);
-	if (ret)
-		return ret;
-
-	return adev->wakeup.gpe_number;
-}
-
-int cros_ec_acpi_install_gpe_handler(struct device *dev)
-{
-	acpi_status status;
-
-	ec_wake_gpe = cros_ec_get_ec_wake_gpe(dev);
-
-	if (ec_wake_gpe < 0)
-		return ec_wake_gpe;
-
-	status = acpi_install_gpe_handler(NULL, ec_wake_gpe,
-					  ACPI_GPE_EDGE_TRIGGERED,
-					  &cros_ec_gpe_handler, NULL);
-	if (ACPI_FAILURE(status))
-		return -ENODEV;
-
-	dev_info(dev, "Initialized, GPE = 0x%x\n", ec_wake_gpe);
-
-	return 0;
-}
-
-void cros_ec_acpi_remove_gpe_handler(void)
-{
-	acpi_status status;
-
-	if (ec_wake_gpe < 0)
-		return;
-
-	status = acpi_remove_gpe_handler(NULL, ec_wake_gpe,
-						 &cros_ec_gpe_handler);
-	if (ACPI_FAILURE(status))
-		pr_err("failed to remove gpe handler\n");
-}
-
-void cros_ec_acpi_clear_gpe(void)
-{
-	if (ec_wake_gpe < 0)
-		return;
-
-	acpi_clear_gpe(NULL, ec_wake_gpe);
-}

+ 33 - 12
drivers/mfd/cros_ec_dev.c

@@ -113,10 +113,10 @@ static int cros_ec_check_features(struct cros_ec_dev *ec, int feature)
 			dev_warn(ec->dev, "cannot get EC features: %d/%d\n",
 			dev_warn(ec->dev, "cannot get EC features: %d/%d\n",
 				 ret, msg->result);
 				 ret, msg->result);
 			memset(ec->features, 0, sizeof(ec->features));
 			memset(ec->features, 0, sizeof(ec->features));
+		} else {
+			memcpy(ec->features, msg->data, sizeof(ec->features));
 		}
 		}
 
 
-		memcpy(ec->features, msg->data, sizeof(ec->features));
-
 		dev_dbg(ec->dev, "EC features %08x %08x\n",
 		dev_dbg(ec->dev, "EC features %08x %08x\n",
 			ec->features[0], ec->features[1]);
 			ec->features[0], ec->features[1]);
 
 
@@ -262,13 +262,6 @@ static const struct file_operations fops = {
 #endif
 #endif
 };
 };
 
 
-static void __remove(struct device *dev)
-{
-	struct cros_ec_dev *ec = container_of(dev, struct cros_ec_dev,
-					      class_dev);
-	kfree(ec);
-}
-
 static void cros_ec_sensors_register(struct cros_ec_dev *ec)
 static void cros_ec_sensors_register(struct cros_ec_dev *ec)
 {
 {
 	/*
 	/*
@@ -383,12 +376,16 @@ error:
 	kfree(msg);
 	kfree(msg);
 }
 }
 
 
+static const struct mfd_cell cros_ec_rtc_cells[] = {
+	{ .name = "cros-ec-rtc" }
+};
+
 static int ec_device_probe(struct platform_device *pdev)
 static int ec_device_probe(struct platform_device *pdev)
 {
 {
 	int retval = -ENOMEM;
 	int retval = -ENOMEM;
 	struct device *dev = &pdev->dev;
 	struct device *dev = &pdev->dev;
 	struct cros_ec_platform *ec_platform = dev_get_platdata(dev);
 	struct cros_ec_platform *ec_platform = dev_get_platdata(dev);
-	struct cros_ec_dev *ec = kzalloc(sizeof(*ec), GFP_KERNEL);
+	struct cros_ec_dev *ec = devm_kzalloc(dev, sizeof(*ec), GFP_KERNEL);
 
 
 	if (!ec)
 	if (!ec)
 		return retval;
 		return retval;
@@ -410,7 +407,6 @@ static int ec_device_probe(struct platform_device *pdev)
 	ec->class_dev.devt = MKDEV(ec_major, pdev->id);
 	ec->class_dev.devt = MKDEV(ec_major, pdev->id);
 	ec->class_dev.class = &cros_class;
 	ec->class_dev.class = &cros_class;
 	ec->class_dev.parent = dev;
 	ec->class_dev.parent = dev;
-	ec->class_dev.release = __remove;
 
 
 	retval = dev_set_name(&ec->class_dev, "%s", ec_platform->ec_name);
 	retval = dev_set_name(&ec->class_dev, "%s", ec_platform->ec_name);
 	if (retval) {
 	if (retval) {
@@ -422,6 +418,18 @@ static int ec_device_probe(struct platform_device *pdev)
 	if (cros_ec_check_features(ec, EC_FEATURE_MOTION_SENSE))
 	if (cros_ec_check_features(ec, EC_FEATURE_MOTION_SENSE))
 		cros_ec_sensors_register(ec);
 		cros_ec_sensors_register(ec);
 
 
+	/* Check whether this EC instance has RTC host command support */
+	if (cros_ec_check_features(ec, EC_FEATURE_RTC)) {
+		retval = mfd_add_devices(ec->dev, PLATFORM_DEVID_AUTO,
+					 cros_ec_rtc_cells,
+					 ARRAY_SIZE(cros_ec_rtc_cells),
+					 NULL, 0, NULL);
+		if (retval)
+			dev_err(ec->dev,
+				"failed to add cros-ec-rtc device: %d\n",
+				retval);
+	}
+
 	/* Take control of the lightbar from the EC. */
 	/* Take control of the lightbar from the EC. */
 	lb_manual_suspend_ctrl(ec, 1);
 	lb_manual_suspend_ctrl(ec, 1);
 
 
@@ -456,9 +464,17 @@ static int ec_device_remove(struct platform_device *pdev)
 	return 0;
 	return 0;
 }
 }
 
 
+static void ec_device_shutdown(struct platform_device *pdev)
+{
+	struct cros_ec_dev *ec = dev_get_drvdata(&pdev->dev);
+
+	/* Be sure to clear up debugfs delayed works */
+	cros_ec_debugfs_remove(ec);
+}
+
 static const struct platform_device_id cros_ec_id[] = {
 static const struct platform_device_id cros_ec_id[] = {
 	{ DRV_NAME, 0 },
 	{ DRV_NAME, 0 },
-	{ /* sentinel */ },
+	{ /* sentinel */ }
 };
 };
 MODULE_DEVICE_TABLE(platform, cros_ec_id);
 MODULE_DEVICE_TABLE(platform, cros_ec_id);
 
 
@@ -466,6 +482,8 @@ static __maybe_unused int ec_device_suspend(struct device *dev)
 {
 {
 	struct cros_ec_dev *ec = dev_get_drvdata(dev);
 	struct cros_ec_dev *ec = dev_get_drvdata(dev);
 
 
+	cros_ec_debugfs_suspend(ec);
+
 	lb_suspend(ec);
 	lb_suspend(ec);
 
 
 	return 0;
 	return 0;
@@ -475,6 +493,8 @@ static __maybe_unused int ec_device_resume(struct device *dev)
 {
 {
 	struct cros_ec_dev *ec = dev_get_drvdata(dev);
 	struct cros_ec_dev *ec = dev_get_drvdata(dev);
 
 
+	cros_ec_debugfs_resume(ec);
+
 	lb_resume(ec);
 	lb_resume(ec);
 
 
 	return 0;
 	return 0;
@@ -494,6 +514,7 @@ static struct platform_driver cros_ec_dev_driver = {
 	},
 	},
 	.probe = ec_device_probe,
 	.probe = ec_device_probe,
 	.remove = ec_device_remove,
 	.remove = ec_device_remove,
+	.shutdown = ec_device_shutdown,
 };
 };
 
 
 static int __init cros_ec_dev_init(void)
 static int __init cros_ec_dev_init(void)

+ 15 - 2
drivers/mfd/cros_ec_i2c.c

@@ -13,6 +13,7 @@
  * GNU General Public License for more details.
  * GNU General Public License for more details.
  */
  */
 
 
+#include <linux/acpi.h>
 #include <linux/delay.h>
 #include <linux/delay.h>
 #include <linux/kernel.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/module.h>
@@ -341,14 +342,17 @@ static int cros_ec_i2c_resume(struct device *dev)
 }
 }
 #endif
 #endif
 
 
-static SIMPLE_DEV_PM_OPS(cros_ec_i2c_pm_ops, cros_ec_i2c_suspend,
-			  cros_ec_i2c_resume);
+static const struct dev_pm_ops cros_ec_i2c_pm_ops = {
+	SET_LATE_SYSTEM_SLEEP_PM_OPS(cros_ec_i2c_suspend, cros_ec_i2c_resume)
+};
 
 
+#ifdef CONFIG_OF
 static const struct of_device_id cros_ec_i2c_of_match[] = {
 static const struct of_device_id cros_ec_i2c_of_match[] = {
 	{ .compatible = "google,cros-ec-i2c", },
 	{ .compatible = "google,cros-ec-i2c", },
 	{ /* sentinel */ },
 	{ /* sentinel */ },
 };
 };
 MODULE_DEVICE_TABLE(of, cros_ec_i2c_of_match);
 MODULE_DEVICE_TABLE(of, cros_ec_i2c_of_match);
+#endif
 
 
 static const struct i2c_device_id cros_ec_i2c_id[] = {
 static const struct i2c_device_id cros_ec_i2c_id[] = {
 	{ "cros-ec-i2c", 0 },
 	{ "cros-ec-i2c", 0 },
@@ -356,9 +360,18 @@ static const struct i2c_device_id cros_ec_i2c_id[] = {
 };
 };
 MODULE_DEVICE_TABLE(i2c, cros_ec_i2c_id);
 MODULE_DEVICE_TABLE(i2c, cros_ec_i2c_id);
 
 
+#ifdef CONFIG_ACPI
+static const struct acpi_device_id cros_ec_i2c_acpi_id[] = {
+	{ "GOOG0008", 0 },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(acpi, cros_ec_i2c_acpi_id);
+#endif
+
 static struct i2c_driver cros_ec_driver = {
 static struct i2c_driver cros_ec_driver = {
 	.driver	= {
 	.driver	= {
 		.name	= "cros-ec-i2c",
 		.name	= "cros-ec-i2c",
+		.acpi_match_table = ACPI_PTR(cros_ec_i2c_acpi_id),
 		.of_match_table = of_match_ptr(cros_ec_i2c_of_match),
 		.of_match_table = of_match_ptr(cros_ec_i2c_of_match),
 		.pm	= &cros_ec_i2c_pm_ops,
 		.pm	= &cros_ec_i2c_pm_ops,
 	},
 	},

+ 114 - 348
drivers/mfd/da9062-core.c

@@ -365,186 +365,69 @@ static int da9062_get_device_type(struct da9062 *chip)
 }
 }
 
 
 static const struct regmap_range da9061_aa_readable_ranges[] = {
 static const struct regmap_range da9061_aa_readable_ranges[] = {
-	{
-		.range_min = DA9062AA_PAGE_CON,
-		.range_max = DA9062AA_STATUS_B,
-	}, {
-		.range_min = DA9062AA_STATUS_D,
-		.range_max = DA9062AA_EVENT_C,
-	}, {
-		.range_min = DA9062AA_IRQ_MASK_A,
-		.range_max = DA9062AA_IRQ_MASK_C,
-	}, {
-		.range_min = DA9062AA_CONTROL_A,
-		.range_max = DA9062AA_GPIO_4,
-	}, {
-		.range_min = DA9062AA_GPIO_WKUP_MODE,
-		.range_max = DA9062AA_GPIO_OUT3_4,
-	}, {
-		.range_min = DA9062AA_BUCK1_CONT,
-		.range_max = DA9062AA_BUCK4_CONT,
-	}, {
-		.range_min = DA9062AA_BUCK3_CONT,
-		.range_max = DA9062AA_BUCK3_CONT,
-	}, {
-		.range_min = DA9062AA_LDO1_CONT,
-		.range_max = DA9062AA_LDO4_CONT,
-	}, {
-		.range_min = DA9062AA_DVC_1,
-		.range_max = DA9062AA_DVC_1,
-	}, {
-		.range_min = DA9062AA_SEQ,
-		.range_max = DA9062AA_ID_4_3,
-	}, {
-		.range_min = DA9062AA_ID_12_11,
-		.range_max = DA9062AA_ID_16_15,
-	}, {
-		.range_min = DA9062AA_ID_22_21,
-		.range_max = DA9062AA_ID_32_31,
-	}, {
-		.range_min = DA9062AA_SEQ_A,
-		.range_max = DA9062AA_WAIT,
-	}, {
-		.range_min = DA9062AA_RESET,
-		.range_max = DA9062AA_BUCK_ILIM_C,
-	}, {
-		.range_min = DA9062AA_BUCK1_CFG,
-		.range_max = DA9062AA_BUCK3_CFG,
-	}, {
-		.range_min = DA9062AA_VBUCK1_A,
-		.range_max = DA9062AA_VBUCK4_A,
-	}, {
-		.range_min = DA9062AA_VBUCK3_A,
-		.range_max = DA9062AA_VBUCK3_A,
-	}, {
-		.range_min = DA9062AA_VLDO1_A,
-		.range_max = DA9062AA_VLDO4_A,
-	}, {
-		.range_min = DA9062AA_VBUCK1_B,
-		.range_max = DA9062AA_VBUCK4_B,
-	}, {
-		.range_min = DA9062AA_VBUCK3_B,
-		.range_max = DA9062AA_VBUCK3_B,
-	}, {
-		.range_min = DA9062AA_VLDO1_B,
-		.range_max = DA9062AA_VLDO4_B,
-	}, {
-		.range_min = DA9062AA_INTERFACE,
-		.range_max = DA9062AA_CONFIG_E,
-	}, {
-		.range_min = DA9062AA_CONFIG_G,
-		.range_max = DA9062AA_CONFIG_K,
-	}, {
-		.range_min = DA9062AA_CONFIG_M,
-		.range_max = DA9062AA_CONFIG_M,
-	}, {
-		.range_min = DA9062AA_GP_ID_0,
-		.range_max = DA9062AA_GP_ID_19,
-	}, {
-		.range_min = DA9062AA_DEVICE_ID,
-		.range_max = DA9062AA_CONFIG_ID,
-	},
+	regmap_reg_range(DA9062AA_PAGE_CON, DA9062AA_STATUS_B),
+	regmap_reg_range(DA9062AA_STATUS_D, DA9062AA_EVENT_C),
+	regmap_reg_range(DA9062AA_IRQ_MASK_A, DA9062AA_IRQ_MASK_C),
+	regmap_reg_range(DA9062AA_CONTROL_A, DA9062AA_GPIO_4),
+	regmap_reg_range(DA9062AA_GPIO_WKUP_MODE, DA9062AA_GPIO_OUT3_4),
+	regmap_reg_range(DA9062AA_BUCK1_CONT, DA9062AA_BUCK4_CONT),
+	regmap_reg_range(DA9062AA_BUCK3_CONT, DA9062AA_BUCK3_CONT),
+	regmap_reg_range(DA9062AA_LDO1_CONT, DA9062AA_LDO4_CONT),
+	regmap_reg_range(DA9062AA_DVC_1, DA9062AA_DVC_1),
+	regmap_reg_range(DA9062AA_SEQ, DA9062AA_ID_4_3),
+	regmap_reg_range(DA9062AA_ID_12_11, DA9062AA_ID_16_15),
+	regmap_reg_range(DA9062AA_ID_22_21, DA9062AA_ID_32_31),
+	regmap_reg_range(DA9062AA_SEQ_A, DA9062AA_WAIT),
+	regmap_reg_range(DA9062AA_RESET, DA9062AA_BUCK_ILIM_C),
+	regmap_reg_range(DA9062AA_BUCK1_CFG, DA9062AA_BUCK3_CFG),
+	regmap_reg_range(DA9062AA_VBUCK1_A, DA9062AA_VBUCK4_A),
+	regmap_reg_range(DA9062AA_VBUCK3_A, DA9062AA_VBUCK3_A),
+	regmap_reg_range(DA9062AA_VLDO1_A, DA9062AA_VLDO4_A),
+	regmap_reg_range(DA9062AA_VBUCK1_B, DA9062AA_VBUCK4_B),
+	regmap_reg_range(DA9062AA_VBUCK3_B, DA9062AA_VBUCK3_B),
+	regmap_reg_range(DA9062AA_VLDO1_B, DA9062AA_VLDO4_B),
+	regmap_reg_range(DA9062AA_INTERFACE, DA9062AA_CONFIG_E),
+	regmap_reg_range(DA9062AA_CONFIG_G, DA9062AA_CONFIG_K),
+	regmap_reg_range(DA9062AA_CONFIG_M, DA9062AA_CONFIG_M),
+	regmap_reg_range(DA9062AA_GP_ID_0, DA9062AA_GP_ID_19),
+	regmap_reg_range(DA9062AA_DEVICE_ID, DA9062AA_CONFIG_ID),
 };
 };
 
 
 static const struct regmap_range da9061_aa_writeable_ranges[] = {
 static const struct regmap_range da9061_aa_writeable_ranges[] = {
-	{
-		.range_min = DA9062AA_PAGE_CON,
-		.range_max = DA9062AA_PAGE_CON,
-	}, {
-		.range_min = DA9062AA_FAULT_LOG,
-		.range_max = DA9062AA_EVENT_C,
-	}, {
-		.range_min = DA9062AA_IRQ_MASK_A,
-		.range_max = DA9062AA_IRQ_MASK_C,
-	}, {
-		.range_min = DA9062AA_CONTROL_A,
-		.range_max = DA9062AA_GPIO_4,
-	}, {
-		.range_min = DA9062AA_GPIO_WKUP_MODE,
-		.range_max = DA9062AA_GPIO_OUT3_4,
-	}, {
-		.range_min = DA9062AA_BUCK1_CONT,
-		.range_max = DA9062AA_BUCK4_CONT,
-	}, {
-		.range_min = DA9062AA_BUCK3_CONT,
-		.range_max = DA9062AA_BUCK3_CONT,
-	}, {
-		.range_min = DA9062AA_LDO1_CONT,
-		.range_max = DA9062AA_LDO4_CONT,
-	}, {
-		.range_min = DA9062AA_DVC_1,
-		.range_max = DA9062AA_DVC_1,
-	}, {
-		.range_min = DA9062AA_SEQ,
-		.range_max = DA9062AA_ID_4_3,
-	}, {
-		.range_min = DA9062AA_ID_12_11,
-		.range_max = DA9062AA_ID_16_15,
-	}, {
-		.range_min = DA9062AA_ID_22_21,
-		.range_max = DA9062AA_ID_32_31,
-	}, {
-		.range_min = DA9062AA_SEQ_A,
-		.range_max = DA9062AA_WAIT,
-	}, {
-		.range_min = DA9062AA_RESET,
-		.range_max = DA9062AA_BUCK_ILIM_C,
-	}, {
-		.range_min = DA9062AA_BUCK1_CFG,
-		.range_max = DA9062AA_BUCK3_CFG,
-	}, {
-		.range_min = DA9062AA_VBUCK1_A,
-		.range_max = DA9062AA_VBUCK4_A,
-	}, {
-		.range_min = DA9062AA_VBUCK3_A,
-		.range_max = DA9062AA_VBUCK3_A,
-	}, {
-		.range_min = DA9062AA_VLDO1_A,
-		.range_max = DA9062AA_VLDO4_A,
-	}, {
-		.range_min = DA9062AA_VBUCK1_B,
-		.range_max = DA9062AA_VBUCK4_B,
-	}, {
-		.range_min = DA9062AA_VBUCK3_B,
-		.range_max = DA9062AA_VBUCK3_B,
-	}, {
-		.range_min = DA9062AA_VLDO1_B,
-		.range_max = DA9062AA_VLDO4_B,
-	}, {
-		.range_min = DA9062AA_GP_ID_0,
-		.range_max = DA9062AA_GP_ID_19,
-	},
+	regmap_reg_range(DA9062AA_PAGE_CON, DA9062AA_PAGE_CON),
+	regmap_reg_range(DA9062AA_FAULT_LOG, DA9062AA_EVENT_C),
+	regmap_reg_range(DA9062AA_IRQ_MASK_A, DA9062AA_IRQ_MASK_C),
+	regmap_reg_range(DA9062AA_CONTROL_A, DA9062AA_GPIO_4),
+	regmap_reg_range(DA9062AA_GPIO_WKUP_MODE, DA9062AA_GPIO_OUT3_4),
+	regmap_reg_range(DA9062AA_BUCK1_CONT, DA9062AA_BUCK4_CONT),
+	regmap_reg_range(DA9062AA_BUCK3_CONT, DA9062AA_BUCK3_CONT),
+	regmap_reg_range(DA9062AA_LDO1_CONT, DA9062AA_LDO4_CONT),
+	regmap_reg_range(DA9062AA_DVC_1, DA9062AA_DVC_1),
+	regmap_reg_range(DA9062AA_SEQ, DA9062AA_ID_4_3),
+	regmap_reg_range(DA9062AA_ID_12_11, DA9062AA_ID_16_15),
+	regmap_reg_range(DA9062AA_ID_22_21, DA9062AA_ID_32_31),
+	regmap_reg_range(DA9062AA_SEQ_A, DA9062AA_WAIT),
+	regmap_reg_range(DA9062AA_RESET, DA9062AA_BUCK_ILIM_C),
+	regmap_reg_range(DA9062AA_BUCK1_CFG, DA9062AA_BUCK3_CFG),
+	regmap_reg_range(DA9062AA_VBUCK1_A, DA9062AA_VBUCK4_A),
+	regmap_reg_range(DA9062AA_VBUCK3_A, DA9062AA_VBUCK3_A),
+	regmap_reg_range(DA9062AA_VLDO1_A, DA9062AA_VLDO4_A),
+	regmap_reg_range(DA9062AA_VBUCK1_B, DA9062AA_VBUCK4_B),
+	regmap_reg_range(DA9062AA_VBUCK3_B, DA9062AA_VBUCK3_B),
+	regmap_reg_range(DA9062AA_VLDO1_B, DA9062AA_VLDO4_B),
+	regmap_reg_range(DA9062AA_GP_ID_0, DA9062AA_GP_ID_19),
 };
 };
 
 
 static const struct regmap_range da9061_aa_volatile_ranges[] = {
 static const struct regmap_range da9061_aa_volatile_ranges[] = {
-	{
-		.range_min = DA9062AA_PAGE_CON,
-		.range_max = DA9062AA_STATUS_B,
-	}, {
-		.range_min = DA9062AA_STATUS_D,
-		.range_max = DA9062AA_EVENT_C,
-	}, {
-		.range_min = DA9062AA_CONTROL_A,
-		.range_max = DA9062AA_CONTROL_B,
-	}, {
-		.range_min = DA9062AA_CONTROL_E,
-		.range_max = DA9062AA_CONTROL_F,
-	}, {
-		.range_min = DA9062AA_BUCK1_CONT,
-		.range_max = DA9062AA_BUCK4_CONT,
-	}, {
-		.range_min = DA9062AA_BUCK3_CONT,
-		.range_max = DA9062AA_BUCK3_CONT,
-	}, {
-		.range_min = DA9062AA_LDO1_CONT,
-		.range_max = DA9062AA_LDO4_CONT,
-	}, {
-		.range_min = DA9062AA_DVC_1,
-		.range_max = DA9062AA_DVC_1,
-	}, {
-		.range_min = DA9062AA_SEQ,
-		.range_max = DA9062AA_SEQ,
-	},
+	regmap_reg_range(DA9062AA_PAGE_CON, DA9062AA_STATUS_B),
+	regmap_reg_range(DA9062AA_STATUS_D, DA9062AA_EVENT_C),
+	regmap_reg_range(DA9062AA_CONTROL_A, DA9062AA_CONTROL_B),
+	regmap_reg_range(DA9062AA_CONTROL_E, DA9062AA_CONTROL_F),
+	regmap_reg_range(DA9062AA_BUCK1_CONT, DA9062AA_BUCK4_CONT),
+	regmap_reg_range(DA9062AA_BUCK3_CONT, DA9062AA_BUCK3_CONT),
+	regmap_reg_range(DA9062AA_LDO1_CONT, DA9062AA_LDO4_CONT),
+	regmap_reg_range(DA9062AA_DVC_1, DA9062AA_DVC_1),
+	regmap_reg_range(DA9062AA_SEQ, DA9062AA_SEQ),
 };
 };
 
 
 static const struct regmap_access_table da9061_aa_readable_table = {
 static const struct regmap_access_table da9061_aa_readable_table = {
@@ -587,186 +470,69 @@ static struct regmap_config da9061_regmap_config = {
 };
 };
 
 
 static const struct regmap_range da9062_aa_readable_ranges[] = {
 static const struct regmap_range da9062_aa_readable_ranges[] = {
-	{
-		.range_min = DA9062AA_PAGE_CON,
-		.range_max = DA9062AA_STATUS_B,
-	}, {
-		.range_min = DA9062AA_STATUS_D,
-		.range_max = DA9062AA_EVENT_C,
-	}, {
-		.range_min = DA9062AA_IRQ_MASK_A,
-		.range_max = DA9062AA_IRQ_MASK_C,
-	}, {
-		.range_min = DA9062AA_CONTROL_A,
-		.range_max = DA9062AA_GPIO_4,
-	}, {
-		.range_min = DA9062AA_GPIO_WKUP_MODE,
-		.range_max = DA9062AA_BUCK4_CONT,
-	}, {
-		.range_min = DA9062AA_BUCK3_CONT,
-		.range_max = DA9062AA_BUCK3_CONT,
-	}, {
-		.range_min = DA9062AA_LDO1_CONT,
-		.range_max = DA9062AA_LDO4_CONT,
-	}, {
-		.range_min = DA9062AA_DVC_1,
-		.range_max = DA9062AA_DVC_1,
-	}, {
-		.range_min = DA9062AA_COUNT_S,
-		.range_max = DA9062AA_SECOND_D,
-	}, {
-		.range_min = DA9062AA_SEQ,
-		.range_max = DA9062AA_ID_4_3,
-	}, {
-		.range_min = DA9062AA_ID_12_11,
-		.range_max = DA9062AA_ID_16_15,
-	}, {
-		.range_min = DA9062AA_ID_22_21,
-		.range_max = DA9062AA_ID_32_31,
-	}, {
-		.range_min = DA9062AA_SEQ_A,
-		.range_max = DA9062AA_BUCK3_CFG,
-	}, {
-		.range_min = DA9062AA_VBUCK2_A,
-		.range_max = DA9062AA_VBUCK4_A,
-	}, {
-		.range_min = DA9062AA_VBUCK3_A,
-		.range_max = DA9062AA_VBUCK3_A,
-	}, {
-		.range_min = DA9062AA_VLDO1_A,
-		.range_max = DA9062AA_VLDO4_A,
-	}, {
-		.range_min = DA9062AA_VBUCK2_B,
-		.range_max = DA9062AA_VBUCK4_B,
-	}, {
-		.range_min = DA9062AA_VBUCK3_B,
-		.range_max = DA9062AA_VBUCK3_B,
-	}, {
-		.range_min = DA9062AA_VLDO1_B,
-		.range_max = DA9062AA_VLDO4_B,
-	}, {
-		.range_min = DA9062AA_BBAT_CONT,
-		.range_max = DA9062AA_BBAT_CONT,
-	}, {
-		.range_min = DA9062AA_INTERFACE,
-		.range_max = DA9062AA_CONFIG_E,
-	}, {
-		.range_min = DA9062AA_CONFIG_G,
-		.range_max = DA9062AA_CONFIG_K,
-	}, {
-		.range_min = DA9062AA_CONFIG_M,
-		.range_max = DA9062AA_CONFIG_M,
-	}, {
-		.range_min = DA9062AA_TRIM_CLDR,
-		.range_max = DA9062AA_GP_ID_19,
-	}, {
-		.range_min = DA9062AA_DEVICE_ID,
-		.range_max = DA9062AA_CONFIG_ID,
-	},
+	regmap_reg_range(DA9062AA_PAGE_CON, DA9062AA_STATUS_B),
+	regmap_reg_range(DA9062AA_STATUS_D, DA9062AA_EVENT_C),
+	regmap_reg_range(DA9062AA_IRQ_MASK_A, DA9062AA_IRQ_MASK_C),
+	regmap_reg_range(DA9062AA_CONTROL_A, DA9062AA_GPIO_4),
+	regmap_reg_range(DA9062AA_GPIO_WKUP_MODE, DA9062AA_BUCK4_CONT),
+	regmap_reg_range(DA9062AA_BUCK3_CONT, DA9062AA_BUCK3_CONT),
+	regmap_reg_range(DA9062AA_LDO1_CONT, DA9062AA_LDO4_CONT),
+	regmap_reg_range(DA9062AA_DVC_1, DA9062AA_DVC_1),
+	regmap_reg_range(DA9062AA_COUNT_S, DA9062AA_SECOND_D),
+	regmap_reg_range(DA9062AA_SEQ, DA9062AA_ID_4_3),
+	regmap_reg_range(DA9062AA_ID_12_11, DA9062AA_ID_16_15),
+	regmap_reg_range(DA9062AA_ID_22_21, DA9062AA_ID_32_31),
+	regmap_reg_range(DA9062AA_SEQ_A, DA9062AA_BUCK3_CFG),
+	regmap_reg_range(DA9062AA_VBUCK2_A, DA9062AA_VBUCK4_A),
+	regmap_reg_range(DA9062AA_VBUCK3_A, DA9062AA_VBUCK3_A),
+	regmap_reg_range(DA9062AA_VLDO1_A, DA9062AA_VLDO4_A),
+	regmap_reg_range(DA9062AA_VBUCK2_B, DA9062AA_VBUCK4_B),
+	regmap_reg_range(DA9062AA_VBUCK3_B, DA9062AA_VBUCK3_B),
+	regmap_reg_range(DA9062AA_VLDO1_B, DA9062AA_VLDO4_B),
+	regmap_reg_range(DA9062AA_BBAT_CONT, DA9062AA_BBAT_CONT),
+	regmap_reg_range(DA9062AA_INTERFACE, DA9062AA_CONFIG_E),
+	regmap_reg_range(DA9062AA_CONFIG_G, DA9062AA_CONFIG_K),
+	regmap_reg_range(DA9062AA_CONFIG_M, DA9062AA_CONFIG_M),
+	regmap_reg_range(DA9062AA_TRIM_CLDR, DA9062AA_GP_ID_19),
+	regmap_reg_range(DA9062AA_DEVICE_ID, DA9062AA_CONFIG_ID),
 };
 };
 
 
 static const struct regmap_range da9062_aa_writeable_ranges[] = {
 static const struct regmap_range da9062_aa_writeable_ranges[] = {
-	{
-		.range_min = DA9062AA_PAGE_CON,
-		.range_max = DA9062AA_PAGE_CON,
-	}, {
-		.range_min = DA9062AA_FAULT_LOG,
-		.range_max = DA9062AA_EVENT_C,
-	}, {
-		.range_min = DA9062AA_IRQ_MASK_A,
-		.range_max = DA9062AA_IRQ_MASK_C,
-	}, {
-		.range_min = DA9062AA_CONTROL_A,
-		.range_max = DA9062AA_GPIO_4,
-	}, {
-		.range_min = DA9062AA_GPIO_WKUP_MODE,
-		.range_max = DA9062AA_BUCK4_CONT,
-	}, {
-		.range_min = DA9062AA_BUCK3_CONT,
-		.range_max = DA9062AA_BUCK3_CONT,
-	}, {
-		.range_min = DA9062AA_LDO1_CONT,
-		.range_max = DA9062AA_LDO4_CONT,
-	}, {
-		.range_min = DA9062AA_DVC_1,
-		.range_max = DA9062AA_DVC_1,
-	}, {
-		.range_min = DA9062AA_COUNT_S,
-		.range_max = DA9062AA_ALARM_Y,
-	}, {
-		.range_min = DA9062AA_SEQ,
-		.range_max = DA9062AA_ID_4_3,
-	}, {
-		.range_min = DA9062AA_ID_12_11,
-		.range_max = DA9062AA_ID_16_15,
-	}, {
-		.range_min = DA9062AA_ID_22_21,
-		.range_max = DA9062AA_ID_32_31,
-	}, {
-		.range_min = DA9062AA_SEQ_A,
-		.range_max = DA9062AA_BUCK3_CFG,
-	}, {
-		.range_min = DA9062AA_VBUCK2_A,
-		.range_max = DA9062AA_VBUCK4_A,
-	}, {
-		.range_min = DA9062AA_VBUCK3_A,
-		.range_max = DA9062AA_VBUCK3_A,
-	}, {
-		.range_min = DA9062AA_VLDO1_A,
-		.range_max = DA9062AA_VLDO4_A,
-	}, {
-		.range_min = DA9062AA_VBUCK2_B,
-		.range_max = DA9062AA_VBUCK4_B,
-	}, {
-		.range_min = DA9062AA_VBUCK3_B,
-		.range_max = DA9062AA_VBUCK3_B,
-	}, {
-		.range_min = DA9062AA_VLDO1_B,
-		.range_max = DA9062AA_VLDO4_B,
-	}, {
-		.range_min = DA9062AA_BBAT_CONT,
-		.range_max = DA9062AA_BBAT_CONT,
-	}, {
-		.range_min = DA9062AA_GP_ID_0,
-		.range_max = DA9062AA_GP_ID_19,
-	},
+	regmap_reg_range(DA9062AA_PAGE_CON, DA9062AA_PAGE_CON),
+	regmap_reg_range(DA9062AA_FAULT_LOG, DA9062AA_EVENT_C),
+	regmap_reg_range(DA9062AA_IRQ_MASK_A, DA9062AA_IRQ_MASK_C),
+	regmap_reg_range(DA9062AA_CONTROL_A, DA9062AA_GPIO_4),
+	regmap_reg_range(DA9062AA_GPIO_WKUP_MODE, DA9062AA_BUCK4_CONT),
+	regmap_reg_range(DA9062AA_BUCK3_CONT, DA9062AA_BUCK3_CONT),
+	regmap_reg_range(DA9062AA_LDO1_CONT, DA9062AA_LDO4_CONT),
+	regmap_reg_range(DA9062AA_DVC_1, DA9062AA_DVC_1),
+	regmap_reg_range(DA9062AA_COUNT_S, DA9062AA_ALARM_Y),
+	regmap_reg_range(DA9062AA_SEQ, DA9062AA_ID_4_3),
+	regmap_reg_range(DA9062AA_ID_12_11, DA9062AA_ID_16_15),
+	regmap_reg_range(DA9062AA_ID_22_21, DA9062AA_ID_32_31),
+	regmap_reg_range(DA9062AA_SEQ_A, DA9062AA_BUCK3_CFG),
+	regmap_reg_range(DA9062AA_VBUCK2_A, DA9062AA_VBUCK4_A),
+	regmap_reg_range(DA9062AA_VBUCK3_A, DA9062AA_VBUCK3_A),
+	regmap_reg_range(DA9062AA_VLDO1_A, DA9062AA_VLDO4_A),
+	regmap_reg_range(DA9062AA_VBUCK2_B, DA9062AA_VBUCK4_B),
+	regmap_reg_range(DA9062AA_VBUCK3_B, DA9062AA_VBUCK3_B),
+	regmap_reg_range(DA9062AA_VLDO1_B, DA9062AA_VLDO4_B),
+	regmap_reg_range(DA9062AA_BBAT_CONT, DA9062AA_BBAT_CONT),
+	regmap_reg_range(DA9062AA_GP_ID_0, DA9062AA_GP_ID_19),
 };
 };
 
 
 static const struct regmap_range da9062_aa_volatile_ranges[] = {
 static const struct regmap_range da9062_aa_volatile_ranges[] = {
-	{
-		.range_min = DA9062AA_PAGE_CON,
-		.range_max = DA9062AA_STATUS_B,
-	}, {
-		.range_min = DA9062AA_STATUS_D,
-		.range_max = DA9062AA_EVENT_C,
-	}, {
-		.range_min = DA9062AA_CONTROL_A,
-		.range_max = DA9062AA_CONTROL_B,
-	}, {
-		.range_min = DA9062AA_CONTROL_E,
-		.range_max = DA9062AA_CONTROL_F,
-	}, {
-		.range_min = DA9062AA_BUCK2_CONT,
-		.range_max = DA9062AA_BUCK4_CONT,
-	}, {
-		.range_min = DA9062AA_BUCK3_CONT,
-		.range_max = DA9062AA_BUCK3_CONT,
-	}, {
-		.range_min = DA9062AA_LDO1_CONT,
-		.range_max = DA9062AA_LDO4_CONT,
-	}, {
-		.range_min = DA9062AA_DVC_1,
-		.range_max = DA9062AA_DVC_1,
-	}, {
-		.range_min = DA9062AA_COUNT_S,
-		.range_max = DA9062AA_SECOND_D,
-	}, {
-		.range_min = DA9062AA_SEQ,
-		.range_max = DA9062AA_SEQ,
-	}, {
-		.range_min = DA9062AA_EN_32K,
-		.range_max = DA9062AA_EN_32K,
-	},
+	regmap_reg_range(DA9062AA_PAGE_CON, DA9062AA_STATUS_B),
+	regmap_reg_range(DA9062AA_STATUS_D, DA9062AA_EVENT_C),
+	regmap_reg_range(DA9062AA_CONTROL_A, DA9062AA_CONTROL_B),
+	regmap_reg_range(DA9062AA_CONTROL_E, DA9062AA_CONTROL_F),
+	regmap_reg_range(DA9062AA_BUCK2_CONT, DA9062AA_BUCK4_CONT),
+	regmap_reg_range(DA9062AA_BUCK3_CONT, DA9062AA_BUCK3_CONT),
+	regmap_reg_range(DA9062AA_LDO1_CONT, DA9062AA_LDO4_CONT),
+	regmap_reg_range(DA9062AA_DVC_1, DA9062AA_DVC_1),
+	regmap_reg_range(DA9062AA_COUNT_S, DA9062AA_SECOND_D),
+	regmap_reg_range(DA9062AA_SEQ, DA9062AA_SEQ),
+	regmap_reg_range(DA9062AA_EN_32K, DA9062AA_EN_32K),
 };
 };
 
 
 static const struct regmap_access_table da9062_aa_readable_table = {
 static const struct regmap_access_table da9062_aa_readable_table = {

+ 1 - 3
drivers/mfd/htc-i2cpld.c

@@ -479,10 +479,8 @@ static int htcpld_setup_chips(struct platform_device *pdev)
 	htcpld->nchips = pdata->num_chip;
 	htcpld->nchips = pdata->num_chip;
 	htcpld->chip = devm_kzalloc(dev, sizeof(struct htcpld_chip) * htcpld->nchips,
 	htcpld->chip = devm_kzalloc(dev, sizeof(struct htcpld_chip) * htcpld->nchips,
 				    GFP_KERNEL);
 				    GFP_KERNEL);
-	if (!htcpld->chip) {
-		dev_warn(dev, "Unable to allocate memory for chips\n");
+	if (!htcpld->chip)
 		return -ENOMEM;
 		return -ENOMEM;
-	}
 
 
 	/* Add the chips as best we can */
 	/* Add the chips as best we can */
 	for (i = 0; i < htcpld->nchips; i++) {
 	for (i = 0; i < htcpld->nchips; i++) {

+ 15 - 10
drivers/mfd/intel-lpss-pci.c

@@ -124,6 +124,11 @@ static const struct intel_lpss_platform_info apl_i2c_info = {
 	.properties = apl_i2c_properties,
 	.properties = apl_i2c_properties,
 };
 };
 
 
+static const struct intel_lpss_platform_info cnl_i2c_info = {
+	.clk_rate = 216000000,
+	.properties = spt_i2c_properties,
+};
+
 static const struct pci_device_id intel_lpss_pci_ids[] = {
 static const struct pci_device_id intel_lpss_pci_ids[] = {
 	/* BXT A-Step */
 	/* BXT A-Step */
 	{ PCI_VDEVICE(INTEL, 0x0aac), (kernel_ulong_t)&bxt_i2c_info },
 	{ PCI_VDEVICE(INTEL, 0x0aac), (kernel_ulong_t)&bxt_i2c_info },
@@ -207,13 +212,13 @@ static const struct pci_device_id intel_lpss_pci_ids[] = {
 	{ PCI_VDEVICE(INTEL, 0x9daa), (kernel_ulong_t)&spt_info },
 	{ PCI_VDEVICE(INTEL, 0x9daa), (kernel_ulong_t)&spt_info },
 	{ PCI_VDEVICE(INTEL, 0x9dab), (kernel_ulong_t)&spt_info },
 	{ PCI_VDEVICE(INTEL, 0x9dab), (kernel_ulong_t)&spt_info },
 	{ PCI_VDEVICE(INTEL, 0x9dfb), (kernel_ulong_t)&spt_info },
 	{ PCI_VDEVICE(INTEL, 0x9dfb), (kernel_ulong_t)&spt_info },
-	{ PCI_VDEVICE(INTEL, 0x9dc5), (kernel_ulong_t)&spt_i2c_info },
-	{ PCI_VDEVICE(INTEL, 0x9dc6), (kernel_ulong_t)&spt_i2c_info },
+	{ PCI_VDEVICE(INTEL, 0x9dc5), (kernel_ulong_t)&cnl_i2c_info },
+	{ PCI_VDEVICE(INTEL, 0x9dc6), (kernel_ulong_t)&cnl_i2c_info },
 	{ PCI_VDEVICE(INTEL, 0x9dc7), (kernel_ulong_t)&spt_uart_info },
 	{ PCI_VDEVICE(INTEL, 0x9dc7), (kernel_ulong_t)&spt_uart_info },
-	{ PCI_VDEVICE(INTEL, 0x9de8), (kernel_ulong_t)&spt_i2c_info },
-	{ PCI_VDEVICE(INTEL, 0x9de9), (kernel_ulong_t)&spt_i2c_info },
-	{ PCI_VDEVICE(INTEL, 0x9dea), (kernel_ulong_t)&spt_i2c_info },
-	{ PCI_VDEVICE(INTEL, 0x9deb), (kernel_ulong_t)&spt_i2c_info },
+	{ PCI_VDEVICE(INTEL, 0x9de8), (kernel_ulong_t)&cnl_i2c_info },
+	{ PCI_VDEVICE(INTEL, 0x9de9), (kernel_ulong_t)&cnl_i2c_info },
+	{ PCI_VDEVICE(INTEL, 0x9dea), (kernel_ulong_t)&cnl_i2c_info },
+	{ PCI_VDEVICE(INTEL, 0x9deb), (kernel_ulong_t)&cnl_i2c_info },
 	/* SPT-H */
 	/* SPT-H */
 	{ PCI_VDEVICE(INTEL, 0xa127), (kernel_ulong_t)&spt_uart_info },
 	{ PCI_VDEVICE(INTEL, 0xa127), (kernel_ulong_t)&spt_uart_info },
 	{ PCI_VDEVICE(INTEL, 0xa128), (kernel_ulong_t)&spt_uart_info },
 	{ PCI_VDEVICE(INTEL, 0xa128), (kernel_ulong_t)&spt_uart_info },
@@ -240,10 +245,10 @@ static const struct pci_device_id intel_lpss_pci_ids[] = {
 	{ PCI_VDEVICE(INTEL, 0xa32b), (kernel_ulong_t)&spt_info },
 	{ PCI_VDEVICE(INTEL, 0xa32b), (kernel_ulong_t)&spt_info },
 	{ PCI_VDEVICE(INTEL, 0xa37b), (kernel_ulong_t)&spt_info },
 	{ PCI_VDEVICE(INTEL, 0xa37b), (kernel_ulong_t)&spt_info },
 	{ PCI_VDEVICE(INTEL, 0xa347), (kernel_ulong_t)&spt_uart_info },
 	{ PCI_VDEVICE(INTEL, 0xa347), (kernel_ulong_t)&spt_uart_info },
-	{ PCI_VDEVICE(INTEL, 0xa368), (kernel_ulong_t)&spt_i2c_info },
-	{ PCI_VDEVICE(INTEL, 0xa369), (kernel_ulong_t)&spt_i2c_info },
-	{ PCI_VDEVICE(INTEL, 0xa36a), (kernel_ulong_t)&spt_i2c_info },
-	{ PCI_VDEVICE(INTEL, 0xa36b), (kernel_ulong_t)&spt_i2c_info },
+	{ PCI_VDEVICE(INTEL, 0xa368), (kernel_ulong_t)&cnl_i2c_info },
+	{ PCI_VDEVICE(INTEL, 0xa369), (kernel_ulong_t)&cnl_i2c_info },
+	{ PCI_VDEVICE(INTEL, 0xa36a), (kernel_ulong_t)&cnl_i2c_info },
+	{ PCI_VDEVICE(INTEL, 0xa36b), (kernel_ulong_t)&cnl_i2c_info },
 	{ }
 	{ }
 };
 };
 MODULE_DEVICE_TABLE(pci, intel_lpss_pci_ids);
 MODULE_DEVICE_TABLE(pci, intel_lpss_pci_ids);

+ 4 - 4
drivers/mfd/intel-lpss.c

@@ -40,8 +40,8 @@
 
 
 /* Offsets from lpss->priv */
 /* Offsets from lpss->priv */
 #define LPSS_PRIV_RESETS		0x04
 #define LPSS_PRIV_RESETS		0x04
-#define LPSS_PRIV_RESETS_FUNC		BIT(2)
-#define LPSS_PRIV_RESETS_IDMA		0x3
+#define LPSS_PRIV_RESETS_IDMA		BIT(2)
+#define LPSS_PRIV_RESETS_FUNC		0x3
 
 
 #define LPSS_PRIV_ACTIVELTR		0x10
 #define LPSS_PRIV_ACTIVELTR		0x10
 #define LPSS_PRIV_IDLELTR		0x14
 #define LPSS_PRIV_IDLELTR		0x14
@@ -275,11 +275,11 @@ static void intel_lpss_init_dev(const struct intel_lpss *lpss)
 
 
 	intel_lpss_deassert_reset(lpss);
 	intel_lpss_deassert_reset(lpss);
 
 
+	intel_lpss_set_remap_addr(lpss);
+
 	if (!intel_lpss_has_idma(lpss))
 	if (!intel_lpss_has_idma(lpss))
 		return;
 		return;
 
 
-	intel_lpss_set_remap_addr(lpss);
-
 	/* Make sure that SPI multiblock DMA transfers are re-enabled */
 	/* Make sure that SPI multiblock DMA transfers are re-enabled */
 	if (lpss->type == LPSS_DEV_SPI)
 	if (lpss->type == LPSS_DEV_SPI)
 		writel(value, lpss->priv + LPSS_PRIV_SSP_REG);
 		writel(value, lpss->priv + LPSS_PRIV_SSP_REG);

+ 1 - 3
drivers/mfd/janz-cmodio.c

@@ -183,10 +183,8 @@ static int cmodio_pci_probe(struct pci_dev *dev,
 	int ret;
 	int ret;
 
 
 	priv = devm_kzalloc(&dev->dev, sizeof(*priv), GFP_KERNEL);
 	priv = devm_kzalloc(&dev->dev, sizeof(*priv), GFP_KERNEL);
-	if (!priv) {
-		dev_err(&dev->dev, "unable to allocate private data\n");
+	if (!priv)
 		return -ENOMEM;
 		return -ENOMEM;
-	}
 
 
 	pci_set_drvdata(dev, priv);
 	pci_set_drvdata(dev, priv);
 	priv->pdev = dev;
 	priv->pdev = dev;

+ 1 - 3
drivers/mfd/jz4740-adc.c

@@ -212,10 +212,8 @@ static int jz4740_adc_probe(struct platform_device *pdev)
 	int irq_base;
 	int irq_base;
 
 
 	adc = devm_kzalloc(&pdev->dev, sizeof(*adc), GFP_KERNEL);
 	adc = devm_kzalloc(&pdev->dev, sizeof(*adc), GFP_KERNEL);
-	if (!adc) {
-		dev_err(&pdev->dev, "Failed to allocate driver structure\n");
+	if (!adc)
 		return -ENOMEM;
 		return -ENOMEM;
-	}
 
 
 	adc->irq = platform_get_irq(pdev, 0);
 	adc->irq = platform_get_irq(pdev, 0);
 	if (adc->irq < 0) {
 	if (adc->irq < 0) {

+ 1 - 3
drivers/mfd/max8997.c

@@ -148,10 +148,8 @@ static struct max8997_platform_data *max8997_i2c_parse_dt_pdata(
 	struct max8997_platform_data *pd;
 	struct max8997_platform_data *pd;
 
 
 	pd = devm_kzalloc(dev, sizeof(*pd), GFP_KERNEL);
 	pd = devm_kzalloc(dev, sizeof(*pd), GFP_KERNEL);
-	if (!pd) {
-		dev_err(dev, "could not allocate memory for pdata\n");
+	if (!pd)
 		return ERR_PTR(-ENOMEM);
 		return ERR_PTR(-ENOMEM);
-	}
 
 
 	pd->ono = irq_of_parse_and_map(dev->of_node, 1);
 	pd->ono = irq_of_parse_and_map(dev->of_node, 1);
 
 

+ 23 - 3
drivers/mfd/mt6397-core.c

@@ -43,6 +43,16 @@ static const struct resource mt6397_rtc_resources[] = {
 	},
 	},
 };
 };
 
 
+static const struct resource mt6323_keys_resources[] = {
+	DEFINE_RES_IRQ(MT6323_IRQ_STATUS_PWRKEY),
+	DEFINE_RES_IRQ(MT6323_IRQ_STATUS_FCHRKEY),
+};
+
+static const struct resource mt6397_keys_resources[] = {
+	DEFINE_RES_IRQ(MT6397_IRQ_PWRKEY),
+	DEFINE_RES_IRQ(MT6397_IRQ_HOMEKEY),
+};
+
 static const struct mfd_cell mt6323_devs[] = {
 static const struct mfd_cell mt6323_devs[] = {
 	{
 	{
 		.name = "mt6323-regulator",
 		.name = "mt6323-regulator",
@@ -50,6 +60,11 @@ static const struct mfd_cell mt6323_devs[] = {
 	}, {
 	}, {
 		.name = "mt6323-led",
 		.name = "mt6323-led",
 		.of_compatible = "mediatek,mt6323-led"
 		.of_compatible = "mediatek,mt6323-led"
+	}, {
+		.name = "mtk-pmic-keys",
+		.num_resources = ARRAY_SIZE(mt6323_keys_resources),
+		.resources = mt6323_keys_resources,
+		.of_compatible = "mediatek,mt6323-keys"
 	},
 	},
 };
 };
 
 
@@ -71,7 +86,12 @@ static const struct mfd_cell mt6397_devs[] = {
 	}, {
 	}, {
 		.name = "mt6397-pinctrl",
 		.name = "mt6397-pinctrl",
 		.of_compatible = "mediatek,mt6397-pinctrl",
 		.of_compatible = "mediatek,mt6397-pinctrl",
-	},
+	}, {
+		.name = "mtk-pmic-keys",
+		.num_resources = ARRAY_SIZE(mt6397_keys_resources),
+		.resources = mt6397_keys_resources,
+		.of_compatible = "mediatek,mt6397-keys"
+	}
 };
 };
 
 
 static void mt6397_irq_lock(struct irq_data *data)
 static void mt6397_irq_lock(struct irq_data *data)
@@ -289,7 +309,7 @@ static int mt6397_probe(struct platform_device *pdev)
 
 
 		ret = devm_mfd_add_devices(&pdev->dev, -1, mt6323_devs,
 		ret = devm_mfd_add_devices(&pdev->dev, -1, mt6323_devs,
 					   ARRAY_SIZE(mt6323_devs), NULL,
 					   ARRAY_SIZE(mt6323_devs), NULL,
-					   0, NULL);
+					   0, pmic->irq_domain);
 		break;
 		break;
 
 
 	case MT6397_CID_CODE:
 	case MT6397_CID_CODE:
@@ -304,7 +324,7 @@ static int mt6397_probe(struct platform_device *pdev)
 
 
 		ret = devm_mfd_add_devices(&pdev->dev, -1, mt6397_devs,
 		ret = devm_mfd_add_devices(&pdev->dev, -1, mt6397_devs,
 					   ARRAY_SIZE(mt6397_devs), NULL,
 					   ARRAY_SIZE(mt6397_devs), NULL,
-					   0, NULL);
+					   0, pmic->irq_domain);
 		break;
 		break;
 
 
 	default:
 	default:

+ 2 - 22
drivers/mfd/omap-usb-host.c

@@ -153,27 +153,6 @@ static const char * const port_modes[] = {
 	[OMAP_OHCI_PORT_MODE_TLL_2PIN_DPDM]	= "ohci-tll-2pin-dpdm",
 	[OMAP_OHCI_PORT_MODE_TLL_2PIN_DPDM]	= "ohci-tll-2pin-dpdm",
 };
 };
 
 
-/**
- * omap_usbhs_get_dt_port_mode - Get the 'enum usbhs_omap_port_mode'
- * from the port mode string.
- * @mode: The port mode string, usually obtained from device tree.
- *
- * The function returns the 'enum usbhs_omap_port_mode' that matches the
- * provided port mode string as per the port_modes table.
- * If no match is found it returns -ENODEV
- */
-static int omap_usbhs_get_dt_port_mode(const char *mode)
-{
-	int i;
-
-	for (i = 0; i < ARRAY_SIZE(port_modes); i++) {
-		if (!strcmp(mode, port_modes[i]))
-			return i;
-	}
-
-	return -ENODEV;
-}
-
 static struct platform_device *omap_usbhs_alloc_child(const char *name,
 static struct platform_device *omap_usbhs_alloc_child(const char *name,
 			struct resource	*res, int num_resources, void *pdata,
 			struct resource	*res, int num_resources, void *pdata,
 			size_t pdata_size, struct device *dev)
 			size_t pdata_size, struct device *dev)
@@ -529,7 +508,8 @@ static int usbhs_omap_get_dt_pdata(struct device *dev,
 		if (ret < 0)
 		if (ret < 0)
 			continue;
 			continue;
 
 
-		ret = omap_usbhs_get_dt_port_mode(mode);
+		/* get 'enum usbhs_omap_port_mode' from port mode string */
+		ret = match_string(port_modes, ARRAY_SIZE(port_modes), mode);
 		if (ret < 0) {
 		if (ret < 0) {
 			dev_warn(dev, "Invalid port%d-mode \"%s\" in device tree\n",
 			dev_warn(dev, "Invalid port%d-mode \"%s\" in device tree\n",
 					i, mode);
 					i, mode);

+ 25 - 35
drivers/mfd/omap-usb-tll.c

@@ -108,9 +108,9 @@
 					 (x) != OMAP_EHCI_PORT_MODE_PHY)
 					 (x) != OMAP_EHCI_PORT_MODE_PHY)
 
 
 struct usbtll_omap {
 struct usbtll_omap {
-	int					nch;	/* num. of channels */
-	struct clk				**ch_clk;
-	void __iomem				*base;
+	void __iomem	*base;
+	int		nch;		/* num. of channels */
+	struct clk	*ch_clk[0];	/* must be the last member */
 };
 };
 
 
 /*-------------------------------------------------------------------------*/
 /*-------------------------------------------------------------------------*/
@@ -216,53 +216,49 @@ static int usbtll_omap_probe(struct platform_device *pdev)
 	struct device				*dev =  &pdev->dev;
 	struct device				*dev =  &pdev->dev;
 	struct resource				*res;
 	struct resource				*res;
 	struct usbtll_omap			*tll;
 	struct usbtll_omap			*tll;
-	int					ret = 0;
-	int					i, ver;
+	void __iomem				*base;
+	int					i, nch, ver;
 
 
 	dev_dbg(dev, "starting TI HSUSB TLL Controller\n");
 	dev_dbg(dev, "starting TI HSUSB TLL Controller\n");
 
 
-	tll = devm_kzalloc(dev, sizeof(struct usbtll_omap), GFP_KERNEL);
-	if (!tll) {
-		dev_err(dev, "Memory allocation failed\n");
-		return -ENOMEM;
-	}
-
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	tll->base = devm_ioremap_resource(dev, res);
-	if (IS_ERR(tll->base))
-		return PTR_ERR(tll->base);
+	base = devm_ioremap_resource(dev, res);
+	if (IS_ERR(base))
+		return PTR_ERR(base);
 
 
-	platform_set_drvdata(pdev, tll);
 	pm_runtime_enable(dev);
 	pm_runtime_enable(dev);
 	pm_runtime_get_sync(dev);
 	pm_runtime_get_sync(dev);
 
 
-	ver =  usbtll_read(tll->base, OMAP_USBTLL_REVISION);
+	ver = usbtll_read(base, OMAP_USBTLL_REVISION);
 	switch (ver) {
 	switch (ver) {
 	case OMAP_USBTLL_REV1:
 	case OMAP_USBTLL_REV1:
 	case OMAP_USBTLL_REV4:
 	case OMAP_USBTLL_REV4:
-		tll->nch = OMAP_TLL_CHANNEL_COUNT;
+		nch = OMAP_TLL_CHANNEL_COUNT;
 		break;
 		break;
 	case OMAP_USBTLL_REV2:
 	case OMAP_USBTLL_REV2:
 	case OMAP_USBTLL_REV3:
 	case OMAP_USBTLL_REV3:
-		tll->nch = OMAP_REV2_TLL_CHANNEL_COUNT;
+		nch = OMAP_REV2_TLL_CHANNEL_COUNT;
 		break;
 		break;
 	default:
 	default:
-		tll->nch = OMAP_TLL_CHANNEL_COUNT;
-		dev_dbg(dev,
-		 "USB TLL Rev : 0x%x not recognized, assuming %d channels\n",
-			ver, tll->nch);
+		nch = OMAP_TLL_CHANNEL_COUNT;
+		dev_dbg(dev, "rev 0x%x not recognized, assuming %d channels\n",
+			ver, nch);
 		break;
 		break;
 	}
 	}
 
 
-	tll->ch_clk = devm_kzalloc(dev, sizeof(struct clk *) * tll->nch,
-						GFP_KERNEL);
-	if (!tll->ch_clk) {
-		ret = -ENOMEM;
-		dev_err(dev, "Couldn't allocate memory for channel clocks\n");
-		goto err_clk_alloc;
+	tll = devm_kzalloc(dev, sizeof(*tll) + sizeof(tll->ch_clk[nch]),
+			   GFP_KERNEL);
+	if (!tll) {
+		pm_runtime_put_sync(dev);
+		pm_runtime_disable(dev);
+		return -ENOMEM;
 	}
 	}
 
 
-	for (i = 0; i < tll->nch; i++) {
+	tll->base = base;
+	tll->nch = nch;
+	platform_set_drvdata(pdev, tll);
+
+	for (i = 0; i < nch; i++) {
 		char clkname[] = "usb_tll_hs_usb_chx_clk";
 		char clkname[] = "usb_tll_hs_usb_chx_clk";
 
 
 		snprintf(clkname, sizeof(clkname),
 		snprintf(clkname, sizeof(clkname),
@@ -282,12 +278,6 @@ static int usbtll_omap_probe(struct platform_device *pdev)
 	spin_unlock(&tll_lock);
 	spin_unlock(&tll_lock);
 
 
 	return 0;
 	return 0;
-
-err_clk_alloc:
-	pm_runtime_put_sync(dev);
-	pm_runtime_disable(dev);
-
-	return ret;
 }
 }
 
 
 /**
 /**

+ 5 - 2
drivers/mfd/pcf50633-core.c

@@ -242,8 +242,10 @@ static int pcf50633_probe(struct i2c_client *client,
 
 
 	for (i = 0; i < PCF50633_NUM_REGULATORS; i++) {
 	for (i = 0; i < PCF50633_NUM_REGULATORS; i++) {
 		pdev = platform_device_alloc("pcf50633-regulator", i);
 		pdev = platform_device_alloc("pcf50633-regulator", i);
-		if (!pdev)
-			return -ENOMEM;
+		if (!pdev) {
+			ret = -ENOMEM;
+			goto err2;
+		}
 
 
 		pdev->dev.parent = pcf->dev;
 		pdev->dev.parent = pcf->dev;
 		ret = platform_device_add_data(pdev, &pdata->reg_init_data[i],
 		ret = platform_device_add_data(pdev, &pdata->reg_init_data[i],
@@ -269,6 +271,7 @@ static int pcf50633_probe(struct i2c_client *client,
 
 
 err:
 err:
 	platform_device_put(pdev);
 	platform_device_put(pdev);
+err2:
 	for (j = 0; j < i; j++)
 	for (j = 0; j < i; j++)
 		platform_device_put(pcf->regulator_pdev[j]);
 		platform_device_put(pcf->regulator_pdev[j]);
 
 

+ 6 - 0
drivers/mfd/qcom-spmi-pmic.c

@@ -39,6 +39,9 @@
 #define PM8916_SUBTYPE		0x0b
 #define PM8916_SUBTYPE		0x0b
 #define PM8004_SUBTYPE		0x0c
 #define PM8004_SUBTYPE		0x0c
 #define PM8909_SUBTYPE		0x0d
 #define PM8909_SUBTYPE		0x0d
+#define PM8998_SUBTYPE		0x14
+#define PMI8998_SUBTYPE		0x15
+#define PM8005_SUBTYPE		0x18
 
 
 static const struct of_device_id pmic_spmi_id_table[] = {
 static const struct of_device_id pmic_spmi_id_table[] = {
 	{ .compatible = "qcom,spmi-pmic", .data = (void *)COMMON_SUBTYPE },
 	{ .compatible = "qcom,spmi-pmic", .data = (void *)COMMON_SUBTYPE },
@@ -55,6 +58,9 @@ static const struct of_device_id pmic_spmi_id_table[] = {
 	{ .compatible = "qcom,pm8916",    .data = (void *)PM8916_SUBTYPE },
 	{ .compatible = "qcom,pm8916",    .data = (void *)PM8916_SUBTYPE },
 	{ .compatible = "qcom,pm8004",    .data = (void *)PM8004_SUBTYPE },
 	{ .compatible = "qcom,pm8004",    .data = (void *)PM8004_SUBTYPE },
 	{ .compatible = "qcom,pm8909",    .data = (void *)PM8909_SUBTYPE },
 	{ .compatible = "qcom,pm8909",    .data = (void *)PM8909_SUBTYPE },
+	{ .compatible = "qcom,pm8998",    .data = (void *)PM8998_SUBTYPE },
+	{ .compatible = "qcom,pmi8998",   .data = (void *)PMI8998_SUBTYPE },
+	{ .compatible = "qcom,pm8005",    .data = (void *)PM8005_SUBTYPE },
 	{ }
 	{ }
 };
 };
 
 

+ 110 - 8
drivers/mfd/rave-sp.c

@@ -45,7 +45,9 @@
 #define RAVE_SP_DLE			0x10
 #define RAVE_SP_DLE			0x10
 
 
 #define RAVE_SP_MAX_DATA_SIZE		64
 #define RAVE_SP_MAX_DATA_SIZE		64
-#define RAVE_SP_CHECKSUM_SIZE		2  /* Worst case scenario on RDU2 */
+#define RAVE_SP_CHECKSUM_8B2C		1
+#define RAVE_SP_CHECKSUM_CCITT		2
+#define RAVE_SP_CHECKSUM_SIZE		RAVE_SP_CHECKSUM_CCITT
 /*
 /*
  * We don't store STX, ETX and unescaped bytes, so Rx is only
  * We don't store STX, ETX and unescaped bytes, so Rx is only
  * DATA + CSUM
  * DATA + CSUM
@@ -160,6 +162,8 @@ struct rave_sp_variant {
  * @variant:			Device variant specific information
  * @variant:			Device variant specific information
  * @event_notifier_list:	Input event notification chain
  * @event_notifier_list:	Input event notification chain
  *
  *
+ * @part_number_firmware:	Firmware version
+ * @part_number_bootloader:	Bootloader version
  */
  */
 struct rave_sp {
 struct rave_sp {
 	struct serdev_device *serdev;
 	struct serdev_device *serdev;
@@ -171,8 +175,40 @@ struct rave_sp {
 
 
 	const struct rave_sp_variant *variant;
 	const struct rave_sp_variant *variant;
 	struct blocking_notifier_head event_notifier_list;
 	struct blocking_notifier_head event_notifier_list;
+
+	const char *part_number_firmware;
+	const char *part_number_bootloader;
 };
 };
 
 
+struct rave_sp_version {
+	u8     hardware;
+	__le16 major;
+	u8     minor;
+	u8     letter[2];
+} __packed;
+
+struct rave_sp_status {
+	struct rave_sp_version bootloader_version;
+	struct rave_sp_version firmware_version;
+	u16 rdu_eeprom_flag;
+	u16 dds_eeprom_flag;
+	u8  pic_flag;
+	u8  orientation;
+	u32 etc;
+	s16 temp[2];
+	u8  backlight_current[3];
+	u8  dip_switch;
+	u8  host_interrupt;
+	u16 voltage_28;
+	u8  i2c_device_status;
+	u8  power_status;
+	u8  general_status;
+	u8  deprecated1;
+	u8  power_led_status;
+	u8  deprecated2;
+	u8  periph_power_shutoff;
+} __packed;
+
 static bool rave_sp_id_is_event(u8 code)
 static bool rave_sp_id_is_event(u8 code)
 {
 {
 	return (code & 0xF0) == RAVE_SP_EVNT_BASE;
 	return (code & 0xF0) == RAVE_SP_EVNT_BASE;
@@ -275,8 +311,8 @@ static int rave_sp_write(struct rave_sp *sp, const u8 *data, u8 data_size)
 
 
 	length = dest - frame;
 	length = dest - frame;
 
 
-	print_hex_dump(KERN_DEBUG, "rave-sp tx: ", DUMP_PREFIX_NONE,
-		       16, 1, frame, length, false);
+	print_hex_dump_debug("rave-sp tx: ", DUMP_PREFIX_NONE,
+			     16, 1, frame, length, false);
 
 
 	return serdev_device_write(sp->serdev, frame, length, HZ);
 	return serdev_device_write(sp->serdev, frame, length, HZ);
 }
 }
@@ -415,10 +451,15 @@ static void rave_sp_receive_frame(struct rave_sp *sp,
 	const size_t payload_length  = length - checksum_length;
 	const size_t payload_length  = length - checksum_length;
 	const u8 *crc_reported       = &data[payload_length];
 	const u8 *crc_reported       = &data[payload_length];
 	struct device *dev           = &sp->serdev->dev;
 	struct device *dev           = &sp->serdev->dev;
-	u8 crc_calculated[checksum_length];
+	u8 crc_calculated[RAVE_SP_CHECKSUM_SIZE];
+
+	if (unlikely(checksum_length > sizeof(crc_calculated))) {
+		dev_warn(dev, "Checksum too long, dropping\n");
+		return;
+	}
 
 
-	print_hex_dump(KERN_DEBUG, "rave-sp rx: ", DUMP_PREFIX_NONE,
-		       16, 1, data, length, false);
+	print_hex_dump_debug("rave-sp rx: ", DUMP_PREFIX_NONE,
+			     16, 1, data, length, false);
 
 
 	if (unlikely(length <= checksum_length)) {
 	if (unlikely(length <= checksum_length)) {
 		dev_warn(dev, "Dropping short frame\n");
 		dev_warn(dev, "Dropping short frame\n");
@@ -512,8 +553,6 @@ static int rave_sp_receive_buf(struct serdev_device *serdev,
 			/* FALLTHROUGH */
 			/* FALLTHROUGH */
 
 
 		case RAVE_SP_EXPECT_ESCAPED_DATA:
 		case RAVE_SP_EXPECT_ESCAPED_DATA:
-			deframer->data[deframer->length++] = byte;
-
 			if (deframer->length == sizeof(deframer->data)) {
 			if (deframer->length == sizeof(deframer->data)) {
 				dev_warn(dev, "Bad frame: Too long\n");
 				dev_warn(dev, "Bad frame: Too long\n");
 				/*
 				/*
@@ -528,6 +567,8 @@ static int rave_sp_receive_buf(struct serdev_device *serdev,
 				goto reset_framer;
 				goto reset_framer;
 			}
 			}
 
 
+			deframer->data[deframer->length++] = byte;
+
 			/*
 			/*
 			 * We've extracted out special byte, now we
 			 * We've extracted out special byte, now we
 			 * can go back to regular data collecting
 			 * can go back to regular data collecting
@@ -609,6 +650,52 @@ static int rave_sp_default_cmd_translate(enum rave_sp_command command)
 	}
 	}
 }
 }
 
 
+static const char *devm_rave_sp_version(struct device *dev,
+					struct rave_sp_version *version)
+{
+	/*
+	 * NOTE: The format string below uses %02d to display u16
+	 * intentionally for the sake of backwards compatibility with
+	 * legacy software.
+	 */
+	return devm_kasprintf(dev, GFP_KERNEL, "%02d%02d%02d.%c%c\n",
+			      version->hardware,
+			      le16_to_cpu(version->major),
+			      version->minor,
+			      version->letter[0],
+			      version->letter[1]);
+}
+
+static int rave_sp_get_status(struct rave_sp *sp)
+{
+	struct device *dev = &sp->serdev->dev;
+	u8 cmd[] = {
+		[0] = RAVE_SP_CMD_STATUS,
+		[1] = 0
+	};
+	struct rave_sp_status status;
+	const char *version;
+	int ret;
+
+	ret = rave_sp_exec(sp, cmd, sizeof(cmd), &status, sizeof(status));
+	if (ret)
+		return ret;
+
+	version = devm_rave_sp_version(dev, &status.firmware_version);
+	if (!version)
+		return -ENOMEM;
+
+	sp->part_number_firmware = version;
+
+	version = devm_rave_sp_version(dev, &status.bootloader_version);
+	if (!version)
+		return -ENOMEM;
+
+	sp->part_number_bootloader = version;
+
+	return 0;
+}
+
 static const struct rave_sp_checksum rave_sp_checksum_8b2c = {
 static const struct rave_sp_checksum rave_sp_checksum_8b2c = {
 	.length     = 1,
 	.length     = 1,
 	.subroutine = csum_8b2c,
 	.subroutine = csum_8b2c,
@@ -657,6 +744,7 @@ static const struct serdev_device_ops rave_sp_serdev_device_ops = {
 static int rave_sp_probe(struct serdev_device *serdev)
 static int rave_sp_probe(struct serdev_device *serdev)
 {
 {
 	struct device *dev = &serdev->dev;
 	struct device *dev = &serdev->dev;
+	const char *unknown = "unknown\n";
 	struct rave_sp *sp;
 	struct rave_sp *sp;
 	u32 baud;
 	u32 baud;
 	int ret;
 	int ret;
@@ -689,6 +777,20 @@ static int rave_sp_probe(struct serdev_device *serdev)
 
 
 	serdev_device_set_baudrate(serdev, baud);
 	serdev_device_set_baudrate(serdev, baud);
 
 
+	ret = rave_sp_get_status(sp);
+	if (ret) {
+		dev_warn(dev, "Failed to get firmware status: %d\n", ret);
+		sp->part_number_firmware   = unknown;
+		sp->part_number_bootloader = unknown;
+	}
+
+	/*
+	 * Those strings already have a \n embedded, so there's no
+	 * need to have one in format string.
+	 */
+	dev_info(dev, "Firmware version: %s",   sp->part_number_firmware);
+	dev_info(dev, "Bootloader version: %s", sp->part_number_bootloader);
+
 	return devm_of_platform_populate(dev);
 	return devm_of_platform_populate(dev);
 }
 }
 
 

+ 2 - 4
drivers/mfd/rc5t583.c

@@ -258,11 +258,9 @@ static int rc5t583_i2c_probe(struct i2c_client *i2c,
 		return -EINVAL;
 		return -EINVAL;
 	}
 	}
 
 
-	rc5t583 = devm_kzalloc(&i2c->dev, sizeof(struct rc5t583), GFP_KERNEL);
-	if (!rc5t583) {
-		dev_err(&i2c->dev, "Memory allocation failed\n");
+	rc5t583 = devm_kzalloc(&i2c->dev, sizeof(*rc5t583), GFP_KERNEL);
+	if (!rc5t583)
 		return -ENOMEM;
 		return -ENOMEM;
-	}
 
 
 	rc5t583->dev = &i2c->dev;
 	rc5t583->dev = &i2c->dev;
 	i2c_set_clientdata(i2c, rc5t583);
 	i2c_set_clientdata(i2c, rc5t583);

+ 2 - 4
drivers/mfd/si476x-i2c.c

@@ -697,11 +697,9 @@ static int si476x_core_probe(struct i2c_client *client,
 	int              cell_num;
 	int              cell_num;
 
 
 	core = devm_kzalloc(&client->dev, sizeof(*core), GFP_KERNEL);
 	core = devm_kzalloc(&client->dev, sizeof(*core), GFP_KERNEL);
-	if (!core) {
-		dev_err(&client->dev,
-			"failed to allocate 'struct si476x_core'\n");
+	if (!core)
 		return -ENOMEM;
 		return -ENOMEM;
-	}
+
 	core->client = client;
 	core->client = client;
 
 
 	core->regmap = devm_regmap_init_si476x(core);
 	core->regmap = devm_regmap_init_si476x(core);

+ 13 - 19
drivers/mfd/sm501.c

@@ -1050,13 +1050,13 @@ static int sm501_register_gpio(struct sm501_devdata *sm)
 	spin_lock_init(&gpio->lock);
 	spin_lock_init(&gpio->lock);
 
 
 	gpio->regs_res = request_mem_region(iobase, 0x20, "sm501-gpio");
 	gpio->regs_res = request_mem_region(iobase, 0x20, "sm501-gpio");
-	if (gpio->regs_res == NULL) {
+	if (!gpio->regs_res) {
 		dev_err(sm->dev, "gpio: failed to request region\n");
 		dev_err(sm->dev, "gpio: failed to request region\n");
 		return -ENXIO;
 		return -ENXIO;
 	}
 	}
 
 
 	gpio->regs = ioremap(iobase, 0x20);
 	gpio->regs = ioremap(iobase, 0x20);
-	if (gpio->regs == NULL) {
+	if (!gpio->regs) {
 		dev_err(sm->dev, "gpio: failed to remap registers\n");
 		dev_err(sm->dev, "gpio: failed to remap registers\n");
 		ret = -ENXIO;
 		ret = -ENXIO;
 		goto err_claimed;
 		goto err_claimed;
@@ -1358,7 +1358,7 @@ static int sm501_init_dev(struct sm501_devdata *sm)
 			sm501_register_gpio(sm);
 			sm501_register_gpio(sm);
 	}
 	}
 
 
-	if (pdata && pdata->gpio_i2c != NULL && pdata->gpio_i2c_nr > 0) {
+	if (pdata && pdata->gpio_i2c && pdata->gpio_i2c_nr > 0) {
 		if (!sm501_gpio_isregistered(sm))
 		if (!sm501_gpio_isregistered(sm))
 			dev_err(sm->dev, "no gpio available for i2c gpio.\n");
 			dev_err(sm->dev, "no gpio available for i2c gpio.\n");
 		else
 		else
@@ -1383,9 +1383,8 @@ static int sm501_plat_probe(struct platform_device *dev)
 	struct sm501_devdata *sm;
 	struct sm501_devdata *sm;
 	int ret;
 	int ret;
 
 
-	sm = kzalloc(sizeof(struct sm501_devdata), GFP_KERNEL);
-	if (sm == NULL) {
-		dev_err(&dev->dev, "no memory for device data\n");
+	sm = kzalloc(sizeof(*sm), GFP_KERNEL);
+	if (!sm) {
 		ret = -ENOMEM;
 		ret = -ENOMEM;
 		goto err1;
 		goto err1;
 	}
 	}
@@ -1403,8 +1402,7 @@ static int sm501_plat_probe(struct platform_device *dev)
 
 
 	sm->io_res = platform_get_resource(dev, IORESOURCE_MEM, 1);
 	sm->io_res = platform_get_resource(dev, IORESOURCE_MEM, 1);
 	sm->mem_res = platform_get_resource(dev, IORESOURCE_MEM, 0);
 	sm->mem_res = platform_get_resource(dev, IORESOURCE_MEM, 0);
-
-	if (sm->io_res == NULL || sm->mem_res == NULL) {
+	if (!sm->io_res || !sm->mem_res) {
 		dev_err(&dev->dev, "failed to get IO resource\n");
 		dev_err(&dev->dev, "failed to get IO resource\n");
 		ret = -ENOENT;
 		ret = -ENOENT;
 		goto err_res;
 		goto err_res;
@@ -1412,8 +1410,7 @@ static int sm501_plat_probe(struct platform_device *dev)
 
 
 	sm->regs_claim = request_mem_region(sm->io_res->start,
 	sm->regs_claim = request_mem_region(sm->io_res->start,
 					    0x100, "sm501");
 					    0x100, "sm501");
-
-	if (sm->regs_claim == NULL) {
+	if (!sm->regs_claim) {
 		dev_err(&dev->dev, "cannot claim registers\n");
 		dev_err(&dev->dev, "cannot claim registers\n");
 		ret = -EBUSY;
 		ret = -EBUSY;
 		goto err_res;
 		goto err_res;
@@ -1422,8 +1419,7 @@ static int sm501_plat_probe(struct platform_device *dev)
 	platform_set_drvdata(dev, sm);
 	platform_set_drvdata(dev, sm);
 
 
 	sm->regs = ioremap(sm->io_res->start, resource_size(sm->io_res));
 	sm->regs = ioremap(sm->io_res->start, resource_size(sm->io_res));
-
-	if (sm->regs == NULL) {
+	if (!sm->regs) {
 		dev_err(&dev->dev, "cannot remap registers\n");
 		dev_err(&dev->dev, "cannot remap registers\n");
 		ret = -EIO;
 		ret = -EIO;
 		goto err_claim;
 		goto err_claim;
@@ -1449,7 +1445,7 @@ static void sm501_set_power(struct sm501_devdata *sm, int on)
 {
 {
 	struct sm501_platdata *pd = sm->platdata;
 	struct sm501_platdata *pd = sm->platdata;
 
 
-	if (pd == NULL)
+	if (!pd)
 		return;
 		return;
 
 
 	if (pd->get_power) {
 	if (pd->get_power) {
@@ -1573,9 +1569,8 @@ static int sm501_pci_probe(struct pci_dev *dev,
 	struct sm501_devdata *sm;
 	struct sm501_devdata *sm;
 	int err;
 	int err;
 
 
-	sm = kzalloc(sizeof(struct sm501_devdata), GFP_KERNEL);
-	if (sm == NULL) {
-		dev_err(&dev->dev, "no memory for device data\n");
+	sm = kzalloc(sizeof(*sm), GFP_KERNEL);
+	if (!sm) {
 		err = -ENOMEM;
 		err = -ENOMEM;
 		goto err1;
 		goto err1;
 	}
 	}
@@ -1626,15 +1621,14 @@ static int sm501_pci_probe(struct pci_dev *dev,
 
 
 	sm->regs_claim = request_mem_region(sm->io_res->start,
 	sm->regs_claim = request_mem_region(sm->io_res->start,
 					    0x100, "sm501");
 					    0x100, "sm501");
-	if (sm->regs_claim == NULL) {
+	if (!sm->regs_claim) {
 		dev_err(&dev->dev, "cannot claim registers\n");
 		dev_err(&dev->dev, "cannot claim registers\n");
 		err= -EBUSY;
 		err= -EBUSY;
 		goto err3;
 		goto err3;
 	}
 	}
 
 
 	sm->regs = pci_ioremap_bar(dev, 1);
 	sm->regs = pci_ioremap_bar(dev, 1);
-
-	if (sm->regs == NULL) {
+	if (!sm->regs) {
 		dev_err(&dev->dev, "cannot remap registers\n");
 		dev_err(&dev->dev, "cannot remap registers\n");
 		err = -EIO;
 		err = -EIO;
 		goto err4;
 		goto err4;

+ 2 - 5
drivers/mfd/smsc-ece1099.c

@@ -37,12 +37,9 @@ static int smsc_i2c_probe(struct i2c_client *i2c,
 	int devid, rev, venid_l, venid_h;
 	int devid, rev, venid_l, venid_h;
 	int ret;
 	int ret;
 
 
-	smsc = devm_kzalloc(&i2c->dev, sizeof(struct smsc),
-				GFP_KERNEL);
-	if (!smsc) {
-		dev_err(&i2c->dev, "smsc mfd driver memory allocation failed\n");
+	smsc = devm_kzalloc(&i2c->dev, sizeof(*smsc), GFP_KERNEL);
+	if (!smsc)
 		return -ENOMEM;
 		return -ENOMEM;
-	}
 
 
 	smsc->regmap = devm_regmap_init_i2c(i2c, &smsc_regmap_config);
 	smsc->regmap = devm_regmap_init_i2c(i2c, &smsc_regmap_config);
 	if (IS_ERR(smsc->regmap))
 	if (IS_ERR(smsc->regmap))

+ 3 - 0
drivers/mfd/sprd-sc27xx-spi.c

@@ -111,6 +111,9 @@ static const struct mfd_cell sprd_pmic_devs[] = {
 	}, {
 	}, {
 		.name = "sc27xx-poweroff",
 		.name = "sc27xx-poweroff",
 		.of_compatible = "sprd,sc27xx-poweroff",
 		.of_compatible = "sprd,sc27xx-poweroff",
+	}, {
+		.name = "sc27xx-syscon",
+		.of_compatible = "sprd,sc27xx-syscon",
 	},
 	},
 };
 };
 
 

+ 199 - 2
drivers/mfd/stm32-timers.c

@@ -4,16 +4,156 @@
  * Author: Benjamin Gaignard <benjamin.gaignard@st.com>
  * Author: Benjamin Gaignard <benjamin.gaignard@st.com>
  */
  */
 
 
+#include <linux/bitfield.h>
 #include <linux/mfd/stm32-timers.h>
 #include <linux/mfd/stm32-timers.h>
 #include <linux/module.h>
 #include <linux/module.h>
 #include <linux/of_platform.h>
 #include <linux/of_platform.h>
 #include <linux/reset.h>
 #include <linux/reset.h>
 
 
+#define STM32_TIMERS_MAX_REGISTERS	0x3fc
+
+/* DIER register DMA enable bits */
+static const u32 stm32_timers_dier_dmaen[STM32_TIMERS_MAX_DMAS] = {
+	TIM_DIER_CC1DE,
+	TIM_DIER_CC2DE,
+	TIM_DIER_CC3DE,
+	TIM_DIER_CC4DE,
+	TIM_DIER_UIE,
+	TIM_DIER_TDE,
+	TIM_DIER_COMDE
+};
+
+static void stm32_timers_dma_done(void *p)
+{
+	struct stm32_timers_dma *dma = p;
+	struct dma_tx_state state;
+	enum dma_status status;
+
+	status = dmaengine_tx_status(dma->chan, dma->chan->cookie, &state);
+	if (status == DMA_COMPLETE)
+		complete(&dma->completion);
+}
+
+/**
+ * stm32_timers_dma_burst_read - Read from timers registers using DMA.
+ *
+ * Read from STM32 timers registers using DMA on a single event.
+ * @dev: reference to stm32_timers MFD device
+ * @buf: DMA'able destination buffer
+ * @id: stm32_timers_dmas event identifier (ch[1..4], up, trig or com)
+ * @reg: registers start offset for DMA to read from (like CCRx for capture)
+ * @num_reg: number of registers to read upon each DMA request, starting @reg.
+ * @bursts: number of bursts to read (e.g. like two for pwm period capture)
+ * @tmo_ms: timeout (milliseconds)
+ */
+int stm32_timers_dma_burst_read(struct device *dev, u32 *buf,
+				enum stm32_timers_dmas id, u32 reg,
+				unsigned int num_reg, unsigned int bursts,
+				unsigned long tmo_ms)
+{
+	struct stm32_timers *ddata = dev_get_drvdata(dev);
+	unsigned long timeout = msecs_to_jiffies(tmo_ms);
+	struct regmap *regmap = ddata->regmap;
+	struct stm32_timers_dma *dma = &ddata->dma;
+	size_t len = num_reg * bursts * sizeof(u32);
+	struct dma_async_tx_descriptor *desc;
+	struct dma_slave_config config;
+	dma_cookie_t cookie;
+	dma_addr_t dma_buf;
+	u32 dbl, dba;
+	long err;
+	int ret;
+
+	/* Sanity check */
+	if (id < STM32_TIMERS_DMA_CH1 || id >= STM32_TIMERS_MAX_DMAS)
+		return -EINVAL;
+
+	if (!num_reg || !bursts || reg > STM32_TIMERS_MAX_REGISTERS ||
+	    (reg + num_reg * sizeof(u32)) > STM32_TIMERS_MAX_REGISTERS)
+		return -EINVAL;
+
+	if (!dma->chans[id])
+		return -ENODEV;
+	mutex_lock(&dma->lock);
+
+	/* Select DMA channel in use */
+	dma->chan = dma->chans[id];
+	dma_buf = dma_map_single(dev, buf, len, DMA_FROM_DEVICE);
+	if (dma_mapping_error(dev, dma_buf)) {
+		ret = -ENOMEM;
+		goto unlock;
+	}
+
+	/* Prepare DMA read from timer registers, using DMA burst mode */
+	memset(&config, 0, sizeof(config));
+	config.src_addr = (dma_addr_t)dma->phys_base + TIM_DMAR;
+	config.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
+	ret = dmaengine_slave_config(dma->chan, &config);
+	if (ret)
+		goto unmap;
+
+	desc = dmaengine_prep_slave_single(dma->chan, dma_buf, len,
+					   DMA_DEV_TO_MEM, DMA_PREP_INTERRUPT);
+	if (!desc) {
+		ret = -EBUSY;
+		goto unmap;
+	}
+
+	desc->callback = stm32_timers_dma_done;
+	desc->callback_param = dma;
+	cookie = dmaengine_submit(desc);
+	ret = dma_submit_error(cookie);
+	if (ret)
+		goto dma_term;
+
+	reinit_completion(&dma->completion);
+	dma_async_issue_pending(dma->chan);
+
+	/* Setup and enable timer DMA burst mode */
+	dbl = FIELD_PREP(TIM_DCR_DBL, bursts - 1);
+	dba = FIELD_PREP(TIM_DCR_DBA, reg >> 2);
+	ret = regmap_write(regmap, TIM_DCR, dbl | dba);
+	if (ret)
+		goto dma_term;
+
+	/* Clear pending flags before enabling DMA request */
+	ret = regmap_write(regmap, TIM_SR, 0);
+	if (ret)
+		goto dcr_clr;
+
+	ret = regmap_update_bits(regmap, TIM_DIER, stm32_timers_dier_dmaen[id],
+				 stm32_timers_dier_dmaen[id]);
+	if (ret)
+		goto dcr_clr;
+
+	err = wait_for_completion_interruptible_timeout(&dma->completion,
+							timeout);
+	if (err == 0)
+		ret = -ETIMEDOUT;
+	else if (err < 0)
+		ret = err;
+
+	regmap_update_bits(regmap, TIM_DIER, stm32_timers_dier_dmaen[id], 0);
+	regmap_write(regmap, TIM_SR, 0);
+dcr_clr:
+	regmap_write(regmap, TIM_DCR, 0);
+dma_term:
+	dmaengine_terminate_all(dma->chan);
+unmap:
+	dma_unmap_single(dev, dma_buf, len, DMA_FROM_DEVICE);
+unlock:
+	dma->chan = NULL;
+	mutex_unlock(&dma->lock);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(stm32_timers_dma_burst_read);
+
 static const struct regmap_config stm32_timers_regmap_cfg = {
 static const struct regmap_config stm32_timers_regmap_cfg = {
 	.reg_bits = 32,
 	.reg_bits = 32,
 	.val_bits = 32,
 	.val_bits = 32,
 	.reg_stride = sizeof(u32),
 	.reg_stride = sizeof(u32),
-	.max_register = 0x3fc,
+	.max_register = STM32_TIMERS_MAX_REGISTERS,
 };
 };
 
 
 static void stm32_timers_get_arr_size(struct stm32_timers *ddata)
 static void stm32_timers_get_arr_size(struct stm32_timers *ddata)
@@ -27,12 +167,45 @@ static void stm32_timers_get_arr_size(struct stm32_timers *ddata)
 	regmap_write(ddata->regmap, TIM_ARR, 0x0);
 	regmap_write(ddata->regmap, TIM_ARR, 0x0);
 }
 }
 
 
+static void stm32_timers_dma_probe(struct device *dev,
+				   struct stm32_timers *ddata)
+{
+	int i;
+	char name[4];
+
+	init_completion(&ddata->dma.completion);
+	mutex_init(&ddata->dma.lock);
+
+	/* Optional DMA support: get valid DMA channel(s) or NULL */
+	for (i = STM32_TIMERS_DMA_CH1; i <= STM32_TIMERS_DMA_CH4; i++) {
+		snprintf(name, ARRAY_SIZE(name), "ch%1d", i + 1);
+		ddata->dma.chans[i] = dma_request_slave_channel(dev, name);
+	}
+	ddata->dma.chans[STM32_TIMERS_DMA_UP] =
+		dma_request_slave_channel(dev, "up");
+	ddata->dma.chans[STM32_TIMERS_DMA_TRIG] =
+		dma_request_slave_channel(dev, "trig");
+	ddata->dma.chans[STM32_TIMERS_DMA_COM] =
+		dma_request_slave_channel(dev, "com");
+}
+
+static void stm32_timers_dma_remove(struct device *dev,
+				    struct stm32_timers *ddata)
+{
+	int i;
+
+	for (i = STM32_TIMERS_DMA_CH1; i < STM32_TIMERS_MAX_DMAS; i++)
+		if (ddata->dma.chans[i])
+			dma_release_channel(ddata->dma.chans[i]);
+}
+
 static int stm32_timers_probe(struct platform_device *pdev)
 static int stm32_timers_probe(struct platform_device *pdev)
 {
 {
 	struct device *dev = &pdev->dev;
 	struct device *dev = &pdev->dev;
 	struct stm32_timers *ddata;
 	struct stm32_timers *ddata;
 	struct resource *res;
 	struct resource *res;
 	void __iomem *mmio;
 	void __iomem *mmio;
+	int ret;
 
 
 	ddata = devm_kzalloc(dev, sizeof(*ddata), GFP_KERNEL);
 	ddata = devm_kzalloc(dev, sizeof(*ddata), GFP_KERNEL);
 	if (!ddata)
 	if (!ddata)
@@ -43,6 +216,9 @@ static int stm32_timers_probe(struct platform_device *pdev)
 	if (IS_ERR(mmio))
 	if (IS_ERR(mmio))
 		return PTR_ERR(mmio);
 		return PTR_ERR(mmio);
 
 
+	/* Timer physical addr for DMA */
+	ddata->dma.phys_base = res->start;
+
 	ddata->regmap = devm_regmap_init_mmio_clk(dev, "int", mmio,
 	ddata->regmap = devm_regmap_init_mmio_clk(dev, "int", mmio,
 						  &stm32_timers_regmap_cfg);
 						  &stm32_timers_regmap_cfg);
 	if (IS_ERR(ddata->regmap))
 	if (IS_ERR(ddata->regmap))
@@ -54,9 +230,29 @@ static int stm32_timers_probe(struct platform_device *pdev)
 
 
 	stm32_timers_get_arr_size(ddata);
 	stm32_timers_get_arr_size(ddata);
 
 
+	stm32_timers_dma_probe(dev, ddata);
+
 	platform_set_drvdata(pdev, ddata);
 	platform_set_drvdata(pdev, ddata);
 
 
-	return devm_of_platform_populate(&pdev->dev);
+	ret = of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev);
+	if (ret)
+		stm32_timers_dma_remove(dev, ddata);
+
+	return ret;
+}
+
+static int stm32_timers_remove(struct platform_device *pdev)
+{
+	struct stm32_timers *ddata = platform_get_drvdata(pdev);
+
+	/*
+	 * Don't use devm_ here: enfore of_platform_depopulate() happens before
+	 * DMA are released, to avoid race on DMA.
+	 */
+	of_platform_depopulate(&pdev->dev);
+	stm32_timers_dma_remove(&pdev->dev, ddata);
+
+	return 0;
 }
 }
 
 
 static const struct of_device_id stm32_timers_of_match[] = {
 static const struct of_device_id stm32_timers_of_match[] = {
@@ -67,6 +263,7 @@ MODULE_DEVICE_TABLE(of, stm32_timers_of_match);
 
 
 static struct platform_driver stm32_timers_driver = {
 static struct platform_driver stm32_timers_driver = {
 	.probe = stm32_timers_probe,
 	.probe = stm32_timers_probe,
+	.remove = stm32_timers_remove,
 	.driver	= {
 	.driver	= {
 		.name = "stm32-timers",
 		.name = "stm32-timers",
 		.of_match_table = stm32_timers_of_match,
 		.of_match_table = stm32_timers_of_match,

+ 2 - 0
drivers/mfd/syscon.c

@@ -106,9 +106,11 @@ static struct syscon *of_syscon_register(struct device_node *np)
 		}
 		}
 	}
 	}
 
 
+	syscon_config.name = of_node_full_name(np);
 	syscon_config.reg_stride = reg_io_width;
 	syscon_config.reg_stride = reg_io_width;
 	syscon_config.val_bits = reg_io_width * 8;
 	syscon_config.val_bits = reg_io_width * 8;
 	syscon_config.max_register = resource_size(&res) - reg_io_width;
 	syscon_config.max_register = resource_size(&res) - reg_io_width;
+	syscon_config.name = of_node_full_name(np);
 
 
 	regmap = regmap_init_mmio(NULL, base, &syscon_config);
 	regmap = regmap_init_mmio(NULL, base, &syscon_config);
 	if (IS_ERR(regmap)) {
 	if (IS_ERR(regmap)) {

+ 2 - 3
drivers/mfd/ti_am335x_tscadc.c

@@ -169,10 +169,9 @@ static	int ti_tscadc_probe(struct platform_device *pdev)
 
 
 	/* Allocate memory for device */
 	/* Allocate memory for device */
 	tscadc = devm_kzalloc(&pdev->dev, sizeof(*tscadc), GFP_KERNEL);
 	tscadc = devm_kzalloc(&pdev->dev, sizeof(*tscadc), GFP_KERNEL);
-	if (!tscadc) {
-		dev_err(&pdev->dev, "failed to allocate memory.\n");
+	if (!tscadc)
 		return -ENOMEM;
 		return -ENOMEM;
-	}
+
 	tscadc->dev = &pdev->dev;
 	tscadc->dev = &pdev->dev;
 
 
 	err = platform_get_irq(pdev, 0);
 	err = platform_get_irq(pdev, 0);

+ 1 - 1
drivers/mfd/timberdale.c

@@ -777,7 +777,7 @@ static int timb_probe(struct pci_dev *dev,
 			&dev->resource[0], msix_entries[0].vector, NULL);
 			&dev->resource[0], msix_entries[0].vector, NULL);
 		break;
 		break;
 	default:
 	default:
-		dev_err(&dev->dev, "Uknown IP setup: %d.%d.%d\n",
+		dev_err(&dev->dev, "Unknown IP setup: %d.%d.%d\n",
 			priv->fw.major, priv->fw.minor, ip_setup);
 			priv->fw.major, priv->fw.minor, ip_setup);
 		err = -ENODEV;
 		err = -ENODEV;
 		goto err_mfd;
 		goto err_mfd;

+ 1 - 3
drivers/mfd/tps65090.c

@@ -192,10 +192,8 @@ static int tps65090_i2c_probe(struct i2c_client *client,
 		irq_base = pdata->irq_base;
 		irq_base = pdata->irq_base;
 
 
 	tps65090 = devm_kzalloc(&client->dev, sizeof(*tps65090), GFP_KERNEL);
 	tps65090 = devm_kzalloc(&client->dev, sizeof(*tps65090), GFP_KERNEL);
-	if (!tps65090) {
-		dev_err(&client->dev, "mem alloc for tps65090 failed\n");
+	if (!tps65090)
 		return -ENOMEM;
 		return -ENOMEM;
-	}
 
 
 	tps65090->dev = &client->dev;
 	tps65090->dev = &client->dev;
 	i2c_set_clientdata(client, tps65090);
 	i2c_set_clientdata(client, tps65090);

+ 1 - 3
drivers/mfd/tps6586x.c

@@ -423,10 +423,8 @@ static struct tps6586x_platform_data *tps6586x_parse_dt(struct i2c_client *clien
 	struct tps6586x_platform_data *pdata;
 	struct tps6586x_platform_data *pdata;
 
 
 	pdata = devm_kzalloc(&client->dev, sizeof(*pdata), GFP_KERNEL);
 	pdata = devm_kzalloc(&client->dev, sizeof(*pdata), GFP_KERNEL);
-	if (!pdata) {
-		dev_err(&client->dev, "Memory allocation failed\n");
+	if (!pdata)
 		return NULL;
 		return NULL;
-	}
 
 
 	pdata->num_subdevs = 0;
 	pdata->num_subdevs = 0;
 	pdata->subdevs = NULL;
 	pdata->subdevs = NULL;

+ 8 - 10
drivers/mfd/tps65910.c

@@ -229,7 +229,7 @@ static struct regmap_irq_chip tps65910_irq_chip = {
 static int tps65910_irq_init(struct tps65910 *tps65910, int irq,
 static int tps65910_irq_init(struct tps65910 *tps65910, int irq,
 		    struct tps65910_platform_data *pdata)
 		    struct tps65910_platform_data *pdata)
 {
 {
-	int ret = 0;
+	int ret;
 	static struct regmap_irq_chip *tps6591x_irqs_chip;
 	static struct regmap_irq_chip *tps6591x_irqs_chip;
 
 
 	if (!irq) {
 	if (!irq) {
@@ -312,14 +312,14 @@ static int tps65910_ck32k_init(struct tps65910 *tps65910,
 static int tps65910_sleepinit(struct tps65910 *tps65910,
 static int tps65910_sleepinit(struct tps65910 *tps65910,
 		struct tps65910_board *pmic_pdata)
 		struct tps65910_board *pmic_pdata)
 {
 {
-	struct device *dev = NULL;
-	int ret = 0;
-
-	dev = tps65910->dev;
+	struct device *dev;
+	int ret;
 
 
 	if (!pmic_pdata->en_dev_slp)
 	if (!pmic_pdata->en_dev_slp)
 		return 0;
 		return 0;
 
 
+	dev = tps65910->dev;
+
 	/* enabling SLEEP device state */
 	/* enabling SLEEP device state */
 	ret = tps65910_reg_set_bits(tps65910, TPS65910_DEVCTRL,
 	ret = tps65910_reg_set_bits(tps65910, TPS65910_DEVCTRL,
 				DEVCTRL_DEV_SLP_MASK);
 				DEVCTRL_DEV_SLP_MASK);
@@ -383,7 +383,7 @@ static struct tps65910_board *tps65910_parse_dt(struct i2c_client *client,
 	struct tps65910_board *board_info;
 	struct tps65910_board *board_info;
 	unsigned int prop;
 	unsigned int prop;
 	const struct of_device_id *match;
 	const struct of_device_id *match;
-	int ret = 0;
+	int ret;
 
 
 	match = of_match_device(tps65910_of_match, &client->dev);
 	match = of_match_device(tps65910_of_match, &client->dev);
 	if (!match) {
 	if (!match) {
@@ -395,10 +395,8 @@ static struct tps65910_board *tps65910_parse_dt(struct i2c_client *client,
 
 
 	board_info = devm_kzalloc(&client->dev, sizeof(*board_info),
 	board_info = devm_kzalloc(&client->dev, sizeof(*board_info),
 			GFP_KERNEL);
 			GFP_KERNEL);
-	if (!board_info) {
-		dev_err(&client->dev, "Failed to allocate pdata\n");
+	if (!board_info)
 		return NULL;
 		return NULL;
-	}
 
 
 	ret = of_property_read_u32(np, "ti,vmbch-threshold", &prop);
 	ret = of_property_read_u32(np, "ti,vmbch-threshold", &prop);
 	if (!ret)
 	if (!ret)
@@ -462,7 +460,7 @@ static int tps65910_i2c_probe(struct i2c_client *i2c,
 	struct tps65910_board *of_pmic_plat_data = NULL;
 	struct tps65910_board *of_pmic_plat_data = NULL;
 	struct tps65910_platform_data *init_data;
 	struct tps65910_platform_data *init_data;
 	unsigned long chip_id = id->driver_data;
 	unsigned long chip_id = id->driver_data;
-	int ret = 0;
+	int ret;
 
 
 	pmic_plat_data = dev_get_platdata(&i2c->dev);
 	pmic_plat_data = dev_get_platdata(&i2c->dev);
 
 

+ 5 - 12
drivers/mfd/tps65911-comparator.c

@@ -22,9 +22,8 @@
 #include <linux/gpio.h>
 #include <linux/gpio.h>
 #include <linux/mfd/tps65910.h>
 #include <linux/mfd/tps65910.h>
 
 
-#define COMP					0
-#define COMP1					1
-#define COMP2					2
+#define COMP1					0
+#define COMP2					1
 
 
 /* Comparator 1 voltage selection table in millivolts */
 /* Comparator 1 voltage selection table in millivolts */
 static const u16 COMP_VSEL_TABLE[] = {
 static const u16 COMP_VSEL_TABLE[] = {
@@ -63,9 +62,6 @@ static int comp_threshold_set(struct tps65910 *tps65910, int id, int voltage)
 	int ret;
 	int ret;
 	u8 index = 0, val;
 	u8 index = 0, val;
 
 
-	if (id == COMP)
-		return 0;
-
 	while (curr_voltage < tps_comp.uV_max) {
 	while (curr_voltage < tps_comp.uV_max) {
 		curr_voltage = tps_comp.vsel_table[index];
 		curr_voltage = tps_comp.vsel_table[index];
 		if (curr_voltage >= voltage)
 		if (curr_voltage >= voltage)
@@ -78,7 +74,7 @@ static int comp_threshold_set(struct tps65910 *tps65910, int id, int voltage)
 		return -EINVAL;
 		return -EINVAL;
 
 
 	val = index << 1;
 	val = index << 1;
-	ret = tps65910->write(tps65910, tps_comp.reg, 1, &val);
+	ret = tps65910_reg_write(tps65910, tps_comp.reg, val);
 
 
 	return ret;
 	return ret;
 }
 }
@@ -86,13 +82,10 @@ static int comp_threshold_set(struct tps65910 *tps65910, int id, int voltage)
 static int comp_threshold_get(struct tps65910 *tps65910, int id)
 static int comp_threshold_get(struct tps65910 *tps65910, int id)
 {
 {
 	struct comparator tps_comp = tps_comparators[id];
 	struct comparator tps_comp = tps_comparators[id];
+	unsigned int val;
 	int ret;
 	int ret;
-	u8 val;
-
-	if (id == COMP)
-		return 0;
 
 
-	ret = tps65910->read(tps65910, tps_comp.reg, 1, &val);
+	ret = tps65910_reg_read(tps65910, tps_comp.reg, &val);
 	if (ret < 0)
 	if (ret < 0)
 		return ret;
 		return ret;
 
 

+ 1 - 9
drivers/mfd/tps68470.c

@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
 /*
  * TPS68470 chip Parent driver
  * TPS68470 chip Parent driver
  *
  *
@@ -8,15 +9,6 @@
  *	Tianshu Qiu <tian.shu.qiu@intel.com>
  *	Tianshu Qiu <tian.shu.qiu@intel.com>
  *	Jian Xu Zheng <jian.xu.zheng@intel.com>
  *	Jian Xu Zheng <jian.xu.zheng@intel.com>
  *	Yuning Pu <yuning.pu@intel.com>
  *	Yuning Pu <yuning.pu@intel.com>
- *
- * 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 version 2.
- *
- * This program is distributed "as is" WITHOUT ANY WARRANTY of any
- * kind, whether express or implied; without even the implied warranty
- * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
  */
  */
 
 
 #include <linux/acpi.h>
 #include <linux/acpi.h>

+ 1 - 3
drivers/mfd/tps80031.c

@@ -431,10 +431,8 @@ static int tps80031_probe(struct i2c_client *client,
 	}
 	}
 
 
 	tps80031 = devm_kzalloc(&client->dev, sizeof(*tps80031), GFP_KERNEL);
 	tps80031 = devm_kzalloc(&client->dev, sizeof(*tps80031), GFP_KERNEL);
-	if (!tps80031) {
-		dev_err(&client->dev, "Malloc failed for tps80031\n");
+	if (!tps80031)
 		return -ENOMEM;
 		return -ENOMEM;
-	}
 
 
 	for (i = 0; i < TPS80031_NUM_SLAVES; i++) {
 	for (i = 0; i < TPS80031_NUM_SLAVES; i++) {
 		if (tps80031_slave_address[i] == client->addr)
 		if (tps80031_slave_address[i] == client->addr)

+ 1 - 1
drivers/mfd/twl-core.c

@@ -1177,7 +1177,7 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id)
 	twl_priv->ready = true;
 	twl_priv->ready = true;
 
 
 	/* setup clock framework */
 	/* setup clock framework */
-	clocks_init(&pdev->dev, pdata ? pdata->clock : NULL);
+	clocks_init(&client->dev, pdata ? pdata->clock : NULL);
 
 
 	/* read TWL IDCODE Register */
 	/* read TWL IDCODE Register */
 	if (twl_class_is_4030()) {
 	if (twl_class_is_4030()) {

+ 1 - 3
drivers/mfd/twl6030-irq.c

@@ -392,10 +392,8 @@ int twl6030_init_irq(struct device *dev, int irq_num)
 	nr_irqs = TWL6030_NR_IRQS;
 	nr_irqs = TWL6030_NR_IRQS;
 
 
 	twl6030_irq = devm_kzalloc(dev, sizeof(*twl6030_irq), GFP_KERNEL);
 	twl6030_irq = devm_kzalloc(dev, sizeof(*twl6030_irq), GFP_KERNEL);
-	if (!twl6030_irq) {
-		dev_err(dev, "twl6030_irq: Memory allocation failed\n");
+	if (!twl6030_irq)
 		return -ENOMEM;
 		return -ENOMEM;
-	}
 
 
 	mask[0] = 0xFF;
 	mask[0] = 0xFF;
 	mask[1] = 0xFF;
 	mask[1] = 0xFF;

+ 1 - 3
drivers/mfd/viperboard.c

@@ -59,10 +59,8 @@ static int vprbrd_probe(struct usb_interface *interface,
 
 
 	/* allocate memory for our device state and initialize it */
 	/* allocate memory for our device state and initialize it */
 	vb = kzalloc(sizeof(*vb), GFP_KERNEL);
 	vb = kzalloc(sizeof(*vb), GFP_KERNEL);
-	if (vb == NULL) {
-		dev_err(&interface->dev, "Out of memory\n");
+	if (!vb)
 		return -ENOMEM;
 		return -ENOMEM;
-	}
 
 
 	mutex_init(&vb->lock);
 	mutex_init(&vb->lock);
 
 

+ 1 - 1
drivers/mfd/wm97xx-core.c

@@ -278,7 +278,7 @@ static int wm97xx_ac97_probe(struct ac97_codec_device *adev)
 
 
 	codec_pdata = &wm97xx->codec_pdata;
 	codec_pdata = &wm97xx->codec_pdata;
 	codec_pdata->ac97 = wm97xx->ac97;
 	codec_pdata->ac97 = wm97xx->ac97;
-	codec_pdata->batt_pdata = pdata->batt_pdata;
+	codec_pdata->batt_pdata = pdata ? pdata->batt_pdata : NULL;
 
 
 	switch (adev->vendor_id) {
 	switch (adev->vendor_id) {
 	case WM9705_VENDOR_ID:
 	case WM9705_VENDOR_ID:

+ 20 - 0
drivers/platform/chrome/cros_ec_debugfs.c

@@ -470,3 +470,23 @@ void cros_ec_debugfs_remove(struct cros_ec_dev *ec)
 	cros_ec_cleanup_console_log(ec->debug_info);
 	cros_ec_cleanup_console_log(ec->debug_info);
 }
 }
 EXPORT_SYMBOL(cros_ec_debugfs_remove);
 EXPORT_SYMBOL(cros_ec_debugfs_remove);
+
+void cros_ec_debugfs_suspend(struct cros_ec_dev *ec)
+{
+	/*
+	 * cros_ec_debugfs_init() failures are non-fatal; it's also possible
+	 * that we initted things but decided that console log wasn't supported.
+	 * We'll use the same set of checks that cros_ec_debugfs_remove() +
+	 * cros_ec_cleanup_console_log() end up using to handle those cases.
+	 */
+	if (ec->debug_info && ec->debug_info->log_buffer.buf)
+		cancel_delayed_work_sync(&ec->debug_info->log_poll_work);
+}
+EXPORT_SYMBOL(cros_ec_debugfs_suspend);
+
+void cros_ec_debugfs_resume(struct cros_ec_dev *ec)
+{
+	if (ec->debug_info && ec->debug_info->log_buffer.buf)
+		schedule_delayed_work(&ec->debug_info->log_poll_work, 0);
+}
+EXPORT_SYMBOL(cros_ec_debugfs_resume);

+ 257 - 0
drivers/pwm/pwm-stm32.c

@@ -8,6 +8,7 @@
  *             pwm-atmel.c from Bo Shen
  *             pwm-atmel.c from Bo Shen
  */
  */
 
 
+#include <linux/bitfield.h>
 #include <linux/mfd/stm32-timers.h>
 #include <linux/mfd/stm32-timers.h>
 #include <linux/module.h>
 #include <linux/module.h>
 #include <linux/of.h>
 #include <linux/of.h>
@@ -25,6 +26,7 @@ struct stm32_pwm {
 	struct regmap *regmap;
 	struct regmap *regmap;
 	u32 max_arr;
 	u32 max_arr;
 	bool have_complementary_output;
 	bool have_complementary_output;
+	u32 capture[4] ____cacheline_aligned; /* DMA'able buffer */
 };
 };
 
 
 struct stm32_breakinput {
 struct stm32_breakinput {
@@ -62,6 +64,258 @@ static int write_ccrx(struct stm32_pwm *dev, int ch, u32 value)
 	return -EINVAL;
 	return -EINVAL;
 }
 }
 
 
+#define TIM_CCER_CC12P (TIM_CCER_CC1P | TIM_CCER_CC2P)
+#define TIM_CCER_CC12E (TIM_CCER_CC1E | TIM_CCER_CC2E)
+#define TIM_CCER_CC34P (TIM_CCER_CC3P | TIM_CCER_CC4P)
+#define TIM_CCER_CC34E (TIM_CCER_CC3E | TIM_CCER_CC4E)
+
+/*
+ * Capture using PWM input mode:
+ *                              ___          ___
+ * TI[1, 2, 3 or 4]: ........._|   |________|
+ *                             ^0  ^1       ^2
+ *                              .   .        .
+ *                              .   .        XXXXX
+ *                              .   .   XXXXX     |
+ *                              .  XXXXX     .    |
+ *                            XXXXX .        .    |
+ * COUNTER:        ______XXXXX  .   .        .    |_XXX
+ *                 start^       .   .        .        ^stop
+ *                      .       .   .        .
+ *                      v       v   .        v
+ *                                  v
+ * CCR1/CCR3:       tx..........t0...........t2
+ * CCR2/CCR4:       tx..............t1.........
+ *
+ * DMA burst transfer:          |            |
+ *                              v            v
+ * DMA buffer:                  { t0, tx }   { t2, t1 }
+ * DMA done:                                 ^
+ *
+ * 0: IC1/3 snapchot on rising edge: counter value -> CCR1/CCR3
+ *    + DMA transfer CCR[1/3] & CCR[2/4] values (t0, tx: doesn't care)
+ * 1: IC2/4 snapchot on falling edge: counter value -> CCR2/CCR4
+ * 2: IC1/3 snapchot on rising edge: counter value -> CCR1/CCR3
+ *    + DMA transfer CCR[1/3] & CCR[2/4] values (t2, t1)
+ *
+ * DMA done, compute:
+ * - Period     = t2 - t0
+ * - Duty cycle = t1 - t0
+ */
+static int stm32_pwm_raw_capture(struct stm32_pwm *priv, struct pwm_device *pwm,
+				 unsigned long tmo_ms, u32 *raw_prd,
+				 u32 *raw_dty)
+{
+	struct device *parent = priv->chip.dev->parent;
+	enum stm32_timers_dmas dma_id;
+	u32 ccen, ccr;
+	int ret;
+
+	/* Ensure registers have been updated, enable counter and capture */
+	regmap_update_bits(priv->regmap, TIM_EGR, TIM_EGR_UG, TIM_EGR_UG);
+	regmap_update_bits(priv->regmap, TIM_CR1, TIM_CR1_CEN, TIM_CR1_CEN);
+
+	/* Use cc1 or cc3 DMA resp for PWM input channels 1 & 2 or 3 & 4 */
+	dma_id = pwm->hwpwm < 2 ? STM32_TIMERS_DMA_CH1 : STM32_TIMERS_DMA_CH3;
+	ccen = pwm->hwpwm < 2 ? TIM_CCER_CC12E : TIM_CCER_CC34E;
+	ccr = pwm->hwpwm < 2 ? TIM_CCR1 : TIM_CCR3;
+	regmap_update_bits(priv->regmap, TIM_CCER, ccen, ccen);
+
+	/*
+	 * Timer DMA burst mode. Request 2 registers, 2 bursts, to get both
+	 * CCR1 & CCR2 (or CCR3 & CCR4) on each capture event.
+	 * We'll get two capture snapchots: { CCR1, CCR2 }, { CCR1, CCR2 }
+	 * or { CCR3, CCR4 }, { CCR3, CCR4 }
+	 */
+	ret = stm32_timers_dma_burst_read(parent, priv->capture, dma_id, ccr, 2,
+					  2, tmo_ms);
+	if (ret)
+		goto stop;
+
+	/* Period: t2 - t0 (take care of counter overflow) */
+	if (priv->capture[0] <= priv->capture[2])
+		*raw_prd = priv->capture[2] - priv->capture[0];
+	else
+		*raw_prd = priv->max_arr - priv->capture[0] + priv->capture[2];
+
+	/* Duty cycle capture requires at least two capture units */
+	if (pwm->chip->npwm < 2)
+		*raw_dty = 0;
+	else if (priv->capture[0] <= priv->capture[3])
+		*raw_dty = priv->capture[3] - priv->capture[0];
+	else
+		*raw_dty = priv->max_arr - priv->capture[0] + priv->capture[3];
+
+	if (*raw_dty > *raw_prd) {
+		/*
+		 * Race beetween PWM input and DMA: it may happen
+		 * falling edge triggers new capture on TI2/4 before DMA
+		 * had a chance to read CCR2/4. It means capture[1]
+		 * contains period + duty_cycle. So, subtract period.
+		 */
+		*raw_dty -= *raw_prd;
+	}
+
+stop:
+	regmap_update_bits(priv->regmap, TIM_CCER, ccen, 0);
+	regmap_update_bits(priv->regmap, TIM_CR1, TIM_CR1_CEN, 0);
+
+	return ret;
+}
+
+static int stm32_pwm_capture(struct pwm_chip *chip, struct pwm_device *pwm,
+			     struct pwm_capture *result, unsigned long tmo_ms)
+{
+	struct stm32_pwm *priv = to_stm32_pwm_dev(chip);
+	unsigned long long prd, div, dty;
+	unsigned long rate;
+	unsigned int psc = 0, icpsc, scale;
+	u32 raw_prd = 0, raw_dty = 0;
+	int ret = 0;
+
+	mutex_lock(&priv->lock);
+
+	if (active_channels(priv)) {
+		ret = -EBUSY;
+		goto unlock;
+	}
+
+	ret = clk_enable(priv->clk);
+	if (ret) {
+		dev_err(priv->chip.dev, "failed to enable counter clock\n");
+		goto unlock;
+	}
+
+	rate = clk_get_rate(priv->clk);
+	if (!rate) {
+		ret = -EINVAL;
+		goto clk_dis;
+	}
+
+	/* prescaler: fit timeout window provided by upper layer */
+	div = (unsigned long long)rate * (unsigned long long)tmo_ms;
+	do_div(div, MSEC_PER_SEC);
+	prd = div;
+	while ((div > priv->max_arr) && (psc < MAX_TIM_PSC)) {
+		psc++;
+		div = prd;
+		do_div(div, psc + 1);
+	}
+	regmap_write(priv->regmap, TIM_ARR, priv->max_arr);
+	regmap_write(priv->regmap, TIM_PSC, psc);
+
+	/* Map TI1 or TI2 PWM input to IC1 & IC2 (or TI3/4 to IC3 & IC4) */
+	regmap_update_bits(priv->regmap,
+			   pwm->hwpwm < 2 ? TIM_CCMR1 : TIM_CCMR2,
+			   TIM_CCMR_CC1S | TIM_CCMR_CC2S, pwm->hwpwm & 0x1 ?
+			   TIM_CCMR_CC1S_TI2 | TIM_CCMR_CC2S_TI2 :
+			   TIM_CCMR_CC1S_TI1 | TIM_CCMR_CC2S_TI1);
+
+	/* Capture period on IC1/3 rising edge, duty cycle on IC2/4 falling. */
+	regmap_update_bits(priv->regmap, TIM_CCER, pwm->hwpwm < 2 ?
+			   TIM_CCER_CC12P : TIM_CCER_CC34P, pwm->hwpwm < 2 ?
+			   TIM_CCER_CC2P : TIM_CCER_CC4P);
+
+	ret = stm32_pwm_raw_capture(priv, pwm, tmo_ms, &raw_prd, &raw_dty);
+	if (ret)
+		goto stop;
+
+	/*
+	 * Got a capture. Try to improve accuracy at high rates:
+	 * - decrease counter clock prescaler, scale up to max rate.
+	 * - use input prescaler, capture once every /2 /4 or /8 edges.
+	 */
+	if (raw_prd) {
+		u32 max_arr = priv->max_arr - 0x1000; /* arbitrary margin */
+
+		scale = max_arr / min(max_arr, raw_prd);
+	} else {
+		scale = priv->max_arr; /* bellow resolution, use max scale */
+	}
+
+	if (psc && scale > 1) {
+		/* 2nd measure with new scale */
+		psc /= scale;
+		regmap_write(priv->regmap, TIM_PSC, psc);
+		ret = stm32_pwm_raw_capture(priv, pwm, tmo_ms, &raw_prd,
+					    &raw_dty);
+		if (ret)
+			goto stop;
+	}
+
+	/* Compute intermediate period not to exceed timeout at low rates */
+	prd = (unsigned long long)raw_prd * (psc + 1) * NSEC_PER_SEC;
+	do_div(prd, rate);
+
+	for (icpsc = 0; icpsc < MAX_TIM_ICPSC ; icpsc++) {
+		/* input prescaler: also keep arbitrary margin */
+		if (raw_prd >= (priv->max_arr - 0x1000) >> (icpsc + 1))
+			break;
+		if (prd >= (tmo_ms * NSEC_PER_MSEC) >> (icpsc + 2))
+			break;
+	}
+
+	if (!icpsc)
+		goto done;
+
+	/* Last chance to improve period accuracy, using input prescaler */
+	regmap_update_bits(priv->regmap,
+			   pwm->hwpwm < 2 ? TIM_CCMR1 : TIM_CCMR2,
+			   TIM_CCMR_IC1PSC | TIM_CCMR_IC2PSC,
+			   FIELD_PREP(TIM_CCMR_IC1PSC, icpsc) |
+			   FIELD_PREP(TIM_CCMR_IC2PSC, icpsc));
+
+	ret = stm32_pwm_raw_capture(priv, pwm, tmo_ms, &raw_prd, &raw_dty);
+	if (ret)
+		goto stop;
+
+	if (raw_dty >= (raw_prd >> icpsc)) {
+		/*
+		 * We may fall here using input prescaler, when input
+		 * capture starts on high side (before falling edge).
+		 * Example with icpsc to capture on each 4 events:
+		 *
+		 *       start   1st capture                     2nd capture
+		 *         v     v                               v
+		 *         ___   _____   _____   _____   _____   ____
+		 * TI1..4     |__|    |__|    |__|    |__|    |__|
+		 *            v  v    .  .    .  .    .       v  v
+		 * icpsc1/3:  .  0    .  1    .  2    .  3    .  0
+		 * icpsc2/4:  0       1       2       3       0
+		 *            v  v                            v  v
+		 * CCR1/3  ......t0..............................t2
+		 * CCR2/4  ..t1..............................t1'...
+		 *               .                            .  .
+		 * Capture0:     .<----------------------------->.
+		 * Capture1:     .<-------------------------->.  .
+		 *               .                            .  .
+		 * Period:       .<------>                    .  .
+		 * Low side:                                  .<>.
+		 *
+		 * Result:
+		 * - Period = Capture0 / icpsc
+		 * - Duty = Period - Low side = Period - (Capture0 - Capture1)
+		 */
+		raw_dty = (raw_prd >> icpsc) - (raw_prd - raw_dty);
+	}
+
+done:
+	prd = (unsigned long long)raw_prd * (psc + 1) * NSEC_PER_SEC;
+	result->period = DIV_ROUND_UP_ULL(prd, rate << icpsc);
+	dty = (unsigned long long)raw_dty * (psc + 1) * NSEC_PER_SEC;
+	result->duty_cycle = DIV_ROUND_UP_ULL(dty, rate);
+stop:
+	regmap_write(priv->regmap, TIM_CCER, 0);
+	regmap_write(priv->regmap, pwm->hwpwm < 2 ? TIM_CCMR1 : TIM_CCMR2, 0);
+	regmap_write(priv->regmap, TIM_PSC, 0);
+clk_dis:
+	clk_disable(priv->clk);
+unlock:
+	mutex_unlock(&priv->lock);
+
+	return ret;
+}
+
 static int stm32_pwm_config(struct stm32_pwm *priv, int ch,
 static int stm32_pwm_config(struct stm32_pwm *priv, int ch,
 			    int duty_ns, int period_ns)
 			    int duty_ns, int period_ns)
 {
 {
@@ -230,6 +484,9 @@ static int stm32_pwm_apply_locked(struct pwm_chip *chip, struct pwm_device *pwm,
 static const struct pwm_ops stm32pwm_ops = {
 static const struct pwm_ops stm32pwm_ops = {
 	.owner = THIS_MODULE,
 	.owner = THIS_MODULE,
 	.apply = stm32_pwm_apply_locked,
 	.apply = stm32_pwm_apply_locked,
+#if IS_ENABLED(CONFIG_DMA_ENGINE)
+	.capture = stm32_pwm_capture,
+#endif
 };
 };
 
 
 static int stm32_pwm_set_breakinput(struct stm32_pwm *priv,
 static int stm32_pwm_set_breakinput(struct stm32_pwm *priv,

+ 3 - 4
drivers/rtc/rtc-mt6397.c

@@ -322,10 +322,9 @@ static int mtk_rtc_probe(struct platform_device *pdev)
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	rtc->addr_base = res->start;
 	rtc->addr_base = res->start;
 
 
-	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
-	rtc->irq = irq_create_mapping(mt6397_chip->irq_domain, res->start);
-	if (rtc->irq <= 0)
-		return -EINVAL;
+	rtc->irq = platform_get_irq(pdev, 0);
+	if (rtc->irq < 0)
+		return rtc->irq;
 
 
 	rtc->regmap = mt6397_chip->regmap;
 	rtc->regmap = mt6397_chip->regmap;
 	rtc->dev = &pdev->dev;
 	rtc->dev = &pdev->dev;

+ 2 - 1
include/linux/mfd/arizona/pdata.h

@@ -56,6 +56,7 @@
 #define ARIZONA_MAX_PDM_SPK 2
 #define ARIZONA_MAX_PDM_SPK 2
 
 
 struct regulator_init_data;
 struct regulator_init_data;
+struct gpio_desc;
 
 
 struct arizona_micbias {
 struct arizona_micbias {
 	int mV;                    /** Regulated voltage */
 	int mV;                    /** Regulated voltage */
@@ -77,7 +78,7 @@ struct arizona_micd_range {
 };
 };
 
 
 struct arizona_pdata {
 struct arizona_pdata {
-	int reset;      /** GPIO controlling /RESET, if any */
+	struct gpio_desc *reset;      /** GPIO controlling /RESET, if any */
 
 
 	/** Regulator configuration for MICVDD */
 	/** Regulator configuration for MICVDD */
 	struct arizona_micsupp_pdata micvdd;
 	struct arizona_micsupp_pdata micvdd;

+ 5 - 5
include/linux/mfd/axp20x.h

@@ -592,11 +592,11 @@ enum axp806_irqs {
 	AXP806_IRQ_DCDCC_V_LOW,
 	AXP806_IRQ_DCDCC_V_LOW,
 	AXP806_IRQ_DCDCD_V_LOW,
 	AXP806_IRQ_DCDCD_V_LOW,
 	AXP806_IRQ_DCDCE_V_LOW,
 	AXP806_IRQ_DCDCE_V_LOW,
-	AXP806_IRQ_PWROK_LONG,
-	AXP806_IRQ_PWROK_SHORT,
+	AXP806_IRQ_POK_LONG,
+	AXP806_IRQ_POK_SHORT,
 	AXP806_IRQ_WAKEUP,
 	AXP806_IRQ_WAKEUP,
-	AXP806_IRQ_PWROK_FALL,
-	AXP806_IRQ_PWROK_RISE,
+	AXP806_IRQ_POK_FALL,
+	AXP806_IRQ_POK_RISE,
 };
 };
 
 
 enum axp809_irqs {
 enum axp809_irqs {
@@ -642,7 +642,7 @@ struct axp20x_dev {
 	struct regmap_irq_chip_data	*regmap_irqc;
 	struct regmap_irq_chip_data	*regmap_irqc;
 	long				variant;
 	long				variant;
 	int                             nr_cells;
 	int                             nr_cells;
-	struct mfd_cell                 *cells;
+	const struct mfd_cell           *cells;
 	const struct regmap_config	*regmap_cfg;
 	const struct regmap_config	*regmap_cfg;
 	const struct regmap_irq_chip	*regmap_irq_chip;
 	const struct regmap_irq_chip	*regmap_irq_chip;
 };
 };

+ 2 - 18
include/linux/mfd/cros_ec.h

@@ -329,23 +329,7 @@ extern struct attribute_group cros_ec_vbc_attr_group;
 /* debugfs stuff */
 /* debugfs stuff */
 int cros_ec_debugfs_init(struct cros_ec_dev *ec);
 int cros_ec_debugfs_init(struct cros_ec_dev *ec);
 void cros_ec_debugfs_remove(struct cros_ec_dev *ec);
 void cros_ec_debugfs_remove(struct cros_ec_dev *ec);
-
-/* ACPI GPE handler */
-#ifdef CONFIG_ACPI
-
-int cros_ec_acpi_install_gpe_handler(struct device *dev);
-void cros_ec_acpi_remove_gpe_handler(void);
-void cros_ec_acpi_clear_gpe(void);
-
-#else /* CONFIG_ACPI */
-
-static inline int cros_ec_acpi_install_gpe_handler(struct device *dev)
-{
-	return -ENODEV;
-}
-static inline void cros_ec_acpi_remove_gpe_handler(void) {}
-static inline void cros_ec_acpi_clear_gpe(void) {}
-
-#endif /* CONFIG_ACPI */
+void cros_ec_debugfs_suspend(struct cros_ec_dev *ec);
+void cros_ec_debugfs_resume(struct cros_ec_dev *ec);
 
 
 #endif /* __LINUX_MFD_CROS_EC_H */
 #endif /* __LINUX_MFD_CROS_EC_H */

+ 70 - 0
include/linux/mfd/stm32-timers.h

@@ -8,6 +8,8 @@
 #define _LINUX_STM32_GPTIMER_H_
 #define _LINUX_STM32_GPTIMER_H_
 
 
 #include <linux/clk.h>
 #include <linux/clk.h>
+#include <linux/dmaengine.h>
+#include <linux/dma-mapping.h>
 #include <linux/regmap.h>
 #include <linux/regmap.h>
 
 
 #define TIM_CR1		0x00	/* Control Register 1      */
 #define TIM_CR1		0x00	/* Control Register 1      */
@@ -27,6 +29,8 @@
 #define TIM_CCR3	0x3C	/* Capt/Comp Register 3    */
 #define TIM_CCR3	0x3C	/* Capt/Comp Register 3    */
 #define TIM_CCR4	0x40	/* Capt/Comp Register 4    */
 #define TIM_CCR4	0x40	/* Capt/Comp Register 4    */
 #define TIM_BDTR	0x44	/* Break and Dead-Time Reg */
 #define TIM_BDTR	0x44	/* Break and Dead-Time Reg */
+#define TIM_DCR		0x48	/* DMA control register    */
+#define TIM_DMAR	0x4C	/* DMA register for transfer */
 
 
 #define TIM_CR1_CEN	BIT(0)	/* Counter Enable	   */
 #define TIM_CR1_CEN	BIT(0)	/* Counter Enable	   */
 #define TIM_CR1_DIR	BIT(4)  /* Counter Direction	   */
 #define TIM_CR1_DIR	BIT(4)  /* Counter Direction	   */
@@ -36,17 +40,35 @@
 #define TIM_SMCR_SMS	(BIT(0) | BIT(1) | BIT(2)) /* Slave mode selection */
 #define TIM_SMCR_SMS	(BIT(0) | BIT(1) | BIT(2)) /* Slave mode selection */
 #define TIM_SMCR_TS	(BIT(4) | BIT(5) | BIT(6)) /* Trigger selection */
 #define TIM_SMCR_TS	(BIT(4) | BIT(5) | BIT(6)) /* Trigger selection */
 #define TIM_DIER_UIE	BIT(0)	/* Update interrupt	   */
 #define TIM_DIER_UIE	BIT(0)	/* Update interrupt	   */
+#define TIM_DIER_UDE	BIT(8)  /* Update DMA request Enable */
+#define TIM_DIER_CC1DE	BIT(9)  /* CC1 DMA request Enable  */
+#define TIM_DIER_CC2DE	BIT(10) /* CC2 DMA request Enable  */
+#define TIM_DIER_CC3DE	BIT(11) /* CC3 DMA request Enable  */
+#define TIM_DIER_CC4DE	BIT(12) /* CC4 DMA request Enable  */
+#define TIM_DIER_COMDE	BIT(13) /* COM DMA request Enable  */
+#define TIM_DIER_TDE	BIT(14) /* Trigger DMA request Enable */
 #define TIM_SR_UIF	BIT(0)	/* Update interrupt flag   */
 #define TIM_SR_UIF	BIT(0)	/* Update interrupt flag   */
 #define TIM_EGR_UG	BIT(0)	/* Update Generation       */
 #define TIM_EGR_UG	BIT(0)	/* Update Generation       */
 #define TIM_CCMR_PE	BIT(3)	/* Channel Preload Enable  */
 #define TIM_CCMR_PE	BIT(3)	/* Channel Preload Enable  */
 #define TIM_CCMR_M1	(BIT(6) | BIT(5))  /* Channel PWM Mode 1 */
 #define TIM_CCMR_M1	(BIT(6) | BIT(5))  /* Channel PWM Mode 1 */
+#define TIM_CCMR_CC1S		(BIT(0) | BIT(1)) /* Capture/compare 1 sel */
+#define TIM_CCMR_IC1PSC		GENMASK(3, 2)	/* Input capture 1 prescaler */
+#define TIM_CCMR_CC2S		(BIT(8) | BIT(9)) /* Capture/compare 2 sel */
+#define TIM_CCMR_IC2PSC		GENMASK(11, 10)	/* Input capture 2 prescaler */
+#define TIM_CCMR_CC1S_TI1	BIT(0)	/* IC1/IC3 selects TI1/TI3 */
+#define TIM_CCMR_CC1S_TI2	BIT(1)	/* IC1/IC3 selects TI2/TI4 */
+#define TIM_CCMR_CC2S_TI2	BIT(8)	/* IC2/IC4 selects TI2/TI4 */
+#define TIM_CCMR_CC2S_TI1	BIT(9)	/* IC2/IC4 selects TI1/TI3 */
 #define TIM_CCER_CC1E	BIT(0)	/* Capt/Comp 1  out Ena    */
 #define TIM_CCER_CC1E	BIT(0)	/* Capt/Comp 1  out Ena    */
 #define TIM_CCER_CC1P	BIT(1)	/* Capt/Comp 1  Polarity   */
 #define TIM_CCER_CC1P	BIT(1)	/* Capt/Comp 1  Polarity   */
 #define TIM_CCER_CC1NE	BIT(2)	/* Capt/Comp 1N out Ena    */
 #define TIM_CCER_CC1NE	BIT(2)	/* Capt/Comp 1N out Ena    */
 #define TIM_CCER_CC1NP	BIT(3)	/* Capt/Comp 1N Polarity   */
 #define TIM_CCER_CC1NP	BIT(3)	/* Capt/Comp 1N Polarity   */
 #define TIM_CCER_CC2E	BIT(4)	/* Capt/Comp 2  out Ena    */
 #define TIM_CCER_CC2E	BIT(4)	/* Capt/Comp 2  out Ena    */
+#define TIM_CCER_CC2P	BIT(5)	/* Capt/Comp 2  Polarity   */
 #define TIM_CCER_CC3E	BIT(8)	/* Capt/Comp 3  out Ena    */
 #define TIM_CCER_CC3E	BIT(8)	/* Capt/Comp 3  out Ena    */
+#define TIM_CCER_CC3P	BIT(9)	/* Capt/Comp 3  Polarity   */
 #define TIM_CCER_CC4E	BIT(12)	/* Capt/Comp 4  out Ena    */
 #define TIM_CCER_CC4E	BIT(12)	/* Capt/Comp 4  out Ena    */
+#define TIM_CCER_CC4P	BIT(13)	/* Capt/Comp 4  Polarity   */
 #define TIM_CCER_CCXE	(BIT(0) | BIT(4) | BIT(8) | BIT(12))
 #define TIM_CCER_CCXE	(BIT(0) | BIT(4) | BIT(8) | BIT(12))
 #define TIM_BDTR_BKE	BIT(12) /* Break input enable	   */
 #define TIM_BDTR_BKE	BIT(12) /* Break input enable	   */
 #define TIM_BDTR_BKP	BIT(13) /* Break input polarity	   */
 #define TIM_BDTR_BKP	BIT(13) /* Break input polarity	   */
@@ -56,8 +78,11 @@
 #define TIM_BDTR_BK2F	(BIT(20) | BIT(21) | BIT(22) | BIT(23))
 #define TIM_BDTR_BK2F	(BIT(20) | BIT(21) | BIT(22) | BIT(23))
 #define TIM_BDTR_BK2E	BIT(24) /* Break 2 input enable	   */
 #define TIM_BDTR_BK2E	BIT(24) /* Break 2 input enable	   */
 #define TIM_BDTR_BK2P	BIT(25) /* Break 2 input polarity  */
 #define TIM_BDTR_BK2P	BIT(25) /* Break 2 input polarity  */
+#define TIM_DCR_DBA	GENMASK(4, 0)	/* DMA base addr */
+#define TIM_DCR_DBL	GENMASK(12, 8)	/* DMA burst len */
 
 
 #define MAX_TIM_PSC		0xFFFF
 #define MAX_TIM_PSC		0xFFFF
+#define MAX_TIM_ICPSC		0x3
 #define TIM_CR2_MMS_SHIFT	4
 #define TIM_CR2_MMS_SHIFT	4
 #define TIM_CR2_MMS2_SHIFT	20
 #define TIM_CR2_MMS2_SHIFT	20
 #define TIM_SMCR_TS_SHIFT	4
 #define TIM_SMCR_TS_SHIFT	4
@@ -65,9 +90,54 @@
 #define TIM_BDTR_BKF_SHIFT	16
 #define TIM_BDTR_BKF_SHIFT	16
 #define TIM_BDTR_BK2F_SHIFT	20
 #define TIM_BDTR_BK2F_SHIFT	20
 
 
+enum stm32_timers_dmas {
+	STM32_TIMERS_DMA_CH1,
+	STM32_TIMERS_DMA_CH2,
+	STM32_TIMERS_DMA_CH3,
+	STM32_TIMERS_DMA_CH4,
+	STM32_TIMERS_DMA_UP,
+	STM32_TIMERS_DMA_TRIG,
+	STM32_TIMERS_DMA_COM,
+	STM32_TIMERS_MAX_DMAS,
+};
+
+/**
+ * struct stm32_timers_dma - STM32 timer DMA handling.
+ * @completion:		end of DMA transfer completion
+ * @phys_base:		control registers physical base address
+ * @lock:		protect DMA access
+ * @chan:		DMA channel in use
+ * @chans:		DMA channels available for this timer instance
+ */
+struct stm32_timers_dma {
+	struct completion completion;
+	phys_addr_t phys_base;
+	struct mutex lock;
+	struct dma_chan *chan;
+	struct dma_chan *chans[STM32_TIMERS_MAX_DMAS];
+};
+
 struct stm32_timers {
 struct stm32_timers {
 	struct clk *clk;
 	struct clk *clk;
 	struct regmap *regmap;
 	struct regmap *regmap;
 	u32 max_arr;
 	u32 max_arr;
+	struct stm32_timers_dma dma; /* Only to be used by the parent */
 };
 };
+
+#if IS_REACHABLE(CONFIG_MFD_STM32_TIMERS)
+int stm32_timers_dma_burst_read(struct device *dev, u32 *buf,
+				enum stm32_timers_dmas id, u32 reg,
+				unsigned int num_reg, unsigned int bursts,
+				unsigned long tmo_ms);
+#else
+static inline int stm32_timers_dma_burst_read(struct device *dev, u32 *buf,
+					      enum stm32_timers_dmas id,
+					      u32 reg,
+					      unsigned int num_reg,
+					      unsigned int bursts,
+					      unsigned long tmo_ms)
+{
+	return -ENODEV;
+}
+#endif
 #endif
 #endif

+ 0 - 21
include/linux/mfd/syscon/exynos4-pmu.h

@@ -1,21 +0,0 @@
-/*
- * Copyright (C) 2015 Samsung Electronics Co., Ltd.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef _LINUX_MFD_SYSCON_PMU_EXYNOS4_H_
-#define _LINUX_MFD_SYSCON_PMU_EXYNOS4_H_
-
-/* Exynos4 PMU register definitions */
-
-/* MIPI_PHYn_CONTROL register offset: n = 0..1 */
-#define EXYNOS4_MIPI_PHY_CONTROL(n)	(0x710 + (n) * 4)
-#define EXYNOS4_MIPI_PHY_ENABLE		(1 << 0)
-#define EXYNOS4_MIPI_PHY_SRESETN	(1 << 1)
-#define EXYNOS4_MIPI_PHY_MRESETN	(1 << 2)
-#define EXYNOS4_MIPI_PHY_RESET_MASK	(3 << 1)
-
-#endif /* _LINUX_MFD_SYSCON_PMU_EXYNOS4_H_ */

+ 0 - 19
include/linux/mfd/syscon/exynos5-pmu.h

@@ -1,19 +0,0 @@
-/*
- * Exynos5 SoC series Power Management Unit (PMU) register offsets
- * and bit definitions.
- *
- * Copyright (C) 2014 Samsung Electronics Co., Ltd.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef _LINUX_MFD_SYSCON_PMU_EXYNOS5_H_
-#define _LINUX_MFD_SYSCON_PMU_EXYNOS5_H_
-
-#define EXYNOS5_PHY_ENABLE			BIT(0)
-#define EXYNOS5_MIPI_PHY_S_RESETN		BIT(1)
-#define EXYNOS5_MIPI_PHY_M_RESETN		BIT(2)
-
-#endif /* _LINUX_MFD_SYSCON_PMU_EXYNOS5_H_ */

+ 2 - 2
include/linux/mfd/tps65218.h

@@ -205,10 +205,10 @@ enum tps65218_regulator_id {
 	TPS65218_DCDC_4,
 	TPS65218_DCDC_4,
 	TPS65218_DCDC_5,
 	TPS65218_DCDC_5,
 	TPS65218_DCDC_6,
 	TPS65218_DCDC_6,
-	/* LS's */
-	TPS65218_LS_3,
 	/* LDOs */
 	/* LDOs */
 	TPS65218_LDO_1,
 	TPS65218_LDO_1,
+	/* LS's */
+	TPS65218_LS_3,
 };
 };
 
 
 #define TPS65218_MAX_REG_ID		TPS65218_LDO_1
 #define TPS65218_MAX_REG_ID		TPS65218_LDO_1

+ 3 - 14
include/linux/mfd/tps68470.h

@@ -1,17 +1,6 @@
-/*
- * Copyright (c) 2017 Intel Corporation
- *
- * Functions to access TPS68470 power management chip.
- *
- * 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 version 2.
- *
- * This program is distributed "as is" WITHOUT ANY WARRANTY of any
- * kind, whether express or implied; without even the implied warranty
- * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright (C) 2017 Intel Corporation */
+/* Functions to access TPS68470 power management chip. */
 
 
 #ifndef __LINUX_MFD_TPS68470_H
 #ifndef __LINUX_MFD_TPS68470_H
 #define __LINUX_MFD_TPS68470_H
 #define __LINUX_MFD_TPS68470_H