aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2016-10-07 11:35:35 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2016-10-07 11:35:35 -0400
commitd042380886fb2fc6c4b0fcfe1214ba473769a8e9 (patch)
tree61e29ff167e0f83f67930ee9911062415030e1ef
parent3477d168ba61c5b0ca42d3d4642f3463609a5417 (diff)
parentb8d336ed90f541097a2ce583be430bb3e895dfbd (diff)
Merge tag 'mfd-for-linus-4.9' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd
Pull MFD updates from Lee Jones: "Core framework: - Add the MFD bindings doc to MAINTAINERS New drivers: - X-Powers AC100 Audio CODEC and RTC - TI LP873x PMIC - Rockchip RK808 PMIC - Samsung Exynos Low Power Audio New device support: - Add support for STMPE1600 variant to stmpe - Add support for PM8018 PMIC to pm8921-core - Add support for AXP806 PMIC in axp20x - Add support for AXP209 GPIO in axp20x New functionality: - Add support for Reset to all STMPE variants - Add support for MKBP event support to cros_ec - Add support for USB to intel_soc_pmic_bxtwc - Add support for IRQs and Power Button to tps65217 Fix-ups: - Clean-up defunct author emails (da9063, max14577) - Kconfig fixups (wm8350-i2c, as37220 - Constify (altera-a10sr, sm501) - Supply PCI IDs (intel-lpss-pci) - Improve clocking (qcom_rpm) - Fix IRQ probing (ucb1x00-core) - Ensure fault log is cleared (da9052) - Remove NO_IRQ check (ucb1x00-core) - Supply I2C properties (intel-lpss-acpi, intel-lpss-pci) - Non standard declaration (tps65217, max8997-irq) - Remove unused code (lp873x, db8500-prcmu, ab8500-debugfs, cros_ec_spi) - Make non-modular (altera-a10sr, intel_msic, smsc-ece1099, sun6i-prcm, twl-core) - OF bindings (ac100, stmpe, qcom-pm8xxx, qcom-rpm, rk808, axp20x, lp873x, exynos5433-lpass, act8945a, aspeed-scu, twl6040, arizona) Bugfixes: - Release OF pointer (qcom_rpm) - Avoid double shifting in suspend/resume (88pm80x) - Fix 'defined but not used' error (exynos-lpass) - Fix 'sleeping whilst attomic' (atmel-hlcdc)" * tag 'mfd-for-linus-4.9' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd: (69 commits) mfd: arizona: Handle probe deferral for reset GPIO mfd: arizona: Remove arizona_of_get_named_gpio helper function mfd: arizona: Add DT options for max_channels_clocked and PDM speaker config mfd: twl6040: Register child device for twl6040-pdmclk mfd: cros_ec_spi: Remove unused variable 'request' mfd: omap-usb-host: Return value is not 'const int' mfd: ab8500-debugfs: Remove 'weak' function suspend_test_wake_cause_interrupt_is_mine() mfd: ab8500-debugfs: Remove ab8500_dump_all_banks_to_mem() mfd: db8500-prcmu: Remove unused *prcmu_set_ddr_opp() calls mfd: ab8500-debugfs: Prevent initialised field from being over-written mfd: max8997-irq: 'inline' should be at the beginning of the declaration mfd: rk808: Fix RK818_IRQ_DISCHG_ILIM initializer mfd: tps65217: Fix nonstandard declaration mfd: lp873x: Remove unused mutex lock from struct lp873x mfd: atmel-hlcdc: Do not sleep in atomic context mfd: exynos-lpass: Mark PM functions as __maybe_unused mfd: intel-lpss: Add default I2C device properties for Apollo Lake mfd: twl-core: Make it explicitly non-modular mfd: sun6i-prcm: Make it explicitly non-modular mfd: smsc-ece1099: Make it explicitly non-modular ...
-rw-r--r--Documentation/devicetree/bindings/mfd/ac100.txt54
-rw-r--r--Documentation/devicetree/bindings/mfd/act8945a.txt22
-rw-r--r--Documentation/devicetree/bindings/mfd/arizona.txt18
-rw-r--r--Documentation/devicetree/bindings/mfd/aspeed-scu.txt18
-rw-r--r--Documentation/devicetree/bindings/mfd/axp20x.txt28
-rw-r--r--Documentation/devicetree/bindings/mfd/lp873x.txt59
-rw-r--r--Documentation/devicetree/bindings/mfd/qcom-pm8xxx.txt1
-rw-r--r--Documentation/devicetree/bindings/mfd/qcom-rpm.txt15
-rw-r--r--Documentation/devicetree/bindings/mfd/rk808.txt37
-rw-r--r--Documentation/devicetree/bindings/mfd/samsung,exynos5433-lpass.txt70
-rw-r--r--Documentation/devicetree/bindings/mfd/twl6040.txt1
-rw-r--r--MAINTAINERS1
-rw-r--r--drivers/input/keyboard/cros_ec_keyb.c135
-rw-r--r--drivers/mfd/Kconfig26
-rw-r--r--drivers/mfd/Makefile3
-rw-r--r--drivers/mfd/ab8500-debugfs.c114
-rw-r--r--drivers/mfd/ac100.c137
-rw-r--r--drivers/mfd/act8945a.c1
-rw-r--r--drivers/mfd/altera-a10sr.c16
-rw-r--r--drivers/mfd/arizona-core.c113
-rw-r--r--drivers/mfd/atmel-hlcdc.c5
-rw-r--r--drivers/mfd/axp20x-rsb.c1
-rw-r--r--drivers/mfd/axp20x.c75
-rw-r--r--drivers/mfd/cros_ec.c58
-rw-r--r--drivers/mfd/cros_ec_spi.c2
-rw-r--r--drivers/mfd/da9052-core.c51
-rw-r--r--drivers/mfd/da9063-core.c7
-rw-r--r--drivers/mfd/da9063-i2c.c2
-rw-r--r--drivers/mfd/da9063-irq.c2
-rw-r--r--drivers/mfd/db8500-prcmu.c19
-rw-r--r--drivers/mfd/dm355evm_msp.c17
-rw-r--r--drivers/mfd/exynos-lpass.c185
-rw-r--r--drivers/mfd/intel-lpss-acpi.c14
-rw-r--r--drivers/mfd/intel-lpss-pci.c51
-rw-r--r--drivers/mfd/intel_msic.c9
-rw-r--r--drivers/mfd/intel_soc_pmic_bxtwc.c23
-rw-r--r--drivers/mfd/lp873x.c2
-rw-r--r--drivers/mfd/max14577.c4
-rw-r--r--drivers/mfd/max8997-irq.c2
-rw-r--r--drivers/mfd/omap-usb-host.c2
-rw-r--r--drivers/mfd/pm8921-core.c1
-rw-r--r--drivers/mfd/qcom_rpm.c72
-rw-r--r--drivers/mfd/rk808.c226
-rw-r--r--drivers/mfd/rtsx_usb.c10
-rw-r--r--drivers/mfd/sm501.c2
-rw-r--r--drivers/mfd/smsc-ece1099.c11
-rw-r--r--drivers/mfd/sun6i-prcm.c8
-rw-r--r--drivers/mfd/tps65217.c205
-rw-r--r--drivers/mfd/twl-core.c9
-rw-r--r--drivers/mfd/twl6040.c6
-rw-r--r--drivers/mfd/ucb1x00-core.c6
-rw-r--r--drivers/platform/chrome/cros_ec_proto.c92
-rw-r--r--drivers/regulator/Kconfig4
-rw-r--r--drivers/regulator/axp20x-regulator.c118
-rw-r--r--drivers/regulator/qcom_rpm-regulator.c66
-rw-r--r--drivers/regulator/rk808-regulator.c143
-rw-r--r--drivers/rtc/Kconfig14
-rw-r--r--drivers/rtc/Makefile1
-rw-r--r--drivers/rtc/rtc-ac100.c627
-rw-r--r--drivers/rtc/rtc-pm8xxx.c1
-rw-r--r--include/dt-bindings/mfd/qcom-rpm.h22
-rw-r--r--include/linux/mfd/88pm80x.h4
-rw-r--r--include/linux/mfd/abx500/ab8500.h2
-rw-r--r--include/linux/mfd/ac100.h178
-rw-r--r--include/linux/mfd/arizona/core.h12
-rw-r--r--include/linux/mfd/axp20x.h60
-rw-r--r--include/linux/mfd/cros_ec.h18
-rw-r--r--include/linux/mfd/cros_ec_commands.h34
-rw-r--r--include/linux/mfd/da9063/core.h4
-rw-r--r--include/linux/mfd/da9063/pdata.h4
-rw-r--r--include/linux/mfd/da9063/registers.h4
-rw-r--r--include/linux/mfd/db8500-prcmu.h6
-rw-r--r--include/linux/mfd/dbx500-prcmu.h9
-rw-r--r--include/linux/mfd/lp873x.h1
-rw-r--r--include/linux/mfd/max14577-private.h2
-rw-r--r--include/linux/mfd/max14577.h2
-rw-r--r--include/linux/mfd/rk808.h154
-rw-r--r--include/linux/mfd/syscon/exynos5-pmu.h4
-rw-r--r--include/linux/mfd/tps65217.h12
-rw-r--r--include/linux/mfd/twl6040.h2
80 files changed, 3111 insertions, 445 deletions
diff --git a/Documentation/devicetree/bindings/mfd/ac100.txt b/Documentation/devicetree/bindings/mfd/ac100.txt
new file mode 100644
index 000000000000..b8ef00667599
--- /dev/null
+++ b/Documentation/devicetree/bindings/mfd/ac100.txt
@@ -0,0 +1,54 @@
1X-Powers AC100 Codec/RTC IC Device Tree bindings
2
3AC100 is a audio codec and RTC subsystem combo IC. The 2 parts are
4separated, including power supplies and interrupt lines, but share
5a common register address space and host interface.
6
7Required properties:
8- compatible: "x-powers,ac100"
9- reg: The I2C slave address or RSB hardware address for the chip
10- sub-nodes:
11 - codec
12 - compatible: "x-powers,ac100-codec"
13 - interrupt-parent: The parent interrupt controller
14 - interrupts: SoC NMI / GPIO interrupt connected to the
15 IRQ_AUDIO pin
16 - #clock-cells: Shall be 0
17 - clock-output-names: "4M_adda"
18
19 - see clock/clock-bindings.txt for common clock bindings
20
21 - rtc
22 - compatible: "x-powers,ac100-rtc"
23 - interrupt-parent: The parent interrupt controller
24 - interrupts: SoC NMI / GPIO interrupt connected to the
25 IRQ_RTC pin
26 - clocks: A phandle to the codec's "4M_adda" clock
27 - #clock-cells: Shall be 1
28 - clock-output-names: "cko1_rtc", "cko2_rtc", "cko3_rtc"
29
30 - see clock/clock-bindings.txt for common clock bindings
31
32Example:
33
34ac100: codec@e89 {
35 compatible = "x-powers,ac100";
36 reg = <0xe89>;
37
38 ac100_codec: codec {
39 compatible = "x-powers,ac100-codec";
40 interrupt-parent = <&r_pio>;
41 interrupts = <0 9 IRQ_TYPE_LEVEL_LOW>; /* PL9 */
42 #clock-cells = <0>;
43 clock-output-names = "4M_adda";
44 };
45
46 ac100_rtc: rtc {
47 compatible = "x-powers,ac100-rtc";
48 interrupt-parent = <&nmi_intc>;
49 interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
50 clocks = <&ac100_codec>;
51 #clock-cells = <1>;
52 clock-output-names = "cko1_rtc", "cko2_rtc", "cko3_rtc";
53 };
54};
diff --git a/Documentation/devicetree/bindings/mfd/act8945a.txt b/Documentation/devicetree/bindings/mfd/act8945a.txt
index f71283055685..462819ac3da8 100644
--- a/Documentation/devicetree/bindings/mfd/act8945a.txt
+++ b/Documentation/devicetree/bindings/mfd/act8945a.txt
@@ -14,13 +14,6 @@ Example:
14 reg = <0x5b>; 14 reg = <0x5b>;
15 status = "okay"; 15 status = "okay";
16 16
17 pinctrl-names = "default";
18 pinctrl-0 = <&pinctrl_charger_chglev>;
19 active-semi,chglev-gpio = <&pioA 12 GPIO_ACTIVE_HIGH>;
20 active-semi,input-voltage-threshold-microvolt = <6600>;
21 active-semi,precondition-timeout = <40>;
22 active-semi,total-timeout = <3>;
23
24 active-semi,vsel-high; 17 active-semi,vsel-high;
25 18
26 regulators { 19 regulators {
@@ -73,4 +66,19 @@ Example:
73 regulator-always-on; 66 regulator-always-on;
74 }; 67 };
75 }; 68 };
69
70 charger {
71 compatible = "active-semi,act8945a-charger";
72 pinctrl-names = "default";
73 pinctrl-0 = <&pinctrl_charger_chglev &pinctrl_charger_lbo &pinctrl_charger_irq>;
74 interrupt-parent = <&pioA>;
75 interrupts = <45 GPIO_ACTIVE_LOW>;
76
77 active-semi,chglev-gpios = <&pioA 12 GPIO_ACTIVE_HIGH>;
78 active-semi,lbo-gpios = <&pioA 72 GPIO_ACTIVE_LOW>;
79 active-semi,input-voltage-threshold-microvolt = <6600>;
80 active-semi,precondition-timeout = <40>;
81 active-semi,total-timeout = <3>;
82 status = "okay";
83 };
76 }; 84 };
diff --git a/Documentation/devicetree/bindings/mfd/arizona.txt b/Documentation/devicetree/bindings/mfd/arizona.txt
index a6e2ea41160c..8f2e2822238d 100644
--- a/Documentation/devicetree/bindings/mfd/arizona.txt
+++ b/Documentation/devicetree/bindings/mfd/arizona.txt
@@ -85,6 +85,24 @@ Optional properties:
85 present, the number of values should be less than or equal to the 85 present, the number of values should be less than or equal to the
86 number of inputs, unspecified inputs will use the chip default. 86 number of inputs, unspecified inputs will use the chip default.
87 87
88 - wlf,max-channels-clocked : The maximum number of channels to be clocked on
89 each AIF, useful for I2S systems with multiple data lines being mastered.
90 Specify one cell for each AIF to be configured, specify zero for AIFs that
91 should be handled normally.
92 If present, number of cells must be less than or equal to the number of
93 AIFs. If less than the number of AIFs, for cells that have not been
94 specified the corresponding AIFs will be treated as default setting.
95
96 - wlf,spk-fmt : PDM speaker data format, must contain 2 cells (OUT5 and OUT6).
97 See the datasheet for values.
98 The second cell is ignored for codecs that do not have OUT6 (wm5102, wm8997,
99 wm8998, wm1814)
100
101 - wlf,spk-mute : PDM speaker mute setting, must contain 2 cells (OUT5 and OUT6).
102 See the datasheet for values.
103 The second cell is ignored for codecs that do not have OUT6 (wm5102, wm8997,
104 wm8998, wm1814)
105
88 - DCVDD-supply, MICVDD-supply : Power supplies, only need to be specified if 106 - DCVDD-supply, MICVDD-supply : Power supplies, only need to be specified if
89 they are being externally supplied. As covered in 107 they are being externally supplied. As covered in
90 Documentation/devicetree/bindings/regulator/regulator.txt 108 Documentation/devicetree/bindings/regulator/regulator.txt
diff --git a/Documentation/devicetree/bindings/mfd/aspeed-scu.txt b/Documentation/devicetree/bindings/mfd/aspeed-scu.txt
new file mode 100644
index 000000000000..4fc5b83726d6
--- /dev/null
+++ b/Documentation/devicetree/bindings/mfd/aspeed-scu.txt
@@ -0,0 +1,18 @@
1The Aspeed System Control Unit manages the global behaviour of the SoC,
2configuring elements such as clocks, pinmux, and reset.
3
4Required properties:
5- compatible: One of:
6 "aspeed,ast2400-scu", "syscon", "simple-mfd"
7 "aspeed,g4-scu", "syscon", "simple-mfd"
8 "aspeed,ast2500-scu", "syscon", "simple-mfd"
9 "aspeed,g5-scu", "syscon", "simple-mfd"
10
11- reg: contains the offset and length of the SCU memory region
12
13Example:
14
15syscon: syscon@1e6e2000 {
16 compatible = "aspeed,ast2400-scu", "syscon", "simple-mfd";
17 reg = <0x1e6e2000 0x1a8>;
18};
diff --git a/Documentation/devicetree/bindings/mfd/axp20x.txt b/Documentation/devicetree/bindings/mfd/axp20x.txt
index 585a95546288..8f3ad9ab4637 100644
--- a/Documentation/devicetree/bindings/mfd/axp20x.txt
+++ b/Documentation/devicetree/bindings/mfd/axp20x.txt
@@ -10,7 +10,8 @@ axp809 (X-Powers)
10 10
11Required properties: 11Required properties:
12- compatible: "x-powers,axp152", "x-powers,axp202", "x-powers,axp209", 12- compatible: "x-powers,axp152", "x-powers,axp202", "x-powers,axp209",
13 "x-powers,axp221", "x-powers,axp223", "x-powers,axp809" 13 "x-powers,axp221", "x-powers,axp223", "x-powers,axp806",
14 "x-powers,axp809"
14- reg: The I2C slave address or RSB hardware address for the AXP chip 15- reg: The I2C slave address or RSB hardware address for the AXP chip
15- interrupt-parent: The parent interrupt controller 16- interrupt-parent: The parent interrupt controller
16- interrupts: SoC NMI / GPIO interrupt connected to the PMIC's IRQ pin 17- interrupts: SoC NMI / GPIO interrupt connected to the PMIC's IRQ pin
@@ -47,7 +48,6 @@ Optional properties for DCDC regulators:
47 probably makes sense for HiFi audio related 48 probably makes sense for HiFi audio related
48 applications that aren't battery constrained. 49 applications that aren't battery constrained.
49 50
50
51AXP202/AXP209 regulators, type, and corresponding input supply names: 51AXP202/AXP209 regulators, type, and corresponding input supply names:
52 52
53Regulator Type Supply Name Notes 53Regulator Type Supply Name Notes
@@ -86,6 +86,30 @@ LDO_IO1 : LDO : ips-supply : GPIO 1
86RTC_LDO : LDO : ips-supply : always on 86RTC_LDO : LDO : ips-supply : always on
87DRIVEVBUS : Enable output : drivevbus-supply : external regulator 87DRIVEVBUS : Enable output : drivevbus-supply : external regulator
88 88
89AXP806 regulators, type, and corresponding input supply names:
90
91Regulator Type Supply Name Notes
92--------- ---- ----------- -----
93DCDCA : DC-DC buck : vina-supply : poly-phase capable
94DCDCB : DC-DC buck : vinb-supply : poly-phase capable
95DCDCC : DC-DC buck : vinc-supply : poly-phase capable
96DCDCD : DC-DC buck : vind-supply : poly-phase capable
97DCDCE : DC-DC buck : vine-supply : poly-phase capable
98ALDO1 : LDO : aldoin-supply : shared supply
99ALDO2 : LDO : aldoin-supply : shared supply
100ALDO3 : LDO : aldoin-supply : shared supply
101BLDO1 : LDO : bldoin-supply : shared supply
102BLDO2 : LDO : bldoin-supply : shared supply
103BLDO3 : LDO : bldoin-supply : shared supply
104BLDO4 : LDO : bldoin-supply : shared supply
105CLDO1 : LDO : cldoin-supply : shared supply
106CLDO2 : LDO : cldoin-supply : shared supply
107CLDO3 : LDO : cldoin-supply : shared supply
108SW : On/Off Switch : swin-supply
109
110Additionally, the AXP806 DC-DC regulators support poly-phase arrangements
111for higher output current. The possible groupings are: A+B, A+B+C, D+E.
112
89AXP809 regulators, type, and corresponding input supply names: 113AXP809 regulators, type, and corresponding input supply names:
90 114
91Regulator Type Supply Name Notes 115Regulator Type Supply Name Notes
diff --git a/Documentation/devicetree/bindings/mfd/lp873x.txt b/Documentation/devicetree/bindings/mfd/lp873x.txt
new file mode 100644
index 000000000000..52766c2035f7
--- /dev/null
+++ b/Documentation/devicetree/bindings/mfd/lp873x.txt
@@ -0,0 +1,59 @@
1TI LP873X PMIC MFD driver
2
3Required properties:
4 - compatible: "ti,lp8732", "ti,lp8733"
5 - reg: I2C slave address.
6 - gpio-controller: Marks the device node as a GPIO Controller.
7 - #gpio-cells: Should be two. The first cell is the pin number and
8 the second cell is used to specify flags.
9 See ../gpio/gpio.txt for more information.
10 - regulators: List of child nodes that specify the regulator
11 initialization data.
12Example:
13
14pmic: lp8733@60 {
15 compatible = "ti,lp8733";
16 reg = <0x60>;
17 gpio-controller;
18 #gpio-cells = <2>;
19
20 regulators {
21 lp8733_buck0: buck0 {
22 regulator-name = "lp8733-buck0";
23 regulator-min-microvolt = <800000>;
24 regulator-max-microvolt = <1400000>;
25 regulator-min-microamp = <1500000>;
26 regulator-max-microamp = <4000000>;
27 regulator-ramp-delay = <10000>;
28 regulator-always-on;
29 regulator-boot-on;
30 };
31
32 lp8733_buck1: buck1 {
33 regulator-name = "lp8733-buck1";
34 regulator-min-microvolt = <800000>;
35 regulator-max-microvolt = <1400000>;
36 regulator-min-microamp = <1500000>;
37 regulator-max-microamp = <4000000>;
38 regulator-ramp-delay = <10000>;
39 regulator-boot-on;
40 regulator-always-on;
41 };
42
43 lp8733_ldo0: ldo0 {
44 regulator-name = "lp8733-ldo0";
45 regulator-min-microvolt = <800000>;
46 regulator-max-microvolt = <3000000>;
47 regulator-boot-on;
48 regulator-always-on;
49 };
50
51 lp8733_ldo1: ldo1 {
52 regulator-name = "lp8733-ldo1";
53 regulator-min-microvolt = <800000>;
54 regulator-max-microvolt = <3000000>;
55 regulator-always-on;
56 regulator-boot-on;
57 };
58 };
59};
diff --git a/Documentation/devicetree/bindings/mfd/qcom-pm8xxx.txt b/Documentation/devicetree/bindings/mfd/qcom-pm8xxx.txt
index f24f33409164..37a088f9a648 100644
--- a/Documentation/devicetree/bindings/mfd/qcom-pm8xxx.txt
+++ b/Documentation/devicetree/bindings/mfd/qcom-pm8xxx.txt
@@ -62,6 +62,7 @@ The below bindings specify the set of valid subnodes.
62 "qcom,pm8058-rtc" 62 "qcom,pm8058-rtc"
63 "qcom,pm8921-rtc" 63 "qcom,pm8921-rtc"
64 "qcom,pm8941-rtc" 64 "qcom,pm8941-rtc"
65 "qcom,pm8018-rtc"
65 66
66- reg: 67- reg:
67 Usage: required 68 Usage: required
diff --git a/Documentation/devicetree/bindings/mfd/qcom-rpm.txt b/Documentation/devicetree/bindings/mfd/qcom-rpm.txt
index b98b291a31ba..485bc59fcc48 100644
--- a/Documentation/devicetree/bindings/mfd/qcom-rpm.txt
+++ b/Documentation/devicetree/bindings/mfd/qcom-rpm.txt
@@ -13,6 +13,7 @@ frequencies.
13 "qcom,rpm-msm8660" 13 "qcom,rpm-msm8660"
14 "qcom,rpm-msm8960" 14 "qcom,rpm-msm8960"
15 "qcom,rpm-ipq8064" 15 "qcom,rpm-ipq8064"
16 "qcom,rpm-mdm9615"
16 17
17- reg: 18- reg:
18 Usage: required 19 Usage: required
@@ -59,6 +60,7 @@ Regulator nodes are identified by their compatible:
59 "qcom,rpm-pm8058-regulators" 60 "qcom,rpm-pm8058-regulators"
60 "qcom,rpm-pm8901-regulators" 61 "qcom,rpm-pm8901-regulators"
61 "qcom,rpm-pm8921-regulators" 62 "qcom,rpm-pm8921-regulators"
63 "qcom,rpm-pm8018-regulators"
62 64
63- vdd_l0_l1_lvs-supply: 65- vdd_l0_l1_lvs-supply:
64- vdd_l2_l11_l12-supply: 66- vdd_l2_l11_l12-supply:
@@ -137,6 +139,15 @@ Regulator nodes are identified by their compatible:
137 Definition: reference to regulator supplying the input pin, as 139 Definition: reference to regulator supplying the input pin, as
138 described in the data sheet 140 described in the data sheet
139 141
142- vin_lvs1-supply:
143- vdd_l7-supply:
144- vdd_l8-supply:
145- vdd_l9_l10_l11_l12-supply:
146 Usage: optional (pm8018 only)
147 Value type: <phandle>
148 Definition: reference to regulator supplying the input pin, as
149 described in the data sheet
150
140The regulator node houses sub-nodes for each regulator within the device. Each 151The regulator node houses sub-nodes for each regulator within the device. Each
141sub-node is identified using the node's name, with valid values listed for each 152sub-node is identified using the node's name, with valid values listed for each
142of the pmics below. 153of the pmics below.
@@ -156,6 +167,10 @@ pm8921:
156 l29, lvs1, lvs2, lvs3, lvs4, lvs5, lvs6, lvs7, usb-switch, hdmi-switch, 167 l29, lvs1, lvs2, lvs3, lvs4, lvs5, lvs6, lvs7, usb-switch, hdmi-switch,
157 ncp 168 ncp
158 169
170pm8018:
171 s1, s2, s3, s4, s5, , l1, l2, l3, l4, l5, l6, l7, l8, l9, l10, l11,
172 l12, l14, lvs1
173
159The content of each sub-node is defined by the standard binding for regulators - 174The content of each sub-node is defined by the standard binding for regulators -
160see regulator.txt - with additional custom properties described below: 175see regulator.txt - with additional custom properties described below:
161 176
diff --git a/Documentation/devicetree/bindings/mfd/rk808.txt b/Documentation/devicetree/bindings/mfd/rk808.txt
index 4ca6aab4273a..9636ae8d8d41 100644
--- a/Documentation/devicetree/bindings/mfd/rk808.txt
+++ b/Documentation/devicetree/bindings/mfd/rk808.txt
@@ -1,7 +1,11 @@
1RK808 Power Management Integrated Circuit 1RK8XX Power Management Integrated Circuit
2
3The rk8xx family current members:
4rk808
5rk818
2 6
3Required properties: 7Required properties:
4- compatible: "rockchip,rk808" 8- compatible: "rockchip,rk808", "rockchip,rk818"
5- reg: I2C slave address 9- reg: I2C slave address
6- interrupt-parent: The parent interrupt controller. 10- interrupt-parent: The parent interrupt controller.
7- interrupts: the interrupt outputs of the controller. 11- interrupts: the interrupt outputs of the controller.
@@ -13,6 +17,8 @@ Optional properties:
13 default output clock name 17 default output clock name
14- rockchip,system-power-controller: Telling whether or not this pmic is controlling 18- rockchip,system-power-controller: Telling whether or not this pmic is controlling
15 the system power. 19 the system power.
20
21Optional RK808 properties:
16- vcc1-supply: The input supply for DCDC_REG1 22- vcc1-supply: The input supply for DCDC_REG1
17- vcc2-supply: The input supply for DCDC_REG2 23- vcc2-supply: The input supply for DCDC_REG2
18- vcc3-supply: The input supply for DCDC_REG3 24- vcc3-supply: The input supply for DCDC_REG3
@@ -29,7 +35,20 @@ Optional properties:
29 the gpio controller. If DVS GPIOs aren't present, voltage changes will happen 35 the gpio controller. If DVS GPIOs aren't present, voltage changes will happen
30 very quickly with no slow ramp time. 36 very quickly with no slow ramp time.
31 37
32Regulators: All the regulators of RK808 to be instantiated shall be 38Optional RK818 properties:
39- vcc1-supply: The input supply for DCDC_REG1
40- vcc2-supply: The input supply for DCDC_REG2
41- vcc3-supply: The input supply for DCDC_REG3
42- vcc4-supply: The input supply for DCDC_REG4
43- boost-supply: The input supply for DCDC_BOOST
44- vcc6-supply: The input supply for LDO_REG1 and LDO_REG2
45- vcc7-supply: The input supply for LDO_REG3, LDO_REG5 and LDO_REG7
46- vcc8-supply: The input supply for LDO_REG4, LDO_REG6 and LDO_REG8
47- vcc9-supply: The input supply for LDO_REG9 and SWITCH_REG
48- h_5v-supply: The input supply for HDMI_SWITCH
49- usb-supply: The input supply for OTG_SWITCH
50
51Regulators: All the regulators of RK8XX to be instantiated shall be
33listed in a child node named 'regulators'. Each regulator is represented 52listed in a child node named 'regulators'. Each regulator is represented
34by a child node of the 'regulators' node. 53by a child node of the 'regulators' node.
35 54
@@ -48,6 +67,18 @@ number as described in RK808 datasheet.
48 - SWITCH_REGn 67 - SWITCH_REGn
49 - valid values for n are 1 to 2 68 - valid values for n are 1 to 2
50 69
70Following regulators of the RK818 PMIC block are supported. Note that
71the 'n' in regulator name, as in DCDC_REGn or LDOn, represents the DCDC or LDO
72number as described in RK818 datasheet.
73
74 - DCDC_REGn
75 - valid values for n are 1 to 4.
76 - LDO_REGn
77 - valid values for n are 1 to 9.
78 - SWITCH_REG
79 - HDMI_SWITCH
80 - OTG_SWITCH
81
51Standard regulator bindings are used inside regulator subnodes. Check 82Standard regulator bindings are used inside regulator subnodes. Check
52 Documentation/devicetree/bindings/regulator/regulator.txt 83 Documentation/devicetree/bindings/regulator/regulator.txt
53for more details 84for more details
diff --git a/Documentation/devicetree/bindings/mfd/samsung,exynos5433-lpass.txt b/Documentation/devicetree/bindings/mfd/samsung,exynos5433-lpass.txt
new file mode 100644
index 000000000000..c110e118b79f
--- /dev/null
+++ b/Documentation/devicetree/bindings/mfd/samsung,exynos5433-lpass.txt
@@ -0,0 +1,70 @@
1Samsung Exynos SoC Low Power Audio Subsystem (LPASS)
2
3Required properties:
4
5 - compatible : "samsung,exynos5433-lpass"
6 - reg : should contain the LPASS top SFR region location
7 and size
8 - samsung,pmu-syscon : the phandle to the Power Management Unit node
9 - #address-cells : should be 1
10 - #size-cells : should be 1
11 - ranges : must be present
12
13Each IP block of the Low Power Audio Subsystem should be specified as
14an optional sub-node. For "samsung,exynos5433-lpass" compatible this includes:
15UART, SLIMBUS, PCM, I2S, DMAC, Timers 0...4, VIC, WDT 0...1 devices.
16
17Bindings of the sub-nodes are described in:
18 ../serial/samsung_uart.txt
19 ../sound/samsung-i2s.txt
20 ../dma/arm-pl330.txt
21
22
23Example:
24
25audio-subsystem {
26 compatible = "samsung,exynos5433-lpass";
27 reg = <0x11400000 0x100>, <0x11500000 0x08>;
28 samsung,pmu-syscon = <&pmu_system_controller>;
29 #address-cells = <1>;
30 #size-cells = <1>;
31 ranges;
32
33 adma: adma@11420000 {
34 compatible = "arm,pl330", "arm,primecell";
35 reg = <0x11420000 0x1000>;
36 interrupts = <0 73 0>;
37 clocks = <&cmu_aud CLK_ACLK_DMAC>;
38 clock-names = "apb_pclk";
39 #dma-cells = <1>;
40 #dma-channels = <8>;
41 #dma-requests = <32>;
42 };
43
44 i2s0: i2s0@11440000 {
45 compatible = "samsung,exynos7-i2s";
46 reg = <0x11440000 0x100>;
47 dmas = <&adma 0 &adma 2>;
48 dma-names = "tx", "rx";
49 interrupts = <0 70 0>;
50 clocks = <&cmu_aud CLK_PCLK_AUD_I2S>,
51 <&cmu_aud CLK_SCLK_AUD_I2S>,
52 <&cmu_aud CLK_SCLK_I2S_BCLK>;
53 clock-names = "iis", "i2s_opclk0", "i2s_opclk1";
54 pinctrl-names = "default";
55 pinctrl-0 = <&i2s0_bus>;
56 status = "disabled";
57 };
58
59 serial_3: serial@11460000 {
60 compatible = "samsung,exynos5433-uart";
61 reg = <0x11460000 0x100>;
62 interrupts = <0 67 0>;
63 clocks = <&cmu_aud CLK_PCLK_AUD_UART>,
64 <&cmu_aud CLK_SCLK_AUD_UART>;
65 clock-names = "uart", "clk_uart_baud0";
66 pinctrl-names = "default";
67 pinctrl-0 = <&uart_aud_bus>;
68 status = "disabled";
69 };
70 };
diff --git a/Documentation/devicetree/bindings/mfd/twl6040.txt b/Documentation/devicetree/bindings/mfd/twl6040.txt
index e6afdfa3543d..9a98ee7c323d 100644
--- a/Documentation/devicetree/bindings/mfd/twl6040.txt
+++ b/Documentation/devicetree/bindings/mfd/twl6040.txt
@@ -12,6 +12,7 @@ Required properties:
12- interrupt-parent: The parent interrupt controller 12- interrupt-parent: The parent interrupt controller
13- gpio-controller: 13- gpio-controller:
14- #gpio-cells = <1>: twl6040 provides GPO lines. 14- #gpio-cells = <1>: twl6040 provides GPO lines.
15- #clock-cells = <0>; twl6040 is a provider of pdmclk which is used by McPDM
15- twl6040,audpwron-gpio: Power on GPIO line for the twl6040 16- twl6040,audpwron-gpio: Power on GPIO line for the twl6040
16 17
17- vio-supply: Regulator for the twl6040 VIO supply 18- vio-supply: Regulator for the twl6040 VIO supply
diff --git a/MAINTAINERS b/MAINTAINERS
index 40f462966564..58c520517107 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -8098,6 +8098,7 @@ MULTIFUNCTION DEVICES (MFD)
8098M: Lee Jones <lee.jones@linaro.org> 8098M: Lee Jones <lee.jones@linaro.org>
8099T: git git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd.git 8099T: git git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd.git
8100S: Supported 8100S: Supported
8101F: Documentation/devicetree/bindings/mfd/
8101F: drivers/mfd/ 8102F: drivers/mfd/
8102F: include/linux/mfd/ 8103F: include/linux/mfd/
8103 8104
diff --git a/drivers/input/keyboard/cros_ec_keyb.c b/drivers/input/keyboard/cros_ec_keyb.c
index 4b0878f35471..25943e9bc8bf 100644
--- a/drivers/input/keyboard/cros_ec_keyb.c
+++ b/drivers/input/keyboard/cros_ec_keyb.c
@@ -27,6 +27,7 @@
27#include <linux/input.h> 27#include <linux/input.h>
28#include <linux/interrupt.h> 28#include <linux/interrupt.h>
29#include <linux/kernel.h> 29#include <linux/kernel.h>
30#include <linux/notifier.h>
30#include <linux/platform_device.h> 31#include <linux/platform_device.h>
31#include <linux/slab.h> 32#include <linux/slab.h>
32#include <linux/input/matrix_keypad.h> 33#include <linux/input/matrix_keypad.h>
@@ -44,6 +45,7 @@
44 * @dev: Device pointer 45 * @dev: Device pointer
45 * @idev: Input device 46 * @idev: Input device
46 * @ec: Top level ChromeOS device to use to talk to EC 47 * @ec: Top level ChromeOS device to use to talk to EC
48 * @notifier: interrupt event notifier for transport devices
47 */ 49 */
48struct cros_ec_keyb { 50struct cros_ec_keyb {
49 unsigned int rows; 51 unsigned int rows;
@@ -57,6 +59,7 @@ struct cros_ec_keyb {
57 struct device *dev; 59 struct device *dev;
58 struct input_dev *idev; 60 struct input_dev *idev;
59 struct cros_ec_device *ec; 61 struct cros_ec_device *ec;
62 struct notifier_block notifier;
60}; 63};
61 64
62 65
@@ -146,67 +149,44 @@ static void cros_ec_keyb_process(struct cros_ec_keyb *ckdev,
146 input_sync(ckdev->idev); 149 input_sync(ckdev->idev);
147} 150}
148 151
149static int cros_ec_keyb_get_state(struct cros_ec_keyb *ckdev, uint8_t *kb_state) 152static int cros_ec_keyb_open(struct input_dev *dev)
150{
151 int ret = 0;
152 struct cros_ec_command *msg;
153
154 msg = kmalloc(sizeof(*msg) + ckdev->cols, GFP_KERNEL);
155 if (!msg)
156 return -ENOMEM;
157
158 msg->version = 0;
159 msg->command = EC_CMD_MKBP_STATE;
160 msg->insize = ckdev->cols;
161 msg->outsize = 0;
162
163 ret = cros_ec_cmd_xfer(ckdev->ec, msg);
164 if (ret < 0) {
165 dev_err(ckdev->dev, "Error transferring EC message %d\n", ret);
166 goto exit;
167 }
168
169 memcpy(kb_state, msg->data, ckdev->cols);
170exit:
171 kfree(msg);
172 return ret;
173}
174
175static irqreturn_t cros_ec_keyb_irq(int irq, void *data)
176{ 153{
177 struct cros_ec_keyb *ckdev = data; 154 struct cros_ec_keyb *ckdev = input_get_drvdata(dev);
178 struct cros_ec_device *ec = ckdev->ec;
179 int ret;
180 uint8_t kb_state[ckdev->cols];
181
182 if (device_may_wakeup(ec->dev))
183 pm_wakeup_event(ec->dev, 0);
184
185 ret = cros_ec_keyb_get_state(ckdev, kb_state);
186 if (ret >= 0)
187 cros_ec_keyb_process(ckdev, kb_state, ret);
188 else
189 dev_err(ckdev->dev, "failed to get keyboard state: %d\n", ret);
190 155
191 return IRQ_HANDLED; 156 return blocking_notifier_chain_register(&ckdev->ec->event_notifier,
157 &ckdev->notifier);
192} 158}
193 159
194static int cros_ec_keyb_open(struct input_dev *dev) 160static void cros_ec_keyb_close(struct input_dev *dev)
195{ 161{
196 struct cros_ec_keyb *ckdev = input_get_drvdata(dev); 162 struct cros_ec_keyb *ckdev = input_get_drvdata(dev);
197 struct cros_ec_device *ec = ckdev->ec;
198 163
199 return request_threaded_irq(ec->irq, NULL, cros_ec_keyb_irq, 164 blocking_notifier_chain_unregister(&ckdev->ec->event_notifier,
200 IRQF_TRIGGER_LOW | IRQF_ONESHOT, 165 &ckdev->notifier);
201 "cros_ec_keyb", ckdev);
202} 166}
203 167
204static void cros_ec_keyb_close(struct input_dev *dev) 168static int cros_ec_keyb_work(struct notifier_block *nb,
169 unsigned long queued_during_suspend, void *_notify)
205{ 170{
206 struct cros_ec_keyb *ckdev = input_get_drvdata(dev); 171 struct cros_ec_keyb *ckdev = container_of(nb, struct cros_ec_keyb,
207 struct cros_ec_device *ec = ckdev->ec; 172 notifier);
208 173
209 free_irq(ec->irq, ckdev); 174 if (ckdev->ec->event_data.event_type != EC_MKBP_EVENT_KEY_MATRIX)
175 return NOTIFY_DONE;
176 /*
177 * If EC is not the wake source, discard key state changes during
178 * suspend.
179 */
180 if (queued_during_suspend)
181 return NOTIFY_OK;
182 if (ckdev->ec->event_size != ckdev->cols) {
183 dev_err(ckdev->dev,
184 "Discarded incomplete key matrix event.\n");
185 return NOTIFY_OK;
186 }
187 cros_ec_keyb_process(ckdev, ckdev->ec->event_data.data.key_matrix,
188 ckdev->ec->event_size);
189 return NOTIFY_OK;
210} 190}
211 191
212/* 192/*
@@ -265,12 +245,8 @@ static int cros_ec_keyb_probe(struct platform_device *pdev)
265 if (!idev) 245 if (!idev)
266 return -ENOMEM; 246 return -ENOMEM;
267 247
268 if (!ec->irq) {
269 dev_err(dev, "no EC IRQ specified\n");
270 return -EINVAL;
271 }
272
273 ckdev->ec = ec; 248 ckdev->ec = ec;
249 ckdev->notifier.notifier_call = cros_ec_keyb_work;
274 ckdev->dev = dev; 250 ckdev->dev = dev;
275 dev_set_drvdata(dev, ckdev); 251 dev_set_drvdata(dev, ckdev);
276 252
@@ -311,54 +287,6 @@ static int cros_ec_keyb_probe(struct platform_device *pdev)
311 return 0; 287 return 0;
312} 288}
313 289
314#ifdef CONFIG_PM_SLEEP
315/* Clear any keys in the buffer */
316static void cros_ec_keyb_clear_keyboard(struct cros_ec_keyb *ckdev)
317{
318 uint8_t old_state[ckdev->cols];
319 uint8_t new_state[ckdev->cols];
320 unsigned long duration;
321 int i, ret;
322
323 /*
324 * Keep reading until we see that the scan state does not change.
325 * That indicates that we are done.
326 *
327 * Assume that the EC keyscan buffer is at most 32 deep.
328 */
329 duration = jiffies;
330 ret = cros_ec_keyb_get_state(ckdev, new_state);
331 for (i = 1; !ret && i < 32; i++) {
332 memcpy(old_state, new_state, sizeof(old_state));
333 ret = cros_ec_keyb_get_state(ckdev, new_state);
334 if (0 == memcmp(old_state, new_state, sizeof(old_state)))
335 break;
336 }
337 duration = jiffies - duration;
338 dev_info(ckdev->dev, "Discarded %d keyscan(s) in %dus\n", i,
339 jiffies_to_usecs(duration));
340}
341
342static int cros_ec_keyb_resume(struct device *dev)
343{
344 struct cros_ec_keyb *ckdev = dev_get_drvdata(dev);
345
346 /*
347 * When the EC is not a wake source, then it could not have caused the
348 * resume, so we clear the EC's key scan buffer. If the EC was a
349 * wake source (e.g. the lid is open and the user might press a key to
350 * wake) then the key scan buffer should be preserved.
351 */
352 if (!ckdev->ec->was_wake_device)
353 cros_ec_keyb_clear_keyboard(ckdev);
354
355 return 0;
356}
357
358#endif
359
360static SIMPLE_DEV_PM_OPS(cros_ec_keyb_pm_ops, NULL, cros_ec_keyb_resume);
361
362#ifdef CONFIG_OF 290#ifdef CONFIG_OF
363static const struct of_device_id cros_ec_keyb_of_match[] = { 291static const struct of_device_id cros_ec_keyb_of_match[] = {
364 { .compatible = "google,cros-ec-keyb" }, 292 { .compatible = "google,cros-ec-keyb" },
@@ -372,7 +300,6 @@ static struct platform_driver cros_ec_keyb_driver = {
372 .driver = { 300 .driver = {
373 .name = "cros-ec-keyb", 301 .name = "cros-ec-keyb",
374 .of_match_table = of_match_ptr(cros_ec_keyb_of_match), 302 .of_match_table = of_match_ptr(cros_ec_keyb_of_match),
375 .pm = &cros_ec_keyb_pm_ops,
376 }, 303 },
377}; 304};
378 305
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 2caf7e967390..c6df6442ba2b 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -50,7 +50,7 @@ config MFD_AS3711
50 Support for the AS3711 PMIC from AMS 50 Support for the AS3711 PMIC from AMS
51 51
52config MFD_AS3722 52config MFD_AS3722
53 bool "ams AS3722 Power Management IC" 53 tristate "ams AS3722 Power Management IC"
54 select MFD_CORE 54 select MFD_CORE
55 select REGMAP_I2C 55 select REGMAP_I2C
56 select REGMAP_IRQ 56 select REGMAP_IRQ
@@ -112,6 +112,16 @@ config MFD_BCM590XX
112 help 112 help
113 Support for the BCM590xx PMUs from Broadcom 113 Support for the BCM590xx PMUs from Broadcom
114 114
115config MFD_AC100
116 tristate "X-Powers AC100"
117 select MFD_CORE
118 depends on SUNXI_RSB
119 help
120 If you say Y here you get support for the X-Powers AC100 audio codec
121 IC.
122 This driver include only the core APIs. You have to select individual
123 components like codecs or RTC under the corresponding menus.
124
115config MFD_AXP20X 125config MFD_AXP20X
116 tristate 126 tristate
117 select MFD_CORE 127 select MFD_CORE
@@ -281,6 +291,14 @@ config MFD_DLN2
281 etc. must be enabled in order to use the functionality of 291 etc. must be enabled in order to use the functionality of
282 the device. 292 the device.
283 293
294config MFD_EXYNOS_LPASS
295 tristate "Samsung Exynos SoC Low Power Audio Subsystem"
296 select MFD_CORE
297 select REGMAP_MMIO
298 help
299 Select this option to enable support for Samsung Exynos Low Power
300 Audio Subsystem.
301
284config MFD_MC13XXX 302config MFD_MC13XXX
285 tristate 303 tristate
286 depends on (SPI_MASTER || I2C) 304 depends on (SPI_MASTER || I2C)
@@ -844,13 +862,13 @@ config MFD_RC5T583
844 different functionality of the device. 862 different functionality of the device.
845 863
846config MFD_RK808 864config MFD_RK808
847 tristate "Rockchip RK808 Power Management chip" 865 tristate "Rockchip RK808/RK818 Power Management Chip"
848 depends on I2C && OF 866 depends on I2C && OF
849 select MFD_CORE 867 select MFD_CORE
850 select REGMAP_I2C 868 select REGMAP_I2C
851 select REGMAP_IRQ 869 select REGMAP_IRQ
852 help 870 help
853 If you say yes here you get support for the RK808 871 If you say yes here you get support for the RK808 and RK818
854 Power Management chips. 872 Power Management chips.
855 This driver provides common support for accessing the device 873 This driver provides common support for accessing the device
856 through I2C interface. The device supports multiple sub-devices 874 through I2C interface. The device supports multiple sub-devices
@@ -1206,6 +1224,7 @@ config MFD_TPS65217
1206 depends on I2C 1224 depends on I2C
1207 select MFD_CORE 1225 select MFD_CORE
1208 select REGMAP_I2C 1226 select REGMAP_I2C
1227 select IRQ_DOMAIN
1209 help 1228 help
1210 If you say yes here you get support for the TPS65217 series of 1229 If you say yes here you get support for the TPS65217 series of
1211 Power Management / White LED chips. 1230 Power Management / White LED chips.
@@ -1555,6 +1574,7 @@ config MFD_WM8350
1555config MFD_WM8350_I2C 1574config MFD_WM8350_I2C
1556 bool "Wolfson Microelectronics WM8350 with I2C" 1575 bool "Wolfson Microelectronics WM8350 with I2C"
1557 select MFD_WM8350 1576 select MFD_WM8350
1577 select REGMAP_I2C
1558 depends on I2C=y 1578 depends on I2C=y
1559 help 1579 help
1560 The WM8350 is an integrated audio and power management 1580 The WM8350 is an integrated audio and power management
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index 2bf6a1ac7428..9834e669d985 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -13,6 +13,7 @@ obj-$(CONFIG_MFD_BCM590XX) += bcm590xx.o
13obj-$(CONFIG_MFD_CROS_EC) += cros_ec.o 13obj-$(CONFIG_MFD_CROS_EC) += cros_ec.o
14obj-$(CONFIG_MFD_CROS_EC_I2C) += cros_ec_i2c.o 14obj-$(CONFIG_MFD_CROS_EC_I2C) += cros_ec_i2c.o
15obj-$(CONFIG_MFD_CROS_EC_SPI) += cros_ec_spi.o 15obj-$(CONFIG_MFD_CROS_EC_SPI) += cros_ec_spi.o
16obj-$(CONFIG_MFD_EXYNOS_LPASS) += exynos-lpass.o
16 17
17rtsx_pci-objs := rtsx_pcr.o rts5209.o rts5229.o rtl8411.o rts5227.o rts5249.o 18rtsx_pci-objs := rtsx_pcr.o rts5209.o rts5229.o rtl8411.o rts5227.o rts5249.o
18obj-$(CONFIG_MFD_RTSX_PCI) += rtsx_pci.o 19obj-$(CONFIG_MFD_RTSX_PCI) += rtsx_pci.o
@@ -114,6 +115,8 @@ obj-$(CONFIG_PMIC_DA9052) += da9052-irq.o
114obj-$(CONFIG_PMIC_DA9052) += da9052-core.o 115obj-$(CONFIG_PMIC_DA9052) += da9052-core.o
115obj-$(CONFIG_MFD_DA9052_SPI) += da9052-spi.o 116obj-$(CONFIG_MFD_DA9052_SPI) += da9052-spi.o
116obj-$(CONFIG_MFD_DA9052_I2C) += da9052-i2c.o 117obj-$(CONFIG_MFD_DA9052_I2C) += da9052-i2c.o
118
119obj-$(CONFIG_MFD_AC100) += ac100.o
117obj-$(CONFIG_MFD_AXP20X) += axp20x.o 120obj-$(CONFIG_MFD_AXP20X) += axp20x.o
118obj-$(CONFIG_MFD_AXP20X_I2C) += axp20x-i2c.o 121obj-$(CONFIG_MFD_AXP20X_I2C) += axp20x-i2c.o
119obj-$(CONFIG_MFD_AXP20X_RSB) += axp20x-rsb.o 122obj-$(CONFIG_MFD_AXP20X_RSB) += axp20x-rsb.o
diff --git a/drivers/mfd/ab8500-debugfs.c b/drivers/mfd/ab8500-debugfs.c
index 0aecd7bd35f8..acf6c00b14b9 100644
--- a/drivers/mfd/ab8500-debugfs.c
+++ b/drivers/mfd/ab8500-debugfs.c
@@ -153,14 +153,14 @@ static struct hwreg_cfg hwreg_cfg = {
153 153
154#define AB8500_NAME_STRING "ab8500" 154#define AB8500_NAME_STRING "ab8500"
155#define AB8500_ADC_NAME_STRING "gpadc" 155#define AB8500_ADC_NAME_STRING "gpadc"
156#define AB8500_NUM_BANKS 24 156#define AB8500_NUM_BANKS AB8500_DEBUG_FIELD_LAST
157 157
158#define AB8500_REV_REG 0x80 158#define AB8500_REV_REG 0x80
159 159
160static struct ab8500_prcmu_ranges *debug_ranges; 160static struct ab8500_prcmu_ranges *debug_ranges;
161 161
162static struct ab8500_prcmu_ranges ab8500_debug_ranges[AB8500_NUM_BANKS] = { 162static struct ab8500_prcmu_ranges ab8500_debug_ranges[AB8500_NUM_BANKS] = {
163 [0x0] = { 163 [AB8500_M_FSM_RANK] = {
164 .num_ranges = 0, 164 .num_ranges = 0,
165 .range = NULL, 165 .range = NULL,
166 }, 166 },
@@ -315,7 +315,7 @@ static struct ab8500_prcmu_ranges ab8500_debug_ranges[AB8500_NUM_BANKS] = {
315 }, 315 },
316 }, 316 },
317 }, 317 },
318 [0x9] = { 318 [AB8500_RESERVED] = {
319 .num_ranges = 0, 319 .num_ranges = 0,
320 .range = NULL, 320 .range = NULL,
321 }, 321 },
@@ -386,24 +386,6 @@ static struct ab8500_prcmu_ranges ab8500_debug_ranges[AB8500_NUM_BANKS] = {
386 }, 386 },
387 }, 387 },
388 }, 388 },
389 [AB8500_DEVELOPMENT] = {
390 .num_ranges = 1,
391 .range = (struct ab8500_reg_range[]) {
392 {
393 .first = 0x00,
394 .last = 0x00,
395 },
396 },
397 },
398 [AB8500_DEBUG] = {
399 .num_ranges = 1,
400 .range = (struct ab8500_reg_range[]) {
401 {
402 .first = 0x05,
403 .last = 0x07,
404 },
405 },
406 },
407 [AB8500_AUDIO] = { 389 [AB8500_AUDIO] = {
408 .num_ranges = 1, 390 .num_ranges = 1,
409 .range = (struct ab8500_reg_range[]) { 391 .range = (struct ab8500_reg_range[]) {
@@ -463,19 +445,29 @@ static struct ab8500_prcmu_ranges ab8500_debug_ranges[AB8500_NUM_BANKS] = {
463 }, 445 },
464 }, 446 },
465 }, 447 },
466 [0x11] = { 448 [AB8500_DEVELOPMENT] = {
467 .num_ranges = 0, 449 .num_ranges = 1,
468 .range = NULL, 450 .range = (struct ab8500_reg_range[]) {
451 {
452 .first = 0x00,
453 .last = 0x00,
454 },
455 },
469 }, 456 },
470 [0x12] = { 457 [AB8500_DEBUG] = {
471 .num_ranges = 0, 458 .num_ranges = 1,
472 .range = NULL, 459 .range = (struct ab8500_reg_range[]) {
460 {
461 .first = 0x05,
462 .last = 0x07,
463 },
464 },
473 }, 465 },
474 [0x13] = { 466 [AB8500_PROD_TEST] = {
475 .num_ranges = 0, 467 .num_ranges = 0,
476 .range = NULL, 468 .range = NULL,
477 }, 469 },
478 [0x14] = { 470 [AB8500_STE_TEST] = {
479 .num_ranges = 0, 471 .num_ranges = 0,
480 .range = NULL, 472 .range = NULL,
481 }, 473 },
@@ -1382,60 +1374,6 @@ void ab8500_dump_all_banks(struct device *dev)
1382 } 1374 }
1383} 1375}
1384 1376
1385/* Space for 500 registers. */
1386#define DUMP_MAX_REGS 700
1387static struct ab8500_register_dump
1388{
1389 u8 bank;
1390 u8 reg;
1391 u8 value;
1392} ab8500_complete_register_dump[DUMP_MAX_REGS];
1393
1394/* This shall only be called upon kernel panic! */
1395void ab8500_dump_all_banks_to_mem(void)
1396{
1397 int i, r = 0;
1398 u8 bank;
1399 int err = 0;
1400
1401 pr_info("Saving all ABB registers for crash analysis.\n");
1402
1403 for (bank = 0; bank < AB8500_NUM_BANKS; bank++) {
1404 for (i = 0; i < debug_ranges[bank].num_ranges; i++) {
1405 u8 reg;
1406
1407 for (reg = debug_ranges[bank].range[i].first;
1408 reg <= debug_ranges[bank].range[i].last;
1409 reg++) {
1410 u8 value;
1411
1412 err = prcmu_abb_read(bank, reg, &value, 1);
1413
1414 if (err < 0)
1415 goto out;
1416
1417 ab8500_complete_register_dump[r].bank = bank;
1418 ab8500_complete_register_dump[r].reg = reg;
1419 ab8500_complete_register_dump[r].value = value;
1420
1421 r++;
1422
1423 if (r >= DUMP_MAX_REGS) {
1424 pr_err("%s: too many register to dump!\n",
1425 __func__);
1426 err = -EINVAL;
1427 goto out;
1428 }
1429 }
1430 }
1431 }
1432out:
1433 if (err >= 0)
1434 pr_info("Saved all ABB registers.\n");
1435 else
1436 pr_info("Failed to save all ABB registers.\n");
1437}
1438
1439static int ab8500_all_banks_open(struct inode *inode, struct file *file) 1377static int ab8500_all_banks_open(struct inode *inode, struct file *file)
1440{ 1378{
1441 struct seq_file *s; 1379 struct seq_file *s;
@@ -1584,18 +1522,10 @@ static u32 num_interrupts[AB8500_MAX_NR_IRQS];
1584static u32 num_wake_interrupts[AB8500_MAX_NR_IRQS]; 1522static u32 num_wake_interrupts[AB8500_MAX_NR_IRQS];
1585static int num_interrupt_lines; 1523static int num_interrupt_lines;
1586 1524
1587bool __attribute__((weak)) suspend_test_wake_cause_interrupt_is_mine(u32 my_int)
1588{
1589 return false;
1590}
1591
1592void ab8500_debug_register_interrupt(int line) 1525void ab8500_debug_register_interrupt(int line)
1593{ 1526{
1594 if (line < num_interrupt_lines) { 1527 if (line < num_interrupt_lines)
1595 num_interrupts[line]++; 1528 num_interrupts[line]++;
1596 if (suspend_test_wake_cause_interrupt_is_mine(irq_ab8500))
1597 num_wake_interrupts[line]++;
1598 }
1599} 1529}
1600 1530
1601static int ab8500_interrupts_print(struct seq_file *s, void *p) 1531static int ab8500_interrupts_print(struct seq_file *s, void *p)
diff --git a/drivers/mfd/ac100.c b/drivers/mfd/ac100.c
new file mode 100644
index 000000000000..9bc69cd7807d
--- /dev/null
+++ b/drivers/mfd/ac100.c
@@ -0,0 +1,137 @@
1/*
2 * MFD core driver for X-Powers' AC100 Audio Codec IC
3 *
4 * The AC100 is a highly integrated audio codec and RTC subsystem designed
5 * for mobile applications. It has 3 I2S/PCM interfaces, a 2 channel DAC,
6 * a 2 channel ADC with 5 inputs and a builtin mixer. The RTC subsystem has
7 * 3 clock outputs.
8 *
9 * The audio codec and RTC parts are completely separate, sharing only the
10 * host interface for access to its registers.
11 *
12 * Copyright (2016) Chen-Yu Tsai
13 *
14 * Author: Chen-Yu Tsai <wens@csie.org>
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License version 2 as
18 * published by the Free Software Foundation.
19 */
20
21#include <linux/interrupt.h>
22#include <linux/kernel.h>
23#include <linux/mfd/core.h>
24#include <linux/mfd/ac100.h>
25#include <linux/module.h>
26#include <linux/of.h>
27#include <linux/regmap.h>
28#include <linux/sunxi-rsb.h>
29
30static const struct regmap_range ac100_writeable_ranges[] = {
31 regmap_reg_range(AC100_CHIP_AUDIO_RST, AC100_I2S_SR_CTRL),
32 regmap_reg_range(AC100_I2S1_CLK_CTRL, AC100_I2S1_MXR_GAIN),
33 regmap_reg_range(AC100_I2S2_CLK_CTRL, AC100_I2S2_MXR_GAIN),
34 regmap_reg_range(AC100_I2S3_CLK_CTRL, AC100_I2S3_SIG_PATH_CTRL),
35 regmap_reg_range(AC100_ADC_DIG_CTRL, AC100_ADC_VOL_CTRL),
36 regmap_reg_range(AC100_HMIC_CTRL1, AC100_HMIC_STATUS),
37 regmap_reg_range(AC100_DAC_DIG_CTRL, AC100_DAC_MXR_GAIN),
38 regmap_reg_range(AC100_ADC_APC_CTRL, AC100_LINEOUT_CTRL),
39 regmap_reg_range(AC100_ADC_DAP_L_CTRL, AC100_ADC_DAP_OPT),
40 regmap_reg_range(AC100_DAC_DAP_CTRL, AC100_DAC_DAP_OPT),
41 regmap_reg_range(AC100_ADC_DAP_ENA, AC100_DAC_DAP_ENA),
42 regmap_reg_range(AC100_SRC1_CTRL1, AC100_SRC1_CTRL2),
43 regmap_reg_range(AC100_SRC2_CTRL1, AC100_SRC2_CTRL2),
44 regmap_reg_range(AC100_CLK32K_ANALOG_CTRL, AC100_CLKOUT_CTRL3),
45 regmap_reg_range(AC100_RTC_RST, AC100_RTC_UPD),
46 regmap_reg_range(AC100_ALM_INT_ENA, AC100_ALM_INT_STA),
47 regmap_reg_range(AC100_ALM_SEC, AC100_RTC_GP(15)),
48};
49
50static const struct regmap_range ac100_volatile_ranges[] = {
51 regmap_reg_range(AC100_CHIP_AUDIO_RST, AC100_PLL_CTRL2),
52 regmap_reg_range(AC100_HMIC_STATUS, AC100_HMIC_STATUS),
53 regmap_reg_range(AC100_ADC_DAP_L_STA, AC100_ADC_DAP_L_STA),
54 regmap_reg_range(AC100_SRC1_CTRL1, AC100_SRC1_CTRL1),
55 regmap_reg_range(AC100_SRC1_CTRL3, AC100_SRC2_CTRL1),
56 regmap_reg_range(AC100_SRC2_CTRL3, AC100_SRC2_CTRL4),
57 regmap_reg_range(AC100_RTC_RST, AC100_RTC_RST),
58 regmap_reg_range(AC100_RTC_SEC, AC100_ALM_INT_STA),
59 regmap_reg_range(AC100_ALM_SEC, AC100_ALM_UPD),
60};
61
62static const struct regmap_access_table ac100_writeable_table = {
63 .yes_ranges = ac100_writeable_ranges,
64 .n_yes_ranges = ARRAY_SIZE(ac100_writeable_ranges),
65};
66
67static const struct regmap_access_table ac100_volatile_table = {
68 .yes_ranges = ac100_volatile_ranges,
69 .n_yes_ranges = ARRAY_SIZE(ac100_volatile_ranges),
70};
71
72static const struct regmap_config ac100_regmap_config = {
73 .reg_bits = 8,
74 .val_bits = 16,
75 .wr_table = &ac100_writeable_table,
76 .volatile_table = &ac100_volatile_table,
77 .max_register = AC100_RTC_GP(15),
78 .cache_type = REGCACHE_RBTREE,
79};
80
81static struct mfd_cell ac100_cells[] = {
82 {
83 .name = "ac100-codec",
84 .of_compatible = "x-powers,ac100-codec",
85 }, {
86 .name = "ac100-rtc",
87 .of_compatible = "x-powers,ac100-rtc",
88 },
89};
90
91static int ac100_rsb_probe(struct sunxi_rsb_device *rdev)
92{
93 struct ac100_dev *ac100;
94 int ret;
95
96 ac100 = devm_kzalloc(&rdev->dev, sizeof(*ac100), GFP_KERNEL);
97 if (!ac100)
98 return -ENOMEM;
99
100 ac100->dev = &rdev->dev;
101 sunxi_rsb_device_set_drvdata(rdev, ac100);
102
103 ac100->regmap = devm_regmap_init_sunxi_rsb(rdev, &ac100_regmap_config);
104 if (IS_ERR(ac100->regmap)) {
105 ret = PTR_ERR(ac100->regmap);
106 dev_err(ac100->dev, "regmap init failed: %d\n", ret);
107 return ret;
108 }
109
110 ret = devm_mfd_add_devices(ac100->dev, PLATFORM_DEVID_NONE, ac100_cells,
111 ARRAY_SIZE(ac100_cells), NULL, 0, NULL);
112 if (ret) {
113 dev_err(ac100->dev, "failed to add MFD devices: %d\n", ret);
114 return ret;
115 }
116
117 return 0;
118}
119
120static const struct of_device_id ac100_of_match[] = {
121 { .compatible = "x-powers,ac100" },
122 { },
123};
124MODULE_DEVICE_TABLE(of, ac100_of_match);
125
126static struct sunxi_rsb_driver ac100_rsb_driver = {
127 .driver = {
128 .name = "ac100",
129 .of_match_table = of_match_ptr(ac100_of_match),
130 },
131 .probe = ac100_rsb_probe,
132};
133module_sunxi_rsb_driver(ac100_rsb_driver);
134
135MODULE_DESCRIPTION("Audio codec MFD core driver for AC100");
136MODULE_AUTHOR("Chen-Yu Tsai <wens@csie.org>");
137MODULE_LICENSE("GPL v2");
diff --git a/drivers/mfd/act8945a.c b/drivers/mfd/act8945a.c
index 10c6d2da8822..a4024d91da01 100644
--- a/drivers/mfd/act8945a.c
+++ b/drivers/mfd/act8945a.c
@@ -23,6 +23,7 @@ static const struct mfd_cell act8945a_devs[] = {
23 }, 23 },
24 { 24 {
25 .name = "act8945a-charger", 25 .name = "act8945a-charger",
26 .of_compatible = "active-semi,act8945a-charger",
26 }, 27 },
27}; 28};
28 29
diff --git a/drivers/mfd/altera-a10sr.c b/drivers/mfd/altera-a10sr.c
index c05aa4ff57fd..06e1f7fc5605 100644
--- a/drivers/mfd/altera-a10sr.c
+++ b/drivers/mfd/altera-a10sr.c
@@ -1,4 +1,8 @@
1/* 1/*
2 * Altera Arria10 DevKit System Resource MFD Driver
3 *
4 * Author: Thor Thayer <tthayer@opensource.altera.com>
5 *
2 * Copyright Intel Corporation (C) 2014-2016. All Rights Reserved 6 * Copyright Intel Corporation (C) 2014-2016. All Rights Reserved
3 * 7 *
4 * This program is free software; you can redistribute it and/or modify it 8 * This program is free software; you can redistribute it and/or modify it
@@ -20,7 +24,7 @@
20 24
21#include <linux/mfd/altera-a10sr.h> 25#include <linux/mfd/altera-a10sr.h>
22#include <linux/mfd/core.h> 26#include <linux/mfd/core.h>
23#include <linux/module.h> 27#include <linux/init.h>
24#include <linux/of.h> 28#include <linux/of.h>
25#include <linux/spi/spi.h> 29#include <linux/spi/spi.h>
26 30
@@ -94,7 +98,7 @@ static bool altr_a10sr_reg_volatile(struct device *dev, unsigned int reg)
94 } 98 }
95} 99}
96 100
97const struct regmap_config altr_a10sr_regmap_config = { 101static const struct regmap_config altr_a10sr_regmap_config = {
98 .reg_bits = 8, 102 .reg_bits = 8,
99 .val_bits = 8, 103 .val_bits = 8,
100 104
@@ -152,7 +156,6 @@ static const struct of_device_id altr_a10sr_spi_of_match[] = {
152 { .compatible = "altr,a10sr" }, 156 { .compatible = "altr,a10sr" },
153 { }, 157 { },
154}; 158};
155MODULE_DEVICE_TABLE(of, altr_a10sr_spi_of_match);
156 159
157static struct spi_driver altr_a10sr_spi_driver = { 160static struct spi_driver altr_a10sr_spi_driver = {
158 .probe = altr_a10sr_spi_probe, 161 .probe = altr_a10sr_spi_probe,
@@ -161,9 +164,4 @@ static struct spi_driver altr_a10sr_spi_driver = {
161 .of_match_table = of_match_ptr(altr_a10sr_spi_of_match), 164 .of_match_table = of_match_ptr(altr_a10sr_spi_of_match),
162 }, 165 },
163}; 166};
164 167builtin_driver(altr_a10sr_spi_driver, spi_register_driver)
165module_spi_driver(altr_a10sr_spi_driver);
166
167MODULE_LICENSE("GPL v2");
168MODULE_AUTHOR("Thor Thayer <tthayer@opensource.altera.com>");
169MODULE_DESCRIPTION("Altera Arria10 DevKit System Resource MFD Driver");
diff --git a/drivers/mfd/arizona-core.c b/drivers/mfd/arizona-core.c
index e4f97b3c824b..41767f7239bb 100644
--- a/drivers/mfd/arizona-core.c
+++ b/drivers/mfd/arizona-core.c
@@ -10,6 +10,7 @@
10 * published by the Free Software Foundation. 10 * published by the Free Software Foundation.
11 */ 11 */
12 12
13#include <linux/clk.h>
13#include <linux/delay.h> 14#include <linux/delay.h>
14#include <linux/err.h> 15#include <linux/err.h>
15#include <linux/gpio.h> 16#include <linux/gpio.h>
@@ -49,7 +50,15 @@ int arizona_clk32k_enable(struct arizona *arizona)
49 case ARIZONA_32KZ_MCLK1: 50 case ARIZONA_32KZ_MCLK1:
50 ret = pm_runtime_get_sync(arizona->dev); 51 ret = pm_runtime_get_sync(arizona->dev);
51 if (ret != 0) 52 if (ret != 0)
52 goto out; 53 goto err_ref;
54 ret = clk_prepare_enable(arizona->mclk[ARIZONA_MCLK1]);
55 if (ret != 0)
56 goto err_pm;
57 break;
58 case ARIZONA_32KZ_MCLK2:
59 ret = clk_prepare_enable(arizona->mclk[ARIZONA_MCLK2]);
60 if (ret != 0)
61 goto err_ref;
53 break; 62 break;
54 } 63 }
55 64
@@ -58,7 +67,9 @@ int arizona_clk32k_enable(struct arizona *arizona)
58 ARIZONA_CLK_32K_ENA); 67 ARIZONA_CLK_32K_ENA);
59 } 68 }
60 69
61out: 70err_pm:
71 pm_runtime_put_sync(arizona->dev);
72err_ref:
62 if (ret != 0) 73 if (ret != 0)
63 arizona->clk32k_ref--; 74 arizona->clk32k_ref--;
64 75
@@ -83,6 +94,10 @@ int arizona_clk32k_disable(struct arizona *arizona)
83 switch (arizona->pdata.clk32k_src) { 94 switch (arizona->pdata.clk32k_src) {
84 case ARIZONA_32KZ_MCLK1: 95 case ARIZONA_32KZ_MCLK1:
85 pm_runtime_put_sync(arizona->dev); 96 pm_runtime_put_sync(arizona->dev);
97 clk_disable_unprepare(arizona->mclk[ARIZONA_MCLK1]);
98 break;
99 case ARIZONA_32KZ_MCLK2:
100 clk_disable_unprepare(arizona->mclk[ARIZONA_MCLK2]);
86 break; 101 break;
87 } 102 }
88 } 103 }
@@ -735,7 +750,7 @@ static int arizona_suspend(struct device *dev)
735 return 0; 750 return 0;
736} 751}
737 752
738static int arizona_suspend_late(struct device *dev) 753static int arizona_suspend_noirq(struct device *dev)
739{ 754{
740 struct arizona *arizona = dev_get_drvdata(dev); 755 struct arizona *arizona = dev_get_drvdata(dev);
741 756
@@ -759,7 +774,7 @@ static int arizona_resume(struct device *dev)
759{ 774{
760 struct arizona *arizona = dev_get_drvdata(dev); 775 struct arizona *arizona = dev_get_drvdata(dev);
761 776
762 dev_dbg(arizona->dev, "Late resume, reenabling IRQ\n"); 777 dev_dbg(arizona->dev, "Resume, reenabling IRQ\n");
763 enable_irq(arizona->irq); 778 enable_irq(arizona->irq);
764 779
765 return 0; 780 return 0;
@@ -771,10 +786,8 @@ const struct dev_pm_ops arizona_pm_ops = {
771 arizona_runtime_resume, 786 arizona_runtime_resume,
772 NULL) 787 NULL)
773 SET_SYSTEM_SLEEP_PM_OPS(arizona_suspend, arizona_resume) 788 SET_SYSTEM_SLEEP_PM_OPS(arizona_suspend, arizona_resume)
774#ifdef CONFIG_PM_SLEEP 789 SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(arizona_suspend_noirq,
775 .suspend_late = arizona_suspend_late, 790 arizona_resume_noirq)
776 .resume_noirq = arizona_resume_noirq,
777#endif
778}; 791};
779EXPORT_SYMBOL_GPL(arizona_pm_ops); 792EXPORT_SYMBOL_GPL(arizona_pm_ops);
780 793
@@ -790,35 +803,25 @@ unsigned long arizona_of_get_type(struct device *dev)
790} 803}
791EXPORT_SYMBOL_GPL(arizona_of_get_type); 804EXPORT_SYMBOL_GPL(arizona_of_get_type);
792 805
793int arizona_of_get_named_gpio(struct arizona *arizona, const char *prop,
794 bool mandatory)
795{
796 int gpio;
797
798 gpio = of_get_named_gpio(arizona->dev->of_node, prop, 0);
799 if (gpio < 0) {
800 if (mandatory)
801 dev_err(arizona->dev,
802 "Mandatory DT gpio %s missing/malformed: %d\n",
803 prop, gpio);
804
805 gpio = 0;
806 }
807
808 return gpio;
809}
810EXPORT_SYMBOL_GPL(arizona_of_get_named_gpio);
811
812static int arizona_of_get_core_pdata(struct arizona *arizona) 806static int arizona_of_get_core_pdata(struct arizona *arizona)
813{ 807{
814 struct arizona_pdata *pdata = &arizona->pdata; 808 struct arizona_pdata *pdata = &arizona->pdata;
815 struct property *prop; 809 struct property *prop;
816 const __be32 *cur; 810 const __be32 *cur;
817 u32 val; 811 u32 val;
812 u32 pdm_val[ARIZONA_MAX_PDM_SPK];
818 int ret, i; 813 int ret, i;
819 int count = 0; 814 int count = 0;
820 815
821 pdata->reset = arizona_of_get_named_gpio(arizona, "wlf,reset", true); 816 pdata->reset = of_get_named_gpio(arizona->dev->of_node, "wlf,reset", 0);
817 if (pdata->reset == -EPROBE_DEFER) {
818 return pdata->reset;
819 } else if (pdata->reset < 0) {
820 dev_err(arizona->dev, "Reset GPIO missing/malformed: %d\n",
821 pdata->reset);
822
823 pdata->reset = 0;
824 }
822 825
823 ret = of_property_read_u32_array(arizona->dev->of_node, 826 ret = of_property_read_u32_array(arizona->dev->of_node,
824 "wlf,gpio-defaults", 827 "wlf,gpio-defaults",
@@ -871,6 +874,35 @@ static int arizona_of_get_core_pdata(struct arizona *arizona)
871 count++; 874 count++;
872 } 875 }
873 876
877 count = 0;
878 of_property_for_each_u32(arizona->dev->of_node,
879 "wlf,max-channels-clocked",
880 prop, cur, val) {
881 if (count == ARRAY_SIZE(pdata->max_channels_clocked))
882 break;
883
884 pdata->max_channels_clocked[count] = val;
885 count++;
886 }
887
888 ret = of_property_read_u32_array(arizona->dev->of_node,
889 "wlf,spk-fmt",
890 pdm_val,
891 ARRAY_SIZE(pdm_val));
892
893 if (ret >= 0)
894 for (count = 0; count < ARRAY_SIZE(pdata->spk_fmt); ++count)
895 pdata->spk_fmt[count] = pdm_val[count];
896
897 ret = of_property_read_u32_array(arizona->dev->of_node,
898 "wlf,spk-mute",
899 pdm_val,
900 ARRAY_SIZE(pdm_val));
901
902 if (ret >= 0)
903 for (count = 0; count < ARRAY_SIZE(pdata->spk_mute); ++count)
904 pdata->spk_mute[count] = pdm_val[count];
905
874 return 0; 906 return 0;
875} 907}
876 908
@@ -1000,6 +1032,7 @@ static const struct mfd_cell wm8998_devs[] = {
1000 1032
1001int arizona_dev_init(struct arizona *arizona) 1033int arizona_dev_init(struct arizona *arizona)
1002{ 1034{
1035 const char * const mclk_name[] = { "mclk1", "mclk2" };
1003 struct device *dev = arizona->dev; 1036 struct device *dev = arizona->dev;
1004 const char *type_name = NULL; 1037 const char *type_name = NULL;
1005 unsigned int reg, val, mask; 1038 unsigned int reg, val, mask;
@@ -1010,11 +1043,24 @@ int arizona_dev_init(struct arizona *arizona)
1010 dev_set_drvdata(arizona->dev, arizona); 1043 dev_set_drvdata(arizona->dev, arizona);
1011 mutex_init(&arizona->clk_lock); 1044 mutex_init(&arizona->clk_lock);
1012 1045
1013 if (dev_get_platdata(arizona->dev)) 1046 if (dev_get_platdata(arizona->dev)) {
1014 memcpy(&arizona->pdata, dev_get_platdata(arizona->dev), 1047 memcpy(&arizona->pdata, dev_get_platdata(arizona->dev),
1015 sizeof(arizona->pdata)); 1048 sizeof(arizona->pdata));
1016 else 1049 } else {
1017 arizona_of_get_core_pdata(arizona); 1050 ret = arizona_of_get_core_pdata(arizona);
1051 if (ret < 0)
1052 return ret;
1053 }
1054
1055 BUILD_BUG_ON(ARRAY_SIZE(arizona->mclk) != ARRAY_SIZE(mclk_name));
1056 for (i = 0; i < ARRAY_SIZE(arizona->mclk); i++) {
1057 arizona->mclk[i] = devm_clk_get(arizona->dev, mclk_name[i]);
1058 if (IS_ERR(arizona->mclk[i])) {
1059 dev_info(arizona->dev, "Failed to get %s: %ld\n",
1060 mclk_name[i], PTR_ERR(arizona->mclk[i]));
1061 arizona->mclk[i] = NULL;
1062 }
1063 }
1018 1064
1019 regcache_cache_only(arizona->regmap, true); 1065 regcache_cache_only(arizona->regmap, true);
1020 1066
@@ -1035,7 +1081,7 @@ int arizona_dev_init(struct arizona *arizona)
1035 default: 1081 default:
1036 dev_err(arizona->dev, "Unknown device type %d\n", 1082 dev_err(arizona->dev, "Unknown device type %d\n",
1037 arizona->type); 1083 arizona->type);
1038 return -EINVAL; 1084 return -ENODEV;
1039 } 1085 }
1040 1086
1041 /* Mark DCVDD as external, LDO1 driver will clear if internal */ 1087 /* Mark DCVDD as external, LDO1 driver will clear if internal */
@@ -1121,6 +1167,7 @@ int arizona_dev_init(struct arizona *arizona)
1121 break; 1167 break;
1122 default: 1168 default:
1123 dev_err(arizona->dev, "Unknown device ID: %x\n", reg); 1169 dev_err(arizona->dev, "Unknown device ID: %x\n", reg);
1170 ret = -ENODEV;
1124 goto err_reset; 1171 goto err_reset;
1125 } 1172 }
1126 1173
@@ -1280,12 +1327,14 @@ int arizona_dev_init(struct arizona *arizona)
1280 break; 1327 break;
1281 default: 1328 default:
1282 dev_err(arizona->dev, "Unknown device ID %x\n", reg); 1329 dev_err(arizona->dev, "Unknown device ID %x\n", reg);
1330 ret = -ENODEV;
1283 goto err_reset; 1331 goto err_reset;
1284 } 1332 }
1285 1333
1286 if (!subdevs) { 1334 if (!subdevs) {
1287 dev_err(arizona->dev, 1335 dev_err(arizona->dev,
1288 "No kernel support for device ID %x\n", reg); 1336 "No kernel support for device ID %x\n", reg);
1337 ret = -ENODEV;
1289 goto err_reset; 1338 goto err_reset;
1290 } 1339 }
1291 1340
diff --git a/drivers/mfd/atmel-hlcdc.c b/drivers/mfd/atmel-hlcdc.c
index eca7ea69b81c..4b15b0840f16 100644
--- a/drivers/mfd/atmel-hlcdc.c
+++ b/drivers/mfd/atmel-hlcdc.c
@@ -50,8 +50,9 @@ static int regmap_atmel_hlcdc_reg_write(void *context, unsigned int reg,
50 if (reg <= ATMEL_HLCDC_DIS) { 50 if (reg <= ATMEL_HLCDC_DIS) {
51 u32 status; 51 u32 status;
52 52
53 readl_poll_timeout(hregmap->regs + ATMEL_HLCDC_SR, status, 53 readl_poll_timeout_atomic(hregmap->regs + ATMEL_HLCDC_SR,
54 !(status & ATMEL_HLCDC_SIP), 1, 100); 54 status, !(status & ATMEL_HLCDC_SIP),
55 1, 100);
55 } 56 }
56 57
57 writel(val, hregmap->regs + reg); 58 writel(val, hregmap->regs + reg);
diff --git a/drivers/mfd/axp20x-rsb.c b/drivers/mfd/axp20x-rsb.c
index a407527bcd09..a732cb50bcff 100644
--- a/drivers/mfd/axp20x-rsb.c
+++ b/drivers/mfd/axp20x-rsb.c
@@ -61,6 +61,7 @@ static int axp20x_rsb_remove(struct sunxi_rsb_device *rdev)
61 61
62static const struct of_device_id axp20x_rsb_of_match[] = { 62static const struct of_device_id axp20x_rsb_of_match[] = {
63 { .compatible = "x-powers,axp223", .data = (void *)AXP223_ID }, 63 { .compatible = "x-powers,axp223", .data = (void *)AXP223_ID },
64 { .compatible = "x-powers,axp806", .data = (void *)AXP806_ID },
64 { .compatible = "x-powers,axp809", .data = (void *)AXP809_ID }, 65 { .compatible = "x-powers,axp809", .data = (void *)AXP809_ID },
65 { }, 66 { },
66}; 67};
diff --git a/drivers/mfd/axp20x.c b/drivers/mfd/axp20x.c
index fd80b0981f0f..ba130be32e61 100644
--- a/drivers/mfd/axp20x.c
+++ b/drivers/mfd/axp20x.c
@@ -38,6 +38,7 @@ static const char * const axp20x_model_names[] = {
38 "AXP221", 38 "AXP221",
39 "AXP223", 39 "AXP223",
40 "AXP288", 40 "AXP288",
41 "AXP806",
41 "AXP809", 42 "AXP809",
42}; 43};
43 44
@@ -129,6 +130,27 @@ static const struct regmap_access_table axp288_volatile_table = {
129 .n_yes_ranges = ARRAY_SIZE(axp288_volatile_ranges), 130 .n_yes_ranges = ARRAY_SIZE(axp288_volatile_ranges),
130}; 131};
131 132
133static const struct regmap_range axp806_writeable_ranges[] = {
134 regmap_reg_range(AXP20X_DATACACHE(0), AXP20X_DATACACHE(3)),
135 regmap_reg_range(AXP806_PWR_OUT_CTRL1, AXP806_CLDO3_V_CTRL),
136 regmap_reg_range(AXP20X_IRQ1_EN, AXP20X_IRQ2_EN),
137 regmap_reg_range(AXP20X_IRQ1_STATE, AXP20X_IRQ2_STATE),
138};
139
140static const struct regmap_range axp806_volatile_ranges[] = {
141 regmap_reg_range(AXP20X_IRQ1_STATE, AXP20X_IRQ2_STATE),
142};
143
144static const struct regmap_access_table axp806_writeable_table = {
145 .yes_ranges = axp806_writeable_ranges,
146 .n_yes_ranges = ARRAY_SIZE(axp806_writeable_ranges),
147};
148
149static const struct regmap_access_table axp806_volatile_table = {
150 .yes_ranges = axp806_volatile_ranges,
151 .n_yes_ranges = ARRAY_SIZE(axp806_volatile_ranges),
152};
153
132static struct resource axp152_pek_resources[] = { 154static struct resource axp152_pek_resources[] = {
133 DEFINE_RES_IRQ_NAMED(AXP152_IRQ_PEK_RIS_EDGE, "PEK_DBR"), 155 DEFINE_RES_IRQ_NAMED(AXP152_IRQ_PEK_RIS_EDGE, "PEK_DBR"),
134 DEFINE_RES_IRQ_NAMED(AXP152_IRQ_PEK_FAL_EDGE, "PEK_DBF"), 156 DEFINE_RES_IRQ_NAMED(AXP152_IRQ_PEK_FAL_EDGE, "PEK_DBF"),
@@ -278,6 +300,15 @@ static const struct regmap_config axp288_regmap_config = {
278 .cache_type = REGCACHE_RBTREE, 300 .cache_type = REGCACHE_RBTREE,
279}; 301};
280 302
303static const struct regmap_config axp806_regmap_config = {
304 .reg_bits = 8,
305 .val_bits = 8,
306 .wr_table = &axp806_writeable_table,
307 .volatile_table = &axp806_volatile_table,
308 .max_register = AXP806_VREF_TEMP_WARN_L,
309 .cache_type = REGCACHE_RBTREE,
310};
311
281#define INIT_REGMAP_IRQ(_variant, _irq, _off, _mask) \ 312#define INIT_REGMAP_IRQ(_variant, _irq, _off, _mask) \
282 [_variant##_IRQ_##_irq] = { .reg_offset = (_off), .mask = BIT(_mask) } 313 [_variant##_IRQ_##_irq] = { .reg_offset = (_off), .mask = BIT(_mask) }
283 314
@@ -409,6 +440,21 @@ static const struct regmap_irq axp288_regmap_irqs[] = {
409 INIT_REGMAP_IRQ(AXP288, BC_USB_CHNG, 5, 1), 440 INIT_REGMAP_IRQ(AXP288, BC_USB_CHNG, 5, 1),
410}; 441};
411 442
443static const struct regmap_irq axp806_regmap_irqs[] = {
444 INIT_REGMAP_IRQ(AXP806, DIE_TEMP_HIGH_LV1, 0, 0),
445 INIT_REGMAP_IRQ(AXP806, DIE_TEMP_HIGH_LV2, 0, 1),
446 INIT_REGMAP_IRQ(AXP806, DCDCA_V_LOW, 0, 3),
447 INIT_REGMAP_IRQ(AXP806, DCDCB_V_LOW, 0, 4),
448 INIT_REGMAP_IRQ(AXP806, DCDCC_V_LOW, 0, 5),
449 INIT_REGMAP_IRQ(AXP806, DCDCD_V_LOW, 0, 6),
450 INIT_REGMAP_IRQ(AXP806, DCDCE_V_LOW, 0, 7),
451 INIT_REGMAP_IRQ(AXP806, PWROK_LONG, 1, 0),
452 INIT_REGMAP_IRQ(AXP806, PWROK_SHORT, 1, 1),
453 INIT_REGMAP_IRQ(AXP806, WAKEUP, 1, 4),
454 INIT_REGMAP_IRQ(AXP806, PWROK_FALL, 1, 5),
455 INIT_REGMAP_IRQ(AXP806, PWROK_RISE, 1, 6),
456};
457
412static const struct regmap_irq axp809_regmap_irqs[] = { 458static const struct regmap_irq axp809_regmap_irqs[] = {
413 INIT_REGMAP_IRQ(AXP809, ACIN_OVER_V, 0, 7), 459 INIT_REGMAP_IRQ(AXP809, ACIN_OVER_V, 0, 7),
414 INIT_REGMAP_IRQ(AXP809, ACIN_PLUGIN, 0, 6), 460 INIT_REGMAP_IRQ(AXP809, ACIN_PLUGIN, 0, 6),
@@ -494,6 +540,18 @@ static const struct regmap_irq_chip axp288_regmap_irq_chip = {
494 540
495}; 541};
496 542
543static const struct regmap_irq_chip axp806_regmap_irq_chip = {
544 .name = "axp806",
545 .status_base = AXP20X_IRQ1_STATE,
546 .ack_base = AXP20X_IRQ1_STATE,
547 .mask_base = AXP20X_IRQ1_EN,
548 .mask_invert = true,
549 .init_ack_masked = true,
550 .irqs = axp806_regmap_irqs,
551 .num_irqs = ARRAY_SIZE(axp806_regmap_irqs),
552 .num_regs = 2,
553};
554
497static const struct regmap_irq_chip axp809_regmap_irq_chip = { 555static const struct regmap_irq_chip axp809_regmap_irq_chip = {
498 .name = "axp809", 556 .name = "axp809",
499 .status_base = AXP20X_IRQ1_STATE, 557 .status_base = AXP20X_IRQ1_STATE,
@@ -508,6 +566,9 @@ static const struct regmap_irq_chip axp809_regmap_irq_chip = {
508 566
509static struct mfd_cell axp20x_cells[] = { 567static struct mfd_cell axp20x_cells[] = {
510 { 568 {
569 .name = "axp20x-gpio",
570 .of_compatible = "x-powers,axp209-gpio",
571 }, {
511 .name = "axp20x-pek", 572 .name = "axp20x-pek",
512 .num_resources = ARRAY_SIZE(axp20x_pek_resources), 573 .num_resources = ARRAY_SIZE(axp20x_pek_resources),
513 .resources = axp20x_pek_resources, 574 .resources = axp20x_pek_resources,
@@ -660,12 +721,20 @@ static struct mfd_cell axp288_cells[] = {
660 }, 721 },
661}; 722};
662 723
724static struct mfd_cell axp806_cells[] = {
725 {
726 .id = 2,
727 .name = "axp20x-regulator",
728 },
729};
730
663static struct mfd_cell axp809_cells[] = { 731static struct mfd_cell axp809_cells[] = {
664 { 732 {
665 .name = "axp20x-pek", 733 .name = "axp20x-pek",
666 .num_resources = ARRAY_SIZE(axp809_pek_resources), 734 .num_resources = ARRAY_SIZE(axp809_pek_resources),
667 .resources = axp809_pek_resources, 735 .resources = axp809_pek_resources,
668 }, { 736 }, {
737 .id = 1,
669 .name = "axp20x-regulator", 738 .name = "axp20x-regulator",
670 }, 739 },
671}; 740};
@@ -732,6 +801,12 @@ int axp20x_match_device(struct axp20x_dev *axp20x)
732 axp20x->regmap_cfg = &axp288_regmap_config; 801 axp20x->regmap_cfg = &axp288_regmap_config;
733 axp20x->regmap_irq_chip = &axp288_regmap_irq_chip; 802 axp20x->regmap_irq_chip = &axp288_regmap_irq_chip;
734 break; 803 break;
804 case AXP806_ID:
805 axp20x->nr_cells = ARRAY_SIZE(axp806_cells);
806 axp20x->cells = axp806_cells;
807 axp20x->regmap_cfg = &axp806_regmap_config;
808 axp20x->regmap_irq_chip = &axp806_regmap_irq_chip;
809 break;
735 case AXP809_ID: 810 case AXP809_ID:
736 axp20x->nr_cells = ARRAY_SIZE(axp809_cells); 811 axp20x->nr_cells = ARRAY_SIZE(axp809_cells);
737 axp20x->cells = axp809_cells; 812 axp20x->cells = axp809_cells;
diff --git a/drivers/mfd/cros_ec.c b/drivers/mfd/cros_ec.c
index 0eee63542038..abd83424b498 100644
--- a/drivers/mfd/cros_ec.c
+++ b/drivers/mfd/cros_ec.c
@@ -23,6 +23,7 @@
23#include <linux/module.h> 23#include <linux/module.h>
24#include <linux/mfd/core.h> 24#include <linux/mfd/core.h>
25#include <linux/mfd/cros_ec.h> 25#include <linux/mfd/cros_ec.h>
26#include <asm/unaligned.h>
26 27
27#define CROS_EC_DEV_EC_INDEX 0 28#define CROS_EC_DEV_EC_INDEX 0
28#define CROS_EC_DEV_PD_INDEX 1 29#define CROS_EC_DEV_PD_INDEX 1
@@ -49,11 +50,28 @@ static const struct mfd_cell ec_pd_cell = {
49 .pdata_size = sizeof(pd_p), 50 .pdata_size = sizeof(pd_p),
50}; 51};
51 52
53static irqreturn_t ec_irq_thread(int irq, void *data)
54{
55 struct cros_ec_device *ec_dev = data;
56 int ret;
57
58 if (device_may_wakeup(ec_dev->dev))
59 pm_wakeup_event(ec_dev->dev, 0);
60
61 ret = cros_ec_get_next_event(ec_dev);
62 if (ret > 0)
63 blocking_notifier_call_chain(&ec_dev->event_notifier,
64 0, ec_dev);
65 return IRQ_HANDLED;
66}
67
52int cros_ec_register(struct cros_ec_device *ec_dev) 68int cros_ec_register(struct cros_ec_device *ec_dev)
53{ 69{
54 struct device *dev = ec_dev->dev; 70 struct device *dev = ec_dev->dev;
55 int err = 0; 71 int err = 0;
56 72
73 BLOCKING_INIT_NOTIFIER_HEAD(&ec_dev->event_notifier);
74
57 ec_dev->max_request = sizeof(struct ec_params_hello); 75 ec_dev->max_request = sizeof(struct ec_params_hello);
58 ec_dev->max_response = sizeof(struct ec_response_get_protocol_info); 76 ec_dev->max_response = sizeof(struct ec_response_get_protocol_info);
59 ec_dev->max_passthru = 0; 77 ec_dev->max_passthru = 0;
@@ -70,13 +88,24 @@ int cros_ec_register(struct cros_ec_device *ec_dev)
70 88
71 cros_ec_query_all(ec_dev); 89 cros_ec_query_all(ec_dev);
72 90
91 if (ec_dev->irq) {
92 err = request_threaded_irq(ec_dev->irq, NULL, ec_irq_thread,
93 IRQF_TRIGGER_LOW | IRQF_ONESHOT,
94 "chromeos-ec", ec_dev);
95 if (err) {
96 dev_err(dev, "Failed to request IRQ %d: %d",
97 ec_dev->irq, err);
98 return err;
99 }
100 }
101
73 err = mfd_add_devices(ec_dev->dev, PLATFORM_DEVID_AUTO, &ec_cell, 1, 102 err = mfd_add_devices(ec_dev->dev, PLATFORM_DEVID_AUTO, &ec_cell, 1,
74 NULL, ec_dev->irq, NULL); 103 NULL, ec_dev->irq, NULL);
75 if (err) { 104 if (err) {
76 dev_err(dev, 105 dev_err(dev,
77 "Failed to register Embedded Controller subdevice %d\n", 106 "Failed to register Embedded Controller subdevice %d\n",
78 err); 107 err);
79 return err; 108 goto fail_mfd;
80 } 109 }
81 110
82 if (ec_dev->max_passthru) { 111 if (ec_dev->max_passthru) {
@@ -94,7 +123,7 @@ int cros_ec_register(struct cros_ec_device *ec_dev)
94 dev_err(dev, 123 dev_err(dev,
95 "Failed to register Power Delivery subdevice %d\n", 124 "Failed to register Power Delivery subdevice %d\n",
96 err); 125 err);
97 return err; 126 goto fail_mfd;
98 } 127 }
99 } 128 }
100 129
@@ -103,13 +132,18 @@ int cros_ec_register(struct cros_ec_device *ec_dev)
103 if (err) { 132 if (err) {
104 mfd_remove_devices(dev); 133 mfd_remove_devices(dev);
105 dev_err(dev, "Failed to register sub-devices\n"); 134 dev_err(dev, "Failed to register sub-devices\n");
106 return err; 135 goto fail_mfd;
107 } 136 }
108 } 137 }
109 138
110 dev_info(dev, "Chrome EC device registered\n"); 139 dev_info(dev, "Chrome EC device registered\n");
111 140
112 return 0; 141 return 0;
142
143fail_mfd:
144 if (ec_dev->irq)
145 free_irq(ec_dev->irq, ec_dev);
146 return err;
113} 147}
114EXPORT_SYMBOL(cros_ec_register); 148EXPORT_SYMBOL(cros_ec_register);
115 149
@@ -136,13 +170,31 @@ int cros_ec_suspend(struct cros_ec_device *ec_dev)
136} 170}
137EXPORT_SYMBOL(cros_ec_suspend); 171EXPORT_SYMBOL(cros_ec_suspend);
138 172
173static void cros_ec_drain_events(struct cros_ec_device *ec_dev)
174{
175 while (cros_ec_get_next_event(ec_dev) > 0)
176 blocking_notifier_call_chain(&ec_dev->event_notifier,
177 1, ec_dev);
178}
179
139int cros_ec_resume(struct cros_ec_device *ec_dev) 180int cros_ec_resume(struct cros_ec_device *ec_dev)
140{ 181{
141 enable_irq(ec_dev->irq); 182 enable_irq(ec_dev->irq);
142 183
184 /*
185 * In some cases, we need to distinguish between events that occur
186 * during suspend if the EC is not a wake source. For example,
187 * keypresses during suspend should be discarded if it does not wake
188 * the system.
189 *
190 * If the EC is not a wake source, drain the event queue and mark them
191 * as "queued during suspend".
192 */
143 if (ec_dev->wake_enabled) { 193 if (ec_dev->wake_enabled) {
144 disable_irq_wake(ec_dev->irq); 194 disable_irq_wake(ec_dev->irq);
145 ec_dev->wake_enabled = 0; 195 ec_dev->wake_enabled = 0;
196 } else {
197 cros_ec_drain_events(ec_dev);
146 } 198 }
147 199
148 return 0; 200 return 0;
diff --git a/drivers/mfd/cros_ec_spi.c b/drivers/mfd/cros_ec_spi.c
index ebe9b9477cb2..a518832ed5f5 100644
--- a/drivers/mfd/cros_ec_spi.c
+++ b/drivers/mfd/cros_ec_spi.c
@@ -366,7 +366,6 @@ static int cros_ec_spi_receive_response(struct cros_ec_device *ec_dev,
366static int cros_ec_pkt_xfer_spi(struct cros_ec_device *ec_dev, 366static int cros_ec_pkt_xfer_spi(struct cros_ec_device *ec_dev,
367 struct cros_ec_command *ec_msg) 367 struct cros_ec_command *ec_msg)
368{ 368{
369 struct ec_host_request *request;
370 struct ec_host_response *response; 369 struct ec_host_response *response;
371 struct cros_ec_spi *ec_spi = ec_dev->priv; 370 struct cros_ec_spi *ec_spi = ec_dev->priv;
372 struct spi_transfer trans, trans_delay; 371 struct spi_transfer trans, trans_delay;
@@ -378,7 +377,6 @@ static int cros_ec_pkt_xfer_spi(struct cros_ec_device *ec_dev,
378 int ret = 0, final_ret; 377 int ret = 0, final_ret;
379 378
380 len = cros_ec_prepare_tx(ec_dev, ec_msg); 379 len = cros_ec_prepare_tx(ec_dev, ec_msg);
381 request = (struct ec_host_request *)ec_dev->dout;
382 dev_dbg(ec_dev->dev, "prepared, len=%d\n", len); 380 dev_dbg(ec_dev->dev, "prepared, len=%d\n", len);
383 381
384 /* If it's too soon to do another transaction, wait */ 382 /* If it's too soon to do another transaction, wait */
diff --git a/drivers/mfd/da9052-core.c b/drivers/mfd/da9052-core.c
index c0bf68a3e614..a88c2065d8ab 100644
--- a/drivers/mfd/da9052-core.c
+++ b/drivers/mfd/da9052-core.c
@@ -167,6 +167,7 @@ static bool da9052_reg_writeable(struct device *dev, unsigned int reg)
167 case DA9052_EVENT_B_REG: 167 case DA9052_EVENT_B_REG:
168 case DA9052_EVENT_C_REG: 168 case DA9052_EVENT_C_REG:
169 case DA9052_EVENT_D_REG: 169 case DA9052_EVENT_D_REG:
170 case DA9052_FAULTLOG_REG:
170 case DA9052_IRQ_MASK_A_REG: 171 case DA9052_IRQ_MASK_A_REG:
171 case DA9052_IRQ_MASK_B_REG: 172 case DA9052_IRQ_MASK_B_REG:
172 case DA9052_IRQ_MASK_C_REG: 173 case DA9052_IRQ_MASK_C_REG:
@@ -541,6 +542,52 @@ const struct regmap_config da9052_regmap_config = {
541}; 542};
542EXPORT_SYMBOL_GPL(da9052_regmap_config); 543EXPORT_SYMBOL_GPL(da9052_regmap_config);
543 544
545static int da9052_clear_fault_log(struct da9052 *da9052)
546{
547 int ret = 0;
548 int fault_log = 0;
549
550 fault_log = da9052_reg_read(da9052, DA9052_FAULTLOG_REG);
551 if (fault_log < 0) {
552 dev_err(da9052->dev,
553 "Cannot read FAULT_LOG %d\n", fault_log);
554 return fault_log;
555 }
556
557 if (fault_log) {
558 if (fault_log & DA9052_FAULTLOG_TWDERROR)
559 dev_dbg(da9052->dev,
560 "Fault log entry detected: TWD_ERROR\n");
561 if (fault_log & DA9052_FAULTLOG_VDDFAULT)
562 dev_dbg(da9052->dev,
563 "Fault log entry detected: VDD_FAULT\n");
564 if (fault_log & DA9052_FAULTLOG_VDDSTART)
565 dev_dbg(da9052->dev,
566 "Fault log entry detected: VDD_START\n");
567 if (fault_log & DA9052_FAULTLOG_TEMPOVER)
568 dev_dbg(da9052->dev,
569 "Fault log entry detected: TEMP_OVER\n");
570 if (fault_log & DA9052_FAULTLOG_KEYSHUT)
571 dev_dbg(da9052->dev,
572 "Fault log entry detected: KEY_SHUT\n");
573 if (fault_log & DA9052_FAULTLOG_NSDSET)
574 dev_dbg(da9052->dev,
575 "Fault log entry detected: nSD_SHUT\n");
576 if (fault_log & DA9052_FAULTLOG_WAITSET)
577 dev_dbg(da9052->dev,
578 "Fault log entry detected: WAIT_SHUT\n");
579
580 ret = da9052_reg_write(da9052,
581 DA9052_FAULTLOG_REG,
582 0xFF);
583 if (ret < 0)
584 dev_err(da9052->dev,
585 "Cannot reset FAULT_LOG values %d\n", ret);
586 }
587
588 return ret;
589}
590
544int da9052_device_init(struct da9052 *da9052, u8 chip_id) 591int da9052_device_init(struct da9052 *da9052, u8 chip_id)
545{ 592{
546 struct da9052_pdata *pdata = dev_get_platdata(da9052->dev); 593 struct da9052_pdata *pdata = dev_get_platdata(da9052->dev);
@@ -549,6 +596,10 @@ int da9052_device_init(struct da9052 *da9052, u8 chip_id)
549 mutex_init(&da9052->auxadc_lock); 596 mutex_init(&da9052->auxadc_lock);
550 init_completion(&da9052->done); 597 init_completion(&da9052->done);
551 598
599 ret = da9052_clear_fault_log(da9052);
600 if (ret < 0)
601 dev_warn(da9052->dev, "Cannot clear FAULT_LOG\n");
602
552 if (pdata && pdata->init != NULL) 603 if (pdata && pdata->init != NULL)
553 pdata->init(da9052); 604 pdata->init(da9052);
554 605
diff --git a/drivers/mfd/da9063-core.c b/drivers/mfd/da9063-core.c
index af841c165787..6c2870d4e754 100644
--- a/drivers/mfd/da9063-core.c
+++ b/drivers/mfd/da9063-core.c
@@ -4,8 +4,8 @@
4 * Copyright 2012 Dialog Semiconductors Ltd. 4 * Copyright 2012 Dialog Semiconductors Ltd.
5 * Copyright 2013 Philipp Zabel, Pengutronix 5 * Copyright 2013 Philipp Zabel, Pengutronix
6 * 6 *
7 * Author: Krystian Garbaciak <krystian.garbaciak@diasemi.com>, 7 * Author: Krystian Garbaciak, Dialog Semiconductor
8 * Michal Hajduk <michal.hajduk@diasemi.com> 8 * Author: Michal Hajduk, Dialog Semiconductor
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify it 10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the 11 * under the terms of the GNU General Public License as published by the
@@ -242,5 +242,6 @@ void da9063_device_exit(struct da9063 *da9063)
242} 242}
243 243
244MODULE_DESCRIPTION("PMIC driver for Dialog DA9063"); 244MODULE_DESCRIPTION("PMIC driver for Dialog DA9063");
245MODULE_AUTHOR("Krystian Garbaciak <krystian.garbaciak@diasemi.com>, Michal Hajduk <michal.hajduk@diasemi.com>"); 245MODULE_AUTHOR("Krystian Garbaciak");
246MODULE_AUTHOR("Michal Hajduk");
246MODULE_LICENSE("GPL"); 247MODULE_LICENSE("GPL");
diff --git a/drivers/mfd/da9063-i2c.c b/drivers/mfd/da9063-i2c.c
index 73901084945f..981805a2c521 100644
--- a/drivers/mfd/da9063-i2c.c
+++ b/drivers/mfd/da9063-i2c.c
@@ -3,7 +3,7 @@
3 * Copyright 2012 Dialog Semiconductor Ltd. 3 * Copyright 2012 Dialog Semiconductor Ltd.
4 * Copyright 2013 Philipp Zabel, Pengutronix 4 * Copyright 2013 Philipp Zabel, Pengutronix
5 * 5 *
6 * Author: Krystian Garbaciak <krystian.garbaciak@diasemi.com> 6 * Author: Krystian Garbaciak, Dialog Semiconductor
7 * 7 *
8 * This program is free software; you can redistribute it and/or modify it 8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the 9 * under the terms of the GNU General Public License as published by the
diff --git a/drivers/mfd/da9063-irq.c b/drivers/mfd/da9063-irq.c
index 7e903fcb8813..207bbfe55449 100644
--- a/drivers/mfd/da9063-irq.c
+++ b/drivers/mfd/da9063-irq.c
@@ -3,7 +3,7 @@
3 * Copyright 2012 Dialog Semiconductor Ltd. 3 * Copyright 2012 Dialog Semiconductor Ltd.
4 * Copyright 2013 Philipp Zabel, Pengutronix 4 * Copyright 2013 Philipp Zabel, Pengutronix
5 * 5 *
6 * Author: Michal Hajduk <michal.hajduk@diasemi.com> 6 * Author: Michal Hajduk, Dialog Semiconductor
7 * 7 *
8 * This program is free software; you can redistribute it and/or modify it 8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the 9 * under the terms of the GNU General Public License as published by the
diff --git a/drivers/mfd/db8500-prcmu.c b/drivers/mfd/db8500-prcmu.c
index 388e268b9bcf..ca38a6a14110 100644
--- a/drivers/mfd/db8500-prcmu.c
+++ b/drivers/mfd/db8500-prcmu.c
@@ -938,25 +938,6 @@ int db8500_prcmu_get_ddr_opp(void)
938 return readb(PRCM_DDR_SUBSYS_APE_MINBW); 938 return readb(PRCM_DDR_SUBSYS_APE_MINBW);
939} 939}
940 940
941/**
942 * db8500_set_ddr_opp - set the appropriate DDR OPP
943 * @opp: The new DDR operating point to which transition is to be made
944 * Returns: 0 on success, non-zero on failure
945 *
946 * This function sets the operating point of the DDR.
947 */
948static bool enable_set_ddr_opp;
949int db8500_prcmu_set_ddr_opp(u8 opp)
950{
951 if (opp < DDR_100_OPP || opp > DDR_25_OPP)
952 return -EINVAL;
953 /* Changing the DDR OPP can hang the hardware pre-v21 */
954 if (enable_set_ddr_opp)
955 writeb(opp, PRCM_DDR_SUBSYS_APE_MINBW);
956
957 return 0;
958}
959
960/* Divide the frequency of certain clocks by 2 for APE_50_PARTLY_25_OPP. */ 941/* Divide the frequency of certain clocks by 2 for APE_50_PARTLY_25_OPP. */
961static void request_even_slower_clocks(bool enable) 942static void request_even_slower_clocks(bool enable)
962{ 943{
diff --git a/drivers/mfd/dm355evm_msp.c b/drivers/mfd/dm355evm_msp.c
index 270e19c0bba1..86eca614507b 100644
--- a/drivers/mfd/dm355evm_msp.c
+++ b/drivers/mfd/dm355evm_msp.c
@@ -209,7 +209,7 @@ static struct device *add_child(struct i2c_client *client, const char *name,
209 status = platform_device_add_data(pdev, pdata, pdata_len); 209 status = platform_device_add_data(pdev, pdata, pdata_len);
210 if (status < 0) { 210 if (status < 0) {
211 dev_dbg(&pdev->dev, "can't add platform_data\n"); 211 dev_dbg(&pdev->dev, "can't add platform_data\n");
212 goto err; 212 goto put_device;
213 } 213 }
214 } 214 }
215 215
@@ -222,19 +222,20 @@ static struct device *add_child(struct i2c_client *client, const char *name,
222 status = platform_device_add_resources(pdev, &r, 1); 222 status = platform_device_add_resources(pdev, &r, 1);
223 if (status < 0) { 223 if (status < 0) {
224 dev_dbg(&pdev->dev, "can't add irq\n"); 224 dev_dbg(&pdev->dev, "can't add irq\n");
225 goto err; 225 goto put_device;
226 } 226 }
227 } 227 }
228 228
229 status = platform_device_add(pdev); 229 status = platform_device_add(pdev);
230 if (status)
231 goto put_device;
230 232
231err:
232 if (status < 0) {
233 platform_device_put(pdev);
234 dev_err(&client->dev, "can't add %s dev\n", name);
235 return ERR_PTR(status);
236 }
237 return &pdev->dev; 233 return &pdev->dev;
234
235put_device:
236 platform_device_put(pdev);
237 dev_err(&client->dev, "failed to add device %s\n", name);
238 return ERR_PTR(status);
238} 239}
239 240
240static int add_children(struct i2c_client *client) 241static int add_children(struct i2c_client *client)
diff --git a/drivers/mfd/exynos-lpass.c b/drivers/mfd/exynos-lpass.c
new file mode 100644
index 000000000000..2e064fb8826f
--- /dev/null
+++ b/drivers/mfd/exynos-lpass.c
@@ -0,0 +1,185 @@
1/*
2 * Copyright (C) 2015 - 2016 Samsung Electronics Co., Ltd.
3 *
4 * Authors: Inha Song <ideal.song@samsung.com>
5 * Sylwester Nawrocki <s.nawrocki@samsung.com>
6 *
7 * Samsung Exynos SoC series Low Power Audio Subsystem driver.
8 *
9 * This module provides regmap for the Top SFR region and instantiates
10 * devices for IP blocks like DMAC, I2S, UART.
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 and
14 * only version 2 as published by the Free Software Foundation.
15 */
16
17#include <linux/delay.h>
18#include <linux/io.h>
19#include <linux/module.h>
20#include <linux/mfd/syscon.h>
21#include <linux/mfd/syscon/exynos5-pmu.h>
22#include <linux/of.h>
23#include <linux/of_platform.h>
24#include <linux/platform_device.h>
25#include <linux/regmap.h>
26#include <linux/types.h>
27
28/* LPASS Top register definitions */
29#define SFR_LPASS_CORE_SW_RESET 0x08
30#define LPASS_SB_SW_RESET BIT(11)
31#define LPASS_UART_SW_RESET BIT(10)
32#define LPASS_PCM_SW_RESET BIT(9)
33#define LPASS_I2S_SW_RESET BIT(8)
34#define LPASS_WDT1_SW_RESET BIT(4)
35#define LPASS_WDT0_SW_RESET BIT(3)
36#define LPASS_TIMER_SW_RESET BIT(2)
37#define LPASS_MEM_SW_RESET BIT(1)
38#define LPASS_DMA_SW_RESET BIT(0)
39
40#define SFR_LPASS_INTR_CA5_MASK 0x48
41#define SFR_LPASS_INTR_CPU_MASK 0x58
42#define LPASS_INTR_APM BIT(9)
43#define LPASS_INTR_MIF BIT(8)
44#define LPASS_INTR_TIMER BIT(7)
45#define LPASS_INTR_DMA BIT(6)
46#define LPASS_INTR_GPIO BIT(5)
47#define LPASS_INTR_I2S BIT(4)
48#define LPASS_INTR_PCM BIT(3)
49#define LPASS_INTR_SLIMBUS BIT(2)
50#define LPASS_INTR_UART BIT(1)
51#define LPASS_INTR_SFR BIT(0)
52
53struct exynos_lpass {
54 /* pointer to the Power Management Unit regmap */
55 struct regmap *pmu;
56 /* pointer to the LPASS TOP regmap */
57 struct regmap *top;
58};
59
60static void exynos_lpass_core_sw_reset(struct exynos_lpass *lpass, int mask)
61{
62 unsigned int val = 0;
63
64 regmap_read(lpass->top, SFR_LPASS_CORE_SW_RESET, &val);
65
66 val &= ~mask;
67 regmap_write(lpass->top, SFR_LPASS_CORE_SW_RESET, val);
68
69 usleep_range(100, 150);
70
71 val |= mask;
72 regmap_write(lpass->top, SFR_LPASS_CORE_SW_RESET, val);
73}
74
75static void exynos_lpass_enable(struct exynos_lpass *lpass)
76{
77 /* Unmask SFR, DMA and I2S interrupt */
78 regmap_write(lpass->top, SFR_LPASS_INTR_CA5_MASK,
79 LPASS_INTR_SFR | LPASS_INTR_DMA | LPASS_INTR_I2S);
80
81 regmap_write(lpass->top, SFR_LPASS_INTR_CPU_MASK,
82 LPASS_INTR_SFR | LPASS_INTR_DMA | LPASS_INTR_I2S);
83
84 /* Activate related PADs from retention state */
85 regmap_write(lpass->pmu, EXYNOS5433_PAD_RETENTION_AUD_OPTION,
86 EXYNOS5433_PAD_INITIATE_WAKEUP_FROM_LOWPWR);
87
88 exynos_lpass_core_sw_reset(lpass, LPASS_I2S_SW_RESET);
89 exynos_lpass_core_sw_reset(lpass, LPASS_DMA_SW_RESET);
90 exynos_lpass_core_sw_reset(lpass, LPASS_MEM_SW_RESET);
91}
92
93static void exynos_lpass_disable(struct exynos_lpass *lpass)
94{
95 /* Mask any unmasked IP interrupt sources */
96 regmap_write(lpass->top, SFR_LPASS_INTR_CPU_MASK, 0);
97 regmap_write(lpass->top, SFR_LPASS_INTR_CA5_MASK, 0);
98
99 /* Deactivate related PADs from retention state */
100 regmap_write(lpass->pmu, EXYNOS5433_PAD_RETENTION_AUD_OPTION, 0);
101}
102
103static const struct regmap_config exynos_lpass_reg_conf = {
104 .reg_bits = 32,
105 .reg_stride = 4,
106 .val_bits = 32,
107 .max_register = 0xfc,
108 .fast_io = true,
109};
110
111static int exynos_lpass_probe(struct platform_device *pdev)
112{
113 struct device *dev = &pdev->dev;
114 struct exynos_lpass *lpass;
115 void __iomem *base_top;
116 struct resource *res;
117
118 lpass = devm_kzalloc(dev, sizeof(*lpass), GFP_KERNEL);
119 if (!lpass)
120 return -ENOMEM;
121
122 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
123 base_top = devm_ioremap_resource(dev, res);
124 if (IS_ERR(base_top))
125 return PTR_ERR(base_top);
126
127 lpass->top = regmap_init_mmio(dev, base_top,
128 &exynos_lpass_reg_conf);
129 if (IS_ERR(lpass->top)) {
130 dev_err(dev, "LPASS top regmap initialization failed\n");
131 return PTR_ERR(lpass->top);
132 }
133
134 lpass->pmu = syscon_regmap_lookup_by_phandle(dev->of_node,
135 "samsung,pmu-syscon");
136 if (IS_ERR(lpass->pmu)) {
137 dev_err(dev, "Failed to lookup PMU regmap\n");
138 return PTR_ERR(lpass->pmu);
139 }
140
141 platform_set_drvdata(pdev, lpass);
142 exynos_lpass_enable(lpass);
143
144 return of_platform_populate(dev->of_node, NULL, NULL, dev);
145}
146
147static int __maybe_unused exynos_lpass_suspend(struct device *dev)
148{
149 struct exynos_lpass *lpass = dev_get_drvdata(dev);
150
151 exynos_lpass_disable(lpass);
152
153 return 0;
154}
155
156static int __maybe_unused exynos_lpass_resume(struct device *dev)
157{
158 struct exynos_lpass *lpass = dev_get_drvdata(dev);
159
160 exynos_lpass_enable(lpass);
161
162 return 0;
163}
164
165static SIMPLE_DEV_PM_OPS(lpass_pm_ops, exynos_lpass_suspend,
166 exynos_lpass_resume);
167
168static const struct of_device_id exynos_lpass_of_match[] = {
169 { .compatible = "samsung,exynos5433-lpass" },
170 { },
171};
172MODULE_DEVICE_TABLE(of, exynos_lpass_of_match);
173
174static struct platform_driver exynos_lpass_driver = {
175 .driver = {
176 .name = "exynos-lpass",
177 .pm = &lpass_pm_ops,
178 .of_match_table = exynos_lpass_of_match,
179 },
180 .probe = exynos_lpass_probe,
181};
182module_platform_driver(exynos_lpass_driver);
183
184MODULE_DESCRIPTION("Samsung Low Power Audio Subsystem driver");
185MODULE_LICENSE("GPL v2");
diff --git a/drivers/mfd/intel-lpss-acpi.c b/drivers/mfd/intel-lpss-acpi.c
index 7ddc4a9563ea..6bf8d643d942 100644
--- a/drivers/mfd/intel-lpss-acpi.c
+++ b/drivers/mfd/intel-lpss-acpi.c
@@ -52,6 +52,18 @@ static const struct intel_lpss_platform_info bxt_i2c_info = {
52 .properties = bxt_i2c_properties, 52 .properties = bxt_i2c_properties,
53}; 53};
54 54
55static struct property_entry apl_i2c_properties[] = {
56 PROPERTY_ENTRY_U32("i2c-sda-hold-time-ns", 207),
57 PROPERTY_ENTRY_U32("i2c-sda-falling-time-ns", 171),
58 PROPERTY_ENTRY_U32("i2c-scl-falling-time-ns", 208),
59 { },
60};
61
62static const struct intel_lpss_platform_info apl_i2c_info = {
63 .clk_rate = 133000000,
64 .properties = apl_i2c_properties,
65};
66
55static const struct acpi_device_id intel_lpss_acpi_ids[] = { 67static const struct acpi_device_id intel_lpss_acpi_ids[] = {
56 /* SPT */ 68 /* SPT */
57 { "INT3446", (kernel_ulong_t)&spt_i2c_info }, 69 { "INT3446", (kernel_ulong_t)&spt_i2c_info },
@@ -61,7 +73,7 @@ static const struct acpi_device_id intel_lpss_acpi_ids[] = {
61 { "80860ABC", (kernel_ulong_t)&bxt_info }, 73 { "80860ABC", (kernel_ulong_t)&bxt_info },
62 { "80860AC2", (kernel_ulong_t)&bxt_info }, 74 { "80860AC2", (kernel_ulong_t)&bxt_info },
63 /* APL */ 75 /* APL */
64 { "80865AAC", (kernel_ulong_t)&bxt_i2c_info }, 76 { "80865AAC", (kernel_ulong_t)&apl_i2c_info },
65 { "80865ABC", (kernel_ulong_t)&bxt_info }, 77 { "80865ABC", (kernel_ulong_t)&bxt_info },
66 { "80865AC2", (kernel_ulong_t)&bxt_info }, 78 { "80865AC2", (kernel_ulong_t)&bxt_info },
67 { } 79 { }
diff --git a/drivers/mfd/intel-lpss-pci.c b/drivers/mfd/intel-lpss-pci.c
index 1d79a3c9370f..3228fd182a99 100644
--- a/drivers/mfd/intel-lpss-pci.c
+++ b/drivers/mfd/intel-lpss-pci.c
@@ -111,6 +111,31 @@ static const struct intel_lpss_platform_info bxt_i2c_info = {
111 .properties = bxt_i2c_properties, 111 .properties = bxt_i2c_properties,
112}; 112};
113 113
114static struct property_entry apl_i2c_properties[] = {
115 PROPERTY_ENTRY_U32("i2c-sda-hold-time-ns", 207),
116 PROPERTY_ENTRY_U32("i2c-sda-falling-time-ns", 171),
117 PROPERTY_ENTRY_U32("i2c-scl-falling-time-ns", 208),
118 { },
119};
120
121static const struct intel_lpss_platform_info apl_i2c_info = {
122 .clk_rate = 133000000,
123 .properties = apl_i2c_properties,
124};
125
126static const struct intel_lpss_platform_info kbl_info = {
127 .clk_rate = 120000000,
128};
129
130static const struct intel_lpss_platform_info kbl_uart_info = {
131 .clk_rate = 120000000,
132 .clk_con_id = "baudclk",
133};
134
135static const struct intel_lpss_platform_info kbl_i2c_info = {
136 .clk_rate = 133000000,
137};
138
114static const struct pci_device_id intel_lpss_pci_ids[] = { 139static const struct pci_device_id intel_lpss_pci_ids[] = {
115 /* BXT A-Step */ 140 /* BXT A-Step */
116 { PCI_VDEVICE(INTEL, 0x0aac), (kernel_ulong_t)&bxt_i2c_info }, 141 { PCI_VDEVICE(INTEL, 0x0aac), (kernel_ulong_t)&bxt_i2c_info },
@@ -146,14 +171,14 @@ static const struct pci_device_id intel_lpss_pci_ids[] = {
146 { PCI_VDEVICE(INTEL, 0x1aee), (kernel_ulong_t)&bxt_uart_info }, 171 { PCI_VDEVICE(INTEL, 0x1aee), (kernel_ulong_t)&bxt_uart_info },
147 172
148 /* APL */ 173 /* APL */
149 { PCI_VDEVICE(INTEL, 0x5aac), (kernel_ulong_t)&bxt_i2c_info }, 174 { PCI_VDEVICE(INTEL, 0x5aac), (kernel_ulong_t)&apl_i2c_info },
150 { PCI_VDEVICE(INTEL, 0x5aae), (kernel_ulong_t)&bxt_i2c_info }, 175 { PCI_VDEVICE(INTEL, 0x5aae), (kernel_ulong_t)&apl_i2c_info },
151 { PCI_VDEVICE(INTEL, 0x5ab0), (kernel_ulong_t)&bxt_i2c_info }, 176 { PCI_VDEVICE(INTEL, 0x5ab0), (kernel_ulong_t)&apl_i2c_info },
152 { PCI_VDEVICE(INTEL, 0x5ab2), (kernel_ulong_t)&bxt_i2c_info }, 177 { PCI_VDEVICE(INTEL, 0x5ab2), (kernel_ulong_t)&apl_i2c_info },
153 { PCI_VDEVICE(INTEL, 0x5ab4), (kernel_ulong_t)&bxt_i2c_info }, 178 { PCI_VDEVICE(INTEL, 0x5ab4), (kernel_ulong_t)&apl_i2c_info },
154 { PCI_VDEVICE(INTEL, 0x5ab6), (kernel_ulong_t)&bxt_i2c_info }, 179 { PCI_VDEVICE(INTEL, 0x5ab6), (kernel_ulong_t)&apl_i2c_info },
155 { PCI_VDEVICE(INTEL, 0x5ab8), (kernel_ulong_t)&bxt_i2c_info }, 180 { PCI_VDEVICE(INTEL, 0x5ab8), (kernel_ulong_t)&apl_i2c_info },
156 { PCI_VDEVICE(INTEL, 0x5aba), (kernel_ulong_t)&bxt_i2c_info }, 181 { PCI_VDEVICE(INTEL, 0x5aba), (kernel_ulong_t)&apl_i2c_info },
157 { PCI_VDEVICE(INTEL, 0x5abc), (kernel_ulong_t)&bxt_uart_info }, 182 { PCI_VDEVICE(INTEL, 0x5abc), (kernel_ulong_t)&bxt_uart_info },
158 { PCI_VDEVICE(INTEL, 0x5abe), (kernel_ulong_t)&bxt_uart_info }, 183 { PCI_VDEVICE(INTEL, 0x5abe), (kernel_ulong_t)&bxt_uart_info },
159 { PCI_VDEVICE(INTEL, 0x5ac0), (kernel_ulong_t)&bxt_uart_info }, 184 { PCI_VDEVICE(INTEL, 0x5ac0), (kernel_ulong_t)&bxt_uart_info },
@@ -181,6 +206,16 @@ static const struct pci_device_id intel_lpss_pci_ids[] = {
181 { PCI_VDEVICE(INTEL, 0xa160), (kernel_ulong_t)&spt_i2c_info }, 206 { PCI_VDEVICE(INTEL, 0xa160), (kernel_ulong_t)&spt_i2c_info },
182 { PCI_VDEVICE(INTEL, 0xa161), (kernel_ulong_t)&spt_i2c_info }, 207 { PCI_VDEVICE(INTEL, 0xa161), (kernel_ulong_t)&spt_i2c_info },
183 { PCI_VDEVICE(INTEL, 0xa166), (kernel_ulong_t)&spt_uart_info }, 208 { PCI_VDEVICE(INTEL, 0xa166), (kernel_ulong_t)&spt_uart_info },
209 /* KBL-H */
210 { PCI_VDEVICE(INTEL, 0xa2a7), (kernel_ulong_t)&kbl_uart_info },
211 { PCI_VDEVICE(INTEL, 0xa2a8), (kernel_ulong_t)&kbl_uart_info },
212 { PCI_VDEVICE(INTEL, 0xa2a9), (kernel_ulong_t)&kbl_info },
213 { PCI_VDEVICE(INTEL, 0xa2aa), (kernel_ulong_t)&kbl_info },
214 { PCI_VDEVICE(INTEL, 0xa2e0), (kernel_ulong_t)&kbl_i2c_info },
215 { PCI_VDEVICE(INTEL, 0xa2e1), (kernel_ulong_t)&kbl_i2c_info },
216 { PCI_VDEVICE(INTEL, 0xa2e2), (kernel_ulong_t)&kbl_i2c_info },
217 { PCI_VDEVICE(INTEL, 0xa2e3), (kernel_ulong_t)&kbl_i2c_info },
218 { PCI_VDEVICE(INTEL, 0xa2e6), (kernel_ulong_t)&kbl_uart_info },
184 { } 219 { }
185}; 220};
186MODULE_DEVICE_TABLE(pci, intel_lpss_pci_ids); 221MODULE_DEVICE_TABLE(pci, intel_lpss_pci_ids);
diff --git a/drivers/mfd/intel_msic.c b/drivers/mfd/intel_msic.c
index 25d486c543cb..2017446c5b4b 100644
--- a/drivers/mfd/intel_msic.c
+++ b/drivers/mfd/intel_msic.c
@@ -12,7 +12,7 @@
12#include <linux/err.h> 12#include <linux/err.h>
13#include <linux/gpio.h> 13#include <linux/gpio.h>
14#include <linux/io.h> 14#include <linux/io.h>
15#include <linux/module.h> 15#include <linux/init.h>
16#include <linux/mfd/core.h> 16#include <linux/mfd/core.h>
17#include <linux/mfd/intel_msic.h> 17#include <linux/mfd/intel_msic.h>
18#include <linux/platform_device.h> 18#include <linux/platform_device.h>
@@ -449,9 +449,4 @@ static struct platform_driver intel_msic_driver = {
449 .name = "intel_msic", 449 .name = "intel_msic",
450 }, 450 },
451}; 451};
452 452builtin_platform_driver(intel_msic_driver);
453module_platform_driver(intel_msic_driver);
454
455MODULE_DESCRIPTION("Driver for Intel MSIC");
456MODULE_AUTHOR("Mika Westerberg <mika.westerberg@linux.intel.com>");
457MODULE_LICENSE("GPL");
diff --git a/drivers/mfd/intel_soc_pmic_bxtwc.c b/drivers/mfd/intel_soc_pmic_bxtwc.c
index b9428767e615..43e54b7e908f 100644
--- a/drivers/mfd/intel_soc_pmic_bxtwc.c
+++ b/drivers/mfd/intel_soc_pmic_bxtwc.c
@@ -47,6 +47,8 @@
47#define BXTWC_MIRQLVL1 0x4E0E 47#define BXTWC_MIRQLVL1 0x4E0E
48#define BXTWC_MPWRTNIRQ 0x4E0F 48#define BXTWC_MPWRTNIRQ 0x4E0F
49 49
50#define BXTWC_MIRQLVL1_MCHGR BIT(5)
51
50#define BXTWC_MTHRM0IRQ 0x4E12 52#define BXTWC_MTHRM0IRQ 0x4E12
51#define BXTWC_MTHRM1IRQ 0x4E13 53#define BXTWC_MTHRM1IRQ 0x4E13
52#define BXTWC_MTHRM2IRQ 0x4E14 54#define BXTWC_MTHRM2IRQ 0x4E14
@@ -109,7 +111,7 @@ static const struct regmap_irq bxtwc_regmap_irqs_level2[] = {
109 REGMAP_IRQ_REG(BXTWC_THRM2_IRQ, 2, 0xff), 111 REGMAP_IRQ_REG(BXTWC_THRM2_IRQ, 2, 0xff),
110 REGMAP_IRQ_REG(BXTWC_BCU_IRQ, 3, 0x1f), 112 REGMAP_IRQ_REG(BXTWC_BCU_IRQ, 3, 0x1f),
111 REGMAP_IRQ_REG(BXTWC_ADC_IRQ, 4, 0xff), 113 REGMAP_IRQ_REG(BXTWC_ADC_IRQ, 4, 0xff),
112 REGMAP_IRQ_REG(BXTWC_CHGR0_IRQ, 5, 0x1f), 114 REGMAP_IRQ_REG(BXTWC_CHGR0_IRQ, 5, 0x3f),
113 REGMAP_IRQ_REG(BXTWC_CHGR1_IRQ, 6, 0x1f), 115 REGMAP_IRQ_REG(BXTWC_CHGR1_IRQ, 6, 0x1f),
114 REGMAP_IRQ_REG(BXTWC_GPIO0_IRQ, 7, 0xff), 116 REGMAP_IRQ_REG(BXTWC_GPIO0_IRQ, 7, 0xff),
115 REGMAP_IRQ_REG(BXTWC_GPIO1_IRQ, 8, 0x3f), 117 REGMAP_IRQ_REG(BXTWC_GPIO1_IRQ, 8, 0x3f),
@@ -143,6 +145,10 @@ static struct resource adc_resources[] = {
143 DEFINE_RES_IRQ_NAMED(BXTWC_ADC_IRQ, "ADC"), 145 DEFINE_RES_IRQ_NAMED(BXTWC_ADC_IRQ, "ADC"),
144}; 146};
145 147
148static struct resource usbc_resources[] = {
149 DEFINE_RES_IRQ_NAMED(BXTWC_CHGR0_IRQ, "USBC"),
150};
151
146static struct resource charger_resources[] = { 152static struct resource charger_resources[] = {
147 DEFINE_RES_IRQ_NAMED(BXTWC_CHGR0_IRQ, "CHARGER"), 153 DEFINE_RES_IRQ_NAMED(BXTWC_CHGR0_IRQ, "CHARGER"),
148 DEFINE_RES_IRQ_NAMED(BXTWC_CHGR1_IRQ, "CHARGER1"), 154 DEFINE_RES_IRQ_NAMED(BXTWC_CHGR1_IRQ, "CHARGER1"),
@@ -170,6 +176,11 @@ static struct mfd_cell bxt_wc_dev[] = {
170 .resources = thermal_resources, 176 .resources = thermal_resources,
171 }, 177 },
172 { 178 {
179 .name = "bxt_wcove_usbc",
180 .num_resources = ARRAY_SIZE(usbc_resources),
181 .resources = usbc_resources,
182 },
183 {
173 .name = "bxt_wcove_ext_charger", 184 .name = "bxt_wcove_ext_charger",
174 .num_resources = ARRAY_SIZE(charger_resources), 185 .num_resources = ARRAY_SIZE(charger_resources),
175 .resources = charger_resources, 186 .resources = charger_resources,
@@ -403,6 +414,16 @@ static int bxtwc_probe(struct platform_device *pdev)
403 goto err_sysfs; 414 goto err_sysfs;
404 } 415 }
405 416
417 /*
418 * There is known hw bug. Upon reset BIT 5 of register
419 * BXTWC_CHGR_LVL1_IRQ is 0 which is the expected value. However,
420 * later it's set to 1(masked) automatically by hardware. So we
421 * have the software workaround here to unmaksed it in order to let
422 * charger interrutp work.
423 */
424 regmap_update_bits(pmic->regmap, BXTWC_MIRQLVL1,
425 BXTWC_MIRQLVL1_MCHGR, 0);
426
406 return 0; 427 return 0;
407 428
408err_sysfs: 429err_sysfs:
diff --git a/drivers/mfd/lp873x.c b/drivers/mfd/lp873x.c
index 9af064c940ee..873c608e6a5d 100644
--- a/drivers/mfd/lp873x.c
+++ b/drivers/mfd/lp873x.c
@@ -53,8 +53,6 @@ static int lp873x_probe(struct i2c_client *client,
53 return ret; 53 return ret;
54 } 54 }
55 55
56 mutex_init(&lp873->lock);
57
58 ret = regmap_read(lp873->regmap, LP873X_REG_OTP_REV, &otpid); 56 ret = regmap_read(lp873->regmap, LP873X_REG_OTP_REV, &otpid);
59 if (ret) { 57 if (ret) {
60 dev_err(lp873->dev, "Failed to read OTP ID\n"); 58 dev_err(lp873->dev, "Failed to read OTP ID\n");
diff --git a/drivers/mfd/max14577.c b/drivers/mfd/max14577.c
index 6c245128ab2e..6cbe96b28f42 100644
--- a/drivers/mfd/max14577.c
+++ b/drivers/mfd/max14577.c
@@ -3,7 +3,7 @@
3 * 3 *
4 * Copyright (C) 2014 Samsung Electronics 4 * Copyright (C) 2014 Samsung Electronics
5 * Chanwoo Choi <cw00.choi@samsung.com> 5 * Chanwoo Choi <cw00.choi@samsung.com>
6 * Krzysztof Kozlowski <k.kozlowski@samsung.com> 6 * Krzysztof Kozlowski <krzk@kernel.org>
7 * 7 *
8 * This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by 9 * it under the terms of the GNU General Public License as published by
@@ -569,6 +569,6 @@ static void __exit max14577_i2c_exit(void)
569} 569}
570module_exit(max14577_i2c_exit); 570module_exit(max14577_i2c_exit);
571 571
572MODULE_AUTHOR("Chanwoo Choi <cw00.choi@samsung.com>, Krzysztof Kozlowski <k.kozlowski@samsung.com>"); 572MODULE_AUTHOR("Chanwoo Choi <cw00.choi@samsung.com>, Krzysztof Kozlowski <krzk@kernel.org>");
573MODULE_DESCRIPTION("Maxim 14577/77836 multi-function core driver"); 573MODULE_DESCRIPTION("Maxim 14577/77836 multi-function core driver");
574MODULE_LICENSE("GPL"); 574MODULE_LICENSE("GPL");
diff --git a/drivers/mfd/max8997-irq.c b/drivers/mfd/max8997-irq.c
index b95a46d79b9d..326f17b632a7 100644
--- a/drivers/mfd/max8997-irq.c
+++ b/drivers/mfd/max8997-irq.c
@@ -139,7 +139,7 @@ static void max8997_irq_sync_unlock(struct irq_data *data)
139 mutex_unlock(&max8997->irqlock); 139 mutex_unlock(&max8997->irqlock);
140} 140}
141 141
142static const inline struct max8997_irq_data * 142inline static const struct max8997_irq_data *
143irq_to_max8997_irq(struct max8997_dev *max8997, struct irq_data *data) 143irq_to_max8997_irq(struct max8997_dev *max8997, struct irq_data *data)
144{ 144{
145 return &max8997_irqs[data->hwirq]; 145 return &max8997_irqs[data->hwirq];
diff --git a/drivers/mfd/omap-usb-host.c b/drivers/mfd/omap-usb-host.c
index 1d924d1533c0..7aab376ecb84 100644
--- a/drivers/mfd/omap-usb-host.c
+++ b/drivers/mfd/omap-usb-host.c
@@ -162,7 +162,7 @@ static const char * const port_modes[] = {
162 * provided port mode string as per the port_modes table. 162 * provided port mode string as per the port_modes table.
163 * If no match is found it returns -ENODEV 163 * If no match is found it returns -ENODEV
164 */ 164 */
165static const int omap_usbhs_get_dt_port_mode(const char *mode) 165static int omap_usbhs_get_dt_port_mode(const char *mode)
166{ 166{
167 int i; 167 int i;
168 168
diff --git a/drivers/mfd/pm8921-core.c b/drivers/mfd/pm8921-core.c
index 1b7ec0870c2a..0e3a2ea25942 100644
--- a/drivers/mfd/pm8921-core.c
+++ b/drivers/mfd/pm8921-core.c
@@ -309,6 +309,7 @@ static const struct regmap_config ssbi_regmap_config = {
309}; 309};
310 310
311static const struct of_device_id pm8921_id_table[] = { 311static const struct of_device_id pm8921_id_table[] = {
312 { .compatible = "qcom,pm8018", },
312 { .compatible = "qcom,pm8058", }, 313 { .compatible = "qcom,pm8058", },
313 { .compatible = "qcom,pm8921", }, 314 { .compatible = "qcom,pm8921", },
314 { } 315 { }
diff --git a/drivers/mfd/qcom_rpm.c b/drivers/mfd/qcom_rpm.c
index 2e44323455dd..52fafea06067 100644
--- a/drivers/mfd/qcom_rpm.c
+++ b/drivers/mfd/qcom_rpm.c
@@ -21,6 +21,7 @@
21#include <linux/mfd/qcom_rpm.h> 21#include <linux/mfd/qcom_rpm.h>
22#include <linux/mfd/syscon.h> 22#include <linux/mfd/syscon.h>
23#include <linux/regmap.h> 23#include <linux/regmap.h>
24#include <linux/clk.h>
24 25
25#include <dt-bindings/mfd/qcom-rpm.h> 26#include <dt-bindings/mfd/qcom-rpm.h>
26 27
@@ -48,6 +49,7 @@ struct qcom_rpm {
48 struct regmap *ipc_regmap; 49 struct regmap *ipc_regmap;
49 unsigned ipc_offset; 50 unsigned ipc_offset;
50 unsigned ipc_bit; 51 unsigned ipc_bit;
52 struct clk *ramclk;
51 53
52 struct completion ack; 54 struct completion ack;
53 struct mutex lock; 55 struct mutex lock;
@@ -388,11 +390,62 @@ static const struct qcom_rpm_data ipq806x_template = {
388 .ack_sel_size = 7, 390 .ack_sel_size = 7,
389}; 391};
390 392
393static const struct qcom_rpm_resource mdm9615_rpm_resource_table[] = {
394 [QCOM_RPM_CXO_CLK] = { 25, 9, 5, 1 },
395 [QCOM_RPM_SYS_FABRIC_CLK] = { 26, 10, 9, 1 },
396 [QCOM_RPM_DAYTONA_FABRIC_CLK] = { 27, 11, 11, 1 },
397 [QCOM_RPM_SFPB_CLK] = { 28, 12, 12, 1 },
398 [QCOM_RPM_CFPB_CLK] = { 29, 13, 13, 1 },
399 [QCOM_RPM_EBI1_CLK] = { 30, 14, 16, 1 },
400 [QCOM_RPM_APPS_FABRIC_HALT] = { 31, 15, 22, 2 },
401 [QCOM_RPM_APPS_FABRIC_MODE] = { 33, 16, 23, 3 },
402 [QCOM_RPM_APPS_FABRIC_IOCTL] = { 36, 17, 24, 1 },
403 [QCOM_RPM_APPS_FABRIC_ARB] = { 37, 18, 25, 27 },
404 [QCOM_RPM_PM8018_SMPS1] = { 64, 19, 30, 2 },
405 [QCOM_RPM_PM8018_SMPS2] = { 66, 21, 31, 2 },
406 [QCOM_RPM_PM8018_SMPS3] = { 68, 23, 32, 2 },
407 [QCOM_RPM_PM8018_SMPS4] = { 70, 25, 33, 2 },
408 [QCOM_RPM_PM8018_SMPS5] = { 72, 27, 34, 2 },
409 [QCOM_RPM_PM8018_LDO1] = { 74, 29, 35, 2 },
410 [QCOM_RPM_PM8018_LDO2] = { 76, 31, 36, 2 },
411 [QCOM_RPM_PM8018_LDO3] = { 78, 33, 37, 2 },
412 [QCOM_RPM_PM8018_LDO4] = { 80, 35, 38, 2 },
413 [QCOM_RPM_PM8018_LDO5] = { 82, 37, 39, 2 },
414 [QCOM_RPM_PM8018_LDO6] = { 84, 39, 40, 2 },
415 [QCOM_RPM_PM8018_LDO7] = { 86, 41, 41, 2 },
416 [QCOM_RPM_PM8018_LDO8] = { 88, 43, 42, 2 },
417 [QCOM_RPM_PM8018_LDO9] = { 90, 45, 43, 2 },
418 [QCOM_RPM_PM8018_LDO10] = { 92, 47, 44, 2 },
419 [QCOM_RPM_PM8018_LDO11] = { 94, 49, 45, 2 },
420 [QCOM_RPM_PM8018_LDO12] = { 96, 51, 46, 2 },
421 [QCOM_RPM_PM8018_LDO13] = { 98, 53, 47, 2 },
422 [QCOM_RPM_PM8018_LDO14] = { 100, 55, 48, 2 },
423 [QCOM_RPM_PM8018_LVS1] = { 102, 57, 49, 1 },
424 [QCOM_RPM_PM8018_NCP] = { 103, 58, 80, 2 },
425 [QCOM_RPM_CXO_BUFFERS] = { 105, 60, 81, 1 },
426 [QCOM_RPM_USB_OTG_SWITCH] = { 106, 61, 82, 1 },
427 [QCOM_RPM_HDMI_SWITCH] = { 107, 62, 83, 1 },
428 [QCOM_RPM_VOLTAGE_CORNER] = { 109, 64, 87, 1 },
429};
430
431static const struct qcom_rpm_data mdm9615_template = {
432 .version = 3,
433 .resource_table = mdm9615_rpm_resource_table,
434 .n_resources = ARRAY_SIZE(mdm9615_rpm_resource_table),
435 .req_ctx_off = 3,
436 .req_sel_off = 11,
437 .ack_ctx_off = 15,
438 .ack_sel_off = 23,
439 .req_sel_size = 4,
440 .ack_sel_size = 7,
441};
442
391static const struct of_device_id qcom_rpm_of_match[] = { 443static const struct of_device_id qcom_rpm_of_match[] = {
392 { .compatible = "qcom,rpm-apq8064", .data = &apq8064_template }, 444 { .compatible = "qcom,rpm-apq8064", .data = &apq8064_template },
393 { .compatible = "qcom,rpm-msm8660", .data = &msm8660_template }, 445 { .compatible = "qcom,rpm-msm8660", .data = &msm8660_template },
394 { .compatible = "qcom,rpm-msm8960", .data = &msm8960_template }, 446 { .compatible = "qcom,rpm-msm8960", .data = &msm8960_template },
395 { .compatible = "qcom,rpm-ipq8064", .data = &ipq806x_template }, 447 { .compatible = "qcom,rpm-ipq8064", .data = &ipq806x_template },
448 { .compatible = "qcom,rpm-mdm9615", .data = &mdm9615_template },
396 { } 449 { }
397}; 450};
398MODULE_DEVICE_TABLE(of, qcom_rpm_of_match); 451MODULE_DEVICE_TABLE(of, qcom_rpm_of_match);
@@ -501,6 +554,20 @@ static int qcom_rpm_probe(struct platform_device *pdev)
501 mutex_init(&rpm->lock); 554 mutex_init(&rpm->lock);
502 init_completion(&rpm->ack); 555 init_completion(&rpm->ack);
503 556
557 /* Enable message RAM clock */
558 rpm->ramclk = devm_clk_get(&pdev->dev, "ram");
559 if (IS_ERR(rpm->ramclk)) {
560 ret = PTR_ERR(rpm->ramclk);
561 if (ret == -EPROBE_DEFER)
562 return ret;
563 /*
564 * Fall through in all other cases, as the clock is
565 * optional. (Does not exist on all platforms.)
566 */
567 rpm->ramclk = NULL;
568 }
569 clk_prepare_enable(rpm->ramclk); /* Accepts NULL */
570
504 irq_ack = platform_get_irq_byname(pdev, "ack"); 571 irq_ack = platform_get_irq_byname(pdev, "ack");
505 if (irq_ack < 0) { 572 if (irq_ack < 0) {
506 dev_err(&pdev->dev, "required ack interrupt missing\n"); 573 dev_err(&pdev->dev, "required ack interrupt missing\n");
@@ -538,6 +605,7 @@ static int qcom_rpm_probe(struct platform_device *pdev)
538 } 605 }
539 606
540 rpm->ipc_regmap = syscon_node_to_regmap(syscon_np); 607 rpm->ipc_regmap = syscon_node_to_regmap(syscon_np);
608 of_node_put(syscon_np);
541 if (IS_ERR(rpm->ipc_regmap)) 609 if (IS_ERR(rpm->ipc_regmap))
542 return PTR_ERR(rpm->ipc_regmap); 610 return PTR_ERR(rpm->ipc_regmap);
543 611
@@ -620,7 +688,11 @@ static int qcom_rpm_probe(struct platform_device *pdev)
620 688
621static int qcom_rpm_remove(struct platform_device *pdev) 689static int qcom_rpm_remove(struct platform_device *pdev)
622{ 690{
691 struct qcom_rpm *rpm = dev_get_drvdata(&pdev->dev);
692
623 of_platform_depopulate(&pdev->dev); 693 of_platform_depopulate(&pdev->dev);
694 clk_disable_unprepare(rpm->ramclk);
695
624 return 0; 696 return 0;
625} 697}
626 698
diff --git a/drivers/mfd/rk808.c b/drivers/mfd/rk808.c
index 49d7f624fc94..0f8acc5882a4 100644
--- a/drivers/mfd/rk808.c
+++ b/drivers/mfd/rk808.c
@@ -1,11 +1,15 @@
1/* 1/*
2 * MFD core driver for Rockchip RK808 2 * MFD core driver for Rockchip RK808/RK818
3 * 3 *
4 * Copyright (c) 2014, Fuzhou Rockchip Electronics Co., Ltd 4 * Copyright (c) 2014, Fuzhou Rockchip Electronics Co., Ltd
5 * 5 *
6 * Author: Chris Zhong <zyw@rock-chips.com> 6 * Author: Chris Zhong <zyw@rock-chips.com>
7 * Author: Zhang Qing <zhangqing@rock-chips.com> 7 * Author: Zhang Qing <zhangqing@rock-chips.com>
8 * 8 *
9 * Copyright (C) 2016 PHYTEC Messtechnik GmbH
10 *
11 * Author: Wadim Egorov <w.egorov@phytec.de>
12 *
9 * This program is free software; you can redistribute it and/or modify it 13 * This program is free software; you can redistribute it and/or modify it
10 * under the terms and conditions of the GNU General Public License, 14 * under the terms and conditions of the GNU General Public License,
11 * version 2, as published by the Free Software Foundation. 15 * version 2, as published by the Free Software Foundation.
@@ -21,6 +25,7 @@
21#include <linux/mfd/rk808.h> 25#include <linux/mfd/rk808.h>
22#include <linux/mfd/core.h> 26#include <linux/mfd/core.h>
23#include <linux/module.h> 27#include <linux/module.h>
28#include <linux/of_device.h>
24#include <linux/regmap.h> 29#include <linux/regmap.h>
25 30
26struct rk808_reg_data { 31struct rk808_reg_data {
@@ -57,6 +62,14 @@ static bool rk808_is_volatile_reg(struct device *dev, unsigned int reg)
57 return false; 62 return false;
58} 63}
59 64
65static const struct regmap_config rk818_regmap_config = {
66 .reg_bits = 8,
67 .val_bits = 8,
68 .max_register = RK818_USB_CTRL_REG,
69 .cache_type = REGCACHE_RBTREE,
70 .volatile_reg = rk808_is_volatile_reg,
71};
72
60static const struct regmap_config rk808_regmap_config = { 73static const struct regmap_config rk808_regmap_config = {
61 .reg_bits = 8, 74 .reg_bits = 8,
62 .val_bits = 8, 75 .val_bits = 8,
@@ -79,11 +92,21 @@ static const struct mfd_cell rk808s[] = {
79 { 92 {
80 .name = "rk808-rtc", 93 .name = "rk808-rtc",
81 .num_resources = ARRAY_SIZE(rtc_resources), 94 .num_resources = ARRAY_SIZE(rtc_resources),
82 .resources = &rtc_resources[0], 95 .resources = rtc_resources,
83 }, 96 },
84}; 97};
85 98
86static const struct rk808_reg_data pre_init_reg[] = { 99static const struct mfd_cell rk818s[] = {
100 { .name = "rk808-clkout", },
101 { .name = "rk808-regulator", },
102 {
103 .name = "rk808-rtc",
104 .num_resources = ARRAY_SIZE(rtc_resources),
105 .resources = rtc_resources,
106 },
107};
108
109static const struct rk808_reg_data rk808_pre_init_reg[] = {
87 { RK808_BUCK3_CONFIG_REG, BUCK_ILMIN_MASK, BUCK_ILMIN_150MA }, 110 { RK808_BUCK3_CONFIG_REG, BUCK_ILMIN_MASK, BUCK_ILMIN_150MA },
88 { RK808_BUCK4_CONFIG_REG, BUCK_ILMIN_MASK, BUCK_ILMIN_200MA }, 111 { RK808_BUCK4_CONFIG_REG, BUCK_ILMIN_MASK, BUCK_ILMIN_200MA },
89 { RK808_BOOST_CONFIG_REG, BOOST_ILMIN_MASK, BOOST_ILMIN_100MA }, 112 { RK808_BOOST_CONFIG_REG, BOOST_ILMIN_MASK, BOOST_ILMIN_100MA },
@@ -94,6 +117,24 @@ static const struct rk808_reg_data pre_init_reg[] = {
94 VB_LO_SEL_3500MV }, 117 VB_LO_SEL_3500MV },
95}; 118};
96 119
120static const struct rk808_reg_data rk818_pre_init_reg[] = {
121 /* improve efficiency */
122 { RK818_BUCK2_CONFIG_REG, BUCK2_RATE_MASK, BUCK_ILMIN_250MA },
123 { RK818_BUCK4_CONFIG_REG, BUCK_ILMIN_MASK, BUCK_ILMIN_250MA },
124 { RK818_BOOST_CONFIG_REG, BOOST_ILMIN_MASK, BOOST_ILMIN_100MA },
125 { RK818_USB_CTRL_REG, RK818_USB_ILIM_SEL_MASK,
126 RK818_USB_ILMIN_2000MA },
127 /* close charger when usb lower then 3.4V */
128 { RK818_USB_CTRL_REG, RK818_USB_CHG_SD_VSEL_MASK,
129 (0x7 << 4) },
130 /* no action when vref */
131 { RK818_H5V_EN_REG, BIT(1), RK818_REF_RDY_CTRL },
132 /* enable HDMI 5V */
133 { RK818_H5V_EN_REG, BIT(0), RK818_H5V_EN },
134 { RK808_VB_MON_REG, MASK_ALL, VB_LO_ACT |
135 VB_LO_SEL_3500MV },
136};
137
97static const struct regmap_irq rk808_irqs[] = { 138static const struct regmap_irq rk808_irqs[] = {
98 /* INT_STS */ 139 /* INT_STS */
99 [RK808_IRQ_VOUT_LO] = { 140 [RK808_IRQ_VOUT_LO] = {
@@ -136,6 +177,76 @@ static const struct regmap_irq rk808_irqs[] = {
136 }, 177 },
137}; 178};
138 179
180static const struct regmap_irq rk818_irqs[] = {
181 /* INT_STS */
182 [RK818_IRQ_VOUT_LO] = {
183 .mask = RK818_IRQ_VOUT_LO_MSK,
184 .reg_offset = 0,
185 },
186 [RK818_IRQ_VB_LO] = {
187 .mask = RK818_IRQ_VB_LO_MSK,
188 .reg_offset = 0,
189 },
190 [RK818_IRQ_PWRON] = {
191 .mask = RK818_IRQ_PWRON_MSK,
192 .reg_offset = 0,
193 },
194 [RK818_IRQ_PWRON_LP] = {
195 .mask = RK818_IRQ_PWRON_LP_MSK,
196 .reg_offset = 0,
197 },
198 [RK818_IRQ_HOTDIE] = {
199 .mask = RK818_IRQ_HOTDIE_MSK,
200 .reg_offset = 0,
201 },
202 [RK818_IRQ_RTC_ALARM] = {
203 .mask = RK818_IRQ_RTC_ALARM_MSK,
204 .reg_offset = 0,
205 },
206 [RK818_IRQ_RTC_PERIOD] = {
207 .mask = RK818_IRQ_RTC_PERIOD_MSK,
208 .reg_offset = 0,
209 },
210 [RK818_IRQ_USB_OV] = {
211 .mask = RK818_IRQ_USB_OV_MSK,
212 .reg_offset = 0,
213 },
214
215 /* INT_STS2 */
216 [RK818_IRQ_PLUG_IN] = {
217 .mask = RK818_IRQ_PLUG_IN_MSK,
218 .reg_offset = 1,
219 },
220 [RK818_IRQ_PLUG_OUT] = {
221 .mask = RK818_IRQ_PLUG_OUT_MSK,
222 .reg_offset = 1,
223 },
224 [RK818_IRQ_CHG_OK] = {
225 .mask = RK818_IRQ_CHG_OK_MSK,
226 .reg_offset = 1,
227 },
228 [RK818_IRQ_CHG_TE] = {
229 .mask = RK818_IRQ_CHG_TE_MSK,
230 .reg_offset = 1,
231 },
232 [RK818_IRQ_CHG_TS1] = {
233 .mask = RK818_IRQ_CHG_TS1_MSK,
234 .reg_offset = 1,
235 },
236 [RK818_IRQ_TS2] = {
237 .mask = RK818_IRQ_TS2_MSK,
238 .reg_offset = 1,
239 },
240 [RK818_IRQ_CHG_CVTLIM] = {
241 .mask = RK818_IRQ_CHG_CVTLIM_MSK,
242 .reg_offset = 1,
243 },
244 [RK818_IRQ_DISCHG_ILIM] = {
245 .mask = RK818_IRQ_DISCHG_ILIM_MSK,
246 .reg_offset = 1,
247 },
248};
249
139static struct regmap_irq_chip rk808_irq_chip = { 250static struct regmap_irq_chip rk808_irq_chip = {
140 .name = "rk808", 251 .name = "rk808",
141 .irqs = rk808_irqs, 252 .irqs = rk808_irqs,
@@ -148,6 +259,18 @@ static struct regmap_irq_chip rk808_irq_chip = {
148 .init_ack_masked = true, 259 .init_ack_masked = true,
149}; 260};
150 261
262static struct regmap_irq_chip rk818_irq_chip = {
263 .name = "rk818",
264 .irqs = rk818_irqs,
265 .num_irqs = ARRAY_SIZE(rk818_irqs),
266 .num_regs = 2,
267 .irq_reg_stride = 2,
268 .status_base = RK818_INT_STS_REG1,
269 .mask_base = RK818_INT_STS_MSK_REG1,
270 .ack_base = RK818_INT_STS_REG1,
271 .init_ack_masked = true,
272};
273
151static struct i2c_client *rk808_i2c_client; 274static struct i2c_client *rk808_i2c_client;
152static void rk808_device_shutdown(void) 275static void rk808_device_shutdown(void)
153{ 276{
@@ -167,55 +290,100 @@ static void rk808_device_shutdown(void)
167 dev_err(&rk808_i2c_client->dev, "power off error!\n"); 290 dev_err(&rk808_i2c_client->dev, "power off error!\n");
168} 291}
169 292
293static const struct of_device_id rk808_of_match[] = {
294 { .compatible = "rockchip,rk808" },
295 { .compatible = "rockchip,rk818" },
296 { },
297};
298MODULE_DEVICE_TABLE(of, rk808_of_match);
299
170static int rk808_probe(struct i2c_client *client, 300static int rk808_probe(struct i2c_client *client,
171 const struct i2c_device_id *id) 301 const struct i2c_device_id *id)
172{ 302{
173 struct device_node *np = client->dev.of_node; 303 struct device_node *np = client->dev.of_node;
174 struct rk808 *rk808; 304 struct rk808 *rk808;
305 const struct rk808_reg_data *pre_init_reg;
306 const struct mfd_cell *cells;
307 int nr_pre_init_regs;
308 int nr_cells;
175 int pm_off = 0; 309 int pm_off = 0;
176 int ret; 310 int ret;
177 int i; 311 int i;
178 312
179 if (!client->irq) {
180 dev_err(&client->dev, "No interrupt support, no core IRQ\n");
181 return -EINVAL;
182 }
183
184 rk808 = devm_kzalloc(&client->dev, sizeof(*rk808), GFP_KERNEL); 313 rk808 = devm_kzalloc(&client->dev, sizeof(*rk808), GFP_KERNEL);
185 if (!rk808) 314 if (!rk808)
186 return -ENOMEM; 315 return -ENOMEM;
187 316
188 rk808->regmap = devm_regmap_init_i2c(client, &rk808_regmap_config); 317 rk808->variant = i2c_smbus_read_word_data(client, RK808_ID_MSB);
318 if (rk808->variant < 0) {
319 dev_err(&client->dev, "Failed to read the chip id at 0x%02x\n",
320 RK808_ID_MSB);
321 return rk808->variant;
322 }
323
324 dev_dbg(&client->dev, "Chip id: 0x%x\n", (unsigned int)rk808->variant);
325
326 switch (rk808->variant) {
327 case RK808_ID:
328 rk808->regmap_cfg = &rk808_regmap_config;
329 rk808->regmap_irq_chip = &rk808_irq_chip;
330 pre_init_reg = rk808_pre_init_reg;
331 nr_pre_init_regs = ARRAY_SIZE(rk808_pre_init_reg);
332 cells = rk808s;
333 nr_cells = ARRAY_SIZE(rk808s);
334 break;
335 case RK818_ID:
336 rk808->regmap_cfg = &rk818_regmap_config;
337 rk808->regmap_irq_chip = &rk818_irq_chip;
338 pre_init_reg = rk818_pre_init_reg;
339 nr_pre_init_regs = ARRAY_SIZE(rk818_pre_init_reg);
340 cells = rk818s;
341 nr_cells = ARRAY_SIZE(rk818s);
342 break;
343 default:
344 dev_err(&client->dev, "Unsupported RK8XX ID %lu\n",
345 rk808->variant);
346 return -EINVAL;
347 }
348
349 rk808->i2c = client;
350 i2c_set_clientdata(client, rk808);
351
352 rk808->regmap = devm_regmap_init_i2c(client, rk808->regmap_cfg);
189 if (IS_ERR(rk808->regmap)) { 353 if (IS_ERR(rk808->regmap)) {
190 dev_err(&client->dev, "regmap initialization failed\n"); 354 dev_err(&client->dev, "regmap initialization failed\n");
191 return PTR_ERR(rk808->regmap); 355 return PTR_ERR(rk808->regmap);
192 } 356 }
193 357
194 for (i = 0; i < ARRAY_SIZE(pre_init_reg); i++) { 358 if (!client->irq) {
195 ret = regmap_update_bits(rk808->regmap, pre_init_reg[i].addr, 359 dev_err(&client->dev, "No interrupt support, no core IRQ\n");
196 pre_init_reg[i].mask, 360 return -EINVAL;
197 pre_init_reg[i].value);
198 if (ret) {
199 dev_err(&client->dev,
200 "0x%x write err\n", pre_init_reg[i].addr);
201 return ret;
202 }
203 } 361 }
204 362
205 ret = regmap_add_irq_chip(rk808->regmap, client->irq, 363 ret = regmap_add_irq_chip(rk808->regmap, client->irq,
206 IRQF_ONESHOT, -1, 364 IRQF_ONESHOT, -1,
207 &rk808_irq_chip, &rk808->irq_data); 365 rk808->regmap_irq_chip, &rk808->irq_data);
208 if (ret) { 366 if (ret) {
209 dev_err(&client->dev, "Failed to add irq_chip %d\n", ret); 367 dev_err(&client->dev, "Failed to add irq_chip %d\n", ret);
210 return ret; 368 return ret;
211 } 369 }
212 370
213 rk808->i2c = client; 371 for (i = 0; i < nr_pre_init_regs; i++) {
214 i2c_set_clientdata(client, rk808); 372 ret = regmap_update_bits(rk808->regmap,
373 pre_init_reg[i].addr,
374 pre_init_reg[i].mask,
375 pre_init_reg[i].value);
376 if (ret) {
377 dev_err(&client->dev,
378 "0x%x write err\n",
379 pre_init_reg[i].addr);
380 return ret;
381 }
382 }
215 383
216 ret = devm_mfd_add_devices(&client->dev, -1, 384 ret = devm_mfd_add_devices(&client->dev, PLATFORM_DEVID_NONE,
217 rk808s, ARRAY_SIZE(rk808s), NULL, 0, 385 cells, nr_cells, NULL, 0,
218 regmap_irq_get_domain(rk808->irq_data)); 386 regmap_irq_get_domain(rk808->irq_data));
219 if (ret) { 387 if (ret) {
220 dev_err(&client->dev, "failed to add MFD devices %d\n", ret); 388 dev_err(&client->dev, "failed to add MFD devices %d\n", ret);
221 goto err_irq; 389 goto err_irq;
@@ -245,14 +413,9 @@ static int rk808_remove(struct i2c_client *client)
245 return 0; 413 return 0;
246} 414}
247 415
248static const struct of_device_id rk808_of_match[] = {
249 { .compatible = "rockchip,rk808" },
250 { },
251};
252MODULE_DEVICE_TABLE(of, rk808_of_match);
253
254static const struct i2c_device_id rk808_ids[] = { 416static const struct i2c_device_id rk808_ids[] = {
255 { "rk808" }, 417 { "rk808" },
418 { "rk818" },
256 { }, 419 { },
257}; 420};
258MODULE_DEVICE_TABLE(i2c, rk808_ids); 421MODULE_DEVICE_TABLE(i2c, rk808_ids);
@@ -272,4 +435,5 @@ module_i2c_driver(rk808_i2c_driver);
272MODULE_LICENSE("GPL"); 435MODULE_LICENSE("GPL");
273MODULE_AUTHOR("Chris Zhong <zyw@rock-chips.com>"); 436MODULE_AUTHOR("Chris Zhong <zyw@rock-chips.com>");
274MODULE_AUTHOR("Zhang Qing <zhangqing@rock-chips.com>"); 437MODULE_AUTHOR("Zhang Qing <zhangqing@rock-chips.com>");
275MODULE_DESCRIPTION("RK808 PMIC driver"); 438MODULE_AUTHOR("Wadim Egorov <w.egorov@phytec.de>");
439MODULE_DESCRIPTION("RK808/RK818 PMIC driver");
diff --git a/drivers/mfd/rtsx_usb.c b/drivers/mfd/rtsx_usb.c
index dbd907d7170e..691dab791f7a 100644
--- a/drivers/mfd/rtsx_usb.c
+++ b/drivers/mfd/rtsx_usb.c
@@ -46,9 +46,6 @@ static void rtsx_usb_sg_timed_out(unsigned long data)
46 46
47 dev_dbg(&ucr->pusb_intf->dev, "%s: sg transfer timed out", __func__); 47 dev_dbg(&ucr->pusb_intf->dev, "%s: sg transfer timed out", __func__);
48 usb_sg_cancel(&ucr->current_sg); 48 usb_sg_cancel(&ucr->current_sg);
49
50 /* we know the cancellation is caused by time-out */
51 ucr->current_sg.status = -ETIMEDOUT;
52} 49}
53 50
54static int rtsx_usb_bulk_transfer_sglist(struct rtsx_ucr *ucr, 51static int rtsx_usb_bulk_transfer_sglist(struct rtsx_ucr *ucr,
@@ -67,12 +64,15 @@ static int rtsx_usb_bulk_transfer_sglist(struct rtsx_ucr *ucr,
67 ucr->sg_timer.expires = jiffies + msecs_to_jiffies(timeout); 64 ucr->sg_timer.expires = jiffies + msecs_to_jiffies(timeout);
68 add_timer(&ucr->sg_timer); 65 add_timer(&ucr->sg_timer);
69 usb_sg_wait(&ucr->current_sg); 66 usb_sg_wait(&ucr->current_sg);
70 del_timer_sync(&ucr->sg_timer); 67 if (!del_timer_sync(&ucr->sg_timer))
68 ret = -ETIMEDOUT;
69 else
70 ret = ucr->current_sg.status;
71 71
72 if (act_len) 72 if (act_len)
73 *act_len = ucr->current_sg.bytes; 73 *act_len = ucr->current_sg.bytes;
74 74
75 return ucr->current_sg.status; 75 return ret;
76} 76}
77 77
78int rtsx_usb_transfer_data(struct rtsx_ucr *ucr, unsigned int pipe, 78int rtsx_usb_transfer_data(struct rtsx_ucr *ucr, unsigned int pipe,
diff --git a/drivers/mfd/sm501.c b/drivers/mfd/sm501.c
index 65cd0d2a822a..40534352e574 100644
--- a/drivers/mfd/sm501.c
+++ b/drivers/mfd/sm501.c
@@ -1001,7 +1001,7 @@ static int sm501_gpio_output(struct gpio_chip *chip,
1001 return 0; 1001 return 0;
1002} 1002}
1003 1003
1004static struct gpio_chip gpio_chip_template = { 1004static const struct gpio_chip gpio_chip_template = {
1005 .ngpio = 32, 1005 .ngpio = 32,
1006 .direction_input = sm501_gpio_input, 1006 .direction_input = sm501_gpio_input,
1007 .direction_output = sm501_gpio_output, 1007 .direction_output = sm501_gpio_output,
diff --git a/drivers/mfd/smsc-ece1099.c b/drivers/mfd/smsc-ece1099.c
index cd18c09827ef..1f40baf1234e 100644
--- a/drivers/mfd/smsc-ece1099.c
+++ b/drivers/mfd/smsc-ece1099.c
@@ -11,8 +11,7 @@
11 * 11 *
12 */ 12 */
13 13
14#include <linux/module.h> 14#include <linux/init.h>
15#include <linux/moduleparam.h>
16#include <linux/slab.h> 15#include <linux/slab.h>
17#include <linux/i2c.h> 16#include <linux/i2c.h>
18#include <linux/gpio.h> 17#include <linux/gpio.h>
@@ -81,7 +80,6 @@ static const struct i2c_device_id smsc_i2c_id[] = {
81 { "smscece1099", 0}, 80 { "smscece1099", 0},
82 {}, 81 {},
83}; 82};
84MODULE_DEVICE_TABLE(i2c, smsc_i2c_id);
85 83
86static struct i2c_driver smsc_i2c_driver = { 84static struct i2c_driver smsc_i2c_driver = {
87 .driver = { 85 .driver = {
@@ -90,9 +88,4 @@ static struct i2c_driver smsc_i2c_driver = {
90 .probe = smsc_i2c_probe, 88 .probe = smsc_i2c_probe,
91 .id_table = smsc_i2c_id, 89 .id_table = smsc_i2c_id,
92}; 90};
93 91builtin_i2c_driver(smsc_i2c_driver);
94module_i2c_driver(smsc_i2c_driver);
95
96MODULE_AUTHOR("Sourav Poddar <sourav.poddar@ti.com>");
97MODULE_DESCRIPTION("SMSC chip multi-function driver");
98MODULE_LICENSE("GPL v2");
diff --git a/drivers/mfd/sun6i-prcm.c b/drivers/mfd/sun6i-prcm.c
index 191173166d65..011fcc555945 100644
--- a/drivers/mfd/sun6i-prcm.c
+++ b/drivers/mfd/sun6i-prcm.c
@@ -9,7 +9,7 @@
9 */ 9 */
10 10
11#include <linux/mfd/core.h> 11#include <linux/mfd/core.h>
12#include <linux/module.h> 12#include <linux/init.h>
13#include <linux/of.h> 13#include <linux/of.h>
14 14
15struct prcm_data { 15struct prcm_data {
@@ -170,8 +170,4 @@ static struct platform_driver sun6i_prcm_driver = {
170 }, 170 },
171 .probe = sun6i_prcm_probe, 171 .probe = sun6i_prcm_probe,
172}; 172};
173module_platform_driver(sun6i_prcm_driver); 173builtin_platform_driver(sun6i_prcm_driver);
174
175MODULE_AUTHOR("Boris BREZILLON <boris.brezillon@free-electrons.com>");
176MODULE_DESCRIPTION("Allwinner sun6i PRCM driver");
177MODULE_LICENSE("GPL v2");
diff --git a/drivers/mfd/tps65217.c b/drivers/mfd/tps65217.c
index 049a6fcac651..9a4d8684dd32 100644
--- a/drivers/mfd/tps65217.c
+++ b/drivers/mfd/tps65217.c
@@ -15,22 +15,103 @@
15 * GNU General Public License for more details. 15 * GNU General Public License for more details.
16 */ 16 */
17 17
18#include <linux/kernel.h>
19#include <linux/device.h> 18#include <linux/device.h>
20#include <linux/module.h> 19#include <linux/err.h>
21#include <linux/platform_device.h>
22#include <linux/init.h> 20#include <linux/init.h>
21#include <linux/interrupt.h>
23#include <linux/i2c.h> 22#include <linux/i2c.h>
24#include <linux/slab.h> 23#include <linux/irq.h>
25#include <linux/regmap.h> 24#include <linux/irqdomain.h>
26#include <linux/err.h> 25#include <linux/kernel.h>
26#include <linux/module.h>
27#include <linux/of.h> 27#include <linux/of.h>
28#include <linux/of_device.h> 28#include <linux/of_device.h>
29#include <linux/platform_device.h>
30#include <linux/regmap.h>
31#include <linux/slab.h>
29 32
30#include <linux/mfd/core.h> 33#include <linux/mfd/core.h>
31#include <linux/mfd/tps65217.h> 34#include <linux/mfd/tps65217.h>
32 35
33static const struct mfd_cell tps65217s[] = { 36static struct resource charger_resources[] = {
37 DEFINE_RES_IRQ_NAMED(TPS65217_IRQ_AC, "AC"),
38 DEFINE_RES_IRQ_NAMED(TPS65217_IRQ_USB, "USB"),
39};
40
41static struct resource pb_resources[] = {
42 DEFINE_RES_IRQ_NAMED(TPS65217_IRQ_PB, "PB"),
43};
44
45struct tps65217_irq {
46 int mask;
47 int interrupt;
48};
49
50static const struct tps65217_irq tps65217_irqs[] = {
51 [TPS65217_IRQ_PB] = {
52 .mask = TPS65217_INT_PBM,
53 .interrupt = TPS65217_INT_PBI,
54 },
55 [TPS65217_IRQ_AC] = {
56 .mask = TPS65217_INT_ACM,
57 .interrupt = TPS65217_INT_ACI,
58 },
59 [TPS65217_IRQ_USB] = {
60 .mask = TPS65217_INT_USBM,
61 .interrupt = TPS65217_INT_USBI,
62 },
63};
64
65static void tps65217_irq_lock(struct irq_data *data)
66{
67 struct tps65217 *tps = irq_data_get_irq_chip_data(data);
68
69 mutex_lock(&tps->irq_lock);
70}
71
72static void tps65217_irq_sync_unlock(struct irq_data *data)
73{
74 struct tps65217 *tps = irq_data_get_irq_chip_data(data);
75 int ret;
76
77 ret = tps65217_reg_write(tps, TPS65217_REG_INT, tps->irq_mask,
78 TPS65217_PROTECT_NONE);
79 if (ret != 0)
80 dev_err(tps->dev, "Failed to sync IRQ masks\n");
81
82 mutex_unlock(&tps->irq_lock);
83}
84
85static inline const struct tps65217_irq *
86irq_to_tps65217_irq(struct tps65217 *tps, struct irq_data *data)
87{
88 return &tps65217_irqs[data->hwirq];
89}
90
91static void tps65217_irq_enable(struct irq_data *data)
92{
93 struct tps65217 *tps = irq_data_get_irq_chip_data(data);
94 const struct tps65217_irq *irq_data = irq_to_tps65217_irq(tps, data);
95
96 tps->irq_mask &= ~irq_data->mask;
97}
98
99static void tps65217_irq_disable(struct irq_data *data)
100{
101 struct tps65217 *tps = irq_data_get_irq_chip_data(data);
102 const struct tps65217_irq *irq_data = irq_to_tps65217_irq(tps, data);
103
104 tps->irq_mask |= irq_data->mask;
105}
106
107static struct irq_chip tps65217_irq_chip = {
108 .irq_bus_lock = tps65217_irq_lock,
109 .irq_bus_sync_unlock = tps65217_irq_sync_unlock,
110 .irq_enable = tps65217_irq_enable,
111 .irq_disable = tps65217_irq_disable,
112};
113
114static struct mfd_cell tps65217s[] = {
34 { 115 {
35 .name = "tps65217-pmic", 116 .name = "tps65217-pmic",
36 .of_compatible = "ti,tps65217-pmic", 117 .of_compatible = "ti,tps65217-pmic",
@@ -41,10 +122,96 @@ static const struct mfd_cell tps65217s[] = {
41 }, 122 },
42 { 123 {
43 .name = "tps65217-charger", 124 .name = "tps65217-charger",
125 .num_resources = ARRAY_SIZE(charger_resources),
126 .resources = charger_resources,
44 .of_compatible = "ti,tps65217-charger", 127 .of_compatible = "ti,tps65217-charger",
45 }, 128 },
129 {
130 .name = "tps65217-pwrbutton",
131 .num_resources = ARRAY_SIZE(pb_resources),
132 .resources = pb_resources,
133 .of_compatible = "ti,tps65217-pwrbutton",
134 },
135};
136
137static irqreturn_t tps65217_irq_thread(int irq, void *data)
138{
139 struct tps65217 *tps = data;
140 unsigned int status;
141 bool handled = false;
142 int i;
143 int ret;
144
145 ret = tps65217_reg_read(tps, TPS65217_REG_INT, &status);
146 if (ret < 0) {
147 dev_err(tps->dev, "Failed to read IRQ status: %d\n",
148 ret);
149 return IRQ_NONE;
150 }
151
152 for (i = 0; i < ARRAY_SIZE(tps65217_irqs); i++) {
153 if (status & tps65217_irqs[i].interrupt) {
154 handle_nested_irq(irq_find_mapping(tps->irq_domain, i));
155 handled = true;
156 }
157 }
158
159 if (handled)
160 return IRQ_HANDLED;
161
162 return IRQ_NONE;
163}
164
165static int tps65217_irq_map(struct irq_domain *h, unsigned int virq,
166 irq_hw_number_t hw)
167{
168 struct tps65217 *tps = h->host_data;
169
170 irq_set_chip_data(virq, tps);
171 irq_set_chip_and_handler(virq, &tps65217_irq_chip, handle_edge_irq);
172 irq_set_nested_thread(virq, 1);
173 irq_set_parent(virq, tps->irq);
174 irq_set_noprobe(virq);
175
176 return 0;
177}
178
179static const struct irq_domain_ops tps65217_irq_domain_ops = {
180 .map = tps65217_irq_map,
46}; 181};
47 182
183static int tps65217_irq_init(struct tps65217 *tps, int irq)
184{
185 int ret;
186
187 mutex_init(&tps->irq_lock);
188 tps->irq = irq;
189
190 /* Mask all interrupt sources */
191 tps->irq_mask = (TPS65217_INT_RESERVEDM | TPS65217_INT_PBM
192 | TPS65217_INT_ACM | TPS65217_INT_USBM);
193 tps65217_reg_write(tps, TPS65217_REG_INT, tps->irq_mask,
194 TPS65217_PROTECT_NONE);
195
196 tps->irq_domain = irq_domain_add_linear(tps->dev->of_node,
197 TPS65217_NUM_IRQ, &tps65217_irq_domain_ops, tps);
198 if (!tps->irq_domain) {
199 dev_err(tps->dev, "Could not create IRQ domain\n");
200 return -ENOMEM;
201 }
202
203 ret = devm_request_threaded_irq(tps->dev, irq, NULL,
204 tps65217_irq_thread, IRQF_ONESHOT,
205 "tps65217-irq", tps);
206 if (ret) {
207 dev_err(tps->dev, "Failed to request IRQ %d: %d\n",
208 irq, ret);
209 return ret;
210 }
211
212 return 0;
213}
214
48/** 215/**
49 * tps65217_reg_read: Read a single tps65217 register. 216 * tps65217_reg_read: Read a single tps65217 register.
50 * 217 *
@@ -149,11 +316,22 @@ int tps65217_clear_bits(struct tps65217 *tps, unsigned int reg,
149} 316}
150EXPORT_SYMBOL_GPL(tps65217_clear_bits); 317EXPORT_SYMBOL_GPL(tps65217_clear_bits);
151 318
319static bool tps65217_volatile_reg(struct device *dev, unsigned int reg)
320{
321 switch (reg) {
322 case TPS65217_REG_INT:
323 return true;
324 default:
325 return false;
326 }
327}
328
152static const struct regmap_config tps65217_regmap_config = { 329static const struct regmap_config tps65217_regmap_config = {
153 .reg_bits = 8, 330 .reg_bits = 8,
154 .val_bits = 8, 331 .val_bits = 8,
155 332
156 .max_register = TPS65217_REG_MAX, 333 .max_register = TPS65217_REG_MAX,
334 .volatile_reg = tps65217_volatile_reg,
157}; 335};
158 336
159static const struct of_device_id tps65217_of_match[] = { 337static const struct of_device_id tps65217_of_match[] = {
@@ -205,8 +383,19 @@ static int tps65217_probe(struct i2c_client *client,
205 return ret; 383 return ret;
206 } 384 }
207 385
386 if (client->irq) {
387 tps65217_irq_init(tps, client->irq);
388 } else {
389 int i;
390
391 /* Don't tell children about IRQ resources which won't fire */
392 for (i = 0; i < ARRAY_SIZE(tps65217s); i++)
393 tps65217s[i].num_resources = 0;
394 }
395
208 ret = devm_mfd_add_devices(tps->dev, -1, tps65217s, 396 ret = devm_mfd_add_devices(tps->dev, -1, tps65217s,
209 ARRAY_SIZE(tps65217s), NULL, 0, NULL); 397 ARRAY_SIZE(tps65217s), NULL, 0,
398 tps->irq_domain);
210 if (ret < 0) { 399 if (ret < 0) {
211 dev_err(tps->dev, "mfd_add_devices failed: %d\n", ret); 400 dev_err(tps->dev, "mfd_add_devices failed: %d\n", ret);
212 return ret; 401 return ret;
diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c
index a49d3db6d936..c64615dca2bd 100644
--- a/drivers/mfd/twl-core.c
+++ b/drivers/mfd/twl-core.c
@@ -30,7 +30,6 @@
30 30
31#include <linux/init.h> 31#include <linux/init.h>
32#include <linux/mutex.h> 32#include <linux/mutex.h>
33#include <linux/module.h>
34#include <linux/platform_device.h> 33#include <linux/platform_device.h>
35#include <linux/regmap.h> 34#include <linux/regmap.h>
36#include <linux/clk.h> 35#include <linux/clk.h>
@@ -1258,7 +1257,6 @@ static const struct i2c_device_id twl_ids[] = {
1258 { "twl6032", TWL6030_CLASS | TWL6032_SUBCLASS }, /* "Phoenix lite" */ 1257 { "twl6032", TWL6030_CLASS | TWL6032_SUBCLASS }, /* "Phoenix lite" */
1259 { /* end of list */ }, 1258 { /* end of list */ },
1260}; 1259};
1261MODULE_DEVICE_TABLE(i2c, twl_ids);
1262 1260
1263/* One Client Driver , 4 Clients */ 1261/* One Client Driver , 4 Clients */
1264static struct i2c_driver twl_driver = { 1262static struct i2c_driver twl_driver = {
@@ -1267,9 +1265,4 @@ static struct i2c_driver twl_driver = {
1267 .probe = twl_probe, 1265 .probe = twl_probe,
1268 .remove = twl_remove, 1266 .remove = twl_remove,
1269}; 1267};
1270 1268builtin_i2c_driver(twl_driver);
1271module_i2c_driver(twl_driver);
1272
1273MODULE_AUTHOR("Texas Instruments, Inc.");
1274MODULE_DESCRIPTION("I2C Core interface for TWL");
1275MODULE_LICENSE("GPL");
diff --git a/drivers/mfd/twl6040.c b/drivers/mfd/twl6040.c
index ab328ec49353..d66502d36ba0 100644
--- a/drivers/mfd/twl6040.c
+++ b/drivers/mfd/twl6040.c
@@ -609,6 +609,7 @@ static const struct regmap_config twl6040_regmap_config = {
609 .writeable_reg = twl6040_writeable_reg, 609 .writeable_reg = twl6040_writeable_reg,
610 610
611 .cache_type = REGCACHE_RBTREE, 611 .cache_type = REGCACHE_RBTREE,
612 .use_single_rw = true,
612}; 613};
613 614
614static const struct regmap_irq twl6040_irqs[] = { 615static const struct regmap_irq twl6040_irqs[] = {
@@ -782,6 +783,11 @@ static int twl6040_probe(struct i2c_client *client,
782 cell->name = "twl6040-gpo"; 783 cell->name = "twl6040-gpo";
783 children++; 784 children++;
784 785
786 /* PDM clock support */
787 cell = &twl6040->cells[children];
788 cell->name = "twl6040-pdmclk";
789 children++;
790
785 /* The chip is powered down so mark regmap to cache only and dirty */ 791 /* The chip is powered down so mark regmap to cache only and dirty */
786 regcache_cache_only(twl6040->regmap, true); 792 regcache_cache_only(twl6040->regmap, true);
787 regcache_mark_dirty(twl6040->regmap); 793 regcache_mark_dirty(twl6040->regmap);
diff --git a/drivers/mfd/ucb1x00-core.c b/drivers/mfd/ucb1x00-core.c
index 9ab9ec47ea75..d6fb2e1a759a 100644
--- a/drivers/mfd/ucb1x00-core.c
+++ b/drivers/mfd/ucb1x00-core.c
@@ -446,10 +446,6 @@ static int ucb1x00_detect_irq(struct ucb1x00 *ucb)
446 unsigned long mask; 446 unsigned long mask;
447 447
448 mask = probe_irq_on(); 448 mask = probe_irq_on();
449 if (!mask) {
450 probe_irq_off(mask);
451 return NO_IRQ;
452 }
453 449
454 /* 450 /*
455 * Enable the ADC interrupt. 451 * Enable the ADC interrupt.
@@ -541,7 +537,7 @@ static int ucb1x00_probe(struct mcp *mcp)
541 ucb1x00_enable(ucb); 537 ucb1x00_enable(ucb);
542 ucb->irq = ucb1x00_detect_irq(ucb); 538 ucb->irq = ucb1x00_detect_irq(ucb);
543 ucb1x00_disable(ucb); 539 ucb1x00_disable(ucb);
544 if (ucb->irq == NO_IRQ) { 540 if (!ucb->irq) {
545 dev_err(&ucb->dev, "IRQ probe failed\n"); 541 dev_err(&ucb->dev, "IRQ probe failed\n");
546 ret = -ENODEV; 542 ret = -ENODEV;
547 goto err_no_irq; 543 goto err_no_irq;
diff --git a/drivers/platform/chrome/cros_ec_proto.c b/drivers/platform/chrome/cros_ec_proto.c
index 6c084b266651..04053fe1e980 100644
--- a/drivers/platform/chrome/cros_ec_proto.c
+++ b/drivers/platform/chrome/cros_ec_proto.c
@@ -19,6 +19,7 @@
19#include <linux/device.h> 19#include <linux/device.h>
20#include <linux/module.h> 20#include <linux/module.h>
21#include <linux/slab.h> 21#include <linux/slab.h>
22#include <asm/unaligned.h>
22 23
23#define EC_COMMAND_RETRIES 50 24#define EC_COMMAND_RETRIES 50
24 25
@@ -234,11 +235,44 @@ static int cros_ec_host_command_proto_query_v2(struct cros_ec_device *ec_dev)
234 return ret; 235 return ret;
235} 236}
236 237
238static int cros_ec_get_host_command_version_mask(struct cros_ec_device *ec_dev,
239 u16 cmd, u32 *mask)
240{
241 struct ec_params_get_cmd_versions *pver;
242 struct ec_response_get_cmd_versions *rver;
243 struct cros_ec_command *msg;
244 int ret;
245
246 msg = kmalloc(sizeof(*msg) + max(sizeof(*rver), sizeof(*pver)),
247 GFP_KERNEL);
248 if (!msg)
249 return -ENOMEM;
250
251 msg->version = 0;
252 msg->command = EC_CMD_GET_CMD_VERSIONS;
253 msg->insize = sizeof(*rver);
254 msg->outsize = sizeof(*pver);
255
256 pver = (struct ec_params_get_cmd_versions *)msg->data;
257 pver->cmd = cmd;
258
259 ret = cros_ec_cmd_xfer(ec_dev, msg);
260 if (ret > 0) {
261 rver = (struct ec_response_get_cmd_versions *)msg->data;
262 *mask = rver->version_mask;
263 }
264
265 kfree(msg);
266
267 return ret;
268}
269
237int cros_ec_query_all(struct cros_ec_device *ec_dev) 270int cros_ec_query_all(struct cros_ec_device *ec_dev)
238{ 271{
239 struct device *dev = ec_dev->dev; 272 struct device *dev = ec_dev->dev;
240 struct cros_ec_command *proto_msg; 273 struct cros_ec_command *proto_msg;
241 struct ec_response_get_protocol_info *proto_info; 274 struct ec_response_get_protocol_info *proto_info;
275 u32 ver_mask = 0;
242 int ret; 276 int ret;
243 277
244 proto_msg = kzalloc(sizeof(*proto_msg) + sizeof(*proto_info), 278 proto_msg = kzalloc(sizeof(*proto_msg) + sizeof(*proto_info),
@@ -328,6 +362,15 @@ int cros_ec_query_all(struct cros_ec_device *ec_dev)
328 goto exit; 362 goto exit;
329 } 363 }
330 364
365 /* Probe if MKBP event is supported */
366 ret = cros_ec_get_host_command_version_mask(ec_dev,
367 EC_CMD_GET_NEXT_EVENT,
368 &ver_mask);
369 if (ret < 0 || ver_mask == 0)
370 ec_dev->mkbp_event_supported = 0;
371 else
372 ec_dev->mkbp_event_supported = 1;
373
331exit: 374exit:
332 kfree(proto_msg); 375 kfree(proto_msg);
333 return ret; 376 return ret;
@@ -397,3 +440,52 @@ int cros_ec_cmd_xfer_status(struct cros_ec_device *ec_dev,
397 return ret; 440 return ret;
398} 441}
399EXPORT_SYMBOL(cros_ec_cmd_xfer_status); 442EXPORT_SYMBOL(cros_ec_cmd_xfer_status);
443
444static int get_next_event(struct cros_ec_device *ec_dev)
445{
446 u8 buffer[sizeof(struct cros_ec_command) + sizeof(ec_dev->event_data)];
447 struct cros_ec_command *msg = (struct cros_ec_command *)&buffer;
448 int ret;
449
450 msg->version = 0;
451 msg->command = EC_CMD_GET_NEXT_EVENT;
452 msg->insize = sizeof(ec_dev->event_data);
453 msg->outsize = 0;
454
455 ret = cros_ec_cmd_xfer(ec_dev, msg);
456 if (ret > 0) {
457 ec_dev->event_size = ret - 1;
458 memcpy(&ec_dev->event_data, msg->data,
459 sizeof(ec_dev->event_data));
460 }
461
462 return ret;
463}
464
465static int get_keyboard_state_event(struct cros_ec_device *ec_dev)
466{
467 u8 buffer[sizeof(struct cros_ec_command) +
468 sizeof(ec_dev->event_data.data)];
469 struct cros_ec_command *msg = (struct cros_ec_command *)&buffer;
470
471 msg->version = 0;
472 msg->command = EC_CMD_MKBP_STATE;
473 msg->insize = sizeof(ec_dev->event_data.data);
474 msg->outsize = 0;
475
476 ec_dev->event_size = cros_ec_cmd_xfer(ec_dev, msg);
477 ec_dev->event_data.event_type = EC_MKBP_EVENT_KEY_MATRIX;
478 memcpy(&ec_dev->event_data.data, msg->data,
479 sizeof(ec_dev->event_data.data));
480
481 return ec_dev->event_size;
482}
483
484int cros_ec_get_next_event(struct cros_ec_device *ec_dev)
485{
486 if (ec_dev->mkbp_event_supported)
487 return get_next_event(ec_dev);
488 else
489 return get_keyboard_state_event(ec_dev);
490}
491EXPORT_SYMBOL(cros_ec_get_next_event);
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index 06c75186af80..936f7ccc9736 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -643,11 +643,11 @@ config REGULATOR_RC5T583
643 outputs which can be controlled by i2c communication. 643 outputs which can be controlled by i2c communication.
644 644
645config REGULATOR_RK808 645config REGULATOR_RK808
646 tristate "Rockchip RK808 Power regulators" 646 tristate "Rockchip RK808/RK818 Power regulators"
647 depends on MFD_RK808 647 depends on MFD_RK808
648 help 648 help
649 Select this option to enable the power regulator of ROCKCHIP 649 Select this option to enable the power regulator of ROCKCHIP
650 PMIC RK808. 650 PMIC RK808 and RK818.
651 This driver supports the control of different power rails of device 651 This driver supports the control of different power rails of device
652 through regulator interface. The device supports multiple DCDC/LDO 652 through regulator interface. The device supports multiple DCDC/LDO
653 outputs which can be controlled by i2c communication. 653 outputs which can be controlled by i2c communication.
diff --git a/drivers/regulator/axp20x-regulator.c b/drivers/regulator/axp20x-regulator.c
index 6d9ac76a772f..54382ef902c6 100644
--- a/drivers/regulator/axp20x-regulator.c
+++ b/drivers/regulator/axp20x-regulator.c
@@ -244,16 +244,64 @@ static const struct regulator_desc axp22x_drivevbus_regulator = {
244 .ops = &axp20x_ops_sw, 244 .ops = &axp20x_ops_sw,
245}; 245};
246 246
247static const struct regulator_linear_range axp809_dcdc4_ranges[] = { 247static const struct regulator_linear_range axp806_dcdca_ranges[] = {
248 REGULATOR_LINEAR_RANGE(600000, 0x0, 0x2f, 20000), 248 REGULATOR_LINEAR_RANGE(600000, 0x0, 0x32, 10000),
249 REGULATOR_LINEAR_RANGE(1800000, 0x30, 0x38, 100000), 249 REGULATOR_LINEAR_RANGE(1120000, 0x33, 0x47, 20000),
250}; 250};
251 251
252static const struct regulator_linear_range axp809_dldo1_ranges[] = { 252static const struct regulator_linear_range axp806_dcdcd_ranges[] = {
253 REGULATOR_LINEAR_RANGE(600000, 0x0, 0x2d, 20000),
254 REGULATOR_LINEAR_RANGE(1600000, 0x2e, 0x3f, 100000),
255};
256
257static const struct regulator_linear_range axp806_cldo2_ranges[] = {
253 REGULATOR_LINEAR_RANGE(700000, 0x0, 0x1a, 100000), 258 REGULATOR_LINEAR_RANGE(700000, 0x0, 0x1a, 100000),
254 REGULATOR_LINEAR_RANGE(3400000, 0x1b, 0x1f, 200000), 259 REGULATOR_LINEAR_RANGE(3400000, 0x1b, 0x1f, 200000),
255}; 260};
256 261
262static const struct regulator_desc axp806_regulators[] = {
263 AXP_DESC_RANGES(AXP806, DCDCA, "dcdca", "vina", axp806_dcdca_ranges,
264 72, AXP806_DCDCA_V_CTRL, 0x7f, AXP806_PWR_OUT_CTRL1,
265 BIT(0)),
266 AXP_DESC(AXP806, DCDCB, "dcdcb", "vinb", 1000, 2550, 50,
267 AXP806_DCDCB_V_CTRL, 0x1f, AXP806_PWR_OUT_CTRL1, BIT(1)),
268 AXP_DESC_RANGES(AXP806, DCDCC, "dcdcc", "vinc", axp806_dcdca_ranges,
269 72, AXP806_DCDCC_V_CTRL, 0x7f, AXP806_PWR_OUT_CTRL1,
270 BIT(2)),
271 AXP_DESC_RANGES(AXP806, DCDCD, "dcdcd", "vind", axp806_dcdcd_ranges,
272 64, AXP806_DCDCD_V_CTRL, 0x3f, AXP806_PWR_OUT_CTRL1,
273 BIT(3)),
274 AXP_DESC(AXP806, DCDCE, "dcdce", "vine", 1100, 3400, 100,
275 AXP806_DCDCB_V_CTRL, 0x1f, AXP806_PWR_OUT_CTRL1, BIT(4)),
276 AXP_DESC(AXP806, ALDO1, "aldo1", "aldoin", 700, 3300, 100,
277 AXP806_ALDO1_V_CTRL, 0x1f, AXP806_PWR_OUT_CTRL1, BIT(5)),
278 AXP_DESC(AXP806, ALDO2, "aldo2", "aldoin", 700, 3400, 100,
279 AXP806_ALDO2_V_CTRL, 0x1f, AXP806_PWR_OUT_CTRL1, BIT(6)),
280 AXP_DESC(AXP806, ALDO3, "aldo3", "aldoin", 700, 3300, 100,
281 AXP806_ALDO3_V_CTRL, 0x1f, AXP806_PWR_OUT_CTRL1, BIT(7)),
282 AXP_DESC(AXP806, BLDO1, "bldo1", "bldoin", 700, 1900, 100,
283 AXP806_BLDO1_V_CTRL, 0x0f, AXP806_PWR_OUT_CTRL2, BIT(0)),
284 AXP_DESC(AXP806, BLDO2, "bldo2", "bldoin", 700, 1900, 100,
285 AXP806_BLDO2_V_CTRL, 0x0f, AXP806_PWR_OUT_CTRL2, BIT(1)),
286 AXP_DESC(AXP806, BLDO3, "bldo3", "bldoin", 700, 1900, 100,
287 AXP806_BLDO3_V_CTRL, 0x0f, AXP806_PWR_OUT_CTRL2, BIT(2)),
288 AXP_DESC(AXP806, BLDO4, "bldo4", "bldoin", 700, 1900, 100,
289 AXP806_BLDO4_V_CTRL, 0x0f, AXP806_PWR_OUT_CTRL2, BIT(3)),
290 AXP_DESC(AXP806, CLDO1, "cldo1", "cldoin", 700, 3300, 100,
291 AXP806_CLDO1_V_CTRL, 0x1f, AXP806_PWR_OUT_CTRL2, BIT(4)),
292 AXP_DESC_RANGES(AXP806, CLDO2, "cldo2", "cldoin", axp806_cldo2_ranges,
293 32, AXP806_CLDO2_V_CTRL, 0x1f, AXP806_PWR_OUT_CTRL2,
294 BIT(5)),
295 AXP_DESC(AXP806, CLDO3, "cldo3", "cldoin", 700, 3300, 100,
296 AXP806_CLDO3_V_CTRL, 0x1f, AXP806_PWR_OUT_CTRL2, BIT(6)),
297 AXP_DESC_SW(AXP806, SW, "sw", "swin", AXP806_PWR_OUT_CTRL2, BIT(7)),
298};
299
300static const struct regulator_linear_range axp809_dcdc4_ranges[] = {
301 REGULATOR_LINEAR_RANGE(600000, 0x0, 0x2f, 20000),
302 REGULATOR_LINEAR_RANGE(1800000, 0x30, 0x38, 100000),
303};
304
257static const struct regulator_desc axp809_regulators[] = { 305static const struct regulator_desc axp809_regulators[] = {
258 AXP_DESC(AXP809, DCDC1, "dcdc1", "vin1", 1600, 3400, 100, 306 AXP_DESC(AXP809, DCDC1, "dcdc1", "vin1", 1600, 3400, 100,
259 AXP22X_DCDC1_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL1, BIT(1)), 307 AXP22X_DCDC1_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL1, BIT(1)),
@@ -278,7 +326,7 @@ static const struct regulator_desc axp809_regulators[] = {
278 AXP22X_ALDO2_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL1, BIT(7)), 326 AXP22X_ALDO2_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL1, BIT(7)),
279 AXP_DESC(AXP809, ALDO3, "aldo3", "aldoin", 700, 3300, 100, 327 AXP_DESC(AXP809, ALDO3, "aldo3", "aldoin", 700, 3300, 100,
280 AXP22X_ALDO3_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL2, BIT(5)), 328 AXP22X_ALDO3_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL2, BIT(5)),
281 AXP_DESC_RANGES(AXP809, DLDO1, "dldo1", "dldoin", axp809_dldo1_ranges, 329 AXP_DESC_RANGES(AXP809, DLDO1, "dldo1", "dldoin", axp806_cldo2_ranges,
282 32, AXP22X_DLDO1_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL2, 330 32, AXP22X_DLDO1_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL2,
283 BIT(3)), 331 BIT(3)),
284 AXP_DESC(AXP809, DLDO2, "dldo2", "dldoin", 700, 3300, 100, 332 AXP_DESC(AXP809, DLDO2, "dldo2", "dldoin", 700, 3300, 100,
@@ -302,6 +350,7 @@ static const struct regulator_desc axp809_regulators[] = {
302static int axp20x_set_dcdc_freq(struct platform_device *pdev, u32 dcdcfreq) 350static int axp20x_set_dcdc_freq(struct platform_device *pdev, u32 dcdcfreq)
303{ 351{
304 struct axp20x_dev *axp20x = dev_get_drvdata(pdev->dev.parent); 352 struct axp20x_dev *axp20x = dev_get_drvdata(pdev->dev.parent);
353 unsigned int reg = AXP20X_DCDC_FREQ;
305 u32 min, max, def, step; 354 u32 min, max, def, step;
306 355
307 switch (axp20x->variant) { 356 switch (axp20x->variant) {
@@ -312,6 +361,14 @@ static int axp20x_set_dcdc_freq(struct platform_device *pdev, u32 dcdcfreq)
312 def = 1500; 361 def = 1500;
313 step = 75; 362 step = 75;
314 break; 363 break;
364 case AXP806_ID:
365 /*
366 * AXP806 DCDC work frequency setting has the same range and
367 * step as AXP22X, but at a different register.
368 * Fall through to the check below.
369 * (See include/linux/mfd/axp20x.h)
370 */
371 reg = AXP806_DCDC_FREQ_CTRL;
315 case AXP221_ID: 372 case AXP221_ID:
316 case AXP223_ID: 373 case AXP223_ID:
317 case AXP809_ID: 374 case AXP809_ID:
@@ -343,7 +400,7 @@ static int axp20x_set_dcdc_freq(struct platform_device *pdev, u32 dcdcfreq)
343 400
344 dcdcfreq = (dcdcfreq - min) / step; 401 dcdcfreq = (dcdcfreq - min) / step;
345 402
346 return regmap_update_bits(axp20x->regmap, AXP20X_DCDC_FREQ, 403 return regmap_update_bits(axp20x->regmap, reg,
347 AXP20X_FREQ_DCDC_MASK, dcdcfreq); 404 AXP20X_FREQ_DCDC_MASK, dcdcfreq);
348} 405}
349 406
@@ -377,6 +434,7 @@ static int axp20x_regulator_parse_dt(struct platform_device *pdev)
377static int axp20x_set_dcdc_workmode(struct regulator_dev *rdev, int id, u32 workmode) 434static int axp20x_set_dcdc_workmode(struct regulator_dev *rdev, int id, u32 workmode)
378{ 435{
379 struct axp20x_dev *axp20x = rdev_get_drvdata(rdev); 436 struct axp20x_dev *axp20x = rdev_get_drvdata(rdev);
437 unsigned int reg = AXP20X_DCDC_MODE;
380 unsigned int mask; 438 unsigned int mask;
381 439
382 switch (axp20x->variant) { 440 switch (axp20x->variant) {
@@ -392,6 +450,13 @@ static int axp20x_set_dcdc_workmode(struct regulator_dev *rdev, int id, u32 work
392 workmode <<= ffs(mask) - 1; 450 workmode <<= ffs(mask) - 1;
393 break; 451 break;
394 452
453 case AXP806_ID:
454 reg = AXP806_DCDC_MODE_CTRL2;
455 /*
456 * AXP806 DCDC regulator IDs have the same range as AXP22X.
457 * Fall through to the check below.
458 * (See include/linux/mfd/axp20x.h)
459 */
395 case AXP221_ID: 460 case AXP221_ID:
396 case AXP223_ID: 461 case AXP223_ID:
397 case AXP809_ID: 462 case AXP809_ID:
@@ -408,7 +473,34 @@ static int axp20x_set_dcdc_workmode(struct regulator_dev *rdev, int id, u32 work
408 return -EINVAL; 473 return -EINVAL;
409 } 474 }
410 475
411 return regmap_update_bits(rdev->regmap, AXP20X_DCDC_MODE, mask, workmode); 476 return regmap_update_bits(rdev->regmap, reg, mask, workmode);
477}
478
479/*
480 * This function checks whether a regulator is part of a poly-phase
481 * output setup based on the registers settings. Returns true if it is.
482 */
483static bool axp20x_is_polyphase_slave(struct axp20x_dev *axp20x, int id)
484{
485 u32 reg = 0;
486
487 /* Only AXP806 has poly-phase outputs */
488 if (axp20x->variant != AXP806_ID)
489 return false;
490
491 regmap_read(axp20x->regmap, AXP806_DCDC_MODE_CTRL2, &reg);
492
493 switch (id) {
494 case AXP806_DCDCB:
495 return (((reg & GENMASK(7, 6)) == BIT(6)) ||
496 ((reg & GENMASK(7, 6)) == BIT(7)));
497 case AXP806_DCDCC:
498 return ((reg & GENMASK(7, 6)) == BIT(7));
499 case AXP806_DCDCE:
500 return !!(reg & BIT(5));
501 }
502
503 return false;
412} 504}
413 505
414static int axp20x_regulator_probe(struct platform_device *pdev) 506static int axp20x_regulator_probe(struct platform_device *pdev)
@@ -440,6 +532,10 @@ static int axp20x_regulator_probe(struct platform_device *pdev)
440 drivevbus = of_property_read_bool(pdev->dev.parent->of_node, 532 drivevbus = of_property_read_bool(pdev->dev.parent->of_node,
441 "x-powers,drive-vbus-en"); 533 "x-powers,drive-vbus-en");
442 break; 534 break;
535 case AXP806_ID:
536 regulators = axp806_regulators;
537 nregulators = AXP806_REG_ID_MAX;
538 break;
443 case AXP809_ID: 539 case AXP809_ID:
444 regulators = axp809_regulators; 540 regulators = axp809_regulators;
445 nregulators = AXP809_REG_ID_MAX; 541 nregulators = AXP809_REG_ID_MAX;
@@ -458,6 +554,14 @@ static int axp20x_regulator_probe(struct platform_device *pdev)
458 struct regulator_desc *new_desc; 554 struct regulator_desc *new_desc;
459 555
460 /* 556 /*
557 * If this regulator is a slave in a poly-phase setup,
558 * skip it, as its controls are bound to the master
559 * regulator and won't work.
560 */
561 if (axp20x_is_polyphase_slave(axp20x, i))
562 continue;
563
564 /*
461 * Regulators DC1SW and DC5LDO are connected internally, 565 * Regulators DC1SW and DC5LDO are connected internally,
462 * so we have to handle their supply names separately. 566 * so we have to handle their supply names separately.
463 * 567 *
diff --git a/drivers/regulator/qcom_rpm-regulator.c b/drivers/regulator/qcom_rpm-regulator.c
index e254272585b2..1b2acc43fea1 100644
--- a/drivers/regulator/qcom_rpm-regulator.c
+++ b/drivers/regulator/qcom_rpm-regulator.c
@@ -448,6 +448,44 @@ static struct regulator_ops switch_ops = {
448}; 448};
449 449
450/* 450/*
451 * PM8018 regulators
452 */
453static const struct qcom_rpm_reg pm8018_pldo = {
454 .desc.linear_ranges = pldo_ranges,
455 .desc.n_linear_ranges = ARRAY_SIZE(pldo_ranges),
456 .desc.n_voltages = 161,
457 .desc.ops = &uV_ops,
458 .parts = &rpm8960_ldo_parts,
459 .supports_force_mode_auto = false,
460 .supports_force_mode_bypass = false,
461};
462
463static const struct qcom_rpm_reg pm8018_nldo = {
464 .desc.linear_ranges = nldo_ranges,
465 .desc.n_linear_ranges = ARRAY_SIZE(nldo_ranges),
466 .desc.n_voltages = 64,
467 .desc.ops = &uV_ops,
468 .parts = &rpm8960_ldo_parts,
469 .supports_force_mode_auto = false,
470 .supports_force_mode_bypass = false,
471};
472
473static const struct qcom_rpm_reg pm8018_smps = {
474 .desc.linear_ranges = smps_ranges,
475 .desc.n_linear_ranges = ARRAY_SIZE(smps_ranges),
476 .desc.n_voltages = 154,
477 .desc.ops = &uV_ops,
478 .parts = &rpm8960_smps_parts,
479 .supports_force_mode_auto = false,
480 .supports_force_mode_bypass = false,
481};
482
483static const struct qcom_rpm_reg pm8018_switch = {
484 .desc.ops = &switch_ops,
485 .parts = &rpm8960_switch_parts,
486};
487
488/*
451 * PM8058 regulators 489 * PM8058 regulators
452 */ 490 */
453static const struct qcom_rpm_reg pm8058_pldo = { 491static const struct qcom_rpm_reg pm8058_pldo = {
@@ -755,6 +793,32 @@ struct rpm_regulator_data {
755 const char *supply; 793 const char *supply;
756}; 794};
757 795
796static const struct rpm_regulator_data rpm_pm8018_regulators[] = {
797 { "s1", QCOM_RPM_PM8018_SMPS1, &pm8018_smps, "vdd_s1" },
798 { "s2", QCOM_RPM_PM8018_SMPS2, &pm8018_smps, "vdd_s2" },
799 { "s3", QCOM_RPM_PM8018_SMPS3, &pm8018_smps, "vdd_s3" },
800 { "s4", QCOM_RPM_PM8018_SMPS4, &pm8018_smps, "vdd_s4" },
801 { "s5", QCOM_RPM_PM8018_SMPS5, &pm8018_smps, "vdd_s5" },
802
803 { "l2", QCOM_RPM_PM8018_LDO2, &pm8018_pldo, "vdd_l2" },
804 { "l3", QCOM_RPM_PM8018_LDO3, &pm8018_pldo, "vdd_l3" },
805 { "l4", QCOM_RPM_PM8018_LDO4, &pm8018_pldo, "vdd_l4" },
806 { "l5", QCOM_RPM_PM8018_LDO5, &pm8018_pldo, "vdd_l5" },
807 { "l6", QCOM_RPM_PM8018_LDO6, &pm8018_pldo, "vdd_l7" },
808 { "l7", QCOM_RPM_PM8018_LDO7, &pm8018_pldo, "vdd_l7" },
809 { "l8", QCOM_RPM_PM8018_LDO8, &pm8018_nldo, "vdd_l8" },
810 { "l9", QCOM_RPM_PM8018_LDO9, &pm8921_nldo1200,
811 "vdd_l9_l10_l11_l12" },
812 { "l10", QCOM_RPM_PM8018_LDO10, &pm8018_nldo, "vdd_l9_l10_l11_l12" },
813 { "l11", QCOM_RPM_PM8018_LDO11, &pm8018_nldo, "vdd_l9_l10_l11_l12" },
814 { "l12", QCOM_RPM_PM8018_LDO12, &pm8018_nldo, "vdd_l9_l10_l11_l12" },
815 { "l14", QCOM_RPM_PM8018_LDO14, &pm8018_pldo, "vdd_l14" },
816
817 { "lvs1", QCOM_RPM_PM8018_LVS1, &pm8018_switch, "lvs1_in" },
818
819 { }
820};
821
758static const struct rpm_regulator_data rpm_pm8058_regulators[] = { 822static const struct rpm_regulator_data rpm_pm8058_regulators[] = {
759 { "l0", QCOM_RPM_PM8058_LDO0, &pm8058_nldo, "vdd_l0_l1_lvs" }, 823 { "l0", QCOM_RPM_PM8058_LDO0, &pm8058_nldo, "vdd_l0_l1_lvs" },
760 { "l1", QCOM_RPM_PM8058_LDO1, &pm8058_nldo, "vdd_l0_l1_lvs" }, 824 { "l1", QCOM_RPM_PM8058_LDO1, &pm8058_nldo, "vdd_l0_l1_lvs" },
@@ -870,6 +934,8 @@ static const struct rpm_regulator_data rpm_pm8921_regulators[] = {
870}; 934};
871 935
872static const struct of_device_id rpm_of_match[] = { 936static const struct of_device_id rpm_of_match[] = {
937 { .compatible = "qcom,rpm-pm8018-regulators",
938 .data = &rpm_pm8018_regulators },
873 { .compatible = "qcom,rpm-pm8058-regulators", .data = &rpm_pm8058_regulators }, 939 { .compatible = "qcom,rpm-pm8058-regulators", .data = &rpm_pm8058_regulators },
874 { .compatible = "qcom,rpm-pm8901-regulators", .data = &rpm_pm8901_regulators }, 940 { .compatible = "qcom,rpm-pm8901-regulators", .data = &rpm_pm8901_regulators },
875 { .compatible = "qcom,rpm-pm8921-regulators", .data = &rpm_pm8921_regulators }, 941 { .compatible = "qcom,rpm-pm8921-regulators", .data = &rpm_pm8921_regulators },
diff --git a/drivers/regulator/rk808-regulator.c b/drivers/regulator/rk808-regulator.c
index a6767494d39b..3314bf299a51 100644
--- a/drivers/regulator/rk808-regulator.c
+++ b/drivers/regulator/rk808-regulator.c
@@ -1,11 +1,15 @@
1/* 1/*
2 * Regulator driver for Rockchip RK808 2 * Regulator driver for Rockchip RK808/RK818
3 * 3 *
4 * Copyright (c) 2014, Fuzhou Rockchip Electronics Co., Ltd 4 * Copyright (c) 2014, Fuzhou Rockchip Electronics Co., Ltd
5 * 5 *
6 * Author: Chris Zhong <zyw@rock-chips.com> 6 * Author: Chris Zhong <zyw@rock-chips.com>
7 * Author: Zhang Qing <zhangqing@rock-chips.com> 7 * Author: Zhang Qing <zhangqing@rock-chips.com>
8 * 8 *
9 * Copyright (C) 2016 PHYTEC Messtechnik GmbH
10 *
11 * Author: Wadim Egorov <w.egorov@phytec.de>
12 *
9 * This program is free software; you can redistribute it and/or modify it 13 * This program is free software; you can redistribute it and/or modify it
10 * under the terms and conditions of the GNU General Public License, 14 * under the terms and conditions of the GNU General Public License,
11 * version 2, as published by the Free Software Foundation. 15 * version 2, as published by the Free Software Foundation.
@@ -32,6 +36,12 @@
32#define RK808_BUCK4_VSEL_MASK 0xf 36#define RK808_BUCK4_VSEL_MASK 0xf
33#define RK808_LDO_VSEL_MASK 0x1f 37#define RK808_LDO_VSEL_MASK 0x1f
34 38
39#define RK818_BUCK_VSEL_MASK 0x3f
40#define RK818_BUCK4_VSEL_MASK 0x1f
41#define RK818_LDO_VSEL_MASK 0x1f
42#define RK818_LDO3_ON_VSEL_MASK 0xf
43#define RK818_BOOST_ON_VSEL_MASK 0xe0
44
35/* Ramp rate definitions for buck1 / buck2 only */ 45/* Ramp rate definitions for buck1 / buck2 only */
36#define RK808_RAMP_RATE_OFFSET 3 46#define RK808_RAMP_RATE_OFFSET 3
37#define RK808_RAMP_RATE_MASK (3 << RK808_RAMP_RATE_OFFSET) 47#define RK808_RAMP_RATE_MASK (3 << RK808_RAMP_RATE_OFFSET)
@@ -454,6 +464,108 @@ static const struct regulator_desc rk808_reg[] = {
454 RK808_DCDC_EN_REG, BIT(6)), 464 RK808_DCDC_EN_REG, BIT(6)),
455}; 465};
456 466
467static const struct regulator_desc rk818_reg[] = {
468 {
469 .name = "DCDC_REG1",
470 .supply_name = "vcc1",
471 .of_match = of_match_ptr("DCDC_REG1"),
472 .regulators_node = of_match_ptr("regulators"),
473 .id = RK818_ID_DCDC1,
474 .ops = &rk808_reg_ops,
475 .type = REGULATOR_VOLTAGE,
476 .min_uV = 712500,
477 .uV_step = 12500,
478 .n_voltages = 64,
479 .vsel_reg = RK818_BUCK1_ON_VSEL_REG,
480 .vsel_mask = RK818_BUCK_VSEL_MASK,
481 .enable_reg = RK818_DCDC_EN_REG,
482 .enable_mask = BIT(0),
483 .owner = THIS_MODULE,
484 }, {
485 .name = "DCDC_REG2",
486 .supply_name = "vcc2",
487 .of_match = of_match_ptr("DCDC_REG2"),
488 .regulators_node = of_match_ptr("regulators"),
489 .id = RK818_ID_DCDC2,
490 .ops = &rk808_reg_ops,
491 .type = REGULATOR_VOLTAGE,
492 .min_uV = 712500,
493 .uV_step = 12500,
494 .n_voltages = 64,
495 .vsel_reg = RK818_BUCK2_ON_VSEL_REG,
496 .vsel_mask = RK818_BUCK_VSEL_MASK,
497 .enable_reg = RK818_DCDC_EN_REG,
498 .enable_mask = BIT(1),
499 .owner = THIS_MODULE,
500 }, {
501 .name = "DCDC_REG3",
502 .supply_name = "vcc3",
503 .of_match = of_match_ptr("DCDC_REG3"),
504 .regulators_node = of_match_ptr("regulators"),
505 .id = RK818_ID_DCDC3,
506 .ops = &rk808_switch_ops,
507 .type = REGULATOR_VOLTAGE,
508 .n_voltages = 1,
509 .enable_reg = RK818_DCDC_EN_REG,
510 .enable_mask = BIT(2),
511 .owner = THIS_MODULE,
512 },
513 RK8XX_DESC(RK818_ID_DCDC4, "DCDC_REG4", "vcc4", 1800, 3600, 100,
514 RK818_BUCK4_ON_VSEL_REG, RK818_BUCK4_VSEL_MASK,
515 RK818_DCDC_EN_REG, BIT(3), 0),
516 RK8XX_DESC(RK818_ID_BOOST, "DCDC_BOOST", "boost", 4700, 5400, 100,
517 RK818_BOOST_LDO9_ON_VSEL_REG, RK818_BOOST_ON_VSEL_MASK,
518 RK818_DCDC_EN_REG, BIT(4), 0),
519 RK8XX_DESC(RK818_ID_LDO1, "LDO_REG1", "vcc6", 1800, 3400, 100,
520 RK818_LDO1_ON_VSEL_REG, RK818_LDO_VSEL_MASK, RK818_LDO_EN_REG,
521 BIT(0), 400),
522 RK8XX_DESC(RK818_ID_LDO2, "LDO_REG2", "vcc6", 1800, 3400, 100,
523 RK818_LDO1_ON_VSEL_REG, RK818_LDO_VSEL_MASK, RK818_LDO_EN_REG,
524 BIT(1), 400),
525 {
526 .name = "LDO_REG3",
527 .supply_name = "vcc7",
528 .of_match = of_match_ptr("LDO_REG3"),
529 .regulators_node = of_match_ptr("regulators"),
530 .id = RK818_ID_LDO3,
531 .ops = &rk808_reg_ops_ranges,
532 .type = REGULATOR_VOLTAGE,
533 .n_voltages = 16,
534 .linear_ranges = rk808_ldo3_voltage_ranges,
535 .n_linear_ranges = ARRAY_SIZE(rk808_ldo3_voltage_ranges),
536 .vsel_reg = RK818_LDO3_ON_VSEL_REG,
537 .vsel_mask = RK818_LDO3_ON_VSEL_MASK,
538 .enable_reg = RK818_LDO_EN_REG,
539 .enable_mask = BIT(2),
540 .enable_time = 400,
541 .owner = THIS_MODULE,
542 },
543 RK8XX_DESC(RK818_ID_LDO4, "LDO_REG4", "vcc8", 1800, 3400, 100,
544 RK818_LDO4_ON_VSEL_REG, RK818_LDO_VSEL_MASK, RK818_LDO_EN_REG,
545 BIT(3), 400),
546 RK8XX_DESC(RK818_ID_LDO5, "LDO_REG5", "vcc7", 1800, 3400, 100,
547 RK818_LDO5_ON_VSEL_REG, RK818_LDO_VSEL_MASK, RK818_LDO_EN_REG,
548 BIT(4), 400),
549 RK8XX_DESC(RK818_ID_LDO6, "LDO_REG6", "vcc8", 800, 2500, 100,
550 RK818_LDO6_ON_VSEL_REG, RK818_LDO_VSEL_MASK, RK818_LDO_EN_REG,
551 BIT(5), 400),
552 RK8XX_DESC(RK818_ID_LDO7, "LDO_REG7", "vcc7", 800, 2500, 100,
553 RK818_LDO7_ON_VSEL_REG, RK818_LDO_VSEL_MASK, RK818_LDO_EN_REG,
554 BIT(6), 400),
555 RK8XX_DESC(RK818_ID_LDO8, "LDO_REG8", "vcc8", 1800, 3400, 100,
556 RK818_LDO8_ON_VSEL_REG, RK818_LDO_VSEL_MASK, RK818_LDO_EN_REG,
557 BIT(7), 400),
558 RK8XX_DESC(RK818_ID_LDO9, "LDO_REG9", "vcc9", 1800, 3400, 100,
559 RK818_BOOST_LDO9_ON_VSEL_REG, RK818_LDO_VSEL_MASK,
560 RK818_DCDC_EN_REG, BIT(5), 400),
561 RK8XX_DESC_SWITCH(RK818_ID_SWITCH, "SWITCH_REG", "vcc9",
562 RK818_DCDC_EN_REG, BIT(6)),
563 RK8XX_DESC_SWITCH(RK818_ID_HDMI_SWITCH, "HDMI_SWITCH", "h_5v",
564 RK818_H5V_EN_REG, BIT(0)),
565 RK8XX_DESC_SWITCH(RK818_ID_OTG_SWITCH, "OTG_SWITCH", "usb",
566 RK818_DCDC_EN_REG, BIT(7)),
567};
568
457static int rk808_regulator_dt_parse_pdata(struct device *dev, 569static int rk808_regulator_dt_parse_pdata(struct device *dev,
458 struct device *client_dev, 570 struct device *client_dev,
459 struct regmap *map, 571 struct regmap *map,
@@ -499,7 +611,8 @@ static int rk808_regulator_probe(struct platform_device *pdev)
499 struct regulator_config config = {}; 611 struct regulator_config config = {};
500 struct regulator_dev *rk808_rdev; 612 struct regulator_dev *rk808_rdev;
501 struct rk808_regulator_data *pdata; 613 struct rk808_regulator_data *pdata;
502 int ret, i; 614 const struct regulator_desc *regulators;
615 int ret, i, nregulators;
503 616
504 pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); 617 pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
505 if (!pdata) 618 if (!pdata)
@@ -512,14 +625,29 @@ static int rk808_regulator_probe(struct platform_device *pdev)
512 625
513 platform_set_drvdata(pdev, pdata); 626 platform_set_drvdata(pdev, pdata);
514 627
628 switch (rk808->variant) {
629 case RK808_ID:
630 regulators = rk808_reg;
631 nregulators = RK808_NUM_REGULATORS;
632 break;
633 case RK818_ID:
634 regulators = rk818_reg;
635 nregulators = RK818_NUM_REGULATORS;
636 break;
637 default:
638 dev_err(&client->dev, "unsupported RK8XX ID %lu\n",
639 rk808->variant);
640 return -EINVAL;
641 }
642
515 config.dev = &client->dev; 643 config.dev = &client->dev;
516 config.driver_data = pdata; 644 config.driver_data = pdata;
517 config.regmap = rk808->regmap; 645 config.regmap = rk808->regmap;
518 646
519 /* Instantiate the regulators */ 647 /* Instantiate the regulators */
520 for (i = 0; i < RK808_NUM_REGULATORS; i++) { 648 for (i = 0; i < nregulators; i++) {
521 rk808_rdev = devm_regulator_register(&pdev->dev, 649 rk808_rdev = devm_regulator_register(&pdev->dev,
522 &rk808_reg[i], &config); 650 &regulators[i], &config);
523 if (IS_ERR(rk808_rdev)) { 651 if (IS_ERR(rk808_rdev)) {
524 dev_err(&client->dev, 652 dev_err(&client->dev,
525 "failed to register %d regulator\n", i); 653 "failed to register %d regulator\n", i);
@@ -539,8 +667,9 @@ static struct platform_driver rk808_regulator_driver = {
539 667
540module_platform_driver(rk808_regulator_driver); 668module_platform_driver(rk808_regulator_driver);
541 669
542MODULE_DESCRIPTION("regulator driver for the rk808 series PMICs"); 670MODULE_DESCRIPTION("regulator driver for the RK808/RK818 series PMICs");
543MODULE_AUTHOR("Chris Zhong<zyw@rock-chips.com>"); 671MODULE_AUTHOR("Chris Zhong <zyw@rock-chips.com>");
544MODULE_AUTHOR("Zhang Qing<zhangqing@rock-chips.com>"); 672MODULE_AUTHOR("Zhang Qing <zhangqing@rock-chips.com>");
673MODULE_AUTHOR("Wadim Egorov <w.egorov@phytec.de>");
545MODULE_LICENSE("GPL"); 674MODULE_LICENSE("GPL");
546MODULE_ALIAS("platform:rk808-regulator"); 675MODULE_ALIAS("platform:rk808-regulator");
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index e215f50794b6..d1e080701264 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -187,6 +187,16 @@ config RTC_DRV_ABX80X
187 This driver can also be built as a module. If so, the module 187 This driver can also be built as a module. If so, the module
188 will be called rtc-abx80x. 188 will be called rtc-abx80x.
189 189
190config RTC_DRV_AC100
191 tristate "X-Powers AC100"
192 depends on MFD_AC100
193 help
194 If you say yes here you get support for the real-time clock found
195 in X-Powers AC100 family peripheral ICs.
196
197 This driver can also be built as a module. If so, the module
198 will be called rtc-ac100.
199
190config RTC_DRV_AS3722 200config RTC_DRV_AS3722
191 tristate "ams AS3722 RTC driver" 201 tristate "ams AS3722 RTC driver"
192 depends on MFD_AS3722 202 depends on MFD_AS3722
@@ -328,11 +338,11 @@ config RTC_DRV_MAX77686
328 will be called rtc-max77686. 338 will be called rtc-max77686.
329 339
330config RTC_DRV_RK808 340config RTC_DRV_RK808
331 tristate "Rockchip RK808 RTC" 341 tristate "Rockchip RK808/RK818 RTC"
332 depends on MFD_RK808 342 depends on MFD_RK808
333 help 343 help
334 If you say yes here you will get support for the 344 If you say yes here you will get support for the
335 RTC of RK808 PMIC. 345 RTC of RK808 and RK818 PMIC.
336 346
337 This driver can also be built as a module. If so, the module 347 This driver can also be built as a module. If so, the module
338 will be called rk808-rtc. 348 will be called rk808-rtc.
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
index 7cf7ad559c79..8fb994bacdf7 100644
--- a/drivers/rtc/Makefile
+++ b/drivers/rtc/Makefile
@@ -27,6 +27,7 @@ obj-$(CONFIG_RTC_DRV_AB3100) += rtc-ab3100.o
27obj-$(CONFIG_RTC_DRV_AB8500) += rtc-ab8500.o 27obj-$(CONFIG_RTC_DRV_AB8500) += rtc-ab8500.o
28obj-$(CONFIG_RTC_DRV_ABB5ZES3) += rtc-ab-b5ze-s3.o 28obj-$(CONFIG_RTC_DRV_ABB5ZES3) += rtc-ab-b5ze-s3.o
29obj-$(CONFIG_RTC_DRV_ABX80X) += rtc-abx80x.o 29obj-$(CONFIG_RTC_DRV_ABX80X) += rtc-abx80x.o
30obj-$(CONFIG_RTC_DRV_AC100) += rtc-ac100.o
30obj-$(CONFIG_RTC_DRV_ARMADA38X) += rtc-armada38x.o 31obj-$(CONFIG_RTC_DRV_ARMADA38X) += rtc-armada38x.o
31obj-$(CONFIG_RTC_DRV_AS3722) += rtc-as3722.o 32obj-$(CONFIG_RTC_DRV_AS3722) += rtc-as3722.o
32obj-$(CONFIG_RTC_DRV_ASM9260) += rtc-asm9260.o 33obj-$(CONFIG_RTC_DRV_ASM9260) += rtc-asm9260.o
diff --git a/drivers/rtc/rtc-ac100.c b/drivers/rtc/rtc-ac100.c
new file mode 100644
index 000000000000..70b4fd0f6122
--- /dev/null
+++ b/drivers/rtc/rtc-ac100.c
@@ -0,0 +1,627 @@
1/*
2 * RTC Driver for X-Powers AC100
3 *
4 * Copyright (c) 2016 Chen-Yu Tsai
5 *
6 * Chen-Yu Tsai <wens@csie.org>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 * more details.
16 */
17
18#include <linux/bcd.h>
19#include <linux/clk-provider.h>
20#include <linux/device.h>
21#include <linux/interrupt.h>
22#include <linux/kernel.h>
23#include <linux/mfd/ac100.h>
24#include <linux/module.h>
25#include <linux/mutex.h>
26#include <linux/of.h>
27#include <linux/platform_device.h>
28#include <linux/regmap.h>
29#include <linux/rtc.h>
30#include <linux/types.h>
31
32/* Control register */
33#define AC100_RTC_CTRL_24HOUR BIT(0)
34
35/* Clock output register bits */
36#define AC100_CLKOUT_PRE_DIV_SHIFT 5
37#define AC100_CLKOUT_PRE_DIV_WIDTH 3
38#define AC100_CLKOUT_MUX_SHIFT 4
39#define AC100_CLKOUT_MUX_WIDTH 1
40#define AC100_CLKOUT_DIV_SHIFT 1
41#define AC100_CLKOUT_DIV_WIDTH 3
42#define AC100_CLKOUT_EN BIT(0)
43
44/* RTC */
45#define AC100_RTC_SEC_MASK GENMASK(6, 0)
46#define AC100_RTC_MIN_MASK GENMASK(6, 0)
47#define AC100_RTC_HOU_MASK GENMASK(5, 0)
48#define AC100_RTC_WEE_MASK GENMASK(2, 0)
49#define AC100_RTC_DAY_MASK GENMASK(5, 0)
50#define AC100_RTC_MON_MASK GENMASK(4, 0)
51#define AC100_RTC_YEA_MASK GENMASK(7, 0)
52#define AC100_RTC_YEA_LEAP BIT(15)
53#define AC100_RTC_UPD_TRIGGER BIT(15)
54
55/* Alarm (wall clock) */
56#define AC100_ALM_INT_ENABLE BIT(0)
57
58#define AC100_ALM_SEC_MASK GENMASK(6, 0)
59#define AC100_ALM_MIN_MASK GENMASK(6, 0)
60#define AC100_ALM_HOU_MASK GENMASK(5, 0)
61#define AC100_ALM_WEE_MASK GENMASK(2, 0)
62#define AC100_ALM_DAY_MASK GENMASK(5, 0)
63#define AC100_ALM_MON_MASK GENMASK(4, 0)
64#define AC100_ALM_YEA_MASK GENMASK(7, 0)
65#define AC100_ALM_ENABLE_FLAG BIT(15)
66#define AC100_ALM_UPD_TRIGGER BIT(15)
67
68/*
69 * The year parameter passed to the driver is usually an offset relative to
70 * the year 1900. This macro is used to convert this offset to another one
71 * relative to the minimum year allowed by the hardware.
72 *
73 * The year range is 1970 - 2069. This range is selected to match Allwinner's
74 * driver.
75 */
76#define AC100_YEAR_MIN 1970
77#define AC100_YEAR_MAX 2069
78#define AC100_YEAR_OFF (AC100_YEAR_MIN - 1900)
79
80struct ac100_clkout {
81 struct clk_hw hw;
82 struct regmap *regmap;
83 u8 offset;
84};
85
86#define to_ac100_clkout(_hw) container_of(_hw, struct ac100_clkout, hw)
87
88#define AC100_RTC_32K_NAME "ac100-rtc-32k"
89#define AC100_RTC_32K_RATE 32768
90#define AC100_CLKOUT_NUM 3
91
92static const char * const ac100_clkout_names[AC100_CLKOUT_NUM] = {
93 "ac100-cko1-rtc",
94 "ac100-cko2-rtc",
95 "ac100-cko3-rtc",
96};
97
98struct ac100_rtc_dev {
99 struct rtc_device *rtc;
100 struct device *dev;
101 struct regmap *regmap;
102 int irq;
103 unsigned long alarm;
104
105 struct clk_hw *rtc_32k_clk;
106 struct ac100_clkout clks[AC100_CLKOUT_NUM];
107 struct clk_hw_onecell_data *clk_data;
108};
109
110/**
111 * Clock controls for 3 clock output pins
112 */
113
114static const struct clk_div_table ac100_clkout_prediv[] = {
115 { .val = 0, .div = 1 },
116 { .val = 1, .div = 2 },
117 { .val = 2, .div = 4 },
118 { .val = 3, .div = 8 },
119 { .val = 4, .div = 16 },
120 { .val = 5, .div = 32 },
121 { .val = 6, .div = 64 },
122 { .val = 7, .div = 122 },
123 { },
124};
125
126/* Abuse the fact that one parent is 32768 Hz, and the other is 4 MHz */
127static unsigned long ac100_clkout_recalc_rate(struct clk_hw *hw,
128 unsigned long prate)
129{
130 struct ac100_clkout *clk = to_ac100_clkout(hw);
131 unsigned int reg, div;
132
133 regmap_read(clk->regmap, clk->offset, &reg);
134
135 /* Handle pre-divider first */
136 if (prate != AC100_RTC_32K_RATE) {
137 div = (reg >> AC100_CLKOUT_PRE_DIV_SHIFT) &
138 ((1 << AC100_CLKOUT_PRE_DIV_WIDTH) - 1);
139 prate = divider_recalc_rate(hw, prate, div,
140 ac100_clkout_prediv, 0);
141 }
142
143 div = (reg >> AC100_CLKOUT_DIV_SHIFT) &
144 (BIT(AC100_CLKOUT_DIV_WIDTH) - 1);
145 return divider_recalc_rate(hw, prate, div, NULL,
146 CLK_DIVIDER_POWER_OF_TWO);
147}
148
149static long ac100_clkout_round_rate(struct clk_hw *hw, unsigned long rate,
150 unsigned long prate)
151{
152 unsigned long best_rate = 0, tmp_rate, tmp_prate;
153 int i;
154
155 if (prate == AC100_RTC_32K_RATE)
156 return divider_round_rate(hw, rate, &prate, NULL,
157 AC100_CLKOUT_DIV_WIDTH,
158 CLK_DIVIDER_POWER_OF_TWO);
159
160 for (i = 0; ac100_clkout_prediv[i].div; i++) {
161 tmp_prate = DIV_ROUND_UP(prate, ac100_clkout_prediv[i].val);
162 tmp_rate = divider_round_rate(hw, rate, &tmp_prate, NULL,
163 AC100_CLKOUT_DIV_WIDTH,
164 CLK_DIVIDER_POWER_OF_TWO);
165
166 if (tmp_rate > rate)
167 continue;
168 if (rate - tmp_rate < best_rate - tmp_rate)
169 best_rate = tmp_rate;
170 }
171
172 return best_rate;
173}
174
175static int ac100_clkout_determine_rate(struct clk_hw *hw,
176 struct clk_rate_request *req)
177{
178 struct clk_hw *best_parent;
179 unsigned long best = 0;
180 int i, num_parents = clk_hw_get_num_parents(hw);
181
182 for (i = 0; i < num_parents; i++) {
183 struct clk_hw *parent = clk_hw_get_parent_by_index(hw, i);
184 unsigned long tmp, prate = clk_hw_get_rate(parent);
185
186 tmp = ac100_clkout_round_rate(hw, req->rate, prate);
187
188 if (tmp > req->rate)
189 continue;
190 if (req->rate - tmp < req->rate - best) {
191 best = tmp;
192 best_parent = parent;
193 }
194 }
195
196 if (!best)
197 return -EINVAL;
198
199 req->best_parent_hw = best_parent;
200 req->best_parent_rate = best;
201 req->rate = best;
202
203 return 0;
204}
205
206static int ac100_clkout_set_rate(struct clk_hw *hw, unsigned long rate,
207 unsigned long prate)
208{
209 struct ac100_clkout *clk = to_ac100_clkout(hw);
210 int div = 0, pre_div = 0;
211
212 do {
213 div = divider_get_val(rate * ac100_clkout_prediv[pre_div].div,
214 prate, NULL, AC100_CLKOUT_DIV_WIDTH,
215 CLK_DIVIDER_POWER_OF_TWO);
216 if (div >= 0)
217 break;
218 } while (prate != AC100_RTC_32K_RATE &&
219 ac100_clkout_prediv[++pre_div].div);
220
221 if (div < 0)
222 return div;
223
224 pre_div = ac100_clkout_prediv[pre_div].val;
225
226 regmap_update_bits(clk->regmap, clk->offset,
227 ((1 << AC100_CLKOUT_DIV_WIDTH) - 1) << AC100_CLKOUT_DIV_SHIFT |
228 ((1 << AC100_CLKOUT_PRE_DIV_WIDTH) - 1) << AC100_CLKOUT_PRE_DIV_SHIFT,
229 (div - 1) << AC100_CLKOUT_DIV_SHIFT |
230 (pre_div - 1) << AC100_CLKOUT_PRE_DIV_SHIFT);
231
232 return 0;
233}
234
235static int ac100_clkout_prepare(struct clk_hw *hw)
236{
237 struct ac100_clkout *clk = to_ac100_clkout(hw);
238
239 return regmap_update_bits(clk->regmap, clk->offset, AC100_CLKOUT_EN,
240 AC100_CLKOUT_EN);
241}
242
243static void ac100_clkout_unprepare(struct clk_hw *hw)
244{
245 struct ac100_clkout *clk = to_ac100_clkout(hw);
246
247 regmap_update_bits(clk->regmap, clk->offset, AC100_CLKOUT_EN, 0);
248}
249
250static int ac100_clkout_is_prepared(struct clk_hw *hw)
251{
252 struct ac100_clkout *clk = to_ac100_clkout(hw);
253 unsigned int reg;
254
255 regmap_read(clk->regmap, clk->offset, &reg);
256
257 return reg & AC100_CLKOUT_EN;
258}
259
260static u8 ac100_clkout_get_parent(struct clk_hw *hw)
261{
262 struct ac100_clkout *clk = to_ac100_clkout(hw);
263 unsigned int reg;
264
265 regmap_read(clk->regmap, clk->offset, &reg);
266
267 return (reg >> AC100_CLKOUT_MUX_SHIFT) & 0x1;
268}
269
270static int ac100_clkout_set_parent(struct clk_hw *hw, u8 index)
271{
272 struct ac100_clkout *clk = to_ac100_clkout(hw);
273
274 return regmap_update_bits(clk->regmap, clk->offset,
275 BIT(AC100_CLKOUT_MUX_SHIFT),
276 index ? BIT(AC100_CLKOUT_MUX_SHIFT) : 0);
277}
278
279static const struct clk_ops ac100_clkout_ops = {
280 .prepare = ac100_clkout_prepare,
281 .unprepare = ac100_clkout_unprepare,
282 .is_prepared = ac100_clkout_is_prepared,
283 .recalc_rate = ac100_clkout_recalc_rate,
284 .determine_rate = ac100_clkout_determine_rate,
285 .get_parent = ac100_clkout_get_parent,
286 .set_parent = ac100_clkout_set_parent,
287 .set_rate = ac100_clkout_set_rate,
288};
289
290static int ac100_rtc_register_clks(struct ac100_rtc_dev *chip)
291{
292 struct device_node *np = chip->dev->of_node;
293 const char *parents[2] = {AC100_RTC_32K_NAME};
294 int i, ret;
295
296 chip->clk_data = devm_kzalloc(chip->dev, sizeof(*chip->clk_data) +
297 sizeof(*chip->clk_data->hws) *
298 AC100_CLKOUT_NUM,
299 GFP_KERNEL);
300 if (!chip->clk_data)
301 return -ENOMEM;
302
303 chip->rtc_32k_clk = clk_hw_register_fixed_rate(chip->dev,
304 AC100_RTC_32K_NAME,
305 NULL, 0,
306 AC100_RTC_32K_RATE);
307 if (IS_ERR(chip->rtc_32k_clk)) {
308 ret = PTR_ERR(chip->rtc_32k_clk);
309 dev_err(chip->dev, "Failed to register RTC-32k clock: %d\n",
310 ret);
311 return ret;
312 }
313
314 parents[1] = of_clk_get_parent_name(np, 0);
315 if (!parents[1]) {
316 dev_err(chip->dev, "Failed to get ADDA 4M clock\n");
317 return -EINVAL;
318 }
319
320 for (i = 0; i < AC100_CLKOUT_NUM; i++) {
321 struct ac100_clkout *clk = &chip->clks[i];
322 struct clk_init_data init = {
323 .name = ac100_clkout_names[i],
324 .ops = &ac100_clkout_ops,
325 .parent_names = parents,
326 .num_parents = ARRAY_SIZE(parents),
327 .flags = 0,
328 };
329
330 clk->regmap = chip->regmap;
331 clk->offset = AC100_CLKOUT_CTRL1 + i;
332 clk->hw.init = &init;
333
334 ret = devm_clk_hw_register(chip->dev, &clk->hw);
335 if (ret) {
336 dev_err(chip->dev, "Failed to register clk '%s': %d\n",
337 init.name, ret);
338 goto err_unregister_rtc_32k;
339 }
340
341 chip->clk_data->hws[i] = &clk->hw;
342 }
343
344 chip->clk_data->num = i;
345 ret = of_clk_add_hw_provider(np, of_clk_hw_onecell_get, chip->clk_data);
346 if (ret)
347 goto err_unregister_rtc_32k;
348
349 return 0;
350
351err_unregister_rtc_32k:
352 clk_unregister_fixed_rate(chip->rtc_32k_clk->clk);
353
354 return ret;
355}
356
357static void ac100_rtc_unregister_clks(struct ac100_rtc_dev *chip)
358{
359 of_clk_del_provider(chip->dev->of_node);
360 clk_unregister_fixed_rate(chip->rtc_32k_clk->clk);
361}
362
363/**
364 * RTC related bits
365 */
366static int ac100_rtc_get_time(struct device *dev, struct rtc_time *rtc_tm)
367{
368 struct ac100_rtc_dev *chip = dev_get_drvdata(dev);
369 struct regmap *regmap = chip->regmap;
370 u16 reg[7];
371 int ret;
372
373 ret = regmap_bulk_read(regmap, AC100_RTC_SEC, reg, 7);
374 if (ret)
375 return ret;
376
377 rtc_tm->tm_sec = bcd2bin(reg[0] & AC100_RTC_SEC_MASK);
378 rtc_tm->tm_min = bcd2bin(reg[1] & AC100_RTC_MIN_MASK);
379 rtc_tm->tm_hour = bcd2bin(reg[2] & AC100_RTC_HOU_MASK);
380 rtc_tm->tm_wday = bcd2bin(reg[3] & AC100_RTC_WEE_MASK);
381 rtc_tm->tm_mday = bcd2bin(reg[4] & AC100_RTC_DAY_MASK);
382 rtc_tm->tm_mon = bcd2bin(reg[5] & AC100_RTC_MON_MASK) - 1;
383 rtc_tm->tm_year = bcd2bin(reg[6] & AC100_RTC_YEA_MASK) +
384 AC100_YEAR_OFF;
385
386 return rtc_valid_tm(rtc_tm);
387}
388
389static int ac100_rtc_set_time(struct device *dev, struct rtc_time *rtc_tm)
390{
391 struct ac100_rtc_dev *chip = dev_get_drvdata(dev);
392 struct regmap *regmap = chip->regmap;
393 int year;
394 u16 reg[8];
395
396 /* our RTC has a limited year range... */
397 year = rtc_tm->tm_year - AC100_YEAR_OFF;
398 if (year < 0 || year > (AC100_YEAR_MAX - 1900)) {
399 dev_err(dev, "rtc only supports year in range %d - %d\n",
400 AC100_YEAR_MIN, AC100_YEAR_MAX);
401 return -EINVAL;
402 }
403
404 /* convert to BCD */
405 reg[0] = bin2bcd(rtc_tm->tm_sec) & AC100_RTC_SEC_MASK;
406 reg[1] = bin2bcd(rtc_tm->tm_min) & AC100_RTC_MIN_MASK;
407 reg[2] = bin2bcd(rtc_tm->tm_hour) & AC100_RTC_HOU_MASK;
408 reg[3] = bin2bcd(rtc_tm->tm_wday) & AC100_RTC_WEE_MASK;
409 reg[4] = bin2bcd(rtc_tm->tm_mday) & AC100_RTC_DAY_MASK;
410 reg[5] = bin2bcd(rtc_tm->tm_mon + 1) & AC100_RTC_MON_MASK;
411 reg[6] = bin2bcd(year) & AC100_RTC_YEA_MASK;
412 /* trigger write */
413 reg[7] = AC100_RTC_UPD_TRIGGER;
414
415 /* Is it a leap year? */
416 if (is_leap_year(year + AC100_YEAR_OFF + 1900))
417 reg[6] |= AC100_RTC_YEA_LEAP;
418
419 return regmap_bulk_write(regmap, AC100_RTC_SEC, reg, 8);
420}
421
422static int ac100_rtc_alarm_irq_enable(struct device *dev, unsigned int en)
423{
424 struct ac100_rtc_dev *chip = dev_get_drvdata(dev);
425 struct regmap *regmap = chip->regmap;
426 unsigned int val;
427
428 val = en ? AC100_ALM_INT_ENABLE : 0;
429
430 return regmap_write(regmap, AC100_ALM_INT_ENA, val);
431}
432
433static int ac100_rtc_get_alarm(struct device *dev, struct rtc_wkalrm *alrm)
434{
435 struct ac100_rtc_dev *chip = dev_get_drvdata(dev);
436 struct regmap *regmap = chip->regmap;
437 struct rtc_time *alrm_tm = &alrm->time;
438 u16 reg[7];
439 unsigned int val;
440 int ret;
441
442 ret = regmap_read(regmap, AC100_ALM_INT_ENA, &val);
443 if (ret)
444 return ret;
445
446 alrm->enabled = !!(val & AC100_ALM_INT_ENABLE);
447
448 ret = regmap_bulk_read(regmap, AC100_ALM_SEC, reg, 7);
449 if (ret)
450 return ret;
451
452 alrm_tm->tm_sec = bcd2bin(reg[0] & AC100_ALM_SEC_MASK);
453 alrm_tm->tm_min = bcd2bin(reg[1] & AC100_ALM_MIN_MASK);
454 alrm_tm->tm_hour = bcd2bin(reg[2] & AC100_ALM_HOU_MASK);
455 alrm_tm->tm_wday = bcd2bin(reg[3] & AC100_ALM_WEE_MASK);
456 alrm_tm->tm_mday = bcd2bin(reg[4] & AC100_ALM_DAY_MASK);
457 alrm_tm->tm_mon = bcd2bin(reg[5] & AC100_ALM_MON_MASK) - 1;
458 alrm_tm->tm_year = bcd2bin(reg[6] & AC100_ALM_YEA_MASK) +
459 AC100_YEAR_OFF;
460
461 return 0;
462}
463
464static int ac100_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
465{
466 struct ac100_rtc_dev *chip = dev_get_drvdata(dev);
467 struct regmap *regmap = chip->regmap;
468 struct rtc_time *alrm_tm = &alrm->time;
469 u16 reg[8];
470 int year;
471 int ret;
472
473 /* our alarm has a limited year range... */
474 year = alrm_tm->tm_year - AC100_YEAR_OFF;
475 if (year < 0 || year > (AC100_YEAR_MAX - 1900)) {
476 dev_err(dev, "alarm only supports year in range %d - %d\n",
477 AC100_YEAR_MIN, AC100_YEAR_MAX);
478 return -EINVAL;
479 }
480
481 /* convert to BCD */
482 reg[0] = (bin2bcd(alrm_tm->tm_sec) & AC100_ALM_SEC_MASK) |
483 AC100_ALM_ENABLE_FLAG;
484 reg[1] = (bin2bcd(alrm_tm->tm_min) & AC100_ALM_MIN_MASK) |
485 AC100_ALM_ENABLE_FLAG;
486 reg[2] = (bin2bcd(alrm_tm->tm_hour) & AC100_ALM_HOU_MASK) |
487 AC100_ALM_ENABLE_FLAG;
488 /* Do not enable weekday alarm */
489 reg[3] = bin2bcd(alrm_tm->tm_wday) & AC100_ALM_WEE_MASK;
490 reg[4] = (bin2bcd(alrm_tm->tm_mday) & AC100_ALM_DAY_MASK) |
491 AC100_ALM_ENABLE_FLAG;
492 reg[5] = (bin2bcd(alrm_tm->tm_mon + 1) & AC100_ALM_MON_MASK) |
493 AC100_ALM_ENABLE_FLAG;
494 reg[6] = (bin2bcd(year) & AC100_ALM_YEA_MASK) |
495 AC100_ALM_ENABLE_FLAG;
496 /* trigger write */
497 reg[7] = AC100_ALM_UPD_TRIGGER;
498
499 ret = regmap_bulk_write(regmap, AC100_ALM_SEC, reg, 8);
500 if (ret)
501 return ret;
502
503 return ac100_rtc_alarm_irq_enable(dev, alrm->enabled);
504}
505
506static irqreturn_t ac100_rtc_irq(int irq, void *data)
507{
508 struct ac100_rtc_dev *chip = data;
509 struct regmap *regmap = chip->regmap;
510 unsigned int val = 0;
511 int ret;
512
513 mutex_lock(&chip->rtc->ops_lock);
514
515 /* read status */
516 ret = regmap_read(regmap, AC100_ALM_INT_STA, &val);
517 if (ret)
518 goto out;
519
520 if (val & AC100_ALM_INT_ENABLE) {
521 /* signal rtc framework */
522 rtc_update_irq(chip->rtc, 1, RTC_AF | RTC_IRQF);
523
524 /* clear status */
525 ret = regmap_write(regmap, AC100_ALM_INT_STA, val);
526 if (ret)
527 goto out;
528
529 /* disable interrupt */
530 ret = ac100_rtc_alarm_irq_enable(chip->dev, 0);
531 if (ret)
532 goto out;
533 }
534
535out:
536 mutex_unlock(&chip->rtc->ops_lock);
537 return IRQ_HANDLED;
538}
539
540static const struct rtc_class_ops ac100_rtc_ops = {
541 .read_time = ac100_rtc_get_time,
542 .set_time = ac100_rtc_set_time,
543 .read_alarm = ac100_rtc_get_alarm,
544 .set_alarm = ac100_rtc_set_alarm,
545 .alarm_irq_enable = ac100_rtc_alarm_irq_enable,
546};
547
548static int ac100_rtc_probe(struct platform_device *pdev)
549{
550 struct ac100_dev *ac100 = dev_get_drvdata(pdev->dev.parent);
551 struct ac100_rtc_dev *chip;
552 int ret;
553
554 chip = devm_kzalloc(&pdev->dev, sizeof(*chip), GFP_KERNEL);
555 platform_set_drvdata(pdev, chip);
556 chip->dev = &pdev->dev;
557 chip->regmap = ac100->regmap;
558
559 chip->irq = platform_get_irq(pdev, 0);
560 if (chip->irq < 0) {
561 dev_err(&pdev->dev, "No IRQ resource\n");
562 return chip->irq;
563 }
564
565 ret = devm_request_threaded_irq(&pdev->dev, chip->irq, NULL,
566 ac100_rtc_irq,
567 IRQF_SHARED | IRQF_ONESHOT,
568 dev_name(&pdev->dev), chip);
569 if (ret) {
570 dev_err(&pdev->dev, "Could not request IRQ\n");
571 return ret;
572 }
573
574 /* always use 24 hour mode */
575 regmap_write_bits(chip->regmap, AC100_RTC_CTRL, AC100_RTC_CTRL_24HOUR,
576 AC100_RTC_CTRL_24HOUR);
577
578 /* disable counter alarm interrupt */
579 regmap_write(chip->regmap, AC100_ALM_INT_ENA, 0);
580
581 /* clear counter alarm pending interrupts */
582 regmap_write(chip->regmap, AC100_ALM_INT_STA, AC100_ALM_INT_ENABLE);
583
584 chip->rtc = devm_rtc_device_register(&pdev->dev, "rtc-ac100",
585 &ac100_rtc_ops, THIS_MODULE);
586 if (IS_ERR(chip->rtc)) {
587 dev_err(&pdev->dev, "unable to register device\n");
588 return PTR_ERR(chip->rtc);
589 }
590
591 ret = ac100_rtc_register_clks(chip);
592 if (ret)
593 return ret;
594
595 dev_info(&pdev->dev, "RTC enabled\n");
596
597 return 0;
598}
599
600static int ac100_rtc_remove(struct platform_device *pdev)
601{
602 struct ac100_rtc_dev *chip = platform_get_drvdata(pdev);
603
604 ac100_rtc_unregister_clks(chip);
605
606 return 0;
607}
608
609static const struct of_device_id ac100_rtc_match[] = {
610 { .compatible = "x-powers,ac100-rtc" },
611 { },
612};
613MODULE_DEVICE_TABLE(of, ac100_rtc_match);
614
615static struct platform_driver ac100_rtc_driver = {
616 .probe = ac100_rtc_probe,
617 .remove = ac100_rtc_remove,
618 .driver = {
619 .name = "ac100-rtc",
620 .of_match_table = of_match_ptr(ac100_rtc_match),
621 },
622};
623module_platform_driver(ac100_rtc_driver);
624
625MODULE_DESCRIPTION("X-Powers AC100 RTC driver");
626MODULE_AUTHOR("Chen-Yu Tsai <wens@csie.org>");
627MODULE_LICENSE("GPL v2");
diff --git a/drivers/rtc/rtc-pm8xxx.c b/drivers/rtc/rtc-pm8xxx.c
index 795fcbd02ea3..fac835530671 100644
--- a/drivers/rtc/rtc-pm8xxx.c
+++ b/drivers/rtc/rtc-pm8xxx.c
@@ -428,6 +428,7 @@ static const struct pm8xxx_rtc_regs pm8941_regs = {
428 */ 428 */
429static const struct of_device_id pm8xxx_id_table[] = { 429static const struct of_device_id pm8xxx_id_table[] = {
430 { .compatible = "qcom,pm8921-rtc", .data = &pm8921_regs }, 430 { .compatible = "qcom,pm8921-rtc", .data = &pm8921_regs },
431 { .compatible = "qcom,pm8018-rtc", .data = &pm8921_regs },
431 { .compatible = "qcom,pm8058-rtc", .data = &pm8058_regs }, 432 { .compatible = "qcom,pm8058-rtc", .data = &pm8058_regs },
432 { .compatible = "qcom,pm8941-rtc", .data = &pm8941_regs }, 433 { .compatible = "qcom,pm8941-rtc", .data = &pm8941_regs },
433 { }, 434 { },
diff --git a/include/dt-bindings/mfd/qcom-rpm.h b/include/dt-bindings/mfd/qcom-rpm.h
index 13a9d4bf2662..54aef5e21763 100644
--- a/include/dt-bindings/mfd/qcom-rpm.h
+++ b/include/dt-bindings/mfd/qcom-rpm.h
@@ -147,6 +147,28 @@
147#define QCOM_RPM_SMB208_S1b 137 147#define QCOM_RPM_SMB208_S1b 137
148#define QCOM_RPM_SMB208_S2a 138 148#define QCOM_RPM_SMB208_S2a 138
149#define QCOM_RPM_SMB208_S2b 139 149#define QCOM_RPM_SMB208_S2b 139
150#define QCOM_RPM_PM8018_SMPS1 140
151#define QCOM_RPM_PM8018_SMPS2 141
152#define QCOM_RPM_PM8018_SMPS3 142
153#define QCOM_RPM_PM8018_SMPS4 143
154#define QCOM_RPM_PM8018_SMPS5 144
155#define QCOM_RPM_PM8018_LDO1 145
156#define QCOM_RPM_PM8018_LDO2 146
157#define QCOM_RPM_PM8018_LDO3 147
158#define QCOM_RPM_PM8018_LDO4 148
159#define QCOM_RPM_PM8018_LDO5 149
160#define QCOM_RPM_PM8018_LDO6 150
161#define QCOM_RPM_PM8018_LDO7 151
162#define QCOM_RPM_PM8018_LDO8 152
163#define QCOM_RPM_PM8018_LDO9 153
164#define QCOM_RPM_PM8018_LDO10 154
165#define QCOM_RPM_PM8018_LDO11 155
166#define QCOM_RPM_PM8018_LDO12 156
167#define QCOM_RPM_PM8018_LDO13 157
168#define QCOM_RPM_PM8018_LDO14 158
169#define QCOM_RPM_PM8018_LVS1 159
170#define QCOM_RPM_PM8018_NCP 160
171#define QCOM_RPM_VOLTAGE_CORNER 161
150 172
151/* 173/*
152 * Constants used to select force mode for regulators. 174 * Constants used to select force mode for regulators.
diff --git a/include/linux/mfd/88pm80x.h b/include/linux/mfd/88pm80x.h
index d409ceb2231e..c118a7ec94d6 100644
--- a/include/linux/mfd/88pm80x.h
+++ b/include/linux/mfd/88pm80x.h
@@ -350,7 +350,7 @@ static inline int pm80x_dev_suspend(struct device *dev)
350 int irq = platform_get_irq(pdev, 0); 350 int irq = platform_get_irq(pdev, 0);
351 351
352 if (device_may_wakeup(dev)) 352 if (device_may_wakeup(dev))
353 set_bit((1 << irq), &chip->wu_flag); 353 set_bit(irq, &chip->wu_flag);
354 354
355 return 0; 355 return 0;
356} 356}
@@ -362,7 +362,7 @@ static inline int pm80x_dev_resume(struct device *dev)
362 int irq = platform_get_irq(pdev, 0); 362 int irq = platform_get_irq(pdev, 0);
363 363
364 if (device_may_wakeup(dev)) 364 if (device_may_wakeup(dev))
365 clear_bit((1 << irq), &chip->wu_flag); 365 clear_bit(irq, &chip->wu_flag);
366 366
367 return 0; 367 return 0;
368} 368}
diff --git a/include/linux/mfd/abx500/ab8500.h b/include/linux/mfd/abx500/ab8500.h
index 9475fee2bfc5..d33c245e75ca 100644
--- a/include/linux/mfd/abx500/ab8500.h
+++ b/include/linux/mfd/abx500/ab8500.h
@@ -63,6 +63,8 @@ enum ab8500_version {
63#define AB8500_STE_TEST 0x14 63#define AB8500_STE_TEST 0x14
64#define AB8500_OTP_EMUL 0x15 64#define AB8500_OTP_EMUL 0x15
65 65
66#define AB8500_DEBUG_FIELD_LAST 0x16
67
66/* 68/*
67 * Interrupts 69 * Interrupts
68 * Values used to index into array ab8500_irq_regoffset[] defined in 70 * Values used to index into array ab8500_irq_regoffset[] defined in
diff --git a/include/linux/mfd/ac100.h b/include/linux/mfd/ac100.h
new file mode 100644
index 000000000000..3c148f196b9f
--- /dev/null
+++ b/include/linux/mfd/ac100.h
@@ -0,0 +1,178 @@
1/*
2 * Functions and registers to access AC100 codec / RTC combo IC.
3 *
4 * Copyright (C) 2016 Chen-Yu Tsai
5 *
6 * Chen-Yu Tsai <wens@csie.org>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#ifndef __LINUX_MFD_AC100_H
14#define __LINUX_MFD_AC100_H
15
16#include <linux/regmap.h>
17
18struct ac100_dev {
19 struct device *dev;
20 struct regmap *regmap;
21};
22
23/* Audio codec related registers */
24#define AC100_CHIP_AUDIO_RST 0x00
25#define AC100_PLL_CTRL1 0x01
26#define AC100_PLL_CTRL2 0x02
27#define AC100_SYSCLK_CTRL 0x03
28#define AC100_MOD_CLK_ENA 0x04
29#define AC100_MOD_RST_CTRL 0x05
30#define AC100_I2S_SR_CTRL 0x06
31
32/* I2S1 interface */
33#define AC100_I2S1_CLK_CTRL 0x10
34#define AC100_I2S1_SND_OUT_CTRL 0x11
35#define AC100_I2S1_SND_IN_CTRL 0x12
36#define AC100_I2S1_MXR_SRC 0x13
37#define AC100_I2S1_VOL_CTRL1 0x14
38#define AC100_I2S1_VOL_CTRL2 0x15
39#define AC100_I2S1_VOL_CTRL3 0x16
40#define AC100_I2S1_VOL_CTRL4 0x17
41#define AC100_I2S1_MXR_GAIN 0x18
42
43/* I2S2 interface */
44#define AC100_I2S2_CLK_CTRL 0x20
45#define AC100_I2S2_SND_OUT_CTRL 0x21
46#define AC100_I2S2_SND_IN_CTRL 0x22
47#define AC100_I2S2_MXR_SRC 0x23
48#define AC100_I2S2_VOL_CTRL1 0x24
49#define AC100_I2S2_VOL_CTRL2 0x25
50#define AC100_I2S2_VOL_CTRL3 0x26
51#define AC100_I2S2_VOL_CTRL4 0x27
52#define AC100_I2S2_MXR_GAIN 0x28
53
54/* I2S3 interface */
55#define AC100_I2S3_CLK_CTRL 0x30
56#define AC100_I2S3_SND_OUT_CTRL 0x31
57#define AC100_I2S3_SND_IN_CTRL 0x32
58#define AC100_I2S3_SIG_PATH_CTRL 0x33
59
60/* ADC digital controls */
61#define AC100_ADC_DIG_CTRL 0x40
62#define AC100_ADC_VOL_CTRL 0x41
63
64/* HMIC plug sensing / key detection */
65#define AC100_HMIC_CTRL1 0x44
66#define AC100_HMIC_CTRL2 0x45
67#define AC100_HMIC_STATUS 0x46
68
69/* DAC digital controls */
70#define AC100_DAC_DIG_CTRL 0x48
71#define AC100_DAC_VOL_CTRL 0x49
72#define AC100_DAC_MXR_SRC 0x4c
73#define AC100_DAC_MXR_GAIN 0x4d
74
75/* Analog controls */
76#define AC100_ADC_APC_CTRL 0x50
77#define AC100_ADC_SRC 0x51
78#define AC100_ADC_SRC_BST_CTRL 0x52
79#define AC100_OUT_MXR_DAC_A_CTRL 0x53
80#define AC100_OUT_MXR_SRC 0x54
81#define AC100_OUT_MXR_SRC_BST 0x55
82#define AC100_HPOUT_CTRL 0x56
83#define AC100_ERPOUT_CTRL 0x57
84#define AC100_SPKOUT_CTRL 0x58
85#define AC100_LINEOUT_CTRL 0x59
86
87/* ADC digital audio processing (high pass filter & auto gain control */
88#define AC100_ADC_DAP_L_STA 0x80
89#define AC100_ADC_DAP_R_STA 0x81
90#define AC100_ADC_DAP_L_CTRL 0x82
91#define AC100_ADC_DAP_R_CTRL 0x83
92#define AC100_ADC_DAP_L_T_L 0x84 /* Left Target Level */
93#define AC100_ADC_DAP_R_T_L 0x85 /* Right Target Level */
94#define AC100_ADC_DAP_L_H_A_C 0x86 /* Left High Avg. Coef */
95#define AC100_ADC_DAP_L_L_A_C 0x87 /* Left Low Avg. Coef */
96#define AC100_ADC_DAP_R_H_A_C 0x88 /* Right High Avg. Coef */
97#define AC100_ADC_DAP_R_L_A_C 0x89 /* Right Low Avg. Coef */
98#define AC100_ADC_DAP_L_D_T 0x8a /* Left Decay Time */
99#define AC100_ADC_DAP_L_A_T 0x8b /* Left Attack Time */
100#define AC100_ADC_DAP_R_D_T 0x8c /* Right Decay Time */
101#define AC100_ADC_DAP_R_A_T 0x8d /* Right Attack Time */
102#define AC100_ADC_DAP_N_TH 0x8e /* Noise Threshold */
103#define AC100_ADC_DAP_L_H_N_A_C 0x8f /* Left High Noise Avg. Coef */
104#define AC100_ADC_DAP_L_L_N_A_C 0x90 /* Left Low Noise Avg. Coef */
105#define AC100_ADC_DAP_R_H_N_A_C 0x91 /* Right High Noise Avg. Coef */
106#define AC100_ADC_DAP_R_L_N_A_C 0x92 /* Right Low Noise Avg. Coef */
107#define AC100_ADC_DAP_H_HPF_C 0x93 /* High High-Pass-Filter Coef */
108#define AC100_ADC_DAP_L_HPF_C 0x94 /* Low High-Pass-Filter Coef */
109#define AC100_ADC_DAP_OPT 0x95 /* AGC Optimum */
110
111/* DAC digital audio processing (high pass filter & dynamic range control) */
112#define AC100_DAC_DAP_CTRL 0xa0
113#define AC100_DAC_DAP_H_HPF_C 0xa1 /* High High-Pass-Filter Coef */
114#define AC100_DAC_DAP_L_HPF_C 0xa2 /* Low High-Pass-Filter Coef */
115#define AC100_DAC_DAP_L_H_E_A_C 0xa3 /* Left High Energy Avg Coef */
116#define AC100_DAC_DAP_L_L_E_A_C 0xa4 /* Left Low Energy Avg Coef */
117#define AC100_DAC_DAP_R_H_E_A_C 0xa5 /* Right High Energy Avg Coef */
118#define AC100_DAC_DAP_R_L_E_A_C 0xa6 /* Right Low Energy Avg Coef */
119#define AC100_DAC_DAP_H_G_D_T_C 0xa7 /* High Gain Delay Time Coef */
120#define AC100_DAC_DAP_L_G_D_T_C 0xa8 /* Low Gain Delay Time Coef */
121#define AC100_DAC_DAP_H_G_A_T_C 0xa9 /* High Gain Attack Time Coef */
122#define AC100_DAC_DAP_L_G_A_T_C 0xaa /* Low Gain Attack Time Coef */
123#define AC100_DAC_DAP_H_E_TH 0xab /* High Energy Threshold */
124#define AC100_DAC_DAP_L_E_TH 0xac /* Low Energy Threshold */
125#define AC100_DAC_DAP_H_G_K 0xad /* High Gain K parameter */
126#define AC100_DAC_DAP_L_G_K 0xae /* Low Gain K parameter */
127#define AC100_DAC_DAP_H_G_OFF 0xaf /* High Gain offset */
128#define AC100_DAC_DAP_L_G_OFF 0xb0 /* Low Gain offset */
129#define AC100_DAC_DAP_OPT 0xb1 /* DRC optimum */
130
131/* Digital audio processing enable */
132#define AC100_ADC_DAP_ENA 0xb4
133#define AC100_DAC_DAP_ENA 0xb5
134
135/* SRC control */
136#define AC100_SRC1_CTRL1 0xb8
137#define AC100_SRC1_CTRL2 0xb9
138#define AC100_SRC1_CTRL3 0xba
139#define AC100_SRC1_CTRL4 0xbb
140#define AC100_SRC2_CTRL1 0xbc
141#define AC100_SRC2_CTRL2 0xbd
142#define AC100_SRC2_CTRL3 0xbe
143#define AC100_SRC2_CTRL4 0xbf
144
145/* RTC clk control */
146#define AC100_CLK32K_ANALOG_CTRL 0xc0
147#define AC100_CLKOUT_CTRL1 0xc1
148#define AC100_CLKOUT_CTRL2 0xc2
149#define AC100_CLKOUT_CTRL3 0xc3
150
151/* RTC module */
152#define AC100_RTC_RST 0xc6
153#define AC100_RTC_CTRL 0xc7
154#define AC100_RTC_SEC 0xc8 /* second */
155#define AC100_RTC_MIN 0xc9 /* minute */
156#define AC100_RTC_HOU 0xca /* hour */
157#define AC100_RTC_WEE 0xcb /* weekday */
158#define AC100_RTC_DAY 0xcc /* day */
159#define AC100_RTC_MON 0xcd /* month */
160#define AC100_RTC_YEA 0xce /* year */
161#define AC100_RTC_UPD 0xcf /* update trigger */
162
163/* RTC alarm */
164#define AC100_ALM_INT_ENA 0xd0
165#define AC100_ALM_INT_STA 0xd1
166#define AC100_ALM_SEC 0xd8
167#define AC100_ALM_MIN 0xd9
168#define AC100_ALM_HOU 0xda
169#define AC100_ALM_WEE 0xdb
170#define AC100_ALM_DAY 0xdc
171#define AC100_ALM_MON 0xdd
172#define AC100_ALM_YEA 0xde
173#define AC100_ALM_UPD 0xdf
174
175/* RTC general purpose register 0 ~ 15 */
176#define AC100_RTC_GP(x) (0xe0 + (x))
177
178#endif /* __LINUX_MFD_AC100_H */
diff --git a/include/linux/mfd/arizona/core.h b/include/linux/mfd/arizona/core.h
index 58ab4c0fe761..b31b3be7f8c9 100644
--- a/include/linux/mfd/arizona/core.h
+++ b/include/linux/mfd/arizona/core.h
@@ -13,6 +13,7 @@
13#ifndef _WM_ARIZONA_CORE_H 13#ifndef _WM_ARIZONA_CORE_H
14#define _WM_ARIZONA_CORE_H 14#define _WM_ARIZONA_CORE_H
15 15
16#include <linux/clk.h>
16#include <linux/interrupt.h> 17#include <linux/interrupt.h>
17#include <linux/notifier.h> 18#include <linux/notifier.h>
18#include <linux/regmap.h> 19#include <linux/regmap.h>
@@ -21,6 +22,12 @@
21 22
22#define ARIZONA_MAX_CORE_SUPPLIES 2 23#define ARIZONA_MAX_CORE_SUPPLIES 2
23 24
25enum {
26 ARIZONA_MCLK1,
27 ARIZONA_MCLK2,
28 ARIZONA_NUM_MCLK
29};
30
24enum arizona_type { 31enum arizona_type {
25 WM5102 = 1, 32 WM5102 = 1,
26 WM5110 = 2, 33 WM5110 = 2,
@@ -139,6 +146,8 @@ struct arizona {
139 struct mutex clk_lock; 146 struct mutex clk_lock;
140 int clk32k_ref; 147 int clk32k_ref;
141 148
149 struct clk *mclk[ARIZONA_NUM_MCLK];
150
142 bool ctrlif_error; 151 bool ctrlif_error;
143 152
144 struct snd_soc_dapm_context *dapm; 153 struct snd_soc_dapm_context *dapm;
@@ -182,7 +191,4 @@ int cs47l24_patch(struct arizona *arizona);
182int wm8997_patch(struct arizona *arizona); 191int wm8997_patch(struct arizona *arizona);
183int wm8998_patch(struct arizona *arizona); 192int wm8998_patch(struct arizona *arizona);
184 193
185extern int arizona_of_get_named_gpio(struct arizona *arizona, const char *prop,
186 bool mandatory);
187
188#endif 194#endif
diff --git a/include/linux/mfd/axp20x.h b/include/linux/mfd/axp20x.h
index 0be4982f08fe..fec597fb34cb 100644
--- a/include/linux/mfd/axp20x.h
+++ b/include/linux/mfd/axp20x.h
@@ -20,6 +20,7 @@ enum {
20 AXP221_ID, 20 AXP221_ID,
21 AXP223_ID, 21 AXP223_ID,
22 AXP288_ID, 22 AXP288_ID,
23 AXP806_ID,
23 AXP809_ID, 24 AXP809_ID,
24 NR_AXP20X_VARIANTS, 25 NR_AXP20X_VARIANTS,
25}; 26};
@@ -91,6 +92,30 @@ enum {
91#define AXP22X_ALDO3_V_OUT 0x2a 92#define AXP22X_ALDO3_V_OUT 0x2a
92#define AXP22X_CHRG_CTRL3 0x35 93#define AXP22X_CHRG_CTRL3 0x35
93 94
95#define AXP806_STARTUP_SRC 0x00
96#define AXP806_CHIP_ID 0x03
97#define AXP806_PWR_OUT_CTRL1 0x10
98#define AXP806_PWR_OUT_CTRL2 0x11
99#define AXP806_DCDCA_V_CTRL 0x12
100#define AXP806_DCDCB_V_CTRL 0x13
101#define AXP806_DCDCC_V_CTRL 0x14
102#define AXP806_DCDCD_V_CTRL 0x15
103#define AXP806_DCDCE_V_CTRL 0x16
104#define AXP806_ALDO1_V_CTRL 0x17
105#define AXP806_ALDO2_V_CTRL 0x18
106#define AXP806_ALDO3_V_CTRL 0x19
107#define AXP806_DCDC_MODE_CTRL1 0x1a
108#define AXP806_DCDC_MODE_CTRL2 0x1b
109#define AXP806_DCDC_FREQ_CTRL 0x1c
110#define AXP806_BLDO1_V_CTRL 0x20
111#define AXP806_BLDO2_V_CTRL 0x21
112#define AXP806_BLDO3_V_CTRL 0x22
113#define AXP806_BLDO4_V_CTRL 0x23
114#define AXP806_CLDO1_V_CTRL 0x24
115#define AXP806_CLDO2_V_CTRL 0x25
116#define AXP806_CLDO3_V_CTRL 0x26
117#define AXP806_VREF_TEMP_WARN_L 0xf3
118
94/* Interrupt */ 119/* Interrupt */
95#define AXP152_IRQ1_EN 0x40 120#define AXP152_IRQ1_EN 0x40
96#define AXP152_IRQ2_EN 0x41 121#define AXP152_IRQ2_EN 0x41
@@ -266,6 +291,26 @@ enum {
266}; 291};
267 292
268enum { 293enum {
294 AXP806_DCDCA = 0,
295 AXP806_DCDCB,
296 AXP806_DCDCC,
297 AXP806_DCDCD,
298 AXP806_DCDCE,
299 AXP806_ALDO1,
300 AXP806_ALDO2,
301 AXP806_ALDO3,
302 AXP806_BLDO1,
303 AXP806_BLDO2,
304 AXP806_BLDO3,
305 AXP806_BLDO4,
306 AXP806_CLDO1,
307 AXP806_CLDO2,
308 AXP806_CLDO3,
309 AXP806_SW,
310 AXP806_REG_ID_MAX,
311};
312
313enum {
269 AXP809_DCDC1 = 0, 314 AXP809_DCDC1 = 0,
270 AXP809_DCDC2, 315 AXP809_DCDC2,
271 AXP809_DCDC3, 316 AXP809_DCDC3,
@@ -414,6 +459,21 @@ enum axp288_irqs {
414 AXP288_IRQ_BC_USB_CHNG, 459 AXP288_IRQ_BC_USB_CHNG,
415}; 460};
416 461
462enum axp806_irqs {
463 AXP806_IRQ_DIE_TEMP_HIGH_LV1,
464 AXP806_IRQ_DIE_TEMP_HIGH_LV2,
465 AXP806_IRQ_DCDCA_V_LOW,
466 AXP806_IRQ_DCDCB_V_LOW,
467 AXP806_IRQ_DCDCC_V_LOW,
468 AXP806_IRQ_DCDCD_V_LOW,
469 AXP806_IRQ_DCDCE_V_LOW,
470 AXP806_IRQ_PWROK_LONG,
471 AXP806_IRQ_PWROK_SHORT,
472 AXP806_IRQ_WAKEUP,
473 AXP806_IRQ_PWROK_FALL,
474 AXP806_IRQ_PWROK_RISE,
475};
476
417enum axp809_irqs { 477enum axp809_irqs {
418 AXP809_IRQ_ACIN_OVER_V = 1, 478 AXP809_IRQ_ACIN_OVER_V = 1,
419 AXP809_IRQ_ACIN_PLUGIN, 479 AXP809_IRQ_ACIN_PLUGIN,
diff --git a/include/linux/mfd/cros_ec.h b/include/linux/mfd/cros_ec.h
index d641a18abacb..76f7ef4d3a0d 100644
--- a/include/linux/mfd/cros_ec.h
+++ b/include/linux/mfd/cros_ec.h
@@ -109,6 +109,10 @@ struct cros_ec_command {
109 * should check msg.result for the EC's result code. 109 * should check msg.result for the EC's result code.
110 * @pkt_xfer: send packet to EC and get response 110 * @pkt_xfer: send packet to EC and get response
111 * @lock: one transaction at a time 111 * @lock: one transaction at a time
112 * @mkbp_event_supported: true if this EC supports the MKBP event protocol.
113 * @event_notifier: interrupt event notifier for transport devices.
114 * @event_data: raw payload transferred with the MKBP event.
115 * @event_size: size in bytes of the event data.
112 */ 116 */
113struct cros_ec_device { 117struct cros_ec_device {
114 118
@@ -137,6 +141,11 @@ struct cros_ec_device {
137 int (*pkt_xfer)(struct cros_ec_device *ec, 141 int (*pkt_xfer)(struct cros_ec_device *ec,
138 struct cros_ec_command *msg); 142 struct cros_ec_command *msg);
139 struct mutex lock; 143 struct mutex lock;
144 bool mkbp_event_supported;
145 struct blocking_notifier_head event_notifier;
146
147 struct ec_response_get_next_event event_data;
148 int event_size;
140}; 149};
141 150
142/* struct cros_ec_platform - ChromeOS EC platform information 151/* struct cros_ec_platform - ChromeOS EC platform information
@@ -269,6 +278,15 @@ int cros_ec_register(struct cros_ec_device *ec_dev);
269 */ 278 */
270int cros_ec_query_all(struct cros_ec_device *ec_dev); 279int cros_ec_query_all(struct cros_ec_device *ec_dev);
271 280
281/**
282 * cros_ec_get_next_event - Fetch next event from the ChromeOS EC
283 *
284 * @ec_dev: Device to fetch event from
285 *
286 * Returns: 0 on success, Linux error number on failure
287 */
288int cros_ec_get_next_event(struct cros_ec_device *ec_dev);
289
272/* sysfs stuff */ 290/* sysfs stuff */
273extern struct attribute_group cros_ec_attr_group; 291extern struct attribute_group cros_ec_attr_group;
274extern struct attribute_group cros_ec_lightbar_attr_group; 292extern struct attribute_group cros_ec_lightbar_attr_group;
diff --git a/include/linux/mfd/cros_ec_commands.h b/include/linux/mfd/cros_ec_commands.h
index 7e7a8d4b4551..76728ff37d01 100644
--- a/include/linux/mfd/cros_ec_commands.h
+++ b/include/linux/mfd/cros_ec_commands.h
@@ -1793,6 +1793,40 @@ struct ec_result_keyscan_seq_ctrl {
1793 }; 1793 };
1794} __packed; 1794} __packed;
1795 1795
1796/*
1797 * Command for retrieving the next pending MKBP event from the EC device
1798 *
1799 * The device replies with UNAVAILABLE if there aren't any pending events.
1800 */
1801#define EC_CMD_GET_NEXT_EVENT 0x67
1802
1803enum ec_mkbp_event {
1804 /* Keyboard matrix changed. The event data is the new matrix state. */
1805 EC_MKBP_EVENT_KEY_MATRIX = 0,
1806
1807 /* New host event. The event data is 4 bytes of host event flags. */
1808 EC_MKBP_EVENT_HOST_EVENT = 1,
1809
1810 /* New Sensor FIFO data. The event data is fifo_info structure. */
1811 EC_MKBP_EVENT_SENSOR_FIFO = 2,
1812
1813 /* Number of MKBP events */
1814 EC_MKBP_EVENT_COUNT,
1815};
1816
1817union ec_response_get_next_data {
1818 uint8_t key_matrix[13];
1819
1820 /* Unaligned */
1821 uint32_t host_event;
1822} __packed;
1823
1824struct ec_response_get_next_event {
1825 uint8_t event_type;
1826 /* Followed by event data if any */
1827 union ec_response_get_next_data data;
1828} __packed;
1829
1796/*****************************************************************************/ 1830/*****************************************************************************/
1797/* Temperature sensor commands */ 1831/* Temperature sensor commands */
1798 1832
diff --git a/include/linux/mfd/da9063/core.h b/include/linux/mfd/da9063/core.h
index 621af82123c6..f3ae65db4c86 100644
--- a/include/linux/mfd/da9063/core.h
+++ b/include/linux/mfd/da9063/core.h
@@ -3,8 +3,8 @@
3 * 3 *
4 * Copyright 2012 Dialog Semiconductor Ltd. 4 * Copyright 2012 Dialog Semiconductor Ltd.
5 * 5 *
6 * Author: Michal Hajduk <michal.hajduk@diasemi.com> 6 * Author: Michal Hajduk, Dialog Semiconductor
7 * Krystian Garbaciak <krystian.garbaciak@diasemi.com> 7 * Author: Krystian Garbaciak, Dialog Semiconductor
8 * 8 *
9 * This program is free software; you can redistribute it and/or modify it 9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the 10 * under the terms of the GNU General Public License as published by the
diff --git a/include/linux/mfd/da9063/pdata.h b/include/linux/mfd/da9063/pdata.h
index 612383bd80ae..8a125701ef7b 100644
--- a/include/linux/mfd/da9063/pdata.h
+++ b/include/linux/mfd/da9063/pdata.h
@@ -3,8 +3,8 @@
3 * 3 *
4 * Copyright 2012 Dialog Semiconductor Ltd. 4 * Copyright 2012 Dialog Semiconductor Ltd.
5 * 5 *
6 * Author: Michal Hajduk <michal.hajduk@diasemi.com> 6 * Author: Michal Hajduk, Dialog Semiconductor
7 * Author: Krystian Garbaciak <krystian.garbaciak@diasemi.com> 7 * Author: Krystian Garbaciak, Dialog Semiconductor
8 * 8 *
9 * This program is free software; you can redistribute it and/or modify it 9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the 10 * under the terms of the GNU General Public License as published by the
diff --git a/include/linux/mfd/da9063/registers.h b/include/linux/mfd/da9063/registers.h
index 2e0ba6d5fbc3..5d42859cb441 100644
--- a/include/linux/mfd/da9063/registers.h
+++ b/include/linux/mfd/da9063/registers.h
@@ -3,8 +3,8 @@
3 * 3 *
4 * Copyright 2012 Dialog Semiconductor Ltd. 4 * Copyright 2012 Dialog Semiconductor Ltd.
5 * 5 *
6 * Author: Michal Hajduk <michal.hajduk@diasemi.com> 6 * Author: Michal Hajduk, Dialog Semiconductor
7 * Krystian Garbaciak <krystian.garbaciak@diasemi.com> 7 * Author: Krystian Garbaciak, Dialog Semiconductor
8 * 8 *
9 * This program is free software; you can redistribute it and/or modify it 9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the 10 * under the terms of the GNU General Public License as published by the
diff --git a/include/linux/mfd/db8500-prcmu.h b/include/linux/mfd/db8500-prcmu.h
index 0bd69446bb05..7ba67b55b312 100644
--- a/include/linux/mfd/db8500-prcmu.h
+++ b/include/linux/mfd/db8500-prcmu.h
@@ -538,7 +538,6 @@ int db8500_prcmu_get_arm_opp(void);
538int db8500_prcmu_set_ape_opp(u8 opp); 538int db8500_prcmu_set_ape_opp(u8 opp);
539int db8500_prcmu_get_ape_opp(void); 539int db8500_prcmu_get_ape_opp(void);
540int db8500_prcmu_request_ape_opp_100_voltage(bool enable); 540int db8500_prcmu_request_ape_opp_100_voltage(bool enable);
541int db8500_prcmu_set_ddr_opp(u8 opp);
542int db8500_prcmu_get_ddr_opp(void); 541int db8500_prcmu_get_ddr_opp(void);
543 542
544u32 db8500_prcmu_read(unsigned int reg); 543u32 db8500_prcmu_read(unsigned int reg);
@@ -594,11 +593,6 @@ static inline int prcmu_release_usb_wakeup_state(void)
594 return 0; 593 return 0;
595} 594}
596 595
597static inline int db8500_prcmu_set_ddr_opp(u8 opp)
598{
599 return 0;
600}
601
602static inline int db8500_prcmu_get_ddr_opp(void) 596static inline int db8500_prcmu_get_ddr_opp(void)
603{ 597{
604 return DDR_100_OPP; 598 return DDR_100_OPP;
diff --git a/include/linux/mfd/dbx500-prcmu.h b/include/linux/mfd/dbx500-prcmu.h
index 5d374601404c..2e2c6a63a065 100644
--- a/include/linux/mfd/dbx500-prcmu.h
+++ b/include/linux/mfd/dbx500-prcmu.h
@@ -269,10 +269,6 @@ unsigned long prcmu_clock_rate(u8 clock);
269long prcmu_round_clock_rate(u8 clock, unsigned long rate); 269long prcmu_round_clock_rate(u8 clock, unsigned long rate);
270int prcmu_set_clock_rate(u8 clock, unsigned long rate); 270int prcmu_set_clock_rate(u8 clock, unsigned long rate);
271 271
272static inline int prcmu_set_ddr_opp(u8 opp)
273{
274 return db8500_prcmu_set_ddr_opp(opp);
275}
276static inline int prcmu_get_ddr_opp(void) 272static inline int prcmu_get_ddr_opp(void)
277{ 273{
278 return db8500_prcmu_get_ddr_opp(); 274 return db8500_prcmu_get_ddr_opp();
@@ -489,11 +485,6 @@ static inline int prcmu_get_arm_opp(void)
489 return ARM_100_OPP; 485 return ARM_100_OPP;
490} 486}
491 487
492static inline int prcmu_set_ddr_opp(u8 opp)
493{
494 return 0;
495}
496
497static inline int prcmu_get_ddr_opp(void) 488static inline int prcmu_get_ddr_opp(void)
498{ 489{
499 return DDR_100_OPP; 490 return DDR_100_OPP;
diff --git a/include/linux/mfd/lp873x.h b/include/linux/mfd/lp873x.h
index 83b1bd7588be..edbec8350a49 100644
--- a/include/linux/mfd/lp873x.h
+++ b/include/linux/mfd/lp873x.h
@@ -263,7 +263,6 @@ enum lp873x_regulator_id {
263struct lp873x { 263struct lp873x {
264 struct device *dev; 264 struct device *dev;
265 u8 rev; 265 u8 rev;
266 struct mutex lock; /* lock guarding the data structure */
267 struct regmap *regmap; 266 struct regmap *regmap;
268}; 267};
269#endif /* __LINUX_MFD_LP873X_H */ 268#endif /* __LINUX_MFD_LP873X_H */
diff --git a/include/linux/mfd/max14577-private.h b/include/linux/mfd/max14577-private.h
index f01c1fae4d84..df75234f979d 100644
--- a/include/linux/mfd/max14577-private.h
+++ b/include/linux/mfd/max14577-private.h
@@ -3,7 +3,7 @@
3 * 3 *
4 * Copyright (C) 2014 Samsung Electrnoics 4 * Copyright (C) 2014 Samsung Electrnoics
5 * Chanwoo Choi <cw00.choi@samsung.com> 5 * Chanwoo Choi <cw00.choi@samsung.com>
6 * Krzysztof Kozlowski <k.kozlowski@samsung.com> 6 * Krzysztof Kozlowski <krzk@kernel.org>
7 * 7 *
8 * This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by 9 * it under the terms of the GNU General Public License as published by
diff --git a/include/linux/mfd/max14577.h b/include/linux/mfd/max14577.h
index ccfaf952c31b..d81b52bb8bee 100644
--- a/include/linux/mfd/max14577.h
+++ b/include/linux/mfd/max14577.h
@@ -3,7 +3,7 @@
3 * 3 *
4 * Copyright (C) 2014 Samsung Electrnoics 4 * Copyright (C) 2014 Samsung Electrnoics
5 * Chanwoo Choi <cw00.choi@samsung.com> 5 * Chanwoo Choi <cw00.choi@samsung.com>
6 * Krzysztof Kozlowski <k.kozlowski@samsung.com> 6 * Krzysztof Kozlowski <krzk@kernel.org>
7 * 7 *
8 * This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by 9 * it under the terms of the GNU General Public License as published by
diff --git a/include/linux/mfd/rk808.h b/include/linux/mfd/rk808.h
index 441b6ee72691..6d435a3c06bc 100644
--- a/include/linux/mfd/rk808.h
+++ b/include/linux/mfd/rk808.h
@@ -1,11 +1,15 @@
1/* 1/*
2 * rk808.h for Rockchip RK808 2 * Register definitions for Rockchip's RK808/RK818 PMIC
3 * 3 *
4 * Copyright (c) 2014, Fuzhou Rockchip Electronics Co., Ltd 4 * Copyright (c) 2014, Fuzhou Rockchip Electronics Co., Ltd
5 * 5 *
6 * Author: Chris Zhong <zyw@rock-chips.com> 6 * Author: Chris Zhong <zyw@rock-chips.com>
7 * Author: Zhang Qing <zhangqing@rock-chips.com> 7 * Author: Zhang Qing <zhangqing@rock-chips.com>
8 * 8 *
9 * Copyright (C) 2016 PHYTEC Messtechnik GmbH
10 *
11 * Author: Wadim Egorov <w.egorov@phytec.de>
12 *
9 * This program is free software; you can redistribute it and/or modify it 13 * This program is free software; you can redistribute it and/or modify it
10 * under the terms and conditions of the GNU General Public License, 14 * under the terms and conditions of the GNU General Public License,
11 * version 2, as published by the Free Software Foundation. 15 * version 2, as published by the Free Software Foundation.
@@ -16,8 +20,8 @@
16 * more details. 20 * more details.
17 */ 21 */
18 22
19#ifndef __LINUX_REGULATOR_rk808_H 23#ifndef __LINUX_REGULATOR_RK808_H
20#define __LINUX_REGULATOR_rk808_H 24#define __LINUX_REGULATOR_RK808_H
21 25
22#include <linux/regulator/machine.h> 26#include <linux/regulator/machine.h>
23#include <linux/regmap.h> 27#include <linux/regmap.h>
@@ -28,7 +32,7 @@
28 32
29#define RK808_DCDC1 0 /* (0+RK808_START) */ 33#define RK808_DCDC1 0 /* (0+RK808_START) */
30#define RK808_LDO1 4 /* (4+RK808_START) */ 34#define RK808_LDO1 4 /* (4+RK808_START) */
31#define RK808_NUM_REGULATORS 14 35#define RK808_NUM_REGULATORS 14
32 36
33enum rk808_reg { 37enum rk808_reg {
34 RK808_ID_DCDC1, 38 RK808_ID_DCDC1,
@@ -65,6 +69,8 @@ enum rk808_reg {
65#define RK808_RTC_INT_REG 0x12 69#define RK808_RTC_INT_REG 0x12
66#define RK808_RTC_COMP_LSB_REG 0x13 70#define RK808_RTC_COMP_LSB_REG 0x13
67#define RK808_RTC_COMP_MSB_REG 0x14 71#define RK808_RTC_COMP_MSB_REG 0x14
72#define RK808_ID_MSB 0x17
73#define RK808_ID_LSB 0x18
68#define RK808_CLK32OUT_REG 0x20 74#define RK808_CLK32OUT_REG 0x20
69#define RK808_VB_MON_REG 0x21 75#define RK808_VB_MON_REG 0x21
70#define RK808_THERMAL_REG 0x22 76#define RK808_THERMAL_REG 0x22
@@ -115,7 +121,92 @@ enum rk808_reg {
115#define RK808_INT_STS_MSK_REG2 0x4f 121#define RK808_INT_STS_MSK_REG2 0x4f
116#define RK808_IO_POL_REG 0x50 122#define RK808_IO_POL_REG 0x50
117 123
118/* IRQ Definitions */ 124/* RK818 */
125#define RK818_DCDC1 0
126#define RK818_LDO1 4
127#define RK818_NUM_REGULATORS 17
128
129enum rk818_reg {
130 RK818_ID_DCDC1,
131 RK818_ID_DCDC2,
132 RK818_ID_DCDC3,
133 RK818_ID_DCDC4,
134 RK818_ID_BOOST,
135 RK818_ID_LDO1,
136 RK818_ID_LDO2,
137 RK818_ID_LDO3,
138 RK818_ID_LDO4,
139 RK818_ID_LDO5,
140 RK818_ID_LDO6,
141 RK818_ID_LDO7,
142 RK818_ID_LDO8,
143 RK818_ID_LDO9,
144 RK818_ID_SWITCH,
145 RK818_ID_HDMI_SWITCH,
146 RK818_ID_OTG_SWITCH,
147};
148
149#define RK818_DCDC_EN_REG 0x23
150#define RK818_LDO_EN_REG 0x24
151#define RK818_SLEEP_SET_OFF_REG1 0x25
152#define RK818_SLEEP_SET_OFF_REG2 0x26
153#define RK818_DCDC_UV_STS_REG 0x27
154#define RK818_DCDC_UV_ACT_REG 0x28
155#define RK818_LDO_UV_STS_REG 0x29
156#define RK818_LDO_UV_ACT_REG 0x2a
157#define RK818_DCDC_PG_REG 0x2b
158#define RK818_LDO_PG_REG 0x2c
159#define RK818_VOUT_MON_TDB_REG 0x2d
160#define RK818_BUCK1_CONFIG_REG 0x2e
161#define RK818_BUCK1_ON_VSEL_REG 0x2f
162#define RK818_BUCK1_SLP_VSEL_REG 0x30
163#define RK818_BUCK2_CONFIG_REG 0x32
164#define RK818_BUCK2_ON_VSEL_REG 0x33
165#define RK818_BUCK2_SLP_VSEL_REG 0x34
166#define RK818_BUCK3_CONFIG_REG 0x36
167#define RK818_BUCK4_CONFIG_REG 0x37
168#define RK818_BUCK4_ON_VSEL_REG 0x38
169#define RK818_BUCK4_SLP_VSEL_REG 0x39
170#define RK818_BOOST_CONFIG_REG 0x3a
171#define RK818_LDO1_ON_VSEL_REG 0x3b
172#define RK818_LDO1_SLP_VSEL_REG 0x3c
173#define RK818_LDO2_ON_VSEL_REG 0x3d
174#define RK818_LDO2_SLP_VSEL_REG 0x3e
175#define RK818_LDO3_ON_VSEL_REG 0x3f
176#define RK818_LDO3_SLP_VSEL_REG 0x40
177#define RK818_LDO4_ON_VSEL_REG 0x41
178#define RK818_LDO4_SLP_VSEL_REG 0x42
179#define RK818_LDO5_ON_VSEL_REG 0x43
180#define RK818_LDO5_SLP_VSEL_REG 0x44
181#define RK818_LDO6_ON_VSEL_REG 0x45
182#define RK818_LDO6_SLP_VSEL_REG 0x46
183#define RK818_LDO7_ON_VSEL_REG 0x47
184#define RK818_LDO7_SLP_VSEL_REG 0x48
185#define RK818_LDO8_ON_VSEL_REG 0x49
186#define RK818_LDO8_SLP_VSEL_REG 0x4a
187#define RK818_BOOST_LDO9_ON_VSEL_REG 0x54
188#define RK818_BOOST_LDO9_SLP_VSEL_REG 0x55
189#define RK818_DEVCTRL_REG 0x4b
190#define RK818_INT_STS_REG1 0X4c
191#define RK818_INT_STS_MSK_REG1 0x4d
192#define RK818_INT_STS_REG2 0x4e
193#define RK818_INT_STS_MSK_REG2 0x4f
194#define RK818_IO_POL_REG 0x50
195#define RK818_H5V_EN_REG 0x52
196#define RK818_SLEEP_SET_OFF_REG3 0x53
197#define RK818_BOOST_LDO9_ON_VSEL_REG 0x54
198#define RK818_BOOST_LDO9_SLP_VSEL_REG 0x55
199#define RK818_BOOST_CTRL_REG 0x56
200#define RK818_DCDC_ILMAX 0x90
201#define RK818_USB_CTRL_REG 0xa1
202
203#define RK818_H5V_EN BIT(0)
204#define RK818_REF_RDY_CTRL BIT(1)
205#define RK818_USB_ILIM_SEL_MASK 0xf
206#define RK818_USB_ILMIN_2000MA 0x7
207#define RK818_USB_CHG_SD_VSEL_MASK 0x70
208
209/* RK808 IRQ Definitions */
119#define RK808_IRQ_VOUT_LO 0 210#define RK808_IRQ_VOUT_LO 0
120#define RK808_IRQ_VB_LO 1 211#define RK808_IRQ_VB_LO 1
121#define RK808_IRQ_PWRON 2 212#define RK808_IRQ_PWRON 2
@@ -137,6 +228,43 @@ enum rk808_reg {
137#define RK808_IRQ_PLUG_IN_INT_MSK BIT(0) 228#define RK808_IRQ_PLUG_IN_INT_MSK BIT(0)
138#define RK808_IRQ_PLUG_OUT_INT_MSK BIT(1) 229#define RK808_IRQ_PLUG_OUT_INT_MSK BIT(1)
139 230
231/* RK818 IRQ Definitions */
232#define RK818_IRQ_VOUT_LO 0
233#define RK818_IRQ_VB_LO 1
234#define RK818_IRQ_PWRON 2
235#define RK818_IRQ_PWRON_LP 3
236#define RK818_IRQ_HOTDIE 4
237#define RK818_IRQ_RTC_ALARM 5
238#define RK818_IRQ_RTC_PERIOD 6
239#define RK818_IRQ_USB_OV 7
240#define RK818_IRQ_PLUG_IN 8
241#define RK818_IRQ_PLUG_OUT 9
242#define RK818_IRQ_CHG_OK 10
243#define RK818_IRQ_CHG_TE 11
244#define RK818_IRQ_CHG_TS1 12
245#define RK818_IRQ_TS2 13
246#define RK818_IRQ_CHG_CVTLIM 14
247#define RK818_IRQ_DISCHG_ILIM 15
248
249#define RK818_IRQ_VOUT_LO_MSK BIT(0)
250#define RK818_IRQ_VB_LO_MSK BIT(1)
251#define RK818_IRQ_PWRON_MSK BIT(2)
252#define RK818_IRQ_PWRON_LP_MSK BIT(3)
253#define RK818_IRQ_HOTDIE_MSK BIT(4)
254#define RK818_IRQ_RTC_ALARM_MSK BIT(5)
255#define RK818_IRQ_RTC_PERIOD_MSK BIT(6)
256#define RK818_IRQ_USB_OV_MSK BIT(7)
257#define RK818_IRQ_PLUG_IN_MSK BIT(0)
258#define RK818_IRQ_PLUG_OUT_MSK BIT(1)
259#define RK818_IRQ_CHG_OK_MSK BIT(2)
260#define RK818_IRQ_CHG_TE_MSK BIT(3)
261#define RK818_IRQ_CHG_TS1_MSK BIT(4)
262#define RK818_IRQ_TS2_MSK BIT(5)
263#define RK818_IRQ_CHG_CVTLIM_MSK BIT(6)
264#define RK818_IRQ_DISCHG_ILIM_MSK BIT(7)
265
266#define RK818_NUM_IRQ 16
267
140#define RK808_VBAT_LOW_2V8 0x00 268#define RK808_VBAT_LOW_2V8 0x00
141#define RK808_VBAT_LOW_2V9 0x01 269#define RK808_VBAT_LOW_2V9 0x01
142#define RK808_VBAT_LOW_3V0 0x02 270#define RK808_VBAT_LOW_3V0 0x02
@@ -191,9 +319,17 @@ enum {
191 BOOST_ILMIN_250MA, 319 BOOST_ILMIN_250MA,
192}; 320};
193 321
322enum {
323 RK808_ID = 0x0000,
324 RK818_ID = 0x8181,
325};
326
194struct rk808 { 327struct rk808 {
195 struct i2c_client *i2c; 328 struct i2c_client *i2c;
196 struct regmap_irq_chip_data *irq_data; 329 struct regmap_irq_chip_data *irq_data;
197 struct regmap *regmap; 330 struct regmap *regmap;
331 long variant;
332 const struct regmap_config *regmap_cfg;
333 const struct regmap_irq_chip *regmap_irq_chip;
198}; 334};
199#endif /* __LINUX_REGULATOR_rk808_H */ 335#endif /* __LINUX_REGULATOR_RK808_H */
diff --git a/include/linux/mfd/syscon/exynos5-pmu.h b/include/linux/mfd/syscon/exynos5-pmu.h
index 76f30f940c70..c28ff21ca4d2 100644
--- a/include/linux/mfd/syscon/exynos5-pmu.h
+++ b/include/linux/mfd/syscon/exynos5-pmu.h
@@ -43,8 +43,10 @@
43#define EXYNOS5433_MIPI_PHY2_CONTROL (0x718) 43#define EXYNOS5433_MIPI_PHY2_CONTROL (0x718)
44 44
45#define EXYNOS5_PHY_ENABLE BIT(0) 45#define EXYNOS5_PHY_ENABLE BIT(0)
46
47#define EXYNOS5_MIPI_PHY_S_RESETN BIT(1) 46#define EXYNOS5_MIPI_PHY_S_RESETN BIT(1)
48#define EXYNOS5_MIPI_PHY_M_RESETN BIT(2) 47#define EXYNOS5_MIPI_PHY_M_RESETN BIT(2)
49 48
49#define EXYNOS5433_PAD_RETENTION_AUD_OPTION (0x3028)
50#define EXYNOS5433_PAD_INITIATE_WAKEUP_FROM_LOWPWR BIT(28)
51
50#endif /* _LINUX_MFD_SYSCON_PMU_EXYNOS5_H_ */ 52#endif /* _LINUX_MFD_SYSCON_PMU_EXYNOS5_H_ */
diff --git a/include/linux/mfd/tps65217.h b/include/linux/mfd/tps65217.h
index 1c88231496d3..4ccda8969639 100644
--- a/include/linux/mfd/tps65217.h
+++ b/include/linux/mfd/tps65217.h
@@ -73,6 +73,7 @@
73#define TPS65217_PPATH_AC_CURRENT_MASK 0x0C 73#define TPS65217_PPATH_AC_CURRENT_MASK 0x0C
74#define TPS65217_PPATH_USB_CURRENT_MASK 0x03 74#define TPS65217_PPATH_USB_CURRENT_MASK 0x03
75 75
76#define TPS65217_INT_RESERVEDM BIT(7)
76#define TPS65217_INT_PBM BIT(6) 77#define TPS65217_INT_PBM BIT(6)
77#define TPS65217_INT_ACM BIT(5) 78#define TPS65217_INT_ACM BIT(5)
78#define TPS65217_INT_USBM BIT(4) 79#define TPS65217_INT_USBM BIT(4)
@@ -233,6 +234,13 @@ struct tps65217_bl_pdata {
233 int dft_brightness; 234 int dft_brightness;
234}; 235};
235 236
237enum tps65217_irq_type {
238 TPS65217_IRQ_PB,
239 TPS65217_IRQ_AC,
240 TPS65217_IRQ_USB,
241 TPS65217_NUM_IRQ
242};
243
236/** 244/**
237 * struct tps65217_board - packages regulator init data 245 * struct tps65217_board - packages regulator init data
238 * @tps65217_regulator_data: regulator initialization values 246 * @tps65217_regulator_data: regulator initialization values
@@ -258,6 +266,10 @@ struct tps65217 {
258 struct regulator_desc desc[TPS65217_NUM_REGULATOR]; 266 struct regulator_desc desc[TPS65217_NUM_REGULATOR];
259 struct regmap *regmap; 267 struct regmap *regmap;
260 u8 *strobes; 268 u8 *strobes;
269 struct irq_domain *irq_domain;
270 struct mutex irq_lock;
271 u8 irq_mask;
272 int irq;
261}; 273};
262 274
263static inline struct tps65217 *dev_to_tps65217(struct device *dev) 275static inline struct tps65217 *dev_to_tps65217(struct device *dev)
diff --git a/include/linux/mfd/twl6040.h b/include/linux/mfd/twl6040.h
index 36795a1be479..a2e88761c09f 100644
--- a/include/linux/mfd/twl6040.h
+++ b/include/linux/mfd/twl6040.h
@@ -168,7 +168,7 @@
168#define TWL6040_VIBROCDET 0x20 168#define TWL6040_VIBROCDET 0x20
169#define TWL6040_TSHUTDET 0x40 169#define TWL6040_TSHUTDET 0x40
170 170
171#define TWL6040_CELLS 3 171#define TWL6040_CELLS 4
172 172
173#define TWL6040_REV_ES1_0 0x00 173#define TWL6040_REV_ES1_0 0x00
174#define TWL6040_REV_ES1_1 0x01 /* Rev ES1.1 and ES1.2 */ 174#define TWL6040_REV_ES1_1 0x01 /* Rev ES1.1 and ES1.2 */