summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2016-07-26 22:49:09 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2016-07-26 22:49:09 -0400
commitf7816ad0f878dacd5f0120476f9b836ccf8699ea (patch)
tree43c81a5697976af080e58e41ec84c7f5c7c29fbe
parent6097d55e10a7e190279e99318a0e075c8d1dce9e (diff)
parent4fcd504edbf7c793325511c2df8dcd083958e28a (diff)
Merge tag 'for-v4.8' of git://git.kernel.org/pub/scm/linux/kernel/git/sre/linux-power-supply
Pull power supply and reset updates from Sebastian Reichel: - introduce reboot mode driver - add DT support to max8903 - add power supply support for axp221 - misc fixes * tag 'for-v4.8' of git://git.kernel.org/pub/scm/linux/kernel/git/sre/linux-power-supply: power: reset: add reboot mode driver dt-bindings: power: reset: add document for reboot-mode driver power_supply: fix return value of get_property power: qcom_smbb: Make an extcon for usb cable detection max8903: adds support for initiation via device tree max8903: adds documentation for device tree bindings. max8903: remove unnecessary 'out of memory' error message. max8903: removes non zero validity checks on gpios. max8903: adds requesting of gpios. max8903: cleans up confusing relationship between dc_valid, dok and dcm. max8903: store pointer to pdata instead of copying it. power_supply: bq27xxx_battery: Group register mappings into one table docs: Move brcm,bcm21664-resetmgr.txt power/reset: make syscon_poweroff() static power: axp20x_usb: Add support for usb power-supply on axp22x pmics power_supply: bq27xxx_battery: Index register numbers by enum power_supply: bq27xxx_battery: Fix copy/paste error in header comment MAINTAINERS: Add file patterns for power supply device tree bindings power: reset: keystone: Enable COMPILE_TEST
-rw-r--r--Documentation/devicetree/bindings/power/max8903-charger.txt25
-rw-r--r--Documentation/devicetree/bindings/power/reset/brcm,bcm21664-resetmgr.txt (renamed from Documentation/devicetree/bindings/reset/brcm,bcm21664-resetmgr.txt)0
-rw-r--r--Documentation/devicetree/bindings/power/reset/reboot-mode.txt25
-rw-r--r--Documentation/devicetree/bindings/power/reset/syscon-reboot-mode.txt35
-rw-r--r--Documentation/devicetree/bindings/power_supply/axp20x_usb_power.txt3
-rw-r--r--MAINTAINERS2
-rw-r--r--drivers/power/Kconfig1
-rw-r--r--drivers/power/axp20x_usb_power.c92
-rw-r--r--drivers/power/bq27xxx_battery.c284
-rw-r--r--drivers/power/bq27xxx_battery_i2c.c2
-rw-r--r--drivers/power/max8903_charger.c239
-rw-r--r--drivers/power/power_supply_core.c6
-rw-r--r--drivers/power/power_supply_sysfs.c2
-rw-r--r--drivers/power/qcom_smbb.c21
-rw-r--r--drivers/power/reset/Kconfig17
-rw-r--r--drivers/power/reset/Makefile2
-rw-r--r--drivers/power/reset/reboot-mode.c140
-rw-r--r--drivers/power/reset/reboot-mode.h14
-rw-r--r--drivers/power/reset/syscon-poweroff.c2
-rw-r--r--drivers/power/reset/syscon-reboot-mode.c99
-rw-r--r--include/linux/power/max8903_charger.h6
-rw-r--r--include/linux/power_supply.h1
22 files changed, 775 insertions, 243 deletions
diff --git a/Documentation/devicetree/bindings/power/max8903-charger.txt b/Documentation/devicetree/bindings/power/max8903-charger.txt
new file mode 100644
index 000000000000..f0f4e12b076e
--- /dev/null
+++ b/Documentation/devicetree/bindings/power/max8903-charger.txt
@@ -0,0 +1,25 @@
1Maxim Semiconductor MAX8903 Battery Charger bindings
2
3Required properties:
4- compatible: "maxim,max8903" for MAX8903 Battery Charger
5- dok-gpios: Valid DC power has been detected (active low, input), optional if uok-gpios is provided
6- uok-gpios: Valid USB power has been detected (active low, input), optional if dok-gpios is provided
7
8Optional properties:
9- cen-gpios: Charge enable pin (active low, output)
10- chg-gpios: Charger status pin (active low, input)
11- flt-gpios: Fault pin (active low, output)
12- dcm-gpios: Current limit mode setting (DC=1 or USB=0, output)
13- usus-gpios: USB suspend pin (active high, output)
14
15
16Example:
17
18 max8903-charger {
19 compatible = "maxim,max8903";
20 dok-gpios = <&gpio2 3 GPIO_ACTIVE_LOW>;
21 flt-gpios = <&gpio2 2 GPIO_ACTIVE_LOW>;
22 chg-gpios = <&gpio3 15 GPIO_ACTIVE_LOW>;
23 cen-gpios = <&gpio2 5 GPIO_ACTIVE_LOW>;
24 status = "okay";
25 };
diff --git a/Documentation/devicetree/bindings/reset/brcm,bcm21664-resetmgr.txt b/Documentation/devicetree/bindings/power/reset/brcm,bcm21664-resetmgr.txt
index 93f31ca1ef4b..93f31ca1ef4b 100644
--- a/Documentation/devicetree/bindings/reset/brcm,bcm21664-resetmgr.txt
+++ b/Documentation/devicetree/bindings/power/reset/brcm,bcm21664-resetmgr.txt
diff --git a/Documentation/devicetree/bindings/power/reset/reboot-mode.txt b/Documentation/devicetree/bindings/power/reset/reboot-mode.txt
new file mode 100644
index 000000000000..de34f27d509e
--- /dev/null
+++ b/Documentation/devicetree/bindings/power/reset/reboot-mode.txt
@@ -0,0 +1,25 @@
1Generic reboot mode core map driver
2
3This driver get reboot mode arguments and call the write
4interface to store the magic value in special register
5or ram. Then the bootloader can read it and take different
6action according to the argument stored.
7
8All mode properties are vendor specific, it is a indication to tell
9the bootloader what to do when the system reboots, and should be named
10as mode-xxx = <magic> (xxx is mode name, magic should be a none-zero value).
11
12For example modes common on Android platform:
13- mode-normal: Normal reboot mode, system reboot with command "reboot".
14- mode-recovery: Android Recovery mode, it is a mode to format the device or update a new image.
15- mode-bootloader: Android fastboot mode, it's a mode to re-flash partitions on the Android based device.
16- mode-loader: A bootloader mode, it's a mode used to download image on Rockchip platform,
17 usually used in development.
18
19Example:
20 reboot-mode {
21 mode-normal = <BOOT_NORMAL>;
22 mode-recovery = <BOOT_RECOVERY>;
23 mode-bootloader = <BOOT_FASTBOOT>;
24 mode-loader = <BOOT_BL_DOWNLOAD>;
25 }
diff --git a/Documentation/devicetree/bindings/power/reset/syscon-reboot-mode.txt b/Documentation/devicetree/bindings/power/reset/syscon-reboot-mode.txt
new file mode 100644
index 000000000000..f7ce1d8af04a
--- /dev/null
+++ b/Documentation/devicetree/bindings/power/reset/syscon-reboot-mode.txt
@@ -0,0 +1,35 @@
1SYSCON reboot mode driver
2
3This driver gets reboot mode magic value form reboot-mode driver
4and stores it in a SYSCON mapped register. Then the bootloader
5can read it and take different action according to the magic
6value stored.
7
8This DT node should be represented as a sub-node of a "syscon", "simple-mfd"
9node.
10
11Required properties:
12- compatible: should be "syscon-reboot-mode"
13- offset: offset in the register map for the storage register (in bytes)
14
15Optional property:
16- mask: bits mask of the bits in the register to store the reboot mode magic value,
17 default set to 0xffffffff if missing.
18
19The rest of the properties should follow the generic reboot-mode description
20found in reboot-mode.txt
21
22Example:
23 pmu: pmu@20004000 {
24 compatible = "rockchip,rk3066-pmu", "syscon", "simple-mfd";
25 reg = <0x20004000 0x100>;
26
27 reboot-mode {
28 compatible = "syscon-reboot-mode";
29 offset = <0x40>;
30 mode-normal = <BOOT_NORMAL>;
31 mode-recovery = <BOOT_RECOVERY>;
32 mode-bootloader = <BOOT_FASTBOOT>;
33 mode-loader = <BOOT_BL_DOWNLOAD>;
34 };
35 };
diff --git a/Documentation/devicetree/bindings/power_supply/axp20x_usb_power.txt b/Documentation/devicetree/bindings/power_supply/axp20x_usb_power.txt
index 862f4a49dc49..f1d7beec45bf 100644
--- a/Documentation/devicetree/bindings/power_supply/axp20x_usb_power.txt
+++ b/Documentation/devicetree/bindings/power_supply/axp20x_usb_power.txt
@@ -1,7 +1,8 @@
1AXP20x USB power supply 1AXP20x USB power supply
2 2
3Required Properties: 3Required Properties:
4-compatible: "x-powers,axp202-usb-power-supply" 4-compatible: One of: "x-powers,axp202-usb-power-supply"
5 "x-powers,axp221-usb-power-supply"
5 6
6This node is a subnode of the axp20x PMIC. 7This node is a subnode of the axp20x PMIC.
7 8
diff --git a/MAINTAINERS b/MAINTAINERS
index b407c5f5caa4..771c31c73172 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -9169,6 +9169,8 @@ M: David Woodhouse <dwmw2@infradead.org>
9169L: linux-pm@vger.kernel.org 9169L: linux-pm@vger.kernel.org
9170T: git git://git.infradead.org/battery-2.6.git 9170T: git git://git.infradead.org/battery-2.6.git
9171S: Maintained 9171S: Maintained
9172F: Documentation/devicetree/bindings/power/
9173F: Documentation/devicetree/bindings/power_supply/
9172F: include/linux/power_supply.h 9174F: include/linux/power_supply.h
9173F: drivers/power/ 9175F: drivers/power/
9174X: drivers/power/avs/ 9176X: drivers/power/avs/
diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig
index 0f11a0f4c369..acd4a1524a1e 100644
--- a/drivers/power/Kconfig
+++ b/drivers/power/Kconfig
@@ -394,6 +394,7 @@ config CHARGER_QCOM_SMBB
394 tristate "Qualcomm Switch-Mode Battery Charger and Boost" 394 tristate "Qualcomm Switch-Mode Battery Charger and Boost"
395 depends on MFD_SPMI_PMIC || COMPILE_TEST 395 depends on MFD_SPMI_PMIC || COMPILE_TEST
396 depends on OF 396 depends on OF
397 depends on EXTCON
397 help 398 help
398 Say Y to include support for the Switch-Mode Battery Charger and 399 Say Y to include support for the Switch-Mode Battery Charger and
399 Boost (SMBB) hardware found in Qualcomm PM8941 PMICs. The charger 400 Boost (SMBB) hardware found in Qualcomm PM8941 PMICs. The charger
diff --git a/drivers/power/axp20x_usb_power.c b/drivers/power/axp20x_usb_power.c
index 421a90b83567..6af6feb7058d 100644
--- a/drivers/power/axp20x_usb_power.c
+++ b/drivers/power/axp20x_usb_power.c
@@ -42,6 +42,7 @@
42#define AXP20X_VBUS_MON_VBUS_VALID BIT(3) 42#define AXP20X_VBUS_MON_VBUS_VALID BIT(3)
43 43
44struct axp20x_usb_power { 44struct axp20x_usb_power {
45 struct device_node *np;
45 struct regmap *regmap; 46 struct regmap *regmap;
46 struct power_supply *supply; 47 struct power_supply *supply;
47}; 48};
@@ -85,7 +86,12 @@ static int axp20x_usb_power_get_property(struct power_supply *psy,
85 86
86 switch (v & AXP20X_VBUS_CLIMIT_MASK) { 87 switch (v & AXP20X_VBUS_CLIMIT_MASK) {
87 case AXP20X_VBUC_CLIMIT_100mA: 88 case AXP20X_VBUC_CLIMIT_100mA:
88 val->intval = 100000; 89 if (of_device_is_compatible(power->np,
90 "x-powers,axp202-usb-power-supply")) {
91 val->intval = 100000;
92 } else {
93 val->intval = -1; /* No 100mA limit */
94 }
89 break; 95 break;
90 case AXP20X_VBUC_CLIMIT_500mA: 96 case AXP20X_VBUC_CLIMIT_500mA:
91 val->intval = 500000; 97 val->intval = 500000;
@@ -122,16 +128,19 @@ static int axp20x_usb_power_get_property(struct power_supply *psy,
122 break; 128 break;
123 } 129 }
124 130
125 ret = regmap_read(power->regmap, AXP20X_USB_OTG_STATUS, &v); 131 val->intval = POWER_SUPPLY_HEALTH_GOOD;
126 if (ret)
127 return ret;
128 132
129 if (!(v & AXP20X_USB_STATUS_VBUS_VALID)) { 133 if (of_device_is_compatible(power->np,
130 val->intval = POWER_SUPPLY_HEALTH_UNSPEC_FAILURE; 134 "x-powers,axp202-usb-power-supply")) {
131 break; 135 ret = regmap_read(power->regmap,
132 } 136 AXP20X_USB_OTG_STATUS, &v);
137 if (ret)
138 return ret;
133 139
134 val->intval = POWER_SUPPLY_HEALTH_GOOD; 140 if (!(v & AXP20X_USB_STATUS_VBUS_VALID))
141 val->intval =
142 POWER_SUPPLY_HEALTH_UNSPEC_FAILURE;
143 }
135 break; 144 break;
136 case POWER_SUPPLY_PROP_PRESENT: 145 case POWER_SUPPLY_PROP_PRESENT:
137 val->intval = !!(input & AXP20X_PWR_STATUS_VBUS_PRESENT); 146 val->intval = !!(input & AXP20X_PWR_STATUS_VBUS_PRESENT);
@@ -156,6 +165,14 @@ static enum power_supply_property axp20x_usb_power_properties[] = {
156 POWER_SUPPLY_PROP_CURRENT_NOW, 165 POWER_SUPPLY_PROP_CURRENT_NOW,
157}; 166};
158 167
168static enum power_supply_property axp22x_usb_power_properties[] = {
169 POWER_SUPPLY_PROP_HEALTH,
170 POWER_SUPPLY_PROP_PRESENT,
171 POWER_SUPPLY_PROP_ONLINE,
172 POWER_SUPPLY_PROP_VOLTAGE_MIN,
173 POWER_SUPPLY_PROP_CURRENT_MAX,
174};
175
159static const struct power_supply_desc axp20x_usb_power_desc = { 176static const struct power_supply_desc axp20x_usb_power_desc = {
160 .name = "axp20x-usb", 177 .name = "axp20x-usb",
161 .type = POWER_SUPPLY_TYPE_USB, 178 .type = POWER_SUPPLY_TYPE_USB,
@@ -164,13 +181,25 @@ static const struct power_supply_desc axp20x_usb_power_desc = {
164 .get_property = axp20x_usb_power_get_property, 181 .get_property = axp20x_usb_power_get_property,
165}; 182};
166 183
184static const struct power_supply_desc axp22x_usb_power_desc = {
185 .name = "axp20x-usb",
186 .type = POWER_SUPPLY_TYPE_USB,
187 .properties = axp22x_usb_power_properties,
188 .num_properties = ARRAY_SIZE(axp22x_usb_power_properties),
189 .get_property = axp20x_usb_power_get_property,
190};
191
167static int axp20x_usb_power_probe(struct platform_device *pdev) 192static int axp20x_usb_power_probe(struct platform_device *pdev)
168{ 193{
169 struct axp20x_dev *axp20x = dev_get_drvdata(pdev->dev.parent); 194 struct axp20x_dev *axp20x = dev_get_drvdata(pdev->dev.parent);
170 struct power_supply_config psy_cfg = {}; 195 struct power_supply_config psy_cfg = {};
171 struct axp20x_usb_power *power; 196 struct axp20x_usb_power *power;
172 static const char * const irq_names[] = { "VBUS_PLUGIN", 197 static const char * const axp20x_irq_names[] = { "VBUS_PLUGIN",
173 "VBUS_REMOVAL", "VBUS_VALID", "VBUS_NOT_VALID" }; 198 "VBUS_REMOVAL", "VBUS_VALID", "VBUS_NOT_VALID", NULL };
199 static const char * const axp22x_irq_names[] = {
200 "VBUS_PLUGIN", "VBUS_REMOVAL", NULL };
201 static const char * const *irq_names;
202 const struct power_supply_desc *usb_power_desc;
174 int i, irq, ret; 203 int i, irq, ret;
175 204
176 if (!of_device_is_available(pdev->dev.of_node)) 205 if (!of_device_is_available(pdev->dev.of_node))
@@ -185,31 +214,47 @@ static int axp20x_usb_power_probe(struct platform_device *pdev)
185 if (!power) 214 if (!power)
186 return -ENOMEM; 215 return -ENOMEM;
187 216
217 power->np = pdev->dev.of_node;
188 power->regmap = axp20x->regmap; 218 power->regmap = axp20x->regmap;
189 219
190 /* Enable vbus valid checking */ 220 if (of_device_is_compatible(power->np,
191 ret = regmap_update_bits(power->regmap, AXP20X_VBUS_MON, 221 "x-powers,axp202-usb-power-supply")) {
192 AXP20X_VBUS_MON_VBUS_VALID, AXP20X_VBUS_MON_VBUS_VALID); 222 /* Enable vbus valid checking */
193 if (ret) 223 ret = regmap_update_bits(power->regmap, AXP20X_VBUS_MON,
194 return ret; 224 AXP20X_VBUS_MON_VBUS_VALID,
225 AXP20X_VBUS_MON_VBUS_VALID);
226 if (ret)
227 return ret;
195 228
196 /* Enable vbus voltage and current measurement */ 229 /* Enable vbus voltage and current measurement */
197 ret = regmap_update_bits(power->regmap, AXP20X_ADC_EN1, 230 ret = regmap_update_bits(power->regmap, AXP20X_ADC_EN1,
198 AXP20X_ADC_EN1_VBUS_CURR | AXP20X_ADC_EN1_VBUS_VOLT, 231 AXP20X_ADC_EN1_VBUS_CURR | AXP20X_ADC_EN1_VBUS_VOLT,
199 AXP20X_ADC_EN1_VBUS_CURR | AXP20X_ADC_EN1_VBUS_VOLT); 232 AXP20X_ADC_EN1_VBUS_CURR | AXP20X_ADC_EN1_VBUS_VOLT);
200 if (ret) 233 if (ret)
201 return ret; 234 return ret;
235
236 usb_power_desc = &axp20x_usb_power_desc;
237 irq_names = axp20x_irq_names;
238 } else if (of_device_is_compatible(power->np,
239 "x-powers,axp221-usb-power-supply")) {
240 usb_power_desc = &axp22x_usb_power_desc;
241 irq_names = axp22x_irq_names;
242 } else {
243 dev_err(&pdev->dev, "Unsupported AXP variant: %ld\n",
244 axp20x->variant);
245 return -EINVAL;
246 }
202 247
203 psy_cfg.of_node = pdev->dev.of_node; 248 psy_cfg.of_node = pdev->dev.of_node;
204 psy_cfg.drv_data = power; 249 psy_cfg.drv_data = power;
205 250
206 power->supply = devm_power_supply_register(&pdev->dev, 251 power->supply = devm_power_supply_register(&pdev->dev, usb_power_desc,
207 &axp20x_usb_power_desc, &psy_cfg); 252 &psy_cfg);
208 if (IS_ERR(power->supply)) 253 if (IS_ERR(power->supply))
209 return PTR_ERR(power->supply); 254 return PTR_ERR(power->supply);
210 255
211 /* Request irqs after registering, as irqs may trigger immediately */ 256 /* Request irqs after registering, as irqs may trigger immediately */
212 for (i = 0; i < ARRAY_SIZE(irq_names); i++) { 257 for (i = 0; irq_names[i]; i++) {
213 irq = platform_get_irq_byname(pdev, irq_names[i]); 258 irq = platform_get_irq_byname(pdev, irq_names[i]);
214 if (irq < 0) { 259 if (irq < 0) {
215 dev_warn(&pdev->dev, "No IRQ for %s: %d\n", 260 dev_warn(&pdev->dev, "No IRQ for %s: %d\n",
@@ -229,6 +274,7 @@ static int axp20x_usb_power_probe(struct platform_device *pdev)
229 274
230static const struct of_device_id axp20x_usb_power_match[] = { 275static const struct of_device_id axp20x_usb_power_match[] = {
231 { .compatible = "x-powers,axp202-usb-power-supply" }, 276 { .compatible = "x-powers,axp202-usb-power-supply" },
277 { .compatible = "x-powers,axp221-usb-power-supply" },
232 { } 278 { }
233}; 279};
234MODULE_DEVICE_TABLE(of, axp20x_usb_power_match); 280MODULE_DEVICE_TABLE(of, axp20x_usb_power_match);
diff --git a/drivers/power/bq27xxx_battery.c b/drivers/power/bq27xxx_battery.c
index e90b3f307e0f..323d05a12f9b 100644
--- a/drivers/power/bq27xxx_battery.c
+++ b/drivers/power/bq27xxx_battery.c
@@ -82,6 +82,7 @@
82 * 82 *
83 * These are indexes into a device's register mapping array. 83 * These are indexes into a device's register mapping array.
84 */ 84 */
85
85enum bq27xxx_reg_index { 86enum bq27xxx_reg_index {
86 BQ27XXX_REG_CTRL = 0, /* Control */ 87 BQ27XXX_REG_CTRL = 0, /* Control */
87 BQ27XXX_REG_TEMP, /* Temperature */ 88 BQ27XXX_REG_TEMP, /* Temperature */
@@ -100,157 +101,144 @@ enum bq27xxx_reg_index {
100 BQ27XXX_REG_SOC, /* State-of-Charge */ 101 BQ27XXX_REG_SOC, /* State-of-Charge */
101 BQ27XXX_REG_DCAP, /* Design Capacity */ 102 BQ27XXX_REG_DCAP, /* Design Capacity */
102 BQ27XXX_REG_AP, /* Average Power */ 103 BQ27XXX_REG_AP, /* Average Power */
104 BQ27XXX_REG_MAX, /* sentinel */
103}; 105};
104 106
105/* Register mappings */ 107/* Register mappings */
106static u8 bq27000_regs[] = { 108static u8 bq27xxx_regs[][BQ27XXX_REG_MAX] = {
107 0x00, /* CONTROL */ 109 [BQ27000] = {
108 0x06, /* TEMP */ 110 [BQ27XXX_REG_CTRL] = 0x00,
109 INVALID_REG_ADDR, /* INT TEMP - NA*/ 111 [BQ27XXX_REG_TEMP] = 0x06,
110 0x08, /* VOLT */ 112 [BQ27XXX_REG_INT_TEMP] = INVALID_REG_ADDR,
111 0x14, /* AVG CURR */ 113 [BQ27XXX_REG_VOLT] = 0x08,
112 0x0a, /* FLAGS */ 114 [BQ27XXX_REG_AI] = 0x14,
113 0x16, /* TTE */ 115 [BQ27XXX_REG_FLAGS] = 0x0a,
114 0x18, /* TTF */ 116 [BQ27XXX_REG_TTE] = 0x16,
115 0x1c, /* TTES */ 117 [BQ27XXX_REG_TTF] = 0x18,
116 0x26, /* TTECP */ 118 [BQ27XXX_REG_TTES] = 0x1c,
117 0x0c, /* NAC */ 119 [BQ27XXX_REG_TTECP] = 0x26,
118 0x12, /* LMD(FCC) */ 120 [BQ27XXX_REG_NAC] = 0x0c,
119 0x2a, /* CYCT */ 121 [BQ27XXX_REG_FCC] = 0x12,
120 0x22, /* AE */ 122 [BQ27XXX_REG_CYCT] = 0x2a,
121 0x0b, /* SOC(RSOC) */ 123 [BQ27XXX_REG_AE] = 0x22,
122 0x76, /* DCAP(ILMD) */ 124 [BQ27XXX_REG_SOC] = 0x0b,
123 0x24, /* AP */ 125 [BQ27XXX_REG_DCAP] = 0x76,
124}; 126 [BQ27XXX_REG_AP] = 0x24,
125 127 },
126static u8 bq27010_regs[] = { 128 [BQ27010] = {
127 0x00, /* CONTROL */ 129 [BQ27XXX_REG_CTRL] = 0x00,
128 0x06, /* TEMP */ 130 [BQ27XXX_REG_TEMP] = 0x06,
129 INVALID_REG_ADDR, /* INT TEMP - NA*/ 131 [BQ27XXX_REG_INT_TEMP] = INVALID_REG_ADDR,
130 0x08, /* VOLT */ 132 [BQ27XXX_REG_VOLT] = 0x08,
131 0x14, /* AVG CURR */ 133 [BQ27XXX_REG_AI] = 0x14,
132 0x0a, /* FLAGS */ 134 [BQ27XXX_REG_FLAGS] = 0x0a,
133 0x16, /* TTE */ 135 [BQ27XXX_REG_TTE] = 0x16,
134 0x18, /* TTF */ 136 [BQ27XXX_REG_TTF] = 0x18,
135 0x1c, /* TTES */ 137 [BQ27XXX_REG_TTES] = 0x1c,
136 0x26, /* TTECP */ 138 [BQ27XXX_REG_TTECP] = 0x26,
137 0x0c, /* NAC */ 139 [BQ27XXX_REG_NAC] = 0x0c,
138 0x12, /* LMD(FCC) */ 140 [BQ27XXX_REG_FCC] = 0x12,
139 0x2a, /* CYCT */ 141 [BQ27XXX_REG_CYCT] = 0x2a,
140 INVALID_REG_ADDR, /* AE - NA */ 142 [BQ27XXX_REG_AE] = INVALID_REG_ADDR,
141 0x0b, /* SOC(RSOC) */ 143 [BQ27XXX_REG_SOC] = 0x0b,
142 0x76, /* DCAP(ILMD) */ 144 [BQ27XXX_REG_DCAP] = 0x76,
143 INVALID_REG_ADDR, /* AP - NA */ 145 [BQ27XXX_REG_AP] = INVALID_REG_ADDR,
144}; 146 },
145 147 [BQ27500] = {
146static u8 bq27500_regs[] = { 148 [BQ27XXX_REG_CTRL] = 0x00,
147 0x00, /* CONTROL */ 149 [BQ27XXX_REG_TEMP] = 0x06,
148 0x06, /* TEMP */ 150 [BQ27XXX_REG_INT_TEMP] = 0x28,
149 0x28, /* INT TEMP */ 151 [BQ27XXX_REG_VOLT] = 0x08,
150 0x08, /* VOLT */ 152 [BQ27XXX_REG_AI] = 0x14,
151 0x14, /* AVG CURR */ 153 [BQ27XXX_REG_FLAGS] = 0x0a,
152 0x0a, /* FLAGS */ 154 [BQ27XXX_REG_TTE] = 0x16,
153 0x16, /* TTE */ 155 [BQ27XXX_REG_TTF] = INVALID_REG_ADDR,
154 INVALID_REG_ADDR, /* TTF - NA */ 156 [BQ27XXX_REG_TTES] = 0x1a,
155 0x1a, /* TTES */ 157 [BQ27XXX_REG_TTECP] = INVALID_REG_ADDR,
156 INVALID_REG_ADDR, /* TTECP - NA */ 158 [BQ27XXX_REG_NAC] = 0x0c,
157 0x0c, /* NAC */ 159 [BQ27XXX_REG_FCC] = 0x12,
158 0x12, /* LMD(FCC) */ 160 [BQ27XXX_REG_CYCT] = 0x2a,
159 0x2a, /* CYCT */ 161 [BQ27XXX_REG_AE] = INVALID_REG_ADDR,
160 INVALID_REG_ADDR, /* AE - NA */ 162 [BQ27XXX_REG_SOC] = 0x2c,
161 0x2c, /* SOC(RSOC) */ 163 [BQ27XXX_REG_DCAP] = 0x3c,
162 0x3c, /* DCAP(ILMD) */ 164 [BQ27XXX_REG_AP] = INVALID_REG_ADDR,
163 INVALID_REG_ADDR, /* AP - NA */ 165 },
164}; 166 [BQ27530] = {
165 167 [BQ27XXX_REG_CTRL] = 0x00,
166static u8 bq27530_regs[] = { 168 [BQ27XXX_REG_TEMP] = 0x06,
167 0x00, /* CONTROL */ 169 [BQ27XXX_REG_INT_TEMP] = 0x32,
168 0x06, /* TEMP */ 170 [BQ27XXX_REG_VOLT] = 0x08,
169 0x32, /* INT TEMP */ 171 [BQ27XXX_REG_AI] = 0x14,
170 0x08, /* VOLT */ 172 [BQ27XXX_REG_FLAGS] = 0x0a,
171 0x14, /* AVG CURR */ 173 [BQ27XXX_REG_TTE] = 0x16,
172 0x0a, /* FLAGS */ 174 [BQ27XXX_REG_TTF] = INVALID_REG_ADDR,
173 0x16, /* TTE */ 175 [BQ27XXX_REG_TTES] = INVALID_REG_ADDR,
174 INVALID_REG_ADDR, /* TTF - NA */ 176 [BQ27XXX_REG_TTECP] = INVALID_REG_ADDR,
175 INVALID_REG_ADDR, /* TTES - NA */ 177 [BQ27XXX_REG_NAC] = 0x0c,
176 INVALID_REG_ADDR, /* TTECP - NA */ 178 [BQ27XXX_REG_FCC] = 0x12,
177 0x0c, /* NAC */ 179 [BQ27XXX_REG_CYCT] = 0x2a,
178 0x12, /* LMD(FCC) */ 180 [BQ27XXX_REG_AE] = INVALID_REG_ADDR,
179 0x2a, /* CYCT */ 181 [BQ27XXX_REG_SOC] = 0x2c,
180 INVALID_REG_ADDR, /* AE - NA */ 182 [BQ27XXX_REG_DCAP] = INVALID_REG_ADDR,
181 0x2c, /* SOC(RSOC) */ 183 [BQ27XXX_REG_AP] = 0x24,
182 INVALID_REG_ADDR, /* DCAP - NA */ 184 },
183 0x24, /* AP */ 185 [BQ27541] = {
184}; 186 [BQ27XXX_REG_CTRL] = 0x00,
185 187 [BQ27XXX_REG_TEMP] = 0x06,
186static u8 bq27541_regs[] = { 188 [BQ27XXX_REG_INT_TEMP] = 0x28,
187 0x00, /* CONTROL */ 189 [BQ27XXX_REG_VOLT] = 0x08,
188 0x06, /* TEMP */ 190 [BQ27XXX_REG_AI] = 0x14,
189 0x28, /* INT TEMP */ 191 [BQ27XXX_REG_FLAGS] = 0x0a,
190 0x08, /* VOLT */ 192 [BQ27XXX_REG_TTE] = 0x16,
191 0x14, /* AVG CURR */ 193 [BQ27XXX_REG_TTF] = INVALID_REG_ADDR,
192 0x0a, /* FLAGS */ 194 [BQ27XXX_REG_TTES] = INVALID_REG_ADDR,
193 0x16, /* TTE */ 195 [BQ27XXX_REG_TTECP] = INVALID_REG_ADDR,
194 INVALID_REG_ADDR, /* TTF - NA */ 196 [BQ27XXX_REG_NAC] = 0x0c,
195 INVALID_REG_ADDR, /* TTES - NA */ 197 [BQ27XXX_REG_FCC] = 0x12,
196 INVALID_REG_ADDR, /* TTECP - NA */ 198 [BQ27XXX_REG_CYCT] = 0x2a,
197 0x0c, /* NAC */ 199 [BQ27XXX_REG_AE] = INVALID_REG_ADDR,
198 0x12, /* LMD(FCC) */ 200 [BQ27XXX_REG_SOC] = 0x2c,
199 0x2a, /* CYCT */ 201 [BQ27XXX_REG_DCAP] = 0x3c,
200 INVALID_REG_ADDR, /* AE - NA */ 202 [BQ27XXX_REG_AP] = 0x24,
201 0x2c, /* SOC(RSOC) */ 203 },
202 0x3c, /* DCAP */ 204 [BQ27545] = {
203 0x24, /* AP */ 205 [BQ27XXX_REG_CTRL] = 0x00,
204}; 206 [BQ27XXX_REG_TEMP] = 0x06,
205 207 [BQ27XXX_REG_INT_TEMP] = 0x28,
206static u8 bq27545_regs[] = { 208 [BQ27XXX_REG_VOLT] = 0x08,
207 0x00, /* CONTROL */ 209 [BQ27XXX_REG_AI] = 0x14,
208 0x06, /* TEMP */ 210 [BQ27XXX_REG_FLAGS] = 0x0a,
209 0x28, /* INT TEMP */ 211 [BQ27XXX_REG_TTE] = 0x16,
210 0x08, /* VOLT */ 212 [BQ27XXX_REG_TTF] = INVALID_REG_ADDR,
211 0x14, /* AVG CURR */ 213 [BQ27XXX_REG_TTES] = INVALID_REG_ADDR,
212 0x0a, /* FLAGS */ 214 [BQ27XXX_REG_TTECP] = INVALID_REG_ADDR,
213 0x16, /* TTE */ 215 [BQ27XXX_REG_NAC] = 0x0c,
214 INVALID_REG_ADDR, /* TTF - NA */ 216 [BQ27XXX_REG_FCC] = 0x12,
215 INVALID_REG_ADDR, /* TTES - NA */ 217 [BQ27XXX_REG_CYCT] = 0x2a,
216 INVALID_REG_ADDR, /* TTECP - NA */ 218 [BQ27XXX_REG_AE] = INVALID_REG_ADDR,
217 0x0c, /* NAC */ 219 [BQ27XXX_REG_SOC] = 0x2c,
218 0x12, /* LMD(FCC) */ 220 [BQ27XXX_REG_DCAP] = INVALID_REG_ADDR,
219 0x2a, /* CYCT */ 221 [BQ27XXX_REG_AP] = 0x24,
220 INVALID_REG_ADDR, /* AE - NA */ 222 },
221 0x2c, /* SOC(RSOC) */ 223 [BQ27421] = {
222 INVALID_REG_ADDR, /* DCAP - NA */ 224 [BQ27XXX_REG_CTRL] = 0x00,
223 0x24, /* AP */ 225 [BQ27XXX_REG_TEMP] = 0x02,
224}; 226 [BQ27XXX_REG_INT_TEMP] = 0x1e,
225 227 [BQ27XXX_REG_VOLT] = 0x04,
226static u8 bq27421_regs[] = { 228 [BQ27XXX_REG_AI] = 0x10,
227 0x00, /* CONTROL */ 229 [BQ27XXX_REG_FLAGS] = 0x06,
228 0x02, /* TEMP */ 230 [BQ27XXX_REG_TTE] = INVALID_REG_ADDR,
229 0x1e, /* INT TEMP */ 231 [BQ27XXX_REG_TTF] = INVALID_REG_ADDR,
230 0x04, /* VOLT */ 232 [BQ27XXX_REG_TTES] = INVALID_REG_ADDR,
231 0x10, /* AVG CURR */ 233 [BQ27XXX_REG_TTECP] = INVALID_REG_ADDR,
232 0x06, /* FLAGS */ 234 [BQ27XXX_REG_NAC] = 0x08,
233 INVALID_REG_ADDR, /* TTE - NA */ 235 [BQ27XXX_REG_FCC] = 0x0e,
234 INVALID_REG_ADDR, /* TTF - NA */ 236 [BQ27XXX_REG_CYCT] = INVALID_REG_ADDR,
235 INVALID_REG_ADDR, /* TTES - NA */ 237 [BQ27XXX_REG_AE] = INVALID_REG_ADDR,
236 INVALID_REG_ADDR, /* TTECP - NA */ 238 [BQ27XXX_REG_SOC] = 0x1c,
237 0x08, /* NAC */ 239 [BQ27XXX_REG_DCAP] = 0x3c,
238 0x0e, /* FCC */ 240 [BQ27XXX_REG_AP] = 0x18,
239 INVALID_REG_ADDR, /* CYCT - NA */ 241 },
240 INVALID_REG_ADDR, /* AE - NA */
241 0x1c, /* SOC */
242 0x3c, /* DCAP */
243 0x18, /* AP */
244};
245
246static u8 *bq27xxx_regs[] = {
247 [BQ27000] = bq27000_regs,
248 [BQ27010] = bq27010_regs,
249 [BQ27500] = bq27500_regs,
250 [BQ27530] = bq27530_regs,
251 [BQ27541] = bq27541_regs,
252 [BQ27545] = bq27545_regs,
253 [BQ27421] = bq27421_regs,
254}; 242};
255 243
256static enum power_supply_property bq27000_battery_props[] = { 244static enum power_supply_property bq27000_battery_props[] = {
diff --git a/drivers/power/bq27xxx_battery_i2c.c b/drivers/power/bq27xxx_battery_i2c.c
index b8f8d3ade31b..85d4ea2a9c20 100644
--- a/drivers/power/bq27xxx_battery_i2c.c
+++ b/drivers/power/bq27xxx_battery_i2c.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * SCI Reset driver for Keystone based devices 2 * BQ27xxx battery monitor I2C driver
3 * 3 *
4 * Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com/ 4 * Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com/
5 * Andrew F. Davis <afd@ti.com> 5 * Andrew F. Davis <afd@ti.com>
diff --git a/drivers/power/max8903_charger.c b/drivers/power/max8903_charger.c
index 17876caf31e5..fdc73d686153 100644
--- a/drivers/power/max8903_charger.c
+++ b/drivers/power/max8903_charger.c
@@ -23,13 +23,16 @@
23#include <linux/gpio.h> 23#include <linux/gpio.h>
24#include <linux/interrupt.h> 24#include <linux/interrupt.h>
25#include <linux/module.h> 25#include <linux/module.h>
26#include <linux/of.h>
27#include <linux/of_device.h>
28#include <linux/of_gpio.h>
26#include <linux/slab.h> 29#include <linux/slab.h>
27#include <linux/power_supply.h> 30#include <linux/power_supply.h>
28#include <linux/platform_device.h> 31#include <linux/platform_device.h>
29#include <linux/power/max8903_charger.h> 32#include <linux/power/max8903_charger.h>
30 33
31struct max8903_data { 34struct max8903_data {
32 struct max8903_pdata pdata; 35 struct max8903_pdata *pdata;
33 struct device *dev; 36 struct device *dev;
34 struct power_supply *psy; 37 struct power_supply *psy;
35 struct power_supply_desc psy_desc; 38 struct power_supply_desc psy_desc;
@@ -53,8 +56,8 @@ static int max8903_get_property(struct power_supply *psy,
53 switch (psp) { 56 switch (psp) {
54 case POWER_SUPPLY_PROP_STATUS: 57 case POWER_SUPPLY_PROP_STATUS:
55 val->intval = POWER_SUPPLY_STATUS_UNKNOWN; 58 val->intval = POWER_SUPPLY_STATUS_UNKNOWN;
56 if (data->pdata.chg) { 59 if (gpio_is_valid(data->pdata->chg)) {
57 if (gpio_get_value(data->pdata.chg) == 0) 60 if (gpio_get_value(data->pdata->chg) == 0)
58 val->intval = POWER_SUPPLY_STATUS_CHARGING; 61 val->intval = POWER_SUPPLY_STATUS_CHARGING;
59 else if (data->usb_in || data->ta_in) 62 else if (data->usb_in || data->ta_in)
60 val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING; 63 val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING;
@@ -75,13 +78,14 @@ static int max8903_get_property(struct power_supply *psy,
75 default: 78 default:
76 return -EINVAL; 79 return -EINVAL;
77 } 80 }
81
78 return 0; 82 return 0;
79} 83}
80 84
81static irqreturn_t max8903_dcin(int irq, void *_data) 85static irqreturn_t max8903_dcin(int irq, void *_data)
82{ 86{
83 struct max8903_data *data = _data; 87 struct max8903_data *data = _data;
84 struct max8903_pdata *pdata = &data->pdata; 88 struct max8903_pdata *pdata = data->pdata;
85 bool ta_in; 89 bool ta_in;
86 enum power_supply_type old_type; 90 enum power_supply_type old_type;
87 91
@@ -93,11 +97,11 @@ static irqreturn_t max8903_dcin(int irq, void *_data)
93 data->ta_in = ta_in; 97 data->ta_in = ta_in;
94 98
95 /* Set Current-Limit-Mode 1:DC 0:USB */ 99 /* Set Current-Limit-Mode 1:DC 0:USB */
96 if (pdata->dcm) 100 if (gpio_is_valid(pdata->dcm))
97 gpio_set_value(pdata->dcm, ta_in ? 1 : 0); 101 gpio_set_value(pdata->dcm, ta_in ? 1 : 0);
98 102
99 /* Charger Enable / Disable (cen is negated) */ 103 /* Charger Enable / Disable (cen is negated) */
100 if (pdata->cen) 104 if (gpio_is_valid(pdata->cen))
101 gpio_set_value(pdata->cen, ta_in ? 0 : 105 gpio_set_value(pdata->cen, ta_in ? 0 :
102 (data->usb_in ? 0 : 1)); 106 (data->usb_in ? 0 : 1));
103 107
@@ -122,7 +126,7 @@ static irqreturn_t max8903_dcin(int irq, void *_data)
122static irqreturn_t max8903_usbin(int irq, void *_data) 126static irqreturn_t max8903_usbin(int irq, void *_data)
123{ 127{
124 struct max8903_data *data = _data; 128 struct max8903_data *data = _data;
125 struct max8903_pdata *pdata = &data->pdata; 129 struct max8903_pdata *pdata = data->pdata;
126 bool usb_in; 130 bool usb_in;
127 enum power_supply_type old_type; 131 enum power_supply_type old_type;
128 132
@@ -136,7 +140,7 @@ static irqreturn_t max8903_usbin(int irq, void *_data)
136 /* Do not touch Current-Limit-Mode */ 140 /* Do not touch Current-Limit-Mode */
137 141
138 /* Charger Enable / Disable (cen is negated) */ 142 /* Charger Enable / Disable (cen is negated) */
139 if (pdata->cen) 143 if (gpio_is_valid(pdata->cen))
140 gpio_set_value(pdata->cen, usb_in ? 0 : 144 gpio_set_value(pdata->cen, usb_in ? 0 :
141 (data->ta_in ? 0 : 1)); 145 (data->ta_in ? 0 : 1));
142 146
@@ -161,7 +165,7 @@ static irqreturn_t max8903_usbin(int irq, void *_data)
161static irqreturn_t max8903_fault(int irq, void *_data) 165static irqreturn_t max8903_fault(int irq, void *_data)
162{ 166{
163 struct max8903_data *data = _data; 167 struct max8903_data *data = _data;
164 struct max8903_pdata *pdata = &data->pdata; 168 struct max8903_pdata *pdata = data->pdata;
165 bool fault; 169 bool fault;
166 170
167 fault = gpio_get_value(pdata->flt) ? false : true; 171 fault = gpio_get_value(pdata->flt) ? false : true;
@@ -179,57 +183,109 @@ static irqreturn_t max8903_fault(int irq, void *_data)
179 return IRQ_HANDLED; 183 return IRQ_HANDLED;
180} 184}
181 185
182static int max8903_probe(struct platform_device *pdev) 186static struct max8903_pdata *max8903_parse_dt_data(struct device *dev)
183{ 187{
184 struct max8903_data *data; 188 struct device_node *np = dev->of_node;
189 struct max8903_pdata *pdata = NULL;
190
191 if (!np)
192 return NULL;
193
194 pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
195 if (!pdata)
196 return NULL;
197
198 pdata->dc_valid = false;
199 pdata->usb_valid = false;
200
201 pdata->cen = of_get_named_gpio(np, "cen-gpios", 0);
202 if (!gpio_is_valid(pdata->cen))
203 pdata->cen = -EINVAL;
204
205 pdata->chg = of_get_named_gpio(np, "chg-gpios", 0);
206 if (!gpio_is_valid(pdata->chg))
207 pdata->chg = -EINVAL;
208
209 pdata->flt = of_get_named_gpio(np, "flt-gpios", 0);
210 if (!gpio_is_valid(pdata->flt))
211 pdata->flt = -EINVAL;
212
213 pdata->usus = of_get_named_gpio(np, "usus-gpios", 0);
214 if (!gpio_is_valid(pdata->usus))
215 pdata->usus = -EINVAL;
216
217 pdata->dcm = of_get_named_gpio(np, "dcm-gpios", 0);
218 if (!gpio_is_valid(pdata->dcm))
219 pdata->dcm = -EINVAL;
220
221 pdata->dok = of_get_named_gpio(np, "dok-gpios", 0);
222 if (!gpio_is_valid(pdata->dok))
223 pdata->dok = -EINVAL;
224 else
225 pdata->dc_valid = true;
226
227 pdata->uok = of_get_named_gpio(np, "uok-gpios", 0);
228 if (!gpio_is_valid(pdata->uok))
229 pdata->uok = -EINVAL;
230 else
231 pdata->usb_valid = true;
232
233 return pdata;
234}
235
236static int max8903_setup_gpios(struct platform_device *pdev)
237{
238 struct max8903_data *data = platform_get_drvdata(pdev);
185 struct device *dev = &pdev->dev; 239 struct device *dev = &pdev->dev;
186 struct max8903_pdata *pdata = pdev->dev.platform_data; 240 struct max8903_pdata *pdata = pdev->dev.platform_data;
187 struct power_supply_config psy_cfg = {};
188 int ret = 0; 241 int ret = 0;
189 int gpio; 242 int gpio;
190 int ta_in = 0; 243 int ta_in = 0;
191 int usb_in = 0; 244 int usb_in = 0;
192 245
193 data = devm_kzalloc(dev, sizeof(struct max8903_data), GFP_KERNEL);
194 if (data == NULL) {
195 dev_err(dev, "Cannot allocate memory.\n");
196 return -ENOMEM;
197 }
198 memcpy(&data->pdata, pdata, sizeof(struct max8903_pdata));
199 data->dev = dev;
200 platform_set_drvdata(pdev, data);
201
202 if (pdata->dc_valid == false && pdata->usb_valid == false) {
203 dev_err(dev, "No valid power sources.\n");
204 return -EINVAL;
205 }
206
207 if (pdata->dc_valid) { 246 if (pdata->dc_valid) {
208 if (pdata->dok && gpio_is_valid(pdata->dok) && 247 if (gpio_is_valid(pdata->dok)) {
209 pdata->dcm && gpio_is_valid(pdata->dcm)) { 248 ret = devm_gpio_request(dev, pdata->dok,
249 data->psy_desc.name);
250 if (ret) {
251 dev_err(dev,
252 "Failed GPIO request for dok: %d err %d\n",
253 pdata->dok, ret);
254 return ret;
255 }
256
210 gpio = pdata->dok; /* PULL_UPed Interrupt */ 257 gpio = pdata->dok; /* PULL_UPed Interrupt */
211 ta_in = gpio_get_value(gpio) ? 0 : 1; 258 ta_in = gpio_get_value(gpio) ? 0 : 1;
212
213 gpio = pdata->dcm; /* Output */
214 gpio_set_value(gpio, ta_in);
215 } else { 259 } else {
216 dev_err(dev, "When DC is wired, DOK and DCM should" 260 dev_err(dev, "When DC is wired, DOK should be wired as well.\n");
217 " be wired as well.\n");
218 return -EINVAL; 261 return -EINVAL;
219 } 262 }
220 } else { 263 }
221 if (pdata->dcm) { 264
222 if (gpio_is_valid(pdata->dcm)) 265 if (gpio_is_valid(pdata->dcm)) {
223 gpio_set_value(pdata->dcm, 0); 266 ret = devm_gpio_request(dev, pdata->dcm, data->psy_desc.name);
224 else { 267 if (ret) {
225 dev_err(dev, "Invalid pin: dcm.\n"); 268 dev_err(dev,
226 return -EINVAL; 269 "Failed GPIO request for dcm: %d err %d\n",
227 } 270 pdata->dcm, ret);
271 return ret;
228 } 272 }
273
274 gpio = pdata->dcm; /* Output */
275 gpio_set_value(gpio, ta_in);
229 } 276 }
230 277
231 if (pdata->usb_valid) { 278 if (pdata->usb_valid) {
232 if (pdata->uok && gpio_is_valid(pdata->uok)) { 279 if (gpio_is_valid(pdata->uok)) {
280 ret = devm_gpio_request(dev, pdata->uok,
281 data->psy_desc.name);
282 if (ret) {
283 dev_err(dev,
284 "Failed GPIO request for uok: %d err %d\n",
285 pdata->uok, ret);
286 return ret;
287 }
288
233 gpio = pdata->uok; 289 gpio = pdata->uok;
234 usb_in = gpio_get_value(gpio) ? 0 : 1; 290 usb_in = gpio_get_value(gpio) ? 0 : 1;
235 } else { 291 } else {
@@ -239,33 +295,45 @@ static int max8903_probe(struct platform_device *pdev)
239 } 295 }
240 } 296 }
241 297
242 if (pdata->cen) { 298 if (gpio_is_valid(pdata->cen)) {
243 if (gpio_is_valid(pdata->cen)) { 299 ret = devm_gpio_request(dev, pdata->cen, data->psy_desc.name);
244 gpio_set_value(pdata->cen, (ta_in || usb_in) ? 0 : 1); 300 if (ret) {
245 } else { 301 dev_err(dev,
246 dev_err(dev, "Invalid pin: cen.\n"); 302 "Failed GPIO request for cen: %d err %d\n",
247 return -EINVAL; 303 pdata->cen, ret);
304 return ret;
248 } 305 }
306
307 gpio_set_value(pdata->cen, (ta_in || usb_in) ? 0 : 1);
249 } 308 }
250 309
251 if (pdata->chg) { 310 if (gpio_is_valid(pdata->chg)) {
252 if (!gpio_is_valid(pdata->chg)) { 311 ret = devm_gpio_request(dev, pdata->chg, data->psy_desc.name);
253 dev_err(dev, "Invalid pin: chg.\n"); 312 if (ret) {
254 return -EINVAL; 313 dev_err(dev,
314 "Failed GPIO request for chg: %d err %d\n",
315 pdata->chg, ret);
316 return ret;
255 } 317 }
256 } 318 }
257 319
258 if (pdata->flt) { 320 if (gpio_is_valid(pdata->flt)) {
259 if (!gpio_is_valid(pdata->flt)) { 321 ret = devm_gpio_request(dev, pdata->flt, data->psy_desc.name);
260 dev_err(dev, "Invalid pin: flt.\n"); 322 if (ret) {
261 return -EINVAL; 323 dev_err(dev,
324 "Failed GPIO request for flt: %d err %d\n",
325 pdata->flt, ret);
326 return ret;
262 } 327 }
263 } 328 }
264 329
265 if (pdata->usus) { 330 if (gpio_is_valid(pdata->usus)) {
266 if (!gpio_is_valid(pdata->usus)) { 331 ret = devm_gpio_request(dev, pdata->usus, data->psy_desc.name);
267 dev_err(dev, "Invalid pin: usus.\n"); 332 if (ret) {
268 return -EINVAL; 333 dev_err(dev,
334 "Failed GPIO request for usus: %d err %d\n",
335 pdata->usus, ret);
336 return ret;
269 } 337 }
270 } 338 }
271 339
@@ -273,14 +341,52 @@ static int max8903_probe(struct platform_device *pdev)
273 data->ta_in = ta_in; 341 data->ta_in = ta_in;
274 data->usb_in = usb_in; 342 data->usb_in = usb_in;
275 343
344 return 0;
345}
346
347static int max8903_probe(struct platform_device *pdev)
348{
349 struct max8903_data *data;
350 struct device *dev = &pdev->dev;
351 struct max8903_pdata *pdata = pdev->dev.platform_data;
352 struct power_supply_config psy_cfg = {};
353 int ret = 0;
354
355 data = devm_kzalloc(dev, sizeof(struct max8903_data), GFP_KERNEL);
356 if (!data)
357 return -ENOMEM;
358
359 if (IS_ENABLED(CONFIG_OF) && !pdata && dev->of_node)
360 pdata = max8903_parse_dt_data(dev);
361
362 if (!pdata) {
363 dev_err(dev, "No platform data.\n");
364 return -EINVAL;
365 }
366
367 pdev->dev.platform_data = pdata;
368 data->pdata = pdata;
369 data->dev = dev;
370 platform_set_drvdata(pdev, data);
371
372 if (pdata->dc_valid == false && pdata->usb_valid == false) {
373 dev_err(dev, "No valid power sources.\n");
374 return -EINVAL;
375 }
376
377 ret = max8903_setup_gpios(pdev);
378 if (ret)
379 return ret;
380
276 data->psy_desc.name = "max8903_charger"; 381 data->psy_desc.name = "max8903_charger";
277 data->psy_desc.type = (ta_in) ? POWER_SUPPLY_TYPE_MAINS : 382 data->psy_desc.type = (data->ta_in) ? POWER_SUPPLY_TYPE_MAINS :
278 ((usb_in) ? POWER_SUPPLY_TYPE_USB : 383 ((data->usb_in) ? POWER_SUPPLY_TYPE_USB :
279 POWER_SUPPLY_TYPE_BATTERY); 384 POWER_SUPPLY_TYPE_BATTERY);
280 data->psy_desc.get_property = max8903_get_property; 385 data->psy_desc.get_property = max8903_get_property;
281 data->psy_desc.properties = max8903_charger_props; 386 data->psy_desc.properties = max8903_charger_props;
282 data->psy_desc.num_properties = ARRAY_SIZE(max8903_charger_props); 387 data->psy_desc.num_properties = ARRAY_SIZE(max8903_charger_props);
283 388
389 psy_cfg.of_node = dev->of_node;
284 psy_cfg.drv_data = data; 390 psy_cfg.drv_data = data;
285 391
286 data->psy = devm_power_supply_register(dev, &data->psy_desc, &psy_cfg); 392 data->psy = devm_power_supply_register(dev, &data->psy_desc, &psy_cfg);
@@ -315,7 +421,7 @@ static int max8903_probe(struct platform_device *pdev)
315 } 421 }
316 } 422 }
317 423
318 if (pdata->flt) { 424 if (gpio_is_valid(pdata->flt)) {
319 ret = devm_request_threaded_irq(dev, gpio_to_irq(pdata->flt), 425 ret = devm_request_threaded_irq(dev, gpio_to_irq(pdata->flt),
320 NULL, max8903_fault, 426 NULL, max8903_fault,
321 IRQF_TRIGGER_FALLING | 427 IRQF_TRIGGER_FALLING |
@@ -331,10 +437,17 @@ static int max8903_probe(struct platform_device *pdev)
331 return 0; 437 return 0;
332} 438}
333 439
440static const struct of_device_id max8903_match_ids[] = {
441 { .compatible = "maxim,max8903", },
442 { /* sentinel */ }
443};
444MODULE_DEVICE_TABLE(of, max8903_match_ids);
445
334static struct platform_driver max8903_driver = { 446static struct platform_driver max8903_driver = {
335 .probe = max8903_probe, 447 .probe = max8903_probe,
336 .driver = { 448 .driver = {
337 .name = "max8903-charger", 449 .name = "max8903-charger",
450 .of_match_table = max8903_match_ids
338 }, 451 },
339}; 452};
340 453
diff --git a/drivers/power/power_supply_core.c b/drivers/power/power_supply_core.c
index b13cd074c52a..a74d8ca383a1 100644
--- a/drivers/power/power_supply_core.c
+++ b/drivers/power/power_supply_core.c
@@ -491,8 +491,11 @@ int power_supply_get_property(struct power_supply *psy,
491 enum power_supply_property psp, 491 enum power_supply_property psp,
492 union power_supply_propval *val) 492 union power_supply_propval *val)
493{ 493{
494 if (atomic_read(&psy->use_cnt) <= 0) 494 if (atomic_read(&psy->use_cnt) <= 0) {
495 if (!psy->initialized)
496 return -EAGAIN;
495 return -ENODEV; 497 return -ENODEV;
498 }
496 499
497 return psy->desc->get_property(psy, psp, val); 500 return psy->desc->get_property(psy, psp, val);
498} 501}
@@ -785,6 +788,7 @@ __power_supply_register(struct device *parent,
785 * after calling power_supply_register()). 788 * after calling power_supply_register()).
786 */ 789 */
787 atomic_inc(&psy->use_cnt); 790 atomic_inc(&psy->use_cnt);
791 psy->initialized = true;
788 792
789 queue_delayed_work(system_power_efficient_wq, 793 queue_delayed_work(system_power_efficient_wq,
790 &psy->deferred_register_work, 794 &psy->deferred_register_work,
diff --git a/drivers/power/power_supply_sysfs.c b/drivers/power/power_supply_sysfs.c
index 80fed98832f9..bcde8d13476a 100644
--- a/drivers/power/power_supply_sysfs.c
+++ b/drivers/power/power_supply_sysfs.c
@@ -83,7 +83,7 @@ static ssize_t power_supply_show_property(struct device *dev,
83 if (ret == -ENODATA) 83 if (ret == -ENODATA)
84 dev_dbg(dev, "driver has no data for `%s' property\n", 84 dev_dbg(dev, "driver has no data for `%s' property\n",
85 attr->attr.name); 85 attr->attr.name);
86 else if (ret != -ENODEV) 86 else if (ret != -ENODEV && ret != -EAGAIN)
87 dev_err(dev, "driver failed to report `%s' property: %zd\n", 87 dev_err(dev, "driver failed to report `%s' property: %zd\n",
88 attr->attr.name, ret); 88 attr->attr.name, ret);
89 return ret; 89 return ret;
diff --git a/drivers/power/qcom_smbb.c b/drivers/power/qcom_smbb.c
index 5eb1e9e543e2..b5896ba2a602 100644
--- a/drivers/power/qcom_smbb.c
+++ b/drivers/power/qcom_smbb.c
@@ -34,6 +34,7 @@
34#include <linux/power_supply.h> 34#include <linux/power_supply.h>
35#include <linux/regmap.h> 35#include <linux/regmap.h>
36#include <linux/slab.h> 36#include <linux/slab.h>
37#include <linux/extcon.h>
37 38
38#define SMBB_CHG_VMAX 0x040 39#define SMBB_CHG_VMAX 0x040
39#define SMBB_CHG_VSAFE 0x041 40#define SMBB_CHG_VSAFE 0x041
@@ -111,6 +112,7 @@ struct smbb_charger {
111 unsigned int revision; 112 unsigned int revision;
112 unsigned int addr; 113 unsigned int addr;
113 struct device *dev; 114 struct device *dev;
115 struct extcon_dev *edev;
114 116
115 bool dc_disabled; 117 bool dc_disabled;
116 bool jeita_ext_temp; 118 bool jeita_ext_temp;
@@ -125,6 +127,11 @@ struct smbb_charger {
125 struct regmap *regmap; 127 struct regmap *regmap;
126}; 128};
127 129
130static const unsigned int smbb_usb_extcon_cable[] = {
131 EXTCON_USB,
132 EXTCON_NONE,
133};
134
128static int smbb_vbat_weak_fn(unsigned int index) 135static int smbb_vbat_weak_fn(unsigned int index)
129{ 136{
130 return 2100000 + index * 100000; 137 return 2100000 + index * 100000;
@@ -371,6 +378,8 @@ static irqreturn_t smbb_usb_valid_handler(int irq, void *_data)
371 struct smbb_charger *chg = _data; 378 struct smbb_charger *chg = _data;
372 379
373 smbb_set_line_flag(chg, irq, STATUS_USBIN_VALID); 380 smbb_set_line_flag(chg, irq, STATUS_USBIN_VALID);
381 extcon_set_cable_state_(chg->edev, EXTCON_USB,
382 chg->status & STATUS_USBIN_VALID);
374 power_supply_changed(chg->usb_psy); 383 power_supply_changed(chg->usb_psy);
375 384
376 return IRQ_HANDLED; 385 return IRQ_HANDLED;
@@ -849,6 +858,18 @@ static int smbb_charger_probe(struct platform_device *pdev)
849 return PTR_ERR(chg->usb_psy); 858 return PTR_ERR(chg->usb_psy);
850 } 859 }
851 860
861 chg->edev = devm_extcon_dev_allocate(&pdev->dev, smbb_usb_extcon_cable);
862 if (IS_ERR(chg->edev)) {
863 dev_err(&pdev->dev, "failed to allocate extcon device\n");
864 return -ENOMEM;
865 }
866
867 rc = devm_extcon_dev_register(&pdev->dev, chg->edev);
868 if (rc < 0) {
869 dev_err(&pdev->dev, "failed to register extcon device\n");
870 return rc;
871 }
872
852 if (!chg->dc_disabled) { 873 if (!chg->dc_disabled) {
853 dc_cfg.drv_data = chg; 874 dc_cfg.drv_data = chg;
854 dc_cfg.supplied_to = smbb_bif; 875 dc_cfg.supplied_to = smbb_bif;
diff --git a/drivers/power/reset/Kconfig b/drivers/power/reset/Kconfig
index 9bb2622c23bf..7053abced0bc 100644
--- a/drivers/power/reset/Kconfig
+++ b/drivers/power/reset/Kconfig
@@ -148,7 +148,8 @@ config POWER_RESET_XGENE
148 148
149config POWER_RESET_KEYSTONE 149config POWER_RESET_KEYSTONE
150 bool "Keystone reset driver" 150 bool "Keystone reset driver"
151 depends on ARCH_KEYSTONE 151 depends on ARCH_KEYSTONE || COMPILE_TEST
152 depends on HAS_IOMEM
152 select MFD_SYSCON 153 select MFD_SYSCON
153 help 154 help
154 Reboot support for the KEYSTONE SoCs. 155 Reboot support for the KEYSTONE SoCs.
@@ -183,5 +184,19 @@ config POWER_RESET_ZX
183 help 184 help
184 Reboot support for ZTE SoCs. 185 Reboot support for ZTE SoCs.
185 186
187config REBOOT_MODE
188 tristate
189
190config SYSCON_REBOOT_MODE
191 tristate "Generic SYSCON regmap reboot mode driver"
192 depends on OF
193 select REBOOT_MODE
194 select MFD_SYSCON
195 help
196 Say y here will enable reboot mode driver. This will
197 get reboot mode arguments and store it in SYSCON mapped
198 register, then the bootloader can read it to take different
199 action according to the mode.
200
186endif 201endif
187 202
diff --git a/drivers/power/reset/Makefile b/drivers/power/reset/Makefile
index ab7aa8614d1f..d6b2560d5c4a 100644
--- a/drivers/power/reset/Makefile
+++ b/drivers/power/reset/Makefile
@@ -21,3 +21,5 @@ obj-$(CONFIG_POWER_RESET_SYSCON) += syscon-reboot.o
21obj-$(CONFIG_POWER_RESET_SYSCON_POWEROFF) += syscon-poweroff.o 21obj-$(CONFIG_POWER_RESET_SYSCON_POWEROFF) += syscon-poweroff.o
22obj-$(CONFIG_POWER_RESET_RMOBILE) += rmobile-reset.o 22obj-$(CONFIG_POWER_RESET_RMOBILE) += rmobile-reset.o
23obj-$(CONFIG_POWER_RESET_ZX) += zx-reboot.o 23obj-$(CONFIG_POWER_RESET_ZX) += zx-reboot.o
24obj-$(CONFIG_REBOOT_MODE) += reboot-mode.o
25obj-$(CONFIG_SYSCON_REBOOT_MODE) += syscon-reboot-mode.o
diff --git a/drivers/power/reset/reboot-mode.c b/drivers/power/reset/reboot-mode.c
new file mode 100644
index 000000000000..2dfbbce0f817
--- /dev/null
+++ b/drivers/power/reset/reboot-mode.c
@@ -0,0 +1,140 @@
1/*
2 * Copyright (c) 2016, Fuzhou Rockchip Electronics Co., Ltd
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 */
9
10#include <linux/device.h>
11#include <linux/init.h>
12#include <linux/kernel.h>
13#include <linux/module.h>
14#include <linux/of.h>
15#include <linux/reboot.h>
16#include "reboot-mode.h"
17
18#define PREFIX "mode-"
19
20struct mode_info {
21 const char *mode;
22 u32 magic;
23 struct list_head list;
24};
25
26static unsigned int get_reboot_mode_magic(struct reboot_mode_driver *reboot,
27 const char *cmd)
28{
29 const char *normal = "normal";
30 int magic = 0;
31 struct mode_info *info;
32
33 if (!cmd)
34 cmd = normal;
35
36 list_for_each_entry(info, &reboot->head, list) {
37 if (!strcmp(info->mode, cmd)) {
38 magic = info->magic;
39 break;
40 }
41 }
42
43 return magic;
44}
45
46static int reboot_mode_notify(struct notifier_block *this,
47 unsigned long mode, void *cmd)
48{
49 struct reboot_mode_driver *reboot;
50 unsigned int magic;
51
52 reboot = container_of(this, struct reboot_mode_driver, reboot_notifier);
53 magic = get_reboot_mode_magic(reboot, cmd);
54 if (magic)
55 reboot->write(reboot, magic);
56
57 return NOTIFY_DONE;
58}
59
60/**
61 * reboot_mode_register - register a reboot mode driver
62 * @reboot: reboot mode driver
63 *
64 * Returns: 0 on success or a negative error code on failure.
65 */
66int reboot_mode_register(struct reboot_mode_driver *reboot)
67{
68 struct mode_info *info;
69 struct property *prop;
70 struct device_node *np = reboot->dev->of_node;
71 size_t len = strlen(PREFIX);
72 int ret;
73
74 INIT_LIST_HEAD(&reboot->head);
75
76 for_each_property_of_node(np, prop) {
77 if (strncmp(prop->name, PREFIX, len))
78 continue;
79
80 info = devm_kzalloc(reboot->dev, sizeof(*info), GFP_KERNEL);
81 if (!info) {
82 ret = -ENOMEM;
83 goto error;
84 }
85
86 if (of_property_read_u32(np, prop->name, &info->magic)) {
87 dev_err(reboot->dev, "reboot mode %s without magic number\n",
88 info->mode);
89 devm_kfree(reboot->dev, info);
90 continue;
91 }
92
93 info->mode = kstrdup_const(prop->name + len, GFP_KERNEL);
94 if (!info->mode) {
95 ret = -ENOMEM;
96 goto error;
97 } else if (info->mode[0] == '\0') {
98 kfree_const(info->mode);
99 ret = -EINVAL;
100 dev_err(reboot->dev, "invalid mode name(%s): too short!\n",
101 prop->name);
102 goto error;
103 }
104
105 list_add_tail(&info->list, &reboot->head);
106 }
107
108 reboot->reboot_notifier.notifier_call = reboot_mode_notify;
109 register_reboot_notifier(&reboot->reboot_notifier);
110
111 return 0;
112
113error:
114 list_for_each_entry(info, &reboot->head, list)
115 kfree_const(info->mode);
116
117 return ret;
118}
119EXPORT_SYMBOL_GPL(reboot_mode_register);
120
121/**
122 * reboot_mode_unregister - unregister a reboot mode driver
123 * @reboot: reboot mode driver
124 */
125int reboot_mode_unregister(struct reboot_mode_driver *reboot)
126{
127 struct mode_info *info;
128
129 unregister_reboot_notifier(&reboot->reboot_notifier);
130
131 list_for_each_entry(info, &reboot->head, list)
132 kfree_const(info->mode);
133
134 return 0;
135}
136EXPORT_SYMBOL_GPL(reboot_mode_unregister);
137
138MODULE_AUTHOR("Andy Yan <andy.yan@rock-chips.com");
139MODULE_DESCRIPTION("System reboot mode core library");
140MODULE_LICENSE("GPL v2");
diff --git a/drivers/power/reset/reboot-mode.h b/drivers/power/reset/reboot-mode.h
new file mode 100644
index 000000000000..2491bb71f591
--- /dev/null
+++ b/drivers/power/reset/reboot-mode.h
@@ -0,0 +1,14 @@
1#ifndef __REBOOT_MODE_H__
2#define __REBOOT_MODE_H__
3
4struct reboot_mode_driver {
5 struct device *dev;
6 struct list_head head;
7 int (*write)(struct reboot_mode_driver *reboot, unsigned int magic);
8 struct notifier_block reboot_notifier;
9};
10
11int reboot_mode_register(struct reboot_mode_driver *reboot);
12int reboot_mode_unregister(struct reboot_mode_driver *reboot);
13
14#endif
diff --git a/drivers/power/reset/syscon-poweroff.c b/drivers/power/reset/syscon-poweroff.c
index 5560b0dbc180..b68338399e5e 100644
--- a/drivers/power/reset/syscon-poweroff.c
+++ b/drivers/power/reset/syscon-poweroff.c
@@ -30,7 +30,7 @@ static struct regmap *map;
30static u32 offset; 30static u32 offset;
31static u32 mask; 31static u32 mask;
32 32
33void syscon_poweroff(void) 33static void syscon_poweroff(void)
34{ 34{
35 /* Issue the poweroff */ 35 /* Issue the poweroff */
36 regmap_write(map, offset, mask); 36 regmap_write(map, offset, mask);
diff --git a/drivers/power/reset/syscon-reboot-mode.c b/drivers/power/reset/syscon-reboot-mode.c
new file mode 100644
index 000000000000..9e1cba5dd58e
--- /dev/null
+++ b/drivers/power/reset/syscon-reboot-mode.c
@@ -0,0 +1,99 @@
1/*
2 * Copyright (c) 2016, Fuzhou Rockchip Electronics Co., Ltd
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 */
9
10#include <linux/init.h>
11#include <linux/module.h>
12#include <linux/kernel.h>
13#include <linux/of.h>
14#include <linux/platform_device.h>
15#include <linux/reboot.h>
16#include <linux/regmap.h>
17#include <linux/mfd/syscon.h>
18#include "reboot-mode.h"
19
20struct syscon_reboot_mode {
21 struct regmap *map;
22 struct reboot_mode_driver reboot;
23 u32 offset;
24 u32 mask;
25};
26
27static int syscon_reboot_mode_write(struct reboot_mode_driver *reboot,
28 unsigned int magic)
29{
30 struct syscon_reboot_mode *syscon_rbm;
31 int ret;
32
33 syscon_rbm = container_of(reboot, struct syscon_reboot_mode, reboot);
34
35 ret = regmap_update_bits(syscon_rbm->map, syscon_rbm->offset,
36 syscon_rbm->mask, magic);
37 if (ret < 0)
38 dev_err(reboot->dev, "update reboot mode bits failed\n");
39
40 return ret;
41}
42
43static int syscon_reboot_mode_probe(struct platform_device *pdev)
44{
45 int ret;
46 struct syscon_reboot_mode *syscon_rbm;
47
48 syscon_rbm = devm_kzalloc(&pdev->dev, sizeof(*syscon_rbm), GFP_KERNEL);
49 if (!syscon_rbm)
50 return -ENOMEM;
51
52 syscon_rbm->reboot.dev = &pdev->dev;
53 syscon_rbm->reboot.write = syscon_reboot_mode_write;
54 syscon_rbm->mask = 0xffffffff;
55
56 dev_set_drvdata(&pdev->dev, syscon_rbm);
57
58 syscon_rbm->map = syscon_node_to_regmap(pdev->dev.parent->of_node);
59 if (IS_ERR(syscon_rbm->map))
60 return PTR_ERR(syscon_rbm->map);
61
62 if (of_property_read_u32(pdev->dev.of_node, "offset",
63 &syscon_rbm->offset))
64 return -EINVAL;
65
66 of_property_read_u32(pdev->dev.of_node, "mask", &syscon_rbm->mask);
67
68 ret = reboot_mode_register(&syscon_rbm->reboot);
69 if (ret)
70 dev_err(&pdev->dev, "can't register reboot mode\n");
71
72 return ret;
73}
74
75static int syscon_reboot_mode_remove(struct platform_device *pdev)
76{
77 struct syscon_reboot_mode *syscon_rbm = dev_get_drvdata(&pdev->dev);
78
79 return reboot_mode_unregister(&syscon_rbm->reboot);
80}
81
82static const struct of_device_id syscon_reboot_mode_of_match[] = {
83 { .compatible = "syscon-reboot-mode" },
84 {}
85};
86
87static struct platform_driver syscon_reboot_mode_driver = {
88 .probe = syscon_reboot_mode_probe,
89 .remove = syscon_reboot_mode_remove,
90 .driver = {
91 .name = "syscon-reboot-mode",
92 .of_match_table = syscon_reboot_mode_of_match,
93 },
94};
95module_platform_driver(syscon_reboot_mode_driver);
96
97MODULE_AUTHOR("Andy Yan <andy.yan@rock-chips.com");
98MODULE_DESCRIPTION("SYSCON reboot mode driver");
99MODULE_LICENSE("GPL v2");
diff --git a/include/linux/power/max8903_charger.h b/include/linux/power/max8903_charger.h
index 24f51db8a83f..89d3f1cb3433 100644
--- a/include/linux/power/max8903_charger.h
+++ b/include/linux/power/max8903_charger.h
@@ -26,8 +26,8 @@
26struct max8903_pdata { 26struct max8903_pdata {
27 /* 27 /*
28 * GPIOs 28 * GPIOs
29 * cen, chg, flt, and usus are optional. 29 * cen, chg, flt, dcm and usus are optional.
30 * dok, dcm, and uok are not optional depending on the status of 30 * dok and uok are not optional depending on the status of
31 * dc_valid and usb_valid. 31 * dc_valid and usb_valid.
32 */ 32 */
33 int cen; /* Charger Enable input */ 33 int cen; /* Charger Enable input */
@@ -41,7 +41,7 @@ struct max8903_pdata {
41 /* 41 /*
42 * DC(Adapter/TA) is wired 42 * DC(Adapter/TA) is wired
43 * When dc_valid is true, 43 * When dc_valid is true,
44 * dok and dcm should be valid. 44 * dok should be valid.
45 * 45 *
46 * At least one of dc_valid or usb_valid should be true. 46 * At least one of dc_valid or usb_valid should be true.
47 */ 47 */
diff --git a/include/linux/power_supply.h b/include/linux/power_supply.h
index 751061790626..3965503315ef 100644
--- a/include/linux/power_supply.h
+++ b/include/linux/power_supply.h
@@ -248,6 +248,7 @@ struct power_supply {
248 struct delayed_work deferred_register_work; 248 struct delayed_work deferred_register_work;
249 spinlock_t changed_lock; 249 spinlock_t changed_lock;
250 bool changed; 250 bool changed;
251 bool initialized;
251 atomic_t use_cnt; 252 atomic_t use_cnt;
252#ifdef CONFIG_THERMAL 253#ifdef CONFIG_THERMAL
253 struct thermal_zone_device *tzd; 254 struct thermal_zone_device *tzd;