aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/power
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/power')
-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
18 files changed, 624 insertions, 62 deletions
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 }