aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2015-06-23 20:31:27 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2015-06-23 20:31:27 -0400
commit84e9c87e6ffc519fdf91949482a65672a7314c9a (patch)
tree29775d71f1f58c41365ce597192524cf5544b340
parent7fe0bf908d4f8f7d134cab280cac64fe65997ac1 (diff)
parent1abf25a25b86dcfe28d243a5af71bd1c9d6de1ef (diff)
Merge tag 'mfd-for-linus-4.2' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd
Pull MFD updates from Lee Jones: "Changes to existing drivers: - Constify structures; throughout the subsystem - Move support to DT in; cros_ec - DT changes and documentation; cros-ec, max77693, max77686, arizona, da9063 - ACPI changes and documentation; mfd-core - Use different platform specific API in; cros_ec_*, arizona-core - Remove unused parent field from; cros_ec_i2c - Add wake-up/reset delay in; cross_ec_spi, arizona-core - Staticise structures/functions in; cros_ec - Remove redundant code; arizona-core, max77686 - Bugfix; twl4030-power - Allow compile test; aat2870, tps65910 - MAINTAINERS adaptions; samsung, syscon - Resource Management (devm_*); arizona-core - Refactor Reset code; arizona-core - Insist on at least one full boot; arizona-core - Trivial formatting; arizona-core - Add low-power-sleep; arizona-core - IRQ ONESHOT changes; twl4030-irq, mc13xxx-core, wm831x-auxadc, htc-i2cpld, wm8350-core, ab8500-debugfs, ab8500-gpadc, si476x-i2c (Re-)moved drivers: - Move protocol helpers out to drivers/platform; cros_ec New drivers/supported devices: - Add support for AXP22x into axp20x - Add support for OnKey into da9063-core - Add support for Pinctrl into mt6397-core - New STMicroelectronics LPC Watchdog driver - New STMicroelectronics LPC Real-Time Clock driver" * tag 'mfd-for-linus-4.2' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd: (59 commits) mfd: lpc_ich: Assign subdevice ids automatically mfd: si476x-i2c: Pass the IRQF_ONESHOT flag mfd: ab8500-gpadc: Pass the IRQF_ONESHOT flag mfd: ab8500-debugfs: Pass the IRQF_ONESHOT flag mfd: wm8350-core: Pass the IRQF_ONESHOT flag mfd: htc-i2cpld: Pass the IRQF_ONESHOT flag mfd: wm831x-auxadc: Pass the IRQF_ONESHOT flag mfd: mc13xxx-core: Pass the IRQF_ONESHOT flag mfd: twl4030-irq: Pass the IRQF_ONESHOT flag mfd: mt6397-core: Add GPIO sub-module support mfd: arizona: Add convience defines for micd_rate/micd_bias_starttime mfd: dt: Add bindings for DA9063 OnKey mfd: da9063: Add support for OnKey driver mfd: arizona: Fix incorrect Makefile conditionals mfd: arizona: Add stub for wm5102_patch() mfd: Check ACPI device companion before checking resources Documentation: Add WM8998/WM1814 device tree bindings mfd: arizona: Split INx_MODE into two fields mfd: wm5110: Add delay before releasing reset line mfd: arizona: Add better support for system suspend ...
-rw-r--r--Documentation/devicetree/bindings/mfd/arizona.txt13
-rw-r--r--Documentation/devicetree/bindings/mfd/axp20x.txt32
-rw-r--r--Documentation/devicetree/bindings/mfd/cros-ec.txt4
-rw-r--r--Documentation/devicetree/bindings/mfd/da9063.txt18
-rw-r--r--Documentation/devicetree/bindings/mfd/max77686.txt2
-rw-r--r--Documentation/devicetree/bindings/mfd/max77693.txt67
-rw-r--r--Documentation/devicetree/bindings/rtc/rtc-st-lpc.txt25
-rw-r--r--Documentation/devicetree/bindings/watchdog/st_lpc_wdt.txt38
-rw-r--r--MAINTAINERS17
-rw-r--r--drivers/i2c/busses/Kconfig2
-rw-r--r--drivers/i2c/busses/i2c-cros-ec-tunnel.c45
-rw-r--r--drivers/input/keyboard/Kconfig2
-rw-r--r--drivers/input/keyboard/cros_ec_keyb.c31
-rw-r--r--drivers/mfd/88pm860x-core.c2
-rw-r--r--drivers/mfd/Kconfig12
-rw-r--r--drivers/mfd/Makefile6
-rw-r--r--drivers/mfd/ab8500-core.c2
-rw-r--r--drivers/mfd/ab8500-debugfs.c2
-rw-r--r--drivers/mfd/ab8500-gpadc.c6
-rw-r--r--drivers/mfd/arizona-core.c361
-rw-r--r--drivers/mfd/arizona-irq.c2
-rw-r--r--drivers/mfd/axp20x.c100
-rw-r--r--drivers/mfd/cros_ec.c173
-rw-r--r--drivers/mfd/cros_ec_i2c.c170
-rw-r--r--drivers/mfd/cros_ec_spi.c408
-rw-r--r--drivers/mfd/da9052-irq.c4
-rw-r--r--drivers/mfd/da9055-core.c6
-rw-r--r--drivers/mfd/da9063-core.c54
-rw-r--r--drivers/mfd/da9063-irq.c4
-rw-r--r--drivers/mfd/da9150-core.c4
-rw-r--r--drivers/mfd/db8500-prcmu.c2
-rw-r--r--drivers/mfd/htc-i2cpld.c3
-rw-r--r--drivers/mfd/intel_soc_pmic_core.h2
-rw-r--r--drivers/mfd/intel_soc_pmic_crc.c2
-rw-r--r--drivers/mfd/lp8788-irq.c2
-rw-r--r--drivers/mfd/lpc_ich.c8
-rw-r--r--drivers/mfd/max8925-core.c2
-rw-r--r--drivers/mfd/max8997-irq.c2
-rw-r--r--drivers/mfd/max8998-irq.c2
-rw-r--r--drivers/mfd/mc13xxx-core.c2
-rw-r--r--drivers/mfd/mfd-core.c8
-rw-r--r--drivers/mfd/mt6397-core.c5
-rw-r--r--drivers/mfd/si476x-i2c.c3
-rw-r--r--drivers/mfd/stmpe.c2
-rw-r--r--drivers/mfd/tc3589x.c2
-rw-r--r--drivers/mfd/tps6586x.c2
-rw-r--r--drivers/mfd/twl4030-irq.c2
-rw-r--r--drivers/mfd/twl4030-power.c45
-rw-r--r--drivers/mfd/twl6030-irq.c2
-rw-r--r--drivers/mfd/wm831x-auxadc.c3
-rw-r--r--drivers/mfd/wm831x-irq.c2
-rw-r--r--drivers/mfd/wm8350-core.c3
-rw-r--r--drivers/mfd/wm8994-irq.c6
-rw-r--r--drivers/platform/chrome/Kconfig9
-rw-r--r--drivers/platform/chrome/Makefile1
-rw-r--r--drivers/platform/chrome/cros_ec_dev.c189
-rw-r--r--drivers/platform/chrome/cros_ec_dev.h7
-rw-r--r--drivers/platform/chrome/cros_ec_lightbar.c217
-rw-r--r--drivers/platform/chrome/cros_ec_lpc.c85
-rw-r--r--drivers/platform/chrome/cros_ec_proto.c382
-rw-r--r--drivers/platform/chrome/cros_ec_sysfs.c178
-rw-r--r--drivers/regulator/axp20x-regulator.c239
-rw-r--r--drivers/rtc/Kconfig11
-rw-r--r--drivers/rtc/Makefile1
-rw-r--r--drivers/rtc/rtc-st-lpc.c354
-rw-r--r--drivers/watchdog/Kconfig12
-rw-r--r--drivers/watchdog/Makefile1
-rw-r--r--drivers/watchdog/st_lpc_wdt.c344
-rw-r--r--include/dt-bindings/mfd/arizona.h14
-rw-r--r--include/dt-bindings/mfd/st-lpc.h15
-rw-r--r--include/linux/i2c/twl.h1
-rw-r--r--include/linux/mfd/arizona/core.h9
-rw-r--r--include/linux/mfd/arizona/pdata.h5
-rw-r--r--include/linux/mfd/arizona/registers.h27
-rw-r--r--include/linux/mfd/axp20x.h86
-rw-r--r--include/linux/mfd/cros_ec.h86
-rw-r--r--include/linux/mfd/cros_ec_commands.h277
-rw-r--r--include/linux/mfd/da9055/core.h2
-rw-r--r--include/linux/mfd/max77686.h5
79 files changed, 3621 insertions, 660 deletions
diff --git a/Documentation/devicetree/bindings/mfd/arizona.txt b/Documentation/devicetree/bindings/mfd/arizona.txt
index 7665aa95979f..64fa3b2de6cd 100644
--- a/Documentation/devicetree/bindings/mfd/arizona.txt
+++ b/Documentation/devicetree/bindings/mfd/arizona.txt
@@ -10,6 +10,9 @@ Required properties:
10 "wlf,wm5110" 10 "wlf,wm5110"
11 "wlf,wm8280" 11 "wlf,wm8280"
12 "wlf,wm8997" 12 "wlf,wm8997"
13 "wlf,wm8998"
14 "wlf,wm1814"
15
13 - reg : I2C slave address when connected using I2C, chip select number when 16 - reg : I2C slave address when connected using I2C, chip select number when
14 using SPI. 17 using SPI.
15 18
@@ -31,10 +34,10 @@ Required properties:
31 as covered in Documentation/devicetree/bindings/regulator/regulator.txt 34 as covered in Documentation/devicetree/bindings/regulator/regulator.txt
32 35
33 - DBVDD2-supply, DBVDD3-supply : Additional databus power supplies (wm5102, 36 - DBVDD2-supply, DBVDD3-supply : Additional databus power supplies (wm5102,
34 wm5110, wm8280) 37 wm5110, wm8280, wm8998, wm1814)
35 38
36 - SPKVDDL-supply, SPKVDDR-supply : Speaker driver power supplies (wm5102, 39 - SPKVDDL-supply, SPKVDDR-supply : Speaker driver power supplies (wm5102,
37 wm5110, wm8280) 40 wm5110, wm8280, wm8998, wm1814)
38 41
39 - SPKVDD-supply : Speaker driver power supply (wm8997) 42 - SPKVDD-supply : Speaker driver power supply (wm8997)
40 43
@@ -53,8 +56,10 @@ Optional properties:
53 of input signals. Valid values are 0 (Differential), 1 (Single-ended) and 56 of input signals. Valid values are 0 (Differential), 1 (Single-ended) and
54 2 (Digital Microphone). If absent, INn_MODE registers set to 0 by default. 57 2 (Digital Microphone). If absent, INn_MODE registers set to 0 by default.
55 If present, values must be specified less than or equal to the number of 58 If present, values must be specified less than or equal to the number of
56 input singals. If values less than the number of input signals, elements 59 input signals. If values less than the number of input signals, elements
57 that has not been specifed are set to 0 by default. 60 that have not been specified are set to 0 by default. Entries are:
61 <IN1, IN2, IN3, IN4> (wm5102, wm5110, wm8280, wm8997)
62 <IN1A, IN2A, IN1B, IN2B> (wm8998, wm1814)
58 63
59 - wlf,dmic-ref : DMIC reference voltage source for each input, can be 64 - wlf,dmic-ref : DMIC reference voltage source for each input, can be
60 selected from either MICVDD or one of the MICBIAS's, defines 65 selected from either MICVDD or one of the MICBIAS's, defines
diff --git a/Documentation/devicetree/bindings/mfd/axp20x.txt b/Documentation/devicetree/bindings/mfd/axp20x.txt
index 98685f291a72..753f14f46e85 100644
--- a/Documentation/devicetree/bindings/mfd/axp20x.txt
+++ b/Documentation/devicetree/bindings/mfd/axp20x.txt
@@ -1,15 +1,16 @@
1AXP202/AXP209 device tree bindings 1AXP family PMIC device tree bindings
2 2
3The axp20x family current members : 3The axp20x family current members :
4axp202 (X-Powers) 4axp202 (X-Powers)
5axp209 (X-Powers) 5axp209 (X-Powers)
6axp221 (X-Powers)
6 7
7Required properties: 8Required properties:
8- compatible: "x-powers,axp202" or "x-powers,axp209" 9- compatible: "x-powers,axp202", "x-powers,axp209", "x-powers,axp221"
9- reg: The I2C slave address for the AXP chip 10- reg: The I2C slave address for the AXP chip
10- interrupt-parent: The parent interrupt controller 11- interrupt-parent: The parent interrupt controller
11- interrupts: SoC NMI / GPIO interrupt connected to the PMIC's IRQ pin 12- interrupts: SoC NMI / GPIO interrupt connected to the PMIC's IRQ pin
12- interrupt-controller: axp20x has its own internal IRQs 13- interrupt-controller: The PMIC has its own internal IRQs
13- #interrupt-cells: Should be set to 1 14- #interrupt-cells: Should be set to 1
14 15
15Optional properties: 16Optional properties:
@@ -48,6 +49,31 @@ LDO3 : LDO : ldo3in-supply
48LDO4 : LDO : ldo24in-supply : shared supply 49LDO4 : LDO : ldo24in-supply : shared supply
49LDO5 : LDO : ldo5in-supply 50LDO5 : LDO : ldo5in-supply
50 51
52AXP221 regulators, type, and corresponding input supply names:
53
54Regulator Type Supply Name Notes
55--------- ---- ----------- -----
56DCDC1 : DC-DC buck : vin1-supply
57DCDC2 : DC-DC buck : vin2-supply
58DCDC3 : DC-DC buck : vin3-supply
59DCDC4 : DC-DC buck : vin4-supply
60DCDC5 : DC-DC buck : vin5-supply
61DC1SW : On/Off Switch : dcdc1-supply : DCDC1 secondary output
62DC5LDO : LDO : dcdc5-supply : input from DCDC5
63ALDO1 : LDO : aldoin-supply : shared supply
64ALDO2 : LDO : aldoin-supply : shared supply
65ALDO3 : LDO : aldoin-supply : shared supply
66DLDO1 : LDO : dldoin-supply : shared supply
67DLDO2 : LDO : dldoin-supply : shared supply
68DLDO3 : LDO : dldoin-supply : shared supply
69DLDO4 : LDO : dldoin-supply : shared supply
70ELDO1 : LDO : eldoin-supply : shared supply
71ELDO2 : LDO : eldoin-supply : shared supply
72ELDO3 : LDO : eldoin-supply : shared supply
73LDO_IO0 : LDO : ips-supply : GPIO 0
74LDO_IO1 : LDO : ips-supply : GPIO 1
75RTC_LDO : LDO : ips-supply : always on
76
51Example: 77Example:
52 78
53axp209: pmic@34 { 79axp209: pmic@34 {
diff --git a/Documentation/devicetree/bindings/mfd/cros-ec.txt b/Documentation/devicetree/bindings/mfd/cros-ec.txt
index 8009c3d87f33..1777916e9e28 100644
--- a/Documentation/devicetree/bindings/mfd/cros-ec.txt
+++ b/Documentation/devicetree/bindings/mfd/cros-ec.txt
@@ -18,6 +18,10 @@ Required properties (SPI):
18- reg: SPI chip select 18- reg: SPI chip select
19 19
20Optional properties (SPI): 20Optional properties (SPI):
21- google,cros-ec-spi-pre-delay: Some implementations of the EC need a little
22 time to wake up from sleep before they can receive SPI transfers at a high
23 clock rate. This property specifies the delay, in usecs, between the
24 assertion of the CS to the start of the first clock pulse.
21- google,cros-ec-spi-msg-delay: Some implementations of the EC require some 25- google,cros-ec-spi-msg-delay: Some implementations of the EC require some
22 additional processing time in order to accept new transactions. If the delay 26 additional processing time in order to accept new transactions. If the delay
23 between transactions is not long enough the EC may not be able to respond 27 between transactions is not long enough the EC may not be able to respond
diff --git a/Documentation/devicetree/bindings/mfd/da9063.txt b/Documentation/devicetree/bindings/mfd/da9063.txt
index 42c6fa6f1c9a..05b21bcb8543 100644
--- a/Documentation/devicetree/bindings/mfd/da9063.txt
+++ b/Documentation/devicetree/bindings/mfd/da9063.txt
@@ -5,6 +5,7 @@ DA9093 consists of a large and varied group of sub-devices (I2C Only):
5Device Supply Names Description 5Device Supply Names Description
6------ ------------ ----------- 6------ ------------ -----------
7da9063-regulator : : LDOs & BUCKs 7da9063-regulator : : LDOs & BUCKs
8da9063-onkey : : On Key
8da9063-rtc : : Real-Time Clock 9da9063-rtc : : Real-Time Clock
9da9063-watchdog : : Watchdog 10da9063-watchdog : : Watchdog
10 11
@@ -51,6 +52,18 @@ Sub-nodes:
51 the DA9063. There are currently no entries in this binding, however 52 the DA9063. There are currently no entries in this binding, however
52 compatible = "dlg,da9063-rtc" should be added if a node is created. 53 compatible = "dlg,da9063-rtc" should be added if a node is created.
53 54
55- onkey : This node defines the OnKey settings for controlling the key
56 functionality of the device. The node should contain the compatible property
57 with the value "dlg,da9063-onkey".
58
59 Optional onkey properties:
60
61 - dlg,disable-key-power : Disable power-down using a long key-press. If this
62 entry exists the OnKey driver will remove support for the KEY_POWER key
63 press. If this entry does not exist then by default the key-press
64 triggered power down is enabled and the OnKey will support both KEY_POWER
65 and KEY_SLEEP.
66
54- watchdog : This node defines settings for the Watchdog timer associated 67- watchdog : This node defines settings for the Watchdog timer associated
55 with the DA9063. There are currently no entries in this binding, however 68 with the DA9063. There are currently no entries in this binding, however
56 compatible = "dlg,da9063-watchdog" should be added if a node is created. 69 compatible = "dlg,da9063-watchdog" should be added if a node is created.
@@ -73,6 +86,11 @@ Example:
73 compatible = "dlg,da9063-watchdog"; 86 compatible = "dlg,da9063-watchdog";
74 }; 87 };
75 88
89 onkey {
90 compatible = "dlg,da9063-onkey";
91 dlg,disable-key-power;
92 };
93
76 regulators { 94 regulators {
77 DA9063_BCORE1: bcore1 { 95 DA9063_BCORE1: bcore1 {
78 regulator-name = "BCORE1"; 96 regulator-name = "BCORE1";
diff --git a/Documentation/devicetree/bindings/mfd/max77686.txt b/Documentation/devicetree/bindings/mfd/max77686.txt
index e39f0bc1f55e..163bd81a4607 100644
--- a/Documentation/devicetree/bindings/mfd/max77686.txt
+++ b/Documentation/devicetree/bindings/mfd/max77686.txt
@@ -1,6 +1,6 @@
1Maxim MAX77686 multi-function device 1Maxim MAX77686 multi-function device
2 2
3MAX77686 is a Mulitifunction device with PMIC, RTC and Charger on chip. It is 3MAX77686 is a Multifunction device with PMIC, RTC and Charger on chip. It is
4interfaced to host controller using i2c interface. PMIC and Charger submodules 4interfaced to host controller using i2c interface. PMIC and Charger submodules
5are addressed using same i2c slave address whereas RTC submodule uses 5are addressed using same i2c slave address whereas RTC submodule uses
6different i2c slave address,presently for which we are statically creating i2c 6different i2c slave address,presently for which we are statically creating i2c
diff --git a/Documentation/devicetree/bindings/mfd/max77693.txt b/Documentation/devicetree/bindings/mfd/max77693.txt
index 38e64405e98d..d3425846aa5b 100644
--- a/Documentation/devicetree/bindings/mfd/max77693.txt
+++ b/Documentation/devicetree/bindings/mfd/max77693.txt
@@ -76,7 +76,60 @@ Optional properties:
76 Valid values: 4300000, 4700000, 4800000, 4900000 76 Valid values: 4300000, 4700000, 4800000, 4900000
77 Default: 4300000 77 Default: 4300000
78 78
79- led : the LED submodule device node
80
81There are two LED outputs available - FLED1 and FLED2. Each of them can
82control a separate LED or they can be connected together to double
83the maximum current for a single connected LED. One LED is represented
84by one child node.
85
86Required properties:
87- compatible : Must be "maxim,max77693-led".
88
89Optional properties:
90- maxim,boost-mode :
91 In boost mode the device can produce up to 1.2A of total current
92 on both outputs. The maximum current on each output is reduced
93 to 625mA then. If not enabled explicitly, boost setting defaults to
94 LEDS_BOOST_FIXED in case both current sources are used.
95 Possible values:
96 LEDS_BOOST_OFF (0) - no boost,
97 LEDS_BOOST_ADAPTIVE (1) - adaptive mode,
98 LEDS_BOOST_FIXED (2) - fixed mode.
99- maxim,boost-mvout : Output voltage of the boost module in millivolts.
100 Valid values: 3300 - 5500, step by 25 (rounded down)
101 Default: 3300
102- maxim,mvsys-min : Low input voltage level in millivolts. Flash is not fired
103 if chip estimates that system voltage could drop below this level due
104 to flash power consumption.
105 Valid values: 2400 - 3400, step by 33 (rounded down)
106 Default: 2400
107
108Required properties for the LED child node:
109- led-sources : see Documentation/devicetree/bindings/leds/common.txt;
110 device current output identifiers: 0 - FLED1, 1 - FLED2
111- led-max-microamp : see Documentation/devicetree/bindings/leds/common.txt
112 Valid values for a LED connected to one FLED output:
113 15625 - 250000, step by 15625 (rounded down)
114 Valid values for a LED connected to both FLED outputs:
115 15625 - 500000, step by 15625 (rounded down)
116- flash-max-microamp : see Documentation/devicetree/bindings/leds/common.txt
117 Valid values for a single LED connected to one FLED output
118 (boost mode must be turned off):
119 15625 - 1000000, step by 15625 (rounded down)
120 Valid values for a single LED connected to both FLED outputs:
121 15625 - 1250000, step by 15625 (rounded down)
122 Valid values for two LEDs case:
123 15625 - 625000, step by 15625 (rounded down)
124- flash-max-timeout-us : see Documentation/devicetree/bindings/leds/common.txt
125 Valid values: 62500 - 1000000, step by 62500 (rounded down)
126
127Optional properties for the LED child node:
128- label : see Documentation/devicetree/bindings/leds/common.txt
129
79Example: 130Example:
131#include <dt-bindings/leds/common.h>
132
80 max77693@66 { 133 max77693@66 {
81 compatible = "maxim,max77693"; 134 compatible = "maxim,max77693";
82 reg = <0x66>; 135 reg = <0x66>;
@@ -117,5 +170,19 @@ Example:
117 maxim,thermal-regulation-celsius = <75>; 170 maxim,thermal-regulation-celsius = <75>;
118 maxim,battery-overcurrent-microamp = <3000000>; 171 maxim,battery-overcurrent-microamp = <3000000>;
119 maxim,charge-input-threshold-microvolt = <4300000>; 172 maxim,charge-input-threshold-microvolt = <4300000>;
173
174 led {
175 compatible = "maxim,max77693-led";
176 maxim,boost-mode = <LEDS_BOOST_FIXED>;
177 maxim,boost-mvout = <5000>;
178 maxim,mvsys-min = <2400>;
179
180 camera_flash: flash-led {
181 label = "max77693-flash";
182 led-sources = <0>, <1>;
183 led-max-microamp = <500000>;
184 flash-max-microamp = <1250000>;
185 flash-max-timeout-us = <1000000>;
186 };
120 }; 187 };
121 }; 188 };
diff --git a/Documentation/devicetree/bindings/rtc/rtc-st-lpc.txt b/Documentation/devicetree/bindings/rtc/rtc-st-lpc.txt
new file mode 100644
index 000000000000..73407f502e4e
--- /dev/null
+++ b/Documentation/devicetree/bindings/rtc/rtc-st-lpc.txt
@@ -0,0 +1,25 @@
1STMicroelectronics Low Power Controller (LPC) - RTC
2===================================================
3
4LPC currently supports Watchdog OR Real Time Clock functionality.
5
6[See: ../watchdog/st_lpc_wdt.txt for Watchdog options]
7
8Required properties
9
10- compatible : Must be one of: "st,stih407-lpc" "st,stih416-lpc"
11 "st,stih415-lpc" "st,stid127-lpc"
12- reg : LPC registers base address + size
13- interrupts : LPC interrupt line number and associated flags
14- clocks : Clock used by LPC device (See: ../clock/clock-bindings.txt)
15- st,lpc-mode : The LPC can run either one of two modes ST_LPC_MODE_RTC [0] or
16 ST_LPC_MODE_WDT [1]. One (and only one) mode must be
17 selected.
18
19Example:
20 lpc@fde05000 {
21 compatible = "st,stih407-lpc";
22 reg = <0xfde05000 0x1000>;
23 clocks = <&clk_s_d3_flexgen CLK_LPC_0>;
24 st,lpc-mode = <ST_LPC_MODE_RTC>;
25 };
diff --git a/Documentation/devicetree/bindings/watchdog/st_lpc_wdt.txt b/Documentation/devicetree/bindings/watchdog/st_lpc_wdt.txt
new file mode 100644
index 000000000000..388c88a01222
--- /dev/null
+++ b/Documentation/devicetree/bindings/watchdog/st_lpc_wdt.txt
@@ -0,0 +1,38 @@
1STMicroelectronics Low Power Controller (LPC) - Watchdog
2========================================================
3
4LPC currently supports Watchdog OR Real Time Clock functionality.
5
6[See: ../rtc/rtc-st-lpc.txt for RTC options]
7
8Required properties
9
10- compatible : Must be one of: "st,stih407-lpc" "st,stih416-lpc"
11 "st,stih415-lpc" "st,stid127-lpc"
12- reg : LPC registers base address + size
13- interrupts : LPC interrupt line number and associated flags
14- clocks : Clock used by LPC device (See: ../clock/clock-bindings.txt)
15- st,lpc-mode : The LPC can run either one of two modes ST_LPC_MODE_RTC [0] or
16 ST_LPC_MODE_WDT [1]. One (and only one) mode must be
17 selected.
18
19Required properties [watchdog mode]
20
21- st,syscfg : Phandle to syscfg node used to enable watchdog and configure
22 CPU reset type.
23- timeout-sec : Watchdog timeout in seconds
24
25Optional properties [watchdog mode]
26
27- st,warm-reset : If present reset type will be 'warm' - if not it will be cold
28
29Example:
30 lpc@fde05000 {
31 compatible = "st,stih407-lpc";
32 reg = <0xfde05000 0x1000>;
33 clocks = <&clk_s_d3_flexgen CLK_LPC_0>;
34 st,syscfg = <&syscfg_core>;
35 timeout-sec = <120>;
36 st,lpc-mode = <ST_LPC_MODE_WDT>;
37 st,warm-reset;
38 };
diff --git a/MAINTAINERS b/MAINTAINERS
index 5829384460e6..a0ee3ca890ed 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1489,10 +1489,12 @@ F: drivers/phy/phy-stih407-usb.c
1489F: drivers/phy/phy-stih41x-usb.c 1489F: drivers/phy/phy-stih41x-usb.c
1490F: drivers/pinctrl/pinctrl-st.c 1490F: drivers/pinctrl/pinctrl-st.c
1491F: drivers/reset/sti/ 1491F: drivers/reset/sti/
1492F: drivers/rtc/rtc-st-lpc.c
1492F: drivers/tty/serial/st-asc.c 1493F: drivers/tty/serial/st-asc.c
1493F: drivers/usb/dwc3/dwc3-st.c 1494F: drivers/usb/dwc3/dwc3-st.c
1494F: drivers/usb/host/ehci-st.c 1495F: drivers/usb/host/ehci-st.c
1495F: drivers/usb/host/ohci-st.c 1496F: drivers/usb/host/ohci-st.c
1497F: drivers/watchdog/st_lpc_wdt.c
1496F: drivers/ata/ahci_st.c 1498F: drivers/ata/ahci_st.c
1497 1499
1498ARM/TECHNOLOGIC SYSTEMS TS7250 MACHINE SUPPORT 1500ARM/TECHNOLOGIC SYSTEMS TS7250 MACHINE SUPPORT
@@ -8581,14 +8583,20 @@ L: linux-fbdev@vger.kernel.org
8581S: Maintained 8583S: Maintained
8582F: drivers/video/fbdev/s3c-fb.c 8584F: drivers/video/fbdev/s3c-fb.c
8583 8585
8584SAMSUNG MULTIFUNCTION DEVICE DRIVERS 8586SAMSUNG MULTIFUNCTION PMIC DEVICE DRIVERS
8585M: Sangbeom Kim <sbkim73@samsung.com> 8587M: Sangbeom Kim <sbkim73@samsung.com>
8588M: Krzysztof Kozlowski <k.kozlowski@samsung.com>
8586L: linux-kernel@vger.kernel.org 8589L: linux-kernel@vger.kernel.org
8590L: linux-samsung-soc@vger.kernel.org
8587S: Supported 8591S: Supported
8588F: drivers/mfd/sec*.c 8592F: drivers/mfd/sec*.c
8589F: drivers/regulator/s2m*.c 8593F: drivers/regulator/s2m*.c
8590F: drivers/regulator/s5m*.c 8594F: drivers/regulator/s5m*.c
8595F: drivers/clk/clk-s2mps11.c
8596F: drivers/rtc/rtc-s5m.c
8591F: include/linux/mfd/samsung/ 8597F: include/linux/mfd/samsung/
8598F: Documentation/devicetree/bindings/regulator/s5m8767-regulator.txt
8599F: Documentation/devicetree/bindings/mfd/s2mp*.txt
8592 8600
8593SAMSUNG S5P/EXYNOS4 SOC SERIES CAMERA SUBSYSTEM DRIVERS 8601SAMSUNG S5P/EXYNOS4 SOC SERIES CAMERA SUBSYSTEM DRIVERS
8594M: Kyungmin Park <kyungmin.park@samsung.com> 8602M: Kyungmin Park <kyungmin.park@samsung.com>
@@ -9627,6 +9635,13 @@ F: arch/arc/
9627F: Documentation/devicetree/bindings/arc/ 9635F: Documentation/devicetree/bindings/arc/
9628F: drivers/tty/serial/arc_uart.c 9636F: drivers/tty/serial/arc_uart.c
9629 9637
9638SYSTEM CONFIGURATION (SYSCON)
9639M: Lee Jones <lee.jones@linaro.org>
9640M: Arnd Bergmann <arnd@arndb.de>
9641T: git git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd.git
9642S: Supported
9643F: drivers/mfd/syscon.c
9644
9630SYSV FILESYSTEM 9645SYSV FILESYSTEM
9631M: Christoph Hellwig <hch@infradead.org> 9646M: Christoph Hellwig <hch@infradead.org>
9632S: Maintained 9647S: Maintained
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
index 2255af23b9c7..5f1c1c4f5d87 100644
--- a/drivers/i2c/busses/Kconfig
+++ b/drivers/i2c/busses/Kconfig
@@ -1103,7 +1103,7 @@ config I2C_SIBYTE
1103 1103
1104config I2C_CROS_EC_TUNNEL 1104config I2C_CROS_EC_TUNNEL
1105 tristate "ChromeOS EC tunnel I2C bus" 1105 tristate "ChromeOS EC tunnel I2C bus"
1106 depends on MFD_CROS_EC 1106 depends on CROS_EC_PROTO
1107 help 1107 help
1108 If you say yes here you get an I2C bus that will tunnel i2c commands 1108 If you say yes here you get an I2C bus that will tunnel i2c commands
1109 through to the other side of the ChromeOS EC to the i2c bus 1109 through to the other side of the ChromeOS EC to the i2c bus
diff --git a/drivers/i2c/busses/i2c-cros-ec-tunnel.c b/drivers/i2c/busses/i2c-cros-ec-tunnel.c
index fa8dedd8c3a2..a0d95ff682ae 100644
--- a/drivers/i2c/busses/i2c-cros-ec-tunnel.c
+++ b/drivers/i2c/busses/i2c-cros-ec-tunnel.c
@@ -182,8 +182,9 @@ static int ec_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg i2c_msgs[],
182 const u16 bus_num = bus->remote_bus; 182 const u16 bus_num = bus->remote_bus;
183 int request_len; 183 int request_len;
184 int response_len; 184 int response_len;
185 int alloc_size;
185 int result; 186 int result;
186 struct cros_ec_command msg = { }; 187 struct cros_ec_command *msg;
187 188
188 request_len = ec_i2c_count_message(i2c_msgs, num); 189 request_len = ec_i2c_count_message(i2c_msgs, num);
189 if (request_len < 0) { 190 if (request_len < 0) {
@@ -198,25 +199,39 @@ static int ec_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg i2c_msgs[],
198 return response_len; 199 return response_len;
199 } 200 }
200 201
201 result = ec_i2c_construct_message(msg.outdata, i2c_msgs, num, bus_num); 202 alloc_size = max(request_len, response_len);
202 if (result) 203 msg = kmalloc(sizeof(*msg) + alloc_size, GFP_KERNEL);
203 return result; 204 if (!msg)
205 return -ENOMEM;
204 206
205 msg.version = 0; 207 result = ec_i2c_construct_message(msg->data, i2c_msgs, num, bus_num);
206 msg.command = EC_CMD_I2C_PASSTHRU; 208 if (result) {
207 msg.outsize = request_len; 209 dev_err(dev, "Error constructing EC i2c message %d\n", result);
208 msg.insize = response_len; 210 goto exit;
211 }
209 212
210 result = cros_ec_cmd_xfer(bus->ec, &msg); 213 msg->version = 0;
211 if (result < 0) 214 msg->command = EC_CMD_I2C_PASSTHRU;
212 return result; 215 msg->outsize = request_len;
216 msg->insize = response_len;
213 217
214 result = ec_i2c_parse_response(msg.indata, i2c_msgs, &num); 218 result = cros_ec_cmd_xfer(bus->ec, msg);
215 if (result < 0) 219 if (result < 0) {
216 return result; 220 dev_err(dev, "Error transferring EC i2c message %d\n", result);
221 goto exit;
222 }
223
224 result = ec_i2c_parse_response(msg->data, i2c_msgs, &num);
225 if (result < 0) {
226 dev_err(dev, "Error parsing EC i2c message %d\n", result);
227 goto exit;
228 }
217 229
218 /* Indicate success by saying how many messages were sent */ 230 /* Indicate success by saying how many messages were sent */
219 return num; 231 result = num;
232exit:
233 kfree(msg);
234 return result;
220} 235}
221 236
222static u32 ec_i2c_functionality(struct i2c_adapter *adap) 237static u32 ec_i2c_functionality(struct i2c_adapter *adap)
diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig
index 106fbac7f8c5..e8eb60c6d83e 100644
--- a/drivers/input/keyboard/Kconfig
+++ b/drivers/input/keyboard/Kconfig
@@ -677,7 +677,7 @@ config KEYBOARD_W90P910
677config KEYBOARD_CROS_EC 677config KEYBOARD_CROS_EC
678 tristate "ChromeOS EC keyboard" 678 tristate "ChromeOS EC keyboard"
679 select INPUT_MATRIXKMAP 679 select INPUT_MATRIXKMAP
680 depends on MFD_CROS_EC 680 depends on CROS_EC_PROTO
681 help 681 help
682 Say Y here to enable the matrix keyboard used by ChromeOS devices 682 Say Y here to enable the matrix keyboard used by ChromeOS devices
683 and implemented on the ChromeOS EC. You must enable one bus option 683 and implemented on the ChromeOS EC. You must enable one bus option
diff --git a/drivers/input/keyboard/cros_ec_keyb.c b/drivers/input/keyboard/cros_ec_keyb.c
index b50c5b8b8a4d..b01966dc7eb3 100644
--- a/drivers/input/keyboard/cros_ec_keyb.c
+++ b/drivers/input/keyboard/cros_ec_keyb.c
@@ -148,19 +148,28 @@ static void cros_ec_keyb_process(struct cros_ec_keyb *ckdev,
148 148
149static int cros_ec_keyb_get_state(struct cros_ec_keyb *ckdev, uint8_t *kb_state) 149static int cros_ec_keyb_get_state(struct cros_ec_keyb *ckdev, uint8_t *kb_state)
150{ 150{
151 int ret; 151 int ret = 0;
152 struct cros_ec_command msg = { 152 struct cros_ec_command *msg;
153 .command = EC_CMD_MKBP_STATE,
154 .insize = ckdev->cols,
155 };
156 153
157 ret = cros_ec_cmd_xfer(ckdev->ec, &msg); 154 msg = kmalloc(sizeof(*msg) + ckdev->cols, GFP_KERNEL);
158 if (ret < 0) 155 if (!msg)
159 return ret; 156 return -ENOMEM;
160 157
161 memcpy(kb_state, msg.indata, ckdev->cols); 158 msg->version = 0;
159 msg->command = EC_CMD_MKBP_STATE;
160 msg->insize = ckdev->cols;
161 msg->outsize = 0;
162 162
163 return 0; 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;
164} 173}
165 174
166static irqreturn_t cros_ec_keyb_irq(int irq, void *data) 175static irqreturn_t cros_ec_keyb_irq(int irq, void *data)
@@ -266,7 +275,7 @@ static int cros_ec_keyb_probe(struct platform_device *pdev)
266 ckdev->dev = dev; 275 ckdev->dev = dev;
267 dev_set_drvdata(&pdev->dev, ckdev); 276 dev_set_drvdata(&pdev->dev, ckdev);
268 277
269 idev->name = ec->ec_name; 278 idev->name = CROS_EC_DEV_NAME;
270 idev->phys = ec->phys_name; 279 idev->phys = ec->phys_name;
271 __set_bit(EV_REP, idev->evbit); 280 __set_bit(EV_REP, idev->evbit);
272 281
diff --git a/drivers/mfd/88pm860x-core.c b/drivers/mfd/88pm860x-core.c
index d2a85cde68da..e03b7f45b8f7 100644
--- a/drivers/mfd/88pm860x-core.c
+++ b/drivers/mfd/88pm860x-core.c
@@ -566,7 +566,7 @@ static int pm860x_irq_domain_map(struct irq_domain *d, unsigned int virq,
566 return 0; 566 return 0;
567} 567}
568 568
569static struct irq_domain_ops pm860x_irq_domain_ops = { 569static const struct irq_domain_ops pm860x_irq_domain_ops = {
570 .map = pm860x_irq_domain_map, 570 .map = pm860x_irq_domain_map,
571 .xlate = irq_domain_xlate_onetwocell, 571 .xlate = irq_domain_xlate_onetwocell,
572}; 572};
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index d5ad04dad081..653815950aa2 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -52,7 +52,8 @@ config PMIC_ADP5520
52config MFD_AAT2870_CORE 52config MFD_AAT2870_CORE
53 bool "AnalogicTech AAT2870" 53 bool "AnalogicTech AAT2870"
54 select MFD_CORE 54 select MFD_CORE
55 depends on I2C=y && GPIOLIB 55 depends on I2C=y
56 depends on GPIOLIB || COMPILE_TEST
56 help 57 help
57 If you say yes here you get support for the AAT2870. 58 If you say yes here you get support for the AAT2870.
58 This driver provides common support for accessing the device, 59 This driver provides common support for accessing the device,
@@ -94,6 +95,8 @@ config MFD_AXP20X
94config MFD_CROS_EC 95config MFD_CROS_EC
95 tristate "ChromeOS Embedded Controller" 96 tristate "ChromeOS Embedded Controller"
96 select MFD_CORE 97 select MFD_CORE
98 select CHROME_PLATFORMS
99 select CROS_EC_PROTO
97 help 100 help
98 If you say Y here you get support for the ChromeOS Embedded 101 If you say Y here you get support for the ChromeOS Embedded
99 Controller (EC) providing keyboard, battery and power services. 102 Controller (EC) providing keyboard, battery and power services.
@@ -102,7 +105,7 @@ config MFD_CROS_EC
102 105
103config MFD_CROS_EC_I2C 106config MFD_CROS_EC_I2C
104 tristate "ChromeOS Embedded Controller (I2C)" 107 tristate "ChromeOS Embedded Controller (I2C)"
105 depends on MFD_CROS_EC && I2C 108 depends on MFD_CROS_EC && CROS_EC_PROTO && I2C
106 109
107 help 110 help
108 If you say Y here, you get support for talking to the ChromeOS 111 If you say Y here, you get support for talking to the ChromeOS
@@ -112,7 +115,7 @@ config MFD_CROS_EC_I2C
112 115
113config MFD_CROS_EC_SPI 116config MFD_CROS_EC_SPI
114 tristate "ChromeOS Embedded Controller (SPI)" 117 tristate "ChromeOS Embedded Controller (SPI)"
115 depends on MFD_CROS_EC && SPI && OF 118 depends on MFD_CROS_EC && CROS_EC_PROTO && SPI && OF
116 119
117 ---help--- 120 ---help---
118 If you say Y here, you get support for talking to the ChromeOS EC 121 If you say Y here, you get support for talking to the ChromeOS EC
@@ -1115,7 +1118,8 @@ config MFD_TPS6586X
1115 1118
1116config MFD_TPS65910 1119config MFD_TPS65910
1117 bool "TI TPS65910 Power Management chip" 1120 bool "TI TPS65910 Power Management chip"
1118 depends on I2C=y && GPIOLIB 1121 depends on I2C=y
1122 depends on GPIOLIB || COMPILE_TEST
1119 select MFD_CORE 1123 select MFD_CORE
1120 select REGMAP_I2C 1124 select REGMAP_I2C
1121 select REGMAP_IRQ 1125 select REGMAP_IRQ
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index 0e5cfeba107c..ea40e076cb61 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -39,13 +39,13 @@ obj-$(CONFIG_MFD_ARIZONA) += arizona-core.o
39obj-$(CONFIG_MFD_ARIZONA) += arizona-irq.o 39obj-$(CONFIG_MFD_ARIZONA) += arizona-irq.o
40obj-$(CONFIG_MFD_ARIZONA_I2C) += arizona-i2c.o 40obj-$(CONFIG_MFD_ARIZONA_I2C) += arizona-i2c.o
41obj-$(CONFIG_MFD_ARIZONA_SPI) += arizona-spi.o 41obj-$(CONFIG_MFD_ARIZONA_SPI) += arizona-spi.o
42ifneq ($(CONFIG_MFD_WM5102),n) 42ifeq ($(CONFIG_MFD_WM5102),y)
43obj-$(CONFIG_MFD_ARIZONA) += wm5102-tables.o 43obj-$(CONFIG_MFD_ARIZONA) += wm5102-tables.o
44endif 44endif
45ifneq ($(CONFIG_MFD_WM5110),n) 45ifeq ($(CONFIG_MFD_WM5110),y)
46obj-$(CONFIG_MFD_ARIZONA) += wm5110-tables.o 46obj-$(CONFIG_MFD_ARIZONA) += wm5110-tables.o
47endif 47endif
48ifneq ($(CONFIG_MFD_WM8997),n) 48ifeq ($(CONFIG_MFD_WM8997),y)
49obj-$(CONFIG_MFD_ARIZONA) += wm8997-tables.o 49obj-$(CONFIG_MFD_ARIZONA) += wm8997-tables.o
50endif 50endif
51obj-$(CONFIG_MFD_WM8400) += wm8400-core.o 51obj-$(CONFIG_MFD_WM8400) += wm8400-core.o
diff --git a/drivers/mfd/ab8500-core.c b/drivers/mfd/ab8500-core.c
index c80a2925f8e5..000da72a0ae9 100644
--- a/drivers/mfd/ab8500-core.c
+++ b/drivers/mfd/ab8500-core.c
@@ -574,7 +574,7 @@ static int ab8500_irq_map(struct irq_domain *d, unsigned int virq,
574 return 0; 574 return 0;
575} 575}
576 576
577static struct irq_domain_ops ab8500_irq_ops = { 577static const struct irq_domain_ops ab8500_irq_ops = {
578 .map = ab8500_irq_map, 578 .map = ab8500_irq_map,
579 .xlate = irq_domain_xlate_twocell, 579 .xlate = irq_domain_xlate_twocell,
580}; 580};
diff --git a/drivers/mfd/ab8500-debugfs.c b/drivers/mfd/ab8500-debugfs.c
index cdd6f3d63314..0236cd7cdce4 100644
--- a/drivers/mfd/ab8500-debugfs.c
+++ b/drivers/mfd/ab8500-debugfs.c
@@ -2885,7 +2885,7 @@ static ssize_t ab8500_subscribe_write(struct file *file,
2885 } 2885 }
2886 2886
2887 err = request_threaded_irq(user_val, NULL, ab8500_debug_handler, 2887 err = request_threaded_irq(user_val, NULL, ab8500_debug_handler,
2888 IRQF_SHARED | IRQF_NO_SUSPEND, 2888 IRQF_SHARED | IRQF_NO_SUSPEND | IRQF_ONESHOT,
2889 "ab8500-debug", &dev->kobj); 2889 "ab8500-debug", &dev->kobj);
2890 if (err < 0) { 2890 if (err < 0) {
2891 pr_info("request_threaded_irq failed %d, %lu\n", 2891 pr_info("request_threaded_irq failed %d, %lu\n",
diff --git a/drivers/mfd/ab8500-gpadc.c b/drivers/mfd/ab8500-gpadc.c
index dabbc93abdd7..c51c1b188d64 100644
--- a/drivers/mfd/ab8500-gpadc.c
+++ b/drivers/mfd/ab8500-gpadc.c
@@ -948,7 +948,8 @@ static int ab8500_gpadc_probe(struct platform_device *pdev)
948 if (gpadc->irq_sw >= 0) { 948 if (gpadc->irq_sw >= 0) {
949 ret = request_threaded_irq(gpadc->irq_sw, NULL, 949 ret = request_threaded_irq(gpadc->irq_sw, NULL,
950 ab8500_bm_gpadcconvend_handler, 950 ab8500_bm_gpadcconvend_handler,
951 IRQF_NO_SUSPEND | IRQF_SHARED, "ab8500-gpadc-sw", 951 IRQF_NO_SUSPEND | IRQF_SHARED | IRQF_ONESHOT,
952 "ab8500-gpadc-sw",
952 gpadc); 953 gpadc);
953 if (ret < 0) { 954 if (ret < 0) {
954 dev_err(gpadc->dev, 955 dev_err(gpadc->dev,
@@ -961,7 +962,8 @@ static int ab8500_gpadc_probe(struct platform_device *pdev)
961 if (gpadc->irq_hw >= 0) { 962 if (gpadc->irq_hw >= 0) {
962 ret = request_threaded_irq(gpadc->irq_hw, NULL, 963 ret = request_threaded_irq(gpadc->irq_hw, NULL,
963 ab8500_bm_gpadcconvend_handler, 964 ab8500_bm_gpadcconvend_handler,
964 IRQF_NO_SUSPEND | IRQF_SHARED, "ab8500-gpadc-hw", 965 IRQF_NO_SUSPEND | IRQF_SHARED | IRQF_ONESHOT,
966 "ab8500-gpadc-hw",
965 gpadc); 967 gpadc);
966 if (ret < 0) { 968 if (ret < 0) {
967 dev_err(gpadc->dev, 969 dev_err(gpadc->dev,
diff --git a/drivers/mfd/arizona-core.c b/drivers/mfd/arizona-core.c
index 6ca6dfab50eb..bebf58a06a6b 100644
--- a/drivers/mfd/arizona-core.c
+++ b/drivers/mfd/arizona-core.c
@@ -250,20 +250,50 @@ static int arizona_wait_for_boot(struct arizona *arizona)
250 return ret; 250 return ret;
251} 251}
252 252
253static int arizona_apply_hardware_patch(struct arizona* arizona) 253static inline void arizona_enable_reset(struct arizona *arizona)
254{
255 if (arizona->pdata.reset)
256 gpio_set_value_cansleep(arizona->pdata.reset, 0);
257}
258
259static void arizona_disable_reset(struct arizona *arizona)
260{
261 if (arizona->pdata.reset) {
262 switch (arizona->type) {
263 case WM5110:
264 case WM8280:
265 /* Meet requirements for minimum reset duration */
266 msleep(5);
267 break;
268 default:
269 break;
270 }
271
272 gpio_set_value_cansleep(arizona->pdata.reset, 1);
273 msleep(1);
274 }
275}
276
277struct arizona_sysclk_state {
278 unsigned int fll;
279 unsigned int sysclk;
280};
281
282static int arizona_enable_freerun_sysclk(struct arizona *arizona,
283 struct arizona_sysclk_state *state)
254{ 284{
255 unsigned int fll, sysclk;
256 int ret, err; 285 int ret, err;
257 286
258 /* Cache existing FLL and SYSCLK settings */ 287 /* Cache existing FLL and SYSCLK settings */
259 ret = regmap_read(arizona->regmap, ARIZONA_FLL1_CONTROL_1, &fll); 288 ret = regmap_read(arizona->regmap, ARIZONA_FLL1_CONTROL_1, &state->fll);
260 if (ret != 0) { 289 if (ret) {
261 dev_err(arizona->dev, "Failed to cache FLL settings: %d\n", 290 dev_err(arizona->dev, "Failed to cache FLL settings: %d\n",
262 ret); 291 ret);
263 return ret; 292 return ret;
264 } 293 }
265 ret = regmap_read(arizona->regmap, ARIZONA_SYSTEM_CLOCK_1, &sysclk); 294 ret = regmap_read(arizona->regmap, ARIZONA_SYSTEM_CLOCK_1,
266 if (ret != 0) { 295 &state->sysclk);
296 if (ret) {
267 dev_err(arizona->dev, "Failed to cache SYSCLK settings: %d\n", 297 dev_err(arizona->dev, "Failed to cache SYSCLK settings: %d\n",
268 ret); 298 ret);
269 return ret; 299 return ret;
@@ -272,7 +302,7 @@ static int arizona_apply_hardware_patch(struct arizona* arizona)
272 /* Start up SYSCLK using the FLL in free running mode */ 302 /* Start up SYSCLK using the FLL in free running mode */
273 ret = regmap_write(arizona->regmap, ARIZONA_FLL1_CONTROL_1, 303 ret = regmap_write(arizona->regmap, ARIZONA_FLL1_CONTROL_1,
274 ARIZONA_FLL1_ENA | ARIZONA_FLL1_FREERUN); 304 ARIZONA_FLL1_ENA | ARIZONA_FLL1_FREERUN);
275 if (ret != 0) { 305 if (ret) {
276 dev_err(arizona->dev, 306 dev_err(arizona->dev,
277 "Failed to start FLL in freerunning mode: %d\n", 307 "Failed to start FLL in freerunning mode: %d\n",
278 ret); 308 ret);
@@ -281,53 +311,137 @@ static int arizona_apply_hardware_patch(struct arizona* arizona)
281 ret = arizona_poll_reg(arizona, 25, ARIZONA_INTERRUPT_RAW_STATUS_5, 311 ret = arizona_poll_reg(arizona, 25, ARIZONA_INTERRUPT_RAW_STATUS_5,
282 ARIZONA_FLL1_CLOCK_OK_STS, 312 ARIZONA_FLL1_CLOCK_OK_STS,
283 ARIZONA_FLL1_CLOCK_OK_STS); 313 ARIZONA_FLL1_CLOCK_OK_STS);
284 if (ret != 0) { 314 if (ret) {
285 ret = -ETIMEDOUT; 315 ret = -ETIMEDOUT;
286 goto err_fll; 316 goto err_fll;
287 } 317 }
288 318
289 ret = regmap_write(arizona->regmap, ARIZONA_SYSTEM_CLOCK_1, 0x0144); 319 ret = regmap_write(arizona->regmap, ARIZONA_SYSTEM_CLOCK_1, 0x0144);
290 if (ret != 0) { 320 if (ret) {
291 dev_err(arizona->dev, "Failed to start SYSCLK: %d\n", ret); 321 dev_err(arizona->dev, "Failed to start SYSCLK: %d\n", ret);
292 goto err_fll; 322 goto err_fll;
293 } 323 }
294 324
325 return 0;
326
327err_fll:
328 err = regmap_write(arizona->regmap, ARIZONA_FLL1_CONTROL_1, state->fll);
329 if (err)
330 dev_err(arizona->dev,
331 "Failed to re-apply old FLL settings: %d\n", err);
332
333 return ret;
334}
335
336static int arizona_disable_freerun_sysclk(struct arizona *arizona,
337 struct arizona_sysclk_state *state)
338{
339 int ret;
340
341 ret = regmap_write(arizona->regmap, ARIZONA_SYSTEM_CLOCK_1,
342 state->sysclk);
343 if (ret) {
344 dev_err(arizona->dev,
345 "Failed to re-apply old SYSCLK settings: %d\n", ret);
346 return ret;
347 }
348
349 ret = regmap_write(arizona->regmap, ARIZONA_FLL1_CONTROL_1, state->fll);
350 if (ret) {
351 dev_err(arizona->dev,
352 "Failed to re-apply old FLL settings: %d\n", ret);
353 return ret;
354 }
355
356 return 0;
357}
358
359static int wm5102_apply_hardware_patch(struct arizona *arizona)
360{
361 struct arizona_sysclk_state state;
362 int err, ret;
363
364 ret = arizona_enable_freerun_sysclk(arizona, &state);
365 if (ret)
366 return ret;
367
295 /* Start the write sequencer and wait for it to finish */ 368 /* Start the write sequencer and wait for it to finish */
296 ret = regmap_write(arizona->regmap, ARIZONA_WRITE_SEQUENCER_CTRL_0, 369 ret = regmap_write(arizona->regmap, ARIZONA_WRITE_SEQUENCER_CTRL_0,
297 ARIZONA_WSEQ_ENA | ARIZONA_WSEQ_START | 160); 370 ARIZONA_WSEQ_ENA | ARIZONA_WSEQ_START | 160);
298 if (ret != 0) { 371 if (ret) {
299 dev_err(arizona->dev, "Failed to start write sequencer: %d\n", 372 dev_err(arizona->dev, "Failed to start write sequencer: %d\n",
300 ret); 373 ret);
301 goto err_sysclk; 374 goto err;
302 } 375 }
376
303 ret = arizona_poll_reg(arizona, 5, ARIZONA_WRITE_SEQUENCER_CTRL_1, 377 ret = arizona_poll_reg(arizona, 5, ARIZONA_WRITE_SEQUENCER_CTRL_1,
304 ARIZONA_WSEQ_BUSY, 0); 378 ARIZONA_WSEQ_BUSY, 0);
305 if (ret != 0) { 379 if (ret) {
306 regmap_write(arizona->regmap, ARIZONA_WRITE_SEQUENCER_CTRL_0, 380 regmap_write(arizona->regmap, ARIZONA_WRITE_SEQUENCER_CTRL_0,
307 ARIZONA_WSEQ_ABORT); 381 ARIZONA_WSEQ_ABORT);
308 ret = -ETIMEDOUT; 382 ret = -ETIMEDOUT;
309 } 383 }
310 384
311err_sysclk: 385err:
312 err = regmap_write(arizona->regmap, ARIZONA_SYSTEM_CLOCK_1, sysclk); 386 err = arizona_disable_freerun_sysclk(arizona, &state);
313 if (err != 0) {
314 dev_err(arizona->dev,
315 "Failed to re-apply old SYSCLK settings: %d\n",
316 err);
317 }
318 387
319err_fll: 388 return ret ?: err;
320 err = regmap_write(arizona->regmap, ARIZONA_FLL1_CONTROL_1, fll); 389}
321 if (err != 0) { 390
391/*
392 * Register patch to some of the CODECs internal write sequences
393 * to ensure a clean exit from the low power sleep state.
394 */
395static const struct reg_default wm5110_sleep_patch[] = {
396 { 0x337A, 0xC100 },
397 { 0x337B, 0x0041 },
398 { 0x3300, 0xA210 },
399 { 0x3301, 0x050C },
400};
401
402static int wm5110_apply_sleep_patch(struct arizona *arizona)
403{
404 struct arizona_sysclk_state state;
405 int err, ret;
406
407 ret = arizona_enable_freerun_sysclk(arizona, &state);
408 if (ret)
409 return ret;
410
411 ret = regmap_multi_reg_write_bypassed(arizona->regmap,
412 wm5110_sleep_patch,
413 ARRAY_SIZE(wm5110_sleep_patch));
414
415 err = arizona_disable_freerun_sysclk(arizona, &state);
416
417 return ret ?: err;
418}
419
420static int wm5102_clear_write_sequencer(struct arizona *arizona)
421{
422 int ret;
423
424 ret = regmap_write(arizona->regmap, ARIZONA_WRITE_SEQUENCER_CTRL_3,
425 0x0);
426 if (ret) {
322 dev_err(arizona->dev, 427 dev_err(arizona->dev,
323 "Failed to re-apply old FLL settings: %d\n", 428 "Failed to clear write sequencer state: %d\n", ret);
324 err); 429 return ret;
325 } 430 }
326 431
327 if (ret != 0) 432 arizona_enable_reset(arizona);
433 regulator_disable(arizona->dcvdd);
434
435 msleep(20);
436
437 ret = regulator_enable(arizona->dcvdd);
438 if (ret) {
439 dev_err(arizona->dev, "Failed to re-enable DCVDD: %d\n", ret);
328 return ret; 440 return ret;
329 else 441 }
330 return err; 442 arizona_disable_reset(arizona);
443
444 return 0;
331} 445}
332 446
333#ifdef CONFIG_PM 447#ifdef CONFIG_PM
@@ -338,12 +452,33 @@ static int arizona_runtime_resume(struct device *dev)
338 452
339 dev_dbg(arizona->dev, "Leaving AoD mode\n"); 453 dev_dbg(arizona->dev, "Leaving AoD mode\n");
340 454
455 if (arizona->has_fully_powered_off) {
456 dev_dbg(arizona->dev, "Re-enabling core supplies\n");
457
458 ret = regulator_bulk_enable(arizona->num_core_supplies,
459 arizona->core_supplies);
460 if (ret) {
461 dev_err(dev, "Failed to enable core supplies: %d\n",
462 ret);
463 return ret;
464 }
465 }
466
341 ret = regulator_enable(arizona->dcvdd); 467 ret = regulator_enable(arizona->dcvdd);
342 if (ret != 0) { 468 if (ret != 0) {
343 dev_err(arizona->dev, "Failed to enable DCVDD: %d\n", ret); 469 dev_err(arizona->dev, "Failed to enable DCVDD: %d\n", ret);
470 if (arizona->has_fully_powered_off)
471 regulator_bulk_disable(arizona->num_core_supplies,
472 arizona->core_supplies);
344 return ret; 473 return ret;
345 } 474 }
346 475
476 if (arizona->has_fully_powered_off) {
477 arizona_disable_reset(arizona);
478 enable_irq(arizona->irq);
479 arizona->has_fully_powered_off = false;
480 }
481
347 regcache_cache_only(arizona->regmap, false); 482 regcache_cache_only(arizona->regmap, false);
348 483
349 switch (arizona->type) { 484 switch (arizona->type) {
@@ -366,14 +501,53 @@ static int arizona_runtime_resume(struct device *dev)
366 goto err; 501 goto err;
367 } 502 }
368 503
369 ret = arizona_apply_hardware_patch(arizona); 504 ret = wm5102_apply_hardware_patch(arizona);
370 if (ret != 0) { 505 if (ret) {
371 dev_err(arizona->dev, 506 dev_err(arizona->dev,
372 "Failed to apply hardware patch: %d\n", 507 "Failed to apply hardware patch: %d\n",
373 ret); 508 ret);
374 goto err; 509 goto err;
375 } 510 }
376 break; 511 break;
512 case WM5110:
513 case WM8280:
514 ret = arizona_wait_for_boot(arizona);
515 if (ret)
516 goto err;
517
518 if (arizona->external_dcvdd) {
519 ret = regmap_update_bits(arizona->regmap,
520 ARIZONA_ISOLATION_CONTROL,
521 ARIZONA_ISOLATE_DCVDD1, 0);
522 if (ret) {
523 dev_err(arizona->dev,
524 "Failed to connect DCVDD: %d\n", ret);
525 goto err;
526 }
527 } else {
528 /*
529 * As this is only called for the internal regulator
530 * (where we know voltage ranges available) it is ok
531 * to request an exact range.
532 */
533 ret = regulator_set_voltage(arizona->dcvdd,
534 1200000, 1200000);
535 if (ret < 0) {
536 dev_err(arizona->dev,
537 "Failed to set resume voltage: %d\n",
538 ret);
539 goto err;
540 }
541 }
542
543 ret = wm5110_apply_sleep_patch(arizona);
544 if (ret) {
545 dev_err(arizona->dev,
546 "Failed to re-apply sleep patch: %d\n",
547 ret);
548 goto err;
549 }
550 break;
377 default: 551 default:
378 ret = arizona_wait_for_boot(arizona); 552 ret = arizona_wait_for_boot(arizona);
379 if (ret != 0) { 553 if (ret != 0) {
@@ -410,10 +584,17 @@ err:
410static int arizona_runtime_suspend(struct device *dev) 584static int arizona_runtime_suspend(struct device *dev)
411{ 585{
412 struct arizona *arizona = dev_get_drvdata(dev); 586 struct arizona *arizona = dev_get_drvdata(dev);
587 unsigned int val;
413 int ret; 588 int ret;
414 589
415 dev_dbg(arizona->dev, "Entering AoD mode\n"); 590 dev_dbg(arizona->dev, "Entering AoD mode\n");
416 591
592 ret = regmap_read(arizona->regmap, ARIZONA_JACK_DETECT_ANALOGUE, &val);
593 if (ret) {
594 dev_err(dev, "Failed to check jack det status: %d\n", ret);
595 return ret;
596 }
597
417 if (arizona->external_dcvdd) { 598 if (arizona->external_dcvdd) {
418 ret = regmap_update_bits(arizona->regmap, 599 ret = regmap_update_bits(arizona->regmap,
419 ARIZONA_ISOLATION_CONTROL, 600 ARIZONA_ISOLATION_CONTROL,
@@ -426,10 +607,56 @@ static int arizona_runtime_suspend(struct device *dev)
426 } 607 }
427 } 608 }
428 609
610 switch (arizona->type) {
611 case WM5110:
612 case WM8280:
613 if (arizona->external_dcvdd)
614 break;
615
616 /*
617 * As this is only called for the internal regulator
618 * (where we know voltage ranges available) it is ok
619 * to request an exact range.
620 */
621 ret = regulator_set_voltage(arizona->dcvdd, 1175000, 1175000);
622 if (ret < 0) {
623 dev_err(arizona->dev,
624 "Failed to set suspend voltage: %d\n", ret);
625 return ret;
626 }
627 break;
628 case WM5102:
629 if (!(val & ARIZONA_JD1_ENA)) {
630 ret = regmap_write(arizona->regmap,
631 ARIZONA_WRITE_SEQUENCER_CTRL_3, 0x0);
632 if (ret) {
633 dev_err(arizona->dev,
634 "Failed to clear write sequencer: %d\n",
635 ret);
636 return ret;
637 }
638 }
639 break;
640 default:
641 break;
642 }
643
429 regcache_cache_only(arizona->regmap, true); 644 regcache_cache_only(arizona->regmap, true);
430 regcache_mark_dirty(arizona->regmap); 645 regcache_mark_dirty(arizona->regmap);
431 regulator_disable(arizona->dcvdd); 646 regulator_disable(arizona->dcvdd);
432 647
648 /* Allow us to completely power down if no jack detection */
649 if (!(val & ARIZONA_JD1_ENA)) {
650 dev_dbg(arizona->dev, "Fully powering off\n");
651
652 arizona->has_fully_powered_off = true;
653
654 disable_irq(arizona->irq);
655 arizona_enable_reset(arizona);
656 regulator_bulk_disable(arizona->num_core_supplies,
657 arizona->core_supplies);
658 }
659
433 return 0; 660 return 0;
434} 661}
435#endif 662#endif
@@ -728,9 +955,9 @@ int arizona_dev_init(struct arizona *arizona)
728 955
729 if (arizona->pdata.reset) { 956 if (arizona->pdata.reset) {
730 /* Start out with /RESET low to put the chip into reset */ 957 /* Start out with /RESET low to put the chip into reset */
731 ret = gpio_request_one(arizona->pdata.reset, 958 ret = devm_gpio_request_one(arizona->dev, arizona->pdata.reset,
732 GPIOF_DIR_OUT | GPIOF_INIT_LOW, 959 GPIOF_DIR_OUT | GPIOF_INIT_LOW,
733 "arizona /RESET"); 960 "arizona /RESET");
734 if (ret != 0) { 961 if (ret != 0) {
735 dev_err(dev, "Failed to request /RESET: %d\n", ret); 962 dev_err(dev, "Failed to request /RESET: %d\n", ret);
736 goto err_dcvdd; 963 goto err_dcvdd;
@@ -751,10 +978,7 @@ int arizona_dev_init(struct arizona *arizona)
751 goto err_enable; 978 goto err_enable;
752 } 979 }
753 980
754 if (arizona->pdata.reset) { 981 arizona_disable_reset(arizona);
755 gpio_set_value_cansleep(arizona->pdata.reset, 1);
756 msleep(1);
757 }
758 982
759 regcache_cache_only(arizona->regmap, false); 983 regcache_cache_only(arizona->regmap, false);
760 984
@@ -777,8 +1001,6 @@ int arizona_dev_init(struct arizona *arizona)
777 1001
778 /* If we have a /RESET GPIO we'll already be reset */ 1002 /* If we have a /RESET GPIO we'll already be reset */
779 if (!arizona->pdata.reset) { 1003 if (!arizona->pdata.reset) {
780 regcache_mark_dirty(arizona->regmap);
781
782 ret = regmap_write(arizona->regmap, ARIZONA_SOFTWARE_RESET, 0); 1004 ret = regmap_write(arizona->regmap, ARIZONA_SOFTWARE_RESET, 0);
783 if (ret != 0) { 1005 if (ret != 0) {
784 dev_err(dev, "Failed to reset device: %d\n", ret); 1006 dev_err(dev, "Failed to reset device: %d\n", ret);
@@ -786,12 +1008,6 @@ int arizona_dev_init(struct arizona *arizona)
786 } 1008 }
787 1009
788 msleep(1); 1010 msleep(1);
789
790 ret = regcache_sync(arizona->regmap);
791 if (ret != 0) {
792 dev_err(dev, "Failed to sync device: %d\n", ret);
793 goto err_reset;
794 }
795 } 1011 }
796 1012
797 /* Ensure device startup is complete */ 1013 /* Ensure device startup is complete */
@@ -799,21 +1015,24 @@ int arizona_dev_init(struct arizona *arizona)
799 case WM5102: 1015 case WM5102:
800 ret = regmap_read(arizona->regmap, 1016 ret = regmap_read(arizona->regmap,
801 ARIZONA_WRITE_SEQUENCER_CTRL_3, &val); 1017 ARIZONA_WRITE_SEQUENCER_CTRL_3, &val);
802 if (ret != 0) 1018 if (ret) {
803 dev_err(dev, 1019 dev_err(dev,
804 "Failed to check write sequencer state: %d\n", 1020 "Failed to check write sequencer state: %d\n",
805 ret); 1021 ret);
806 else if (val & 0x01) 1022 } else if (val & 0x01) {
807 break; 1023 ret = wm5102_clear_write_sequencer(arizona);
808 /* Fall through */ 1024 if (ret)
809 default: 1025 return ret;
810 ret = arizona_wait_for_boot(arizona);
811 if (ret != 0) {
812 dev_err(arizona->dev,
813 "Device failed initial boot: %d\n", ret);
814 goto err_reset;
815 } 1026 }
816 break; 1027 break;
1028 default:
1029 break;
1030 }
1031
1032 ret = arizona_wait_for_boot(arizona);
1033 if (ret) {
1034 dev_err(arizona->dev, "Device failed initial boot: %d\n", ret);
1035 goto err_reset;
817 } 1036 }
818 1037
819 /* Read the device ID information & do device specific stuff */ 1038 /* Read the device ID information & do device specific stuff */
@@ -891,14 +1110,24 @@ int arizona_dev_init(struct arizona *arizona)
891 1110
892 switch (arizona->type) { 1111 switch (arizona->type) {
893 case WM5102: 1112 case WM5102:
894 ret = arizona_apply_hardware_patch(arizona); 1113 ret = wm5102_apply_hardware_patch(arizona);
895 if (ret != 0) { 1114 if (ret) {
896 dev_err(arizona->dev, 1115 dev_err(arizona->dev,
897 "Failed to apply hardware patch: %d\n", 1116 "Failed to apply hardware patch: %d\n",
898 ret); 1117 ret);
899 goto err_reset; 1118 goto err_reset;
900 } 1119 }
901 break; 1120 break;
1121 case WM5110:
1122 case WM8280:
1123 ret = wm5110_apply_sleep_patch(arizona);
1124 if (ret) {
1125 dev_err(arizona->dev,
1126 "Failed to apply sleep patch: %d\n",
1127 ret);
1128 goto err_reset;
1129 }
1130 break;
902 default: 1131 default:
903 break; 1132 break;
904 } 1133 }
@@ -977,12 +1206,16 @@ int arizona_dev_init(struct arizona *arizona)
977 /* Default for both is 0 so noop with defaults */ 1206 /* Default for both is 0 so noop with defaults */
978 val = arizona->pdata.dmic_ref[i] 1207 val = arizona->pdata.dmic_ref[i]
979 << ARIZONA_IN1_DMIC_SUP_SHIFT; 1208 << ARIZONA_IN1_DMIC_SUP_SHIFT;
980 val |= arizona->pdata.inmode[i] << ARIZONA_IN1_MODE_SHIFT; 1209 if (arizona->pdata.inmode[i] & ARIZONA_INMODE_DMIC)
1210 val |= 1 << ARIZONA_IN1_MODE_SHIFT;
1211 if (arizona->pdata.inmode[i] & ARIZONA_INMODE_SE)
1212 val |= 1 << ARIZONA_IN1_SINGLE_ENDED_SHIFT;
981 1213
982 regmap_update_bits(arizona->regmap, 1214 regmap_update_bits(arizona->regmap,
983 ARIZONA_IN1L_CONTROL + (i * 8), 1215 ARIZONA_IN1L_CONTROL + (i * 8),
984 ARIZONA_IN1_DMIC_SUP_MASK | 1216 ARIZONA_IN1_DMIC_SUP_MASK |
985 ARIZONA_IN1_MODE_MASK, val); 1217 ARIZONA_IN1_MODE_MASK |
1218 ARIZONA_IN1_SINGLE_ENDED_MASK, val);
986 } 1219 }
987 1220
988 for (i = 0; i < ARIZONA_MAX_OUTPUT; i++) { 1221 for (i = 0; i < ARIZONA_MAX_OUTPUT; i++) {
@@ -1054,10 +1287,7 @@ int arizona_dev_init(struct arizona *arizona)
1054err_irq: 1287err_irq:
1055 arizona_irq_exit(arizona); 1288 arizona_irq_exit(arizona);
1056err_reset: 1289err_reset:
1057 if (arizona->pdata.reset) { 1290 arizona_enable_reset(arizona);
1058 gpio_set_value_cansleep(arizona->pdata.reset, 0);
1059 gpio_free(arizona->pdata.reset);
1060 }
1061 regulator_disable(arizona->dcvdd); 1291 regulator_disable(arizona->dcvdd);
1062err_enable: 1292err_enable:
1063 regulator_bulk_disable(arizona->num_core_supplies, 1293 regulator_bulk_disable(arizona->num_core_supplies,
@@ -1082,8 +1312,7 @@ int arizona_dev_exit(struct arizona *arizona)
1082 arizona_free_irq(arizona, ARIZONA_IRQ_OVERCLOCKED, arizona); 1312 arizona_free_irq(arizona, ARIZONA_IRQ_OVERCLOCKED, arizona);
1083 arizona_free_irq(arizona, ARIZONA_IRQ_CLKGEN_ERR, arizona); 1313 arizona_free_irq(arizona, ARIZONA_IRQ_CLKGEN_ERR, arizona);
1084 arizona_irq_exit(arizona); 1314 arizona_irq_exit(arizona);
1085 if (arizona->pdata.reset) 1315 arizona_enable_reset(arizona);
1086 gpio_set_value_cansleep(arizona->pdata.reset, 0);
1087 1316
1088 regulator_bulk_disable(arizona->num_core_supplies, 1317 regulator_bulk_disable(arizona->num_core_supplies,
1089 arizona->core_supplies); 1318 arizona->core_supplies);
diff --git a/drivers/mfd/arizona-irq.c b/drivers/mfd/arizona-irq.c
index d063b94b94b5..2b9965d53e4e 100644
--- a/drivers/mfd/arizona-irq.c
+++ b/drivers/mfd/arizona-irq.c
@@ -186,7 +186,7 @@ static int arizona_irq_map(struct irq_domain *h, unsigned int virq,
186 return 0; 186 return 0;
187} 187}
188 188
189static struct irq_domain_ops arizona_domain_ops = { 189static const struct irq_domain_ops arizona_domain_ops = {
190 .map = arizona_irq_map, 190 .map = arizona_irq_map,
191 .xlate = irq_domain_xlate_twocell, 191 .xlate = irq_domain_xlate_twocell,
192}; 192};
diff --git a/drivers/mfd/axp20x.c b/drivers/mfd/axp20x.c
index d18029be6a78..6df91556faf3 100644
--- a/drivers/mfd/axp20x.c
+++ b/drivers/mfd/axp20x.c
@@ -32,6 +32,7 @@
32static const char * const axp20x_model_names[] = { 32static const char * const axp20x_model_names[] = {
33 "AXP202", 33 "AXP202",
34 "AXP209", 34 "AXP209",
35 "AXP221",
35 "AXP288", 36 "AXP288",
36}; 37};
37 38
@@ -54,6 +55,25 @@ static const struct regmap_access_table axp20x_volatile_table = {
54 .n_yes_ranges = ARRAY_SIZE(axp20x_volatile_ranges), 55 .n_yes_ranges = ARRAY_SIZE(axp20x_volatile_ranges),
55}; 56};
56 57
58static const struct regmap_range axp22x_writeable_ranges[] = {
59 regmap_reg_range(AXP20X_DATACACHE(0), AXP20X_IRQ5_STATE),
60 regmap_reg_range(AXP20X_DCDC_MODE, AXP22X_BATLOW_THRES1),
61};
62
63static const struct regmap_range axp22x_volatile_ranges[] = {
64 regmap_reg_range(AXP20X_IRQ1_EN, AXP20X_IRQ5_STATE),
65};
66
67static const struct regmap_access_table axp22x_writeable_table = {
68 .yes_ranges = axp22x_writeable_ranges,
69 .n_yes_ranges = ARRAY_SIZE(axp22x_writeable_ranges),
70};
71
72static const struct regmap_access_table axp22x_volatile_table = {
73 .yes_ranges = axp22x_volatile_ranges,
74 .n_yes_ranges = ARRAY_SIZE(axp22x_volatile_ranges),
75};
76
57static const struct regmap_range axp288_writeable_ranges[] = { 77static const struct regmap_range axp288_writeable_ranges[] = {
58 regmap_reg_range(AXP20X_DATACACHE(0), AXP20X_IRQ6_STATE), 78 regmap_reg_range(AXP20X_DATACACHE(0), AXP20X_IRQ6_STATE),
59 regmap_reg_range(AXP20X_DCDC_MODE, AXP288_FG_TUNE5), 79 regmap_reg_range(AXP20X_DCDC_MODE, AXP288_FG_TUNE5),
@@ -87,6 +107,20 @@ static struct resource axp20x_pek_resources[] = {
87 }, 107 },
88}; 108};
89 109
110static struct resource axp22x_pek_resources[] = {
111 {
112 .name = "PEK_DBR",
113 .start = AXP22X_IRQ_PEK_RIS_EDGE,
114 .end = AXP22X_IRQ_PEK_RIS_EDGE,
115 .flags = IORESOURCE_IRQ,
116 }, {
117 .name = "PEK_DBF",
118 .start = AXP22X_IRQ_PEK_FAL_EDGE,
119 .end = AXP22X_IRQ_PEK_FAL_EDGE,
120 .flags = IORESOURCE_IRQ,
121 },
122};
123
90static struct resource axp288_fuel_gauge_resources[] = { 124static struct resource axp288_fuel_gauge_resources[] = {
91 { 125 {
92 .start = AXP288_IRQ_QWBTU, 126 .start = AXP288_IRQ_QWBTU,
@@ -129,6 +163,15 @@ static const struct regmap_config axp20x_regmap_config = {
129 .cache_type = REGCACHE_RBTREE, 163 .cache_type = REGCACHE_RBTREE,
130}; 164};
131 165
166static const struct regmap_config axp22x_regmap_config = {
167 .reg_bits = 8,
168 .val_bits = 8,
169 .wr_table = &axp22x_writeable_table,
170 .volatile_table = &axp22x_volatile_table,
171 .max_register = AXP22X_BATLOW_THRES1,
172 .cache_type = REGCACHE_RBTREE,
173};
174
132static const struct regmap_config axp288_regmap_config = { 175static const struct regmap_config axp288_regmap_config = {
133 .reg_bits = 8, 176 .reg_bits = 8,
134 .val_bits = 8, 177 .val_bits = 8,
@@ -181,6 +224,34 @@ static const struct regmap_irq axp20x_regmap_irqs[] = {
181 INIT_REGMAP_IRQ(AXP20X, GPIO0_INPUT, 4, 0), 224 INIT_REGMAP_IRQ(AXP20X, GPIO0_INPUT, 4, 0),
182}; 225};
183 226
227static const struct regmap_irq axp22x_regmap_irqs[] = {
228 INIT_REGMAP_IRQ(AXP22X, ACIN_OVER_V, 0, 7),
229 INIT_REGMAP_IRQ(AXP22X, ACIN_PLUGIN, 0, 6),
230 INIT_REGMAP_IRQ(AXP22X, ACIN_REMOVAL, 0, 5),
231 INIT_REGMAP_IRQ(AXP22X, VBUS_OVER_V, 0, 4),
232 INIT_REGMAP_IRQ(AXP22X, VBUS_PLUGIN, 0, 3),
233 INIT_REGMAP_IRQ(AXP22X, VBUS_REMOVAL, 0, 2),
234 INIT_REGMAP_IRQ(AXP22X, VBUS_V_LOW, 0, 1),
235 INIT_REGMAP_IRQ(AXP22X, BATT_PLUGIN, 1, 7),
236 INIT_REGMAP_IRQ(AXP22X, BATT_REMOVAL, 1, 6),
237 INIT_REGMAP_IRQ(AXP22X, BATT_ENT_ACT_MODE, 1, 5),
238 INIT_REGMAP_IRQ(AXP22X, BATT_EXIT_ACT_MODE, 1, 4),
239 INIT_REGMAP_IRQ(AXP22X, CHARG, 1, 3),
240 INIT_REGMAP_IRQ(AXP22X, CHARG_DONE, 1, 2),
241 INIT_REGMAP_IRQ(AXP22X, BATT_TEMP_HIGH, 1, 1),
242 INIT_REGMAP_IRQ(AXP22X, BATT_TEMP_LOW, 1, 0),
243 INIT_REGMAP_IRQ(AXP22X, DIE_TEMP_HIGH, 2, 7),
244 INIT_REGMAP_IRQ(AXP22X, PEK_SHORT, 2, 1),
245 INIT_REGMAP_IRQ(AXP22X, PEK_LONG, 2, 0),
246 INIT_REGMAP_IRQ(AXP22X, LOW_PWR_LVL1, 3, 1),
247 INIT_REGMAP_IRQ(AXP22X, LOW_PWR_LVL2, 3, 0),
248 INIT_REGMAP_IRQ(AXP22X, TIMER, 4, 7),
249 INIT_REGMAP_IRQ(AXP22X, PEK_RIS_EDGE, 4, 6),
250 INIT_REGMAP_IRQ(AXP22X, PEK_FAL_EDGE, 4, 5),
251 INIT_REGMAP_IRQ(AXP22X, GPIO1_INPUT, 4, 1),
252 INIT_REGMAP_IRQ(AXP22X, GPIO0_INPUT, 4, 0),
253};
254
184/* some IRQs are compatible with axp20x models */ 255/* some IRQs are compatible with axp20x models */
185static const struct regmap_irq axp288_regmap_irqs[] = { 256static const struct regmap_irq axp288_regmap_irqs[] = {
186 INIT_REGMAP_IRQ(AXP288, VBUS_FALL, 0, 2), 257 INIT_REGMAP_IRQ(AXP288, VBUS_FALL, 0, 2),
@@ -224,6 +295,7 @@ static const struct regmap_irq axp288_regmap_irqs[] = {
224static const struct of_device_id axp20x_of_match[] = { 295static const struct of_device_id axp20x_of_match[] = {
225 { .compatible = "x-powers,axp202", .data = (void *) AXP202_ID }, 296 { .compatible = "x-powers,axp202", .data = (void *) AXP202_ID },
226 { .compatible = "x-powers,axp209", .data = (void *) AXP209_ID }, 297 { .compatible = "x-powers,axp209", .data = (void *) AXP209_ID },
298 { .compatible = "x-powers,axp221", .data = (void *) AXP221_ID },
227 { }, 299 { },
228}; 300};
229MODULE_DEVICE_TABLE(of, axp20x_of_match); 301MODULE_DEVICE_TABLE(of, axp20x_of_match);
@@ -258,6 +330,18 @@ static const struct regmap_irq_chip axp20x_regmap_irq_chip = {
258 330
259}; 331};
260 332
333static const struct regmap_irq_chip axp22x_regmap_irq_chip = {
334 .name = "axp22x_irq_chip",
335 .status_base = AXP20X_IRQ1_STATE,
336 .ack_base = AXP20X_IRQ1_STATE,
337 .mask_base = AXP20X_IRQ1_EN,
338 .mask_invert = true,
339 .init_ack_masked = true,
340 .irqs = axp22x_regmap_irqs,
341 .num_irqs = ARRAY_SIZE(axp22x_regmap_irqs),
342 .num_regs = 5,
343};
344
261static const struct regmap_irq_chip axp288_regmap_irq_chip = { 345static const struct regmap_irq_chip axp288_regmap_irq_chip = {
262 .name = "axp288_irq_chip", 346 .name = "axp288_irq_chip",
263 .status_base = AXP20X_IRQ1_STATE, 347 .status_base = AXP20X_IRQ1_STATE,
@@ -281,6 +365,16 @@ static struct mfd_cell axp20x_cells[] = {
281 }, 365 },
282}; 366};
283 367
368static struct mfd_cell axp22x_cells[] = {
369 {
370 .name = "axp20x-pek",
371 .num_resources = ARRAY_SIZE(axp22x_pek_resources),
372 .resources = axp22x_pek_resources,
373 }, {
374 .name = "axp20x-regulator",
375 },
376};
377
284static struct resource axp288_adc_resources[] = { 378static struct resource axp288_adc_resources[] = {
285 { 379 {
286 .name = "GPADC", 380 .name = "GPADC",
@@ -426,6 +520,12 @@ static int axp20x_match_device(struct axp20x_dev *axp20x, struct device *dev)
426 axp20x->regmap_cfg = &axp20x_regmap_config; 520 axp20x->regmap_cfg = &axp20x_regmap_config;
427 axp20x->regmap_irq_chip = &axp20x_regmap_irq_chip; 521 axp20x->regmap_irq_chip = &axp20x_regmap_irq_chip;
428 break; 522 break;
523 case AXP221_ID:
524 axp20x->nr_cells = ARRAY_SIZE(axp22x_cells);
525 axp20x->cells = axp22x_cells;
526 axp20x->regmap_cfg = &axp22x_regmap_config;
527 axp20x->regmap_irq_chip = &axp22x_regmap_irq_chip;
528 break;
429 case AXP288_ID: 529 case AXP288_ID:
430 axp20x->cells = axp288_cells; 530 axp20x->cells = axp288_cells;
431 axp20x->nr_cells = ARRAY_SIZE(axp288_cells); 531 axp20x->nr_cells = ARRAY_SIZE(axp288_cells);
diff --git a/drivers/mfd/cros_ec.c b/drivers/mfd/cros_ec.c
index c4aecc6f8373..0eee63542038 100644
--- a/drivers/mfd/cros_ec.c
+++ b/drivers/mfd/cros_ec.c
@@ -17,111 +17,36 @@
17 * battery charging and regulator control, firmware update. 17 * battery charging and regulator control, firmware update.
18 */ 18 */
19 19
20#include <linux/of_platform.h>
20#include <linux/interrupt.h> 21#include <linux/interrupt.h>
21#include <linux/slab.h> 22#include <linux/slab.h>
22#include <linux/module.h> 23#include <linux/module.h>
23#include <linux/mfd/core.h> 24#include <linux/mfd/core.h>
24#include <linux/mfd/cros_ec.h> 25#include <linux/mfd/cros_ec.h>
25#include <linux/mfd/cros_ec_commands.h>
26#include <linux/delay.h>
27 26
28#define EC_COMMAND_RETRIES 50 27#define CROS_EC_DEV_EC_INDEX 0
28#define CROS_EC_DEV_PD_INDEX 1
29 29
30int cros_ec_prepare_tx(struct cros_ec_device *ec_dev, 30static struct cros_ec_platform ec_p = {
31 struct cros_ec_command *msg) 31 .ec_name = CROS_EC_DEV_NAME,
32{ 32 .cmd_offset = EC_CMD_PASSTHRU_OFFSET(CROS_EC_DEV_EC_INDEX),
33 uint8_t *out; 33};
34 int csum, i;
35
36 BUG_ON(msg->outsize > EC_PROTO2_MAX_PARAM_SIZE);
37 out = ec_dev->dout;
38 out[0] = EC_CMD_VERSION0 + msg->version;
39 out[1] = msg->command;
40 out[2] = msg->outsize;
41 csum = out[0] + out[1] + out[2];
42 for (i = 0; i < msg->outsize; i++)
43 csum += out[EC_MSG_TX_HEADER_BYTES + i] = msg->outdata[i];
44 out[EC_MSG_TX_HEADER_BYTES + msg->outsize] = (uint8_t)(csum & 0xff);
45
46 return EC_MSG_TX_PROTO_BYTES + msg->outsize;
47}
48EXPORT_SYMBOL(cros_ec_prepare_tx);
49
50int cros_ec_check_result(struct cros_ec_device *ec_dev,
51 struct cros_ec_command *msg)
52{
53 switch (msg->result) {
54 case EC_RES_SUCCESS:
55 return 0;
56 case EC_RES_IN_PROGRESS:
57 dev_dbg(ec_dev->dev, "command 0x%02x in progress\n",
58 msg->command);
59 return -EAGAIN;
60 default:
61 dev_dbg(ec_dev->dev, "command 0x%02x returned %d\n",
62 msg->command, msg->result);
63 return 0;
64 }
65}
66EXPORT_SYMBOL(cros_ec_check_result);
67
68int cros_ec_cmd_xfer(struct cros_ec_device *ec_dev,
69 struct cros_ec_command *msg)
70{
71 int ret;
72
73 mutex_lock(&ec_dev->lock);
74 ret = ec_dev->cmd_xfer(ec_dev, msg);
75 if (msg->result == EC_RES_IN_PROGRESS) {
76 int i;
77 struct cros_ec_command status_msg = { };
78 struct ec_response_get_comms_status *status;
79
80 status_msg.command = EC_CMD_GET_COMMS_STATUS;
81 status_msg.insize = sizeof(*status);
82
83 /*
84 * Query the EC's status until it's no longer busy or
85 * we encounter an error.
86 */
87 for (i = 0; i < EC_COMMAND_RETRIES; i++) {
88 usleep_range(10000, 11000);
89
90 ret = ec_dev->cmd_xfer(ec_dev, &status_msg);
91 if (ret < 0)
92 break;
93 34
94 msg->result = status_msg.result; 35static struct cros_ec_platform pd_p = {
95 if (status_msg.result != EC_RES_SUCCESS) 36 .ec_name = CROS_EC_DEV_PD_NAME,
96 break; 37 .cmd_offset = EC_CMD_PASSTHRU_OFFSET(CROS_EC_DEV_PD_INDEX),
38};
97 39
98 status = (struct ec_response_get_comms_status *) 40static const struct mfd_cell ec_cell = {
99 status_msg.indata; 41 .name = "cros-ec-ctl",
100 if (!(status->flags & EC_COMMS_STATUS_PROCESSING)) 42 .platform_data = &ec_p,
101 break; 43 .pdata_size = sizeof(ec_p),
102 } 44};
103 }
104 mutex_unlock(&ec_dev->lock);
105 45
106 return ret; 46static const struct mfd_cell ec_pd_cell = {
107} 47 .name = "cros-ec-ctl",
108EXPORT_SYMBOL(cros_ec_cmd_xfer); 48 .platform_data = &pd_p,
109 49 .pdata_size = sizeof(pd_p),
110static const struct mfd_cell cros_devs[] = {
111 {
112 .name = "cros-ec-keyb",
113 .id = 1,
114 .of_compatible = "google,cros-ec-keyb",
115 },
116 {
117 .name = "cros-ec-i2c-tunnel",
118 .id = 2,
119 .of_compatible = "google,cros-ec-i2c-tunnel",
120 },
121 {
122 .name = "cros-ec-ctl",
123 .id = 3,
124 },
125}; 50};
126 51
127int cros_ec_register(struct cros_ec_device *ec_dev) 52int cros_ec_register(struct cros_ec_device *ec_dev)
@@ -129,27 +54,59 @@ int cros_ec_register(struct cros_ec_device *ec_dev)
129 struct device *dev = ec_dev->dev; 54 struct device *dev = ec_dev->dev;
130 int err = 0; 55 int err = 0;
131 56
132 if (ec_dev->din_size) { 57 ec_dev->max_request = sizeof(struct ec_params_hello);
133 ec_dev->din = devm_kzalloc(dev, ec_dev->din_size, GFP_KERNEL); 58 ec_dev->max_response = sizeof(struct ec_response_get_protocol_info);
134 if (!ec_dev->din) 59 ec_dev->max_passthru = 0;
135 return -ENOMEM; 60
136 } 61 ec_dev->din = devm_kzalloc(dev, ec_dev->din_size, GFP_KERNEL);
137 if (ec_dev->dout_size) { 62 if (!ec_dev->din)
138 ec_dev->dout = devm_kzalloc(dev, ec_dev->dout_size, GFP_KERNEL); 63 return -ENOMEM;
139 if (!ec_dev->dout) 64
140 return -ENOMEM; 65 ec_dev->dout = devm_kzalloc(dev, ec_dev->dout_size, GFP_KERNEL);
141 } 66 if (!ec_dev->dout)
67 return -ENOMEM;
142 68
143 mutex_init(&ec_dev->lock); 69 mutex_init(&ec_dev->lock);
144 70
145 err = mfd_add_devices(dev, 0, cros_devs, 71 cros_ec_query_all(ec_dev);
146 ARRAY_SIZE(cros_devs), 72
73 err = mfd_add_devices(ec_dev->dev, PLATFORM_DEVID_AUTO, &ec_cell, 1,
147 NULL, ec_dev->irq, NULL); 74 NULL, ec_dev->irq, NULL);
148 if (err) { 75 if (err) {
149 dev_err(dev, "failed to add mfd devices\n"); 76 dev_err(dev,
77 "Failed to register Embedded Controller subdevice %d\n",
78 err);
150 return err; 79 return err;
151 } 80 }
152 81
82 if (ec_dev->max_passthru) {
83 /*
84 * Register a PD device as well on top of this device.
85 * We make the following assumptions:
86 * - behind an EC, we have a pd
87 * - only one device added.
88 * - the EC is responsive at init time (it is not true for a
89 * sensor hub.
90 */
91 err = mfd_add_devices(ec_dev->dev, PLATFORM_DEVID_AUTO,
92 &ec_pd_cell, 1, NULL, ec_dev->irq, NULL);
93 if (err) {
94 dev_err(dev,
95 "Failed to register Power Delivery subdevice %d\n",
96 err);
97 return err;
98 }
99 }
100
101 if (IS_ENABLED(CONFIG_OF) && dev->of_node) {
102 err = of_platform_populate(dev->of_node, NULL, NULL, dev);
103 if (err) {
104 mfd_remove_devices(dev);
105 dev_err(dev, "Failed to register sub-devices\n");
106 return err;
107 }
108 }
109
153 dev_info(dev, "Chrome EC device registered\n"); 110 dev_info(dev, "Chrome EC device registered\n");
154 111
155 return 0; 112 return 0;
diff --git a/drivers/mfd/cros_ec_i2c.c b/drivers/mfd/cros_ec_i2c.c
index c0c30f4f946f..b9a0963ca5c3 100644
--- a/drivers/mfd/cros_ec_i2c.c
+++ b/drivers/mfd/cros_ec_i2c.c
@@ -13,6 +13,7 @@
13 * GNU General Public License for more details. 13 * GNU General Public License for more details.
14 */ 14 */
15 15
16#include <linux/delay.h>
16#include <linux/kernel.h> 17#include <linux/kernel.h>
17#include <linux/module.h> 18#include <linux/module.h>
18#include <linux/i2c.h> 19#include <linux/i2c.h>
@@ -22,6 +23,32 @@
22#include <linux/platform_device.h> 23#include <linux/platform_device.h>
23#include <linux/slab.h> 24#include <linux/slab.h>
24 25
26/**
27 * Request format for protocol v3
28 * byte 0 0xda (EC_COMMAND_PROTOCOL_3)
29 * byte 1-8 struct ec_host_request
30 * byte 10- response data
31 */
32struct ec_host_request_i2c {
33 /* Always 0xda to backward compatible with v2 struct */
34 uint8_t command_protocol;
35 struct ec_host_request ec_request;
36} __packed;
37
38
39/*
40 * Response format for protocol v3
41 * byte 0 result code
42 * byte 1 packet_length
43 * byte 2-9 struct ec_host_response
44 * byte 10- response data
45 */
46struct ec_host_response_i2c {
47 uint8_t result;
48 uint8_t packet_length;
49 struct ec_host_response ec_response;
50} __packed;
51
25static inline struct cros_ec_device *to_ec_dev(struct device *dev) 52static inline struct cros_ec_device *to_ec_dev(struct device *dev)
26{ 53{
27 struct i2c_client *client = to_i2c_client(dev); 54 struct i2c_client *client = to_i2c_client(dev);
@@ -29,6 +56,134 @@ static inline struct cros_ec_device *to_ec_dev(struct device *dev)
29 return i2c_get_clientdata(client); 56 return i2c_get_clientdata(client);
30} 57}
31 58
59static int cros_ec_pkt_xfer_i2c(struct cros_ec_device *ec_dev,
60 struct cros_ec_command *msg)
61{
62 struct i2c_client *client = ec_dev->priv;
63 int ret = -ENOMEM;
64 int i;
65 int packet_len;
66 u8 *out_buf = NULL;
67 u8 *in_buf = NULL;
68 u8 sum;
69 struct i2c_msg i2c_msg[2];
70 struct ec_host_response *ec_response;
71 struct ec_host_request_i2c *ec_request_i2c;
72 struct ec_host_response_i2c *ec_response_i2c;
73 int request_header_size = sizeof(struct ec_host_request_i2c);
74 int response_header_size = sizeof(struct ec_host_response_i2c);
75
76 i2c_msg[0].addr = client->addr;
77 i2c_msg[0].flags = 0;
78 i2c_msg[1].addr = client->addr;
79 i2c_msg[1].flags = I2C_M_RD;
80
81 packet_len = msg->insize + response_header_size;
82 BUG_ON(packet_len > ec_dev->din_size);
83 in_buf = ec_dev->din;
84 i2c_msg[1].len = packet_len;
85 i2c_msg[1].buf = (char *) in_buf;
86
87 packet_len = msg->outsize + request_header_size;
88 BUG_ON(packet_len > ec_dev->dout_size);
89 out_buf = ec_dev->dout;
90 i2c_msg[0].len = packet_len;
91 i2c_msg[0].buf = (char *) out_buf;
92
93 /* create request data */
94 ec_request_i2c = (struct ec_host_request_i2c *) out_buf;
95 ec_request_i2c->command_protocol = EC_COMMAND_PROTOCOL_3;
96
97 ec_dev->dout++;
98 ret = cros_ec_prepare_tx(ec_dev, msg);
99 ec_dev->dout--;
100
101 /* send command to EC and read answer */
102 ret = i2c_transfer(client->adapter, i2c_msg, 2);
103 if (ret < 0) {
104 dev_dbg(ec_dev->dev, "i2c transfer failed: %d\n", ret);
105 goto done;
106 } else if (ret != 2) {
107 dev_err(ec_dev->dev, "failed to get response: %d\n", ret);
108 ret = -EIO;
109 goto done;
110 }
111
112 ec_response_i2c = (struct ec_host_response_i2c *) in_buf;
113 msg->result = ec_response_i2c->result;
114 ec_response = &ec_response_i2c->ec_response;
115
116 switch (msg->result) {
117 case EC_RES_SUCCESS:
118 break;
119 case EC_RES_IN_PROGRESS:
120 ret = -EAGAIN;
121 dev_dbg(ec_dev->dev, "command 0x%02x in progress\n",
122 msg->command);
123 goto done;
124
125 default:
126 dev_dbg(ec_dev->dev, "command 0x%02x returned %d\n",
127 msg->command, msg->result);
128 /*
129 * When we send v3 request to v2 ec, ec won't recognize the
130 * 0xda (EC_COMMAND_PROTOCOL_3) and will return with status
131 * EC_RES_INVALID_COMMAND with zero data length.
132 *
133 * In case of invalid command for v3 protocol the data length
134 * will be at least sizeof(struct ec_host_response)
135 */
136 if (ec_response_i2c->result == EC_RES_INVALID_COMMAND &&
137 ec_response_i2c->packet_length == 0) {
138 ret = -EPROTONOSUPPORT;
139 goto done;
140 }
141 }
142
143 if (ec_response_i2c->packet_length < sizeof(struct ec_host_response)) {
144 dev_err(ec_dev->dev,
145 "response of %u bytes too short; not a full header\n",
146 ec_response_i2c->packet_length);
147 ret = -EBADMSG;
148 goto done;
149 }
150
151 if (msg->insize < ec_response->data_len) {
152 dev_err(ec_dev->dev,
153 "response data size is too large: expected %u, got %u\n",
154 msg->insize,
155 ec_response->data_len);
156 ret = -EMSGSIZE;
157 goto done;
158 }
159
160 /* copy response packet payload and compute checksum */
161 sum = 0;
162 for (i = 0; i < sizeof(struct ec_host_response); i++)
163 sum += ((u8 *)ec_response)[i];
164
165 memcpy(msg->data,
166 in_buf + response_header_size,
167 ec_response->data_len);
168 for (i = 0; i < ec_response->data_len; i++)
169 sum += msg->data[i];
170
171 /* All bytes should sum to zero */
172 if (sum) {
173 dev_err(ec_dev->dev, "bad packet checksum\n");
174 ret = -EBADMSG;
175 goto done;
176 }
177
178 ret = ec_response->data_len;
179
180done:
181 if (msg->command == EC_CMD_REBOOT_EC)
182 msleep(EC_REBOOT_DELAY_MS);
183
184 return ret;
185}
186
32static int cros_ec_cmd_xfer_i2c(struct cros_ec_device *ec_dev, 187static int cros_ec_cmd_xfer_i2c(struct cros_ec_device *ec_dev,
33 struct cros_ec_command *msg) 188 struct cros_ec_command *msg)
34{ 189{
@@ -76,7 +231,7 @@ static int cros_ec_cmd_xfer_i2c(struct cros_ec_device *ec_dev,
76 /* copy message payload and compute checksum */ 231 /* copy message payload and compute checksum */
77 sum = out_buf[0] + out_buf[1] + out_buf[2]; 232 sum = out_buf[0] + out_buf[1] + out_buf[2];
78 for (i = 0; i < msg->outsize; i++) { 233 for (i = 0; i < msg->outsize; i++) {
79 out_buf[3 + i] = msg->outdata[i]; 234 out_buf[3 + i] = msg->data[i];
80 sum += out_buf[3 + i]; 235 sum += out_buf[3 + i];
81 } 236 }
82 out_buf[3 + msg->outsize] = sum; 237 out_buf[3 + msg->outsize] = sum;
@@ -109,7 +264,7 @@ static int cros_ec_cmd_xfer_i2c(struct cros_ec_device *ec_dev,
109 /* copy response packet payload and compute checksum */ 264 /* copy response packet payload and compute checksum */
110 sum = in_buf[0] + in_buf[1]; 265 sum = in_buf[0] + in_buf[1];
111 for (i = 0; i < len; i++) { 266 for (i = 0; i < len; i++) {
112 msg->indata[i] = in_buf[2 + i]; 267 msg->data[i] = in_buf[2 + i];
113 sum += in_buf[2 + i]; 268 sum += in_buf[2 + i];
114 } 269 }
115 dev_dbg(ec_dev->dev, "packet: %*ph, sum = %02x\n", 270 dev_dbg(ec_dev->dev, "packet: %*ph, sum = %02x\n",
@@ -121,9 +276,12 @@ static int cros_ec_cmd_xfer_i2c(struct cros_ec_device *ec_dev,
121 } 276 }
122 277
123 ret = len; 278 ret = len;
124 done: 279done:
125 kfree(in_buf); 280 kfree(in_buf);
126 kfree(out_buf); 281 kfree(out_buf);
282 if (msg->command == EC_CMD_REBOOT_EC)
283 msleep(EC_REBOOT_DELAY_MS);
284
127 return ret; 285 return ret;
128} 286}
129 287
@@ -143,9 +301,11 @@ static int cros_ec_i2c_probe(struct i2c_client *client,
143 ec_dev->priv = client; 301 ec_dev->priv = client;
144 ec_dev->irq = client->irq; 302 ec_dev->irq = client->irq;
145 ec_dev->cmd_xfer = cros_ec_cmd_xfer_i2c; 303 ec_dev->cmd_xfer = cros_ec_cmd_xfer_i2c;
146 ec_dev->ec_name = client->name; 304 ec_dev->pkt_xfer = cros_ec_pkt_xfer_i2c;
147 ec_dev->phys_name = client->adapter->name; 305 ec_dev->phys_name = client->adapter->name;
148 ec_dev->parent = &client->dev; 306 ec_dev->din_size = sizeof(struct ec_host_response_i2c) +
307 sizeof(struct ec_response_get_protocol_info);
308 ec_dev->dout_size = sizeof(struct ec_host_request_i2c);
149 309
150 err = cros_ec_register(ec_dev); 310 err = cros_ec_register(ec_dev);
151 if (err) { 311 if (err) {
diff --git a/drivers/mfd/cros_ec_spi.c b/drivers/mfd/cros_ec_spi.c
index bf6e08e8013e..16f228dc243f 100644
--- a/drivers/mfd/cros_ec_spi.c
+++ b/drivers/mfd/cros_ec_spi.c
@@ -65,29 +65,26 @@
65 */ 65 */
66#define EC_SPI_RECOVERY_TIME_NS (200 * 1000) 66#define EC_SPI_RECOVERY_TIME_NS (200 * 1000)
67 67
68/*
69 * The EC is unresponsive for a time after a reboot command. Add a
70 * simple delay to make sure that the bus stays locked.
71 */
72#define EC_REBOOT_DELAY_MS 50
73
74/** 68/**
75 * struct cros_ec_spi - information about a SPI-connected EC 69 * struct cros_ec_spi - information about a SPI-connected EC
76 * 70 *
77 * @spi: SPI device we are connected to 71 * @spi: SPI device we are connected to
78 * @last_transfer_ns: time that we last finished a transfer, or 0 if there 72 * @last_transfer_ns: time that we last finished a transfer, or 0 if there
79 * if no record 73 * if no record
74 * @start_of_msg_delay: used to set the delay_usecs on the spi_transfer that
75 * is sent when we want to turn on CS at the start of a transaction.
80 * @end_of_msg_delay: used to set the delay_usecs on the spi_transfer that 76 * @end_of_msg_delay: used to set the delay_usecs on the spi_transfer that
81 * is sent when we want to turn off CS at the end of a transaction. 77 * is sent when we want to turn off CS at the end of a transaction.
82 */ 78 */
83struct cros_ec_spi { 79struct cros_ec_spi {
84 struct spi_device *spi; 80 struct spi_device *spi;
85 s64 last_transfer_ns; 81 s64 last_transfer_ns;
82 unsigned int start_of_msg_delay;
86 unsigned int end_of_msg_delay; 83 unsigned int end_of_msg_delay;
87}; 84};
88 85
89static void debug_packet(struct device *dev, const char *name, u8 *ptr, 86static void debug_packet(struct device *dev, const char *name, u8 *ptr,
90 int len) 87 int len)
91{ 88{
92#ifdef DEBUG 89#ifdef DEBUG
93 int i; 90 int i;
@@ -100,6 +97,172 @@ static void debug_packet(struct device *dev, const char *name, u8 *ptr,
100#endif 97#endif
101} 98}
102 99
100static int terminate_request(struct cros_ec_device *ec_dev)
101{
102 struct cros_ec_spi *ec_spi = ec_dev->priv;
103 struct spi_message msg;
104 struct spi_transfer trans;
105 int ret;
106
107 /*
108 * Turn off CS, possibly adding a delay to ensure the rising edge
109 * doesn't come too soon after the end of the data.
110 */
111 spi_message_init(&msg);
112 memset(&trans, 0, sizeof(trans));
113 trans.delay_usecs = ec_spi->end_of_msg_delay;
114 spi_message_add_tail(&trans, &msg);
115
116 ret = spi_sync(ec_spi->spi, &msg);
117
118 /* Reset end-of-response timer */
119 ec_spi->last_transfer_ns = ktime_get_ns();
120 if (ret < 0) {
121 dev_err(ec_dev->dev,
122 "cs-deassert spi transfer failed: %d\n",
123 ret);
124 }
125
126 return ret;
127}
128
129/**
130 * receive_n_bytes - receive n bytes from the EC.
131 *
132 * Assumes buf is a pointer into the ec_dev->din buffer
133 */
134static int receive_n_bytes(struct cros_ec_device *ec_dev, u8 *buf, int n)
135{
136 struct cros_ec_spi *ec_spi = ec_dev->priv;
137 struct spi_transfer trans;
138 struct spi_message msg;
139 int ret;
140
141 BUG_ON(buf - ec_dev->din + n > ec_dev->din_size);
142
143 memset(&trans, 0, sizeof(trans));
144 trans.cs_change = 1;
145 trans.rx_buf = buf;
146 trans.len = n;
147
148 spi_message_init(&msg);
149 spi_message_add_tail(&trans, &msg);
150 ret = spi_sync(ec_spi->spi, &msg);
151 if (ret < 0)
152 dev_err(ec_dev->dev, "spi transfer failed: %d\n", ret);
153
154 return ret;
155}
156
157/**
158 * cros_ec_spi_receive_packet - Receive a packet from the EC.
159 *
160 * This function has two phases: reading the preamble bytes (since if we read
161 * data from the EC before it is ready to send, we just get preamble) and
162 * reading the actual message.
163 *
164 * The received data is placed into ec_dev->din.
165 *
166 * @ec_dev: ChromeOS EC device
167 * @need_len: Number of message bytes we need to read
168 */
169static int cros_ec_spi_receive_packet(struct cros_ec_device *ec_dev,
170 int need_len)
171{
172 struct ec_host_response *response;
173 u8 *ptr, *end;
174 int ret;
175 unsigned long deadline;
176 int todo;
177
178 BUG_ON(EC_MSG_PREAMBLE_COUNT > ec_dev->din_size);
179
180 /* Receive data until we see the header byte */
181 deadline = jiffies + msecs_to_jiffies(EC_MSG_DEADLINE_MS);
182 while (true) {
183 unsigned long start_jiffies = jiffies;
184
185 ret = receive_n_bytes(ec_dev,
186 ec_dev->din,
187 EC_MSG_PREAMBLE_COUNT);
188 if (ret < 0)
189 return ret;
190
191 ptr = ec_dev->din;
192 for (end = ptr + EC_MSG_PREAMBLE_COUNT; ptr != end; ptr++) {
193 if (*ptr == EC_SPI_FRAME_START) {
194 dev_dbg(ec_dev->dev, "msg found at %zd\n",
195 ptr - ec_dev->din);
196 break;
197 }
198 }
199 if (ptr != end)
200 break;
201
202 /*
203 * Use the time at the start of the loop as a timeout. This
204 * gives us one last shot at getting the transfer and is useful
205 * in case we got context switched out for a while.
206 */
207 if (time_after(start_jiffies, deadline)) {
208 dev_warn(ec_dev->dev, "EC failed to respond in time\n");
209 return -ETIMEDOUT;
210 }
211 }
212
213 /*
214 * ptr now points to the header byte. Copy any valid data to the
215 * start of our buffer
216 */
217 todo = end - ++ptr;
218 BUG_ON(todo < 0 || todo > ec_dev->din_size);
219 todo = min(todo, need_len);
220 memmove(ec_dev->din, ptr, todo);
221 ptr = ec_dev->din + todo;
222 dev_dbg(ec_dev->dev, "need %d, got %d bytes from preamble\n",
223 need_len, todo);
224 need_len -= todo;
225
226 /* If the entire response struct wasn't read, get the rest of it. */
227 if (todo < sizeof(*response)) {
228 ret = receive_n_bytes(ec_dev, ptr, sizeof(*response) - todo);
229 if (ret < 0)
230 return -EBADMSG;
231 ptr += (sizeof(*response) - todo);
232 todo = sizeof(*response);
233 }
234
235 response = (struct ec_host_response *)ec_dev->din;
236
237 /* Abort if data_len is too large. */
238 if (response->data_len > ec_dev->din_size)
239 return -EMSGSIZE;
240
241 /* Receive data until we have it all */
242 while (need_len > 0) {
243 /*
244 * We can't support transfers larger than the SPI FIFO size
245 * unless we have DMA. We don't have DMA on the ISP SPI ports
246 * for Exynos. We need a way of asking SPI driver for
247 * maximum-supported transfer size.
248 */
249 todo = min(need_len, 256);
250 dev_dbg(ec_dev->dev, "loop, todo=%d, need_len=%d, ptr=%zd\n",
251 todo, need_len, ptr - ec_dev->din);
252
253 ret = receive_n_bytes(ec_dev, ptr, todo);
254 if (ret < 0)
255 return ret;
256
257 ptr += todo;
258 need_len -= todo;
259 }
260
261 dev_dbg(ec_dev->dev, "loop done, ptr=%zd\n", ptr - ec_dev->din);
262
263 return 0;
264}
265
103/** 266/**
104 * cros_ec_spi_receive_response - Receive a response from the EC. 267 * cros_ec_spi_receive_response - Receive a response from the EC.
105 * 268 *
@@ -115,34 +278,27 @@ static void debug_packet(struct device *dev, const char *name, u8 *ptr,
115static int cros_ec_spi_receive_response(struct cros_ec_device *ec_dev, 278static int cros_ec_spi_receive_response(struct cros_ec_device *ec_dev,
116 int need_len) 279 int need_len)
117{ 280{
118 struct cros_ec_spi *ec_spi = ec_dev->priv;
119 struct spi_transfer trans;
120 struct spi_message msg;
121 u8 *ptr, *end; 281 u8 *ptr, *end;
122 int ret; 282 int ret;
123 unsigned long deadline; 283 unsigned long deadline;
124 int todo; 284 int todo;
125 285
286 BUG_ON(EC_MSG_PREAMBLE_COUNT > ec_dev->din_size);
287
126 /* Receive data until we see the header byte */ 288 /* Receive data until we see the header byte */
127 deadline = jiffies + msecs_to_jiffies(EC_MSG_DEADLINE_MS); 289 deadline = jiffies + msecs_to_jiffies(EC_MSG_DEADLINE_MS);
128 while (true) { 290 while (true) {
129 unsigned long start_jiffies = jiffies; 291 unsigned long start_jiffies = jiffies;
130 292
131 memset(&trans, 0, sizeof(trans)); 293 ret = receive_n_bytes(ec_dev,
132 trans.cs_change = 1; 294 ec_dev->din,
133 trans.rx_buf = ptr = ec_dev->din; 295 EC_MSG_PREAMBLE_COUNT);
134 trans.len = EC_MSG_PREAMBLE_COUNT; 296 if (ret < 0)
135
136 spi_message_init(&msg);
137 spi_message_add_tail(&trans, &msg);
138 ret = spi_sync(ec_spi->spi, &msg);
139 if (ret < 0) {
140 dev_err(ec_dev->dev, "spi transfer failed: %d\n", ret);
141 return ret; 297 return ret;
142 }
143 298
299 ptr = ec_dev->din;
144 for (end = ptr + EC_MSG_PREAMBLE_COUNT; ptr != end; ptr++) { 300 for (end = ptr + EC_MSG_PREAMBLE_COUNT; ptr != end; ptr++) {
145 if (*ptr == EC_MSG_HEADER) { 301 if (*ptr == EC_SPI_FRAME_START) {
146 dev_dbg(ec_dev->dev, "msg found at %zd\n", 302 dev_dbg(ec_dev->dev, "msg found at %zd\n",
147 ptr - ec_dev->din); 303 ptr - ec_dev->din);
148 break; 304 break;
@@ -187,21 +343,9 @@ static int cros_ec_spi_receive_response(struct cros_ec_device *ec_dev,
187 dev_dbg(ec_dev->dev, "loop, todo=%d, need_len=%d, ptr=%zd\n", 343 dev_dbg(ec_dev->dev, "loop, todo=%d, need_len=%d, ptr=%zd\n",
188 todo, need_len, ptr - ec_dev->din); 344 todo, need_len, ptr - ec_dev->din);
189 345
190 memset(&trans, 0, sizeof(trans)); 346 ret = receive_n_bytes(ec_dev, ptr, todo);
191 trans.cs_change = 1; 347 if (ret < 0)
192 trans.rx_buf = ptr;
193 trans.len = todo;
194 spi_message_init(&msg);
195 spi_message_add_tail(&trans, &msg);
196
197 /* send command to EC and read answer */
198 BUG_ON((u8 *)trans.rx_buf - ec_dev->din + todo >
199 ec_dev->din_size);
200 ret = spi_sync(ec_spi->spi, &msg);
201 if (ret < 0) {
202 dev_err(ec_dev->dev, "spi transfer failed: %d\n", ret);
203 return ret; 348 return ret;
204 }
205 349
206 debug_packet(ec_dev->dev, "interim", ptr, todo); 350 debug_packet(ec_dev->dev, "interim", ptr, todo);
207 ptr += todo; 351 ptr += todo;
@@ -214,6 +358,138 @@ static int cros_ec_spi_receive_response(struct cros_ec_device *ec_dev,
214} 358}
215 359
216/** 360/**
361 * cros_ec_pkt_xfer_spi - Transfer a packet over SPI and receive the reply
362 *
363 * @ec_dev: ChromeOS EC device
364 * @ec_msg: Message to transfer
365 */
366static int cros_ec_pkt_xfer_spi(struct cros_ec_device *ec_dev,
367 struct cros_ec_command *ec_msg)
368{
369 struct ec_host_request *request;
370 struct ec_host_response *response;
371 struct cros_ec_spi *ec_spi = ec_dev->priv;
372 struct spi_transfer trans, trans_delay;
373 struct spi_message msg;
374 int i, len;
375 u8 *ptr;
376 u8 *rx_buf;
377 u8 sum;
378 int ret = 0, final_ret;
379
380 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);
383
384 /* If it's too soon to do another transaction, wait */
385 if (ec_spi->last_transfer_ns) {
386 unsigned long delay; /* The delay completed so far */
387
388 delay = ktime_get_ns() - ec_spi->last_transfer_ns;
389 if (delay < EC_SPI_RECOVERY_TIME_NS)
390 ndelay(EC_SPI_RECOVERY_TIME_NS - delay);
391 }
392
393 rx_buf = kzalloc(len, GFP_KERNEL);
394 if (!rx_buf) {
395 ret = -ENOMEM;
396 goto exit;
397 }
398
399 /*
400 * Leave a gap between CS assertion and clocking of data to allow the
401 * EC time to wakeup.
402 */
403 spi_message_init(&msg);
404 if (ec_spi->start_of_msg_delay) {
405 memset(&trans_delay, 0, sizeof(trans_delay));
406 trans_delay.delay_usecs = ec_spi->start_of_msg_delay;
407 spi_message_add_tail(&trans_delay, &msg);
408 }
409
410 /* Transmit phase - send our message */
411 memset(&trans, 0, sizeof(trans));
412 trans.tx_buf = ec_dev->dout;
413 trans.rx_buf = rx_buf;
414 trans.len = len;
415 trans.cs_change = 1;
416 spi_message_add_tail(&trans, &msg);
417 ret = spi_sync(ec_spi->spi, &msg);
418
419 /* Get the response */
420 if (!ret) {
421 /* Verify that EC can process command */
422 for (i = 0; i < len; i++) {
423 switch (rx_buf[i]) {
424 case EC_SPI_PAST_END:
425 case EC_SPI_RX_BAD_DATA:
426 case EC_SPI_NOT_READY:
427 ret = -EAGAIN;
428 ec_msg->result = EC_RES_IN_PROGRESS;
429 default:
430 break;
431 }
432 if (ret)
433 break;
434 }
435 if (!ret)
436 ret = cros_ec_spi_receive_packet(ec_dev,
437 ec_msg->insize + sizeof(*response));
438 } else {
439 dev_err(ec_dev->dev, "spi transfer failed: %d\n", ret);
440 }
441
442 final_ret = terminate_request(ec_dev);
443 if (!ret)
444 ret = final_ret;
445 if (ret < 0)
446 goto exit;
447
448 ptr = ec_dev->din;
449
450 /* check response error code */
451 response = (struct ec_host_response *)ptr;
452 ec_msg->result = response->result;
453
454 ret = cros_ec_check_result(ec_dev, ec_msg);
455 if (ret)
456 goto exit;
457
458 len = response->data_len;
459 sum = 0;
460 if (len > ec_msg->insize) {
461 dev_err(ec_dev->dev, "packet too long (%d bytes, expected %d)",
462 len, ec_msg->insize);
463 ret = -EMSGSIZE;
464 goto exit;
465 }
466
467 for (i = 0; i < sizeof(*response); i++)
468 sum += ptr[i];
469
470 /* copy response packet payload and compute checksum */
471 memcpy(ec_msg->data, ptr + sizeof(*response), len);
472 for (i = 0; i < len; i++)
473 sum += ec_msg->data[i];
474
475 if (sum) {
476 dev_err(ec_dev->dev,
477 "bad packet checksum, calculated %x\n",
478 sum);
479 ret = -EBADMSG;
480 goto exit;
481 }
482
483 ret = len;
484exit:
485 kfree(rx_buf);
486 if (ec_msg->command == EC_CMD_REBOOT_EC)
487 msleep(EC_REBOOT_DELAY_MS);
488
489 return ret;
490}
491
492/**
217 * cros_ec_cmd_xfer_spi - Transfer a message over SPI and receive the reply 493 * cros_ec_cmd_xfer_spi - Transfer a message over SPI and receive the reply
218 * 494 *
219 * @ec_dev: ChromeOS EC device 495 * @ec_dev: ChromeOS EC device
@@ -227,6 +503,7 @@ static int cros_ec_cmd_xfer_spi(struct cros_ec_device *ec_dev,
227 struct spi_message msg; 503 struct spi_message msg;
228 int i, len; 504 int i, len;
229 u8 *ptr; 505 u8 *ptr;
506 u8 *rx_buf;
230 int sum; 507 int sum;
231 int ret = 0, final_ret; 508 int ret = 0, final_ret;
232 509
@@ -242,10 +519,17 @@ static int cros_ec_cmd_xfer_spi(struct cros_ec_device *ec_dev,
242 ndelay(EC_SPI_RECOVERY_TIME_NS - delay); 519 ndelay(EC_SPI_RECOVERY_TIME_NS - delay);
243 } 520 }
244 521
522 rx_buf = kzalloc(len, GFP_KERNEL);
523 if (!rx_buf) {
524 ret = -ENOMEM;
525 goto exit;
526 }
527
245 /* Transmit phase - send our message */ 528 /* Transmit phase - send our message */
246 debug_packet(ec_dev->dev, "out", ec_dev->dout, len); 529 debug_packet(ec_dev->dev, "out", ec_dev->dout, len);
247 memset(&trans, 0, sizeof(trans)); 530 memset(&trans, 0, sizeof(trans));
248 trans.tx_buf = ec_dev->dout; 531 trans.tx_buf = ec_dev->dout;
532 trans.rx_buf = rx_buf;
249 trans.len = len; 533 trans.len = len;
250 trans.cs_change = 1; 534 trans.cs_change = 1;
251 spi_message_init(&msg); 535 spi_message_init(&msg);
@@ -254,29 +538,32 @@ static int cros_ec_cmd_xfer_spi(struct cros_ec_device *ec_dev,
254 538
255 /* Get the response */ 539 /* Get the response */
256 if (!ret) { 540 if (!ret) {
257 ret = cros_ec_spi_receive_response(ec_dev, 541 /* Verify that EC can process command */
258 ec_msg->insize + EC_MSG_TX_PROTO_BYTES); 542 for (i = 0; i < len; i++) {
543 switch (rx_buf[i]) {
544 case EC_SPI_PAST_END:
545 case EC_SPI_RX_BAD_DATA:
546 case EC_SPI_NOT_READY:
547 ret = -EAGAIN;
548 ec_msg->result = EC_RES_IN_PROGRESS;
549 default:
550 break;
551 }
552 if (ret)
553 break;
554 }
555 if (!ret)
556 ret = cros_ec_spi_receive_response(ec_dev,
557 ec_msg->insize + EC_MSG_TX_PROTO_BYTES);
259 } else { 558 } else {
260 dev_err(ec_dev->dev, "spi transfer failed: %d\n", ret); 559 dev_err(ec_dev->dev, "spi transfer failed: %d\n", ret);
261 } 560 }
262 561
263 /* 562 final_ret = terminate_request(ec_dev);
264 * Turn off CS, possibly adding a delay to ensure the rising edge
265 * doesn't come too soon after the end of the data.
266 */
267 spi_message_init(&msg);
268 memset(&trans, 0, sizeof(trans));
269 trans.delay_usecs = ec_spi->end_of_msg_delay;
270 spi_message_add_tail(&trans, &msg);
271
272 final_ret = spi_sync(ec_spi->spi, &msg);
273 ec_spi->last_transfer_ns = ktime_get_ns();
274 if (!ret) 563 if (!ret)
275 ret = final_ret; 564 ret = final_ret;
276 if (ret < 0) { 565 if (ret < 0)
277 dev_err(ec_dev->dev, "spi transfer failed: %d\n", ret);
278 goto exit; 566 goto exit;
279 }
280 567
281 ptr = ec_dev->din; 568 ptr = ec_dev->din;
282 569
@@ -299,7 +586,7 @@ static int cros_ec_cmd_xfer_spi(struct cros_ec_device *ec_dev,
299 for (i = 0; i < len; i++) { 586 for (i = 0; i < len; i++) {
300 sum += ptr[i + 2]; 587 sum += ptr[i + 2];
301 if (ec_msg->insize) 588 if (ec_msg->insize)
302 ec_msg->indata[i] = ptr[i + 2]; 589 ec_msg->data[i] = ptr[i + 2];
303 } 590 }
304 sum &= 0xff; 591 sum &= 0xff;
305 592
@@ -315,6 +602,7 @@ static int cros_ec_cmd_xfer_spi(struct cros_ec_device *ec_dev,
315 602
316 ret = len; 603 ret = len;
317exit: 604exit:
605 kfree(rx_buf);
318 if (ec_msg->command == EC_CMD_REBOOT_EC) 606 if (ec_msg->command == EC_CMD_REBOOT_EC)
319 msleep(EC_REBOOT_DELAY_MS); 607 msleep(EC_REBOOT_DELAY_MS);
320 608
@@ -327,6 +615,10 @@ static void cros_ec_spi_dt_probe(struct cros_ec_spi *ec_spi, struct device *dev)
327 u32 val; 615 u32 val;
328 int ret; 616 int ret;
329 617
618 ret = of_property_read_u32(np, "google,cros-ec-spi-pre-delay", &val);
619 if (!ret)
620 ec_spi->start_of_msg_delay = val;
621
330 ret = of_property_read_u32(np, "google,cros-ec-spi-msg-delay", &val); 622 ret = of_property_read_u32(np, "google,cros-ec-spi-msg-delay", &val);
331 if (!ret) 623 if (!ret)
332 ec_spi->end_of_msg_delay = val; 624 ec_spi->end_of_msg_delay = val;
@@ -361,11 +653,13 @@ static int cros_ec_spi_probe(struct spi_device *spi)
361 ec_dev->priv = ec_spi; 653 ec_dev->priv = ec_spi;
362 ec_dev->irq = spi->irq; 654 ec_dev->irq = spi->irq;
363 ec_dev->cmd_xfer = cros_ec_cmd_xfer_spi; 655 ec_dev->cmd_xfer = cros_ec_cmd_xfer_spi;
364 ec_dev->ec_name = ec_spi->spi->modalias; 656 ec_dev->pkt_xfer = cros_ec_pkt_xfer_spi;
365 ec_dev->phys_name = dev_name(&ec_spi->spi->dev); 657 ec_dev->phys_name = dev_name(&ec_spi->spi->dev);
366 ec_dev->parent = &ec_spi->spi->dev; 658 ec_dev->din_size = EC_MSG_PREAMBLE_COUNT +
367 ec_dev->din_size = EC_MSG_BYTES + EC_MSG_PREAMBLE_COUNT; 659 sizeof(struct ec_host_response) +
368 ec_dev->dout_size = EC_MSG_BYTES; 660 sizeof(struct ec_response_get_protocol_info);
661 ec_dev->dout_size = sizeof(struct ec_host_request);
662
369 663
370 err = cros_ec_register(ec_dev); 664 err = cros_ec_register(ec_dev);
371 if (err) { 665 if (err) {
diff --git a/drivers/mfd/da9052-irq.c b/drivers/mfd/da9052-irq.c
index e65ca194fa98..f4cb4613140b 100644
--- a/drivers/mfd/da9052-irq.c
+++ b/drivers/mfd/da9052-irq.c
@@ -35,7 +35,7 @@
35#define DA9052_IRQ_MASK_POS_7 0x40 35#define DA9052_IRQ_MASK_POS_7 0x40
36#define DA9052_IRQ_MASK_POS_8 0x80 36#define DA9052_IRQ_MASK_POS_8 0x80
37 37
38static struct regmap_irq da9052_irqs[] = { 38static const struct regmap_irq da9052_irqs[] = {
39 [DA9052_IRQ_DCIN] = { 39 [DA9052_IRQ_DCIN] = {
40 .reg_offset = 0, 40 .reg_offset = 0,
41 .mask = DA9052_IRQ_MASK_POS_1, 41 .mask = DA9052_IRQ_MASK_POS_1,
@@ -166,7 +166,7 @@ static struct regmap_irq da9052_irqs[] = {
166 }, 166 },
167}; 167};
168 168
169static struct regmap_irq_chip da9052_regmap_irq_chip = { 169static const struct regmap_irq_chip da9052_regmap_irq_chip = {
170 .name = "da9052_irq", 170 .name = "da9052_irq",
171 .status_base = DA9052_EVENT_A_REG, 171 .status_base = DA9052_EVENT_A_REG,
172 .mask_base = DA9052_IRQ_MASK_A_REG, 172 .mask_base = DA9052_IRQ_MASK_A_REG,
diff --git a/drivers/mfd/da9055-core.c b/drivers/mfd/da9055-core.c
index b4d920c1ead1..177e65a12c12 100644
--- a/drivers/mfd/da9055-core.c
+++ b/drivers/mfd/da9055-core.c
@@ -222,7 +222,7 @@ static bool da9055_register_volatile(struct device *dev, unsigned int reg)
222 } 222 }
223} 223}
224 224
225static struct regmap_irq da9055_irqs[] = { 225static const struct regmap_irq da9055_irqs[] = {
226 [DA9055_IRQ_NONKEY] = { 226 [DA9055_IRQ_NONKEY] = {
227 .reg_offset = 0, 227 .reg_offset = 0,
228 .mask = DA9055_IRQ_NONKEY_MASK, 228 .mask = DA9055_IRQ_NONKEY_MASK,
@@ -245,7 +245,7 @@ static struct regmap_irq da9055_irqs[] = {
245 }, 245 },
246}; 246};
247 247
248struct regmap_config da9055_regmap_config = { 248const struct regmap_config da9055_regmap_config = {
249 .reg_bits = 8, 249 .reg_bits = 8,
250 .val_bits = 8, 250 .val_bits = 8,
251 251
@@ -367,7 +367,7 @@ static const struct mfd_cell da9055_devs[] = {
367 }, 367 },
368}; 368};
369 369
370static struct regmap_irq_chip da9055_regmap_irq_chip = { 370static const struct regmap_irq_chip da9055_regmap_irq_chip = {
371 .name = "da9055_irq", 371 .name = "da9055_irq",
372 .status_base = DA9055_REG_EVENT_A, 372 .status_base = DA9055_REG_EVENT_A,
373 .mask_base = DA9055_REG_IRQ_MASK_A, 373 .mask_base = DA9055_REG_IRQ_MASK_A,
diff --git a/drivers/mfd/da9063-core.c b/drivers/mfd/da9063-core.c
index facd3610ac77..af841c165787 100644
--- a/drivers/mfd/da9063-core.c
+++ b/drivers/mfd/da9063-core.c
@@ -60,6 +60,7 @@ static struct resource da9063_rtc_resources[] = {
60 60
61static struct resource da9063_onkey_resources[] = { 61static struct resource da9063_onkey_resources[] = {
62 { 62 {
63 .name = "ONKEY",
63 .start = DA9063_IRQ_ONKEY, 64 .start = DA9063_IRQ_ONKEY,
64 .end = DA9063_IRQ_ONKEY, 65 .end = DA9063_IRQ_ONKEY,
65 .flags = IORESOURCE_IRQ, 66 .flags = IORESOURCE_IRQ,
@@ -97,6 +98,7 @@ static const struct mfd_cell da9063_devs[] = {
97 .name = DA9063_DRVNAME_ONKEY, 98 .name = DA9063_DRVNAME_ONKEY,
98 .num_resources = ARRAY_SIZE(da9063_onkey_resources), 99 .num_resources = ARRAY_SIZE(da9063_onkey_resources),
99 .resources = da9063_onkey_resources, 100 .resources = da9063_onkey_resources,
101 .of_compatible = "dlg,da9063-onkey",
100 }, 102 },
101 { 103 {
102 .name = DA9063_DRVNAME_RTC, 104 .name = DA9063_DRVNAME_RTC,
@@ -109,12 +111,64 @@ static const struct mfd_cell da9063_devs[] = {
109 }, 111 },
110}; 112};
111 113
114static int da9063_clear_fault_log(struct da9063 *da9063)
115{
116 int ret = 0;
117 int fault_log = 0;
118
119 ret = regmap_read(da9063->regmap, DA9063_REG_FAULT_LOG, &fault_log);
120 if (ret < 0) {
121 dev_err(da9063->dev, "Cannot read FAULT_LOG.\n");
122 return -EIO;
123 }
124
125 if (fault_log) {
126 if (fault_log & DA9063_TWD_ERROR)
127 dev_dbg(da9063->dev,
128 "Fault log entry detected: DA9063_TWD_ERROR\n");
129 if (fault_log & DA9063_POR)
130 dev_dbg(da9063->dev,
131 "Fault log entry detected: DA9063_POR\n");
132 if (fault_log & DA9063_VDD_FAULT)
133 dev_dbg(da9063->dev,
134 "Fault log entry detected: DA9063_VDD_FAULT\n");
135 if (fault_log & DA9063_VDD_START)
136 dev_dbg(da9063->dev,
137 "Fault log entry detected: DA9063_VDD_START\n");
138 if (fault_log & DA9063_TEMP_CRIT)
139 dev_dbg(da9063->dev,
140 "Fault log entry detected: DA9063_TEMP_CRIT\n");
141 if (fault_log & DA9063_KEY_RESET)
142 dev_dbg(da9063->dev,
143 "Fault log entry detected: DA9063_KEY_RESET\n");
144 if (fault_log & DA9063_NSHUTDOWN)
145 dev_dbg(da9063->dev,
146 "Fault log entry detected: DA9063_NSHUTDOWN\n");
147 if (fault_log & DA9063_WAIT_SHUT)
148 dev_dbg(da9063->dev,
149 "Fault log entry detected: DA9063_WAIT_SHUT\n");
150 }
151
152 ret = regmap_write(da9063->regmap,
153 DA9063_REG_FAULT_LOG,
154 fault_log);
155 if (ret < 0)
156 dev_err(da9063->dev,
157 "Cannot reset FAULT_LOG values %d\n", ret);
158
159 return ret;
160}
161
112int da9063_device_init(struct da9063 *da9063, unsigned int irq) 162int da9063_device_init(struct da9063 *da9063, unsigned int irq)
113{ 163{
114 struct da9063_pdata *pdata = da9063->dev->platform_data; 164 struct da9063_pdata *pdata = da9063->dev->platform_data;
115 int model, variant_id, variant_code; 165 int model, variant_id, variant_code;
116 int ret; 166 int ret;
117 167
168 ret = da9063_clear_fault_log(da9063);
169 if (ret < 0)
170 dev_err(da9063->dev, "Cannot clear fault log\n");
171
118 if (pdata) { 172 if (pdata) {
119 da9063->flags = pdata->flags; 173 da9063->flags = pdata->flags;
120 da9063->irq_base = pdata->irq_base; 174 da9063->irq_base = pdata->irq_base;
diff --git a/drivers/mfd/da9063-irq.c b/drivers/mfd/da9063-irq.c
index 822922602ce9..eaf1ec9208b2 100644
--- a/drivers/mfd/da9063-irq.c
+++ b/drivers/mfd/da9063-irq.c
@@ -34,7 +34,7 @@ struct da9063_irq_data {
34 u8 mask; 34 u8 mask;
35}; 35};
36 36
37static struct regmap_irq da9063_irqs[] = { 37static const struct regmap_irq da9063_irqs[] = {
38 /* DA9063 event A register */ 38 /* DA9063 event A register */
39 [DA9063_IRQ_ONKEY] = { 39 [DA9063_IRQ_ONKEY] = {
40 .reg_offset = DA9063_REG_EVENT_A_OFFSET, 40 .reg_offset = DA9063_REG_EVENT_A_OFFSET,
@@ -153,7 +153,7 @@ static struct regmap_irq da9063_irqs[] = {
153 }, 153 },
154}; 154};
155 155
156static struct regmap_irq_chip da9063_irq_chip = { 156static const struct regmap_irq_chip da9063_irq_chip = {
157 .name = "da9063-irq", 157 .name = "da9063-irq",
158 .irqs = da9063_irqs, 158 .irqs = da9063_irqs,
159 .num_irqs = DA9063_NUM_IRQ, 159 .num_irqs = DA9063_NUM_IRQ,
diff --git a/drivers/mfd/da9150-core.c b/drivers/mfd/da9150-core.c
index 5549817df32e..94b9bbd1a69b 100644
--- a/drivers/mfd/da9150-core.c
+++ b/drivers/mfd/da9150-core.c
@@ -164,7 +164,7 @@ void da9150_bulk_write(struct da9150 *da9150, u16 reg, int count, const u8 *buf)
164} 164}
165EXPORT_SYMBOL_GPL(da9150_bulk_write); 165EXPORT_SYMBOL_GPL(da9150_bulk_write);
166 166
167static struct regmap_irq da9150_irqs[] = { 167static const struct regmap_irq da9150_irqs[] = {
168 [DA9150_IRQ_VBUS] = { 168 [DA9150_IRQ_VBUS] = {
169 .reg_offset = 0, 169 .reg_offset = 0,
170 .mask = DA9150_E_VBUS_MASK, 170 .mask = DA9150_E_VBUS_MASK,
@@ -251,7 +251,7 @@ static struct regmap_irq da9150_irqs[] = {
251 }, 251 },
252}; 252};
253 253
254static struct regmap_irq_chip da9150_regmap_irq_chip = { 254static const struct regmap_irq_chip da9150_regmap_irq_chip = {
255 .name = "da9150_irq", 255 .name = "da9150_irq",
256 .status_base = DA9150_EVENT_E, 256 .status_base = DA9150_EVENT_E,
257 .mask_base = DA9150_IRQ_MASK_E, 257 .mask_base = DA9150_IRQ_MASK_E,
diff --git a/drivers/mfd/db8500-prcmu.c b/drivers/mfd/db8500-prcmu.c
index cc1a404328c2..8b14740f9fca 100644
--- a/drivers/mfd/db8500-prcmu.c
+++ b/drivers/mfd/db8500-prcmu.c
@@ -2659,7 +2659,7 @@ static int db8500_irq_map(struct irq_domain *d, unsigned int virq,
2659 return 0; 2659 return 0;
2660} 2660}
2661 2661
2662static struct irq_domain_ops db8500_irq_ops = { 2662static const struct irq_domain_ops db8500_irq_ops = {
2663 .map = db8500_irq_map, 2663 .map = db8500_irq_map,
2664 .xlate = irq_domain_xlate_twocell, 2664 .xlate = irq_domain_xlate_twocell,
2665}; 2665};
diff --git a/drivers/mfd/htc-i2cpld.c b/drivers/mfd/htc-i2cpld.c
index ebb9cf19e347..b54baad30164 100644
--- a/drivers/mfd/htc-i2cpld.c
+++ b/drivers/mfd/htc-i2cpld.c
@@ -564,7 +564,8 @@ static int htcpld_core_probe(struct platform_device *pdev)
564 htcpld->chained_irq = res->start; 564 htcpld->chained_irq = res->start;
565 565
566 /* Setup the chained interrupt handler */ 566 /* Setup the chained interrupt handler */
567 flags = IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING; 567 flags = IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING |
568 IRQF_ONESHOT;
568 ret = request_threaded_irq(htcpld->chained_irq, 569 ret = request_threaded_irq(htcpld->chained_irq,
569 NULL, htcpld_handler, 570 NULL, htcpld_handler,
570 flags, pdev->name, htcpld); 571 flags, pdev->name, htcpld);
diff --git a/drivers/mfd/intel_soc_pmic_core.h b/drivers/mfd/intel_soc_pmic_core.h
index 9498d6719847..ff2464bc172f 100644
--- a/drivers/mfd/intel_soc_pmic_core.h
+++ b/drivers/mfd/intel_soc_pmic_core.h
@@ -24,7 +24,7 @@ struct intel_soc_pmic_config {
24 struct mfd_cell *cell_dev; 24 struct mfd_cell *cell_dev;
25 int n_cell_devs; 25 int n_cell_devs;
26 const struct regmap_config *regmap_config; 26 const struct regmap_config *regmap_config;
27 struct regmap_irq_chip *irq_chip; 27 const struct regmap_irq_chip *irq_chip;
28}; 28};
29 29
30extern struct intel_soc_pmic_config intel_soc_pmic_config_crc; 30extern struct intel_soc_pmic_config intel_soc_pmic_config_crc;
diff --git a/drivers/mfd/intel_soc_pmic_crc.c b/drivers/mfd/intel_soc_pmic_crc.c
index 4cc1b324e971..7436075e8983 100644
--- a/drivers/mfd/intel_soc_pmic_crc.c
+++ b/drivers/mfd/intel_soc_pmic_crc.c
@@ -143,7 +143,7 @@ static const struct regmap_irq crystal_cove_irqs[] = {
143 }, 143 },
144}; 144};
145 145
146static struct regmap_irq_chip crystal_cove_irq_chip = { 146static const struct regmap_irq_chip crystal_cove_irq_chip = {
147 .name = "Crystal Cove", 147 .name = "Crystal Cove",
148 .irqs = crystal_cove_irqs, 148 .irqs = crystal_cove_irqs,
149 .num_irqs = ARRAY_SIZE(crystal_cove_irqs), 149 .num_irqs = ARRAY_SIZE(crystal_cove_irqs),
diff --git a/drivers/mfd/lp8788-irq.c b/drivers/mfd/lp8788-irq.c
index 23982dbf014d..a87f2b548f71 100644
--- a/drivers/mfd/lp8788-irq.c
+++ b/drivers/mfd/lp8788-irq.c
@@ -151,7 +151,7 @@ static int lp8788_irq_map(struct irq_domain *d, unsigned int virq,
151 return 0; 151 return 0;
152} 152}
153 153
154static struct irq_domain_ops lp8788_domain_ops = { 154static const struct irq_domain_ops lp8788_domain_ops = {
155 .map = lp8788_irq_map, 155 .map = lp8788_irq_map,
156}; 156};
157 157
diff --git a/drivers/mfd/lpc_ich.c b/drivers/mfd/lpc_ich.c
index 12d960a60ec4..8de34398abc0 100644
--- a/drivers/mfd/lpc_ich.c
+++ b/drivers/mfd/lpc_ich.c
@@ -934,8 +934,8 @@ gpe0_done:
934 lpc_ich_enable_gpio_space(dev); 934 lpc_ich_enable_gpio_space(dev);
935 935
936 lpc_ich_finalize_cell(dev, &lpc_ich_cells[LPC_GPIO]); 936 lpc_ich_finalize_cell(dev, &lpc_ich_cells[LPC_GPIO]);
937 ret = mfd_add_devices(&dev->dev, -1, &lpc_ich_cells[LPC_GPIO], 937 ret = mfd_add_devices(&dev->dev, PLATFORM_DEVID_AUTO,
938 1, NULL, 0, NULL); 938 &lpc_ich_cells[LPC_GPIO], 1, NULL, 0, NULL);
939 939
940gpio_done: 940gpio_done:
941 if (acpi_conflict) 941 if (acpi_conflict)
@@ -1008,8 +1008,8 @@ static int lpc_ich_init_wdt(struct pci_dev *dev)
1008 } 1008 }
1009 1009
1010 lpc_ich_finalize_cell(dev, &lpc_ich_cells[LPC_WDT]); 1010 lpc_ich_finalize_cell(dev, &lpc_ich_cells[LPC_WDT]);
1011 ret = mfd_add_devices(&dev->dev, -1, &lpc_ich_cells[LPC_WDT], 1011 ret = mfd_add_devices(&dev->dev, PLATFORM_DEVID_AUTO,
1012 1, NULL, 0, NULL); 1012 &lpc_ich_cells[LPC_WDT], 1, NULL, 0, NULL);
1013 1013
1014wdt_done: 1014wdt_done:
1015 return ret; 1015 return ret;
diff --git a/drivers/mfd/max8925-core.c b/drivers/mfd/max8925-core.c
index 97a787ab3d51..8520bd68c1ff 100644
--- a/drivers/mfd/max8925-core.c
+++ b/drivers/mfd/max8925-core.c
@@ -658,7 +658,7 @@ static int max8925_irq_domain_map(struct irq_domain *d, unsigned int virq,
658 return 0; 658 return 0;
659} 659}
660 660
661static struct irq_domain_ops max8925_irq_domain_ops = { 661static const struct irq_domain_ops max8925_irq_domain_ops = {
662 .map = max8925_irq_domain_map, 662 .map = max8925_irq_domain_map,
663 .xlate = irq_domain_xlate_onetwocell, 663 .xlate = irq_domain_xlate_onetwocell,
664}; 664};
diff --git a/drivers/mfd/max8997-irq.c b/drivers/mfd/max8997-irq.c
index 43fa61413e93..d3025be57f39 100644
--- a/drivers/mfd/max8997-irq.c
+++ b/drivers/mfd/max8997-irq.c
@@ -303,7 +303,7 @@ static int max8997_irq_domain_map(struct irq_domain *d, unsigned int irq,
303 return 0; 303 return 0;
304} 304}
305 305
306static struct irq_domain_ops max8997_irq_domain_ops = { 306static const struct irq_domain_ops max8997_irq_domain_ops = {
307 .map = max8997_irq_domain_map, 307 .map = max8997_irq_domain_map,
308}; 308};
309 309
diff --git a/drivers/mfd/max8998-irq.c b/drivers/mfd/max8998-irq.c
index c469477eb778..3702056628a8 100644
--- a/drivers/mfd/max8998-irq.c
+++ b/drivers/mfd/max8998-irq.c
@@ -214,7 +214,7 @@ static int max8998_irq_domain_map(struct irq_domain *d, unsigned int irq,
214 return 0; 214 return 0;
215} 215}
216 216
217static struct irq_domain_ops max8998_irq_domain_ops = { 217static const struct irq_domain_ops max8998_irq_domain_ops = {
218 .map = max8998_irq_domain_map, 218 .map = max8998_irq_domain_map,
219}; 219};
220 220
diff --git a/drivers/mfd/mc13xxx-core.c b/drivers/mfd/mc13xxx-core.c
index 25fd7116493a..3f9f4c874d2a 100644
--- a/drivers/mfd/mc13xxx-core.c
+++ b/drivers/mfd/mc13xxx-core.c
@@ -163,7 +163,7 @@ int mc13xxx_irq_request(struct mc13xxx *mc13xxx, int irq,
163 int virq = regmap_irq_get_virq(mc13xxx->irq_data, irq); 163 int virq = regmap_irq_get_virq(mc13xxx->irq_data, irq);
164 164
165 return devm_request_threaded_irq(mc13xxx->dev, virq, NULL, handler, 165 return devm_request_threaded_irq(mc13xxx->dev, virq, NULL, handler,
166 0, name, dev); 166 IRQF_ONESHOT, name, dev);
167} 167}
168EXPORT_SYMBOL(mc13xxx_irq_request); 168EXPORT_SYMBOL(mc13xxx_irq_request);
169 169
diff --git a/drivers/mfd/mfd-core.c b/drivers/mfd/mfd-core.c
index 1aed3b7b8d9b..14fd5cbcf0f2 100644
--- a/drivers/mfd/mfd-core.c
+++ b/drivers/mfd/mfd-core.c
@@ -207,9 +207,11 @@ static int mfd_add_device(struct device *parent, int id,
207 } 207 }
208 208
209 if (!cell->ignore_resource_conflicts) { 209 if (!cell->ignore_resource_conflicts) {
210 ret = acpi_check_resource_conflict(&res[r]); 210 if (has_acpi_companion(&pdev->dev)) {
211 if (ret) 211 ret = acpi_check_resource_conflict(&res[r]);
212 goto fail_alias; 212 if (ret)
213 goto fail_alias;
214 }
213 } 215 }
214 } 216 }
215 217
diff --git a/drivers/mfd/mt6397-core.c b/drivers/mfd/mt6397-core.c
index 09bc7804952a..38a0458f7834 100644
--- a/drivers/mfd/mt6397-core.c
+++ b/drivers/mfd/mt6397-core.c
@@ -34,6 +34,9 @@ static const struct mfd_cell mt6397_devs[] = {
34 }, { 34 }, {
35 .name = "mt6397-clk", 35 .name = "mt6397-clk",
36 .of_compatible = "mediatek,mt6397-clk", 36 .of_compatible = "mediatek,mt6397-clk",
37 }, {
38 .name = "mt6397-pinctrl",
39 .of_compatible = "mediatek,mt6397-pinctrl",
37 }, 40 },
38}; 41};
39 42
@@ -130,7 +133,7 @@ static int mt6397_irq_domain_map(struct irq_domain *d, unsigned int irq,
130 return 0; 133 return 0;
131} 134}
132 135
133static struct irq_domain_ops mt6397_irq_domain_ops = { 136static const struct irq_domain_ops mt6397_irq_domain_ops = {
134 .map = mt6397_irq_domain_map, 137 .map = mt6397_irq_domain_map,
135}; 138};
136 139
diff --git a/drivers/mfd/si476x-i2c.c b/drivers/mfd/si476x-i2c.c
index 7f87c62d91b3..e3deb466628b 100644
--- a/drivers/mfd/si476x-i2c.c
+++ b/drivers/mfd/si476x-i2c.c
@@ -777,7 +777,8 @@ static int si476x_core_probe(struct i2c_client *client,
777 rval = devm_request_threaded_irq(&client->dev, 777 rval = devm_request_threaded_irq(&client->dev,
778 client->irq, NULL, 778 client->irq, NULL,
779 si476x_core_interrupt, 779 si476x_core_interrupt,
780 IRQF_TRIGGER_FALLING, 780 IRQF_TRIGGER_FALLING |
781 IRQF_ONESHOT,
781 client->name, core); 782 client->name, core);
782 if (rval < 0) { 783 if (rval < 0) {
783 dev_err(&client->dev, "Could not request IRQ %d\n", 784 dev_err(&client->dev, "Could not request IRQ %d\n",
diff --git a/drivers/mfd/stmpe.c b/drivers/mfd/stmpe.c
index 2d7fae94c861..18c4d72d1d2a 100644
--- a/drivers/mfd/stmpe.c
+++ b/drivers/mfd/stmpe.c
@@ -989,7 +989,7 @@ static void stmpe_irq_unmap(struct irq_domain *d, unsigned int virq)
989 irq_set_chip_data(virq, NULL); 989 irq_set_chip_data(virq, NULL);
990} 990}
991 991
992static struct irq_domain_ops stmpe_irq_ops = { 992static const struct irq_domain_ops stmpe_irq_ops = {
993 .map = stmpe_irq_map, 993 .map = stmpe_irq_map,
994 .unmap = stmpe_irq_unmap, 994 .unmap = stmpe_irq_unmap,
995 .xlate = irq_domain_xlate_twocell, 995 .xlate = irq_domain_xlate_twocell,
diff --git a/drivers/mfd/tc3589x.c b/drivers/mfd/tc3589x.c
index cf356395c9e9..96d420dfc15d 100644
--- a/drivers/mfd/tc3589x.c
+++ b/drivers/mfd/tc3589x.c
@@ -233,7 +233,7 @@ static void tc3589x_irq_unmap(struct irq_domain *d, unsigned int virq)
233 irq_set_chip_data(virq, NULL); 233 irq_set_chip_data(virq, NULL);
234} 234}
235 235
236static struct irq_domain_ops tc3589x_irq_ops = { 236static const struct irq_domain_ops tc3589x_irq_ops = {
237 .map = tc3589x_irq_map, 237 .map = tc3589x_irq_map,
238 .unmap = tc3589x_irq_unmap, 238 .unmap = tc3589x_irq_unmap,
239 .xlate = irq_domain_xlate_onecell, 239 .xlate = irq_domain_xlate_onecell,
diff --git a/drivers/mfd/tps6586x.c b/drivers/mfd/tps6586x.c
index 8e1dbc469580..e0a2583916ce 100644
--- a/drivers/mfd/tps6586x.c
+++ b/drivers/mfd/tps6586x.c
@@ -311,7 +311,7 @@ static int tps6586x_irq_map(struct irq_domain *h, unsigned int virq,
311 return 0; 311 return 0;
312} 312}
313 313
314static struct irq_domain_ops tps6586x_domain_ops = { 314static const struct irq_domain_ops tps6586x_domain_ops = {
315 .map = tps6586x_irq_map, 315 .map = tps6586x_irq_map,
316 .xlate = irq_domain_xlate_twocell, 316 .xlate = irq_domain_xlate_twocell,
317}; 317};
diff --git a/drivers/mfd/twl4030-irq.c b/drivers/mfd/twl4030-irq.c
index 1b772ef761cb..a3fa7f4f1fb4 100644
--- a/drivers/mfd/twl4030-irq.c
+++ b/drivers/mfd/twl4030-irq.c
@@ -674,7 +674,7 @@ int twl4030_sih_setup(struct device *dev, int module, int irq_base)
674 irq_set_handler_data(irq, agent); 674 irq_set_handler_data(irq, agent);
675 agent->irq_name = kasprintf(GFP_KERNEL, "twl4030_%s", sih->name); 675 agent->irq_name = kasprintf(GFP_KERNEL, "twl4030_%s", sih->name);
676 status = request_threaded_irq(irq, NULL, handle_twl4030_sih, 676 status = request_threaded_irq(irq, NULL, handle_twl4030_sih,
677 IRQF_EARLY_RESUME, 677 IRQF_EARLY_RESUME | IRQF_ONESHOT,
678 agent->irq_name ?: sih->name, NULL); 678 agent->irq_name ?: sih->name, NULL);
679 679
680 dev_info(dev, "%s (irq %d) chaining IRQs %d..%d\n", sih->name, 680 dev_info(dev, "%s (irq %d) chaining IRQs %d..%d\n", sih->name,
diff --git a/drivers/mfd/twl4030-power.c b/drivers/mfd/twl4030-power.c
index f440aed61305..04b539850e72 100644
--- a/drivers/mfd/twl4030-power.c
+++ b/drivers/mfd/twl4030-power.c
@@ -264,7 +264,9 @@ out:
264 return err; 264 return err;
265} 265}
266 266
267static int twl4030_config_wakeup12_sequence(u8 address) 267static int
268twl4030_config_wakeup12_sequence(const struct twl4030_power_data *pdata,
269 u8 address)
268{ 270{
269 int err = 0; 271 int err = 0;
270 u8 data; 272 u8 data;
@@ -293,13 +295,14 @@ static int twl4030_config_wakeup12_sequence(u8 address)
293 if (err) 295 if (err)
294 goto out; 296 goto out;
295 297
296 if (machine_is_omap_3430sdp() || machine_is_omap_ldp()) { 298 if (pdata->ac_charger_quirk || machine_is_omap_3430sdp() ||
299 machine_is_omap_ldp()) {
297 /* Disabling AC charger effect on sleep-active transitions */ 300 /* Disabling AC charger effect on sleep-active transitions */
298 err = twl_i2c_read_u8(TWL_MODULE_PM_MASTER, &data, 301 err = twl_i2c_read_u8(TWL_MODULE_PM_MASTER, &data,
299 R_CFG_P1_TRANSITION); 302 R_CFG_P1_TRANSITION);
300 if (err) 303 if (err)
301 goto out; 304 goto out;
302 data &= ~(1<<1); 305 data &= ~STARTON_CHG;
303 err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, data, 306 err = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, data,
304 R_CFG_P1_TRANSITION); 307 R_CFG_P1_TRANSITION);
305 if (err) 308 if (err)
@@ -459,8 +462,9 @@ static int twl4030_configure_resource(struct twl4030_resconfig *rconfig)
459 return 0; 462 return 0;
460} 463}
461 464
462static int load_twl4030_script(struct twl4030_script *tscript, 465static int load_twl4030_script(const struct twl4030_power_data *pdata,
463 u8 address) 466 struct twl4030_script *tscript,
467 u8 address)
464{ 468{
465 int err; 469 int err;
466 static int order; 470 static int order;
@@ -487,7 +491,7 @@ static int load_twl4030_script(struct twl4030_script *tscript,
487 if (err) 491 if (err)
488 goto out; 492 goto out;
489 493
490 err = twl4030_config_wakeup12_sequence(address); 494 err = twl4030_config_wakeup12_sequence(pdata, address);
491 if (err) 495 if (err)
492 goto out; 496 goto out;
493 order = 1; 497 order = 1;
@@ -567,7 +571,7 @@ twl4030_power_configure_scripts(const struct twl4030_power_data *pdata)
567 u8 address = twl4030_start_script_address; 571 u8 address = twl4030_start_script_address;
568 572
569 for (i = 0; i < pdata->num; i++) { 573 for (i = 0; i < pdata->num; i++) {
570 err = load_twl4030_script(pdata->scripts[i], address); 574 err = load_twl4030_script(pdata, pdata->scripts[i], address);
571 if (err) 575 if (err)
572 return err; 576 return err;
573 address += pdata->scripts[i]->size; 577 address += pdata->scripts[i]->size;
@@ -829,6 +833,21 @@ static struct twl4030_power_data osc_off_idle = {
829 .board_config = osc_off_rconfig, 833 .board_config = osc_off_rconfig,
830}; 834};
831 835
836static struct twl4030_power_data omap3_idle_ac_quirk = {
837 .scripts = omap3_idle_scripts,
838 .num = ARRAY_SIZE(omap3_idle_scripts),
839 .resource_config = omap3_idle_rconfig,
840 .ac_charger_quirk = true,
841};
842
843static struct twl4030_power_data omap3_idle_ac_quirk_osc_off = {
844 .scripts = omap3_idle_scripts,
845 .num = ARRAY_SIZE(omap3_idle_scripts),
846 .resource_config = omap3_idle_rconfig,
847 .board_config = osc_off_rconfig,
848 .ac_charger_quirk = true,
849};
850
832static const struct of_device_id twl4030_power_of_match[] = { 851static const struct of_device_id twl4030_power_of_match[] = {
833 { 852 {
834 .compatible = "ti,twl4030-power", 853 .compatible = "ti,twl4030-power",
@@ -845,6 +864,18 @@ static const struct of_device_id twl4030_power_of_match[] = {
845 .compatible = "ti,twl4030-power-idle-osc-off", 864 .compatible = "ti,twl4030-power-idle-osc-off",
846 .data = &osc_off_idle, 865 .data = &osc_off_idle,
847 }, 866 },
867 {
868 .compatible = "ti,twl4030-power-omap3-sdp",
869 .data = &omap3_idle_ac_quirk,
870 },
871 {
872 .compatible = "ti,twl4030-power-omap3-ldp",
873 .data = &omap3_idle_ac_quirk_osc_off,
874 },
875 {
876 .compatible = "ti,twl4030-power-omap3-evm",
877 .data = &omap3_idle_ac_quirk,
878 },
848 { }, 879 { },
849}; 880};
850MODULE_DEVICE_TABLE(of, twl4030_power_of_match); 881MODULE_DEVICE_TABLE(of, twl4030_power_of_match);
diff --git a/drivers/mfd/twl6030-irq.c b/drivers/mfd/twl6030-irq.c
index 2807e1a95663..20fb58179ada 100644
--- a/drivers/mfd/twl6030-irq.c
+++ b/drivers/mfd/twl6030-irq.c
@@ -376,7 +376,7 @@ static void twl6030_irq_unmap(struct irq_domain *d, unsigned int virq)
376 irq_set_chip_data(virq, NULL); 376 irq_set_chip_data(virq, NULL);
377} 377}
378 378
379static struct irq_domain_ops twl6030_irq_domain_ops = { 379static const struct irq_domain_ops twl6030_irq_domain_ops = {
380 .map = twl6030_irq_map, 380 .map = twl6030_irq_map,
381 .unmap = twl6030_irq_unmap, 381 .unmap = twl6030_irq_unmap,
382 .xlate = irq_domain_xlate_onetwocell, 382 .xlate = irq_domain_xlate_onetwocell,
diff --git a/drivers/mfd/wm831x-auxadc.c b/drivers/mfd/wm831x-auxadc.c
index 6ee3018d8653..fd789d2eb0f5 100644
--- a/drivers/mfd/wm831x-auxadc.c
+++ b/drivers/mfd/wm831x-auxadc.c
@@ -285,7 +285,8 @@ void wm831x_auxadc_init(struct wm831x *wm831x)
285 285
286 ret = request_threaded_irq(wm831x_irq(wm831x, 286 ret = request_threaded_irq(wm831x_irq(wm831x,
287 WM831X_IRQ_AUXADC_DATA), 287 WM831X_IRQ_AUXADC_DATA),
288 NULL, wm831x_auxadc_irq, 0, 288 NULL, wm831x_auxadc_irq,
289 IRQF_ONESHOT,
289 "auxadc", wm831x); 290 "auxadc", wm831x);
290 if (ret < 0) { 291 if (ret < 0) {
291 dev_err(wm831x->dev, "AUXADC IRQ request failed: %d\n", 292 dev_err(wm831x->dev, "AUXADC IRQ request failed: %d\n",
diff --git a/drivers/mfd/wm831x-irq.c b/drivers/mfd/wm831x-irq.c
index 64e512eadf17..3da81263c764 100644
--- a/drivers/mfd/wm831x-irq.c
+++ b/drivers/mfd/wm831x-irq.c
@@ -564,7 +564,7 @@ static int wm831x_irq_map(struct irq_domain *h, unsigned int virq,
564 return 0; 564 return 0;
565} 565}
566 566
567static struct irq_domain_ops wm831x_irq_domain_ops = { 567static const struct irq_domain_ops wm831x_irq_domain_ops = {
568 .map = wm831x_irq_map, 568 .map = wm831x_irq_map,
569 .xlate = irq_domain_xlate_twocell, 569 .xlate = irq_domain_xlate_twocell,
570}; 570};
diff --git a/drivers/mfd/wm8350-core.c b/drivers/mfd/wm8350-core.c
index f5124a8acad8..8a07c5634aee 100644
--- a/drivers/mfd/wm8350-core.c
+++ b/drivers/mfd/wm8350-core.c
@@ -404,7 +404,8 @@ int wm8350_device_init(struct wm8350 *wm8350, int irq,
404 if (wm8350->irq_base) { 404 if (wm8350->irq_base) {
405 ret = request_threaded_irq(wm8350->irq_base + 405 ret = request_threaded_irq(wm8350->irq_base +
406 WM8350_IRQ_AUXADC_DATARDY, 406 WM8350_IRQ_AUXADC_DATARDY,
407 NULL, wm8350_auxadc_irq, 0, 407 NULL, wm8350_auxadc_irq,
408 IRQF_ONESHOT,
408 "auxadc", wm8350); 409 "auxadc", wm8350);
409 if (ret < 0) 410 if (ret < 0)
410 dev_warn(wm8350->dev, 411 dev_warn(wm8350->dev,
diff --git a/drivers/mfd/wm8994-irq.c b/drivers/mfd/wm8994-irq.c
index a14407edbd89..55c380a67686 100644
--- a/drivers/mfd/wm8994-irq.c
+++ b/drivers/mfd/wm8994-irq.c
@@ -28,7 +28,7 @@
28 28
29#include <linux/delay.h> 29#include <linux/delay.h>
30 30
31static struct regmap_irq wm8994_irqs[] = { 31static const struct regmap_irq wm8994_irqs[] = {
32 [WM8994_IRQ_TEMP_SHUT] = { 32 [WM8994_IRQ_TEMP_SHUT] = {
33 .reg_offset = 1, 33 .reg_offset = 1,
34 .mask = WM8994_TEMP_SHUT_EINT, 34 .mask = WM8994_TEMP_SHUT_EINT,
@@ -128,7 +128,7 @@ static struct regmap_irq wm8994_irqs[] = {
128 }, 128 },
129}; 129};
130 130
131static struct regmap_irq_chip wm8994_irq_chip = { 131static const struct regmap_irq_chip wm8994_irq_chip = {
132 .name = "wm8994", 132 .name = "wm8994",
133 .irqs = wm8994_irqs, 133 .irqs = wm8994_irqs,
134 .num_irqs = ARRAY_SIZE(wm8994_irqs), 134 .num_irqs = ARRAY_SIZE(wm8994_irqs),
@@ -184,7 +184,7 @@ static int wm8994_edge_irq_map(struct irq_domain *h, unsigned int virq,
184 return 0; 184 return 0;
185} 185}
186 186
187static struct irq_domain_ops wm8994_edge_irq_ops = { 187static const struct irq_domain_ops wm8994_edge_irq_ops = {
188 .map = wm8994_edge_irq_map, 188 .map = wm8994_edge_irq_map,
189 .xlate = irq_domain_xlate_twocell, 189 .xlate = irq_domain_xlate_twocell,
190}; 190};
diff --git a/drivers/platform/chrome/Kconfig b/drivers/platform/chrome/Kconfig
index 2a6531a5fde8..cb1329919527 100644
--- a/drivers/platform/chrome/Kconfig
+++ b/drivers/platform/chrome/Kconfig
@@ -40,7 +40,7 @@ config CHROMEOS_PSTORE
40 40
41config CROS_EC_CHARDEV 41config CROS_EC_CHARDEV
42 tristate "Chrome OS Embedded Controller userspace device interface" 42 tristate "Chrome OS Embedded Controller userspace device interface"
43 depends on MFD_CROS_EC 43 depends on CROS_EC_PROTO
44 ---help--- 44 ---help---
45 This driver adds support to talk with the ChromeOS EC from userspace. 45 This driver adds support to talk with the ChromeOS EC from userspace.
46 46
@@ -49,7 +49,7 @@ config CROS_EC_CHARDEV
49 49
50config CROS_EC_LPC 50config CROS_EC_LPC
51 tristate "ChromeOS Embedded Controller (LPC)" 51 tristate "ChromeOS Embedded Controller (LPC)"
52 depends on MFD_CROS_EC && (X86 || COMPILE_TEST) 52 depends on MFD_CROS_EC && CROS_EC_PROTO && (X86 || COMPILE_TEST)
53 help 53 help
54 If you say Y here, you get support for talking to the ChromeOS EC 54 If you say Y here, you get support for talking to the ChromeOS EC
55 over an LPC bus. This uses a simple byte-level protocol with a 55 over an LPC bus. This uses a simple byte-level protocol with a
@@ -59,4 +59,9 @@ config CROS_EC_LPC
59 To compile this driver as a module, choose M here: the 59 To compile this driver as a module, choose M here: the
60 module will be called cros_ec_lpc. 60 module will be called cros_ec_lpc.
61 61
62config CROS_EC_PROTO
63 bool
64 help
65 ChromeOS EC communication protocol helpers.
66
62endif # CHROMEOS_PLATFORMS 67endif # CHROMEOS_PLATFORMS
diff --git a/drivers/platform/chrome/Makefile b/drivers/platform/chrome/Makefile
index bd8d8601e875..4a11b010f5d8 100644
--- a/drivers/platform/chrome/Makefile
+++ b/drivers/platform/chrome/Makefile
@@ -4,3 +4,4 @@ obj-$(CONFIG_CHROMEOS_PSTORE) += chromeos_pstore.o
4cros_ec_devs-objs := cros_ec_dev.o cros_ec_sysfs.o cros_ec_lightbar.o 4cros_ec_devs-objs := cros_ec_dev.o cros_ec_sysfs.o cros_ec_lightbar.o
5obj-$(CONFIG_CROS_EC_CHARDEV) += cros_ec_devs.o 5obj-$(CONFIG_CROS_EC_CHARDEV) += cros_ec_devs.o
6obj-$(CONFIG_CROS_EC_LPC) += cros_ec_lpc.o 6obj-$(CONFIG_CROS_EC_LPC) += cros_ec_lpc.o
7obj-$(CONFIG_CROS_EC_PROTO) += cros_ec_proto.o
diff --git a/drivers/platform/chrome/cros_ec_dev.c b/drivers/platform/chrome/cros_ec_dev.c
index 6090d0b2826f..e8fcdc237029 100644
--- a/drivers/platform/chrome/cros_ec_dev.c
+++ b/drivers/platform/chrome/cros_ec_dev.c
@@ -20,44 +20,59 @@
20#include <linux/fs.h> 20#include <linux/fs.h>
21#include <linux/module.h> 21#include <linux/module.h>
22#include <linux/platform_device.h> 22#include <linux/platform_device.h>
23#include <linux/slab.h>
23#include <linux/uaccess.h> 24#include <linux/uaccess.h>
24 25
25#include "cros_ec_dev.h" 26#include "cros_ec_dev.h"
26 27
27/* Device variables */ 28/* Device variables */
28#define CROS_MAX_DEV 128 29#define CROS_MAX_DEV 128
29static struct class *cros_class;
30static int ec_major; 30static int ec_major;
31 31
32static const struct attribute_group *cros_ec_groups[] = {
33 &cros_ec_attr_group,
34 &cros_ec_lightbar_attr_group,
35 NULL,
36};
37
38static struct class cros_class = {
39 .owner = THIS_MODULE,
40 .name = "chromeos",
41 .dev_groups = cros_ec_groups,
42};
43
32/* Basic communication */ 44/* Basic communication */
33static int ec_get_version(struct cros_ec_device *ec, char *str, int maxlen) 45static int ec_get_version(struct cros_ec_dev *ec, char *str, int maxlen)
34{ 46{
35 struct ec_response_get_version *resp; 47 struct ec_response_get_version *resp;
36 static const char * const current_image_name[] = { 48 static const char * const current_image_name[] = {
37 "unknown", "read-only", "read-write", "invalid", 49 "unknown", "read-only", "read-write", "invalid",
38 }; 50 };
39 struct cros_ec_command msg = { 51 struct cros_ec_command *msg;
40 .version = 0,
41 .command = EC_CMD_GET_VERSION,
42 .outdata = { 0 },
43 .outsize = 0,
44 .indata = { 0 },
45 .insize = sizeof(*resp),
46 };
47 int ret; 52 int ret;
48 53
49 ret = cros_ec_cmd_xfer(ec, &msg); 54 msg = kmalloc(sizeof(*msg) + sizeof(*resp), GFP_KERNEL);
55 if (!msg)
56 return -ENOMEM;
57
58 msg->version = 0;
59 msg->command = EC_CMD_GET_VERSION + ec->cmd_offset;
60 msg->insize = sizeof(*resp);
61 msg->outsize = 0;
62
63 ret = cros_ec_cmd_xfer(ec->ec_dev, msg);
50 if (ret < 0) 64 if (ret < 0)
51 return ret; 65 goto exit;
52 66
53 if (msg.result != EC_RES_SUCCESS) { 67 if (msg->result != EC_RES_SUCCESS) {
54 snprintf(str, maxlen, 68 snprintf(str, maxlen,
55 "%s\nUnknown EC version: EC returned %d\n", 69 "%s\nUnknown EC version: EC returned %d\n",
56 CROS_EC_DEV_VERSION, msg.result); 70 CROS_EC_DEV_VERSION, msg->result);
57 return 0; 71 ret = -EINVAL;
72 goto exit;
58 } 73 }
59 74
60 resp = (struct ec_response_get_version *)msg.indata; 75 resp = (struct ec_response_get_version *)msg->data;
61 if (resp->current_image >= ARRAY_SIZE(current_image_name)) 76 if (resp->current_image >= ARRAY_SIZE(current_image_name))
62 resp->current_image = 3; /* invalid */ 77 resp->current_image = 3; /* invalid */
63 78
@@ -65,14 +80,19 @@ static int ec_get_version(struct cros_ec_device *ec, char *str, int maxlen)
65 resp->version_string_ro, resp->version_string_rw, 80 resp->version_string_ro, resp->version_string_rw,
66 current_image_name[resp->current_image]); 81 current_image_name[resp->current_image]);
67 82
68 return 0; 83 ret = 0;
84exit:
85 kfree(msg);
86 return ret;
69} 87}
70 88
71/* Device file ops */ 89/* Device file ops */
72static int ec_device_open(struct inode *inode, struct file *filp) 90static int ec_device_open(struct inode *inode, struct file *filp)
73{ 91{
74 filp->private_data = container_of(inode->i_cdev, 92 struct cros_ec_dev *ec = container_of(inode->i_cdev,
75 struct cros_ec_device, cdev); 93 struct cros_ec_dev, cdev);
94 filp->private_data = ec;
95 nonseekable_open(inode, filp);
76 return 0; 96 return 0;
77} 97}
78 98
@@ -84,7 +104,7 @@ static int ec_device_release(struct inode *inode, struct file *filp)
84static ssize_t ec_device_read(struct file *filp, char __user *buffer, 104static ssize_t ec_device_read(struct file *filp, char __user *buffer,
85 size_t length, loff_t *offset) 105 size_t length, loff_t *offset)
86{ 106{
87 struct cros_ec_device *ec = filp->private_data; 107 struct cros_ec_dev *ec = filp->private_data;
88 char msg[sizeof(struct ec_response_get_version) + 108 char msg[sizeof(struct ec_response_get_version) +
89 sizeof(CROS_EC_DEV_VERSION)]; 109 sizeof(CROS_EC_DEV_VERSION)];
90 size_t count; 110 size_t count;
@@ -107,38 +127,53 @@ static ssize_t ec_device_read(struct file *filp, char __user *buffer,
107} 127}
108 128
109/* Ioctls */ 129/* Ioctls */
110static long ec_device_ioctl_xcmd(struct cros_ec_device *ec, void __user *arg) 130static long ec_device_ioctl_xcmd(struct cros_ec_dev *ec, void __user *arg)
111{ 131{
112 long ret; 132 long ret;
113 struct cros_ec_command s_cmd = { }; 133 struct cros_ec_command u_cmd;
134 struct cros_ec_command *s_cmd;
114 135
115 if (copy_from_user(&s_cmd, arg, sizeof(s_cmd))) 136 if (copy_from_user(&u_cmd, arg, sizeof(u_cmd)))
116 return -EFAULT; 137 return -EFAULT;
117 138
118 ret = cros_ec_cmd_xfer(ec, &s_cmd); 139 s_cmd = kmalloc(sizeof(*s_cmd) + max(u_cmd.outsize, u_cmd.insize),
140 GFP_KERNEL);
141 if (!s_cmd)
142 return -ENOMEM;
143
144 if (copy_from_user(s_cmd, arg, sizeof(*s_cmd) + u_cmd.outsize)) {
145 ret = -EFAULT;
146 goto exit;
147 }
148
149 s_cmd->command += ec->cmd_offset;
150 ret = cros_ec_cmd_xfer(ec->ec_dev, s_cmd);
119 /* Only copy data to userland if data was received. */ 151 /* Only copy data to userland if data was received. */
120 if (ret < 0) 152 if (ret < 0)
121 return ret; 153 goto exit;
122
123 if (copy_to_user(arg, &s_cmd, sizeof(s_cmd)))
124 return -EFAULT;
125 154
126 return 0; 155 if (copy_to_user(arg, s_cmd, sizeof(*s_cmd) + u_cmd.insize))
156 ret = -EFAULT;
157exit:
158 kfree(s_cmd);
159 return ret;
127} 160}
128 161
129static long ec_device_ioctl_readmem(struct cros_ec_device *ec, void __user *arg) 162static long ec_device_ioctl_readmem(struct cros_ec_dev *ec, void __user *arg)
130{ 163{
164 struct cros_ec_device *ec_dev = ec->ec_dev;
131 struct cros_ec_readmem s_mem = { }; 165 struct cros_ec_readmem s_mem = { };
132 long num; 166 long num;
133 167
134 /* Not every platform supports direct reads */ 168 /* Not every platform supports direct reads */
135 if (!ec->cmd_readmem) 169 if (!ec_dev->cmd_readmem)
136 return -ENOTTY; 170 return -ENOTTY;
137 171
138 if (copy_from_user(&s_mem, arg, sizeof(s_mem))) 172 if (copy_from_user(&s_mem, arg, sizeof(s_mem)))
139 return -EFAULT; 173 return -EFAULT;
140 174
141 num = ec->cmd_readmem(ec, s_mem.offset, s_mem.bytes, s_mem.buffer); 175 num = ec_dev->cmd_readmem(ec_dev, s_mem.offset, s_mem.bytes,
176 s_mem.buffer);
142 if (num <= 0) 177 if (num <= 0)
143 return num; 178 return num;
144 179
@@ -151,7 +186,7 @@ static long ec_device_ioctl_readmem(struct cros_ec_device *ec, void __user *arg)
151static long ec_device_ioctl(struct file *filp, unsigned int cmd, 186static long ec_device_ioctl(struct file *filp, unsigned int cmd,
152 unsigned long arg) 187 unsigned long arg)
153{ 188{
154 struct cros_ec_device *ec = filp->private_data; 189 struct cros_ec_dev *ec = filp->private_data;
155 190
156 if (_IOC_TYPE(cmd) != CROS_EC_DEV_IOC) 191 if (_IOC_TYPE(cmd) != CROS_EC_DEV_IOC)
157 return -ENOTTY; 192 return -ENOTTY;
@@ -174,45 +209,81 @@ static const struct file_operations fops = {
174 .unlocked_ioctl = ec_device_ioctl, 209 .unlocked_ioctl = ec_device_ioctl,
175}; 210};
176 211
212static void __remove(struct device *dev)
213{
214 struct cros_ec_dev *ec = container_of(dev, struct cros_ec_dev,
215 class_dev);
216 kfree(ec);
217}
218
177static int ec_device_probe(struct platform_device *pdev) 219static int ec_device_probe(struct platform_device *pdev)
178{ 220{
179 struct cros_ec_device *ec = dev_get_drvdata(pdev->dev.parent); 221 int retval = -ENOMEM;
180 int retval = -ENOTTY; 222 struct device *dev = &pdev->dev;
181 dev_t devno = MKDEV(ec_major, 0); 223 struct cros_ec_platform *ec_platform = dev_get_platdata(dev);
224 dev_t devno = MKDEV(ec_major, pdev->id);
225 struct cros_ec_dev *ec = kzalloc(sizeof(*ec), GFP_KERNEL);
226
227 if (!ec)
228 return retval;
182 229
183 /* Instantiate it (and remember the EC) */ 230 dev_set_drvdata(dev, ec);
231 ec->ec_dev = dev_get_drvdata(dev->parent);
232 ec->dev = dev;
233 ec->cmd_offset = ec_platform->cmd_offset;
234 device_initialize(&ec->class_dev);
184 cdev_init(&ec->cdev, &fops); 235 cdev_init(&ec->cdev, &fops);
185 236
237 /*
238 * Add the character device
239 * Link cdev to the class device to be sure device is not used
240 * before unbinding it.
241 */
242 ec->cdev.kobj.parent = &ec->class_dev.kobj;
186 retval = cdev_add(&ec->cdev, devno, 1); 243 retval = cdev_add(&ec->cdev, devno, 1);
187 if (retval) { 244 if (retval) {
188 dev_err(&pdev->dev, ": failed to add character device\n"); 245 dev_err(dev, ": failed to add character device\n");
189 return retval; 246 goto cdev_add_failed;
190 } 247 }
191 248
192 ec->vdev = device_create(cros_class, NULL, devno, ec, 249 /*
193 CROS_EC_DEV_NAME); 250 * Add the class device
194 if (IS_ERR(ec->vdev)) { 251 * Link to the character device for creating the /dev entry
195 retval = PTR_ERR(ec->vdev); 252 * in devtmpfs.
196 dev_err(&pdev->dev, ": failed to create device\n"); 253 */
197 cdev_del(&ec->cdev); 254 ec->class_dev.devt = ec->cdev.dev;
198 return retval; 255 ec->class_dev.class = &cros_class;
256 ec->class_dev.parent = dev;
257 ec->class_dev.release = __remove;
258
259 retval = dev_set_name(&ec->class_dev, "%s", ec_platform->ec_name);
260 if (retval) {
261 dev_err(dev, "dev_set_name failed => %d\n", retval);
262 goto set_named_failed;
199 } 263 }
200 264
201 /* Initialize extra interfaces */ 265 retval = device_add(&ec->class_dev);
202 ec_dev_sysfs_init(ec); 266 if (retval) {
203 ec_dev_lightbar_init(ec); 267 dev_err(dev, "device_register failed => %d\n", retval);
268 goto dev_reg_failed;
269 }
204 270
205 return 0; 271 return 0;
272
273dev_reg_failed:
274set_named_failed:
275 dev_set_drvdata(dev, NULL);
276 cdev_del(&ec->cdev);
277cdev_add_failed:
278 kfree(ec);
279 return retval;
206} 280}
207 281
208static int ec_device_remove(struct platform_device *pdev) 282static int ec_device_remove(struct platform_device *pdev)
209{ 283{
210 struct cros_ec_device *ec = dev_get_drvdata(pdev->dev.parent); 284 struct cros_ec_dev *ec = dev_get_drvdata(&pdev->dev);
211
212 ec_dev_lightbar_remove(ec);
213 ec_dev_sysfs_remove(ec);
214 device_destroy(cros_class, MKDEV(ec_major, 0));
215 cdev_del(&ec->cdev); 285 cdev_del(&ec->cdev);
286 device_unregister(&ec->class_dev);
216 return 0; 287 return 0;
217} 288}
218 289
@@ -229,10 +300,10 @@ static int __init cros_ec_dev_init(void)
229 int ret; 300 int ret;
230 dev_t dev = 0; 301 dev_t dev = 0;
231 302
232 cros_class = class_create(THIS_MODULE, "chromeos"); 303 ret = class_register(&cros_class);
233 if (IS_ERR(cros_class)) { 304 if (ret) {
234 pr_err(CROS_EC_DEV_NAME ": failed to register device class\n"); 305 pr_err(CROS_EC_DEV_NAME ": failed to register device class\n");
235 return PTR_ERR(cros_class); 306 return ret;
236 } 307 }
237 308
238 /* Get a range of minor numbers (starting with 0) to work with */ 309 /* Get a range of minor numbers (starting with 0) to work with */
@@ -254,7 +325,7 @@ static int __init cros_ec_dev_init(void)
254failed_devreg: 325failed_devreg:
255 unregister_chrdev_region(MKDEV(ec_major, 0), CROS_MAX_DEV); 326 unregister_chrdev_region(MKDEV(ec_major, 0), CROS_MAX_DEV);
256failed_chrdevreg: 327failed_chrdevreg:
257 class_destroy(cros_class); 328 class_unregister(&cros_class);
258 return ret; 329 return ret;
259} 330}
260 331
@@ -262,7 +333,7 @@ static void __exit cros_ec_dev_exit(void)
262{ 333{
263 platform_driver_unregister(&cros_ec_dev_driver); 334 platform_driver_unregister(&cros_ec_dev_driver);
264 unregister_chrdev(ec_major, CROS_EC_DEV_NAME); 335 unregister_chrdev(ec_major, CROS_EC_DEV_NAME);
265 class_destroy(cros_class); 336 class_unregister(&cros_class);
266} 337}
267 338
268module_init(cros_ec_dev_init); 339module_init(cros_ec_dev_init);
diff --git a/drivers/platform/chrome/cros_ec_dev.h b/drivers/platform/chrome/cros_ec_dev.h
index 45d67f7e518c..bfd2c84c3571 100644
--- a/drivers/platform/chrome/cros_ec_dev.h
+++ b/drivers/platform/chrome/cros_ec_dev.h
@@ -24,7 +24,6 @@
24#include <linux/types.h> 24#include <linux/types.h>
25#include <linux/mfd/cros_ec.h> 25#include <linux/mfd/cros_ec.h>
26 26
27#define CROS_EC_DEV_NAME "cros_ec"
28#define CROS_EC_DEV_VERSION "1.0.0" 27#define CROS_EC_DEV_VERSION "1.0.0"
29 28
30/* 29/*
@@ -44,10 +43,4 @@ struct cros_ec_readmem {
44#define CROS_EC_DEV_IOCXCMD _IOWR(CROS_EC_DEV_IOC, 0, struct cros_ec_command) 43#define CROS_EC_DEV_IOCXCMD _IOWR(CROS_EC_DEV_IOC, 0, struct cros_ec_command)
45#define CROS_EC_DEV_IOCRDMEM _IOWR(CROS_EC_DEV_IOC, 1, struct cros_ec_readmem) 44#define CROS_EC_DEV_IOCRDMEM _IOWR(CROS_EC_DEV_IOC, 1, struct cros_ec_readmem)
46 45
47void ec_dev_sysfs_init(struct cros_ec_device *);
48void ec_dev_sysfs_remove(struct cros_ec_device *);
49
50void ec_dev_lightbar_init(struct cros_ec_device *);
51void ec_dev_lightbar_remove(struct cros_ec_device *);
52
53#endif /* _CROS_EC_DEV_H_ */ 46#endif /* _CROS_EC_DEV_H_ */
diff --git a/drivers/platform/chrome/cros_ec_lightbar.c b/drivers/platform/chrome/cros_ec_lightbar.c
index b4ff47a9069a..144e09df9b84 100644
--- a/drivers/platform/chrome/cros_ec_lightbar.c
+++ b/drivers/platform/chrome/cros_ec_lightbar.c
@@ -31,6 +31,7 @@
31#include <linux/sched.h> 31#include <linux/sched.h>
32#include <linux/types.h> 32#include <linux/types.h>
33#include <linux/uaccess.h> 33#include <linux/uaccess.h>
34#include <linux/slab.h>
34 35
35#include "cros_ec_dev.h" 36#include "cros_ec_dev.h"
36 37
@@ -91,55 +92,81 @@ out:
91 return ret; 92 return ret;
92} 93}
93 94
94#define INIT_MSG(P, R) { \ 95static struct cros_ec_command *alloc_lightbar_cmd_msg(struct cros_ec_dev *ec)
95 .command = EC_CMD_LIGHTBAR_CMD, \ 96{
96 .outsize = sizeof(*P), \ 97 struct cros_ec_command *msg;
97 .insize = sizeof(*R), \ 98 int len;
98 } 99
100 len = max(sizeof(struct ec_params_lightbar),
101 sizeof(struct ec_response_lightbar));
102
103 msg = kmalloc(sizeof(*msg) + len, GFP_KERNEL);
104 if (!msg)
105 return NULL;
106
107 msg->version = 0;
108 msg->command = EC_CMD_LIGHTBAR_CMD + ec->cmd_offset;
109 msg->outsize = sizeof(struct ec_params_lightbar);
110 msg->insize = sizeof(struct ec_response_lightbar);
111
112 return msg;
113}
99 114
100static int get_lightbar_version(struct cros_ec_device *ec, 115static int get_lightbar_version(struct cros_ec_dev *ec,
101 uint32_t *ver_ptr, uint32_t *flg_ptr) 116 uint32_t *ver_ptr, uint32_t *flg_ptr)
102{ 117{
103 struct ec_params_lightbar *param; 118 struct ec_params_lightbar *param;
104 struct ec_response_lightbar *resp; 119 struct ec_response_lightbar *resp;
105 struct cros_ec_command msg = INIT_MSG(param, resp); 120 struct cros_ec_command *msg;
106 int ret; 121 int ret;
107 122
108 param = (struct ec_params_lightbar *)msg.outdata; 123 msg = alloc_lightbar_cmd_msg(ec);
109 param->cmd = LIGHTBAR_CMD_VERSION; 124 if (!msg)
110 ret = cros_ec_cmd_xfer(ec, &msg);
111 if (ret < 0)
112 return 0; 125 return 0;
113 126
114 switch (msg.result) { 127 param = (struct ec_params_lightbar *)msg->data;
128 param->cmd = LIGHTBAR_CMD_VERSION;
129 ret = cros_ec_cmd_xfer(ec->ec_dev, msg);
130 if (ret < 0) {
131 ret = 0;
132 goto exit;
133 }
134
135 switch (msg->result) {
115 case EC_RES_INVALID_PARAM: 136 case EC_RES_INVALID_PARAM:
116 /* Pixel had no version command. */ 137 /* Pixel had no version command. */
117 if (ver_ptr) 138 if (ver_ptr)
118 *ver_ptr = 0; 139 *ver_ptr = 0;
119 if (flg_ptr) 140 if (flg_ptr)
120 *flg_ptr = 0; 141 *flg_ptr = 0;
121 return 1; 142 ret = 1;
143 goto exit;
122 144
123 case EC_RES_SUCCESS: 145 case EC_RES_SUCCESS:
124 resp = (struct ec_response_lightbar *)msg.indata; 146 resp = (struct ec_response_lightbar *)msg->data;
125 147
126 /* Future devices w/lightbars should implement this command */ 148 /* Future devices w/lightbars should implement this command */
127 if (ver_ptr) 149 if (ver_ptr)
128 *ver_ptr = resp->version.num; 150 *ver_ptr = resp->version.num;
129 if (flg_ptr) 151 if (flg_ptr)
130 *flg_ptr = resp->version.flags; 152 *flg_ptr = resp->version.flags;
131 return 1; 153 ret = 1;
154 goto exit;
132 } 155 }
133 156
134 /* Anything else (ie, EC_RES_INVALID_COMMAND) - no lightbar */ 157 /* Anything else (ie, EC_RES_INVALID_COMMAND) - no lightbar */
135 return 0; 158 ret = 0;
159exit:
160 kfree(msg);
161 return ret;
136} 162}
137 163
138static ssize_t version_show(struct device *dev, 164static ssize_t version_show(struct device *dev,
139 struct device_attribute *attr, char *buf) 165 struct device_attribute *attr, char *buf)
140{ 166{
141 uint32_t version, flags; 167 uint32_t version = 0, flags = 0;
142 struct cros_ec_device *ec = dev_get_drvdata(dev); 168 struct cros_ec_dev *ec = container_of(dev,
169 struct cros_ec_dev, class_dev);
143 int ret; 170 int ret;
144 171
145 ret = lb_throttle(); 172 ret = lb_throttle();
@@ -158,30 +185,39 @@ static ssize_t brightness_store(struct device *dev,
158 const char *buf, size_t count) 185 const char *buf, size_t count)
159{ 186{
160 struct ec_params_lightbar *param; 187 struct ec_params_lightbar *param;
161 struct ec_response_lightbar *resp; 188 struct cros_ec_command *msg;
162 struct cros_ec_command msg = INIT_MSG(param, resp);
163 int ret; 189 int ret;
164 unsigned int val; 190 unsigned int val;
165 struct cros_ec_device *ec = dev_get_drvdata(dev); 191 struct cros_ec_dev *ec = container_of(dev,
192 struct cros_ec_dev, class_dev);
166 193
167 if (kstrtouint(buf, 0, &val)) 194 if (kstrtouint(buf, 0, &val))
168 return -EINVAL; 195 return -EINVAL;
169 196
170 param = (struct ec_params_lightbar *)msg.outdata; 197 msg = alloc_lightbar_cmd_msg(ec);
171 param->cmd = LIGHTBAR_CMD_BRIGHTNESS; 198 if (!msg)
172 param->brightness.num = val; 199 return -ENOMEM;
200
201 param = (struct ec_params_lightbar *)msg->data;
202 param->cmd = LIGHTBAR_CMD_SET_BRIGHTNESS;
203 param->set_brightness.num = val;
173 ret = lb_throttle(); 204 ret = lb_throttle();
174 if (ret) 205 if (ret)
175 return ret; 206 goto exit;
176 207
177 ret = cros_ec_cmd_xfer(ec, &msg); 208 ret = cros_ec_cmd_xfer(ec->ec_dev, msg);
178 if (ret < 0) 209 if (ret < 0)
179 return ret; 210 goto exit;
180 211
181 if (msg.result != EC_RES_SUCCESS) 212 if (msg->result != EC_RES_SUCCESS) {
182 return -EINVAL; 213 ret = -EINVAL;
214 goto exit;
215 }
183 216
184 return count; 217 ret = count;
218exit:
219 kfree(msg);
220 return ret;
185} 221}
186 222
187 223
@@ -196,12 +232,16 @@ static ssize_t led_rgb_store(struct device *dev, struct device_attribute *attr,
196 const char *buf, size_t count) 232 const char *buf, size_t count)
197{ 233{
198 struct ec_params_lightbar *param; 234 struct ec_params_lightbar *param;
199 struct ec_response_lightbar *resp; 235 struct cros_ec_command *msg;
200 struct cros_ec_command msg = INIT_MSG(param, resp); 236 struct cros_ec_dev *ec = container_of(dev,
201 struct cros_ec_device *ec = dev_get_drvdata(dev); 237 struct cros_ec_dev, class_dev);
202 unsigned int val[4]; 238 unsigned int val[4];
203 int ret, i = 0, j = 0, ok = 0; 239 int ret, i = 0, j = 0, ok = 0;
204 240
241 msg = alloc_lightbar_cmd_msg(ec);
242 if (!msg)
243 return -ENOMEM;
244
205 do { 245 do {
206 /* Skip any whitespace */ 246 /* Skip any whitespace */
207 while (*buf && isspace(*buf)) 247 while (*buf && isspace(*buf))
@@ -215,12 +255,12 @@ static ssize_t led_rgb_store(struct device *dev, struct device_attribute *attr,
215 return -EINVAL; 255 return -EINVAL;
216 256
217 if (i == 4) { 257 if (i == 4) {
218 param = (struct ec_params_lightbar *)msg.outdata; 258 param = (struct ec_params_lightbar *)msg->data;
219 param->cmd = LIGHTBAR_CMD_RGB; 259 param->cmd = LIGHTBAR_CMD_SET_RGB;
220 param->rgb.led = val[0]; 260 param->set_rgb.led = val[0];
221 param->rgb.red = val[1]; 261 param->set_rgb.red = val[1];
222 param->rgb.green = val[2]; 262 param->set_rgb.green = val[2];
223 param->rgb.blue = val[3]; 263 param->set_rgb.blue = val[3];
224 /* 264 /*
225 * Throttle only the first of every four transactions, 265 * Throttle only the first of every four transactions,
226 * so that the user can update all four LEDs at once. 266 * so that the user can update all four LEDs at once.
@@ -231,12 +271,14 @@ static ssize_t led_rgb_store(struct device *dev, struct device_attribute *attr,
231 return ret; 271 return ret;
232 } 272 }
233 273
234 ret = cros_ec_cmd_xfer(ec, &msg); 274 ret = cros_ec_cmd_xfer(ec->ec_dev, msg);
235 if (ret < 0) 275 if (ret < 0)
236 return ret; 276 goto exit;
237 277
238 if (msg.result != EC_RES_SUCCESS) 278 if (msg->result != EC_RES_SUCCESS) {
239 return -EINVAL; 279 ret = -EINVAL;
280 goto exit;
281 }
240 282
241 i = 0; 283 i = 0;
242 ok = 1; 284 ok = 1;
@@ -248,6 +290,8 @@ static ssize_t led_rgb_store(struct device *dev, struct device_attribute *attr,
248 290
249 } while (*buf); 291 } while (*buf);
250 292
293exit:
294 kfree(msg);
251 return (ok && i == 0) ? count : -EINVAL; 295 return (ok && i == 0) ? count : -EINVAL;
252} 296}
253 297
@@ -261,41 +305,56 @@ static ssize_t sequence_show(struct device *dev,
261{ 305{
262 struct ec_params_lightbar *param; 306 struct ec_params_lightbar *param;
263 struct ec_response_lightbar *resp; 307 struct ec_response_lightbar *resp;
264 struct cros_ec_command msg = INIT_MSG(param, resp); 308 struct cros_ec_command *msg;
265 int ret; 309 int ret;
266 struct cros_ec_device *ec = dev_get_drvdata(dev); 310 struct cros_ec_dev *ec = container_of(dev,
311 struct cros_ec_dev, class_dev);
312
313 msg = alloc_lightbar_cmd_msg(ec);
314 if (!msg)
315 return -ENOMEM;
267 316
268 param = (struct ec_params_lightbar *)msg.outdata; 317 param = (struct ec_params_lightbar *)msg->data;
269 param->cmd = LIGHTBAR_CMD_GET_SEQ; 318 param->cmd = LIGHTBAR_CMD_GET_SEQ;
270 ret = lb_throttle(); 319 ret = lb_throttle();
271 if (ret) 320 if (ret)
272 return ret; 321 goto exit;
273 322
274 ret = cros_ec_cmd_xfer(ec, &msg); 323 ret = cros_ec_cmd_xfer(ec->ec_dev, msg);
275 if (ret < 0) 324 if (ret < 0)
276 return ret; 325 goto exit;
277 326
278 if (msg.result != EC_RES_SUCCESS) 327 if (msg->result != EC_RES_SUCCESS) {
279 return scnprintf(buf, PAGE_SIZE, 328 ret = scnprintf(buf, PAGE_SIZE,
280 "ERROR: EC returned %d\n", msg.result); 329 "ERROR: EC returned %d\n", msg->result);
330 goto exit;
331 }
281 332
282 resp = (struct ec_response_lightbar *)msg.indata; 333 resp = (struct ec_response_lightbar *)msg->data;
283 if (resp->get_seq.num >= ARRAY_SIZE(seqname)) 334 if (resp->get_seq.num >= ARRAY_SIZE(seqname))
284 return scnprintf(buf, PAGE_SIZE, "%d\n", resp->get_seq.num); 335 ret = scnprintf(buf, PAGE_SIZE, "%d\n", resp->get_seq.num);
285 else 336 else
286 return scnprintf(buf, PAGE_SIZE, "%s\n", 337 ret = scnprintf(buf, PAGE_SIZE, "%s\n",
287 seqname[resp->get_seq.num]); 338 seqname[resp->get_seq.num]);
339
340exit:
341 kfree(msg);
342 return ret;
288} 343}
289 344
290static ssize_t sequence_store(struct device *dev, struct device_attribute *attr, 345static ssize_t sequence_store(struct device *dev, struct device_attribute *attr,
291 const char *buf, size_t count) 346 const char *buf, size_t count)
292{ 347{
293 struct ec_params_lightbar *param; 348 struct ec_params_lightbar *param;
294 struct ec_response_lightbar *resp; 349 struct cros_ec_command *msg;
295 struct cros_ec_command msg = INIT_MSG(param, resp);
296 unsigned int num; 350 unsigned int num;
297 int ret, len; 351 int ret, len;
298 struct cros_ec_device *ec = dev_get_drvdata(dev); 352 struct cros_ec_dev *ec = container_of(dev,
353 struct cros_ec_dev, class_dev);
354
355 msg = alloc_lightbar_cmd_msg(ec);
356 if (!msg)
357 return -ENOMEM;
299 358
300 for (len = 0; len < count; len++) 359 for (len = 0; len < count; len++)
301 if (!isalnum(buf[len])) 360 if (!isalnum(buf[len]))
@@ -311,18 +370,18 @@ static ssize_t sequence_store(struct device *dev, struct device_attribute *attr,
311 return ret; 370 return ret;
312 } 371 }
313 372
314 param = (struct ec_params_lightbar *)msg.outdata; 373 param = (struct ec_params_lightbar *)msg->data;
315 param->cmd = LIGHTBAR_CMD_SEQ; 374 param->cmd = LIGHTBAR_CMD_SEQ;
316 param->seq.num = num; 375 param->seq.num = num;
317 ret = lb_throttle(); 376 ret = lb_throttle();
318 if (ret) 377 if (ret)
319 return ret; 378 return ret;
320 379
321 ret = cros_ec_cmd_xfer(ec, &msg); 380 ret = cros_ec_cmd_xfer(ec->ec_dev, msg);
322 if (ret < 0) 381 if (ret < 0)
323 return ret; 382 return ret;
324 383
325 if (msg.result != EC_RES_SUCCESS) 384 if (msg->result != EC_RES_SUCCESS)
326 return -EINVAL; 385 return -EINVAL;
327 386
328 return count; 387 return count;
@@ -343,25 +402,27 @@ static struct attribute *__lb_cmds_attrs[] = {
343 &dev_attr_sequence.attr, 402 &dev_attr_sequence.attr,
344 NULL, 403 NULL,
345}; 404};
346static struct attribute_group lb_cmds_attr_group = {
347 .name = "lightbar",
348 .attrs = __lb_cmds_attrs,
349};
350 405
351void ec_dev_lightbar_init(struct cros_ec_device *ec) 406static umode_t cros_ec_lightbar_attrs_are_visible(struct kobject *kobj,
407 struct attribute *a, int n)
352{ 408{
353 int ret = 0; 409 struct device *dev = container_of(kobj, struct device, kobj);
410 struct cros_ec_dev *ec = container_of(dev,
411 struct cros_ec_dev, class_dev);
412 struct platform_device *pdev = container_of(ec->dev,
413 struct platform_device, dev);
414 if (pdev->id != 0)
415 return 0;
354 416
355 /* Only instantiate this stuff if the EC has a lightbar */ 417 /* Only instantiate this stuff if the EC has a lightbar */
356 if (!get_lightbar_version(ec, NULL, NULL)) 418 if (get_lightbar_version(ec, NULL, NULL))
357 return; 419 return a->mode;
358 420 else
359 ret = sysfs_create_group(&ec->vdev->kobj, &lb_cmds_attr_group); 421 return 0;
360 if (ret)
361 pr_warn("sysfs_create_group() failed: %d\n", ret);
362} 422}
363 423
364void ec_dev_lightbar_remove(struct cros_ec_device *ec) 424struct attribute_group cros_ec_lightbar_attr_group = {
365{ 425 .name = "lightbar",
366 sysfs_remove_group(&ec->vdev->kobj, &lb_cmds_attr_group); 426 .attrs = __lb_cmds_attrs,
367} 427 .is_visible = cros_ec_lightbar_attrs_are_visible,
428};
diff --git a/drivers/platform/chrome/cros_ec_lpc.c b/drivers/platform/chrome/cros_ec_lpc.c
index 8f9ac4d7bbd0..bdd77ce45f05 100644
--- a/drivers/platform/chrome/cros_ec_lpc.c
+++ b/drivers/platform/chrome/cros_ec_lpc.c
@@ -46,6 +46,77 @@ static int ec_response_timed_out(void)
46 return 1; 46 return 1;
47} 47}
48 48
49static int cros_ec_pkt_xfer_lpc(struct cros_ec_device *ec,
50 struct cros_ec_command *msg)
51{
52 struct ec_host_request *request;
53 struct ec_host_response response;
54 u8 sum = 0;
55 int i;
56 int ret = 0;
57 u8 *dout;
58
59 ret = cros_ec_prepare_tx(ec, msg);
60
61 /* Write buffer */
62 for (i = 0; i < ret; i++)
63 outb(ec->dout[i], EC_LPC_ADDR_HOST_PACKET + i);
64
65 request = (struct ec_host_request *)ec->dout;
66
67 /* Here we go */
68 outb(EC_COMMAND_PROTOCOL_3, EC_LPC_ADDR_HOST_CMD);
69
70 if (ec_response_timed_out()) {
71 dev_warn(ec->dev, "EC responsed timed out\n");
72 ret = -EIO;
73 goto done;
74 }
75
76 /* Check result */
77 msg->result = inb(EC_LPC_ADDR_HOST_DATA);
78 ret = cros_ec_check_result(ec, msg);
79 if (ret)
80 goto done;
81
82 /* Read back response */
83 dout = (u8 *)&response;
84 for (i = 0; i < sizeof(response); i++) {
85 dout[i] = inb(EC_LPC_ADDR_HOST_PACKET + i);
86 sum += dout[i];
87 }
88
89 msg->result = response.result;
90
91 if (response.data_len > msg->insize) {
92 dev_err(ec->dev,
93 "packet too long (%d bytes, expected %d)",
94 response.data_len, msg->insize);
95 ret = -EMSGSIZE;
96 goto done;
97 }
98
99 /* Read response and process checksum */
100 for (i = 0; i < response.data_len; i++) {
101 msg->data[i] =
102 inb(EC_LPC_ADDR_HOST_PACKET + sizeof(response) + i);
103 sum += msg->data[i];
104 }
105
106 if (sum) {
107 dev_err(ec->dev,
108 "bad packet checksum %02x\n",
109 response.checksum);
110 ret = -EBADMSG;
111 goto done;
112 }
113
114 /* Return actual amount of data received */
115 ret = response.data_len;
116done:
117 return ret;
118}
119
49static int cros_ec_cmd_xfer_lpc(struct cros_ec_device *ec, 120static int cros_ec_cmd_xfer_lpc(struct cros_ec_device *ec,
50 struct cros_ec_command *msg) 121 struct cros_ec_command *msg)
51{ 122{
@@ -73,8 +144,8 @@ static int cros_ec_cmd_xfer_lpc(struct cros_ec_device *ec,
73 144
74 /* Copy data and update checksum */ 145 /* Copy data and update checksum */
75 for (i = 0; i < msg->outsize; i++) { 146 for (i = 0; i < msg->outsize; i++) {
76 outb(msg->outdata[i], EC_LPC_ADDR_HOST_PARAM + i); 147 outb(msg->data[i], EC_LPC_ADDR_HOST_PARAM + i);
77 csum += msg->outdata[i]; 148 csum += msg->data[i];
78 } 149 }
79 150
80 /* Finalize checksum and write args */ 151 /* Finalize checksum and write args */
@@ -129,8 +200,8 @@ static int cros_ec_cmd_xfer_lpc(struct cros_ec_device *ec,
129 200
130 /* Read response and update checksum */ 201 /* Read response and update checksum */
131 for (i = 0; i < args.data_size; i++) { 202 for (i = 0; i < args.data_size; i++) {
132 msg->indata[i] = inb(EC_LPC_ADDR_HOST_PARAM + i); 203 msg->data[i] = inb(EC_LPC_ADDR_HOST_PARAM + i);
133 csum += msg->indata[i]; 204 csum += msg->data[i];
134 } 205 }
135 206
136 /* Verify checksum */ 207 /* Verify checksum */
@@ -212,11 +283,13 @@ static int cros_ec_lpc_probe(struct platform_device *pdev)
212 283
213 platform_set_drvdata(pdev, ec_dev); 284 platform_set_drvdata(pdev, ec_dev);
214 ec_dev->dev = dev; 285 ec_dev->dev = dev;
215 ec_dev->ec_name = pdev->name;
216 ec_dev->phys_name = dev_name(dev); 286 ec_dev->phys_name = dev_name(dev);
217 ec_dev->parent = dev;
218 ec_dev->cmd_xfer = cros_ec_cmd_xfer_lpc; 287 ec_dev->cmd_xfer = cros_ec_cmd_xfer_lpc;
288 ec_dev->pkt_xfer = cros_ec_pkt_xfer_lpc;
219 ec_dev->cmd_readmem = cros_ec_lpc_readmem; 289 ec_dev->cmd_readmem = cros_ec_lpc_readmem;
290 ec_dev->din_size = sizeof(struct ec_host_response) +
291 sizeof(struct ec_response_get_protocol_info);
292 ec_dev->dout_size = sizeof(struct ec_host_request);
220 293
221 ret = cros_ec_register(ec_dev); 294 ret = cros_ec_register(ec_dev);
222 if (ret) { 295 if (ret) {
diff --git a/drivers/platform/chrome/cros_ec_proto.c b/drivers/platform/chrome/cros_ec_proto.c
new file mode 100644
index 000000000000..990308ca384f
--- /dev/null
+++ b/drivers/platform/chrome/cros_ec_proto.c
@@ -0,0 +1,382 @@
1/*
2 * ChromeOS EC communication protocol helper functions
3 *
4 * Copyright (C) 2015 Google, Inc
5 *
6 * This software is licensed under the terms of the GNU General Public
7 * License version 2, as published by the Free Software Foundation, and
8 * may be copied, distributed, and modified under those terms.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 */
16
17#include <linux/mfd/cros_ec.h>
18#include <linux/delay.h>
19#include <linux/device.h>
20#include <linux/module.h>
21#include <linux/slab.h>
22
23#define EC_COMMAND_RETRIES 50
24
25static int prepare_packet(struct cros_ec_device *ec_dev,
26 struct cros_ec_command *msg)
27{
28 struct ec_host_request *request;
29 u8 *out;
30 int i;
31 u8 csum = 0;
32
33 BUG_ON(ec_dev->proto_version != EC_HOST_REQUEST_VERSION);
34 BUG_ON(msg->outsize + sizeof(*request) > ec_dev->dout_size);
35
36 out = ec_dev->dout;
37 request = (struct ec_host_request *)out;
38 request->struct_version = EC_HOST_REQUEST_VERSION;
39 request->checksum = 0;
40 request->command = msg->command;
41 request->command_version = msg->version;
42 request->reserved = 0;
43 request->data_len = msg->outsize;
44
45 for (i = 0; i < sizeof(*request); i++)
46 csum += out[i];
47
48 /* Copy data and update checksum */
49 memcpy(out + sizeof(*request), msg->data, msg->outsize);
50 for (i = 0; i < msg->outsize; i++)
51 csum += msg->data[i];
52
53 request->checksum = -csum;
54
55 return sizeof(*request) + msg->outsize;
56}
57
58static int send_command(struct cros_ec_device *ec_dev,
59 struct cros_ec_command *msg)
60{
61 int ret;
62
63 if (ec_dev->proto_version > 2)
64 ret = ec_dev->pkt_xfer(ec_dev, msg);
65 else
66 ret = ec_dev->cmd_xfer(ec_dev, msg);
67
68 if (msg->result == EC_RES_IN_PROGRESS) {
69 int i;
70 struct cros_ec_command *status_msg;
71 struct ec_response_get_comms_status *status;
72
73 status_msg = kmalloc(sizeof(*status_msg) + sizeof(*status),
74 GFP_KERNEL);
75 if (!status_msg)
76 return -ENOMEM;
77
78 status_msg->version = 0;
79 status_msg->command = EC_CMD_GET_COMMS_STATUS;
80 status_msg->insize = sizeof(*status);
81 status_msg->outsize = 0;
82
83 /*
84 * Query the EC's status until it's no longer busy or
85 * we encounter an error.
86 */
87 for (i = 0; i < EC_COMMAND_RETRIES; i++) {
88 usleep_range(10000, 11000);
89
90 ret = ec_dev->cmd_xfer(ec_dev, status_msg);
91 if (ret < 0)
92 break;
93
94 msg->result = status_msg->result;
95 if (status_msg->result != EC_RES_SUCCESS)
96 break;
97
98 status = (struct ec_response_get_comms_status *)
99 status_msg->data;
100 if (!(status->flags & EC_COMMS_STATUS_PROCESSING))
101 break;
102 }
103
104 kfree(status_msg);
105 }
106
107 return ret;
108}
109
110int cros_ec_prepare_tx(struct cros_ec_device *ec_dev,
111 struct cros_ec_command *msg)
112{
113 u8 *out;
114 u8 csum;
115 int i;
116
117 if (ec_dev->proto_version > 2)
118 return prepare_packet(ec_dev, msg);
119
120 BUG_ON(msg->outsize > EC_PROTO2_MAX_PARAM_SIZE);
121 out = ec_dev->dout;
122 out[0] = EC_CMD_VERSION0 + msg->version;
123 out[1] = msg->command;
124 out[2] = msg->outsize;
125 csum = out[0] + out[1] + out[2];
126 for (i = 0; i < msg->outsize; i++)
127 csum += out[EC_MSG_TX_HEADER_BYTES + i] = msg->data[i];
128 out[EC_MSG_TX_HEADER_BYTES + msg->outsize] = csum;
129
130 return EC_MSG_TX_PROTO_BYTES + msg->outsize;
131}
132EXPORT_SYMBOL(cros_ec_prepare_tx);
133
134int cros_ec_check_result(struct cros_ec_device *ec_dev,
135 struct cros_ec_command *msg)
136{
137 switch (msg->result) {
138 case EC_RES_SUCCESS:
139 return 0;
140 case EC_RES_IN_PROGRESS:
141 dev_dbg(ec_dev->dev, "command 0x%02x in progress\n",
142 msg->command);
143 return -EAGAIN;
144 default:
145 dev_dbg(ec_dev->dev, "command 0x%02x returned %d\n",
146 msg->command, msg->result);
147 return 0;
148 }
149}
150EXPORT_SYMBOL(cros_ec_check_result);
151
152static int cros_ec_host_command_proto_query(struct cros_ec_device *ec_dev,
153 int devidx,
154 struct cros_ec_command *msg)
155{
156 /*
157 * Try using v3+ to query for supported protocols. If this
158 * command fails, fall back to v2. Returns the highest protocol
159 * supported by the EC.
160 * Also sets the max request/response/passthru size.
161 */
162 int ret;
163
164 if (!ec_dev->pkt_xfer)
165 return -EPROTONOSUPPORT;
166
167 memset(msg, 0, sizeof(*msg));
168 msg->command = EC_CMD_PASSTHRU_OFFSET(devidx) | EC_CMD_GET_PROTOCOL_INFO;
169 msg->insize = sizeof(struct ec_response_get_protocol_info);
170
171 ret = send_command(ec_dev, msg);
172
173 if (ret < 0) {
174 dev_dbg(ec_dev->dev,
175 "failed to check for EC[%d] protocol version: %d\n",
176 devidx, ret);
177 return ret;
178 }
179
180 if (devidx > 0 && msg->result == EC_RES_INVALID_COMMAND)
181 return -ENODEV;
182 else if (msg->result != EC_RES_SUCCESS)
183 return msg->result;
184
185 return 0;
186}
187
188static int cros_ec_host_command_proto_query_v2(struct cros_ec_device *ec_dev)
189{
190 struct cros_ec_command *msg;
191 struct ec_params_hello *hello_params;
192 struct ec_response_hello *hello_response;
193 int ret;
194 int len = max(sizeof(*hello_params), sizeof(*hello_response));
195
196 msg = kmalloc(sizeof(*msg) + len, GFP_KERNEL);
197 if (!msg)
198 return -ENOMEM;
199
200 msg->version = 0;
201 msg->command = EC_CMD_HELLO;
202 hello_params = (struct ec_params_hello *)msg->data;
203 msg->outsize = sizeof(*hello_params);
204 hello_response = (struct ec_response_hello *)msg->data;
205 msg->insize = sizeof(*hello_response);
206
207 hello_params->in_data = 0xa0b0c0d0;
208
209 ret = send_command(ec_dev, msg);
210
211 if (ret < 0) {
212 dev_dbg(ec_dev->dev,
213 "EC failed to respond to v2 hello: %d\n",
214 ret);
215 goto exit;
216 } else if (msg->result != EC_RES_SUCCESS) {
217 dev_err(ec_dev->dev,
218 "EC responded to v2 hello with error: %d\n",
219 msg->result);
220 ret = msg->result;
221 goto exit;
222 } else if (hello_response->out_data != 0xa1b2c3d4) {
223 dev_err(ec_dev->dev,
224 "EC responded to v2 hello with bad result: %u\n",
225 hello_response->out_data);
226 ret = -EBADMSG;
227 goto exit;
228 }
229
230 ret = 0;
231
232 exit:
233 kfree(msg);
234 return ret;
235}
236
237int cros_ec_query_all(struct cros_ec_device *ec_dev)
238{
239 struct device *dev = ec_dev->dev;
240 struct cros_ec_command *proto_msg;
241 struct ec_response_get_protocol_info *proto_info;
242 int ret;
243
244 proto_msg = kzalloc(sizeof(*proto_msg) + sizeof(*proto_info),
245 GFP_KERNEL);
246 if (!proto_msg)
247 return -ENOMEM;
248
249 /* First try sending with proto v3. */
250 ec_dev->proto_version = 3;
251 ret = cros_ec_host_command_proto_query(ec_dev, 0, proto_msg);
252
253 if (ret == 0) {
254 proto_info = (struct ec_response_get_protocol_info *)
255 proto_msg->data;
256 ec_dev->max_request = proto_info->max_request_packet_size -
257 sizeof(struct ec_host_request);
258 ec_dev->max_response = proto_info->max_response_packet_size -
259 sizeof(struct ec_host_response);
260 ec_dev->proto_version =
261 min(EC_HOST_REQUEST_VERSION,
262 fls(proto_info->protocol_versions) - 1);
263 dev_dbg(ec_dev->dev,
264 "using proto v%u\n",
265 ec_dev->proto_version);
266
267 ec_dev->din_size = ec_dev->max_response +
268 sizeof(struct ec_host_response) +
269 EC_MAX_RESPONSE_OVERHEAD;
270 ec_dev->dout_size = ec_dev->max_request +
271 sizeof(struct ec_host_request) +
272 EC_MAX_REQUEST_OVERHEAD;
273
274 /*
275 * Check for PD
276 */
277 ret = cros_ec_host_command_proto_query(ec_dev, 1, proto_msg);
278
279 if (ret) {
280 dev_dbg(ec_dev->dev, "no PD chip found: %d\n", ret);
281 ec_dev->max_passthru = 0;
282 } else {
283 dev_dbg(ec_dev->dev, "found PD chip\n");
284 ec_dev->max_passthru =
285 proto_info->max_request_packet_size -
286 sizeof(struct ec_host_request);
287 }
288 } else {
289 /* Try querying with a v2 hello message. */
290 ec_dev->proto_version = 2;
291 ret = cros_ec_host_command_proto_query_v2(ec_dev);
292
293 if (ret == 0) {
294 /* V2 hello succeeded. */
295 dev_dbg(ec_dev->dev, "falling back to proto v2\n");
296
297 ec_dev->max_request = EC_PROTO2_MAX_PARAM_SIZE;
298 ec_dev->max_response = EC_PROTO2_MAX_PARAM_SIZE;
299 ec_dev->max_passthru = 0;
300 ec_dev->pkt_xfer = NULL;
301 ec_dev->din_size = EC_MSG_BYTES;
302 ec_dev->dout_size = EC_MSG_BYTES;
303 } else {
304 /*
305 * It's possible for a test to occur too early when
306 * the EC isn't listening. If this happens, we'll
307 * test later when the first command is run.
308 */
309 ec_dev->proto_version = EC_PROTO_VERSION_UNKNOWN;
310 dev_dbg(ec_dev->dev, "EC query failed: %d\n", ret);
311 goto exit;
312 }
313 }
314
315 devm_kfree(dev, ec_dev->din);
316 devm_kfree(dev, ec_dev->dout);
317
318 ec_dev->din = devm_kzalloc(dev, ec_dev->din_size, GFP_KERNEL);
319 if (!ec_dev->din) {
320 ret = -ENOMEM;
321 goto exit;
322 }
323
324 ec_dev->dout = devm_kzalloc(dev, ec_dev->dout_size, GFP_KERNEL);
325 if (!ec_dev->dout) {
326 devm_kfree(dev, ec_dev->din);
327 ret = -ENOMEM;
328 goto exit;
329 }
330
331exit:
332 kfree(proto_msg);
333 return ret;
334}
335EXPORT_SYMBOL(cros_ec_query_all);
336
337int cros_ec_cmd_xfer(struct cros_ec_device *ec_dev,
338 struct cros_ec_command *msg)
339{
340 int ret;
341
342 mutex_lock(&ec_dev->lock);
343 if (ec_dev->proto_version == EC_PROTO_VERSION_UNKNOWN) {
344 ret = cros_ec_query_all(ec_dev);
345 if (ret) {
346 dev_err(ec_dev->dev,
347 "EC version unknown and query failed; aborting command\n");
348 mutex_unlock(&ec_dev->lock);
349 return ret;
350 }
351 }
352
353 if (msg->insize > ec_dev->max_response) {
354 dev_dbg(ec_dev->dev, "clamping message receive buffer\n");
355 msg->insize = ec_dev->max_response;
356 }
357
358 if (msg->command < EC_CMD_PASSTHRU_OFFSET(1)) {
359 if (msg->outsize > ec_dev->max_request) {
360 dev_err(ec_dev->dev,
361 "request of size %u is too big (max: %u)\n",
362 msg->outsize,
363 ec_dev->max_request);
364 mutex_unlock(&ec_dev->lock);
365 return -EMSGSIZE;
366 }
367 } else {
368 if (msg->outsize > ec_dev->max_passthru) {
369 dev_err(ec_dev->dev,
370 "passthru rq of size %u is too big (max: %u)\n",
371 msg->outsize,
372 ec_dev->max_passthru);
373 mutex_unlock(&ec_dev->lock);
374 return -EMSGSIZE;
375 }
376 }
377 ret = send_command(ec_dev, msg);
378 mutex_unlock(&ec_dev->lock);
379
380 return ret;
381}
382EXPORT_SYMBOL(cros_ec_cmd_xfer);
diff --git a/drivers/platform/chrome/cros_ec_sysfs.c b/drivers/platform/chrome/cros_ec_sysfs.c
index fb62ab6cc659..f3baf9973989 100644
--- a/drivers/platform/chrome/cros_ec_sysfs.c
+++ b/drivers/platform/chrome/cros_ec_sysfs.c
@@ -29,6 +29,7 @@
29#include <linux/module.h> 29#include <linux/module.h>
30#include <linux/platform_device.h> 30#include <linux/platform_device.h>
31#include <linux/printk.h> 31#include <linux/printk.h>
32#include <linux/slab.h>
32#include <linux/stat.h> 33#include <linux/stat.h>
33#include <linux/types.h> 34#include <linux/types.h>
34#include <linux/uaccess.h> 35#include <linux/uaccess.h>
@@ -66,13 +67,19 @@ static ssize_t store_ec_reboot(struct device *dev,
66 {"hibernate", EC_REBOOT_HIBERNATE, 0}, 67 {"hibernate", EC_REBOOT_HIBERNATE, 0},
67 {"at-shutdown", -1, EC_REBOOT_FLAG_ON_AP_SHUTDOWN}, 68 {"at-shutdown", -1, EC_REBOOT_FLAG_ON_AP_SHUTDOWN},
68 }; 69 };
69 struct cros_ec_command msg = { 0 }; 70 struct cros_ec_command *msg;
70 struct ec_params_reboot_ec *param = 71 struct ec_params_reboot_ec *param;
71 (struct ec_params_reboot_ec *)msg.outdata;
72 int got_cmd = 0, offset = 0; 72 int got_cmd = 0, offset = 0;
73 int i; 73 int i;
74 int ret; 74 int ret;
75 struct cros_ec_device *ec = dev_get_drvdata(dev); 75 struct cros_ec_dev *ec = container_of(dev,
76 struct cros_ec_dev, class_dev);
77
78 msg = kmalloc(sizeof(*msg) + sizeof(*param), GFP_KERNEL);
79 if (!msg)
80 return -ENOMEM;
81
82 param = (struct ec_params_reboot_ec *)msg->data;
76 83
77 param->flags = 0; 84 param->flags = 0;
78 while (1) { 85 while (1) {
@@ -100,19 +107,26 @@ static ssize_t store_ec_reboot(struct device *dev,
100 offset++; 107 offset++;
101 } 108 }
102 109
103 if (!got_cmd) 110 if (!got_cmd) {
104 return -EINVAL; 111 count = -EINVAL;
105 112 goto exit;
106 msg.command = EC_CMD_REBOOT_EC;
107 msg.outsize = sizeof(param);
108 ret = cros_ec_cmd_xfer(ec, &msg);
109 if (ret < 0)
110 return ret;
111 if (msg.result != EC_RES_SUCCESS) {
112 dev_dbg(ec->dev, "EC result %d\n", msg.result);
113 return -EINVAL;
114 } 113 }
115 114
115 msg->version = 0;
116 msg->command = EC_CMD_REBOOT_EC + ec->cmd_offset;
117 msg->outsize = sizeof(*param);
118 msg->insize = 0;
119 ret = cros_ec_cmd_xfer(ec->ec_dev, msg);
120 if (ret < 0) {
121 count = ret;
122 goto exit;
123 }
124 if (msg->result != EC_RES_SUCCESS) {
125 dev_dbg(ec->dev, "EC result %d\n", msg->result);
126 count = -EINVAL;
127 }
128exit:
129 kfree(msg);
116 return count; 130 return count;
117} 131}
118 132
@@ -123,22 +137,33 @@ static ssize_t show_ec_version(struct device *dev,
123 struct ec_response_get_version *r_ver; 137 struct ec_response_get_version *r_ver;
124 struct ec_response_get_chip_info *r_chip; 138 struct ec_response_get_chip_info *r_chip;
125 struct ec_response_board_version *r_board; 139 struct ec_response_board_version *r_board;
126 struct cros_ec_command msg = { 0 }; 140 struct cros_ec_command *msg;
127 int ret; 141 int ret;
128 int count = 0; 142 int count = 0;
129 struct cros_ec_device *ec = dev_get_drvdata(dev); 143 struct cros_ec_dev *ec = container_of(dev,
144 struct cros_ec_dev, class_dev);
145
146 msg = kmalloc(sizeof(*msg) + EC_HOST_PARAM_SIZE, GFP_KERNEL);
147 if (!msg)
148 return -ENOMEM;
130 149
131 /* Get versions. RW may change. */ 150 /* Get versions. RW may change. */
132 msg.command = EC_CMD_GET_VERSION; 151 msg->version = 0;
133 msg.insize = sizeof(*r_ver); 152 msg->command = EC_CMD_GET_VERSION + ec->cmd_offset;
134 ret = cros_ec_cmd_xfer(ec, &msg); 153 msg->insize = sizeof(*r_ver);
135 if (ret < 0) 154 msg->outsize = 0;
136 return ret; 155 ret = cros_ec_cmd_xfer(ec->ec_dev, msg);
137 if (msg.result != EC_RES_SUCCESS) 156 if (ret < 0) {
138 return scnprintf(buf, PAGE_SIZE, 157 count = ret;
139 "ERROR: EC returned %d\n", msg.result); 158 goto exit;
159 }
160 if (msg->result != EC_RES_SUCCESS) {
161 count = scnprintf(buf, PAGE_SIZE,
162 "ERROR: EC returned %d\n", msg->result);
163 goto exit;
164 }
140 165
141 r_ver = (struct ec_response_get_version *)msg.indata; 166 r_ver = (struct ec_response_get_version *)msg->data;
142 /* Strings should be null-terminated, but let's be sure. */ 167 /* Strings should be null-terminated, but let's be sure. */
143 r_ver->version_string_ro[sizeof(r_ver->version_string_ro) - 1] = '\0'; 168 r_ver->version_string_ro[sizeof(r_ver->version_string_ro) - 1] = '\0';
144 r_ver->version_string_rw[sizeof(r_ver->version_string_rw) - 1] = '\0'; 169 r_ver->version_string_rw[sizeof(r_ver->version_string_rw) - 1] = '\0';
@@ -152,33 +177,33 @@ static ssize_t show_ec_version(struct device *dev,
152 image_names[r_ver->current_image] : "?")); 177 image_names[r_ver->current_image] : "?"));
153 178
154 /* Get build info. */ 179 /* Get build info. */
155 msg.command = EC_CMD_GET_BUILD_INFO; 180 msg->command = EC_CMD_GET_BUILD_INFO + ec->cmd_offset;
156 msg.insize = sizeof(msg.indata); 181 msg->insize = EC_HOST_PARAM_SIZE;
157 ret = cros_ec_cmd_xfer(ec, &msg); 182 ret = cros_ec_cmd_xfer(ec->ec_dev, msg);
158 if (ret < 0) 183 if (ret < 0)
159 count += scnprintf(buf + count, PAGE_SIZE - count, 184 count += scnprintf(buf + count, PAGE_SIZE - count,
160 "Build info: XFER ERROR %d\n", ret); 185 "Build info: XFER ERROR %d\n", ret);
161 else if (msg.result != EC_RES_SUCCESS) 186 else if (msg->result != EC_RES_SUCCESS)
162 count += scnprintf(buf + count, PAGE_SIZE - count, 187 count += scnprintf(buf + count, PAGE_SIZE - count,
163 "Build info: EC error %d\n", msg.result); 188 "Build info: EC error %d\n", msg->result);
164 else { 189 else {
165 msg.indata[sizeof(msg.indata) - 1] = '\0'; 190 msg->data[sizeof(msg->data) - 1] = '\0';
166 count += scnprintf(buf + count, PAGE_SIZE - count, 191 count += scnprintf(buf + count, PAGE_SIZE - count,
167 "Build info: %s\n", msg.indata); 192 "Build info: %s\n", msg->data);
168 } 193 }
169 194
170 /* Get chip info. */ 195 /* Get chip info. */
171 msg.command = EC_CMD_GET_CHIP_INFO; 196 msg->command = EC_CMD_GET_CHIP_INFO + ec->cmd_offset;
172 msg.insize = sizeof(*r_chip); 197 msg->insize = sizeof(*r_chip);
173 ret = cros_ec_cmd_xfer(ec, &msg); 198 ret = cros_ec_cmd_xfer(ec->ec_dev, msg);
174 if (ret < 0) 199 if (ret < 0)
175 count += scnprintf(buf + count, PAGE_SIZE - count, 200 count += scnprintf(buf + count, PAGE_SIZE - count,
176 "Chip info: XFER ERROR %d\n", ret); 201 "Chip info: XFER ERROR %d\n", ret);
177 else if (msg.result != EC_RES_SUCCESS) 202 else if (msg->result != EC_RES_SUCCESS)
178 count += scnprintf(buf + count, PAGE_SIZE - count, 203 count += scnprintf(buf + count, PAGE_SIZE - count,
179 "Chip info: EC error %d\n", msg.result); 204 "Chip info: EC error %d\n", msg->result);
180 else { 205 else {
181 r_chip = (struct ec_response_get_chip_info *)msg.indata; 206 r_chip = (struct ec_response_get_chip_info *)msg->data;
182 207
183 r_chip->vendor[sizeof(r_chip->vendor) - 1] = '\0'; 208 r_chip->vendor[sizeof(r_chip->vendor) - 1] = '\0';
184 r_chip->name[sizeof(r_chip->name) - 1] = '\0'; 209 r_chip->name[sizeof(r_chip->name) - 1] = '\0';
@@ -192,23 +217,25 @@ static ssize_t show_ec_version(struct device *dev,
192 } 217 }
193 218
194 /* Get board version */ 219 /* Get board version */
195 msg.command = EC_CMD_GET_BOARD_VERSION; 220 msg->command = EC_CMD_GET_BOARD_VERSION + ec->cmd_offset;
196 msg.insize = sizeof(*r_board); 221 msg->insize = sizeof(*r_board);
197 ret = cros_ec_cmd_xfer(ec, &msg); 222 ret = cros_ec_cmd_xfer(ec->ec_dev, msg);
198 if (ret < 0) 223 if (ret < 0)
199 count += scnprintf(buf + count, PAGE_SIZE - count, 224 count += scnprintf(buf + count, PAGE_SIZE - count,
200 "Board version: XFER ERROR %d\n", ret); 225 "Board version: XFER ERROR %d\n", ret);
201 else if (msg.result != EC_RES_SUCCESS) 226 else if (msg->result != EC_RES_SUCCESS)
202 count += scnprintf(buf + count, PAGE_SIZE - count, 227 count += scnprintf(buf + count, PAGE_SIZE - count,
203 "Board version: EC error %d\n", msg.result); 228 "Board version: EC error %d\n", msg->result);
204 else { 229 else {
205 r_board = (struct ec_response_board_version *)msg.indata; 230 r_board = (struct ec_response_board_version *)msg->data;
206 231
207 count += scnprintf(buf + count, PAGE_SIZE - count, 232 count += scnprintf(buf + count, PAGE_SIZE - count,
208 "Board version: %d\n", 233 "Board version: %d\n",
209 r_board->board_version); 234 r_board->board_version);
210 } 235 }
211 236
237exit:
238 kfree(msg);
212 return count; 239 return count;
213} 240}
214 241
@@ -216,27 +243,39 @@ static ssize_t show_ec_flashinfo(struct device *dev,
216 struct device_attribute *attr, char *buf) 243 struct device_attribute *attr, char *buf)
217{ 244{
218 struct ec_response_flash_info *resp; 245 struct ec_response_flash_info *resp;
219 struct cros_ec_command msg = { 0 }; 246 struct cros_ec_command *msg;
220 int ret; 247 int ret;
221 struct cros_ec_device *ec = dev_get_drvdata(dev); 248 struct cros_ec_dev *ec = container_of(dev,
249 struct cros_ec_dev, class_dev);
250
251 msg = kmalloc(sizeof(*msg) + sizeof(*resp), GFP_KERNEL);
252 if (!msg)
253 return -ENOMEM;
222 254
223 /* The flash info shouldn't ever change, but ask each time anyway. */ 255 /* The flash info shouldn't ever change, but ask each time anyway. */
224 msg.command = EC_CMD_FLASH_INFO; 256 msg->version = 0;
225 msg.insize = sizeof(*resp); 257 msg->command = EC_CMD_FLASH_INFO + ec->cmd_offset;
226 ret = cros_ec_cmd_xfer(ec, &msg); 258 msg->insize = sizeof(*resp);
259 msg->outsize = 0;
260 ret = cros_ec_cmd_xfer(ec->ec_dev, msg);
227 if (ret < 0) 261 if (ret < 0)
228 return ret; 262 goto exit;
229 if (msg.result != EC_RES_SUCCESS) 263 if (msg->result != EC_RES_SUCCESS) {
230 return scnprintf(buf, PAGE_SIZE, 264 ret = scnprintf(buf, PAGE_SIZE,
231 "ERROR: EC returned %d\n", msg.result); 265 "ERROR: EC returned %d\n", msg->result);
232 266 goto exit;
233 resp = (struct ec_response_flash_info *)msg.indata; 267 }
234 268
235 return scnprintf(buf, PAGE_SIZE, 269 resp = (struct ec_response_flash_info *)msg->data;
236 "FlashSize %d\nWriteSize %d\n" 270
237 "EraseSize %d\nProtectSize %d\n", 271 ret = scnprintf(buf, PAGE_SIZE,
238 resp->flash_size, resp->write_block_size, 272 "FlashSize %d\nWriteSize %d\n"
239 resp->erase_block_size, resp->protect_block_size); 273 "EraseSize %d\nProtectSize %d\n",
274 resp->flash_size, resp->write_block_size,
275 resp->erase_block_size, resp->protect_block_size);
276exit:
277 kfree(msg);
278 return ret;
240} 279}
241 280
242/* Module initialization */ 281/* Module initialization */
@@ -252,20 +291,7 @@ static struct attribute *__ec_attrs[] = {
252 NULL, 291 NULL,
253}; 292};
254 293
255static struct attribute_group ec_attr_group = { 294struct attribute_group cros_ec_attr_group = {
256 .attrs = __ec_attrs, 295 .attrs = __ec_attrs,
257}; 296};
258 297
259void ec_dev_sysfs_init(struct cros_ec_device *ec)
260{
261 int error;
262
263 error = sysfs_create_group(&ec->vdev->kobj, &ec_attr_group);
264 if (error)
265 pr_warn("failed to create group: %d\n", error);
266}
267
268void ec_dev_sysfs_remove(struct cros_ec_device *ec)
269{
270 sysfs_remove_group(&ec->vdev->kobj, &ec_attr_group);
271}
diff --git a/drivers/regulator/axp20x-regulator.c b/drivers/regulator/axp20x-regulator.c
index e4331f5e5d7d..646829132b59 100644
--- a/drivers/regulator/axp20x-regulator.c
+++ b/drivers/regulator/axp20x-regulator.c
@@ -27,20 +27,24 @@
27#define AXP20X_IO_ENABLED 0x03 27#define AXP20X_IO_ENABLED 0x03
28#define AXP20X_IO_DISABLED 0x07 28#define AXP20X_IO_DISABLED 0x07
29 29
30#define AXP22X_IO_ENABLED 0x04
31#define AXP22X_IO_DISABLED 0x03
32
30#define AXP20X_WORKMODE_DCDC2_MASK BIT(2) 33#define AXP20X_WORKMODE_DCDC2_MASK BIT(2)
31#define AXP20X_WORKMODE_DCDC3_MASK BIT(1) 34#define AXP20X_WORKMODE_DCDC3_MASK BIT(1)
35#define AXP22X_WORKMODE_DCDCX_MASK(x) BIT(x)
32 36
33#define AXP20X_FREQ_DCDC_MASK 0x0f 37#define AXP20X_FREQ_DCDC_MASK 0x0f
34 38
35#define AXP20X_DESC_IO(_id, _match, _supply, _min, _max, _step, _vreg, _vmask, \ 39#define AXP_DESC_IO(_family, _id, _match, _supply, _min, _max, _step, _vreg, \
36 _ereg, _emask, _enable_val, _disable_val) \ 40 _vmask, _ereg, _emask, _enable_val, _disable_val) \
37 [AXP20X_##_id] = { \ 41 [_family##_##_id] = { \
38 .name = #_id, \ 42 .name = #_id, \
39 .supply_name = (_supply), \ 43 .supply_name = (_supply), \
40 .of_match = of_match_ptr(_match), \ 44 .of_match = of_match_ptr(_match), \
41 .regulators_node = of_match_ptr("regulators"), \ 45 .regulators_node = of_match_ptr("regulators"), \
42 .type = REGULATOR_VOLTAGE, \ 46 .type = REGULATOR_VOLTAGE, \
43 .id = AXP20X_##_id, \ 47 .id = _family##_##_id, \
44 .n_voltages = (((_max) - (_min)) / (_step) + 1), \ 48 .n_voltages = (((_max) - (_min)) / (_step) + 1), \
45 .owner = THIS_MODULE, \ 49 .owner = THIS_MODULE, \
46 .min_uV = (_min) * 1000, \ 50 .min_uV = (_min) * 1000, \
@@ -54,15 +58,15 @@
54 .ops = &axp20x_ops, \ 58 .ops = &axp20x_ops, \
55 } 59 }
56 60
57#define AXP20X_DESC(_id, _match, _supply, _min, _max, _step, _vreg, _vmask, \ 61#define AXP_DESC(_family, _id, _match, _supply, _min, _max, _step, _vreg, \
58 _ereg, _emask) \ 62 _vmask, _ereg, _emask) \
59 [AXP20X_##_id] = { \ 63 [_family##_##_id] = { \
60 .name = #_id, \ 64 .name = #_id, \
61 .supply_name = (_supply), \ 65 .supply_name = (_supply), \
62 .of_match = of_match_ptr(_match), \ 66 .of_match = of_match_ptr(_match), \
63 .regulators_node = of_match_ptr("regulators"), \ 67 .regulators_node = of_match_ptr("regulators"), \
64 .type = REGULATOR_VOLTAGE, \ 68 .type = REGULATOR_VOLTAGE, \
65 .id = AXP20X_##_id, \ 69 .id = _family##_##_id, \
66 .n_voltages = (((_max) - (_min)) / (_step) + 1), \ 70 .n_voltages = (((_max) - (_min)) / (_step) + 1), \
67 .owner = THIS_MODULE, \ 71 .owner = THIS_MODULE, \
68 .min_uV = (_min) * 1000, \ 72 .min_uV = (_min) * 1000, \
@@ -74,29 +78,49 @@
74 .ops = &axp20x_ops, \ 78 .ops = &axp20x_ops, \
75 } 79 }
76 80
77#define AXP20X_DESC_FIXED(_id, _match, _supply, _volt) \ 81#define AXP_DESC_SW(_family, _id, _match, _supply, _min, _max, _step, _vreg, \
78 [AXP20X_##_id] = { \ 82 _vmask, _ereg, _emask) \
83 [_family##_##_id] = { \
79 .name = #_id, \ 84 .name = #_id, \
80 .supply_name = (_supply), \ 85 .supply_name = (_supply), \
81 .of_match = of_match_ptr(_match), \ 86 .of_match = of_match_ptr(_match), \
82 .regulators_node = of_match_ptr("regulators"), \ 87 .regulators_node = of_match_ptr("regulators"), \
83 .type = REGULATOR_VOLTAGE, \ 88 .type = REGULATOR_VOLTAGE, \
84 .id = AXP20X_##_id, \ 89 .id = _family##_##_id, \
90 .n_voltages = (((_max) - (_min)) / (_step) + 1), \
91 .owner = THIS_MODULE, \
92 .min_uV = (_min) * 1000, \
93 .uV_step = (_step) * 1000, \
94 .vsel_reg = (_vreg), \
95 .vsel_mask = (_vmask), \
96 .enable_reg = (_ereg), \
97 .enable_mask = (_emask), \
98 .ops = &axp20x_ops_sw, \
99 }
100
101#define AXP_DESC_FIXED(_family, _id, _match, _supply, _volt) \
102 [_family##_##_id] = { \
103 .name = #_id, \
104 .supply_name = (_supply), \
105 .of_match = of_match_ptr(_match), \
106 .regulators_node = of_match_ptr("regulators"), \
107 .type = REGULATOR_VOLTAGE, \
108 .id = _family##_##_id, \
85 .n_voltages = 1, \ 109 .n_voltages = 1, \
86 .owner = THIS_MODULE, \ 110 .owner = THIS_MODULE, \
87 .min_uV = (_volt) * 1000, \ 111 .min_uV = (_volt) * 1000, \
88 .ops = &axp20x_ops_fixed \ 112 .ops = &axp20x_ops_fixed \
89 } 113 }
90 114
91#define AXP20X_DESC_TABLE(_id, _match, _supply, _table, _vreg, _vmask, _ereg, \ 115#define AXP_DESC_TABLE(_family, _id, _match, _supply, _table, _vreg, _vmask, \
92 _emask) \ 116 _ereg, _emask) \
93 [AXP20X_##_id] = { \ 117 [_family##_##_id] = { \
94 .name = #_id, \ 118 .name = #_id, \
95 .supply_name = (_supply), \ 119 .supply_name = (_supply), \
96 .of_match = of_match_ptr(_match), \ 120 .of_match = of_match_ptr(_match), \
97 .regulators_node = of_match_ptr("regulators"), \ 121 .regulators_node = of_match_ptr("regulators"), \
98 .type = REGULATOR_VOLTAGE, \ 122 .type = REGULATOR_VOLTAGE, \
99 .id = AXP20X_##_id, \ 123 .id = _family##_##_id, \
100 .n_voltages = ARRAY_SIZE(_table), \ 124 .n_voltages = ARRAY_SIZE(_table), \
101 .owner = THIS_MODULE, \ 125 .owner = THIS_MODULE, \
102 .vsel_reg = (_vreg), \ 126 .vsel_reg = (_vreg), \
@@ -135,38 +159,118 @@ static struct regulator_ops axp20x_ops = {
135 .is_enabled = regulator_is_enabled_regmap, 159 .is_enabled = regulator_is_enabled_regmap,
136}; 160};
137 161
162static struct regulator_ops axp20x_ops_sw = {
163 .get_voltage_sel = regulator_get_voltage_sel_regmap,
164 .list_voltage = regulator_list_voltage_linear,
165 .enable = regulator_enable_regmap,
166 .disable = regulator_disable_regmap,
167 .is_enabled = regulator_is_enabled_regmap,
168};
169
138static const struct regulator_desc axp20x_regulators[] = { 170static const struct regulator_desc axp20x_regulators[] = {
139 AXP20X_DESC(DCDC2, "dcdc2", "vin2", 700, 2275, 25, AXP20X_DCDC2_V_OUT, 171 AXP_DESC(AXP20X, DCDC2, "dcdc2", "vin2", 700, 2275, 25,
140 0x3f, AXP20X_PWR_OUT_CTRL, 0x10), 172 AXP20X_DCDC2_V_OUT, 0x3f, AXP20X_PWR_OUT_CTRL, 0x10),
141 AXP20X_DESC(DCDC3, "dcdc3", "vin3", 700, 3500, 25, AXP20X_DCDC3_V_OUT, 173 AXP_DESC(AXP20X, DCDC3, "dcdc3", "vin3", 700, 3500, 25,
142 0x7f, AXP20X_PWR_OUT_CTRL, 0x02), 174 AXP20X_DCDC3_V_OUT, 0x7f, AXP20X_PWR_OUT_CTRL, 0x02),
143 AXP20X_DESC_FIXED(LDO1, "ldo1", "acin", 1300), 175 AXP_DESC_FIXED(AXP20X, LDO1, "ldo1", "acin", 1300),
144 AXP20X_DESC(LDO2, "ldo2", "ldo24in", 1800, 3300, 100, 176 AXP_DESC(AXP20X, LDO2, "ldo2", "ldo24in", 1800, 3300, 100,
145 AXP20X_LDO24_V_OUT, 0xf0, AXP20X_PWR_OUT_CTRL, 0x04), 177 AXP20X_LDO24_V_OUT, 0xf0, AXP20X_PWR_OUT_CTRL, 0x04),
146 AXP20X_DESC(LDO3, "ldo3", "ldo3in", 700, 3500, 25, AXP20X_LDO3_V_OUT, 178 AXP_DESC(AXP20X, LDO3, "ldo3", "ldo3in", 700, 3500, 25,
147 0x7f, AXP20X_PWR_OUT_CTRL, 0x40), 179 AXP20X_LDO3_V_OUT, 0x7f, AXP20X_PWR_OUT_CTRL, 0x40),
148 AXP20X_DESC_TABLE(LDO4, "ldo4", "ldo24in", axp20x_ldo4_data, 180 AXP_DESC_TABLE(AXP20X, LDO4, "ldo4", "ldo24in", axp20x_ldo4_data,
149 AXP20X_LDO24_V_OUT, 0x0f, AXP20X_PWR_OUT_CTRL, 0x08), 181 AXP20X_LDO24_V_OUT, 0x0f, AXP20X_PWR_OUT_CTRL, 0x08),
150 AXP20X_DESC_IO(LDO5, "ldo5", "ldo5in", 1800, 3300, 100, 182 AXP_DESC_IO(AXP20X, LDO5, "ldo5", "ldo5in", 1800, 3300, 100,
151 AXP20X_LDO5_V_OUT, 0xf0, AXP20X_GPIO0_CTRL, 0x07, 183 AXP20X_LDO5_V_OUT, 0xf0, AXP20X_GPIO0_CTRL, 0x07,
152 AXP20X_IO_ENABLED, AXP20X_IO_DISABLED), 184 AXP20X_IO_ENABLED, AXP20X_IO_DISABLED),
185};
186
187static const struct regulator_desc axp22x_regulators[] = {
188 AXP_DESC(AXP22X, DCDC1, "dcdc1", "vin1", 1600, 3400, 100,
189 AXP22X_DCDC1_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL1, BIT(1)),
190 AXP_DESC(AXP22X, DCDC2, "dcdc2", "vin2", 600, 1540, 20,
191 AXP22X_DCDC2_V_OUT, 0x3f, AXP22X_PWR_OUT_CTRL1, BIT(2)),
192 AXP_DESC(AXP22X, DCDC3, "dcdc3", "vin3", 600, 1860, 20,
193 AXP22X_DCDC3_V_OUT, 0x3f, AXP22X_PWR_OUT_CTRL1, BIT(3)),
194 AXP_DESC(AXP22X, DCDC4, "dcdc4", "vin4", 600, 1540, 20,
195 AXP22X_DCDC4_V_OUT, 0x3f, AXP22X_PWR_OUT_CTRL1, BIT(3)),
196 AXP_DESC(AXP22X, DCDC5, "dcdc5", "vin5", 1000, 2550, 50,
197 AXP22X_DCDC5_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL1, BIT(4)),
198 /* secondary switchable output of DCDC1 */
199 AXP_DESC_SW(AXP22X, DC1SW, "dc1sw", "dcdc1", 1600, 3400, 100,
200 AXP22X_DCDC1_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL2, BIT(7)),
201 /* LDO regulator internally chained to DCDC5 */
202 AXP_DESC(AXP22X, DC5LDO, "dc5ldo", "dcdc5", 700, 1400, 100,
203 AXP22X_DC5LDO_V_OUT, 0x7, AXP22X_PWR_OUT_CTRL1, BIT(0)),
204 AXP_DESC(AXP22X, ALDO1, "aldo1", "aldoin", 700, 3300, 100,
205 AXP22X_ALDO1_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL1, BIT(6)),
206 AXP_DESC(AXP22X, ALDO2, "aldo2", "aldoin", 700, 3300, 100,
207 AXP22X_ALDO2_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL1, BIT(7)),
208 AXP_DESC(AXP22X, ALDO3, "aldo3", "aldoin", 700, 3300, 100,
209 AXP22X_ALDO3_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL3, BIT(7)),
210 AXP_DESC(AXP22X, DLDO1, "dldo1", "dldoin", 700, 3300, 100,
211 AXP22X_DLDO1_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL2, BIT(3)),
212 AXP_DESC(AXP22X, DLDO2, "dldo2", "dldoin", 700, 3300, 100,
213 AXP22X_DLDO2_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL2, BIT(4)),
214 AXP_DESC(AXP22X, DLDO3, "dldo3", "dldoin", 700, 3300, 100,
215 AXP22X_DLDO3_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL2, BIT(5)),
216 AXP_DESC(AXP22X, DLDO4, "dldo4", "dldoin", 700, 3300, 100,
217 AXP22X_DLDO4_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL2, BIT(6)),
218 AXP_DESC(AXP22X, ELDO1, "eldo1", "eldoin", 700, 3300, 100,
219 AXP22X_ELDO1_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL2, BIT(0)),
220 AXP_DESC(AXP22X, ELDO2, "eldo2", "eldoin", 700, 3300, 100,
221 AXP22X_ELDO2_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL2, BIT(1)),
222 AXP_DESC(AXP22X, ELDO3, "eldo3", "eldoin", 700, 3300, 100,
223 AXP22X_ELDO3_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL2, BIT(2)),
224 AXP_DESC_IO(AXP22X, LDO_IO0, "ldo_io0", "ips", 1800, 3300, 100,
225 AXP22X_LDO_IO0_V_OUT, 0x1f, AXP20X_GPIO0_CTRL, 0x07,
226 AXP22X_IO_ENABLED, AXP22X_IO_DISABLED),
227 AXP_DESC_IO(AXP22X, LDO_IO1, "ldo_io1", "ips", 1800, 3300, 100,
228 AXP22X_LDO_IO1_V_OUT, 0x1f, AXP20X_GPIO1_CTRL, 0x07,
229 AXP22X_IO_ENABLED, AXP22X_IO_DISABLED),
230 AXP_DESC_FIXED(AXP22X, RTC_LDO, "rtc_ldo", "ips", 3000),
153}; 231};
154 232
155static int axp20x_set_dcdc_freq(struct platform_device *pdev, u32 dcdcfreq) 233static int axp20x_set_dcdc_freq(struct platform_device *pdev, u32 dcdcfreq)
156{ 234{
157 struct axp20x_dev *axp20x = dev_get_drvdata(pdev->dev.parent); 235 struct axp20x_dev *axp20x = dev_get_drvdata(pdev->dev.parent);
236 u32 min, max, def, step;
237
238 switch (axp20x->variant) {
239 case AXP202_ID:
240 case AXP209_ID:
241 min = 750;
242 max = 1875;
243 def = 1500;
244 step = 75;
245 break;
246 case AXP221_ID:
247 min = 1800;
248 max = 4050;
249 def = 3000;
250 step = 150;
251 break;
252 default:
253 dev_err(&pdev->dev,
254 "Setting DCDC frequency for unsupported AXP variant\n");
255 return -EINVAL;
256 }
257
258 if (dcdcfreq == 0)
259 dcdcfreq = def;
158 260
159 if (dcdcfreq < 750) { 261 if (dcdcfreq < min) {
160 dcdcfreq = 750; 262 dcdcfreq = min;
161 dev_warn(&pdev->dev, "DCDC frequency too low. Set to 750kHz\n"); 263 dev_warn(&pdev->dev, "DCDC frequency too low. Set to %ukHz\n",
264 min);
162 } 265 }
163 266
164 if (dcdcfreq > 1875) { 267 if (dcdcfreq > max) {
165 dcdcfreq = 1875; 268 dcdcfreq = max;
166 dev_warn(&pdev->dev, "DCDC frequency too high. Set to 1875kHz\n"); 269 dev_warn(&pdev->dev, "DCDC frequency too high. Set to %ukHz\n",
270 max);
167 } 271 }
168 272
169 dcdcfreq = (dcdcfreq - 750) / 75; 273 dcdcfreq = (dcdcfreq - min) / step;
170 274
171 return regmap_update_bits(axp20x->regmap, AXP20X_DCDC_FREQ, 275 return regmap_update_bits(axp20x->regmap, AXP20X_DCDC_FREQ,
172 AXP20X_FREQ_DCDC_MASK, dcdcfreq); 276 AXP20X_FREQ_DCDC_MASK, dcdcfreq);
@@ -176,7 +280,7 @@ static int axp20x_regulator_parse_dt(struct platform_device *pdev)
176{ 280{
177 struct device_node *np, *regulators; 281 struct device_node *np, *regulators;
178 int ret; 282 int ret;
179 u32 dcdcfreq; 283 u32 dcdcfreq = 0;
180 284
181 np = of_node_get(pdev->dev.parent->of_node); 285 np = of_node_get(pdev->dev.parent->of_node);
182 if (!np) 286 if (!np)
@@ -186,7 +290,6 @@ static int axp20x_regulator_parse_dt(struct platform_device *pdev)
186 if (!regulators) { 290 if (!regulators) {
187 dev_warn(&pdev->dev, "regulators node not found\n"); 291 dev_warn(&pdev->dev, "regulators node not found\n");
188 } else { 292 } else {
189 dcdcfreq = 1500;
190 of_property_read_u32(regulators, "x-powers,dcdc-freq", &dcdcfreq); 293 of_property_read_u32(regulators, "x-powers,dcdc-freq", &dcdcfreq);
191 ret = axp20x_set_dcdc_freq(pdev, dcdcfreq); 294 ret = axp20x_set_dcdc_freq(pdev, dcdcfreq);
192 if (ret < 0) { 295 if (ret < 0) {
@@ -202,15 +305,35 @@ static int axp20x_regulator_parse_dt(struct platform_device *pdev)
202 305
203static int axp20x_set_dcdc_workmode(struct regulator_dev *rdev, int id, u32 workmode) 306static int axp20x_set_dcdc_workmode(struct regulator_dev *rdev, int id, u32 workmode)
204{ 307{
205 unsigned int mask = AXP20X_WORKMODE_DCDC2_MASK; 308 struct axp20x_dev *axp20x = rdev_get_drvdata(rdev);
309 unsigned int mask;
206 310
207 if ((id != AXP20X_DCDC2) && (id != AXP20X_DCDC3)) 311 switch (axp20x->variant) {
208 return -EINVAL; 312 case AXP202_ID:
313 case AXP209_ID:
314 if ((id != AXP20X_DCDC2) && (id != AXP20X_DCDC3))
315 return -EINVAL;
316
317 mask = AXP20X_WORKMODE_DCDC2_MASK;
318 if (id == AXP20X_DCDC3)
319 mask = AXP20X_WORKMODE_DCDC3_MASK;
320
321 workmode <<= ffs(mask) - 1;
322 break;
209 323
210 if (id == AXP20X_DCDC3) 324 case AXP221_ID:
211 mask = AXP20X_WORKMODE_DCDC3_MASK; 325 if (id < AXP22X_DCDC1 || id > AXP22X_DCDC5)
326 return -EINVAL;
212 327
213 workmode <<= ffs(mask) - 1; 328 mask = AXP22X_WORKMODE_DCDCX_MASK(id - AXP22X_DCDC1);
329 workmode <<= id - AXP22X_DCDC1;
330 break;
331
332 default:
333 /* should not happen */
334 WARN_ON(1);
335 return -EINVAL;
336 }
214 337
215 return regmap_update_bits(rdev->regmap, AXP20X_DCDC_MODE, mask, workmode); 338 return regmap_update_bits(rdev->regmap, AXP20X_DCDC_MODE, mask, workmode);
216} 339}
@@ -219,22 +342,40 @@ static int axp20x_regulator_probe(struct platform_device *pdev)
219{ 342{
220 struct regulator_dev *rdev; 343 struct regulator_dev *rdev;
221 struct axp20x_dev *axp20x = dev_get_drvdata(pdev->dev.parent); 344 struct axp20x_dev *axp20x = dev_get_drvdata(pdev->dev.parent);
345 const struct regulator_desc *regulators;
222 struct regulator_config config = { 346 struct regulator_config config = {
223 .dev = pdev->dev.parent, 347 .dev = pdev->dev.parent,
224 .regmap = axp20x->regmap, 348 .regmap = axp20x->regmap,
349 .driver_data = axp20x,
225 }; 350 };
226 int ret, i; 351 int ret, i, nregulators;
227 u32 workmode; 352 u32 workmode;
228 353
354 switch (axp20x->variant) {
355 case AXP202_ID:
356 case AXP209_ID:
357 regulators = axp20x_regulators;
358 nregulators = AXP20X_REG_ID_MAX;
359 break;
360 case AXP221_ID:
361 regulators = axp22x_regulators;
362 nregulators = AXP22X_REG_ID_MAX;
363 break;
364 default:
365 dev_err(&pdev->dev, "Unsupported AXP variant: %ld\n",
366 axp20x->variant);
367 return -EINVAL;
368 }
369
229 /* This only sets the dcdc freq. Ignore any errors */ 370 /* This only sets the dcdc freq. Ignore any errors */
230 axp20x_regulator_parse_dt(pdev); 371 axp20x_regulator_parse_dt(pdev);
231 372
232 for (i = 0; i < AXP20X_REG_ID_MAX; i++) { 373 for (i = 0; i < nregulators; i++) {
233 rdev = devm_regulator_register(&pdev->dev, &axp20x_regulators[i], 374 rdev = devm_regulator_register(&pdev->dev, &regulators[i],
234 &config); 375 &config);
235 if (IS_ERR(rdev)) { 376 if (IS_ERR(rdev)) {
236 dev_err(&pdev->dev, "Failed to register %s\n", 377 dev_err(&pdev->dev, "Failed to register %s\n",
237 axp20x_regulators[i].name); 378 regulators[i].name);
238 379
239 return PTR_ERR(rdev); 380 return PTR_ERR(rdev);
240 } 381 }
@@ -245,7 +386,7 @@ static int axp20x_regulator_probe(struct platform_device *pdev)
245 if (!ret) { 386 if (!ret) {
246 if (axp20x_set_dcdc_workmode(rdev, i, workmode)) 387 if (axp20x_set_dcdc_workmode(rdev, i, workmode))
247 dev_err(&pdev->dev, "Failed to set workmode on %s\n", 388 dev_err(&pdev->dev, "Failed to set workmode on %s\n",
248 axp20x_regulators[i].name); 389 rdev->desc->name);
249 } 390 }
250 } 391 }
251 392
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index 0fe4ad8826b2..5e963df9e565 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -1520,6 +1520,17 @@ config RTC_DRV_SIRFSOC
1520 Say "yes" here to support the real time clock on SiRF SOC chips. 1520 Say "yes" here to support the real time clock on SiRF SOC chips.
1521 This driver can also be built as a module called rtc-sirfsoc. 1521 This driver can also be built as a module called rtc-sirfsoc.
1522 1522
1523config RTC_DRV_ST_LPC
1524 tristate "STMicroelectronics LPC RTC"
1525 depends on ARCH_STI
1526 depends on OF
1527 help
1528 Say Y here to include STMicroelectronics Low Power Controller
1529 (LPC) based RTC support.
1530
1531 To compile this driver as a module, choose M here: the
1532 module will be called rtc-st-lpc.
1533
1523config RTC_DRV_MOXART 1534config RTC_DRV_MOXART
1524 tristate "MOXA ART RTC" 1535 tristate "MOXA ART RTC"
1525 depends on ARCH_MOXART || COMPILE_TEST 1536 depends on ARCH_MOXART || COMPILE_TEST
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
index 2b82e2b0311b..ebe2c085d01c 100644
--- a/drivers/rtc/Makefile
+++ b/drivers/rtc/Makefile
@@ -154,4 +154,5 @@ obj-$(CONFIG_RTC_DRV_WM8350) += rtc-wm8350.o
154obj-$(CONFIG_RTC_DRV_X1205) += rtc-x1205.o 154obj-$(CONFIG_RTC_DRV_X1205) += rtc-x1205.o
155obj-$(CONFIG_RTC_DRV_XGENE) += rtc-xgene.o 155obj-$(CONFIG_RTC_DRV_XGENE) += rtc-xgene.o
156obj-$(CONFIG_RTC_DRV_SIRFSOC) += rtc-sirfsoc.o 156obj-$(CONFIG_RTC_DRV_SIRFSOC) += rtc-sirfsoc.o
157obj-$(CONFIG_RTC_DRV_ST_LPC) += rtc-st-lpc.o
157obj-$(CONFIG_RTC_DRV_MOXART) += rtc-moxart.o 158obj-$(CONFIG_RTC_DRV_MOXART) += rtc-moxart.o
diff --git a/drivers/rtc/rtc-st-lpc.c b/drivers/rtc/rtc-st-lpc.c
new file mode 100644
index 000000000000..3f9d0acb81c7
--- /dev/null
+++ b/drivers/rtc/rtc-st-lpc.c
@@ -0,0 +1,354 @@
1/*
2 * rtc-st-lpc.c - ST's LPC RTC, powered by the Low Power Timer
3 *
4 * Copyright (C) 2014 STMicroelectronics Limited
5 *
6 * Author: David Paris <david.paris@st.com> for STMicroelectronics
7 * Lee Jones <lee.jones@linaro.org> for STMicroelectronics
8 *
9 * Based on the original driver written by Stuart Menefy.
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public Licence
13 * as published by the Free Software Foundation; either version
14 * 2 of the Licence, or (at your option) any later version.
15 */
16
17#include <linux/clk.h>
18#include <linux/delay.h>
19#include <linux/init.h>
20#include <linux/io.h>
21#include <linux/irq.h>
22#include <linux/kernel.h>
23#include <linux/module.h>
24#include <linux/of.h>
25#include <linux/of_irq.h>
26#include <linux/platform_device.h>
27#include <linux/rtc.h>
28
29#include <dt-bindings/mfd/st-lpc.h>
30
31/* Low Power Timer */
32#define LPC_LPT_LSB_OFF 0x400
33#define LPC_LPT_MSB_OFF 0x404
34#define LPC_LPT_START_OFF 0x408
35
36/* Low Power Alarm */
37#define LPC_LPA_LSB_OFF 0x410
38#define LPC_LPA_MSB_OFF 0x414
39#define LPC_LPA_START_OFF 0x418
40
41/* LPC as WDT */
42#define LPC_WDT_OFF 0x510
43#define LPC_WDT_FLAG_OFF 0x514
44
45struct st_rtc {
46 struct rtc_device *rtc_dev;
47 struct rtc_wkalrm alarm;
48 struct resource *res;
49 struct clk *clk;
50 unsigned long clkrate;
51 void __iomem *ioaddr;
52 bool irq_enabled:1;
53 spinlock_t lock;
54 short irq;
55};
56
57static void st_rtc_set_hw_alarm(struct st_rtc *rtc,
58 unsigned long msb, unsigned long lsb)
59{
60 unsigned long flags;
61
62 spin_lock_irqsave(&rtc->lock, flags);
63
64 writel_relaxed(1, rtc->ioaddr + LPC_WDT_OFF);
65
66 writel_relaxed(msb, rtc->ioaddr + LPC_LPA_MSB_OFF);
67 writel_relaxed(lsb, rtc->ioaddr + LPC_LPA_LSB_OFF);
68 writel_relaxed(1, rtc->ioaddr + LPC_LPA_START_OFF);
69
70 writel_relaxed(0, rtc->ioaddr + LPC_WDT_OFF);
71
72 spin_unlock_irqrestore(&rtc->lock, flags);
73}
74
75static irqreturn_t st_rtc_handler(int this_irq, void *data)
76{
77 struct st_rtc *rtc = (struct st_rtc *)data;
78
79 rtc_update_irq(rtc->rtc_dev, 1, RTC_AF);
80
81 return IRQ_HANDLED;
82}
83
84static int st_rtc_read_time(struct device *dev, struct rtc_time *tm)
85{
86 struct st_rtc *rtc = dev_get_drvdata(dev);
87 unsigned long lpt_lsb, lpt_msb;
88 unsigned long long lpt;
89 unsigned long flags;
90
91 spin_lock_irqsave(&rtc->lock, flags);
92
93 do {
94 lpt_msb = readl_relaxed(rtc->ioaddr + LPC_LPT_MSB_OFF);
95 lpt_lsb = readl_relaxed(rtc->ioaddr + LPC_LPT_LSB_OFF);
96 } while (readl_relaxed(rtc->ioaddr + LPC_LPT_MSB_OFF) != lpt_msb);
97
98 spin_unlock_irqrestore(&rtc->lock, flags);
99
100 lpt = ((unsigned long long)lpt_msb << 32) | lpt_lsb;
101 do_div(lpt, rtc->clkrate);
102 rtc_time_to_tm(lpt, tm);
103
104 return 0;
105}
106
107static int st_rtc_set_time(struct device *dev, struct rtc_time *tm)
108{
109 struct st_rtc *rtc = dev_get_drvdata(dev);
110 unsigned long long lpt;
111 unsigned long secs, flags;
112 int ret;
113
114 ret = rtc_tm_to_time(tm, &secs);
115 if (ret)
116 return ret;
117
118 lpt = (unsigned long long)secs * rtc->clkrate;
119
120 spin_lock_irqsave(&rtc->lock, flags);
121
122 writel_relaxed(lpt >> 32, rtc->ioaddr + LPC_LPT_MSB_OFF);
123 writel_relaxed(lpt, rtc->ioaddr + LPC_LPT_LSB_OFF);
124 writel_relaxed(1, rtc->ioaddr + LPC_LPT_START_OFF);
125
126 spin_unlock_irqrestore(&rtc->lock, flags);
127
128 return 0;
129}
130
131static int st_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *wkalrm)
132{
133 struct st_rtc *rtc = dev_get_drvdata(dev);
134 unsigned long flags;
135
136 spin_lock_irqsave(&rtc->lock, flags);
137
138 memcpy(wkalrm, &rtc->alarm, sizeof(struct rtc_wkalrm));
139
140 spin_unlock_irqrestore(&rtc->lock, flags);
141
142 return 0;
143}
144
145static int st_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
146{
147 struct st_rtc *rtc = dev_get_drvdata(dev);
148
149 if (enabled && !rtc->irq_enabled) {
150 enable_irq(rtc->irq);
151 rtc->irq_enabled = true;
152 } else if (!enabled && rtc->irq_enabled) {
153 disable_irq(rtc->irq);
154 rtc->irq_enabled = false;
155 }
156
157 return 0;
158}
159
160static int st_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *t)
161{
162 struct st_rtc *rtc = dev_get_drvdata(dev);
163 struct rtc_time now;
164 unsigned long now_secs;
165 unsigned long alarm_secs;
166 unsigned long long lpa;
167
168 st_rtc_read_time(dev, &now);
169 rtc_tm_to_time(&now, &now_secs);
170 rtc_tm_to_time(&t->time, &alarm_secs);
171
172 /* Invalid alarm time */
173 if (now_secs > alarm_secs)
174 return -EINVAL;
175
176 memcpy(&rtc->alarm, t, sizeof(struct rtc_wkalrm));
177
178 /* Now many secs to fire */
179 alarm_secs -= now_secs;
180 lpa = (unsigned long long)alarm_secs * rtc->clkrate;
181
182 st_rtc_set_hw_alarm(rtc, lpa >> 32, lpa);
183 st_rtc_alarm_irq_enable(dev, t->enabled);
184
185 return 0;
186}
187
188static struct rtc_class_ops st_rtc_ops = {
189 .read_time = st_rtc_read_time,
190 .set_time = st_rtc_set_time,
191 .read_alarm = st_rtc_read_alarm,
192 .set_alarm = st_rtc_set_alarm,
193 .alarm_irq_enable = st_rtc_alarm_irq_enable,
194};
195
196static int st_rtc_probe(struct platform_device *pdev)
197{
198 struct device_node *np = pdev->dev.of_node;
199 struct st_rtc *rtc;
200 struct resource *res;
201 struct rtc_time tm_check;
202 uint32_t mode;
203 int ret = 0;
204
205 ret = of_property_read_u32(np, "st,lpc-mode", &mode);
206 if (ret) {
207 dev_err(&pdev->dev, "An LPC mode must be provided\n");
208 return -EINVAL;
209 }
210
211 /* LPC can either run in RTC or WDT mode */
212 if (mode != ST_LPC_MODE_RTC)
213 return -ENODEV;
214
215 rtc = devm_kzalloc(&pdev->dev, sizeof(struct st_rtc), GFP_KERNEL);
216 if (!rtc)
217 return -ENOMEM;
218
219 spin_lock_init(&rtc->lock);
220
221 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
222 rtc->ioaddr = devm_ioremap_resource(&pdev->dev, res);
223 if (IS_ERR(rtc->ioaddr))
224 return PTR_ERR(rtc->ioaddr);
225
226 rtc->irq = irq_of_parse_and_map(np, 0);
227 if (!rtc->irq) {
228 dev_err(&pdev->dev, "IRQ missing or invalid\n");
229 return -EINVAL;
230 }
231
232 ret = devm_request_irq(&pdev->dev, rtc->irq, st_rtc_handler, 0,
233 pdev->name, rtc);
234 if (ret) {
235 dev_err(&pdev->dev, "Failed to request irq %i\n", rtc->irq);
236 return ret;
237 }
238
239 enable_irq_wake(rtc->irq);
240 disable_irq(rtc->irq);
241
242 rtc->clk = clk_get(&pdev->dev, NULL);
243 if (IS_ERR(rtc->clk)) {
244 dev_err(&pdev->dev, "Unable to request clock\n");
245 return PTR_ERR(rtc->clk);
246 }
247
248 clk_prepare_enable(rtc->clk);
249
250 rtc->clkrate = clk_get_rate(rtc->clk);
251 if (!rtc->clkrate) {
252 dev_err(&pdev->dev, "Unable to fetch clock rate\n");
253 return -EINVAL;
254 }
255
256 device_set_wakeup_capable(&pdev->dev, 1);
257
258 platform_set_drvdata(pdev, rtc);
259
260 /*
261 * The RTC-LPC is able to manage date.year > 2038
262 * but currently the kernel can not manage this date!
263 * If the RTC-LPC has a date.year > 2038 then
264 * it's set to the epoch "Jan 1st 2000"
265 */
266 st_rtc_read_time(&pdev->dev, &tm_check);
267
268 if (tm_check.tm_year >= (2038 - 1900)) {
269 memset(&tm_check, 0, sizeof(tm_check));
270 tm_check.tm_year = 100;
271 tm_check.tm_mday = 1;
272 st_rtc_set_time(&pdev->dev, &tm_check);
273 }
274
275 rtc->rtc_dev = rtc_device_register("st-lpc-rtc", &pdev->dev,
276 &st_rtc_ops, THIS_MODULE);
277 if (IS_ERR(rtc->rtc_dev)) {
278 clk_disable_unprepare(rtc->clk);
279 return PTR_ERR(rtc->rtc_dev);
280 }
281
282 return 0;
283}
284
285static int st_rtc_remove(struct platform_device *pdev)
286{
287 struct st_rtc *rtc = platform_get_drvdata(pdev);
288
289 if (likely(rtc->rtc_dev))
290 rtc_device_unregister(rtc->rtc_dev);
291
292 return 0;
293}
294
295#ifdef CONFIG_PM_SLEEP
296static int st_rtc_suspend(struct device *dev)
297{
298 struct st_rtc *rtc = dev_get_drvdata(dev);
299
300 if (device_may_wakeup(dev))
301 return 0;
302
303 writel_relaxed(1, rtc->ioaddr + LPC_WDT_OFF);
304 writel_relaxed(0, rtc->ioaddr + LPC_LPA_START_OFF);
305 writel_relaxed(0, rtc->ioaddr + LPC_WDT_OFF);
306
307 return 0;
308}
309
310static int st_rtc_resume(struct device *dev)
311{
312 struct st_rtc *rtc = dev_get_drvdata(dev);
313
314 rtc_alarm_irq_enable(rtc->rtc_dev, 0);
315
316 /*
317 * clean 'rtc->alarm' to allow a new
318 * .set_alarm to the upper RTC layer
319 */
320 memset(&rtc->alarm, 0, sizeof(struct rtc_wkalrm));
321
322 writel_relaxed(0, rtc->ioaddr + LPC_LPA_MSB_OFF);
323 writel_relaxed(0, rtc->ioaddr + LPC_LPA_LSB_OFF);
324 writel_relaxed(1, rtc->ioaddr + LPC_WDT_OFF);
325 writel_relaxed(1, rtc->ioaddr + LPC_LPA_START_OFF);
326 writel_relaxed(0, rtc->ioaddr + LPC_WDT_OFF);
327
328 return 0;
329}
330#endif
331
332static SIMPLE_DEV_PM_OPS(st_rtc_pm_ops, st_rtc_suspend, st_rtc_resume);
333
334static const struct of_device_id st_rtc_match[] = {
335 { .compatible = "st,stih407-lpc" },
336 {}
337};
338MODULE_DEVICE_TABLE(of, st_rtc_match);
339
340static struct platform_driver st_rtc_platform_driver = {
341 .driver = {
342 .name = "st-lpc-rtc",
343 .pm = &st_rtc_pm_ops,
344 .of_match_table = st_rtc_match,
345 },
346 .probe = st_rtc_probe,
347 .remove = st_rtc_remove,
348};
349
350module_platform_driver(st_rtc_platform_driver);
351
352MODULE_DESCRIPTION("STMicroelectronics LPC RTC driver");
353MODULE_AUTHOR("David Paris <david.paris@st.com>");
354MODULE_LICENSE("GPL");
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index e5e7c5505de7..262647bbc614 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -470,6 +470,18 @@ config SIRFSOC_WATCHDOG
470 Support for CSR SiRFprimaII and SiRFatlasVI watchdog. When 470 Support for CSR SiRFprimaII and SiRFatlasVI watchdog. When
471 the watchdog triggers the system will be reset. 471 the watchdog triggers the system will be reset.
472 472
473config ST_LPC_WATCHDOG
474 tristate "STMicroelectronics LPC Watchdog"
475 depends on ARCH_STI
476 depends on OF
477 select WATCHDOG_CORE
478 help
479 Say Y here to include STMicroelectronics Low Power Controller
480 (LPC) based Watchdog timer support.
481
482 To compile this driver as a module, choose M here: the
483 module will be called st_lpc_wdt.
484
473config TEGRA_WATCHDOG 485config TEGRA_WATCHDOG
474 tristate "Tegra watchdog" 486 tristate "Tegra watchdog"
475 depends on (ARCH_TEGRA || COMPILE_TEST) && HAS_IOMEM 487 depends on (ARCH_TEGRA || COMPILE_TEST) && HAS_IOMEM
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
index 5c19294d1c30..d98768c7d928 100644
--- a/drivers/watchdog/Makefile
+++ b/drivers/watchdog/Makefile
@@ -59,6 +59,7 @@ obj-$(CONFIG_RETU_WATCHDOG) += retu_wdt.o
59obj-$(CONFIG_BCM2835_WDT) += bcm2835_wdt.o 59obj-$(CONFIG_BCM2835_WDT) += bcm2835_wdt.o
60obj-$(CONFIG_MOXART_WDT) += moxart_wdt.o 60obj-$(CONFIG_MOXART_WDT) += moxart_wdt.o
61obj-$(CONFIG_SIRFSOC_WATCHDOG) += sirfsoc_wdt.o 61obj-$(CONFIG_SIRFSOC_WATCHDOG) += sirfsoc_wdt.o
62obj-$(CONFIG_ST_LPC_WATCHDOG) += st_lpc_wdt.o
62obj-$(CONFIG_QCOM_WDT) += qcom-wdt.o 63obj-$(CONFIG_QCOM_WDT) += qcom-wdt.o
63obj-$(CONFIG_BCM_KONA_WDT) += bcm_kona_wdt.o 64obj-$(CONFIG_BCM_KONA_WDT) += bcm_kona_wdt.o
64obj-$(CONFIG_TEGRA_WATCHDOG) += tegra_wdt.o 65obj-$(CONFIG_TEGRA_WATCHDOG) += tegra_wdt.o
diff --git a/drivers/watchdog/st_lpc_wdt.c b/drivers/watchdog/st_lpc_wdt.c
new file mode 100644
index 000000000000..f32be155212a
--- /dev/null
+++ b/drivers/watchdog/st_lpc_wdt.c
@@ -0,0 +1,344 @@
1/*
2 * ST's LPC Watchdog
3 *
4 * Copyright (C) 2014 STMicroelectronics -- All Rights Reserved
5 *
6 * Author: David Paris <david.paris@st.com> for STMicroelectronics
7 * Lee Jones <lee.jones@linaro.org> for STMicroelectronics
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public Licence
11 * as published by the Free Software Foundation; either version
12 * 2 of the Licence, or (at your option) any later version.
13 */
14
15#include <linux/clk.h>
16#include <linux/init.h>
17#include <linux/io.h>
18#include <linux/kernel.h>
19#include <linux/mfd/syscon.h>
20#include <linux/module.h>
21#include <linux/of.h>
22#include <linux/of_platform.h>
23#include <linux/platform_device.h>
24#include <linux/regmap.h>
25#include <linux/watchdog.h>
26
27#include <dt-bindings/mfd/st-lpc.h>
28
29/* Low Power Alarm */
30#define LPC_LPA_LSB_OFF 0x410
31#define LPC_LPA_START_OFF 0x418
32
33/* LPC as WDT */
34#define LPC_WDT_OFF 0x510
35
36static struct watchdog_device st_wdog_dev;
37
38struct st_wdog_syscfg {
39 unsigned int reset_type_reg;
40 unsigned int reset_type_mask;
41 unsigned int enable_reg;
42 unsigned int enable_mask;
43};
44
45struct st_wdog {
46 void __iomem *base;
47 struct device *dev;
48 struct regmap *regmap;
49 struct st_wdog_syscfg *syscfg;
50 struct clk *clk;
51 unsigned long clkrate;
52 bool warm_reset;
53};
54
55static struct st_wdog_syscfg stid127_syscfg = {
56 .reset_type_reg = 0x004,
57 .reset_type_mask = BIT(2),
58 .enable_reg = 0x000,
59 .enable_mask = BIT(2),
60};
61
62static struct st_wdog_syscfg stih415_syscfg = {
63 .reset_type_reg = 0x0B8,
64 .reset_type_mask = BIT(6),
65 .enable_reg = 0x0B4,
66 .enable_mask = BIT(7),
67};
68
69static struct st_wdog_syscfg stih416_syscfg = {
70 .reset_type_reg = 0x88C,
71 .reset_type_mask = BIT(6),
72 .enable_reg = 0x888,
73 .enable_mask = BIT(7),
74};
75
76static struct st_wdog_syscfg stih407_syscfg = {
77 .enable_reg = 0x204,
78 .enable_mask = BIT(19),
79};
80
81static const struct of_device_id st_wdog_match[] = {
82 {
83 .compatible = "st,stih407-lpc",
84 .data = &stih407_syscfg,
85 },
86 {
87 .compatible = "st,stih416-lpc",
88 .data = &stih416_syscfg,
89 },
90 {
91 .compatible = "st,stih415-lpc",
92 .data = &stih415_syscfg,
93 },
94 {
95 .compatible = "st,stid127-lpc",
96 .data = &stid127_syscfg,
97 },
98 {},
99};
100MODULE_DEVICE_TABLE(of, st_wdog_match);
101
102static void st_wdog_setup(struct st_wdog *st_wdog, bool enable)
103{
104 /* Type of watchdog reset - 0: Cold 1: Warm */
105 if (st_wdog->syscfg->reset_type_reg)
106 regmap_update_bits(st_wdog->regmap,
107 st_wdog->syscfg->reset_type_reg,
108 st_wdog->syscfg->reset_type_mask,
109 st_wdog->warm_reset);
110
111 /* Mask/unmask watchdog reset */
112 regmap_update_bits(st_wdog->regmap,
113 st_wdog->syscfg->enable_reg,
114 st_wdog->syscfg->enable_mask,
115 enable ? 0 : st_wdog->syscfg->enable_mask);
116}
117
118static void st_wdog_load_timer(struct st_wdog *st_wdog, unsigned int timeout)
119{
120 unsigned long clkrate = st_wdog->clkrate;
121
122 writel_relaxed(timeout * clkrate, st_wdog->base + LPC_LPA_LSB_OFF);
123 writel_relaxed(1, st_wdog->base + LPC_LPA_START_OFF);
124}
125
126static int st_wdog_start(struct watchdog_device *wdd)
127{
128 struct st_wdog *st_wdog = watchdog_get_drvdata(wdd);
129
130 writel_relaxed(1, st_wdog->base + LPC_WDT_OFF);
131
132 return 0;
133}
134
135static int st_wdog_stop(struct watchdog_device *wdd)
136{
137 struct st_wdog *st_wdog = watchdog_get_drvdata(wdd);
138
139 writel_relaxed(0, st_wdog->base + LPC_WDT_OFF);
140
141 return 0;
142}
143
144static int st_wdog_set_timeout(struct watchdog_device *wdd,
145 unsigned int timeout)
146{
147 struct st_wdog *st_wdog = watchdog_get_drvdata(wdd);
148
149 wdd->timeout = timeout;
150 st_wdog_load_timer(st_wdog, timeout);
151
152 return 0;
153}
154
155static int st_wdog_keepalive(struct watchdog_device *wdd)
156{
157 struct st_wdog *st_wdog = watchdog_get_drvdata(wdd);
158
159 st_wdog_load_timer(st_wdog, wdd->timeout);
160
161 return 0;
162}
163
164static const struct watchdog_info st_wdog_info = {
165 .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE,
166 .identity = "ST LPC WDT",
167};
168
169static const struct watchdog_ops st_wdog_ops = {
170 .owner = THIS_MODULE,
171 .start = st_wdog_start,
172 .stop = st_wdog_stop,
173 .ping = st_wdog_keepalive,
174 .set_timeout = st_wdog_set_timeout,
175};
176
177static struct watchdog_device st_wdog_dev = {
178 .info = &st_wdog_info,
179 .ops = &st_wdog_ops,
180};
181
182static int st_wdog_probe(struct platform_device *pdev)
183{
184 const struct of_device_id *match;
185 struct device_node *np = pdev->dev.of_node;
186 struct st_wdog *st_wdog;
187 struct regmap *regmap;
188 struct resource *res;
189 struct clk *clk;
190 void __iomem *base;
191 uint32_t mode;
192 int ret;
193
194 ret = of_property_read_u32(np, "st,lpc-mode", &mode);
195 if (ret) {
196 dev_err(&pdev->dev, "An LPC mode must be provided\n");
197 return -EINVAL;
198 }
199
200 /* LPC can either run in RTC or WDT mode */
201 if (mode != ST_LPC_MODE_WDT)
202 return -ENODEV;
203
204 st_wdog = devm_kzalloc(&pdev->dev, sizeof(*st_wdog), GFP_KERNEL);
205 if (!st_wdog)
206 return -ENOMEM;
207
208 match = of_match_device(st_wdog_match, &pdev->dev);
209 if (!match) {
210 dev_err(&pdev->dev, "Couldn't match device\n");
211 return -ENODEV;
212 }
213 st_wdog->syscfg = (struct st_wdog_syscfg *)match->data;
214
215 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
216 base = devm_ioremap_resource(&pdev->dev, res);
217 if (IS_ERR(base))
218 return PTR_ERR(base);
219
220 regmap = syscon_regmap_lookup_by_phandle(np, "st,syscfg");
221 if (IS_ERR(regmap)) {
222 dev_err(&pdev->dev, "No syscfg phandle specified\n");
223 return PTR_ERR(regmap);
224 }
225
226 clk = devm_clk_get(&pdev->dev, NULL);
227 if (IS_ERR(clk)) {
228 dev_err(&pdev->dev, "Unable to request clock\n");
229 return PTR_ERR(clk);
230 }
231
232 st_wdog->dev = &pdev->dev;
233 st_wdog->base = base;
234 st_wdog->clk = clk;
235 st_wdog->regmap = regmap;
236 st_wdog->warm_reset = of_property_read_bool(np, "st,warm_reset");
237 st_wdog->clkrate = clk_get_rate(st_wdog->clk);
238
239 if (!st_wdog->clkrate) {
240 dev_err(&pdev->dev, "Unable to fetch clock rate\n");
241 return -EINVAL;
242 }
243 st_wdog_dev.max_timeout = 0xFFFFFFFF / st_wdog->clkrate;
244
245 ret = clk_prepare_enable(clk);
246 if (ret) {
247 dev_err(&pdev->dev, "Unable to enable clock\n");
248 return ret;
249 }
250
251 watchdog_set_drvdata(&st_wdog_dev, st_wdog);
252 watchdog_set_nowayout(&st_wdog_dev, WATCHDOG_NOWAYOUT);
253
254 /* Init Watchdog timeout with value in DT */
255 ret = watchdog_init_timeout(&st_wdog_dev, 0, &pdev->dev);
256 if (ret) {
257 dev_err(&pdev->dev, "Unable to initialise watchdog timeout\n");
258 clk_disable_unprepare(clk);
259 return ret;
260 }
261
262 ret = watchdog_register_device(&st_wdog_dev);
263 if (ret) {
264 dev_err(&pdev->dev, "Unable to register watchdog\n");
265 clk_disable_unprepare(clk);
266 return ret;
267 }
268
269 st_wdog_setup(st_wdog, true);
270
271 dev_info(&pdev->dev, "LPC Watchdog driver registered, reset type is %s",
272 st_wdog->warm_reset ? "warm" : "cold");
273
274 return ret;
275}
276
277static int st_wdog_remove(struct platform_device *pdev)
278{
279 struct st_wdog *st_wdog = watchdog_get_drvdata(&st_wdog_dev);
280
281 st_wdog_setup(st_wdog, false);
282 watchdog_unregister_device(&st_wdog_dev);
283 clk_disable_unprepare(st_wdog->clk);
284
285 return 0;
286}
287
288#ifdef CONFIG_PM_SLEEP
289static int st_wdog_suspend(struct device *dev)
290{
291 struct st_wdog *st_wdog = watchdog_get_drvdata(&st_wdog_dev);
292
293 if (watchdog_active(&st_wdog_dev))
294 st_wdog_stop(&st_wdog_dev);
295
296 st_wdog_setup(st_wdog, false);
297
298 clk_disable(st_wdog->clk);
299
300 return 0;
301}
302
303static int st_wdog_resume(struct device *dev)
304{
305 struct st_wdog *st_wdog = watchdog_get_drvdata(&st_wdog_dev);
306 int ret;
307
308 ret = clk_enable(st_wdog->clk);
309 if (ret) {
310 dev_err(dev, "Unable to re-enable clock\n");
311 watchdog_unregister_device(&st_wdog_dev);
312 clk_unprepare(st_wdog->clk);
313 return ret;
314 }
315
316 st_wdog_setup(st_wdog, true);
317
318 if (watchdog_active(&st_wdog_dev)) {
319 st_wdog_load_timer(st_wdog, st_wdog_dev.timeout);
320 st_wdog_start(&st_wdog_dev);
321 }
322
323 return 0;
324}
325#endif
326
327static SIMPLE_DEV_PM_OPS(st_wdog_pm_ops,
328 st_wdog_suspend,
329 st_wdog_resume);
330
331static struct platform_driver st_wdog_driver = {
332 .driver = {
333 .name = "st-lpc-wdt",
334 .pm = &st_wdog_pm_ops,
335 .of_match_table = st_wdog_match,
336 },
337 .probe = st_wdog_probe,
338 .remove = st_wdog_remove,
339};
340module_platform_driver(st_wdog_driver);
341
342MODULE_AUTHOR("David Paris <david.paris@st.com>");
343MODULE_DESCRIPTION("ST LPC Watchdog Driver");
344MODULE_LICENSE("GPL");
diff --git a/include/dt-bindings/mfd/arizona.h b/include/dt-bindings/mfd/arizona.h
index c7af7c7ef793..555609910acb 100644
--- a/include/dt-bindings/mfd/arizona.h
+++ b/include/dt-bindings/mfd/arizona.h
@@ -90,4 +90,18 @@
90#define ARIZONA_INMODE_SE 1 90#define ARIZONA_INMODE_SE 1
91#define ARIZONA_INMODE_DMIC 2 91#define ARIZONA_INMODE_DMIC 2
92 92
93#define ARIZONA_MICD_TIME_CONTINUOUS 0
94#define ARIZONA_MICD_TIME_250US 1
95#define ARIZONA_MICD_TIME_500US 2
96#define ARIZONA_MICD_TIME_1MS 3
97#define ARIZONA_MICD_TIME_2MS 4
98#define ARIZONA_MICD_TIME_4MS 5
99#define ARIZONA_MICD_TIME_8MS 6
100#define ARIZONA_MICD_TIME_16MS 7
101#define ARIZONA_MICD_TIME_32MS 8
102#define ARIZONA_MICD_TIME_64MS 9
103#define ARIZONA_MICD_TIME_128MS 10
104#define ARIZONA_MICD_TIME_256MS 11
105#define ARIZONA_MICD_TIME_512MS 12
106
93#endif 107#endif
diff --git a/include/dt-bindings/mfd/st-lpc.h b/include/dt-bindings/mfd/st-lpc.h
new file mode 100644
index 000000000000..e3e6c75d8822
--- /dev/null
+++ b/include/dt-bindings/mfd/st-lpc.h
@@ -0,0 +1,15 @@
1/*
2 * This header provides shared DT/Driver defines for ST's LPC device
3 *
4 * Copyright (C) 2014 STMicroelectronics -- All Rights Reserved
5 *
6 * Author: Lee Jones <lee.jones@linaro.org> for STMicroelectronics
7 */
8
9#ifndef __DT_BINDINGS_ST_LPC_H__
10#define __DT_BINDINGS_ST_LPC_H__
11
12#define ST_LPC_MODE_RTC 0
13#define ST_LPC_MODE_WDT 1
14
15#endif /* __DT_BINDINGS_ST_LPC_H__ */
diff --git a/include/linux/i2c/twl.h b/include/linux/i2c/twl.h
index 0bc03f100d04..9ad7828d9d34 100644
--- a/include/linux/i2c/twl.h
+++ b/include/linux/i2c/twl.h
@@ -675,6 +675,7 @@ struct twl4030_power_data {
675 struct twl4030_resconfig *board_config; 675 struct twl4030_resconfig *board_config;
676#define TWL4030_RESCONFIG_UNDEF ((u8)-1) 676#define TWL4030_RESCONFIG_UNDEF ((u8)-1)
677 bool use_poweroff; /* Board is wired for TWL poweroff */ 677 bool use_poweroff; /* Board is wired for TWL poweroff */
678 bool ac_charger_quirk; /* Disable AC charger on board */
678}; 679};
679 680
680extern int twl4030_remove_script(u8 flags); 681extern int twl4030_remove_script(u8 flags);
diff --git a/include/linux/mfd/arizona/core.h b/include/linux/mfd/arizona/core.h
index 16a498f48169..2f434f4f79a1 100644
--- a/include/linux/mfd/arizona/core.h
+++ b/include/linux/mfd/arizona/core.h
@@ -117,6 +117,7 @@ struct arizona {
117 int num_core_supplies; 117 int num_core_supplies;
118 struct regulator_bulk_data core_supplies[ARIZONA_MAX_CORE_SUPPLIES]; 118 struct regulator_bulk_data core_supplies[ARIZONA_MAX_CORE_SUPPLIES];
119 struct regulator *dcvdd; 119 struct regulator *dcvdd;
120 bool has_fully_powered_off;
120 121
121 struct arizona_pdata pdata; 122 struct arizona_pdata pdata;
122 123
@@ -153,7 +154,15 @@ int arizona_request_irq(struct arizona *arizona, int irq, char *name,
153void arizona_free_irq(struct arizona *arizona, int irq, void *data); 154void arizona_free_irq(struct arizona *arizona, int irq, void *data);
154int arizona_set_irq_wake(struct arizona *arizona, int irq, int on); 155int arizona_set_irq_wake(struct arizona *arizona, int irq, int on);
155 156
157#ifdef CONFIG_MFD_WM5102
156int wm5102_patch(struct arizona *arizona); 158int wm5102_patch(struct arizona *arizona);
159#else
160static inline int wm5102_patch(struct arizona *arizona)
161{
162 return 0;
163}
164#endif
165
157int wm5110_patch(struct arizona *arizona); 166int wm5110_patch(struct arizona *arizona);
158int wm8997_patch(struct arizona *arizona); 167int wm8997_patch(struct arizona *arizona);
159 168
diff --git a/include/linux/mfd/arizona/pdata.h b/include/linux/mfd/arizona/pdata.h
index 1789cb0f4f17..f6722677e6d0 100644
--- a/include/linux/mfd/arizona/pdata.h
+++ b/include/linux/mfd/arizona/pdata.h
@@ -156,7 +156,10 @@ struct arizona_pdata {
156 /** MICBIAS configurations */ 156 /** MICBIAS configurations */
157 struct arizona_micbias micbias[ARIZONA_MAX_MICBIAS]; 157 struct arizona_micbias micbias[ARIZONA_MAX_MICBIAS];
158 158
159 /** Mode of input structures */ 159 /**
160 * Mode of input structures
161 * One of the ARIZONA_INMODE_xxx values
162 */
160 int inmode[ARIZONA_MAX_INPUT]; 163 int inmode[ARIZONA_MAX_INPUT];
161 164
162 /** Mode for outputs */ 165 /** Mode for outputs */
diff --git a/include/linux/mfd/arizona/registers.h b/include/linux/mfd/arizona/registers.h
index aacc10d7789c..3499d36e6067 100644
--- a/include/linux/mfd/arizona/registers.h
+++ b/include/linux/mfd/arizona/registers.h
@@ -2515,9 +2515,12 @@
2515#define ARIZONA_IN1_DMIC_SUP_MASK 0x1800 /* IN1_DMIC_SUP - [12:11] */ 2515#define ARIZONA_IN1_DMIC_SUP_MASK 0x1800 /* IN1_DMIC_SUP - [12:11] */
2516#define ARIZONA_IN1_DMIC_SUP_SHIFT 11 /* IN1_DMIC_SUP - [12:11] */ 2516#define ARIZONA_IN1_DMIC_SUP_SHIFT 11 /* IN1_DMIC_SUP - [12:11] */
2517#define ARIZONA_IN1_DMIC_SUP_WIDTH 2 /* IN1_DMIC_SUP - [12:11] */ 2517#define ARIZONA_IN1_DMIC_SUP_WIDTH 2 /* IN1_DMIC_SUP - [12:11] */
2518#define ARIZONA_IN1_MODE_MASK 0x0600 /* IN1_MODE - [10:9] */ 2518#define ARIZONA_IN1_MODE_MASK 0x0400 /* IN1_MODE - [10] */
2519#define ARIZONA_IN1_MODE_SHIFT 9 /* IN1_MODE - [10:9] */ 2519#define ARIZONA_IN1_MODE_SHIFT 10 /* IN1_MODE - [10] */
2520#define ARIZONA_IN1_MODE_WIDTH 2 /* IN1_MODE - [10:9] */ 2520#define ARIZONA_IN1_MODE_WIDTH 1 /* IN1_MODE - [10] */
2521#define ARIZONA_IN1_SINGLE_ENDED_MASK 0x0200 /* IN1_MODE - [9] */
2522#define ARIZONA_IN1_SINGLE_ENDED_SHIFT 9 /* IN1_MODE - [9] */
2523#define ARIZONA_IN1_SINGLE_ENDED_WIDTH 1 /* IN1_MODE - [9] */
2521#define ARIZONA_IN1L_PGA_VOL_MASK 0x00FE /* IN1L_PGA_VOL - [7:1] */ 2524#define ARIZONA_IN1L_PGA_VOL_MASK 0x00FE /* IN1L_PGA_VOL - [7:1] */
2522#define ARIZONA_IN1L_PGA_VOL_SHIFT 1 /* IN1L_PGA_VOL - [7:1] */ 2525#define ARIZONA_IN1L_PGA_VOL_SHIFT 1 /* IN1L_PGA_VOL - [7:1] */
2523#define ARIZONA_IN1L_PGA_VOL_WIDTH 7 /* IN1L_PGA_VOL - [7:1] */ 2526#define ARIZONA_IN1L_PGA_VOL_WIDTH 7 /* IN1L_PGA_VOL - [7:1] */
@@ -2588,9 +2591,12 @@
2588#define ARIZONA_IN2_DMIC_SUP_MASK 0x1800 /* IN2_DMIC_SUP - [12:11] */ 2591#define ARIZONA_IN2_DMIC_SUP_MASK 0x1800 /* IN2_DMIC_SUP - [12:11] */
2589#define ARIZONA_IN2_DMIC_SUP_SHIFT 11 /* IN2_DMIC_SUP - [12:11] */ 2592#define ARIZONA_IN2_DMIC_SUP_SHIFT 11 /* IN2_DMIC_SUP - [12:11] */
2590#define ARIZONA_IN2_DMIC_SUP_WIDTH 2 /* IN2_DMIC_SUP - [12:11] */ 2593#define ARIZONA_IN2_DMIC_SUP_WIDTH 2 /* IN2_DMIC_SUP - [12:11] */
2591#define ARIZONA_IN2_MODE_MASK 0x0600 /* IN2_MODE - [10:9] */ 2594#define ARIZONA_IN2_MODE_MASK 0x0400 /* IN2_MODE - [10] */
2592#define ARIZONA_IN2_MODE_SHIFT 9 /* IN2_MODE - [10:9] */ 2595#define ARIZONA_IN2_MODE_SHIFT 10 /* IN2_MODE - [10] */
2593#define ARIZONA_IN2_MODE_WIDTH 2 /* IN2_MODE - [10:9] */ 2596#define ARIZONA_IN2_MODE_WIDTH 1 /* IN2_MODE - [10] */
2597#define ARIZONA_IN2_SINGLE_ENDED_MASK 0x0200 /* IN2_MODE - [9] */
2598#define ARIZONA_IN2_SINGLE_ENDED_SHIFT 9 /* IN2_MODE - [9] */
2599#define ARIZONA_IN2_SINGLE_ENDED_WIDTH 1 /* IN2_MODE - [9] */
2594#define ARIZONA_IN2L_PGA_VOL_MASK 0x00FE /* IN2L_PGA_VOL - [7:1] */ 2600#define ARIZONA_IN2L_PGA_VOL_MASK 0x00FE /* IN2L_PGA_VOL - [7:1] */
2595#define ARIZONA_IN2L_PGA_VOL_SHIFT 1 /* IN2L_PGA_VOL - [7:1] */ 2601#define ARIZONA_IN2L_PGA_VOL_SHIFT 1 /* IN2L_PGA_VOL - [7:1] */
2596#define ARIZONA_IN2L_PGA_VOL_WIDTH 7 /* IN2L_PGA_VOL - [7:1] */ 2602#define ARIZONA_IN2L_PGA_VOL_WIDTH 7 /* IN2L_PGA_VOL - [7:1] */
@@ -2661,9 +2667,12 @@
2661#define ARIZONA_IN3_DMIC_SUP_MASK 0x1800 /* IN3_DMIC_SUP - [12:11] */ 2667#define ARIZONA_IN3_DMIC_SUP_MASK 0x1800 /* IN3_DMIC_SUP - [12:11] */
2662#define ARIZONA_IN3_DMIC_SUP_SHIFT 11 /* IN3_DMIC_SUP - [12:11] */ 2668#define ARIZONA_IN3_DMIC_SUP_SHIFT 11 /* IN3_DMIC_SUP - [12:11] */
2663#define ARIZONA_IN3_DMIC_SUP_WIDTH 2 /* IN3_DMIC_SUP - [12:11] */ 2669#define ARIZONA_IN3_DMIC_SUP_WIDTH 2 /* IN3_DMIC_SUP - [12:11] */
2664#define ARIZONA_IN3_MODE_MASK 0x0600 /* IN3_MODE - [10:9] */ 2670#define ARIZONA_IN3_MODE_MASK 0x0400 /* IN3_MODE - [10] */
2665#define ARIZONA_IN3_MODE_SHIFT 9 /* IN3_MODE - [10:9] */ 2671#define ARIZONA_IN3_MODE_SHIFT 10 /* IN3_MODE - [10] */
2666#define ARIZONA_IN3_MODE_WIDTH 2 /* IN3_MODE - [10:9] */ 2672#define ARIZONA_IN3_MODE_WIDTH 1 /* IN3_MODE - [10] */
2673#define ARIZONA_IN3_SINGLE_ENDED_MASK 0x0200 /* IN3_MODE - [9] */
2674#define ARIZONA_IN3_SINGLE_ENDED_SHIFT 9 /* IN3_MODE - [9] */
2675#define ARIZONA_IN3_SINGLE_ENDED_WIDTH 1 /* IN3_MODE - [9] */
2667#define ARIZONA_IN3L_PGA_VOL_MASK 0x00FE /* IN3L_PGA_VOL - [7:1] */ 2676#define ARIZONA_IN3L_PGA_VOL_MASK 0x00FE /* IN3L_PGA_VOL - [7:1] */
2668#define ARIZONA_IN3L_PGA_VOL_SHIFT 1 /* IN3L_PGA_VOL - [7:1] */ 2677#define ARIZONA_IN3L_PGA_VOL_SHIFT 1 /* IN3L_PGA_VOL - [7:1] */
2669#define ARIZONA_IN3L_PGA_VOL_WIDTH 7 /* IN3L_PGA_VOL - [7:1] */ 2678#define ARIZONA_IN3L_PGA_VOL_WIDTH 7 /* IN3L_PGA_VOL - [7:1] */
diff --git a/include/linux/mfd/axp20x.h b/include/linux/mfd/axp20x.h
index f9030df5acd1..02f97dc568ac 100644
--- a/include/linux/mfd/axp20x.h
+++ b/include/linux/mfd/axp20x.h
@@ -14,6 +14,7 @@
14enum { 14enum {
15 AXP202_ID = 0, 15 AXP202_ID = 0,
16 AXP209_ID, 16 AXP209_ID,
17 AXP221_ID,
17 AXP288_ID, 18 AXP288_ID,
18 NR_AXP20X_VARIANTS, 19 NR_AXP20X_VARIANTS,
19}; 20};
@@ -45,6 +46,28 @@ enum {
45#define AXP20X_V_LTF_DISCHRG 0x3c 46#define AXP20X_V_LTF_DISCHRG 0x3c
46#define AXP20X_V_HTF_DISCHRG 0x3d 47#define AXP20X_V_HTF_DISCHRG 0x3d
47 48
49#define AXP22X_PWR_OUT_CTRL1 0x10
50#define AXP22X_PWR_OUT_CTRL2 0x12
51#define AXP22X_PWR_OUT_CTRL3 0x13
52#define AXP22X_DLDO1_V_OUT 0x15
53#define AXP22X_DLDO2_V_OUT 0x16
54#define AXP22X_DLDO3_V_OUT 0x17
55#define AXP22X_DLDO4_V_OUT 0x18
56#define AXP22X_ELDO1_V_OUT 0x19
57#define AXP22X_ELDO2_V_OUT 0x1a
58#define AXP22X_ELDO3_V_OUT 0x1b
59#define AXP22X_DC5LDO_V_OUT 0x1c
60#define AXP22X_DCDC1_V_OUT 0x21
61#define AXP22X_DCDC2_V_OUT 0x22
62#define AXP22X_DCDC3_V_OUT 0x23
63#define AXP22X_DCDC4_V_OUT 0x24
64#define AXP22X_DCDC5_V_OUT 0x25
65#define AXP22X_DCDC23_V_RAMP_CTRL 0x27
66#define AXP22X_ALDO1_V_OUT 0x28
67#define AXP22X_ALDO2_V_OUT 0x29
68#define AXP22X_ALDO3_V_OUT 0x2a
69#define AXP22X_CHRG_CTRL3 0x35
70
48/* Interrupt */ 71/* Interrupt */
49#define AXP20X_IRQ1_EN 0x40 72#define AXP20X_IRQ1_EN 0x40
50#define AXP20X_IRQ2_EN 0x41 73#define AXP20X_IRQ2_EN 0x41
@@ -100,6 +123,9 @@ enum {
100#define AXP20X_VBUS_MON 0x8b 123#define AXP20X_VBUS_MON 0x8b
101#define AXP20X_OVER_TMP 0x8f 124#define AXP20X_OVER_TMP 0x8f
102 125
126#define AXP22X_PWREN_CTRL1 0x8c
127#define AXP22X_PWREN_CTRL2 0x8d
128
103/* GPIO */ 129/* GPIO */
104#define AXP20X_GPIO0_CTRL 0x90 130#define AXP20X_GPIO0_CTRL 0x90
105#define AXP20X_LDO5_V_OUT 0x91 131#define AXP20X_LDO5_V_OUT 0x91
@@ -108,6 +134,11 @@ enum {
108#define AXP20X_GPIO20_SS 0x94 134#define AXP20X_GPIO20_SS 0x94
109#define AXP20X_GPIO3_CTRL 0x95 135#define AXP20X_GPIO3_CTRL 0x95
110 136
137#define AXP22X_LDO_IO0_V_OUT 0x91
138#define AXP22X_LDO_IO1_V_OUT 0x93
139#define AXP22X_GPIO_STATE 0x94
140#define AXP22X_GPIO_PULL_DOWN 0x95
141
111/* Battery */ 142/* Battery */
112#define AXP20X_CHRG_CC_31_24 0xb0 143#define AXP20X_CHRG_CC_31_24 0xb0
113#define AXP20X_CHRG_CC_23_16 0xb1 144#define AXP20X_CHRG_CC_23_16 0xb1
@@ -120,6 +151,9 @@ enum {
120#define AXP20X_CC_CTRL 0xb8 151#define AXP20X_CC_CTRL 0xb8
121#define AXP20X_FG_RES 0xb9 152#define AXP20X_FG_RES 0xb9
122 153
154/* AXP22X specific registers */
155#define AXP22X_BATLOW_THRES1 0xe6
156
123/* AXP288 specific registers */ 157/* AXP288 specific registers */
124#define AXP288_PMIC_ADC_H 0x56 158#define AXP288_PMIC_ADC_H 0x56
125#define AXP288_PMIC_ADC_L 0x57 159#define AXP288_PMIC_ADC_L 0x57
@@ -158,6 +192,30 @@ enum {
158 AXP20X_REG_ID_MAX, 192 AXP20X_REG_ID_MAX,
159}; 193};
160 194
195enum {
196 AXP22X_DCDC1 = 0,
197 AXP22X_DCDC2,
198 AXP22X_DCDC3,
199 AXP22X_DCDC4,
200 AXP22X_DCDC5,
201 AXP22X_DC1SW,
202 AXP22X_DC5LDO,
203 AXP22X_ALDO1,
204 AXP22X_ALDO2,
205 AXP22X_ALDO3,
206 AXP22X_ELDO1,
207 AXP22X_ELDO2,
208 AXP22X_ELDO3,
209 AXP22X_DLDO1,
210 AXP22X_DLDO2,
211 AXP22X_DLDO3,
212 AXP22X_DLDO4,
213 AXP22X_RTC_LDO,
214 AXP22X_LDO_IO0,
215 AXP22X_LDO_IO1,
216 AXP22X_REG_ID_MAX,
217};
218
161/* IRQs */ 219/* IRQs */
162enum { 220enum {
163 AXP20X_IRQ_ACIN_OVER_V = 1, 221 AXP20X_IRQ_ACIN_OVER_V = 1,
@@ -199,6 +257,34 @@ enum {
199 AXP20X_IRQ_GPIO0_INPUT, 257 AXP20X_IRQ_GPIO0_INPUT,
200}; 258};
201 259
260enum axp22x_irqs {
261 AXP22X_IRQ_ACIN_OVER_V = 1,
262 AXP22X_IRQ_ACIN_PLUGIN,
263 AXP22X_IRQ_ACIN_REMOVAL,
264 AXP22X_IRQ_VBUS_OVER_V,
265 AXP22X_IRQ_VBUS_PLUGIN,
266 AXP22X_IRQ_VBUS_REMOVAL,
267 AXP22X_IRQ_VBUS_V_LOW,
268 AXP22X_IRQ_BATT_PLUGIN,
269 AXP22X_IRQ_BATT_REMOVAL,
270 AXP22X_IRQ_BATT_ENT_ACT_MODE,
271 AXP22X_IRQ_BATT_EXIT_ACT_MODE,
272 AXP22X_IRQ_CHARG,
273 AXP22X_IRQ_CHARG_DONE,
274 AXP22X_IRQ_BATT_TEMP_HIGH,
275 AXP22X_IRQ_BATT_TEMP_LOW,
276 AXP22X_IRQ_DIE_TEMP_HIGH,
277 AXP22X_IRQ_PEK_SHORT,
278 AXP22X_IRQ_PEK_LONG,
279 AXP22X_IRQ_LOW_PWR_LVL1,
280 AXP22X_IRQ_LOW_PWR_LVL2,
281 AXP22X_IRQ_TIMER,
282 AXP22X_IRQ_PEK_RIS_EDGE,
283 AXP22X_IRQ_PEK_FAL_EDGE,
284 AXP22X_IRQ_GPIO1_INPUT,
285 AXP22X_IRQ_GPIO0_INPUT,
286};
287
202enum axp288_irqs { 288enum axp288_irqs {
203 AXP288_IRQ_VBUS_FALL = 2, 289 AXP288_IRQ_VBUS_FALL = 2,
204 AXP288_IRQ_VBUS_RISE, 290 AXP288_IRQ_VBUS_RISE,
diff --git a/include/linux/mfd/cros_ec.h b/include/linux/mfd/cros_ec.h
index 324a34683971..da72671a42fa 100644
--- a/include/linux/mfd/cros_ec.h
+++ b/include/linux/mfd/cros_ec.h
@@ -17,10 +17,29 @@
17#define __LINUX_MFD_CROS_EC_H 17#define __LINUX_MFD_CROS_EC_H
18 18
19#include <linux/cdev.h> 19#include <linux/cdev.h>
20#include <linux/device.h>
20#include <linux/notifier.h> 21#include <linux/notifier.h>
21#include <linux/mfd/cros_ec_commands.h> 22#include <linux/mfd/cros_ec_commands.h>
22#include <linux/mutex.h> 23#include <linux/mutex.h>
23 24
25#define CROS_EC_DEV_NAME "cros_ec"
26#define CROS_EC_DEV_PD_NAME "cros_pd"
27
28/*
29 * The EC is unresponsive for a time after a reboot command. Add a
30 * simple delay to make sure that the bus stays locked.
31 */
32#define EC_REBOOT_DELAY_MS 50
33
34/*
35 * Max bus-specific overhead incurred by request/responses.
36 * I2C requires 1 additional byte for requests.
37 * I2C requires 2 additional bytes for responses.
38 * */
39#define EC_PROTO_VERSION_UNKNOWN 0
40#define EC_MAX_REQUEST_OVERHEAD 1
41#define EC_MAX_RESPONSE_OVERHEAD 2
42
24/* 43/*
25 * Command interface between EC and AP, for LPC, I2C and SPI interfaces. 44 * Command interface between EC and AP, for LPC, I2C and SPI interfaces.
26 */ 45 */
@@ -42,8 +61,7 @@ enum {
42 * @outsize: Outgoing length in bytes 61 * @outsize: Outgoing length in bytes
43 * @insize: Max number of bytes to accept from EC 62 * @insize: Max number of bytes to accept from EC
44 * @result: EC's response to the command (separate from communication failure) 63 * @result: EC's response to the command (separate from communication failure)
45 * @outdata: Outgoing data to EC 64 * @data: Where to put the incoming data from EC and outgoing data to EC
46 * @indata: Where to put the incoming data from EC
47 */ 65 */
48struct cros_ec_command { 66struct cros_ec_command {
49 uint32_t version; 67 uint32_t version;
@@ -51,18 +69,14 @@ struct cros_ec_command {
51 uint32_t outsize; 69 uint32_t outsize;
52 uint32_t insize; 70 uint32_t insize;
53 uint32_t result; 71 uint32_t result;
54 uint8_t outdata[EC_PROTO2_MAX_PARAM_SIZE]; 72 uint8_t data[0];
55 uint8_t indata[EC_PROTO2_MAX_PARAM_SIZE];
56}; 73};
57 74
58/** 75/**
59 * struct cros_ec_device - Information about a ChromeOS EC device 76 * struct cros_ec_device - Information about a ChromeOS EC device
60 * 77 *
61 * @ec_name: name of EC device (e.g. 'chromeos-ec')
62 * @phys_name: name of physical comms layer (e.g. 'i2c-4') 78 * @phys_name: name of physical comms layer (e.g. 'i2c-4')
63 * @dev: Device pointer for physical comms device 79 * @dev: Device pointer for physical comms device
64 * @vdev: Device pointer for virtual comms device
65 * @cdev: Character device structure for virtual comms device
66 * @was_wake_device: true if this device was set to wake the system from 80 * @was_wake_device: true if this device was set to wake the system from
67 * sleep at the last suspend 81 * sleep at the last suspend
68 * @cmd_readmem: direct read of the EC memory-mapped region, if supported 82 * @cmd_readmem: direct read of the EC memory-mapped region, if supported
@@ -74,6 +88,7 @@ struct cros_ec_command {
74 * 88 *
75 * @priv: Private data 89 * @priv: Private data
76 * @irq: Interrupt to use 90 * @irq: Interrupt to use
91 * @id: Device id
77 * @din: input buffer (for data from EC) 92 * @din: input buffer (for data from EC)
78 * @dout: output buffer (for data to EC) 93 * @dout: output buffer (for data to EC)
79 * \note 94 * \note
@@ -85,41 +100,72 @@ struct cros_ec_command {
85 * to using dword. 100 * to using dword.
86 * @din_size: size of din buffer to allocate (zero to use static din) 101 * @din_size: size of din buffer to allocate (zero to use static din)
87 * @dout_size: size of dout buffer to allocate (zero to use static dout) 102 * @dout_size: size of dout buffer to allocate (zero to use static dout)
88 * @parent: pointer to parent device (e.g. i2c or spi device)
89 * @wake_enabled: true if this device can wake the system from sleep 103 * @wake_enabled: true if this device can wake the system from sleep
90 * @cmd_xfer: send command to EC and get response 104 * @cmd_xfer: send command to EC and get response
91 * Returns the number of bytes received if the communication succeeded, but 105 * Returns the number of bytes received if the communication succeeded, but
92 * that doesn't mean the EC was happy with the command. The caller 106 * that doesn't mean the EC was happy with the command. The caller
93 * should check msg.result for the EC's result code. 107 * should check msg.result for the EC's result code.
108 * @pkt_xfer: send packet to EC and get response
94 * @lock: one transaction at a time 109 * @lock: one transaction at a time
95 */ 110 */
96struct cros_ec_device { 111struct cros_ec_device {
97 112
98 /* These are used by other drivers that want to talk to the EC */ 113 /* These are used by other drivers that want to talk to the EC */
99 const char *ec_name;
100 const char *phys_name; 114 const char *phys_name;
101 struct device *dev; 115 struct device *dev;
102 struct device *vdev;
103 struct cdev cdev;
104 bool was_wake_device; 116 bool was_wake_device;
105 struct class *cros_class; 117 struct class *cros_class;
106 int (*cmd_readmem)(struct cros_ec_device *ec, unsigned int offset, 118 int (*cmd_readmem)(struct cros_ec_device *ec, unsigned int offset,
107 unsigned int bytes, void *dest); 119 unsigned int bytes, void *dest);
108 120
109 /* These are used to implement the platform-specific interface */ 121 /* These are used to implement the platform-specific interface */
122 u16 max_request;
123 u16 max_response;
124 u16 max_passthru;
125 u16 proto_version;
110 void *priv; 126 void *priv;
111 int irq; 127 int irq;
112 uint8_t *din; 128 u8 *din;
113 uint8_t *dout; 129 u8 *dout;
114 int din_size; 130 int din_size;
115 int dout_size; 131 int dout_size;
116 struct device *parent;
117 bool wake_enabled; 132 bool wake_enabled;
118 int (*cmd_xfer)(struct cros_ec_device *ec, 133 int (*cmd_xfer)(struct cros_ec_device *ec,
119 struct cros_ec_command *msg); 134 struct cros_ec_command *msg);
135 int (*pkt_xfer)(struct cros_ec_device *ec,
136 struct cros_ec_command *msg);
120 struct mutex lock; 137 struct mutex lock;
121}; 138};
122 139
140/* struct cros_ec_platform - ChromeOS EC platform information
141 *
142 * @ec_name: name of EC device (e.g. 'cros-ec', 'cros-pd', ...)
143 * used in /dev/ and sysfs.
144 * @cmd_offset: offset to apply for each command. Set when
145 * registering a devicde behind another one.
146 */
147struct cros_ec_platform {
148 const char *ec_name;
149 u16 cmd_offset;
150};
151
152/*
153 * struct cros_ec_dev - ChromeOS EC device entry point
154 *
155 * @class_dev: Device structure used in sysfs
156 * @cdev: Character device structure in /dev
157 * @ec_dev: cros_ec_device structure to talk to the physical device
158 * @dev: pointer to the platform device
159 * @cmd_offset: offset to apply for each command.
160 */
161struct cros_ec_dev {
162 struct device class_dev;
163 struct cdev cdev;
164 struct cros_ec_device *ec_dev;
165 struct device *dev;
166 u16 cmd_offset;
167};
168
123/** 169/**
124 * cros_ec_suspend - Handle a suspend operation for the ChromeOS EC device 170 * cros_ec_suspend - Handle a suspend operation for the ChromeOS EC device
125 * 171 *
@@ -198,4 +244,16 @@ int cros_ec_remove(struct cros_ec_device *ec_dev);
198 */ 244 */
199int cros_ec_register(struct cros_ec_device *ec_dev); 245int cros_ec_register(struct cros_ec_device *ec_dev);
200 246
247/**
248 * cros_ec_register - Query the protocol version supported by the ChromeOS EC
249 *
250 * @ec_dev: Device to register
251 * @return 0 if ok, -ve on error
252 */
253int cros_ec_query_all(struct cros_ec_device *ec_dev);
254
255/* sysfs stuff */
256extern struct attribute_group cros_ec_attr_group;
257extern struct attribute_group cros_ec_lightbar_attr_group;
258
201#endif /* __LINUX_MFD_CROS_EC_H */ 259#endif /* __LINUX_MFD_CROS_EC_H */
diff --git a/include/linux/mfd/cros_ec_commands.h b/include/linux/mfd/cros_ec_commands.h
index a49cd41feea7..13b630c10d4c 100644
--- a/include/linux/mfd/cros_ec_commands.h
+++ b/include/linux/mfd/cros_ec_commands.h
@@ -515,7 +515,7 @@ struct ec_host_response {
515/* 515/*
516 * Notes on commands: 516 * Notes on commands:
517 * 517 *
518 * Each command is an 8-byte command value. Commands which take params or 518 * Each command is an 16-bit command value. Commands which take params or
519 * return response data specify structs for that data. If no struct is 519 * return response data specify structs for that data. If no struct is
520 * specified, the command does not input or output data, respectively. 520 * specified, the command does not input or output data, respectively.
521 * Parameter/response length is implicit in the structs. Some underlying 521 * Parameter/response length is implicit in the structs. Some underlying
@@ -966,7 +966,7 @@ struct rgb_s {
966/* List of tweakable parameters. NOTE: It's __packed so it can be sent in a 966/* List of tweakable parameters. NOTE: It's __packed so it can be sent in a
967 * host command, but the alignment is the same regardless. Keep it that way. 967 * host command, but the alignment is the same regardless. Keep it that way.
968 */ 968 */
969struct lightbar_params { 969struct lightbar_params_v0 {
970 /* Timing */ 970 /* Timing */
971 int32_t google_ramp_up; 971 int32_t google_ramp_up;
972 int32_t google_ramp_down; 972 int32_t google_ramp_down;
@@ -1000,32 +1000,81 @@ struct lightbar_params {
1000 struct rgb_s color[8]; /* 0-3 are Google colors */ 1000 struct rgb_s color[8]; /* 0-3 are Google colors */
1001} __packed; 1001} __packed;
1002 1002
1003struct lightbar_params_v1 {
1004 /* Timing */
1005 int32_t google_ramp_up;
1006 int32_t google_ramp_down;
1007 int32_t s3s0_ramp_up;
1008 int32_t s0_tick_delay[2]; /* AC=0/1 */
1009 int32_t s0a_tick_delay[2]; /* AC=0/1 */
1010 int32_t s0s3_ramp_down;
1011 int32_t s3_sleep_for;
1012 int32_t s3_ramp_up;
1013 int32_t s3_ramp_down;
1014 int32_t tap_tick_delay;
1015 int32_t tap_display_time;
1016
1017 /* Tap-for-battery params */
1018 uint8_t tap_pct_red;
1019 uint8_t tap_pct_green;
1020 uint8_t tap_seg_min_on;
1021 uint8_t tap_seg_max_on;
1022 uint8_t tap_seg_osc;
1023 uint8_t tap_idx[3];
1024
1025 /* Oscillation */
1026 uint8_t osc_min[2]; /* AC=0/1 */
1027 uint8_t osc_max[2]; /* AC=0/1 */
1028 uint8_t w_ofs[2]; /* AC=0/1 */
1029
1030 /* Brightness limits based on the backlight and AC. */
1031 uint8_t bright_bl_off_fixed[2]; /* AC=0/1 */
1032 uint8_t bright_bl_on_min[2]; /* AC=0/1 */
1033 uint8_t bright_bl_on_max[2]; /* AC=0/1 */
1034
1035 /* Battery level thresholds */
1036 uint8_t battery_threshold[LB_BATTERY_LEVELS - 1];
1037
1038 /* Map [AC][battery_level] to color index */
1039 uint8_t s0_idx[2][LB_BATTERY_LEVELS]; /* AP is running */
1040 uint8_t s3_idx[2][LB_BATTERY_LEVELS]; /* AP is sleeping */
1041
1042 /* Color palette */
1043 struct rgb_s color[8]; /* 0-3 are Google colors */
1044} __packed;
1045
1003struct ec_params_lightbar { 1046struct ec_params_lightbar {
1004 uint8_t cmd; /* Command (see enum lightbar_command) */ 1047 uint8_t cmd; /* Command (see enum lightbar_command) */
1005 union { 1048 union {
1006 struct { 1049 struct {
1007 /* no args */ 1050 /* no args */
1008 } dump, off, on, init, get_seq, get_params, version; 1051 } dump, off, on, init, get_seq, get_params_v0, get_params_v1,
1052 version, get_brightness, get_demo;
1009 1053
1010 struct num { 1054 struct {
1011 uint8_t num; 1055 uint8_t num;
1012 } brightness, seq, demo; 1056 } set_brightness, seq, demo;
1013 1057
1014 struct reg { 1058 struct {
1015 uint8_t ctrl, reg, value; 1059 uint8_t ctrl, reg, value;
1016 } reg; 1060 } reg;
1017 1061
1018 struct rgb { 1062 struct {
1019 uint8_t led, red, green, blue; 1063 uint8_t led, red, green, blue;
1020 } rgb; 1064 } set_rgb;
1065
1066 struct {
1067 uint8_t led;
1068 } get_rgb;
1021 1069
1022 struct lightbar_params set_params; 1070 struct lightbar_params_v0 set_params_v0;
1071 struct lightbar_params_v1 set_params_v1;
1023 }; 1072 };
1024} __packed; 1073} __packed;
1025 1074
1026struct ec_response_lightbar { 1075struct ec_response_lightbar {
1027 union { 1076 union {
1028 struct dump { 1077 struct {
1029 struct { 1078 struct {
1030 uint8_t reg; 1079 uint8_t reg;
1031 uint8_t ic0; 1080 uint8_t ic0;
@@ -1033,20 +1082,26 @@ struct ec_response_lightbar {
1033 } vals[23]; 1082 } vals[23];
1034 } dump; 1083 } dump;
1035 1084
1036 struct get_seq { 1085 struct {
1037 uint8_t num; 1086 uint8_t num;
1038 } get_seq; 1087 } get_seq, get_brightness, get_demo;
1039 1088
1040 struct lightbar_params get_params; 1089 struct lightbar_params_v0 get_params_v0;
1090 struct lightbar_params_v1 get_params_v1;
1041 1091
1042 struct version { 1092 struct {
1043 uint32_t num; 1093 uint32_t num;
1044 uint32_t flags; 1094 uint32_t flags;
1045 } version; 1095 } version;
1046 1096
1047 struct { 1097 struct {
1098 uint8_t red, green, blue;
1099 } get_rgb;
1100
1101 struct {
1048 /* no return params */ 1102 /* no return params */
1049 } off, on, init, brightness, seq, reg, rgb, demo, set_params; 1103 } off, on, init, set_brightness, seq, reg, set_rgb,
1104 demo, set_params_v0, set_params_v1;
1050 }; 1105 };
1051} __packed; 1106} __packed;
1052 1107
@@ -1056,15 +1111,20 @@ enum lightbar_command {
1056 LIGHTBAR_CMD_OFF = 1, 1111 LIGHTBAR_CMD_OFF = 1,
1057 LIGHTBAR_CMD_ON = 2, 1112 LIGHTBAR_CMD_ON = 2,
1058 LIGHTBAR_CMD_INIT = 3, 1113 LIGHTBAR_CMD_INIT = 3,
1059 LIGHTBAR_CMD_BRIGHTNESS = 4, 1114 LIGHTBAR_CMD_SET_BRIGHTNESS = 4,
1060 LIGHTBAR_CMD_SEQ = 5, 1115 LIGHTBAR_CMD_SEQ = 5,
1061 LIGHTBAR_CMD_REG = 6, 1116 LIGHTBAR_CMD_REG = 6,
1062 LIGHTBAR_CMD_RGB = 7, 1117 LIGHTBAR_CMD_SET_RGB = 7,
1063 LIGHTBAR_CMD_GET_SEQ = 8, 1118 LIGHTBAR_CMD_GET_SEQ = 8,
1064 LIGHTBAR_CMD_DEMO = 9, 1119 LIGHTBAR_CMD_DEMO = 9,
1065 LIGHTBAR_CMD_GET_PARAMS = 10, 1120 LIGHTBAR_CMD_GET_PARAMS_V0 = 10,
1066 LIGHTBAR_CMD_SET_PARAMS = 11, 1121 LIGHTBAR_CMD_SET_PARAMS_V0 = 11,
1067 LIGHTBAR_CMD_VERSION = 12, 1122 LIGHTBAR_CMD_VERSION = 12,
1123 LIGHTBAR_CMD_GET_BRIGHTNESS = 13,
1124 LIGHTBAR_CMD_GET_RGB = 14,
1125 LIGHTBAR_CMD_GET_DEMO = 15,
1126 LIGHTBAR_CMD_GET_PARAMS_V1 = 16,
1127 LIGHTBAR_CMD_SET_PARAMS_V1 = 17,
1068 LIGHTBAR_NUM_CMDS 1128 LIGHTBAR_NUM_CMDS
1069}; 1129};
1070 1130
@@ -1421,8 +1481,40 @@ struct ec_response_rtc {
1421/*****************************************************************************/ 1481/*****************************************************************************/
1422/* Port80 log access */ 1482/* Port80 log access */
1423 1483
1484/* Maximum entries that can be read/written in a single command */
1485#define EC_PORT80_SIZE_MAX 32
1486
1424/* Get last port80 code from previous boot */ 1487/* Get last port80 code from previous boot */
1425#define EC_CMD_PORT80_LAST_BOOT 0x48 1488#define EC_CMD_PORT80_LAST_BOOT 0x48
1489#define EC_CMD_PORT80_READ 0x48
1490
1491enum ec_port80_subcmd {
1492 EC_PORT80_GET_INFO = 0,
1493 EC_PORT80_READ_BUFFER,
1494};
1495
1496struct ec_params_port80_read {
1497 uint16_t subcmd;
1498 union {
1499 struct {
1500 uint32_t offset;
1501 uint32_t num_entries;
1502 } read_buffer;
1503 };
1504} __packed;
1505
1506struct ec_response_port80_read {
1507 union {
1508 struct {
1509 uint32_t writes;
1510 uint32_t history_size;
1511 uint32_t last_boot;
1512 } get_info;
1513 struct {
1514 uint16_t codes[EC_PORT80_SIZE_MAX];
1515 } data;
1516 };
1517} __packed;
1426 1518
1427struct ec_response_port80_last_boot { 1519struct ec_response_port80_last_boot {
1428 uint16_t code; 1520 uint16_t code;
@@ -1782,6 +1874,7 @@ struct ec_params_gpio_set {
1782/* Get GPIO value */ 1874/* Get GPIO value */
1783#define EC_CMD_GPIO_GET 0x93 1875#define EC_CMD_GPIO_GET 0x93
1784 1876
1877/* Version 0 of input params and response */
1785struct ec_params_gpio_get { 1878struct ec_params_gpio_get {
1786 char name[32]; 1879 char name[32];
1787} __packed; 1880} __packed;
@@ -1789,6 +1882,38 @@ struct ec_response_gpio_get {
1789 uint8_t val; 1882 uint8_t val;
1790} __packed; 1883} __packed;
1791 1884
1885/* Version 1 of input params and response */
1886struct ec_params_gpio_get_v1 {
1887 uint8_t subcmd;
1888 union {
1889 struct {
1890 char name[32];
1891 } get_value_by_name;
1892 struct {
1893 uint8_t index;
1894 } get_info;
1895 };
1896} __packed;
1897
1898struct ec_response_gpio_get_v1 {
1899 union {
1900 struct {
1901 uint8_t val;
1902 } get_value_by_name, get_count;
1903 struct {
1904 uint8_t val;
1905 char name[32];
1906 uint32_t flags;
1907 } get_info;
1908 };
1909} __packed;
1910
1911enum gpio_get_subcmd {
1912 EC_GPIO_GET_BY_NAME = 0,
1913 EC_GPIO_GET_COUNT = 1,
1914 EC_GPIO_GET_INFO = 2,
1915};
1916
1792/*****************************************************************************/ 1917/*****************************************************************************/
1793/* I2C commands. Only available when flash write protect is unlocked. */ 1918/* I2C commands. Only available when flash write protect is unlocked. */
1794 1919
@@ -1857,13 +1982,21 @@ struct ec_params_charge_control {
1857/*****************************************************************************/ 1982/*****************************************************************************/
1858 1983
1859/* 1984/*
1860 * Cut off battery power output if the battery supports. 1985 * Cut off battery power immediately or after the host has shut down.
1861 * 1986 *
1862 * For unsupported battery, just don't implement this command and lets EC 1987 * return EC_RES_INVALID_COMMAND if unsupported by a board/battery.
1863 * return EC_RES_INVALID_COMMAND. 1988 * EC_RES_SUCCESS if the command was successful.
1989 * EC_RES_ERROR if the cut off command failed.
1864 */ 1990 */
1991
1865#define EC_CMD_BATTERY_CUT_OFF 0x99 1992#define EC_CMD_BATTERY_CUT_OFF 0x99
1866 1993
1994#define EC_BATTERY_CUTOFF_FLAG_AT_SHUTDOWN (1 << 0)
1995
1996struct ec_params_battery_cutoff {
1997 uint8_t flags;
1998} __packed;
1999
1867/*****************************************************************************/ 2000/*****************************************************************************/
1868/* USB port mux control. */ 2001/* USB port mux control. */
1869 2002
@@ -2142,6 +2275,32 @@ struct ec_params_sb_wr_block {
2142} __packed; 2275} __packed;
2143 2276
2144/*****************************************************************************/ 2277/*****************************************************************************/
2278/* Battery vendor parameters
2279 *
2280 * Get or set vendor-specific parameters in the battery. Implementations may
2281 * differ between boards or batteries. On a set operation, the response
2282 * contains the actual value set, which may be rounded or clipped from the
2283 * requested value.
2284 */
2285
2286#define EC_CMD_BATTERY_VENDOR_PARAM 0xb4
2287
2288enum ec_battery_vendor_param_mode {
2289 BATTERY_VENDOR_PARAM_MODE_GET = 0,
2290 BATTERY_VENDOR_PARAM_MODE_SET,
2291};
2292
2293struct ec_params_battery_vendor_param {
2294 uint32_t param;
2295 uint32_t value;
2296 uint8_t mode;
2297} __packed;
2298
2299struct ec_response_battery_vendor_param {
2300 uint32_t value;
2301} __packed;
2302
2303/*****************************************************************************/
2145/* System commands */ 2304/* System commands */
2146 2305
2147/* 2306/*
@@ -2338,6 +2497,80 @@ struct ec_params_reboot_ec {
2338 2497
2339/*****************************************************************************/ 2498/*****************************************************************************/
2340/* 2499/*
2500 * PD commands
2501 *
2502 * These commands are for PD MCU communication.
2503 */
2504
2505/* EC to PD MCU exchange status command */
2506#define EC_CMD_PD_EXCHANGE_STATUS 0x100
2507
2508/* Status of EC being sent to PD */
2509struct ec_params_pd_status {
2510 int8_t batt_soc; /* battery state of charge */
2511} __packed;
2512
2513/* Status of PD being sent back to EC */
2514struct ec_response_pd_status {
2515 int8_t status; /* PD MCU status */
2516 uint32_t curr_lim_ma; /* input current limit */
2517} __packed;
2518
2519/* Set USB type-C port role and muxes */
2520#define EC_CMD_USB_PD_CONTROL 0x101
2521
2522enum usb_pd_control_role {
2523 USB_PD_CTRL_ROLE_NO_CHANGE = 0,
2524 USB_PD_CTRL_ROLE_TOGGLE_ON = 1, /* == AUTO */
2525 USB_PD_CTRL_ROLE_TOGGLE_OFF = 2,
2526 USB_PD_CTRL_ROLE_FORCE_SINK = 3,
2527 USB_PD_CTRL_ROLE_FORCE_SOURCE = 4,
2528};
2529
2530enum usb_pd_control_mux {
2531 USB_PD_CTRL_MUX_NO_CHANGE = 0,
2532 USB_PD_CTRL_MUX_NONE = 1,
2533 USB_PD_CTRL_MUX_USB = 2,
2534 USB_PD_CTRL_MUX_DP = 3,
2535 USB_PD_CTRL_MUX_DOCK = 4,
2536 USB_PD_CTRL_MUX_AUTO = 5,
2537};
2538
2539struct ec_params_usb_pd_control {
2540 uint8_t port;
2541 uint8_t role;
2542 uint8_t mux;
2543} __packed;
2544
2545/*****************************************************************************/
2546/*
2547 * Passthru commands
2548 *
2549 * Some platforms have sub-processors chained to each other. For example.
2550 *
2551 * AP <--> EC <--> PD MCU
2552 *
2553 * The top 2 bits of the command number are used to indicate which device the
2554 * command is intended for. Device 0 is always the device receiving the
2555 * command; other device mapping is board-specific.
2556 *
2557 * When a device receives a command to be passed to a sub-processor, it passes
2558 * it on with the device number set back to 0. This allows the sub-processor
2559 * to remain blissfully unaware of whether the command originated on the next
2560 * device up the chain, or was passed through from the AP.
2561 *
2562 * In the above example, if the AP wants to send command 0x0002 to the PD MCU,
2563 * AP sends command 0x4002 to the EC
2564 * EC sends command 0x0002 to the PD MCU
2565 * EC forwards PD MCU response back to the AP
2566 */
2567
2568/* Offset and max command number for sub-device n */
2569#define EC_CMD_PASSTHRU_OFFSET(n) (0x4000 * (n))
2570#define EC_CMD_PASSTHRU_MAX(n) (EC_CMD_PASSTHRU_OFFSET(n) + 0x3fff)
2571
2572/*****************************************************************************/
2573/*
2341 * Deprecated constants. These constants have been renamed for clarity. The 2574 * Deprecated constants. These constants have been renamed for clarity. The
2342 * meaning and size has not changed. Programs that use the old names should 2575 * meaning and size has not changed. Programs that use the old names should
2343 * switch to the new names soon, as the old names may not be carried forward 2576 * switch to the new names soon, as the old names may not be carried forward
diff --git a/include/linux/mfd/da9055/core.h b/include/linux/mfd/da9055/core.h
index 956afa445998..5dc743fd63a6 100644
--- a/include/linux/mfd/da9055/core.h
+++ b/include/linux/mfd/da9055/core.h
@@ -89,6 +89,6 @@ static inline int da9055_reg_update(struct da9055 *da9055, unsigned char reg,
89int da9055_device_init(struct da9055 *da9055); 89int da9055_device_init(struct da9055 *da9055);
90void da9055_device_exit(struct da9055 *da9055); 90void da9055_device_exit(struct da9055 *da9055);
91 91
92extern struct regmap_config da9055_regmap_config; 92extern const struct regmap_config da9055_regmap_config;
93 93
94#endif /* __DA9055_CORE_H */ 94#endif /* __DA9055_CORE_H */
diff --git a/include/linux/mfd/max77686.h b/include/linux/mfd/max77686.h
index bb995ab9a575..d4b72d519115 100644
--- a/include/linux/mfd/max77686.h
+++ b/include/linux/mfd/max77686.h
@@ -125,9 +125,4 @@ enum max77686_opmode {
125 MAX77686_OPMODE_STANDBY, 125 MAX77686_OPMODE_STANDBY,
126}; 126};
127 127
128struct max77686_opmode_data {
129 int id;
130 int mode;
131};
132
133#endif /* __LINUX_MFD_MAX77686_H */ 128#endif /* __LINUX_MFD_MAX77686_H */