aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2016-03-17 15:50:55 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2016-03-17 15:50:55 -0400
commit9cc984e4bc089cd21b715b92ffe2d2bda0bb1d1a (patch)
treee653d8f15b91321604a5f3052bfb568d7aa4b6b0
parentb5b131c7473e17275debcdf1c226f452dc3876ed (diff)
parent0df6e32b0e36710fe989095241833e09dac3e41d (diff)
Merge tag 'for-v4.6' of git://git.kernel.org/pub/scm/linux/kernel/git/sre/linux-power-supply
Pull power supply and reset changes from Sebastian Reichel: - add types for USB Type C and PD chargers - add act8945a charger driver - add ACPI/DT bindings for goldfish-battery - add support for versatile reset controller - misc fixes * tag 'for-v4.6' of git://git.kernel.org/pub/scm/linux/kernel/git/sre/linux-power-supply: (24 commits) power: pm2301-charger: use __maybe_unused to hide pm functions power: ipaq-micro-battery: use __maybe_unused to hide pm functions power_supply: 88pm860x_charger: do not pass NULL to power_supply_put jz4740-battery: Correct voltage change check power_supply: lp8788-charger: initialize boolean 'found' goldfish: Enable ACPI-based enumeration for goldfish battery power: goldfish_battery: add devicetree bindings power: act8945a: add charger driver for ACT8945A power: add documentation for ACT8945A's charger DT bindings ARM: dts: n900: Rename isp1704 to isp1707 to match correct name power_supply: bq27xxx_battery: Add of modalias and match table when CONFIG_OF is enabled power_supply: bq2415x_charger: Add of modalias and match table when CONFIG_OF is enabled power_supply: bq2415x_charger: Do not add acpi modalias when CONFIG_ACPI is not enabled power_supply: isp1704_charger: Add compatible of match for nxp,isp1707 power_supply: isp1704_charger: Error messages when probe fail power_supply: Add types for USB Type C and PD chargers power: bq24735-charger: add 'ti,external-control' option power: bq24735-charger: document 'ti,external-control' option power: bq24735-charger: fix failed i2c with ac-detect power: reset: Fix dependencies for !HAS_IOMEM archs ...
-rw-r--r--Documentation/devicetree/bindings/goldfish/battery.txt17
-rw-r--r--Documentation/devicetree/bindings/power/act8945a-charger.txt35
-rw-r--r--Documentation/devicetree/bindings/power_supply/ti,bq24735.txt3
-rw-r--r--arch/arm/boot/dts/omap3-n900.dts6
-rw-r--r--drivers/power/88pm860x_charger.c2
-rw-r--r--drivers/power/Kconfig7
-rw-r--r--drivers/power/Makefile1
-rw-r--r--drivers/power/act8945a_charger.c359
-rw-r--r--drivers/power/bq2415x_charger.c22
-rw-r--r--drivers/power/bq24735-charger.c146
-rw-r--r--drivers/power/bq27xxx_battery.c12
-rw-r--r--drivers/power/bq27xxx_battery_i2c.c24
-rw-r--r--drivers/power/collie_battery.c3
-rw-r--r--drivers/power/goldfish_battery.c17
-rw-r--r--drivers/power/ipaq_micro_battery.c4
-rw-r--r--drivers/power/isp1704_charger.c19
-rw-r--r--drivers/power/jz4740-battery.c2
-rw-r--r--drivers/power/lp8788-charger.c2
-rw-r--r--drivers/power/pm2301_charger.c22
-rw-r--r--drivers/power/power_supply_sysfs.c3
-rw-r--r--drivers/power/reset/Kconfig2
-rw-r--r--drivers/power/reset/arm-versatile-reboot.c39
-rw-r--r--include/linux/power/bq24735-charger.h2
-rw-r--r--include/linux/power_supply.h3
24 files changed, 687 insertions, 65 deletions
diff --git a/Documentation/devicetree/bindings/goldfish/battery.txt b/Documentation/devicetree/bindings/goldfish/battery.txt
new file mode 100644
index 000000000000..4fb613933214
--- /dev/null
+++ b/Documentation/devicetree/bindings/goldfish/battery.txt
@@ -0,0 +1,17 @@
1Android Goldfish Battery
2
3Android goldfish battery device generated by android emulator.
4
5Required properties:
6
7- compatible : should contain "google,goldfish-battery" to match emulator
8- reg : <registers mapping>
9- interrupts : <interrupt mapping>
10
11Example:
12
13 goldfish_battery@9020000 {
14 compatible = "google,goldfish-battery";
15 reg = <0x9020000 0x1000>;
16 interrupts = <0x3>;
17 };
diff --git a/Documentation/devicetree/bindings/power/act8945a-charger.txt b/Documentation/devicetree/bindings/power/act8945a-charger.txt
new file mode 100644
index 000000000000..bea254c9d136
--- /dev/null
+++ b/Documentation/devicetree/bindings/power/act8945a-charger.txt
@@ -0,0 +1,35 @@
1Device-Tree bindings for charger of Active-semi ACT8945A Multi-Function Device
2
3Required properties:
4 - compatible: "active-semi,act8945a", please refer to ../mfd/act8945a.txt.
5 - active-semi,chglev-gpios: charge current level phandle with args
6 as described in ../gpio/gpio.txt.
7
8Optional properties:
9 - active-semi,check-battery-temperature: boolean to check the battery
10 temperature or not.
11 - active-semi,input-voltage-threshold-microvolt: unit: mV;
12 Specifies the charger's input over-voltage threshold value;
13 The value can be: 6600, 7000, 7500, 8000; default: 6600
14 - active-semi,precondition-timeout: unit: minutes;
15 Specifies the charger's PRECONDITION safety timer setting value;
16 The value can be: 40, 60, 80, 0; If 0, it means to disable this timer;
17 default: 40.
18 - active-semi,total-timeout: unit: hours;
19 Specifies the charger's total safety timer setting value;
20 The value can be: 3, 4, 5, 0; If 0, it means to disable this timer;
21 default: 3.
22
23Example:
24 pmic@5b {
25 compatible = "active-semi,act8945a";
26 reg = <0x5b>;
27 status = "okay";
28
29 pinctrl-names = "default";
30 pinctrl-0 = <&pinctrl_charger_chglev>;
31 active-semi,chglev-gpios = <&pioA 12 GPIO_ACTIVE_HIGH>;
32 active-semi,input-voltage-threshold-microvolt = <6600>;
33 active-semi,precondition-timeout = <40>;
34 active-semi,total-timeout = <3>;
35 };
diff --git a/Documentation/devicetree/bindings/power_supply/ti,bq24735.txt b/Documentation/devicetree/bindings/power_supply/ti,bq24735.txt
index 4f6a550184d0..3bf55757ceec 100644
--- a/Documentation/devicetree/bindings/power_supply/ti,bq24735.txt
+++ b/Documentation/devicetree/bindings/power_supply/ti,bq24735.txt
@@ -22,6 +22,9 @@ Optional properties :
22 value must be between 128mA and 8.064A with a 128mA step resolution. The 22 value must be between 128mA and 8.064A with a 128mA step resolution. The
23 POR value is 0x1000h. This number is in mA (e.g. 8064), see the spec for 23 POR value is 0x1000h. This number is in mA (e.g. 8064), see the spec for
24 more information about the InputCurrent (0x3fh) register. 24 more information about the InputCurrent (0x3fh) register.
25 - ti,external-control : Indicates that the charger is configured externally
26 and that the host should not attempt to enable/disable charging or set the
27 charge voltage/current.
25 28
26Example: 29Example:
27 30
diff --git a/arch/arm/boot/dts/omap3-n900.dts b/arch/arm/boot/dts/omap3-n900.dts
index 74d8f7eb5563..e3bdcf819643 100644
--- a/arch/arm/boot/dts/omap3-n900.dts
+++ b/arch/arm/boot/dts/omap3-n900.dts
@@ -107,8 +107,8 @@
107 }; 107 };
108 }; 108 };
109 109
110 isp1704: isp1704 { 110 isp1707: isp1707 {
111 compatible = "nxp,isp1704"; 111 compatible = "nxp,isp1707";
112 nxp,enable-gpio = <&gpio3 3 GPIO_ACTIVE_HIGH>; 112 nxp,enable-gpio = <&gpio3 3 GPIO_ACTIVE_HIGH>;
113 usb-phy = <&usb2_phy>; 113 usb-phy = <&usb2_phy>;
114 }; 114 };
@@ -618,7 +618,7 @@
618 ti,termination-current = <100>; 618 ti,termination-current = <100>;
619 ti,resistor-sense = <68>; 619 ti,resistor-sense = <68>;
620 620
621 ti,usb-charger-detection = <&isp1704>; 621 ti,usb-charger-detection = <&isp1707>;
622 }; 622 };
623}; 623};
624 624
diff --git a/drivers/power/88pm860x_charger.c b/drivers/power/88pm860x_charger.c
index 297e72dc70e6..2b82e44d9027 100644
--- a/drivers/power/88pm860x_charger.c
+++ b/drivers/power/88pm860x_charger.c
@@ -435,7 +435,7 @@ static irqreturn_t pm860x_temp_handler(int irq, void *data)
435 435
436 psy = power_supply_get_by_name(pm860x_supplied_to[0]); 436 psy = power_supply_get_by_name(pm860x_supplied_to[0]);
437 if (!psy) 437 if (!psy)
438 goto out; 438 return IRQ_HANDLED;
439 ret = power_supply_get_property(psy, POWER_SUPPLY_PROP_TEMP, &temp); 439 ret = power_supply_get_property(psy, POWER_SUPPLY_PROP_TEMP, &temp);
440 if (ret) 440 if (ret)
441 goto out; 441 goto out;
diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig
index 1ddd13cc0c07..421770ddafa3 100644
--- a/drivers/power/Kconfig
+++ b/drivers/power/Kconfig
@@ -75,6 +75,13 @@ config BATTERY_88PM860X
75 help 75 help
76 Say Y here to enable battery monitor for Marvell 88PM860x chip. 76 Say Y here to enable battery monitor for Marvell 88PM860x chip.
77 77
78config BATTERY_ACT8945A
79 tristate "Active-semi ACT8945A charger driver"
80 depends on MFD_ACT8945A || COMPILE_TEST
81 help
82 Say Y here to enable support for power supply provided by
83 Active-semi ActivePath ACT8945A charger.
84
78config BATTERY_DS2760 85config BATTERY_DS2760
79 tristate "DS2760 battery driver (HP iPAQ & others)" 86 tristate "DS2760 battery driver (HP iPAQ & others)"
80 depends on W1 && W1_SLAVE_DS2760 87 depends on W1 && W1_SLAVE_DS2760
diff --git a/drivers/power/Makefile b/drivers/power/Makefile
index 0e4eab55f8d7..e46b75d448a5 100644
--- a/drivers/power/Makefile
+++ b/drivers/power/Makefile
@@ -17,6 +17,7 @@ obj-$(CONFIG_WM8350_POWER) += wm8350_power.o
17obj-$(CONFIG_TEST_POWER) += test_power.o 17obj-$(CONFIG_TEST_POWER) += test_power.o
18 18
19obj-$(CONFIG_BATTERY_88PM860X) += 88pm860x_battery.o 19obj-$(CONFIG_BATTERY_88PM860X) += 88pm860x_battery.o
20obj-$(CONFIG_BATTERY_ACT8945A) += act8945a_charger.o
20obj-$(CONFIG_BATTERY_DS2760) += ds2760_battery.o 21obj-$(CONFIG_BATTERY_DS2760) += ds2760_battery.o
21obj-$(CONFIG_BATTERY_DS2780) += ds2780_battery.o 22obj-$(CONFIG_BATTERY_DS2780) += ds2780_battery.o
22obj-$(CONFIG_BATTERY_DS2781) += ds2781_battery.o 23obj-$(CONFIG_BATTERY_DS2781) += ds2781_battery.o
diff --git a/drivers/power/act8945a_charger.c b/drivers/power/act8945a_charger.c
new file mode 100644
index 000000000000..b5c00e45741e
--- /dev/null
+++ b/drivers/power/act8945a_charger.c
@@ -0,0 +1,359 @@
1/*
2 * Power supply driver for the Active-semi ACT8945A PMIC
3 *
4 * Copyright (C) 2015 Atmel Corporation
5 *
6 * Author: Wenyou Yang <wenyou.yang@atmel.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 */
13#include <linux/module.h>
14#include <linux/of.h>
15#include <linux/of_gpio.h>
16#include <linux/platform_device.h>
17#include <linux/power_supply.h>
18#include <linux/regmap.h>
19
20static const char *act8945a_charger_model = "ACT8945A";
21static const char *act8945a_charger_manufacturer = "Active-semi";
22
23/**
24 * ACT8945A Charger Register Map
25 */
26
27/* 0x70: Reserved */
28#define ACT8945A_APCH_CFG 0x71
29#define ACT8945A_APCH_STATUS 0x78
30#define ACT8945A_APCH_CTRL 0x79
31#define ACT8945A_APCH_STATE 0x7A
32
33/* ACT8945A_APCH_CFG */
34#define APCH_CFG_OVPSET (0x3 << 0)
35#define APCH_CFG_OVPSET_6V6 (0x0 << 0)
36#define APCH_CFG_OVPSET_7V (0x1 << 0)
37#define APCH_CFG_OVPSET_7V5 (0x2 << 0)
38#define APCH_CFG_OVPSET_8V (0x3 << 0)
39#define APCH_CFG_PRETIMO (0x3 << 2)
40#define APCH_CFG_PRETIMO_40_MIN (0x0 << 2)
41#define APCH_CFG_PRETIMO_60_MIN (0x1 << 2)
42#define APCH_CFG_PRETIMO_80_MIN (0x2 << 2)
43#define APCH_CFG_PRETIMO_DISABLED (0x3 << 2)
44#define APCH_CFG_TOTTIMO (0x3 << 4)
45#define APCH_CFG_TOTTIMO_3_HOUR (0x0 << 4)
46#define APCH_CFG_TOTTIMO_4_HOUR (0x1 << 4)
47#define APCH_CFG_TOTTIMO_5_HOUR (0x2 << 4)
48#define APCH_CFG_TOTTIMO_DISABLED (0x3 << 4)
49#define APCH_CFG_SUSCHG (0x1 << 7)
50
51#define APCH_STATUS_CHGDAT BIT(0)
52#define APCH_STATUS_INDAT BIT(1)
53#define APCH_STATUS_TEMPDAT BIT(2)
54#define APCH_STATUS_TIMRDAT BIT(3)
55#define APCH_STATUS_CHGSTAT BIT(4)
56#define APCH_STATUS_INSTAT BIT(5)
57#define APCH_STATUS_TEMPSTAT BIT(6)
58#define APCH_STATUS_TIMRSTAT BIT(7)
59
60#define APCH_CTRL_CHGEOCOUT BIT(0)
61#define APCH_CTRL_INDIS BIT(1)
62#define APCH_CTRL_TEMPOUT BIT(2)
63#define APCH_CTRL_TIMRPRE BIT(3)
64#define APCH_CTRL_CHGEOCIN BIT(4)
65#define APCH_CTRL_INCON BIT(5)
66#define APCH_CTRL_TEMPIN BIT(6)
67#define APCH_CTRL_TIMRTOT BIT(7)
68
69#define APCH_STATE_ACINSTAT (0x1 << 1)
70#define APCH_STATE_CSTATE (0x3 << 4)
71#define APCH_STATE_CSTATE_SHIFT 4
72#define APCH_STATE_CSTATE_DISABLED 0x00
73#define APCH_STATE_CSTATE_EOC 0x01
74#define APCH_STATE_CSTATE_FAST 0x02
75#define APCH_STATE_CSTATE_PRE 0x03
76
77struct act8945a_charger {
78 struct regmap *regmap;
79 bool battery_temperature;
80};
81
82static int act8945a_get_charger_state(struct regmap *regmap, int *val)
83{
84 int ret;
85 unsigned int status, state;
86
87 ret = regmap_read(regmap, ACT8945A_APCH_STATUS, &status);
88 if (ret < 0)
89 return ret;
90
91 ret = regmap_read(regmap, ACT8945A_APCH_STATE, &state);
92 if (ret < 0)
93 return ret;
94
95 state &= APCH_STATE_CSTATE;
96 state >>= APCH_STATE_CSTATE_SHIFT;
97
98 if (state == APCH_STATE_CSTATE_EOC) {
99 if (status & APCH_STATUS_CHGDAT)
100 *val = POWER_SUPPLY_STATUS_FULL;
101 else
102 *val = POWER_SUPPLY_STATUS_NOT_CHARGING;
103 } else if ((state == APCH_STATE_CSTATE_FAST) ||
104 (state == APCH_STATE_CSTATE_PRE)) {
105 *val = POWER_SUPPLY_STATUS_CHARGING;
106 } else {
107 *val = POWER_SUPPLY_STATUS_NOT_CHARGING;
108 }
109
110 return 0;
111}
112
113static int act8945a_get_charge_type(struct regmap *regmap, int *val)
114{
115 int ret;
116 unsigned int state;
117
118 ret = regmap_read(regmap, ACT8945A_APCH_STATE, &state);
119 if (ret < 0)
120 return ret;
121
122 state &= APCH_STATE_CSTATE;
123 state >>= APCH_STATE_CSTATE_SHIFT;
124
125 switch (state) {
126 case APCH_STATE_CSTATE_PRE:
127 *val = POWER_SUPPLY_CHARGE_TYPE_TRICKLE;
128 break;
129 case APCH_STATE_CSTATE_FAST:
130 *val = POWER_SUPPLY_CHARGE_TYPE_FAST;
131 break;
132 case APCH_STATE_CSTATE_EOC:
133 case APCH_STATE_CSTATE_DISABLED:
134 default:
135 *val = POWER_SUPPLY_CHARGE_TYPE_NONE;
136 }
137
138 return 0;
139}
140
141static int act8945a_get_battery_health(struct act8945a_charger *charger,
142 struct regmap *regmap, int *val)
143{
144 int ret;
145 unsigned int status;
146
147 ret = regmap_read(regmap, ACT8945A_APCH_STATUS, &status);
148 if (ret < 0)
149 return ret;
150
151 if (charger->battery_temperature && !(status & APCH_STATUS_TEMPDAT))
152 *val = POWER_SUPPLY_HEALTH_OVERHEAT;
153 else if (!(status & APCH_STATUS_INDAT))
154 *val = POWER_SUPPLY_HEALTH_OVERVOLTAGE;
155 else if (status & APCH_STATUS_TIMRDAT)
156 *val = POWER_SUPPLY_HEALTH_SAFETY_TIMER_EXPIRE;
157 else
158 *val = POWER_SUPPLY_HEALTH_GOOD;
159
160 return 0;
161}
162
163static enum power_supply_property act8945a_charger_props[] = {
164 POWER_SUPPLY_PROP_STATUS,
165 POWER_SUPPLY_PROP_CHARGE_TYPE,
166 POWER_SUPPLY_PROP_TECHNOLOGY,
167 POWER_SUPPLY_PROP_HEALTH,
168 POWER_SUPPLY_PROP_MODEL_NAME,
169 POWER_SUPPLY_PROP_MANUFACTURER
170};
171
172static int act8945a_charger_get_property(struct power_supply *psy,
173 enum power_supply_property prop,
174 union power_supply_propval *val)
175{
176 struct act8945a_charger *charger = power_supply_get_drvdata(psy);
177 struct regmap *regmap = charger->regmap;
178 int ret = 0;
179
180 switch (prop) {
181 case POWER_SUPPLY_PROP_STATUS:
182 ret = act8945a_get_charger_state(regmap, &val->intval);
183 break;
184 case POWER_SUPPLY_PROP_CHARGE_TYPE:
185 ret = act8945a_get_charge_type(regmap, &val->intval);
186 break;
187 case POWER_SUPPLY_PROP_TECHNOLOGY:
188 val->intval = POWER_SUPPLY_TECHNOLOGY_LION;
189 break;
190 case POWER_SUPPLY_PROP_HEALTH:
191 ret = act8945a_get_battery_health(charger,
192 regmap, &val->intval);
193 break;
194 case POWER_SUPPLY_PROP_MODEL_NAME:
195 val->strval = act8945a_charger_model;
196 break;
197 case POWER_SUPPLY_PROP_MANUFACTURER:
198 val->strval = act8945a_charger_manufacturer;
199 break;
200 default:
201 return -EINVAL;
202 }
203
204 return ret;
205}
206
207static const struct power_supply_desc act8945a_charger_desc = {
208 .name = "act8945a-charger",
209 .type = POWER_SUPPLY_TYPE_BATTERY,
210 .get_property = act8945a_charger_get_property,
211 .properties = act8945a_charger_props,
212 .num_properties = ARRAY_SIZE(act8945a_charger_props),
213};
214
215#define DEFAULT_TOTAL_TIME_OUT 3
216#define DEFAULT_PRE_TIME_OUT 40
217#define DEFAULT_INPUT_OVP_THRESHOLD 6600
218
219static int act8945a_charger_config(struct device *dev,
220 struct act8945a_charger *charger)
221{
222 struct device_node *np = dev->of_node;
223 enum of_gpio_flags flags;
224 struct regmap *regmap = charger->regmap;
225
226 u32 total_time_out;
227 u32 pre_time_out;
228 u32 input_voltage_threshold;
229 int chglev_pin;
230
231 unsigned int value = 0;
232
233 if (!np) {
234 dev_err(dev, "no charger of node\n");
235 return -EINVAL;
236 }
237
238 charger->battery_temperature = of_property_read_bool(np,
239 "active-semi,check-battery-temperature");
240
241 chglev_pin = of_get_named_gpio_flags(np,
242 "active-semi,chglev-gpios", 0, &flags);
243
244 if (gpio_is_valid(chglev_pin)) {
245 gpio_set_value(chglev_pin,
246 ((flags == OF_GPIO_ACTIVE_LOW) ? 0 : 1));
247 }
248
249 if (of_property_read_u32(np,
250 "active-semi,input-voltage-threshold-microvolt",
251 &input_voltage_threshold))
252 input_voltage_threshold = DEFAULT_INPUT_OVP_THRESHOLD;
253
254 if (of_property_read_u32(np,
255 "active-semi,precondition-timeout",
256 &pre_time_out))
257 pre_time_out = DEFAULT_PRE_TIME_OUT;
258
259 if (of_property_read_u32(np, "active-semi,total-timeout",
260 &total_time_out))
261 total_time_out = DEFAULT_TOTAL_TIME_OUT;
262
263 switch (input_voltage_threshold) {
264 case 8000:
265 value |= APCH_CFG_OVPSET_8V;
266 break;
267 case 7500:
268 value |= APCH_CFG_OVPSET_7V5;
269 break;
270 case 7000:
271 value |= APCH_CFG_OVPSET_7V;
272 break;
273 case 6600:
274 default:
275 value |= APCH_CFG_OVPSET_6V6;
276 break;
277 }
278
279 switch (pre_time_out) {
280 case 60:
281 value |= APCH_CFG_PRETIMO_60_MIN;
282 break;
283 case 80:
284 value |= APCH_CFG_PRETIMO_80_MIN;
285 break;
286 case 0:
287 value |= APCH_CFG_PRETIMO_DISABLED;
288 break;
289 case 40:
290 default:
291 value |= APCH_CFG_PRETIMO_40_MIN;
292 break;
293 }
294
295 switch (total_time_out) {
296 case 4:
297 value |= APCH_CFG_TOTTIMO_4_HOUR;
298 break;
299 case 5:
300 value |= APCH_CFG_TOTTIMO_5_HOUR;
301 break;
302 case 0:
303 value |= APCH_CFG_TOTTIMO_DISABLED;
304 break;
305 case 3:
306 default:
307 value |= APCH_CFG_TOTTIMO_3_HOUR;
308 break;
309 }
310
311 return regmap_write(regmap, ACT8945A_APCH_CFG, value);
312}
313
314static int act8945a_charger_probe(struct platform_device *pdev)
315{
316 struct act8945a_charger *charger;
317 struct power_supply *psy;
318 struct power_supply_config psy_cfg = {};
319 int ret;
320
321 charger = devm_kzalloc(&pdev->dev, sizeof(*charger), GFP_KERNEL);
322 if (!charger)
323 return -ENOMEM;
324
325 charger->regmap = dev_get_regmap(pdev->dev.parent, NULL);
326 if (!charger->regmap) {
327 dev_err(&pdev->dev, "Parent did not provide regmap\n");
328 return -EINVAL;
329 }
330
331 ret = act8945a_charger_config(pdev->dev.parent, charger);
332 if (ret)
333 return ret;
334
335 psy_cfg.of_node = pdev->dev.parent->of_node;
336 psy_cfg.drv_data = charger;
337
338 psy = devm_power_supply_register(&pdev->dev,
339 &act8945a_charger_desc,
340 &psy_cfg);
341 if (IS_ERR(psy)) {
342 dev_err(&pdev->dev, "failed to register power supply\n");
343 return PTR_ERR(psy);
344 }
345
346 return 0;
347}
348
349static struct platform_driver act8945a_charger_driver = {
350 .driver = {
351 .name = "act8945a-charger",
352 },
353 .probe = act8945a_charger_probe,
354};
355module_platform_driver(act8945a_charger_driver);
356
357MODULE_DESCRIPTION("Active-semi ACT8945A ActivePath charger driver");
358MODULE_AUTHOR("Wenyou Yang <wenyou.yang@atmel.com>");
359MODULE_LICENSE("GPL");
diff --git a/drivers/power/bq2415x_charger.c b/drivers/power/bq2415x_charger.c
index 27e89536689a..73e2f0b79dd4 100644
--- a/drivers/power/bq2415x_charger.c
+++ b/drivers/power/bq2415x_charger.c
@@ -1759,6 +1759,7 @@ static const struct i2c_device_id bq2415x_i2c_id_table[] = {
1759}; 1759};
1760MODULE_DEVICE_TABLE(i2c, bq2415x_i2c_id_table); 1760MODULE_DEVICE_TABLE(i2c, bq2415x_i2c_id_table);
1761 1761
1762#ifdef CONFIG_ACPI
1762static const struct acpi_device_id bq2415x_i2c_acpi_match[] = { 1763static const struct acpi_device_id bq2415x_i2c_acpi_match[] = {
1763 { "BQ2415X", BQUNKNOWN }, 1764 { "BQ2415X", BQUNKNOWN },
1764 { "BQ241500", BQ24150 }, 1765 { "BQ241500", BQ24150 },
@@ -1776,10 +1777,31 @@ static const struct acpi_device_id bq2415x_i2c_acpi_match[] = {
1776 {}, 1777 {},
1777}; 1778};
1778MODULE_DEVICE_TABLE(acpi, bq2415x_i2c_acpi_match); 1779MODULE_DEVICE_TABLE(acpi, bq2415x_i2c_acpi_match);
1780#endif
1781
1782#ifdef CONFIG_OF
1783static const struct of_device_id bq2415x_of_match_table[] = {
1784 { .compatible = "ti,bq24150" },
1785 { .compatible = "ti,bq24150a" },
1786 { .compatible = "ti,bq24151" },
1787 { .compatible = "ti,bq24151a" },
1788 { .compatible = "ti,bq24152" },
1789 { .compatible = "ti,bq24153" },
1790 { .compatible = "ti,bq24153a" },
1791 { .compatible = "ti,bq24155" },
1792 { .compatible = "ti,bq24156" },
1793 { .compatible = "ti,bq24156a" },
1794 { .compatible = "ti,bq24157s" },
1795 { .compatible = "ti,bq24158" },
1796 {},
1797};
1798MODULE_DEVICE_TABLE(of, bq2415x_of_match_table);
1799#endif
1779 1800
1780static struct i2c_driver bq2415x_driver = { 1801static struct i2c_driver bq2415x_driver = {
1781 .driver = { 1802 .driver = {
1782 .name = "bq2415x-charger", 1803 .name = "bq2415x-charger",
1804 .of_match_table = of_match_ptr(bq2415x_of_match_table),
1783 .acpi_match_table = ACPI_PTR(bq2415x_i2c_acpi_match), 1805 .acpi_match_table = ACPI_PTR(bq2415x_i2c_acpi_match),
1784 }, 1806 },
1785 .probe = bq2415x_probe, 1807 .probe = bq2415x_probe,
diff --git a/drivers/power/bq24735-charger.c b/drivers/power/bq24735-charger.c
index eb2b3689de97..fa454c19ce17 100644
--- a/drivers/power/bq24735-charger.c
+++ b/drivers/power/bq24735-charger.c
@@ -48,6 +48,8 @@ struct bq24735 {
48 struct power_supply_desc charger_desc; 48 struct power_supply_desc charger_desc;
49 struct i2c_client *client; 49 struct i2c_client *client;
50 struct bq24735_platform *pdata; 50 struct bq24735_platform *pdata;
51 struct mutex lock;
52 bool charging;
51}; 53};
52 54
53static inline struct bq24735 *to_bq24735(struct power_supply *psy) 55static inline struct bq24735 *to_bq24735(struct power_supply *psy)
@@ -56,9 +58,23 @@ static inline struct bq24735 *to_bq24735(struct power_supply *psy)
56} 58}
57 59
58static enum power_supply_property bq24735_charger_properties[] = { 60static enum power_supply_property bq24735_charger_properties[] = {
61 POWER_SUPPLY_PROP_STATUS,
59 POWER_SUPPLY_PROP_ONLINE, 62 POWER_SUPPLY_PROP_ONLINE,
60}; 63};
61 64
65static int bq24735_charger_property_is_writeable(struct power_supply *psy,
66 enum power_supply_property psp)
67{
68 switch (psp) {
69 case POWER_SUPPLY_PROP_STATUS:
70 return 1;
71 default:
72 break;
73 }
74
75 return 0;
76}
77
62static inline int bq24735_write_word(struct i2c_client *client, u8 reg, 78static inline int bq24735_write_word(struct i2c_client *client, u8 reg,
63 u16 value) 79 u16 value)
64{ 80{
@@ -90,6 +106,9 @@ static int bq24735_update_word(struct i2c_client *client, u8 reg,
90 106
91static inline int bq24735_enable_charging(struct bq24735 *charger) 107static inline int bq24735_enable_charging(struct bq24735 *charger)
92{ 108{
109 if (charger->pdata->ext_control)
110 return 0;
111
93 return bq24735_update_word(charger->client, BQ24735_CHG_OPT, 112 return bq24735_update_word(charger->client, BQ24735_CHG_OPT,
94 BQ24735_CHG_OPT_CHARGE_DISABLE, 113 BQ24735_CHG_OPT_CHARGE_DISABLE,
95 ~BQ24735_CHG_OPT_CHARGE_DISABLE); 114 ~BQ24735_CHG_OPT_CHARGE_DISABLE);
@@ -97,6 +116,9 @@ static inline int bq24735_enable_charging(struct bq24735 *charger)
97 116
98static inline int bq24735_disable_charging(struct bq24735 *charger) 117static inline int bq24735_disable_charging(struct bq24735 *charger)
99{ 118{
119 if (charger->pdata->ext_control)
120 return 0;
121
100 return bq24735_update_word(charger->client, BQ24735_CHG_OPT, 122 return bq24735_update_word(charger->client, BQ24735_CHG_OPT,
101 BQ24735_CHG_OPT_CHARGE_DISABLE, 123 BQ24735_CHG_OPT_CHARGE_DISABLE,
102 BQ24735_CHG_OPT_CHARGE_DISABLE); 124 BQ24735_CHG_OPT_CHARGE_DISABLE);
@@ -108,6 +130,9 @@ static int bq24735_config_charger(struct bq24735 *charger)
108 int ret; 130 int ret;
109 u16 value; 131 u16 value;
110 132
133 if (pdata->ext_control)
134 return 0;
135
111 if (pdata->charge_current) { 136 if (pdata->charge_current) {
112 value = pdata->charge_current & BQ24735_CHARGE_CURRENT_MASK; 137 value = pdata->charge_current & BQ24735_CHARGE_CURRENT_MASK;
113 138
@@ -174,16 +199,30 @@ static bool bq24735_charger_is_present(struct bq24735 *charger)
174 return false; 199 return false;
175} 200}
176 201
202static int bq24735_charger_is_charging(struct bq24735 *charger)
203{
204 int ret = bq24735_read_word(charger->client, BQ24735_CHG_OPT);
205
206 if (ret < 0)
207 return ret;
208
209 return !(ret & BQ24735_CHG_OPT_CHARGE_DISABLE);
210}
211
177static irqreturn_t bq24735_charger_isr(int irq, void *devid) 212static irqreturn_t bq24735_charger_isr(int irq, void *devid)
178{ 213{
179 struct power_supply *psy = devid; 214 struct power_supply *psy = devid;
180 struct bq24735 *charger = to_bq24735(psy); 215 struct bq24735 *charger = to_bq24735(psy);
181 216
182 if (bq24735_charger_is_present(charger)) 217 mutex_lock(&charger->lock);
218
219 if (charger->charging && bq24735_charger_is_present(charger))
183 bq24735_enable_charging(charger); 220 bq24735_enable_charging(charger);
184 else 221 else
185 bq24735_disable_charging(charger); 222 bq24735_disable_charging(charger);
186 223
224 mutex_unlock(&charger->lock);
225
187 power_supply_changed(psy); 226 power_supply_changed(psy);
188 227
189 return IRQ_HANDLED; 228 return IRQ_HANDLED;
@@ -199,6 +238,19 @@ static int bq24735_charger_get_property(struct power_supply *psy,
199 case POWER_SUPPLY_PROP_ONLINE: 238 case POWER_SUPPLY_PROP_ONLINE:
200 val->intval = bq24735_charger_is_present(charger) ? 1 : 0; 239 val->intval = bq24735_charger_is_present(charger) ? 1 : 0;
201 break; 240 break;
241 case POWER_SUPPLY_PROP_STATUS:
242 switch (bq24735_charger_is_charging(charger)) {
243 case 1:
244 val->intval = POWER_SUPPLY_STATUS_CHARGING;
245 break;
246 case 0:
247 val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING;
248 break;
249 default:
250 val->intval = POWER_SUPPLY_STATUS_UNKNOWN;
251 break;
252 }
253 break;
202 default: 254 default:
203 return -EINVAL; 255 return -EINVAL;
204 } 256 }
@@ -206,6 +258,46 @@ static int bq24735_charger_get_property(struct power_supply *psy,
206 return 0; 258 return 0;
207} 259}
208 260
261static int bq24735_charger_set_property(struct power_supply *psy,
262 enum power_supply_property psp,
263 const union power_supply_propval *val)
264{
265 struct bq24735 *charger = to_bq24735(psy);
266 int ret;
267
268 switch (psp) {
269 case POWER_SUPPLY_PROP_STATUS:
270 switch (val->intval) {
271 case POWER_SUPPLY_STATUS_CHARGING:
272 mutex_lock(&charger->lock);
273 charger->charging = true;
274 ret = bq24735_enable_charging(charger);
275 mutex_unlock(&charger->lock);
276 if (ret)
277 return ret;
278 bq24735_config_charger(charger);
279 break;
280 case POWER_SUPPLY_STATUS_DISCHARGING:
281 case POWER_SUPPLY_STATUS_NOT_CHARGING:
282 mutex_lock(&charger->lock);
283 charger->charging = false;
284 ret = bq24735_disable_charging(charger);
285 mutex_unlock(&charger->lock);
286 if (ret)
287 return ret;
288 break;
289 default:
290 return -EINVAL;
291 }
292 power_supply_changed(psy);
293 break;
294 default:
295 return -EPERM;
296 }
297
298 return 0;
299}
300
209static struct bq24735_platform *bq24735_parse_dt_data(struct i2c_client *client) 301static struct bq24735_platform *bq24735_parse_dt_data(struct i2c_client *client)
210{ 302{
211 struct bq24735_platform *pdata; 303 struct bq24735_platform *pdata;
@@ -239,6 +331,8 @@ static struct bq24735_platform *bq24735_parse_dt_data(struct i2c_client *client)
239 if (!ret) 331 if (!ret)
240 pdata->input_current = val; 332 pdata->input_current = val;
241 333
334 pdata->ext_control = of_property_read_bool(np, "ti,external-control");
335
242 return pdata; 336 return pdata;
243} 337}
244 338
@@ -255,6 +349,8 @@ static int bq24735_charger_probe(struct i2c_client *client,
255 if (!charger) 349 if (!charger)
256 return -ENOMEM; 350 return -ENOMEM;
257 351
352 mutex_init(&charger->lock);
353 charger->charging = true;
258 charger->pdata = client->dev.platform_data; 354 charger->pdata = client->dev.platform_data;
259 355
260 if (IS_ENABLED(CONFIG_OF) && !charger->pdata && client->dev.of_node) 356 if (IS_ENABLED(CONFIG_OF) && !charger->pdata && client->dev.of_node)
@@ -285,6 +381,9 @@ static int bq24735_charger_probe(struct i2c_client *client,
285 supply_desc->properties = bq24735_charger_properties; 381 supply_desc->properties = bq24735_charger_properties;
286 supply_desc->num_properties = ARRAY_SIZE(bq24735_charger_properties); 382 supply_desc->num_properties = ARRAY_SIZE(bq24735_charger_properties);
287 supply_desc->get_property = bq24735_charger_get_property; 383 supply_desc->get_property = bq24735_charger_get_property;
384 supply_desc->set_property = bq24735_charger_set_property;
385 supply_desc->property_is_writeable =
386 bq24735_charger_property_is_writeable;
288 387
289 psy_cfg.supplied_to = charger->pdata->supplied_to; 388 psy_cfg.supplied_to = charger->pdata->supplied_to;
290 psy_cfg.num_supplicants = charger->pdata->num_supplicants; 389 psy_cfg.num_supplicants = charger->pdata->num_supplicants;
@@ -293,27 +392,6 @@ static int bq24735_charger_probe(struct i2c_client *client,
293 392
294 i2c_set_clientdata(client, charger); 393 i2c_set_clientdata(client, charger);
295 394
296 ret = bq24735_read_word(client, BQ24735_MANUFACTURER_ID);
297 if (ret < 0) {
298 dev_err(&client->dev, "Failed to read manufacturer id : %d\n",
299 ret);
300 return ret;
301 } else if (ret != 0x0040) {
302 dev_err(&client->dev,
303 "manufacturer id mismatch. 0x0040 != 0x%04x\n", ret);
304 return -ENODEV;
305 }
306
307 ret = bq24735_read_word(client, BQ24735_DEVICE_ID);
308 if (ret < 0) {
309 dev_err(&client->dev, "Failed to read device id : %d\n", ret);
310 return ret;
311 } else if (ret != 0x000B) {
312 dev_err(&client->dev,
313 "device id mismatch. 0x000b != 0x%04x\n", ret);
314 return -ENODEV;
315 }
316
317 if (gpio_is_valid(charger->pdata->status_gpio)) { 395 if (gpio_is_valid(charger->pdata->status_gpio)) {
318 ret = devm_gpio_request(&client->dev, 396 ret = devm_gpio_request(&client->dev,
319 charger->pdata->status_gpio, 397 charger->pdata->status_gpio,
@@ -327,6 +405,30 @@ static int bq24735_charger_probe(struct i2c_client *client,
327 charger->pdata->status_gpio_valid = !ret; 405 charger->pdata->status_gpio_valid = !ret;
328 } 406 }
329 407
408 if (!charger->pdata->status_gpio_valid
409 || bq24735_charger_is_present(charger)) {
410 ret = bq24735_read_word(client, BQ24735_MANUFACTURER_ID);
411 if (ret < 0) {
412 dev_err(&client->dev, "Failed to read manufacturer id : %d\n",
413 ret);
414 return ret;
415 } else if (ret != 0x0040) {
416 dev_err(&client->dev,
417 "manufacturer id mismatch. 0x0040 != 0x%04x\n", ret);
418 return -ENODEV;
419 }
420
421 ret = bq24735_read_word(client, BQ24735_DEVICE_ID);
422 if (ret < 0) {
423 dev_err(&client->dev, "Failed to read device id : %d\n", ret);
424 return ret;
425 } else if (ret != 0x000B) {
426 dev_err(&client->dev,
427 "device id mismatch. 0x000b != 0x%04x\n", ret);
428 return -ENODEV;
429 }
430 }
431
330 ret = bq24735_config_charger(charger); 432 ret = bq24735_config_charger(charger);
331 if (ret < 0) { 433 if (ret < 0) {
332 dev_err(&client->dev, "failed in configuring charger"); 434 dev_err(&client->dev, "failed in configuring charger");
diff --git a/drivers/power/bq27xxx_battery.c b/drivers/power/bq27xxx_battery.c
index 6b027a418943..45f6ebf88df6 100644
--- a/drivers/power/bq27xxx_battery.c
+++ b/drivers/power/bq27xxx_battery.c
@@ -46,6 +46,7 @@
46#include <linux/platform_device.h> 46#include <linux/platform_device.h>
47#include <linux/power_supply.h> 47#include <linux/power_supply.h>
48#include <linux/slab.h> 48#include <linux/slab.h>
49#include <linux/of.h>
49 50
50#include <linux/power/bq27xxx_battery.h> 51#include <linux/power/bq27xxx_battery.h>
51 52
@@ -1090,16 +1091,27 @@ static const struct platform_device_id bq27xxx_battery_platform_id_table[] = {
1090}; 1091};
1091MODULE_DEVICE_TABLE(platform, bq27xxx_battery_platform_id_table); 1092MODULE_DEVICE_TABLE(platform, bq27xxx_battery_platform_id_table);
1092 1093
1094#ifdef CONFIG_OF
1095static const struct of_device_id bq27xxx_battery_platform_of_match_table[] = {
1096 { .compatible = "ti,bq27000" },
1097 {},
1098};
1099MODULE_DEVICE_TABLE(of, bq27xxx_battery_platform_of_match_table);
1100#endif
1101
1093static struct platform_driver bq27xxx_battery_platform_driver = { 1102static struct platform_driver bq27xxx_battery_platform_driver = {
1094 .probe = bq27xxx_battery_platform_probe, 1103 .probe = bq27xxx_battery_platform_probe,
1095 .remove = bq27xxx_battery_platform_remove, 1104 .remove = bq27xxx_battery_platform_remove,
1096 .driver = { 1105 .driver = {
1097 .name = "bq27000-battery", 1106 .name = "bq27000-battery",
1107 .of_match_table = of_match_ptr(bq27xxx_battery_platform_of_match_table),
1098 }, 1108 },
1099 .id_table = bq27xxx_battery_platform_id_table, 1109 .id_table = bq27xxx_battery_platform_id_table,
1100}; 1110};
1101module_platform_driver(bq27xxx_battery_platform_driver); 1111module_platform_driver(bq27xxx_battery_platform_driver);
1102 1112
1113MODULE_ALIAS("platform:bq27000-battery");
1114
1103MODULE_AUTHOR("Rodolfo Giometti <giometti@linux.it>"); 1115MODULE_AUTHOR("Rodolfo Giometti <giometti@linux.it>");
1104MODULE_DESCRIPTION("BQ27xxx battery monitor driver"); 1116MODULE_DESCRIPTION("BQ27xxx battery monitor driver");
1105MODULE_LICENSE("GPL"); 1117MODULE_LICENSE("GPL");
diff --git a/drivers/power/bq27xxx_battery_i2c.c b/drivers/power/bq27xxx_battery_i2c.c
index 8eafc6f0df88..b8f8d3ade31b 100644
--- a/drivers/power/bq27xxx_battery_i2c.c
+++ b/drivers/power/bq27xxx_battery_i2c.c
@@ -166,9 +166,33 @@ static const struct i2c_device_id bq27xxx_i2c_id_table[] = {
166}; 166};
167MODULE_DEVICE_TABLE(i2c, bq27xxx_i2c_id_table); 167MODULE_DEVICE_TABLE(i2c, bq27xxx_i2c_id_table);
168 168
169#ifdef CONFIG_OF
170static const struct of_device_id bq27xxx_battery_i2c_of_match_table[] = {
171 { .compatible = "ti,bq27200" },
172 { .compatible = "ti,bq27210" },
173 { .compatible = "ti,bq27500" },
174 { .compatible = "ti,bq27510" },
175 { .compatible = "ti,bq27520" },
176 { .compatible = "ti,bq27530" },
177 { .compatible = "ti,bq27531" },
178 { .compatible = "ti,bq27541" },
179 { .compatible = "ti,bq27542" },
180 { .compatible = "ti,bq27546" },
181 { .compatible = "ti,bq27742" },
182 { .compatible = "ti,bq27545" },
183 { .compatible = "ti,bq27421" },
184 { .compatible = "ti,bq27425" },
185 { .compatible = "ti,bq27441" },
186 { .compatible = "ti,bq27621" },
187 {},
188};
189MODULE_DEVICE_TABLE(of, bq27xxx_battery_i2c_of_match_table);
190#endif
191
169static struct i2c_driver bq27xxx_battery_i2c_driver = { 192static struct i2c_driver bq27xxx_battery_i2c_driver = {
170 .driver = { 193 .driver = {
171 .name = "bq27xxx-battery", 194 .name = "bq27xxx-battery",
195 .of_match_table = of_match_ptr(bq27xxx_battery_i2c_of_match_table),
172 }, 196 },
173 .probe = bq27xxx_battery_i2c_probe, 197 .probe = bq27xxx_battery_i2c_probe,
174 .remove = bq27xxx_battery_i2c_remove, 198 .remove = bq27xxx_battery_i2c_remove,
diff --git a/drivers/power/collie_battery.c b/drivers/power/collie_battery.c
index 8a971b3dbe58..3a0bc608d4b5 100644
--- a/drivers/power/collie_battery.c
+++ b/drivers/power/collie_battery.c
@@ -26,7 +26,6 @@
26static DEFINE_MUTEX(bat_lock); /* protects gpio pins */ 26static DEFINE_MUTEX(bat_lock); /* protects gpio pins */
27static struct work_struct bat_work; 27static struct work_struct bat_work;
28static struct ucb1x00 *ucb; 28static struct ucb1x00 *ucb;
29static int wakeup_enabled;
30 29
31struct collie_bat { 30struct collie_bat {
32 int status; 31 int status;
@@ -291,6 +290,8 @@ static struct gpio collie_batt_gpios[] = {
291}; 290};
292 291
293#ifdef CONFIG_PM 292#ifdef CONFIG_PM
293static int wakeup_enabled;
294
294static int collie_bat_suspend(struct ucb1x00_dev *dev) 295static int collie_bat_suspend(struct ucb1x00_dev *dev)
295{ 296{
296 /* flush all pending status updates */ 297 /* flush all pending status updates */
diff --git a/drivers/power/goldfish_battery.c b/drivers/power/goldfish_battery.c
index a50bb988c69a..f5c525e4482a 100644
--- a/drivers/power/goldfish_battery.c
+++ b/drivers/power/goldfish_battery.c
@@ -24,6 +24,7 @@
24#include <linux/pci.h> 24#include <linux/pci.h>
25#include <linux/interrupt.h> 25#include <linux/interrupt.h>
26#include <linux/io.h> 26#include <linux/io.h>
27#include <linux/acpi.h>
27 28
28struct goldfish_battery_data { 29struct goldfish_battery_data {
29 void __iomem *reg_base; 30 void __iomem *reg_base;
@@ -227,11 +228,25 @@ static int goldfish_battery_remove(struct platform_device *pdev)
227 return 0; 228 return 0;
228} 229}
229 230
231static const struct of_device_id goldfish_battery_of_match[] = {
232 { .compatible = "google,goldfish-battery", },
233 {},
234};
235MODULE_DEVICE_TABLE(of, goldfish_battery_of_match);
236
237static const struct acpi_device_id goldfish_battery_acpi_match[] = {
238 { "GFSH0001", 0 },
239 { },
240};
241MODULE_DEVICE_TABLE(acpi, goldfish_battery_acpi_match);
242
230static struct platform_driver goldfish_battery_device = { 243static struct platform_driver goldfish_battery_device = {
231 .probe = goldfish_battery_probe, 244 .probe = goldfish_battery_probe,
232 .remove = goldfish_battery_remove, 245 .remove = goldfish_battery_remove,
233 .driver = { 246 .driver = {
234 .name = "goldfish-battery" 247 .name = "goldfish-battery",
248 .of_match_table = goldfish_battery_of_match,
249 .acpi_match_table = ACPI_PTR(goldfish_battery_acpi_match),
235 } 250 }
236}; 251};
237module_platform_driver(goldfish_battery_device); 252module_platform_driver(goldfish_battery_device);
diff --git a/drivers/power/ipaq_micro_battery.c b/drivers/power/ipaq_micro_battery.c
index f03014ea1dc4..3f314b1a30d7 100644
--- a/drivers/power/ipaq_micro_battery.c
+++ b/drivers/power/ipaq_micro_battery.c
@@ -281,7 +281,7 @@ static int micro_batt_remove(struct platform_device *pdev)
281 return 0; 281 return 0;
282} 282}
283 283
284static int micro_batt_suspend(struct device *dev) 284static int __maybe_unused micro_batt_suspend(struct device *dev)
285{ 285{
286 struct micro_battery *mb = dev_get_drvdata(dev); 286 struct micro_battery *mb = dev_get_drvdata(dev);
287 287
@@ -289,7 +289,7 @@ static int micro_batt_suspend(struct device *dev)
289 return 0; 289 return 0;
290} 290}
291 291
292static int micro_batt_resume(struct device *dev) 292static int __maybe_unused micro_batt_resume(struct device *dev)
293{ 293{
294 struct micro_battery *mb = dev_get_drvdata(dev); 294 struct micro_battery *mb = dev_get_drvdata(dev);
295 295
diff --git a/drivers/power/isp1704_charger.c b/drivers/power/isp1704_charger.c
index 46a292aa182d..4cd6899b961e 100644
--- a/drivers/power/isp1704_charger.c
+++ b/drivers/power/isp1704_charger.c
@@ -411,8 +411,10 @@ static int isp1704_charger_probe(struct platform_device *pdev)
411 if (np) { 411 if (np) {
412 int gpio = of_get_named_gpio(np, "nxp,enable-gpio", 0); 412 int gpio = of_get_named_gpio(np, "nxp,enable-gpio", 0);
413 413
414 if (gpio < 0) 414 if (gpio < 0) {
415 dev_err(&pdev->dev, "missing DT GPIO nxp,enable-gpio\n");
415 return gpio; 416 return gpio;
417 }
416 418
417 pdata = devm_kzalloc(&pdev->dev, 419 pdata = devm_kzalloc(&pdev->dev,
418 sizeof(struct isp1704_charger_data), GFP_KERNEL); 420 sizeof(struct isp1704_charger_data), GFP_KERNEL);
@@ -422,8 +424,10 @@ static int isp1704_charger_probe(struct platform_device *pdev)
422 424
423 ret = devm_gpio_request_one(&pdev->dev, pdata->enable_gpio, 425 ret = devm_gpio_request_one(&pdev->dev, pdata->enable_gpio,
424 GPIOF_OUT_INIT_HIGH, "isp1704_reset"); 426 GPIOF_OUT_INIT_HIGH, "isp1704_reset");
425 if (ret) 427 if (ret) {
428 dev_err(&pdev->dev, "gpio request failed\n");
426 goto fail0; 429 goto fail0;
430 }
427 } 431 }
428 432
429 if (!pdata) { 433 if (!pdata) {
@@ -443,6 +447,7 @@ static int isp1704_charger_probe(struct platform_device *pdev)
443 447
444 if (IS_ERR(isp->phy)) { 448 if (IS_ERR(isp->phy)) {
445 ret = PTR_ERR(isp->phy); 449 ret = PTR_ERR(isp->phy);
450 dev_err(&pdev->dev, "usb_get_phy failed\n");
446 goto fail0; 451 goto fail0;
447 } 452 }
448 453
@@ -452,8 +457,10 @@ static int isp1704_charger_probe(struct platform_device *pdev)
452 isp1704_charger_set_power(isp, 1); 457 isp1704_charger_set_power(isp, 1);
453 458
454 ret = isp1704_test_ulpi(isp); 459 ret = isp1704_test_ulpi(isp);
455 if (ret < 0) 460 if (ret < 0) {
461 dev_err(&pdev->dev, "isp1704_test_ulpi failed\n");
456 goto fail1; 462 goto fail1;
463 }
457 464
458 isp->psy_desc.name = "isp1704"; 465 isp->psy_desc.name = "isp1704";
459 isp->psy_desc.type = POWER_SUPPLY_TYPE_USB; 466 isp->psy_desc.type = POWER_SUPPLY_TYPE_USB;
@@ -466,6 +473,7 @@ static int isp1704_charger_probe(struct platform_device *pdev)
466 isp->psy = power_supply_register(isp->dev, &isp->psy_desc, &psy_cfg); 473 isp->psy = power_supply_register(isp->dev, &isp->psy_desc, &psy_cfg);
467 if (IS_ERR(isp->psy)) { 474 if (IS_ERR(isp->psy)) {
468 ret = PTR_ERR(isp->psy); 475 ret = PTR_ERR(isp->psy);
476 dev_err(&pdev->dev, "power_supply_register failed\n");
469 goto fail1; 477 goto fail1;
470 } 478 }
471 479
@@ -478,8 +486,10 @@ static int isp1704_charger_probe(struct platform_device *pdev)
478 isp->nb.notifier_call = isp1704_notifier_call; 486 isp->nb.notifier_call = isp1704_notifier_call;
479 487
480 ret = usb_register_notifier(isp->phy, &isp->nb); 488 ret = usb_register_notifier(isp->phy, &isp->nb);
481 if (ret) 489 if (ret) {
490 dev_err(&pdev->dev, "usb_register_notifier failed\n");
482 goto fail2; 491 goto fail2;
492 }
483 493
484 dev_info(isp->dev, "registered with product id %s\n", isp->model); 494 dev_info(isp->dev, "registered with product id %s\n", isp->model);
485 495
@@ -526,6 +536,7 @@ static int isp1704_charger_remove(struct platform_device *pdev)
526#ifdef CONFIG_OF 536#ifdef CONFIG_OF
527static const struct of_device_id omap_isp1704_of_match[] = { 537static const struct of_device_id omap_isp1704_of_match[] = {
528 { .compatible = "nxp,isp1704", }, 538 { .compatible = "nxp,isp1704", },
539 { .compatible = "nxp,isp1707", },
529 {}, 540 {},
530}; 541};
531MODULE_DEVICE_TABLE(of, omap_isp1704_of_match); 542MODULE_DEVICE_TABLE(of, omap_isp1704_of_match);
diff --git a/drivers/power/jz4740-battery.c b/drivers/power/jz4740-battery.c
index abdfc21ec13f..88f04f4d1a70 100644
--- a/drivers/power/jz4740-battery.c
+++ b/drivers/power/jz4740-battery.c
@@ -208,7 +208,7 @@ static void jz_battery_update(struct jz_battery *jz_battery)
208 } 208 }
209 209
210 voltage = jz_battery_read_voltage(jz_battery); 210 voltage = jz_battery_read_voltage(jz_battery);
211 if (abs(voltage - jz_battery->voltage) < 50000) { 211 if (voltage >= 0 && abs(voltage - jz_battery->voltage) > 50000) {
212 jz_battery->voltage = voltage; 212 jz_battery->voltage = voltage;
213 has_changed = true; 213 has_changed = true;
214 } 214 }
diff --git a/drivers/power/lp8788-charger.c b/drivers/power/lp8788-charger.c
index f5a48fd68b01..7321b727d484 100644
--- a/drivers/power/lp8788-charger.c
+++ b/drivers/power/lp8788-charger.c
@@ -455,7 +455,7 @@ static void lp8788_charger_event(struct work_struct *work)
455 455
456static bool lp8788_find_irq_id(struct lp8788_charger *pchg, int virq, int *id) 456static bool lp8788_find_irq_id(struct lp8788_charger *pchg, int virq, int *id)
457{ 457{
458 bool found; 458 bool found = false;
459 int i; 459 int i;
460 460
461 for (i = 0; i < pchg->num_irqs; i++) { 461 for (i = 0; i < pchg->num_irqs; i++) {
diff --git a/drivers/power/pm2301_charger.c b/drivers/power/pm2301_charger.c
index 8f9bd1d0eeb6..fb62ed3fc38c 100644
--- a/drivers/power/pm2301_charger.c
+++ b/drivers/power/pm2301_charger.c
@@ -911,11 +911,7 @@ static struct pm2xxx_irq pm2xxx_charger_irq[] = {
911 {"PM2XXX_IRQ_INT", pm2xxx_irq_int}, 911 {"PM2XXX_IRQ_INT", pm2xxx_irq_int},
912}; 912};
913 913
914#ifdef CONFIG_PM 914static int __maybe_unused pm2xxx_wall_charger_resume(struct device *dev)
915
916#ifdef CONFIG_PM_SLEEP
917
918static int pm2xxx_wall_charger_resume(struct device *dev)
919{ 915{
920 struct i2c_client *i2c_client = to_i2c_client(dev); 916 struct i2c_client *i2c_client = to_i2c_client(dev);
921 struct pm2xxx_charger *pm2; 917 struct pm2xxx_charger *pm2;
@@ -931,7 +927,7 @@ static int pm2xxx_wall_charger_resume(struct device *dev)
931 return 0; 927 return 0;
932} 928}
933 929
934static int pm2xxx_wall_charger_suspend(struct device *dev) 930static int __maybe_unused pm2xxx_wall_charger_suspend(struct device *dev)
935{ 931{
936 struct i2c_client *i2c_client = to_i2c_client(dev); 932 struct i2c_client *i2c_client = to_i2c_client(dev);
937 struct pm2xxx_charger *pm2; 933 struct pm2xxx_charger *pm2;
@@ -949,9 +945,7 @@ static int pm2xxx_wall_charger_suspend(struct device *dev)
949 return 0; 945 return 0;
950} 946}
951 947
952#endif 948static int __maybe_unused pm2xxx_runtime_suspend(struct device *dev)
953
954static int pm2xxx_runtime_suspend(struct device *dev)
955{ 949{
956 struct i2c_client *pm2xxx_i2c_client = to_i2c_client(dev); 950 struct i2c_client *pm2xxx_i2c_client = to_i2c_client(dev);
957 struct pm2xxx_charger *pm2; 951 struct pm2xxx_charger *pm2;
@@ -962,7 +956,7 @@ static int pm2xxx_runtime_suspend(struct device *dev)
962 return 0; 956 return 0;
963} 957}
964 958
965static int pm2xxx_runtime_resume(struct device *dev) 959static int __maybe_unused pm2xxx_runtime_resume(struct device *dev)
966{ 960{
967 struct i2c_client *pm2xxx_i2c_client = to_i2c_client(dev); 961 struct i2c_client *pm2xxx_i2c_client = to_i2c_client(dev);
968 struct pm2xxx_charger *pm2; 962 struct pm2xxx_charger *pm2;
@@ -975,15 +969,11 @@ static int pm2xxx_runtime_resume(struct device *dev)
975 return 0; 969 return 0;
976} 970}
977 971
978static const struct dev_pm_ops pm2xxx_pm_ops = { 972static const struct dev_pm_ops pm2xxx_pm_ops __maybe_unused = {
979 SET_SYSTEM_SLEEP_PM_OPS(pm2xxx_wall_charger_suspend, 973 SET_SYSTEM_SLEEP_PM_OPS(pm2xxx_wall_charger_suspend,
980 pm2xxx_wall_charger_resume) 974 pm2xxx_wall_charger_resume)
981 SET_RUNTIME_PM_OPS(pm2xxx_runtime_suspend, pm2xxx_runtime_resume, NULL) 975 SET_RUNTIME_PM_OPS(pm2xxx_runtime_suspend, pm2xxx_runtime_resume, NULL)
982}; 976};
983#define PM2XXX_PM_OPS (&pm2xxx_pm_ops)
984#else
985#define PM2XXX_PM_OPS NULL
986#endif
987 977
988static int pm2xxx_wall_charger_probe(struct i2c_client *i2c_client, 978static int pm2xxx_wall_charger_probe(struct i2c_client *i2c_client,
989 const struct i2c_device_id *id) 979 const struct i2c_device_id *id)
@@ -1244,7 +1234,7 @@ static struct i2c_driver pm2xxx_charger_driver = {
1244 .remove = pm2xxx_wall_charger_remove, 1234 .remove = pm2xxx_wall_charger_remove,
1245 .driver = { 1235 .driver = {
1246 .name = "pm2xxx-wall_charger", 1236 .name = "pm2xxx-wall_charger",
1247 .pm = PM2XXX_PM_OPS, 1237 .pm = IS_ENABLED(CONFIG_PM) ? &pm2xxx_pm_ops : NULL,
1248 }, 1238 },
1249 .id_table = pm2xxx_id, 1239 .id_table = pm2xxx_id,
1250}; 1240};
diff --git a/drivers/power/power_supply_sysfs.c b/drivers/power/power_supply_sysfs.c
index ed2d7fd0c734..80fed98832f9 100644
--- a/drivers/power/power_supply_sysfs.c
+++ b/drivers/power/power_supply_sysfs.c
@@ -45,7 +45,8 @@ static ssize_t power_supply_show_property(struct device *dev,
45 char *buf) { 45 char *buf) {
46 static char *type_text[] = { 46 static char *type_text[] = {
47 "Unknown", "Battery", "UPS", "Mains", "USB", 47 "Unknown", "Battery", "UPS", "Mains", "USB",
48 "USB_DCP", "USB_CDP", "USB_ACA" 48 "USB_DCP", "USB_CDP", "USB_ACA", "USB_C",
49 "USB_PD", "USB_PD_DRP"
49 }; 50 };
50 static char *status_text[] = { 51 static char *status_text[] = {
51 "Unknown", "Charging", "Discharging", "Not charging", "Full" 52 "Unknown", "Charging", "Discharging", "Not charging", "Full"
diff --git a/drivers/power/reset/Kconfig b/drivers/power/reset/Kconfig
index 1131cf75acc6..0a6408a39c66 100644
--- a/drivers/power/reset/Kconfig
+++ b/drivers/power/reset/Kconfig
@@ -148,6 +148,7 @@ config POWER_RESET_KEYSTONE
148config POWER_RESET_SYSCON 148config POWER_RESET_SYSCON
149 bool "Generic SYSCON regmap reset driver" 149 bool "Generic SYSCON regmap reset driver"
150 depends on OF 150 depends on OF
151 depends on HAS_IOMEM
151 select MFD_SYSCON 152 select MFD_SYSCON
152 help 153 help
153 Reboot support for generic SYSCON mapped register reset. 154 Reboot support for generic SYSCON mapped register reset.
@@ -155,6 +156,7 @@ config POWER_RESET_SYSCON
155config POWER_RESET_SYSCON_POWEROFF 156config POWER_RESET_SYSCON_POWEROFF
156 bool "Generic SYSCON regmap poweroff driver" 157 bool "Generic SYSCON regmap poweroff driver"
157 depends on OF 158 depends on OF
159 depends on HAS_IOMEM
158 select MFD_SYSCON 160 select MFD_SYSCON
159 help 161 help
160 Poweroff support for generic SYSCON mapped register poweroff. 162 Poweroff support for generic SYSCON mapped register poweroff.
diff --git a/drivers/power/reset/arm-versatile-reboot.c b/drivers/power/reset/arm-versatile-reboot.c
index b208073c887d..06d34ab47df5 100644
--- a/drivers/power/reset/arm-versatile-reboot.c
+++ b/drivers/power/reset/arm-versatile-reboot.c
@@ -18,8 +18,8 @@
18#define INTEGRATOR_HDR_LOCK_OFFSET 0x14 18#define INTEGRATOR_HDR_LOCK_OFFSET 0x14
19#define INTEGRATOR_CM_CTRL_RESET (1 << 3) 19#define INTEGRATOR_CM_CTRL_RESET (1 << 3)
20 20
21#define REALVIEW_SYS_LOCK_OFFSET 0x20 21#define VERSATILE_SYS_LOCK_OFFSET 0x20
22#define REALVIEW_SYS_RESETCTL_OFFSET 0x40 22#define VERSATILE_SYS_RESETCTL_OFFSET 0x40
23 23
24/* Magic unlocking token used on all Versatile boards */ 24/* Magic unlocking token used on all Versatile boards */
25#define VERSATILE_LOCK_VAL 0xA05F 25#define VERSATILE_LOCK_VAL 0xA05F
@@ -29,6 +29,7 @@
29 */ 29 */
30enum versatile_reboot { 30enum versatile_reboot {
31 INTEGRATOR_REBOOT_CM, 31 INTEGRATOR_REBOOT_CM,
32 VERSATILE_REBOOT_CM,
32 REALVIEW_REBOOT_EB, 33 REALVIEW_REBOOT_EB,
33 REALVIEW_REBOOT_PB1176, 34 REALVIEW_REBOOT_PB1176,
34 REALVIEW_REBOOT_PB11MP, 35 REALVIEW_REBOOT_PB11MP,
@@ -46,6 +47,10 @@ static const struct of_device_id versatile_reboot_of_match[] = {
46 .data = (void *)INTEGRATOR_REBOOT_CM 47 .data = (void *)INTEGRATOR_REBOOT_CM
47 }, 48 },
48 { 49 {
50 .compatible = "arm,core-module-versatile",
51 .data = (void *)VERSATILE_REBOOT_CM,
52 },
53 {
49 .compatible = "arm,realview-eb-syscon", 54 .compatible = "arm,realview-eb-syscon",
50 .data = (void *)REALVIEW_REBOOT_EB, 55 .data = (void *)REALVIEW_REBOOT_EB,
51 }, 56 },
@@ -82,33 +87,43 @@ static int versatile_reboot(struct notifier_block *this, unsigned long mode,
82 INTEGRATOR_CM_CTRL_RESET, 87 INTEGRATOR_CM_CTRL_RESET,
83 INTEGRATOR_CM_CTRL_RESET); 88 INTEGRATOR_CM_CTRL_RESET);
84 break; 89 break;
90 case VERSATILE_REBOOT_CM:
91 regmap_write(syscon_regmap, VERSATILE_SYS_LOCK_OFFSET,
92 VERSATILE_LOCK_VAL);
93 regmap_update_bits(syscon_regmap,
94 VERSATILE_SYS_RESETCTL_OFFSET,
95 0x0107,
96 0x0105);
97 regmap_write(syscon_regmap, VERSATILE_SYS_LOCK_OFFSET,
98 0);
99 break;
85 case REALVIEW_REBOOT_EB: 100 case REALVIEW_REBOOT_EB:
86 regmap_write(syscon_regmap, REALVIEW_SYS_LOCK_OFFSET, 101 regmap_write(syscon_regmap, VERSATILE_SYS_LOCK_OFFSET,
87 VERSATILE_LOCK_VAL); 102 VERSATILE_LOCK_VAL);
88 regmap_write(syscon_regmap, 103 regmap_write(syscon_regmap,
89 REALVIEW_SYS_RESETCTL_OFFSET, 0x0008); 104 VERSATILE_SYS_RESETCTL_OFFSET, 0x0008);
90 break; 105 break;
91 case REALVIEW_REBOOT_PB1176: 106 case REALVIEW_REBOOT_PB1176:
92 regmap_write(syscon_regmap, REALVIEW_SYS_LOCK_OFFSET, 107 regmap_write(syscon_regmap, VERSATILE_SYS_LOCK_OFFSET,
93 VERSATILE_LOCK_VAL); 108 VERSATILE_LOCK_VAL);
94 regmap_write(syscon_regmap, 109 regmap_write(syscon_regmap,
95 REALVIEW_SYS_RESETCTL_OFFSET, 0x0100); 110 VERSATILE_SYS_RESETCTL_OFFSET, 0x0100);
96 break; 111 break;
97 case REALVIEW_REBOOT_PB11MP: 112 case REALVIEW_REBOOT_PB11MP:
98 case REALVIEW_REBOOT_PBA8: 113 case REALVIEW_REBOOT_PBA8:
99 regmap_write(syscon_regmap, REALVIEW_SYS_LOCK_OFFSET, 114 regmap_write(syscon_regmap, VERSATILE_SYS_LOCK_OFFSET,
100 VERSATILE_LOCK_VAL); 115 VERSATILE_LOCK_VAL);
101 regmap_write(syscon_regmap, REALVIEW_SYS_RESETCTL_OFFSET, 116 regmap_write(syscon_regmap, VERSATILE_SYS_RESETCTL_OFFSET,
102 0x0000); 117 0x0000);
103 regmap_write(syscon_regmap, REALVIEW_SYS_RESETCTL_OFFSET, 118 regmap_write(syscon_regmap, VERSATILE_SYS_RESETCTL_OFFSET,
104 0x0004); 119 0x0004);
105 break; 120 break;
106 case REALVIEW_REBOOT_PBX: 121 case REALVIEW_REBOOT_PBX:
107 regmap_write(syscon_regmap, REALVIEW_SYS_LOCK_OFFSET, 122 regmap_write(syscon_regmap, VERSATILE_SYS_LOCK_OFFSET,
108 VERSATILE_LOCK_VAL); 123 VERSATILE_LOCK_VAL);
109 regmap_write(syscon_regmap, REALVIEW_SYS_RESETCTL_OFFSET, 124 regmap_write(syscon_regmap, VERSATILE_SYS_RESETCTL_OFFSET,
110 0x00f0); 125 0x00f0);
111 regmap_write(syscon_regmap, REALVIEW_SYS_RESETCTL_OFFSET, 126 regmap_write(syscon_regmap, VERSATILE_SYS_RESETCTL_OFFSET,
112 0x00f4); 127 0x00f4);
113 break; 128 break;
114 } 129 }
diff --git a/include/linux/power/bq24735-charger.h b/include/linux/power/bq24735-charger.h
index f536164a6069..6b750c1a45fa 100644
--- a/include/linux/power/bq24735-charger.h
+++ b/include/linux/power/bq24735-charger.h
@@ -32,6 +32,8 @@ struct bq24735_platform {
32 int status_gpio_active_low; 32 int status_gpio_active_low;
33 bool status_gpio_valid; 33 bool status_gpio_valid;
34 34
35 bool ext_control;
36
35 char **supplied_to; 37 char **supplied_to;
36 size_t num_supplicants; 38 size_t num_supplicants;
37}; 39};
diff --git a/include/linux/power_supply.h b/include/linux/power_supply.h
index ef9f1592185d..751061790626 100644
--- a/include/linux/power_supply.h
+++ b/include/linux/power_supply.h
@@ -163,6 +163,9 @@ enum power_supply_type {
163 POWER_SUPPLY_TYPE_USB_DCP, /* Dedicated Charging Port */ 163 POWER_SUPPLY_TYPE_USB_DCP, /* Dedicated Charging Port */
164 POWER_SUPPLY_TYPE_USB_CDP, /* Charging Downstream Port */ 164 POWER_SUPPLY_TYPE_USB_CDP, /* Charging Downstream Port */
165 POWER_SUPPLY_TYPE_USB_ACA, /* Accessory Charger Adapters */ 165 POWER_SUPPLY_TYPE_USB_ACA, /* Accessory Charger Adapters */
166 POWER_SUPPLY_TYPE_USB_TYPE_C, /* Type C Port */
167 POWER_SUPPLY_TYPE_USB_PD, /* Power Delivery Port */
168 POWER_SUPPLY_TYPE_USB_PD_DRP, /* PD Dual Role Port */
166}; 169};
167 170
168enum power_supply_notifier_events { 171enum power_supply_notifier_events {