From 6c1d7a1c77e98ff53cd58687251c13c5985024ab Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Mon, 6 May 2013 13:16:30 +0900 Subject: [PATCH 01/25] 88pm860x_battery: Remove unnecessary platform_set_drvdata() The driver core clears the driver data to NULL after device_release or on probe failure, since commit 0998d0631001288a5974afc0b2a5f568bcdecb4d (device-core: Ensure drvdata = NULL when no driver is bound). Thus, it is not needed to manually clear the device driver data to NULL. Signed-off-by: Jingoo Han Signed-off-by: Anton Vorontsov --- drivers/power/88pm860x_battery.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/power/88pm860x_battery.c b/drivers/power/88pm860x_battery.c index d338c1c4e8c8..dfcda3a49403 100644 --- a/drivers/power/88pm860x_battery.c +++ b/drivers/power/88pm860x_battery.c @@ -992,7 +992,6 @@ static int pm860x_battery_remove(struct platform_device *pdev) free_irq(info->irq_batt, info); free_irq(info->irq_cc, info); power_supply_unregister(&info->battery); - platform_set_drvdata(pdev, NULL); return 0; } From 71c29b3a89ea49c1f07c85518a9e75bf530673cd Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Mon, 6 May 2013 13:17:24 +0900 Subject: [PATCH 02/25] 88pm860x_charger: Remove unnecessary platform_set_drvdata() The driver core clears the driver data to NULL after device_release or on probe failure, since commit 0998d0631001288a5974afc0b2a5f568bcdecb4d (device-core: Ensure drvdata = NULL when no driver is bound). Thus, it is not needed to manually clear the device driver data to NULL. Signed-off-by: Jingoo Han Signed-off-by: Anton Vorontsov --- drivers/power/88pm860x_charger.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/power/88pm860x_charger.c b/drivers/power/88pm860x_charger.c index 36fb4b5a4b0d..ffff66b1c1aa 100644 --- a/drivers/power/88pm860x_charger.c +++ b/drivers/power/88pm860x_charger.c @@ -722,7 +722,6 @@ static int pm860x_charger_remove(struct platform_device *pdev) struct pm860x_charger_info *info = platform_get_drvdata(pdev); int i; - platform_set_drvdata(pdev, NULL); power_supply_unregister(&info->usb); free_irq(info->irq[0], info); for (i = 0; i < info->irq_nums; i++) From ddeeb8f973bbe3bebac78e78c234ff18bfb00bf0 Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Mon, 6 May 2013 13:20:15 +0900 Subject: [PATCH 03/25] ab8500_bm: Remove unnecessary platform_set_drvdata() The driver core clears the driver data to NULL after device_release or on probe failure, since commit 0998d0631001288a5974afc0b2a5f568bcdecb4d (device-core: Ensure drvdata = NULL when no driver is bound). Thus, it is not needed to manually clear the device driver data to NULL. Signed-off-by: Jingoo Han Acked-by: Lee Jones Signed-off-by: Anton Vorontsov --- drivers/power/ab8500_btemp.c | 1 - drivers/power/ab8500_charger.c | 2 -- drivers/power/ab8500_fg.c | 1 - drivers/power/abx500_chargalg.c | 1 - 4 files changed, 5 deletions(-) diff --git a/drivers/power/ab8500_btemp.c b/drivers/power/ab8500_btemp.c index d412d34bf3df..7f9a4547dccd 100644 --- a/drivers/power/ab8500_btemp.c +++ b/drivers/power/ab8500_btemp.c @@ -1045,7 +1045,6 @@ static int ab8500_btemp_remove(struct platform_device *pdev) flush_scheduled_work(); power_supply_unregister(&di->btemp_psy); - platform_set_drvdata(pdev, NULL); return 0; } diff --git a/drivers/power/ab8500_charger.c b/drivers/power/ab8500_charger.c index a558318b169c..f098fdafee9f 100644 --- a/drivers/power/ab8500_charger.c +++ b/drivers/power/ab8500_charger.c @@ -3425,8 +3425,6 @@ static int ab8500_charger_remove(struct platform_device *pdev) if (di->ac_chg.enabled && !di->ac_chg.external) power_supply_unregister(&di->ac_chg.psy); - platform_set_drvdata(pdev, NULL); - return 0; } diff --git a/drivers/power/ab8500_fg.c b/drivers/power/ab8500_fg.c index c5391f5c372d..1263638b102d 100644 --- a/drivers/power/ab8500_fg.c +++ b/drivers/power/ab8500_fg.c @@ -3070,7 +3070,6 @@ static int ab8500_fg_remove(struct platform_device *pdev) flush_scheduled_work(); ab8500_fg_sysfs_psy_remove_attrs(di->fg_psy.dev); power_supply_unregister(&di->fg_psy); - platform_set_drvdata(pdev, NULL); return ret; } diff --git a/drivers/power/abx500_chargalg.c b/drivers/power/abx500_chargalg.c index 9863e423602c..6d2723664a01 100644 --- a/drivers/power/abx500_chargalg.c +++ b/drivers/power/abx500_chargalg.c @@ -2035,7 +2035,6 @@ static int abx500_chargalg_remove(struct platform_device *pdev) destroy_workqueue(di->chargalg_wq); power_supply_unregister(&di->chargalg_psy); - platform_set_drvdata(pdev, NULL); return 0; } From 30cf74b94166b2cdeaa8e0439161e339f17e1012 Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Mon, 6 May 2013 13:21:16 +0900 Subject: [PATCH 04/25] bq27x00_battery: Remove unnecessary platform_set_drvdata() The driver core clears the driver data to NULL after device_release or on probe failure, since commit 0998d0631001288a5974afc0b2a5f568bcdecb4d (device-core: Ensure drvdata = NULL when no driver is bound). Thus, it is not needed to manually clear the device driver data to NULL. Signed-off-by: Jingoo Han Signed-off-by: Anton Vorontsov --- drivers/power/bq27x00_battery.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/power/bq27x00_battery.c b/drivers/power/bq27x00_battery.c index 26037ca7efb4..b309713b63bc 100644 --- a/drivers/power/bq27x00_battery.c +++ b/drivers/power/bq27x00_battery.c @@ -966,7 +966,6 @@ static int bq27000_battery_probe(struct platform_device *pdev) return 0; err_free: - platform_set_drvdata(pdev, NULL); kfree(di); return ret; @@ -978,7 +977,6 @@ static int bq27000_battery_remove(struct platform_device *pdev) bq27x00_powersupply_unregister(di); - platform_set_drvdata(pdev, NULL); kfree(di); return 0; From 6fe6a40a83716166ac55e7f60053f59563d53878 Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Mon, 6 May 2013 13:22:00 +0900 Subject: [PATCH 05/25] gpio-charger: Remove unnecessary platform_set_drvdata() The driver core clears the driver data to NULL after device_release or on probe failure, since commit 0998d0631001288a5974afc0b2a5f568bcdecb4d (device-core: Ensure drvdata = NULL when no driver is bound). Thus, it is not needed to manually clear the device driver data to NULL. Signed-off-by: Jingoo Han Signed-off-by: Anton Vorontsov --- drivers/power/gpio-charger.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/power/gpio-charger.c b/drivers/power/gpio-charger.c index e9883eeeee76..4e858a23568f 100644 --- a/drivers/power/gpio-charger.c +++ b/drivers/power/gpio-charger.c @@ -155,8 +155,6 @@ static int gpio_charger_remove(struct platform_device *pdev) gpio_free(gpio_charger->pdata->gpio); - platform_set_drvdata(pdev, NULL); - return 0; } From 8ff3fb2902dd5d3c953f907906a413b18d9d150a Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Mon, 6 May 2013 13:22:41 +0900 Subject: [PATCH 06/25] jz4740-battery: Remove unnecessary platform_set_drvdata() The driver core clears the driver data to NULL after device_release or on probe failure, since commit 0998d0631001288a5974afc0b2a5f568bcdecb4d (device-core: Ensure drvdata = NULL when no driver is bound). Thus, it is not needed to manually clear the device driver data to NULL. Signed-off-by: Jingoo Han Signed-off-by: Anton Vorontsov --- drivers/power/jz4740-battery.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/power/jz4740-battery.c b/drivers/power/jz4740-battery.c index c675553d4647..d9686aa9270a 100644 --- a/drivers/power/jz4740-battery.c +++ b/drivers/power/jz4740-battery.c @@ -292,7 +292,7 @@ static int jz_battery_probe(struct platform_device *pdev) jz_battery); if (ret) { dev_err(&pdev->dev, "Failed to request irq %d\n", ret); - goto err; + return ret; } disable_irq(jz_battery->irq); @@ -349,8 +349,6 @@ err_free_gpio: gpio_free(jz_battery->pdata->gpio_charge); err_free_irq: free_irq(jz_battery->irq, jz_battery); -err: - platform_set_drvdata(pdev, NULL); return ret; } From f70d739ada3298fd613d738c0a1c8b10cef63bdf Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Mon, 6 May 2013 13:23:45 +0900 Subject: [PATCH 07/25] rx51_battery: Remove unnecessary platform_set_drvdata() The driver core clears the driver data to NULL after device_release or on probe failure, since commit 0998d0631001288a5974afc0b2a5f568bcdecb4d (device-core: Ensure drvdata = NULL when no driver is bound). Thus, it is not needed to manually clear the device driver data to NULL. Signed-off-by: Jingoo Han Signed-off-by: Anton Vorontsov --- drivers/power/rx51_battery.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/power/rx51_battery.c b/drivers/power/rx51_battery.c index cbde1d6d3228..8a6288d87056 100644 --- a/drivers/power/rx51_battery.c +++ b/drivers/power/rx51_battery.c @@ -216,10 +216,8 @@ static int rx51_battery_probe(struct platform_device *pdev) di->bat.get_property = rx51_battery_get_property; ret = power_supply_register(di->dev, &di->bat); - if (ret) { - platform_set_drvdata(pdev, NULL); + if (ret) return ret; - } return 0; } @@ -229,7 +227,6 @@ static int rx51_battery_remove(struct platform_device *pdev) struct rx51_device_info *di = platform_get_drvdata(pdev); power_supply_unregister(&di->bat); - platform_set_drvdata(pdev, NULL); return 0; } From 0f1e0169e08e1645a8406ab84286ebaf19c5cce5 Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Mon, 6 May 2013 13:24:33 +0900 Subject: [PATCH 08/25] twl4030_charger: Remove unnecessary platform_set_drvdata() The driver core clears the driver data to NULL after device_release or on probe failure, since commit 0998d0631001288a5974afc0b2a5f568bcdecb4d (device-core: Ensure drvdata = NULL when no driver is bound). Thus, it is not needed to manually clear the device driver data to NULL. Signed-off-by: Jingoo Han Signed-off-by: Anton Vorontsov --- drivers/power/twl4030_charger.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/power/twl4030_charger.c b/drivers/power/twl4030_charger.c index bed458172dd2..be98e70380f9 100644 --- a/drivers/power/twl4030_charger.c +++ b/drivers/power/twl4030_charger.c @@ -594,7 +594,6 @@ fail_chg_irq: fail_register_usb: power_supply_unregister(&bci->ac); fail_register_ac: - platform_set_drvdata(pdev, NULL); kfree(bci); return ret; @@ -622,7 +621,6 @@ static int __exit twl4030_bci_remove(struct platform_device *pdev) free_irq(bci->irq_chg, bci); power_supply_unregister(&bci->usb); power_supply_unregister(&bci->ac); - platform_set_drvdata(pdev, NULL); kfree(bci); return 0; From 17b4565b308ed31fa20b59842c75e685a101dc8a Mon Sep 17 00:00:00 2001 From: "Kim, Milo" Date: Fri, 10 May 2013 07:17:51 +0000 Subject: [PATCH 09/25] lp8727_charger: Support the device tree feature The interrupt and charging parameters are configurable in the device tree structure. In the board test, a GPIO is used for handling LP8727 interrupts. The device tree binding documentation is added also. Signed-off-by: Milo(Woogyom) Kim Signed-off-by: Anton Vorontsov --- .../bindings/power_supply/lp8727_charger.txt | 44 ++++++++++++ drivers/power/lp8727_charger.c | 68 +++++++++++++++++++ 2 files changed, 112 insertions(+) create mode 100644 Documentation/devicetree/bindings/power_supply/lp8727_charger.txt diff --git a/Documentation/devicetree/bindings/power_supply/lp8727_charger.txt b/Documentation/devicetree/bindings/power_supply/lp8727_charger.txt new file mode 100644 index 000000000000..2246bc5c874b --- /dev/null +++ b/Documentation/devicetree/bindings/power_supply/lp8727_charger.txt @@ -0,0 +1,44 @@ +Binding for TI/National Semiconductor LP8727 Charger + +Required properties: +- compatible: "ti,lp8727" +- reg: I2C slave address 27h + +Optional properties: +- interrupt-parent: interrupt controller node (see interrupt binding[0]) +- interrupts: interrupt specifier (see interrupt binding[0]) +- debounce-ms: interrupt debounce time. (u32) + +AC and USB charging parameters +- charger-type: "ac" or "usb" (string) +- eoc-level: value of 'enum lp8727_eoc_level' (u8) +- charging-current: value of 'enum lp8727_ichg' (u8) + +[0]: Documentation/devicetree/bindings/interrupt-controller/interrupts.txt + +Example) + +lp8727@27 { + compatible = "ti,lp8727"; + reg = <0x27>; + + /* GPIO 134 is used for LP8728 interrupt pin */ + interrupt-parent = <&gpio5>; /* base = 128 */ + interrupts = <6 0x2>; /* offset = 6, falling edge type */ + + debounce-ms = <300>; + + /* AC charger: 5% EOC and 500mA charging current */ + ac { + charger-type = "ac"; + eoc-level = /bits/ 8 <0>; + charging-current = /bits/ 8 <4>; + }; + + /* USB charger: 10% EOC and 400mA charging current */ + usb { + charger-type = "usb"; + eoc-level = /bits/ 8 <1>; + charging-current = /bits/ 8 <2>; + }; +}; diff --git a/drivers/power/lp8727_charger.c b/drivers/power/lp8727_charger.c index 5ef41b819172..32de636dcd73 100644 --- a/drivers/power/lp8727_charger.c +++ b/drivers/power/lp8727_charger.c @@ -16,6 +16,7 @@ #include #include #include +#include #define LP8788_NUM_INTREGS 2 #define DEFAULT_DEBOUNCE_MSEC 270 @@ -481,6 +482,60 @@ static void lp8727_unregister_psy(struct lp8727_chg *pchg) power_supply_unregister(&psy->batt); } +#ifdef CONFIG_OF +static struct lp8727_chg_param +*lp8727_parse_charge_pdata(struct device *dev, struct device_node *np) +{ + struct lp8727_chg_param *param; + + param = devm_kzalloc(dev, sizeof(*param), GFP_KERNEL); + if (!param) + goto out; + + of_property_read_u8(np, "eoc-level", (u8 *)¶m->eoc_level); + of_property_read_u8(np, "charging-current", (u8 *)¶m->ichg); +out: + return param; +} + +static int lp8727_parse_dt(struct device *dev) +{ + struct device_node *np = dev->of_node; + struct device_node *child; + struct lp8727_platform_data *pdata; + const char *type; + + /* If charging parameter is not defined, just skip parsing the dt */ + if (of_get_child_count(np) == 0) + goto out; + + pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); + if (!pdata) + return -ENOMEM; + + of_property_read_u32(np, "debounce-ms", &pdata->debounce_msec); + + for_each_child_of_node(np, child) { + of_property_read_string(child, "charger-type", &type); + + if (!strcmp(type, "ac")) + pdata->ac = lp8727_parse_charge_pdata(dev, child); + + if (!strcmp(type, "usb")) + pdata->usb = lp8727_parse_charge_pdata(dev, child); + } + + dev->platform_data = pdata; +out: + return 0; +} +#else +static int lp8727_parse_dt(struct device *dev) +{ + return 0; +} +#endif + static int lp8727_probe(struct i2c_client *cl, const struct i2c_device_id *id) { struct lp8727_chg *pchg; @@ -489,6 +544,12 @@ static int lp8727_probe(struct i2c_client *cl, const struct i2c_device_id *id) if (!i2c_check_functionality(cl->adapter, I2C_FUNC_SMBUS_I2C_BLOCK)) return -EIO; + if (cl->dev.of_node) { + ret = lp8727_parse_dt(&cl->dev); + if (ret) + return ret; + } + pchg = devm_kzalloc(&cl->dev, sizeof(*pchg), GFP_KERNEL); if (!pchg) return -ENOMEM; @@ -531,6 +592,12 @@ static int lp8727_remove(struct i2c_client *cl) return 0; } +static const struct of_device_id lp8727_dt_ids[] = { + { .compatible = "ti,lp8727", }, + { } +}; +MODULE_DEVICE_TABLE(of, lp8727_dt_ids); + static const struct i2c_device_id lp8727_ids[] = { {"lp8727", 0}, { } @@ -540,6 +607,7 @@ MODULE_DEVICE_TABLE(i2c, lp8727_ids); static struct i2c_driver lp8727_driver = { .driver = { .name = "lp8727", + .of_match_table = of_match_ptr(lp8727_dt_ids), }, .probe = lp8727_probe, .remove = lp8727_remove, From df311333a8c13f3ffe2537a4ff507887208cb863 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Thu, 16 May 2013 17:31:00 +0800 Subject: [PATCH 10/25] pm2301_charger: Fix NULL pointer dereference Add checking pl_data in probe, this prevent possible NULL pointer dereference. Also fix NULL pointer deference in dev_err when allocate memory for pm2 fails. Signed-off-by: Axel Lin Acked-by: Linus Walleij Signed-off-by: Anton Vorontsov --- drivers/power/pm2301_charger.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/power/pm2301_charger.c b/drivers/power/pm2301_charger.c index fef56e2041b3..bb346becd7b4 100644 --- a/drivers/power/pm2301_charger.c +++ b/drivers/power/pm2301_charger.c @@ -1007,9 +1007,14 @@ static int pm2xxx_wall_charger_probe(struct i2c_client *i2c_client, u8 val; int i; + if (!pl_data) { + dev_err(&i2c_client->dev, "No platform data supplied\n"); + return -EINVAL; + } + pm2 = kzalloc(sizeof(struct pm2xxx_charger), GFP_KERNEL); if (!pm2) { - dev_err(pm2->dev, "pm2xxx_charger allocation failed\n"); + dev_err(&i2c_client->dev, "pm2xxx_charger allocation failed\n"); return -ENOMEM; } From c509a62c9469e2787bcacc7aba454d555732b0b6 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Thu, 16 May 2013 21:17:04 +0800 Subject: [PATCH 11/25] pm2301_charger: Return error if create_singlethread_workqueue fails Return error instead of 0 if create_singlethread_workqueue call fails. Signed-off-by: Axel Lin Acked-by: Linus Walleij Signed-off-by: Anton Vorontsov --- drivers/power/pm2301_charger.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/power/pm2301_charger.c b/drivers/power/pm2301_charger.c index bb346becd7b4..1c0bfcbae062 100644 --- a/drivers/power/pm2301_charger.c +++ b/drivers/power/pm2301_charger.c @@ -1075,9 +1075,9 @@ static int pm2xxx_wall_charger_probe(struct i2c_client *i2c_client, pm2->ac_chg.external = true; /* Create a work queue for the charger */ - pm2->charger_wq = - create_singlethread_workqueue("pm2xxx_charger_wq"); + pm2->charger_wq = create_singlethread_workqueue("pm2xxx_charger_wq"); if (pm2->charger_wq == NULL) { + ret = -ENOMEM; dev_err(pm2->dev, "failed to create work queue\n"); goto free_device_info; } From e08358792422ef0b78d7c81f333fc0803fb41cd4 Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Thu, 23 May 2013 19:34:39 +0900 Subject: [PATCH 12/25] power: Use platform_{get,set}_drvdata() Use the wrapper functions for getting and setting the driver data using platform_device instead of using dev_{get,set}_drvdata() with &pdev->dev, so we can directly pass a struct platform_device. Signed-off-by: Jingoo Han Signed-off-by: Anton Vorontsov --- drivers/power/intel_mid_battery.c | 2 +- drivers/power/tps65090-charger.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/power/intel_mid_battery.c b/drivers/power/intel_mid_battery.c index 18d136b443ee..4520811168ad 100644 --- a/drivers/power/intel_mid_battery.c +++ b/drivers/power/intel_mid_battery.c @@ -756,7 +756,7 @@ static int platform_pmic_battery_probe(struct platform_device *pdev) static int platform_pmic_battery_remove(struct platform_device *pdev) { - struct pmic_power_module_info *pbi = dev_get_drvdata(&pdev->dev); + struct pmic_power_module_info *pbi = platform_get_drvdata(pdev); free_irq(pbi->irq, pbi); cancel_delayed_work_sync(&pbi->monitor_battery); diff --git a/drivers/power/tps65090-charger.c b/drivers/power/tps65090-charger.c index 9fbca310a2ad..77ab8561fa34 100644 --- a/drivers/power/tps65090-charger.c +++ b/drivers/power/tps65090-charger.c @@ -218,7 +218,7 @@ static int tps65090_charger_probe(struct platform_device *pdev) return -ENOMEM; } - dev_set_drvdata(&pdev->dev, cdata); + platform_set_drvdata(pdev, cdata); cdata->dev = &pdev->dev; cdata->pdata = pdata; @@ -291,7 +291,7 @@ fail_unregister_supply: static int tps65090_charger_remove(struct platform_device *pdev) { - struct tps65090_charger *cdata = dev_get_drvdata(&pdev->dev); + struct tps65090_charger *cdata = platform_get_drvdata(pdev); devm_free_irq(cdata->dev, cdata->irq, cdata); power_supply_unregister(&cdata->ac); From d211c6e82435dfa4ae9f4d80bb2ee75930bde5d4 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Sat, 25 May 2013 01:41:44 +0800 Subject: [PATCH 13/25] generic-adc-battery: Fix checking if none of the channels are supported If none of the channels are supported, index is 0. Also ensure to return error code instead of 0 in goto second_mem_fail path. Signed-off-by: Axel Lin Acked-by: anish kumar Signed-off-by: Anton Vorontsov --- drivers/power/generic-adc-battery.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/power/generic-adc-battery.c b/drivers/power/generic-adc-battery.c index 8cb5d7f67ace..59a1421f9288 100644 --- a/drivers/power/generic-adc-battery.c +++ b/drivers/power/generic-adc-battery.c @@ -299,8 +299,10 @@ static int gab_probe(struct platform_device *pdev) } /* none of the channels are supported so let's bail out */ - if (index == ARRAY_SIZE(gab_chan_name)) + if (index == 0) { + ret = -ENODEV; goto second_mem_fail; + } /* * Total number of properties is equal to static properties From 4b43eb67ae246b9a846c46e5ff96ea0212ae7a51 Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Mon, 3 Jun 2013 18:05:05 +0900 Subject: [PATCH 14/25] power_supply: Replace strict_strtoul() with kstrtoul() The usage of strict_strtoul() is not preferred, because strict_strtoul() is obsolete. Thus, kstrtoul() should be used. Signed-off-by: Jingoo Han Reviewed-by: Andy Shevchenko Signed-off-by: Anton Vorontsov --- drivers/power/ab8500_fg.c | 6 +++--- drivers/power/pcf50633-charger.c | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/power/ab8500_fg.c b/drivers/power/ab8500_fg.c index 1263638b102d..754970717c31 100644 --- a/drivers/power/ab8500_fg.c +++ b/drivers/power/ab8500_fg.c @@ -2465,9 +2465,9 @@ static ssize_t charge_full_store(struct ab8500_fg *di, const char *buf, size_t count) { unsigned long charge_full; - ssize_t ret = -EINVAL; + ssize_t ret; - ret = strict_strtoul(buf, 10, &charge_full); + ret = kstrtoul(buf, 10, &charge_full); dev_dbg(di->dev, "Ret %zd charge_full %lu", ret, charge_full); @@ -2489,7 +2489,7 @@ static ssize_t charge_now_store(struct ab8500_fg *di, const char *buf, unsigned long charge_now; ssize_t ret; - ret = strict_strtoul(buf, 10, &charge_now); + ret = kstrtoul(buf, 10, &charge_now); dev_dbg(di->dev, "Ret %zd charge_now %lu was %d", ret, charge_now, di->bat_cap.prev_mah); diff --git a/drivers/power/pcf50633-charger.c b/drivers/power/pcf50633-charger.c index 17fd77f24b2a..771c4f0fb8ac 100644 --- a/drivers/power/pcf50633-charger.c +++ b/drivers/power/pcf50633-charger.c @@ -191,9 +191,9 @@ static ssize_t set_usblim(struct device *dev, unsigned long ma; int ret; - ret = strict_strtoul(buf, 10, &ma); + ret = kstrtoul(buf, 10, &ma); if (ret) - return -EINVAL; + return ret; pcf50633_mbc_usb_curlim_set(mbc->pcf, ma); @@ -228,9 +228,9 @@ static ssize_t set_chglim(struct device *dev, if (!mbc->pcf->pdata->charger_reference_current_ma) return -ENODEV; - ret = strict_strtoul(buf, 10, &ma); + ret = kstrtoul(buf, 10, &ma); if (ret) - return -EINVAL; + return ret; mbcc5 = (ma << 8) / mbc->pcf->pdata->charger_reference_current_ma; if (mbcc5 > 255) From 3594f4c0d7bc51e3a7e6d73c44e368ae079e42f3 Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Thu, 6 Jun 2013 13:52:21 -0700 Subject: [PATCH 15/25] charger-manager: Ensure event is not used as format string The exposed interface for cm_notify_event() could result in the event msg string being parsed as a format string. Make sure it is only used as a literal string. Signed-off-by: Kees Cook Cc: stable@vger.kernel.org Cc: Anton Vorontsov Cc: David Woodhouse Signed-off-by: Anton Vorontsov --- drivers/power/charger-manager.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/power/charger-manager.c b/drivers/power/charger-manager.c index fefc39fe42be..98de1ddce458 100644 --- a/drivers/power/charger-manager.c +++ b/drivers/power/charger-manager.c @@ -450,7 +450,7 @@ static void uevent_notify(struct charger_manager *cm, const char *event) strncpy(env_str, event, UEVENT_BUF_SIZE); kobject_uevent(&cm->dev->kobj, KOBJ_CHANGE); - dev_info(cm->dev, event); + dev_info(cm->dev, "%s", event); } /** From 9d5e2a023eee96b2326f9b0830a753b400917280 Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Sun, 9 Jun 2013 09:41:23 -0700 Subject: [PATCH 16/25] MAINTAINERS: Update email address for Anton Vorontsov Old email addresses seem to gradually stop working so people are getting bounces. This patch updates my email address. Suggested-by: Andy Shevchenko Signed-off-by: Anton Vorontsov --- MAINTAINERS | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index f35a259a6564..9e63f919922f 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -742,7 +742,7 @@ S: Maintained F: arch/arm/mach-highbank/ ARM/CAVIUM NETWORKS CNS3XXX MACHINE SUPPORT -M: Anton Vorontsov +M: Anton Vorontsov S: Maintained F: arch/arm/mach-cns3xxx/ T: git git://git.infradead.org/users/cbou/linux-cns3xxx.git @@ -6314,7 +6314,7 @@ F: include/linux/timer* F: kernel/*timer* POWER SUPPLY CLASS/SUBSYSTEM and DRIVERS -M: Anton Vorontsov +M: Anton Vorontsov M: David Woodhouse T: git git://git.infradead.org/battery-2.6.git S: Maintained @@ -6424,7 +6424,7 @@ S: Maintained F: drivers/block/ps3vram.c PSTORE FILESYSTEM -M: Anton Vorontsov +M: Anton Vorontsov M: Colin Cross M: Kees Cook M: Tony Luck @@ -7122,7 +7122,7 @@ F: drivers/mmc/host/sdhci.* F: drivers/mmc/host/sdhci-pltfm.[ch] SECURE DIGITAL HOST CONTROLLER INTERFACE, OPEN FIRMWARE BINDINGS (SDHCI-OF) -M: Anton Vorontsov +M: Anton Vorontsov L: linuxppc-dev@lists.ozlabs.org L: linux-mmc@vger.kernel.org S: Maintained From e24142178fc2f60824af4312d326edacdcd667a3 Mon Sep 17 00:00:00 2001 From: Andrew Chew Date: Thu, 6 Jun 2013 14:12:43 -0700 Subject: [PATCH 17/25] tps65090-charger: Fix AC detect The VACG interrupt was not being enabled. Thus, interrupts were never generated when AC status changes. In addition, interrupts were never cleared after taking and processing the interrupt. Added the register offset for the INTR_MASK register, since this is needed to unmask the VACG interrupt. Enabled the VACG interrupt in tps65090_config_charger(). Cleared interrupts after processing, in tps65090_charger_isr(). Also removed unused variable "enable" in tps65090_enable_charging(), and fixed a typo in one of the dev_err() prints. Signed-off-by: Andrew Chew Tested-by: Rhyland Klein Acked-by: Rhyland Klein Signed-off-by: Anton Vorontsov --- drivers/power/tps65090-charger.c | 35 +++++++++++++++++++++++++++----- 1 file changed, 30 insertions(+), 5 deletions(-) diff --git a/drivers/power/tps65090-charger.c b/drivers/power/tps65090-charger.c index 77ab8561fa34..e628f9813e08 100644 --- a/drivers/power/tps65090-charger.c +++ b/drivers/power/tps65090-charger.c @@ -27,6 +27,7 @@ #include #define TPS65090_REG_INTR_STS 0x00 +#define TPS65090_REG_INTR_MASK 0x02 #define TPS65090_REG_CG_CTRL0 0x04 #define TPS65090_REG_CG_CTRL1 0x05 #define TPS65090_REG_CG_CTRL2 0x06 @@ -67,8 +68,7 @@ static int tps65090_low_chrg_current(struct tps65090_charger *charger) return 0; } -static int tps65090_enable_charging(struct tps65090_charger *charger, - uint8_t enable) +static int tps65090_enable_charging(struct tps65090_charger *charger) { int ret; uint8_t ctrl0 = 0; @@ -84,7 +84,7 @@ static int tps65090_enable_charging(struct tps65090_charger *charger, ret = tps65090_write(charger->dev->parent, TPS65090_REG_CG_CTRL0, (ctrl0 | TPS65090_CHARGER_ENABLE)); if (ret < 0) { - dev_err(charger->dev, "%s(): error reading in register 0x%x\n", + dev_err(charger->dev, "%s(): error writing in register 0x%x\n", __func__, TPS65090_REG_CG_CTRL0); return ret; } @@ -93,6 +93,7 @@ static int tps65090_enable_charging(struct tps65090_charger *charger, static int tps65090_config_charger(struct tps65090_charger *charger) { + uint8_t intrmask = 0; int ret; if (charger->pdata->enable_low_current_chrg) { @@ -104,6 +105,23 @@ static int tps65090_config_charger(struct tps65090_charger *charger) } } + /* Enable the VACG interrupt for AC power detect */ + ret = tps65090_read(charger->dev->parent, TPS65090_REG_INTR_MASK, + &intrmask); + if (ret < 0) { + dev_err(charger->dev, "%s(): error reading in register 0x%x\n", + __func__, TPS65090_REG_INTR_MASK); + return ret; + } + + ret = tps65090_write(charger->dev->parent, TPS65090_REG_INTR_MASK, + (intrmask | TPS65090_VACG)); + if (ret < 0) { + dev_err(charger->dev, "%s(): error writing in register 0x%x\n", + __func__, TPS65090_REG_CG_CTRL0); + return ret; + } + return 0; } @@ -146,7 +164,7 @@ static irqreturn_t tps65090_charger_isr(int irq, void *dev_id) } if (intrsts & TPS65090_VACG) { - ret = tps65090_enable_charging(charger, 1); + ret = tps65090_enable_charging(charger); if (ret < 0) return IRQ_HANDLED; charger->ac_online = 1; @@ -154,6 +172,13 @@ static irqreturn_t tps65090_charger_isr(int irq, void *dev_id) charger->ac_online = 0; } + /* Clear interrupts. */ + ret = tps65090_write(charger->dev->parent, TPS65090_REG_INTR_STS, 0x00); + if (ret < 0) { + dev_err(charger->dev, "%s(): Error in writing reg 0x%x\n", + __func__, TPS65090_REG_INTR_STS); + } + if (charger->prev_ac_online != charger->ac_online) power_supply_changed(&charger->ac); @@ -270,7 +295,7 @@ static int tps65090_charger_probe(struct platform_device *pdev) } if (status1 != 0) { - ret = tps65090_enable_charging(cdata, 1); + ret = tps65090_enable_charging(cdata); if (ret < 0) { dev_err(cdata->dev, "error enabling charger\n"); goto fail_free_irq; From e5409cbd8c0bf44f65e7528635cf05ed298e0c61 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Thu, 6 Jun 2013 18:25:12 -0700 Subject: [PATCH 18/25] charger-manager: Add missing newlines, fix a couple of typos, add pr_fmt Make sure that dev_ calls are newline terminated. Add #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt to prefix all pr_ calls with "charger-manager: " Fix a couple of typos. Fix formats with terminating n that should be \n. Coalesce formats for easier grep. Align arguments to open parenthesis for these dev_ calls. Add missing spaces after coalescing multiple string segments. Signed-off-by: Joe Perches Acked-by: Kees Cook Signed-off-by: Anton Vorontsov --- drivers/power/charger-manager.c | 137 +++++++++++++------------------- 1 file changed, 57 insertions(+), 80 deletions(-) diff --git a/drivers/power/charger-manager.c b/drivers/power/charger-manager.c index 98de1ddce458..ba420292628e 100644 --- a/drivers/power/charger-manager.c +++ b/drivers/power/charger-manager.c @@ -12,6 +12,8 @@ * published by the Free Software Foundation. **/ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -195,8 +197,8 @@ static bool is_charging(struct charger_manager *cm) cm->charger_stat[i], POWER_SUPPLY_PROP_ONLINE, &val); if (ret) { - dev_warn(cm->dev, "Cannot read ONLINE value from %s.\n", - cm->desc->psy_charger_stat[i]); + dev_warn(cm->dev, "Cannot read ONLINE value from %s\n", + cm->desc->psy_charger_stat[i]); continue; } if (val.intval == 0) @@ -210,8 +212,8 @@ static bool is_charging(struct charger_manager *cm) cm->charger_stat[i], POWER_SUPPLY_PROP_STATUS, &val); if (ret) { - dev_warn(cm->dev, "Cannot read STATUS value from %s.\n", - cm->desc->psy_charger_stat[i]); + dev_warn(cm->dev, "Cannot read STATUS value from %s\n", + cm->desc->psy_charger_stat[i]); continue; } if (val.intval == POWER_SUPPLY_STATUS_FULL || @@ -289,7 +291,7 @@ static bool is_polling_required(struct charger_manager *cm) return is_charging(cm); default: dev_warn(cm->dev, "Incorrect polling_mode (%d)\n", - cm->desc->polling_mode); + cm->desc->polling_mode); } return false; @@ -331,9 +333,8 @@ static int try_charger_enable(struct charger_manager *cm, bool enable) err = regulator_enable(desc->charger_regulators[i].consumer); if (err < 0) { - dev_warn(cm->dev, - "Cannot enable %s regulator\n", - desc->charger_regulators[i].regulator_name); + dev_warn(cm->dev, "Cannot enable %s regulator\n", + desc->charger_regulators[i].regulator_name); } } } else { @@ -350,9 +351,8 @@ static int try_charger_enable(struct charger_manager *cm, bool enable) err = regulator_disable(desc->charger_regulators[i].consumer); if (err < 0) { - dev_warn(cm->dev, - "Cannot disable %s regulator\n", - desc->charger_regulators[i].regulator_name); + dev_warn(cm->dev, "Cannot disable %s regulator\n", + desc->charger_regulators[i].regulator_name); } } @@ -365,9 +365,8 @@ static int try_charger_enable(struct charger_manager *cm, bool enable) desc->charger_regulators[i].consumer)) { regulator_force_disable( desc->charger_regulators[i].consumer); - dev_warn(cm->dev, - "Disable regulator(%s) forcibly.\n", - desc->charger_regulators[i].regulator_name); + dev_warn(cm->dev, "Disable regulator(%s) forcibly\n", + desc->charger_regulators[i].regulator_name); } } } @@ -450,7 +449,7 @@ static void uevent_notify(struct charger_manager *cm, const char *event) strncpy(env_str, event, UEVENT_BUF_SIZE); kobject_uevent(&cm->dev->kobj, KOBJ_CHANGE); - dev_info(cm->dev, "%s", event); + dev_info(cm->dev, "%s\n", event); } /** @@ -478,7 +477,7 @@ static void fullbatt_vchk(struct work_struct *work) err = get_batt_uV(cm, &batt_uV); if (err) { - dev_err(cm->dev, "%s: get_batt_uV error(%d).\n", __func__, err); + dev_err(cm->dev, "%s: get_batt_uV error(%d)\n", __func__, err); return; } @@ -486,7 +485,7 @@ static void fullbatt_vchk(struct work_struct *work) if (diff < 0) return; - dev_info(cm->dev, "VBATT dropped %duV after full-batt.\n", diff); + dev_info(cm->dev, "VBATT dropped %duV after full-batt\n", diff); if (diff > desc->fullbatt_vchkdrop_uV) { try_charger_restart(cm); @@ -519,7 +518,7 @@ static int check_charging_duration(struct charger_manager *cm) duration = curr - cm->charging_start_time; if (duration > desc->charging_max_duration_ms) { - dev_info(cm->dev, "Charging duration exceed %lldms", + dev_info(cm->dev, "Charging duration exceed %lldms\n", desc->charging_max_duration_ms); uevent_notify(cm, "Discharging"); try_charger_enable(cm, false); @@ -530,9 +529,9 @@ static int check_charging_duration(struct charger_manager *cm) if (duration > desc->charging_max_duration_ms && is_ext_pwr_online(cm)) { - dev_info(cm->dev, "DisCharging duration exceed %lldms", + dev_info(cm->dev, "Discharging duration exceed %lldms\n", desc->discharging_max_duration_ms); - uevent_notify(cm, "Recharing"); + uevent_notify(cm, "Recharging"); try_charger_enable(cm, true); ret = true; } @@ -579,7 +578,7 @@ static bool _cm_monitor(struct charger_manager *cm) */ } else if (!cm->emergency_stop && check_charging_duration(cm)) { dev_dbg(cm->dev, - "Charging/Discharging duration is out of range"); + "Charging/Discharging duration is out of range\n"); /* * Check dropped voltage of battery. If battery voltage is more * dropped than fullbatt_vchkdrop_uV after fully charged state, @@ -595,7 +594,7 @@ static bool _cm_monitor(struct charger_manager *cm) */ } else if (!cm->emergency_stop && is_full_charged(cm) && cm->charger_enabled) { - dev_info(cm->dev, "EVENT_HANDLE: Battery Fully Charged.\n"); + dev_info(cm->dev, "EVENT_HANDLE: Battery Fully Charged\n"); uevent_notify(cm, default_event_names[CM_EVENT_BATT_FULL]); try_charger_enable(cm, false); @@ -725,7 +724,7 @@ static void fullbatt_handler(struct charger_manager *cm) cm->fullbatt_vchk_jiffies_at = 1; out: - dev_info(cm->dev, "EVENT_HANDLE: Battery Fully Charged.\n"); + dev_info(cm->dev, "EVENT_HANDLE: Battery Fully Charged\n"); uevent_notify(cm, default_event_names[CM_EVENT_BATT_FULL]); } @@ -972,7 +971,7 @@ static bool cm_setup_timer(void) mutex_unlock(&cm_list_mtx); if (wakeup_ms < UINT_MAX && wakeup_ms > 0) { - pr_info("Charger Manager wakeup timer: %u ms.\n", wakeup_ms); + pr_info("Charger Manager wakeup timer: %u ms\n", wakeup_ms); if (rtc_dev) { struct rtc_wkalrm tmp; unsigned long time, now; @@ -1005,8 +1004,7 @@ static bool cm_setup_timer(void) ret = false; } - pr_info("Waking up after %lu secs.\n", - time - now); + pr_info("Waking up after %lu secs\n", time - now); rtc_time_to_tm(time, &tmp.time); rtc_set_alarm(rtc_dev, &tmp); @@ -1101,7 +1099,7 @@ int setup_charger_manager(struct charger_global_desc *gd) g_desc = NULL; if (!gd->rtc_only_wakeup) { - pr_err("The callback rtc_only_wakeup is not given.\n"); + pr_err("The callback rtc_only_wakeup is not given\n"); return -EINVAL; } @@ -1112,7 +1110,7 @@ int setup_charger_manager(struct charger_global_desc *gd) /* Retry at probe. RTC may be not registered yet */ } } else { - pr_warn("No wakeup timer is given for charger manager." + pr_warn("No wakeup timer is given for charger manager. " "In-suspend monitoring won't work.\n"); } @@ -1138,13 +1136,13 @@ static void charger_extcon_work(struct work_struct *work) cable->min_uA, cable->max_uA); if (ret < 0) { pr_err("Cannot set current limit of %s (%s)\n", - cable->charger->regulator_name, cable->name); + cable->charger->regulator_name, cable->name); return; } pr_info("Set current limit of %s : %duA ~ %duA\n", - cable->charger->regulator_name, - cable->min_uA, cable->max_uA); + cable->charger->regulator_name, + cable->min_uA, cable->max_uA); } try_charger_enable(cable->cm, cable->attached); @@ -1210,9 +1208,8 @@ static int charger_extcon_init(struct charger_manager *cm, ret = extcon_register_interest(&cable->extcon_dev, cable->extcon_name, cable->name, &cable->nb); if (ret < 0) { - pr_info("Cannot register extcon_dev for %s(cable: %s).\n", - cable->extcon_name, - cable->name); + pr_info("Cannot register extcon_dev for %s(cable: %s)\n", + cable->extcon_name, cable->name); ret = -EINVAL; } @@ -1243,8 +1240,8 @@ static int charger_manager_register_extcon(struct charger_manager *cm) charger->consumer = regulator_get(cm->dev, charger->regulator_name); if (charger->consumer == NULL) { - dev_err(cm->dev, "Cannot find charger(%s)n", - charger->regulator_name); + dev_err(cm->dev, "Cannot find charger(%s)\n", + charger->regulator_name); ret = -EINVAL; goto err; } @@ -1255,8 +1252,8 @@ static int charger_manager_register_extcon(struct charger_manager *cm) ret = charger_extcon_init(cm, cable); if (ret < 0) { - dev_err(cm->dev, "Cannot initialize charger(%s)n", - charger->regulator_name); + dev_err(cm->dev, "Cannot initialize charger(%s)\n", + charger->regulator_name); goto err; } cable->charger = charger; @@ -1347,10 +1344,8 @@ static ssize_t charger_externally_control_store(struct device *dev, } } else { dev_warn(cm->dev, - "'%s' regulator should be controlled " - "in charger-manager because charger-manager " - "must need at least one charger for charging\n", - charger->regulator_name); + "'%s' regulator should be controlled in charger-manager because charger-manager must need at least one charger for charging\n", + charger->regulator_name); } return count; @@ -1386,8 +1381,6 @@ static int charger_manager_register_sysfs(struct charger_manager *cm) snprintf(buf, 10, "charger.%d", i); str = kzalloc(sizeof(char) * (strlen(buf) + 1), GFP_KERNEL); if (!str) { - dev_err(cm->dev, "Cannot allocate memory: %s\n", - charger->regulator_name); ret = -ENOMEM; goto err; } @@ -1423,26 +1416,21 @@ static int charger_manager_register_sysfs(struct charger_manager *cm) !chargers_externally_control) chargers_externally_control = 0; - dev_info(cm->dev, "'%s' regulator's externally_control" - "is %d\n", charger->regulator_name, - charger->externally_control); + dev_info(cm->dev, "'%s' regulator's externally_control is %d\n", + charger->regulator_name, charger->externally_control); ret = sysfs_create_group(&cm->charger_psy.dev->kobj, &charger->attr_g); if (ret < 0) { - dev_err(cm->dev, "Cannot create sysfs entry" - "of %s regulator\n", - charger->regulator_name); + dev_err(cm->dev, "Cannot create sysfs entry of %s regulator\n", + charger->regulator_name); ret = -EINVAL; goto err; } } if (chargers_externally_control) { - dev_err(cm->dev, "Cannot register regulator because " - "charger-manager must need at least " - "one charger for charging battery\n"); - + dev_err(cm->dev, "Cannot register regulator because charger-manager must need at least one charger for charging battery\n"); ret = -EINVAL; goto err; } @@ -1463,7 +1451,7 @@ static int charger_manager_probe(struct platform_device *pdev) rtc_dev = rtc_class_open(g_desc->rtc_name); if (IS_ERR_OR_NULL(rtc_dev)) { rtc_dev = NULL; - dev_err(&pdev->dev, "Cannot get RTC %s.\n", + dev_err(&pdev->dev, "Cannot get RTC %s\n", g_desc->rtc_name); ret = -ENODEV; goto err_alloc; @@ -1471,14 +1459,13 @@ static int charger_manager_probe(struct platform_device *pdev) } if (!desc) { - dev_err(&pdev->dev, "No platform data (desc) found.\n"); + dev_err(&pdev->dev, "No platform data (desc) found\n"); ret = -ENODEV; goto err_alloc; } cm = kzalloc(sizeof(struct charger_manager), GFP_KERNEL); if (!cm) { - dev_err(&pdev->dev, "Cannot allocate memory.\n"); ret = -ENOMEM; goto err_alloc; } @@ -1487,7 +1474,6 @@ static int charger_manager_probe(struct platform_device *pdev) cm->dev = &pdev->dev; cm->desc = kmemdup(desc, sizeof(struct charger_desc), GFP_KERNEL); if (!cm->desc) { - dev_err(&pdev->dev, "Cannot allocate memory.\n"); ret = -ENOMEM; goto err_alloc_desc; } @@ -1498,33 +1484,28 @@ static int charger_manager_probe(struct platform_device *pdev) * Users may intentionally ignore those two features. */ if (desc->fullbatt_uV == 0) { - dev_info(&pdev->dev, "Ignoring full-battery voltage threshold" - " as it is not supplied."); + dev_info(&pdev->dev, "Ignoring full-battery voltage threshold as it is not supplied\n"); } if (!desc->fullbatt_vchkdrop_ms || !desc->fullbatt_vchkdrop_uV) { - dev_info(&pdev->dev, "Disabling full-battery voltage drop " - "checking mechanism as it is not supplied."); + dev_info(&pdev->dev, "Disabling full-battery voltage drop checking mechanism as it is not supplied\n"); desc->fullbatt_vchkdrop_ms = 0; desc->fullbatt_vchkdrop_uV = 0; } if (desc->fullbatt_soc == 0) { - dev_info(&pdev->dev, "Ignoring full-battery soc(state of" - " charge) threshold as it is not" - " supplied."); + dev_info(&pdev->dev, "Ignoring full-battery soc(state of charge) threshold as it is not supplied\n"); } if (desc->fullbatt_full_capacity == 0) { - dev_info(&pdev->dev, "Ignoring full-battery full capacity" - " threshold as it is not supplied."); + dev_info(&pdev->dev, "Ignoring full-battery full capacity threshold as it is not supplied\n"); } if (!desc->charger_regulators || desc->num_charger_regulators < 1) { ret = -EINVAL; - dev_err(&pdev->dev, "charger_regulators undefined.\n"); + dev_err(&pdev->dev, "charger_regulators undefined\n"); goto err_no_charger; } if (!desc->psy_charger_stat || !desc->psy_charger_stat[0]) { - dev_err(&pdev->dev, "No power supply defined.\n"); + dev_err(&pdev->dev, "No power supply defined\n"); ret = -EINVAL; goto err_no_charger_stat; } @@ -1544,9 +1525,8 @@ static int charger_manager_probe(struct platform_device *pdev) cm->charger_stat[i] = power_supply_get_by_name( desc->psy_charger_stat[i]); if (!cm->charger_stat[i]) { - dev_err(&pdev->dev, "Cannot find power supply " - "\"%s\"\n", - desc->psy_charger_stat[i]); + dev_err(&pdev->dev, "Cannot find power supply \"%s\"\n", + desc->psy_charger_stat[i]); ret = -ENODEV; goto err_chg_stat; } @@ -1555,7 +1535,7 @@ static int charger_manager_probe(struct platform_device *pdev) cm->fuel_gauge = power_supply_get_by_name(desc->psy_fuel_gauge); if (!cm->fuel_gauge) { dev_err(&pdev->dev, "Cannot find power supply \"%s\"\n", - desc->psy_fuel_gauge); + desc->psy_fuel_gauge); ret = -ENODEV; goto err_chg_stat; } @@ -1575,9 +1555,7 @@ static int charger_manager_probe(struct platform_device *pdev) if (!desc->charging_max_duration_ms || !desc->discharging_max_duration_ms) { - dev_info(&pdev->dev, "Cannot limit charging duration " - "checking mechanism to prevent overcharge/overheat " - "and control discharging duration"); + dev_info(&pdev->dev, "Cannot limit charging duration checking mechanism to prevent overcharge/overheat and control discharging duration\n"); desc->charging_max_duration_ms = 0; desc->discharging_max_duration_ms = 0; } @@ -1598,7 +1576,6 @@ static int charger_manager_probe(struct platform_device *pdev) NUM_CHARGER_PSY_OPTIONAL), GFP_KERNEL); if (!cm->charger_psy.properties) { - dev_err(&pdev->dev, "Cannot allocate for psy properties.\n"); ret = -ENOMEM; goto err_chg_stat; } @@ -1636,8 +1613,8 @@ static int charger_manager_probe(struct platform_device *pdev) ret = power_supply_register(NULL, &cm->charger_psy); if (ret) { - dev_err(&pdev->dev, "Cannot register charger-manager with" - " name \"%s\".\n", cm->charger_psy.name); + dev_err(&pdev->dev, "Cannot register charger-manager with name \"%s\"\n", + cm->charger_psy.name); goto err_register; } @@ -1948,7 +1925,7 @@ void cm_notify_event(struct power_supply *psy, enum cm_event_types type, uevent_notify(cm, msg ? msg : default_event_names[type]); break; default: - dev_err(cm->dev, "%s type not specified.\n", __func__); + dev_err(cm->dev, "%s: type not specified\n", __func__); break; } } From b52eafcd79728d61cfc75b64c817b5037a31dfe7 Mon Sep 17 00:00:00 2001 From: Pawel Moll Date: Mon, 10 Jun 2013 16:12:01 +0100 Subject: [PATCH 19/25] power/reset: Make the vexpress driver optional on arm and arm64 The driver can be used on either arm or arm64 platforms, but the latter doesn't have any platform-specific configuration options, so it must be possible to manually enable the driver. Signed-off-by: Pawel Moll Acked-by: Catalin Marinas Signed-off-by: Anton Vorontsov --- drivers/power/reset/Kconfig | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/power/reset/Kconfig b/drivers/power/reset/Kconfig index 349e9ae8090a..ee039dcead04 100644 --- a/drivers/power/reset/Kconfig +++ b/drivers/power/reset/Kconfig @@ -32,7 +32,8 @@ config POWER_RESET_RESTART user presses a key. u-boot then boots into Linux. config POWER_RESET_VEXPRESS - bool + bool "ARM Versatile Express power-off and reset driver" + depends on ARM || ARM64 depends on POWER_RESET help Power off and reset support for the ARM Ltd. Versatile From b50df95c8f0703c95625181d2eaf53855c5ebee5 Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Fri, 28 Jun 2013 18:17:22 -0700 Subject: [PATCH 20/25] power_supply: Move of_node out of the #ifdef CONFIG_OF Similar to linux/device.h, move of_node struct member out of the #ifdef CONFIG_OF so that the drivers won't have to mess with #ifdefs in .c files. Signed-off-by: Anton Vorontsov --- include/linux/power_supply.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/linux/power_supply.h b/include/linux/power_supply.h index 3828cefb4f65..804b90643a85 100644 --- a/include/linux/power_supply.h +++ b/include/linux/power_supply.h @@ -162,6 +162,8 @@ union power_supply_propval { const char *strval; }; +struct device_node; + struct power_supply { const char *name; enum power_supply_type type; @@ -173,9 +175,7 @@ struct power_supply { char **supplied_from; size_t num_supplies; -#ifdef CONFIG_OF struct device_node *of_node; -#endif int (*get_property)(struct power_supply *psy, enum power_supply_property psp, From 2054d6e90e26b01ac0f125a42fecba63f226e55e Mon Sep 17 00:00:00 2001 From: Rhyland Klein Date: Mon, 10 Jun 2013 17:26:39 -0400 Subject: [PATCH 21/25] power_supply: Add of_node_put to fix refcount of_parse_phandle increments the refcount for a dt node before returning it. Add of_node_put where needed to properly decrement the refcount when we are done using a given node. Signed-off-by: Rhyland Klein Signed-off-by: Anton Vorontsov --- drivers/power/power_supply_core.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/power/power_supply_core.c b/drivers/power/power_supply_core.c index 1c517c34e4be..3b2d5df45e7a 100644 --- a/drivers/power/power_supply_core.c +++ b/drivers/power/power_supply_core.c @@ -109,8 +109,10 @@ static int __power_supply_populate_supplied_from(struct device *dev, psy->name, epsy->name); psy->supplied_from[i-1] = (char *)epsy->name; psy->num_supplies++; + of_node_put(np); break; } + of_node_put(np); } while (np); return 0; @@ -193,8 +195,10 @@ static int power_supply_check_supplies(struct power_supply *psy) ret = power_supply_find_supply_from_node(np); if (ret) { dev_dbg(psy->dev, "Failed to find supply, defer!\n"); + of_node_put(np); return -EPROBE_DEFER; } + of_node_put(np); } while (np); /* All supplies found, allocate char ** array for filling */ From 89a22b1a9850028bd216457397321db5a5ee18f5 Mon Sep 17 00:00:00 2001 From: Rhyland Klein Date: Mon, 10 Jun 2013 17:26:40 -0400 Subject: [PATCH 22/25] sbs-battery: Add dt to power_supply struct By passing in the dt node of this device, we enable the logic for linking power_supplies together from dt. This is specified by adding a "power-supplies" property with a phandle to the charger for a given supply. Enable this logic now for the sbs-battery driver. Signed-off-by: Rhyland Klein Signed-off-by: Anton Vorontsov --- drivers/power/sbs-battery.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/power/sbs-battery.c b/drivers/power/sbs-battery.c index c8c78a74e75a..b5f2a76b6cdf 100644 --- a/drivers/power/sbs-battery.c +++ b/drivers/power/sbs-battery.c @@ -704,6 +704,7 @@ static int sbs_probe(struct i2c_client *client, chip->power_supply.properties = sbs_properties; chip->power_supply.num_properties = ARRAY_SIZE(sbs_properties); chip->power_supply.get_property = sbs_get_property; + chip->power_supply.of_node = client->dev.of_node; /* ignore first notification of external change, it is generated * from the power_supply_register call back */ From 605860bc2495cd584fd639f00806591af0b1fefa Mon Sep 17 00:00:00 2001 From: Rhyland Klein Date: Mon, 10 Jun 2013 17:26:41 -0400 Subject: [PATCH 23/25] tps65090-charger: Add dt node to power_supply Passing in the dt node for this charger enables the logic in the core to lookup this device, to see if it is supplying another power_supply, through dt. Signed-off-by: Rhyland Klein Signed-off-by: Anton Vorontsov --- drivers/power/tps65090-charger.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/power/tps65090-charger.c b/drivers/power/tps65090-charger.c index e628f9813e08..bdd7b9b2546a 100644 --- a/drivers/power/tps65090-charger.c +++ b/drivers/power/tps65090-charger.c @@ -255,6 +255,7 @@ static int tps65090_charger_probe(struct platform_device *pdev) cdata->ac.num_properties = ARRAY_SIZE(tps65090_ac_props); cdata->ac.supplied_to = pdata->supplied_to; cdata->ac.num_supplicants = pdata->num_supplicants; + cdata->ac.of_node = pdev->dev.of_node; ret = power_supply_register(&pdev->dev, &cdata->ac); if (ret) { From 3cc9d26966ea02f71258ab0553ebd3388f40533a Mon Sep 17 00:00:00 2001 From: Jonghwa Lee Date: Tue, 25 Jun 2013 14:02:49 +0900 Subject: [PATCH 24/25] charger-manager: Fix a bug when it unregisters notifier block of extcon This patch prevents NULL pointer error cauesed by unregistering unregistered exton notifier block. At the probing time of charger manager, it tries to remove extcon notifier block when it fails to initialize them. It has to be applied for only registered one. Otherwise, it'd make kernel panic. To make it work right, it checks extcon_specific_cable_nb's extcon_dev node. If extcon cable notifier block was registered successfully, it has proper extcon_dev pointer if not so it has NULL pointer. Signed-off-by: Jonghwa Lee Signed-off-by: Myungjoo Ham Acked-by: Chanwoo Choi Signed-off-by: Anton Vorontsov --- drivers/power/charger-manager.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/power/charger-manager.c b/drivers/power/charger-manager.c index ba420292628e..8ad9698b55a9 100644 --- a/drivers/power/charger-manager.c +++ b/drivers/power/charger-manager.c @@ -1666,7 +1666,9 @@ err_reg_extcon: charger = &desc->charger_regulators[i]; for (j = 0; j < charger->num_cables; j++) { struct charger_cable *cable = &charger->cables[j]; - extcon_unregister_interest(&cable->extcon_dev); + /* Remove notifier block if only edev exists */ + if (cable->extcon_dev.edev) + extcon_unregister_interest(&cable->extcon_dev); } regulator_put(desc->charger_regulators[i].consumer); From 5a6c2208455f25b3e6f939adc2da59aa00d4806e Mon Sep 17 00:00:00 2001 From: Jonghwa Lee Date: Tue, 25 Jun 2013 14:18:14 +0900 Subject: [PATCH 25/25] charger-manager: Fix regulator_get() return check This patch fixes return value checking of regulator_get() in charger-manager driver. The API, regulator_get(), returns ERR_PTR() when it fails to get regulator with given name, not NULL. Signed-off-by: Jonghwa Lee Signed-off-by: Myungjoo Ham Acked-by: Chanwoo Choi Signed-off-by: Anton Vorontsov --- drivers/power/charger-manager.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/power/charger-manager.c b/drivers/power/charger-manager.c index 8ad9698b55a9..e30e847600bb 100644 --- a/drivers/power/charger-manager.c +++ b/drivers/power/charger-manager.c @@ -1239,11 +1239,10 @@ static int charger_manager_register_extcon(struct charger_manager *cm) charger->consumer = regulator_get(cm->dev, charger->regulator_name); - if (charger->consumer == NULL) { + if (IS_ERR(charger->consumer)) { dev_err(cm->dev, "Cannot find charger(%s)\n", charger->regulator_name); - ret = -EINVAL; - goto err; + return PTR_ERR(charger->consumer); } charger->cm = cm;