Commit 7d3107d2 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'for-v3.11' of git://git.infradead.org/battery-2.6

Pull battery subsystem update from Anton Vorontsov:
 "Nothing exciting this time, just assorted fixes and cleanups"

* tag 'for-v3.11' of git://git.infradead.org/battery-2.6: (25 commits)
  charger-manager: Fix regulator_get() return check
  charger-manager: Fix a bug when it unregisters notifier block of extcon
  tps65090-charger: Add dt node to power_supply
  sbs-battery: Add dt to power_supply struct
  power_supply: Add of_node_put to fix refcount
  power_supply: Move of_node out of the #ifdef CONFIG_OF
  power/reset: Make the vexpress driver optional on arm and arm64
  charger-manager: Add missing newlines, fix a couple of typos, add pr_fmt
  tps65090-charger: Fix AC detect
  MAINTAINERS: Update email address for Anton Vorontsov
  charger-manager: Ensure event is not used as format string
  power_supply: Replace strict_strtoul() with kstrtoul()
  generic-adc-battery: Fix checking if none of the channels are supported
  power: Use platform_{get,set}_drvdata()
  pm2301_charger: Return error if create_singlethread_workqueue fails
  pm2301_charger: Fix NULL pointer dereference
  lp8727_charger: Support the device tree feature
  twl4030_charger: Remove unnecessary platform_set_drvdata()
  rx51_battery: Remove unnecessary platform_set_drvdata()
  jz4740-battery: Remove unnecessary platform_set_drvdata()
  ...
parents 3aa78e0c 5a6c2208
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>;
};
};
...@@ -752,7 +752,7 @@ S: Maintained ...@@ -752,7 +752,7 @@ S: Maintained
F: arch/arm/mach-highbank/ F: arch/arm/mach-highbank/
ARM/CAVIUM NETWORKS CNS3XXX MACHINE SUPPORT ARM/CAVIUM NETWORKS CNS3XXX MACHINE SUPPORT
M: Anton Vorontsov <avorontsov@mvista.com> M: Anton Vorontsov <anton@enomsg.org>
S: Maintained S: Maintained
F: arch/arm/mach-cns3xxx/ F: arch/arm/mach-cns3xxx/
T: git git://git.infradead.org/users/cbou/linux-cns3xxx.git T: git git://git.infradead.org/users/cbou/linux-cns3xxx.git
...@@ -6406,7 +6406,7 @@ F: include/linux/timer* ...@@ -6406,7 +6406,7 @@ F: include/linux/timer*
F: kernel/*timer* F: kernel/*timer*
POWER SUPPLY CLASS/SUBSYSTEM and DRIVERS POWER SUPPLY CLASS/SUBSYSTEM and DRIVERS
M: Anton Vorontsov <cbou@mail.ru> M: Anton Vorontsov <anton@enomsg.org>
M: David Woodhouse <dwmw2@infradead.org> M: David Woodhouse <dwmw2@infradead.org>
T: git git://git.infradead.org/battery-2.6.git T: git git://git.infradead.org/battery-2.6.git
S: Maintained S: Maintained
...@@ -6516,7 +6516,7 @@ S: Maintained ...@@ -6516,7 +6516,7 @@ S: Maintained
F: drivers/block/ps3vram.c F: drivers/block/ps3vram.c
PSTORE FILESYSTEM PSTORE FILESYSTEM
M: Anton Vorontsov <cbouatmailru@gmail.com> M: Anton Vorontsov <anton@enomsg.org>
M: Colin Cross <ccross@android.com> M: Colin Cross <ccross@android.com>
M: Kees Cook <keescook@chromium.org> M: Kees Cook <keescook@chromium.org>
M: Tony Luck <tony.luck@intel.com> M: Tony Luck <tony.luck@intel.com>
...@@ -7214,7 +7214,7 @@ F: drivers/mmc/host/sdhci.* ...@@ -7214,7 +7214,7 @@ F: drivers/mmc/host/sdhci.*
F: drivers/mmc/host/sdhci-pltfm.[ch] F: drivers/mmc/host/sdhci-pltfm.[ch]
SECURE DIGITAL HOST CONTROLLER INTERFACE, OPEN FIRMWARE BINDINGS (SDHCI-OF) SECURE DIGITAL HOST CONTROLLER INTERFACE, OPEN FIRMWARE BINDINGS (SDHCI-OF)
M: Anton Vorontsov <avorontsov@ru.mvista.com> M: Anton Vorontsov <anton@enomsg.org>
L: linuxppc-dev@lists.ozlabs.org L: linuxppc-dev@lists.ozlabs.org
L: linux-mmc@vger.kernel.org L: linux-mmc@vger.kernel.org
S: Maintained S: Maintained
......
...@@ -992,7 +992,6 @@ static int pm860x_battery_remove(struct platform_device *pdev) ...@@ -992,7 +992,6 @@ static int pm860x_battery_remove(struct platform_device *pdev)
free_irq(info->irq_batt, info); free_irq(info->irq_batt, info);
free_irq(info->irq_cc, info); free_irq(info->irq_cc, info);
power_supply_unregister(&info->battery); power_supply_unregister(&info->battery);
platform_set_drvdata(pdev, NULL);
return 0; return 0;
} }
......
...@@ -722,7 +722,6 @@ static int pm860x_charger_remove(struct platform_device *pdev) ...@@ -722,7 +722,6 @@ static int pm860x_charger_remove(struct platform_device *pdev)
struct pm860x_charger_info *info = platform_get_drvdata(pdev); struct pm860x_charger_info *info = platform_get_drvdata(pdev);
int i; int i;
platform_set_drvdata(pdev, NULL);
power_supply_unregister(&info->usb); power_supply_unregister(&info->usb);
free_irq(info->irq[0], info); free_irq(info->irq[0], info);
for (i = 0; i < info->irq_nums; i++) for (i = 0; i < info->irq_nums; i++)
......
...@@ -1045,7 +1045,6 @@ static int ab8500_btemp_remove(struct platform_device *pdev) ...@@ -1045,7 +1045,6 @@ static int ab8500_btemp_remove(struct platform_device *pdev)
flush_scheduled_work(); flush_scheduled_work();
power_supply_unregister(&di->btemp_psy); power_supply_unregister(&di->btemp_psy);
platform_set_drvdata(pdev, NULL);
return 0; return 0;
} }
......
...@@ -3425,8 +3425,6 @@ static int ab8500_charger_remove(struct platform_device *pdev) ...@@ -3425,8 +3425,6 @@ static int ab8500_charger_remove(struct platform_device *pdev)
if (di->ac_chg.enabled && !di->ac_chg.external) if (di->ac_chg.enabled && !di->ac_chg.external)
power_supply_unregister(&di->ac_chg.psy); power_supply_unregister(&di->ac_chg.psy);
platform_set_drvdata(pdev, NULL);
return 0; return 0;
} }
......
...@@ -2465,9 +2465,9 @@ static ssize_t charge_full_store(struct ab8500_fg *di, const char *buf, ...@@ -2465,9 +2465,9 @@ static ssize_t charge_full_store(struct ab8500_fg *di, const char *buf,
size_t count) size_t count)
{ {
unsigned long charge_full; 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); 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, ...@@ -2489,7 +2489,7 @@ static ssize_t charge_now_store(struct ab8500_fg *di, const char *buf,
unsigned long charge_now; unsigned long charge_now;
ssize_t ret; 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", dev_dbg(di->dev, "Ret %zd charge_now %lu was %d",
ret, charge_now, di->bat_cap.prev_mah); ret, charge_now, di->bat_cap.prev_mah);
...@@ -3070,7 +3070,6 @@ static int ab8500_fg_remove(struct platform_device *pdev) ...@@ -3070,7 +3070,6 @@ static int ab8500_fg_remove(struct platform_device *pdev)
flush_scheduled_work(); flush_scheduled_work();
ab8500_fg_sysfs_psy_remove_attrs(di->fg_psy.dev); ab8500_fg_sysfs_psy_remove_attrs(di->fg_psy.dev);
power_supply_unregister(&di->fg_psy); power_supply_unregister(&di->fg_psy);
platform_set_drvdata(pdev, NULL);
return ret; return ret;
} }
......
...@@ -2035,7 +2035,6 @@ static int abx500_chargalg_remove(struct platform_device *pdev) ...@@ -2035,7 +2035,6 @@ static int abx500_chargalg_remove(struct platform_device *pdev)
destroy_workqueue(di->chargalg_wq); destroy_workqueue(di->chargalg_wq);
power_supply_unregister(&di->chargalg_psy); power_supply_unregister(&di->chargalg_psy);
platform_set_drvdata(pdev, NULL);
return 0; return 0;
} }
......
...@@ -966,7 +966,6 @@ static int bq27000_battery_probe(struct platform_device *pdev) ...@@ -966,7 +966,6 @@ static int bq27000_battery_probe(struct platform_device *pdev)
return 0; return 0;
err_free: err_free:
platform_set_drvdata(pdev, NULL);
kfree(di); kfree(di);
return ret; return ret;
...@@ -978,7 +977,6 @@ static int bq27000_battery_remove(struct platform_device *pdev) ...@@ -978,7 +977,6 @@ static int bq27000_battery_remove(struct platform_device *pdev)
bq27x00_powersupply_unregister(di); bq27x00_powersupply_unregister(di);
platform_set_drvdata(pdev, NULL);
kfree(di); kfree(di);
return 0; return 0;
......
This diff is collapsed.
...@@ -299,8 +299,10 @@ static int gab_probe(struct platform_device *pdev) ...@@ -299,8 +299,10 @@ static int gab_probe(struct platform_device *pdev)
} }
/* none of the channels are supported so let's bail out */ /* 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; goto second_mem_fail;
}
/* /*
* Total number of properties is equal to static properties * Total number of properties is equal to static properties
......
...@@ -155,8 +155,6 @@ static int gpio_charger_remove(struct platform_device *pdev) ...@@ -155,8 +155,6 @@ static int gpio_charger_remove(struct platform_device *pdev)
gpio_free(gpio_charger->pdata->gpio); gpio_free(gpio_charger->pdata->gpio);
platform_set_drvdata(pdev, NULL);
return 0; return 0;
} }
......
...@@ -756,7 +756,7 @@ static int platform_pmic_battery_probe(struct platform_device *pdev) ...@@ -756,7 +756,7 @@ static int platform_pmic_battery_probe(struct platform_device *pdev)
static int platform_pmic_battery_remove(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); free_irq(pbi->irq, pbi);
cancel_delayed_work_sync(&pbi->monitor_battery); cancel_delayed_work_sync(&pbi->monitor_battery);
......
...@@ -292,7 +292,7 @@ static int jz_battery_probe(struct platform_device *pdev) ...@@ -292,7 +292,7 @@ static int jz_battery_probe(struct platform_device *pdev)
jz_battery); jz_battery);
if (ret) { if (ret) {
dev_err(&pdev->dev, "Failed to request irq %d\n", ret); dev_err(&pdev->dev, "Failed to request irq %d\n", ret);
goto err; return ret;
} }
disable_irq(jz_battery->irq); disable_irq(jz_battery->irq);
...@@ -349,8 +349,6 @@ static int jz_battery_probe(struct platform_device *pdev) ...@@ -349,8 +349,6 @@ static int jz_battery_probe(struct platform_device *pdev)
gpio_free(jz_battery->pdata->gpio_charge); gpio_free(jz_battery->pdata->gpio_charge);
err_free_irq: err_free_irq:
free_irq(jz_battery->irq, jz_battery); free_irq(jz_battery->irq, jz_battery);
err:
platform_set_drvdata(pdev, NULL);
return ret; return ret;
} }
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/power_supply.h> #include <linux/power_supply.h>
#include <linux/platform_data/lp8727.h> #include <linux/platform_data/lp8727.h>
#include <linux/of.h>
#define LP8788_NUM_INTREGS 2 #define LP8788_NUM_INTREGS 2
#define DEFAULT_DEBOUNCE_MSEC 270 #define DEFAULT_DEBOUNCE_MSEC 270
...@@ -481,6 +482,60 @@ static void lp8727_unregister_psy(struct lp8727_chg *pchg) ...@@ -481,6 +482,60 @@ static void lp8727_unregister_psy(struct lp8727_chg *pchg)
power_supply_unregister(&psy->batt); 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 *)&param->eoc_level);
of_property_read_u8(np, "charging-current", (u8 *)&param->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) static int lp8727_probe(struct i2c_client *cl, const struct i2c_device_id *id)
{ {
struct lp8727_chg *pchg; struct lp8727_chg *pchg;
...@@ -489,6 +544,12 @@ static int lp8727_probe(struct i2c_client *cl, const struct i2c_device_id *id) ...@@ -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)) if (!i2c_check_functionality(cl->adapter, I2C_FUNC_SMBUS_I2C_BLOCK))
return -EIO; 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); pchg = devm_kzalloc(&cl->dev, sizeof(*pchg), GFP_KERNEL);
if (!pchg) if (!pchg)
return -ENOMEM; return -ENOMEM;
...@@ -531,6 +592,12 @@ static int lp8727_remove(struct i2c_client *cl) ...@@ -531,6 +592,12 @@ static int lp8727_remove(struct i2c_client *cl)
return 0; 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[] = { static const struct i2c_device_id lp8727_ids[] = {
{"lp8727", 0}, {"lp8727", 0},
{ } { }
...@@ -540,6 +607,7 @@ MODULE_DEVICE_TABLE(i2c, lp8727_ids); ...@@ -540,6 +607,7 @@ MODULE_DEVICE_TABLE(i2c, lp8727_ids);
static struct i2c_driver lp8727_driver = { static struct i2c_driver lp8727_driver = {
.driver = { .driver = {
.name = "lp8727", .name = "lp8727",
.of_match_table = of_match_ptr(lp8727_dt_ids),
}, },
.probe = lp8727_probe, .probe = lp8727_probe,
.remove = lp8727_remove, .remove = lp8727_remove,
......
...@@ -191,9 +191,9 @@ static ssize_t set_usblim(struct device *dev, ...@@ -191,9 +191,9 @@ static ssize_t set_usblim(struct device *dev,
unsigned long ma; unsigned long ma;
int ret; int ret;
ret = strict_strtoul(buf, 10, &ma); ret = kstrtoul(buf, 10, &ma);
if (ret) if (ret)
return -EINVAL; return ret;
pcf50633_mbc_usb_curlim_set(mbc->pcf, ma); pcf50633_mbc_usb_curlim_set(mbc->pcf, ma);
...@@ -228,9 +228,9 @@ static ssize_t set_chglim(struct device *dev, ...@@ -228,9 +228,9 @@ static ssize_t set_chglim(struct device *dev,
if (!mbc->pcf->pdata->charger_reference_current_ma) if (!mbc->pcf->pdata->charger_reference_current_ma)
return -ENODEV; return -ENODEV;
ret = strict_strtoul(buf, 10, &ma); ret = kstrtoul(buf, 10, &ma);
if (ret) if (ret)
return -EINVAL; return ret;
mbcc5 = (ma << 8) / mbc->pcf->pdata->charger_reference_current_ma; mbcc5 = (ma << 8) / mbc->pcf->pdata->charger_reference_current_ma;
if (mbcc5 > 255) if (mbcc5 > 255)
......
...@@ -1007,9 +1007,14 @@ static int pm2xxx_wall_charger_probe(struct i2c_client *i2c_client, ...@@ -1007,9 +1007,14 @@ static int pm2xxx_wall_charger_probe(struct i2c_client *i2c_client,
u8 val; u8 val;
int i; 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); pm2 = kzalloc(sizeof(struct pm2xxx_charger), GFP_KERNEL);
if (!pm2) { if (!pm2) {
dev_err(pm2->dev, "pm2xxx_charger allocation failed\n"); dev_err(&i2c_client->dev, "pm2xxx_charger allocation failed\n");
return -ENOMEM; return -ENOMEM;
} }
...@@ -1070,9 +1075,9 @@ static int pm2xxx_wall_charger_probe(struct i2c_client *i2c_client, ...@@ -1070,9 +1075,9 @@ static int pm2xxx_wall_charger_probe(struct i2c_client *i2c_client,
pm2->ac_chg.external = true; pm2->ac_chg.external = true;
/* Create a work queue for the charger */ /* Create a work queue for the charger */
pm2->charger_wq = pm2->charger_wq = create_singlethread_workqueue("pm2xxx_charger_wq");
create_singlethread_workqueue("pm2xxx_charger_wq");
if (pm2->charger_wq == NULL) { if (pm2->charger_wq == NULL) {
ret = -ENOMEM;
dev_err(pm2->dev, "failed to create work queue\n"); dev_err(pm2->dev, "failed to create work queue\n");
goto free_device_info; goto free_device_info;
} }
......
...@@ -109,8 +109,10 @@ static int __power_supply_populate_supplied_from(struct device *dev, ...@@ -109,8 +109,10 @@ static int __power_supply_populate_supplied_from(struct device *dev,
psy->name, epsy->name); psy->name, epsy->name);
psy->supplied_from[i-1] = (char *)epsy->name; psy->supplied_from[i-1] = (char *)epsy->name;
psy->num_supplies++; psy->num_supplies++;
of_node_put(np);
break; break;
} }
of_node_put(np);
} while (np); } while (np);
return 0; return 0;
...@@ -193,8 +195,10 @@ static int power_supply_check_supplies(struct power_supply *psy) ...@@ -193,8 +195,10 @@ static int power_supply_check_supplies(struct power_supply *psy)
ret = power_supply_find_supply_from_node(np); ret = power_supply_find_supply_from_node(np);
if (ret) { if (ret) {
dev_dbg(psy->dev, "Failed to find supply, defer!\n"); dev_dbg(psy->dev, "Failed to find supply, defer!\n");
of_node_put(np);
return -EPROBE_DEFER; return -EPROBE_DEFER;
} }
of_node_put(np);
} while (np); } while (np);
/* All supplies found, allocate char ** array for filling */ /* All supplies found, allocate char ** array for filling */
......
...@@ -32,7 +32,8 @@ config POWER_RESET_RESTART ...@@ -32,7 +32,8 @@ config POWER_RESET_RESTART
user presses a key. u-boot then boots into Linux. user presses a key. u-boot then boots into Linux.
config POWER_RESET_VEXPRESS config POWER_RESET_VEXPRESS
bool bool "ARM Versatile Express power-off and reset driver"
depends on ARM || ARM64
depends on POWER_RESET depends on POWER_RESET
help help
Power off and reset support for the ARM Ltd. Versatile Power off and reset support for the ARM Ltd. Versatile
......
...@@ -216,10 +216,8 @@ static int rx51_battery_probe(struct platform_device *pdev) ...@@ -216,10 +216,8 @@ static int rx51_battery_probe(struct platform_device *pdev)
di->bat.get_property = rx51_battery_get_property; di->bat.get_property = rx51_battery_get_property;
ret = power_supply_register(di->dev, &di->bat); ret = power_supply_register(di->dev, &di->bat);
if (ret) { if (ret)
platform_set_drvdata(pdev, NULL);
return ret; return ret;
}
return 0; return 0;
} }
...@@ -229,7 +227,6 @@ static int rx51_battery_remove(struct platform_device *pdev) ...@@ -229,7 +227,6 @@ static int rx51_battery_remove(struct platform_device *pdev)
struct rx51_device_info *di = platform_get_drvdata(pdev); struct rx51_device_info *di = platform_get_drvdata(pdev);
power_supply_unregister(&di->bat); power_supply_unregister(&di->bat);
platform_set_drvdata(pdev, NULL);
return 0; return 0;
} }
......
...@@ -704,6 +704,7 @@ static int sbs_probe(struct i2c_client *client, ...@@ -704,6 +704,7 @@ static int sbs_probe(struct i2c_client *client,
chip->power_supply.properties = sbs_properties; chip->power_supply.properties = sbs_properties;
chip->power_supply.num_properties = ARRAY_SIZE(sbs_properties); chip->power_supply.num_properties = ARRAY_SIZE(sbs_properties);
chip->power_supply.get_property = sbs_get_property; 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 /* ignore first notification of external change, it is generated
* from the power_supply_register call back * from the power_supply_register call back
*/ */
......
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#include <linux/mfd/tps65090.h> #include <linux/mfd/tps65090.h>
#define TPS65090_REG_INTR_STS 0x00 #define TPS65090_REG_INTR_STS 0x00
#define TPS65090_REG_INTR_MASK 0x02
#define TPS65090_REG_CG_CTRL0 0x04 #define TPS65090_REG_CG_CTRL0 0x04
#define TPS65090_REG_CG_CTRL1 0x05 #define TPS65090_REG_CG_CTRL1 0x05
#define TPS65090_REG_CG_CTRL2 0x06 #define TPS65090_REG_CG_CTRL2 0x06
...@@ -67,8 +68,7 @@ static int tps65090_low_chrg_current(struct tps65090_charger *charger) ...@@ -67,8 +68,7 @@ static int tps65090_low_chrg_current(struct tps65090_charger *charger)
return 0; return 0;
} }
static int tps65090_enable_charging(struct tps65090_charger *charger, static int tps65090_enable_charging(struct tps65090_charger *charger)
uint8_t enable)
{ {
int ret; int ret;
uint8_t ctrl0 = 0; uint8_t ctrl0 = 0;
...@@ -84,7 +84,7 @@ static int tps65090_enable_charging(struct tps65090_charger *charger, ...@@ -84,7 +84,7 @@ static int tps65090_enable_charging(struct tps65090_charger *charger,
ret = tps65090_write(charger->dev->parent, TPS65090_REG_CG_CTRL0, ret = tps65090_write(charger->dev->parent, TPS65090_REG_CG_CTRL0,
(ctrl0 | TPS65090_CHARGER_ENABLE)); (ctrl0 | TPS65090_CHARGER_ENABLE));
if (ret < 0) { 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); __func__, TPS65090_REG_CG_CTRL0);
return ret; return ret;
} }
...@@ -93,6 +93,7 @@ static int tps65090_enable_charging(struct tps65090_charger *charger, ...@@ -93,6 +93,7 @@ static int tps65090_enable_charging(struct tps65090_charger *charger,
static int tps65090_config_charger(struct tps65090_charger *charger) static int tps65090_config_charger(struct tps65090_charger *charger)
{ {
uint8_t intrmask = 0;
int ret; int ret;
if (charger->pdata->enable_low_current_chrg) { if (charger->pdata->enable_low_current_chrg) {
...@@ -104,6 +105,23 @@ static int tps65090_config_charger(struct tps65090_charger *charger) ...@@ -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; return 0;
} }
...@@ -146,7 +164,7 @@ static irqreturn_t tps65090_charger_isr(int irq, void *dev_id) ...@@ -146,7 +164,7 @@ static irqreturn_t tps65090_charger_isr(int irq, void *dev_id)
} }
if (intrsts & TPS65090_VACG) { if (intrsts & TPS65090_VACG) {
ret = tps65090_enable_charging(charger, 1); ret = tps65090_enable_charging(charger);
if (ret < 0) if (ret < 0)
return IRQ_HANDLED; return IRQ_HANDLED;
charger->ac_online = 1; charger->ac_online = 1;
...@@ -154,6 +172,13 @@ static irqreturn_t tps65090_charger_isr(int irq, void *dev_id) ...@@ -154,6 +172,13 @@ static irqreturn_t tps65090_charger_isr(int irq, void *dev_id)
charger->ac_online = 0; 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) if (charger->prev_ac_online != charger->ac_online)
power_supply_changed(&charger->ac); power_supply_changed(&charger->ac);
...@@ -218,7 +243,7 @@ static int tps65090_charger_probe(struct platform_device *pdev) ...@@ -218,7 +243,7 @@ static int tps65090_charger_probe(struct platform_device *pdev)
return -ENOMEM; return -ENOMEM;
} }
dev_set_drvdata(&pdev->dev, cdata); platform_set_drvdata(pdev, cdata);
cdata->dev = &pdev->dev; cdata->dev = &pdev->dev;
cdata->pdata = pdata; cdata->pdata = pdata;
...@@ -230,6 +255,7 @@ static int tps65090_charger_probe(struct platform_device *pdev) ...@@ -230,6 +255,7 @@ static int tps65090_charger_probe(struct platform_device *pdev)
cdata->ac.num_properties = ARRAY_SIZE(tps65090_ac_props); cdata->ac.num_properties = ARRAY_SIZE(tps65090_ac_props);
cdata->ac.supplied_to = pdata->supplied_to; cdata->ac.supplied_to = pdata->supplied_to;
cdata->ac.num_supplicants = pdata->num_supplicants; cdata->ac.num_supplicants = pdata->num_supplicants;
cdata->ac.of_node = pdev->dev.of_node;
ret = power_supply_register(&pdev->dev, &cdata->ac); ret = power_supply_register(&pdev->dev, &cdata->ac);
if (ret) { if (ret) {
...@@ -270,7 +296,7 @@ static int tps65090_charger_probe(struct platform_device *pdev) ...@@ -270,7 +296,7 @@ static int tps65090_charger_probe(struct platform_device *pdev)
} }
if (status1 != 0) { if (status1 != 0) {
ret = tps65090_enable_charging(cdata, 1); ret = tps65090_enable_charging(cdata);
if (ret < 0) { if (ret < 0) {
dev_err(cdata->dev, "error enabling charger\n"); dev_err(cdata->dev, "error enabling charger\n");
goto fail_free_irq; goto fail_free_irq;
...@@ -291,7 +317,7 @@ static int tps65090_charger_probe(struct platform_device *pdev) ...@@ -291,7 +317,7 @@ static int tps65090_charger_probe(struct platform_device *pdev)
static int tps65090_charger_remove(struct platform_device *pdev) 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); devm_free_irq(cdata->dev, cdata->irq, cdata);
power_supply_unregister(&cdata->ac); power_supply_unregister(&cdata->ac);
......
...@@ -594,7 +594,6 @@ static int __init twl4030_bci_probe(struct platform_device *pdev) ...@@ -594,7 +594,6 @@ static int __init twl4030_bci_probe(struct platform_device *pdev)
fail_register_usb: fail_register_usb:
power_supply_unregister(&bci->ac); power_supply_unregister(&bci->ac);
fail_register_ac: fail_register_ac:
platform_set_drvdata(pdev, NULL);
kfree(bci); kfree(bci);
return ret; return ret;
...@@ -622,7 +621,6 @@ static int __exit twl4030_bci_remove(struct platform_device *pdev) ...@@ -622,7 +621,6 @@ static int __exit twl4030_bci_remove(struct platform_device *pdev)
free_irq(bci->irq_chg, bci); free_irq(bci->irq_chg, bci);
power_supply_unregister(&bci->usb); power_supply_unregister(&bci->usb);
power_supply_unregister(&bci->ac); power_supply_unregister(&bci->ac);
platform_set_drvdata(pdev, NULL);
kfree(bci); kfree(bci);
return 0; return 0;
......
...@@ -162,6 +162,8 @@ union power_supply_propval { ...@@ -162,6 +162,8 @@ union power_supply_propval {
const char *strval; const char *strval;
}; };
struct device_node;
struct power_supply { struct power_supply {
const char *name; const char *name;
enum power_supply_type type; enum power_supply_type type;
...@@ -173,9 +175,7 @@ struct power_supply { ...@@ -173,9 +175,7 @@ struct power_supply {
char **supplied_from; char **supplied_from;
size_t num_supplies; size_t num_supplies;
#ifdef CONFIG_OF
struct device_node *of_node; struct device_node *of_node;
#endif
int (*get_property)(struct power_supply *psy, int (*get_property)(struct power_supply *psy,
enum power_supply_property psp, enum power_supply_property psp,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment