summaryrefslogtreecommitdiffstats
path: root/drivers/power
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/power')
-rw-r--r--drivers/power/reset/gpio-restart.c2
-rw-r--r--drivers/power/reset/reboot-mode.c2
-rw-r--r--drivers/power/supply/Kconfig13
-rw-r--r--drivers/power/supply/Makefile1
-rw-r--r--drivers/power/supply/ab8500_charger.c8
-rw-r--r--drivers/power/supply/axp288_fuel_gauge.c14
-rw-r--r--drivers/power/supply/bq25890_charger.c12
-rw-r--r--drivers/power/supply/cpcap-charger.c23
-rw-r--r--drivers/power/supply/cros_usbpd-charger.c5
-rw-r--r--drivers/power/supply/isp1704_charger.c2
-rw-r--r--drivers/power/supply/jz4740-battery.c421
-rw-r--r--drivers/power/supply/max17042_battery.c8
-rw-r--r--drivers/power/supply/max77650-charger.c1
-rw-r--r--drivers/power/supply/power_supply_core.c10
-rw-r--r--drivers/power/supply/power_supply_hwmon.c15
-rw-r--r--drivers/power/supply/sbs-battery.c27
-rw-r--r--drivers/power/supply/sc27xx_fuel_gauge.c223
17 files changed, 236 insertions, 551 deletions
diff --git a/drivers/power/reset/gpio-restart.c b/drivers/power/reset/gpio-restart.c
index 2880cd5ae0d2..308ca9d9d276 100644
--- a/drivers/power/reset/gpio-restart.c
+++ b/drivers/power/reset/gpio-restart.c
@@ -65,7 +65,7 @@ static int gpio_restart_probe(struct platform_device *pdev)
gpio_restart->reset_gpio = devm_gpiod_get(&pdev->dev, NULL,
open_source ? GPIOD_IN : GPIOD_OUT_LOW);
if (IS_ERR(gpio_restart->reset_gpio)) {
- dev_err(&pdev->dev, "Could net get reset GPIO\n");
+ dev_err(&pdev->dev, "Could not get reset GPIO\n");
return PTR_ERR(gpio_restart->reset_gpio);
}
diff --git a/drivers/power/reset/reboot-mode.c b/drivers/power/reset/reboot-mode.c
index 06ff035b57f5..b4076b10b893 100644
--- a/drivers/power/reset/reboot-mode.c
+++ b/drivers/power/reset/reboot-mode.c
@@ -190,6 +190,6 @@ void devm_reboot_mode_unregister(struct device *dev,
}
EXPORT_SYMBOL_GPL(devm_reboot_mode_unregister);
-MODULE_AUTHOR("Andy Yan <andy.yan@rock-chips.com");
+MODULE_AUTHOR("Andy Yan <andy.yan@rock-chips.com>");
MODULE_DESCRIPTION("System reboot mode core library");
MODULE_LICENSE("GPL v2");
diff --git a/drivers/power/supply/Kconfig b/drivers/power/supply/Kconfig
index 5d91b5160b41..c84a7b1caeb6 100644
--- a/drivers/power/supply/Kconfig
+++ b/drivers/power/supply/Kconfig
@@ -417,17 +417,6 @@ config CHARGER_PCF50633
help
Say Y to include support for NXP PCF50633 Main Battery Charger.
-config BATTERY_JZ4740
- tristate "Ingenic JZ4740 battery"
- depends on MACH_JZ4740
- depends on MFD_JZ4740_ADC
- help
- Say Y to enable support for the battery on Ingenic JZ4740 based
- boards.
-
- This driver can be build as a module. If so, the module will be
- called jz4740-battery.
-
config BATTERY_RX51
tristate "Nokia RX-51 (N900) battery driver"
depends on TWL4030_MADC
@@ -670,7 +659,7 @@ config CHARGER_RT9455
config CHARGER_CROS_USBPD
tristate "ChromeOS EC based USBPD charger"
- depends on MFD_CROS_EC
+ depends on CROS_EC
default n
help
Say Y here to enable ChromeOS EC based USBPD charger
diff --git a/drivers/power/supply/Makefile b/drivers/power/supply/Makefile
index 96c2b74b36bf..6c7da920ea83 100644
--- a/drivers/power/supply/Makefile
+++ b/drivers/power/supply/Makefile
@@ -58,7 +58,6 @@ obj-$(CONFIG_BATTERY_S3C_ADC) += s3c_adc_battery.o
obj-$(CONFIG_BATTERY_TWL4030_MADC) += twl4030_madc_battery.o
obj-$(CONFIG_CHARGER_88PM860X) += 88pm860x_charger.o
obj-$(CONFIG_CHARGER_PCF50633) += pcf50633-charger.o
-obj-$(CONFIG_BATTERY_JZ4740) += jz4740-battery.o
obj-$(CONFIG_BATTERY_RX51) += rx51_battery.o
obj-$(CONFIG_AB8500_BM) += ab8500_bmdata.o ab8500_charger.o ab8500_fg.o ab8500_btemp.o abx500_chargalg.o pm2301_charger.o
obj-$(CONFIG_CHARGER_CPCAP) += cpcap-charger.o
diff --git a/drivers/power/supply/ab8500_charger.c b/drivers/power/supply/ab8500_charger.c
index 30de448de802..e51d0e72beea 100644
--- a/drivers/power/supply/ab8500_charger.c
+++ b/drivers/power/supply/ab8500_charger.c
@@ -742,6 +742,7 @@ static int ab8500_charger_max_usb_curr(struct ab8500_charger *di,
USB_CH_IP_CUR_LVL_1P5;
break;
}
+ /* else, fall through */
case USB_STAT_HM_IDGND:
dev_err(di->dev, "USB Type - Charging not allowed\n");
di->max_usb_in_curr.usb_type_max = USB_CH_IP_CUR_LVL_0P05;
@@ -3010,7 +3011,6 @@ static int ab8500_charger_usb_get_property(struct power_supply *psy,
static int ab8500_charger_init_hw_registers(struct ab8500_charger *di)
{
int ret = 0;
- u8 bup_vch_range = 0, vbup33_vrtcn = 0;
/* Setup maximum charger current and voltage for ABB cut2.0 */
if (!is_ab8500_1p1_or_earlier(di->parent)) {
@@ -3111,12 +3111,6 @@ static int ab8500_charger_init_hw_registers(struct ab8500_charger *di)
goto out;
}
- /* Backup battery voltage and current */
- if (di->bm->bkup_bat_v > BUP_VCH_SEL_3P1V)
- bup_vch_range = BUP_VCH_RANGE;
- if (di->bm->bkup_bat_v == BUP_VCH_SEL_3P3V)
- vbup33_vrtcn = VBUP33_VRTCN;
-
ret = abx500_set_register_interruptible(di->dev,
AB8500_RTC,
AB8500_RTC_BACKUP_CHG_REG,
diff --git a/drivers/power/supply/axp288_fuel_gauge.c b/drivers/power/supply/axp288_fuel_gauge.c
index 44169dabb705..e1bc4e6e6f30 100644
--- a/drivers/power/supply/axp288_fuel_gauge.c
+++ b/drivers/power/supply/axp288_fuel_gauge.c
@@ -674,6 +674,7 @@ intr_failed:
/*
* Some devices have no battery (HDMI sticks) and the axp288 battery's
* detection reports one despite it not being there.
+ * Please keep this listed sorted alphabetically.
*/
static const struct dmi_system_id axp288_fuel_gauge_blacklist[] = {
{
@@ -697,6 +698,12 @@ static const struct dmi_system_id axp288_fuel_gauge_blacklist[] = {
},
},
{
+ /* ECS EF20EA */
+ .matches = {
+ DMI_MATCH(DMI_PRODUCT_NAME, "EF20EA"),
+ },
+ },
+ {
/* Intel Cherry Trail Compute Stick, Windows version */
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"),
@@ -720,10 +727,11 @@ static const struct dmi_system_id axp288_fuel_gauge_blacklist[] = {
},
},
{
- /* ECS EF20EA */
+ /* Minix Neo Z83-4 mini PC */
.matches = {
- DMI_MATCH(DMI_PRODUCT_NAME, "EF20EA"),
- },
+ DMI_MATCH(DMI_SYS_VENDOR, "MINIX"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Z83-4"),
+ }
},
{}
};
diff --git a/drivers/power/supply/bq25890_charger.c b/drivers/power/supply/bq25890_charger.c
index d333f2b321b9..9d1ec8d677de 100644
--- a/drivers/power/supply/bq25890_charger.c
+++ b/drivers/power/supply/bq25890_charger.c
@@ -22,6 +22,7 @@
#define BQ25890_IRQ_PIN "bq25890_irq"
#define BQ25890_ID 3
+#define BQ25895_ID 7
#define BQ25896_ID 0
enum bq25890_fields {
@@ -171,7 +172,7 @@ static const struct reg_field bq25890_reg_fields[] = {
[F_WD] = REG_FIELD(0x07, 4, 5),
[F_TMR_EN] = REG_FIELD(0x07, 3, 3),
[F_CHG_TMR] = REG_FIELD(0x07, 1, 2),
- [F_JEITA_ISET] = REG_FIELD(0x07, 0, 0),
+ [F_JEITA_ISET] = REG_FIELD(0x07, 0, 0), // reserved on BQ25895
/* REG08 */
[F_BATCMP] = REG_FIELD(0x08, 5, 7),
[F_VCLAMP] = REG_FIELD(0x08, 2, 4),
@@ -180,7 +181,7 @@ static const struct reg_field bq25890_reg_fields[] = {
[F_FORCE_ICO] = REG_FIELD(0x09, 7, 7),
[F_TMR2X_EN] = REG_FIELD(0x09, 6, 6),
[F_BATFET_DIS] = REG_FIELD(0x09, 5, 5),
- [F_JEITA_VSET] = REG_FIELD(0x09, 4, 4),
+ [F_JEITA_VSET] = REG_FIELD(0x09, 4, 4), // reserved on BQ25895
[F_BATFET_DLY] = REG_FIELD(0x09, 3, 3),
[F_BATFET_RST_EN] = REG_FIELD(0x09, 2, 2),
[F_PUMPX_UP] = REG_FIELD(0x09, 1, 1),
@@ -188,7 +189,7 @@ static const struct reg_field bq25890_reg_fields[] = {
/* REG0A */
[F_BOOSTV] = REG_FIELD(0x0A, 4, 7),
/* PFM_OTG_DIS 3 on BQ25896 */
- [F_BOOSTI] = REG_FIELD(0x0A, 0, 2),
+ [F_BOOSTI] = REG_FIELD(0x0A, 0, 2), // reserved on BQ25895
/* REG0B */
[F_VBUS_STAT] = REG_FIELD(0x0B, 5, 7),
[F_CHG_STAT] = REG_FIELD(0x0B, 3, 4),
@@ -392,6 +393,8 @@ static int bq25890_power_supply_get_property(struct power_supply *psy,
case POWER_SUPPLY_PROP_MODEL_NAME:
if (bq->chip_id == BQ25890_ID)
val->strval = "BQ25890";
+ else if (bq->chip_id == BQ25895_ID)
+ val->strval = "BQ25895";
else if (bq->chip_id == BQ25896_ID)
val->strval = "BQ25896";
else
@@ -862,7 +865,8 @@ static int bq25890_probe(struct i2c_client *client,
return bq->chip_id;
}
- if ((bq->chip_id != BQ25890_ID) && (bq->chip_id != BQ25896_ID)) {
+ if ((bq->chip_id != BQ25890_ID) && (bq->chip_id != BQ25895_ID)
+ && (bq->chip_id != BQ25896_ID)) {
dev_err(dev, "Chip with ID=%d, not supported!\n", bq->chip_id);
return -ENODEV;
}
diff --git a/drivers/power/supply/cpcap-charger.c b/drivers/power/supply/cpcap-charger.c
index cc546bc40a78..74258c7fe17d 100644
--- a/drivers/power/supply/cpcap-charger.c
+++ b/drivers/power/supply/cpcap-charger.c
@@ -108,6 +108,9 @@
#define CPCAP_REG_CRM_ICHRG_1A596 CPCAP_REG_CRM_ICHRG(0xe)
#define CPCAP_REG_CRM_ICHRG_NO_LIMIT CPCAP_REG_CRM_ICHRG(0xf)
+/* CPCAP_REG_VUSBC register bits needed for VBUS */
+#define CPCAP_BIT_VBUS_SWITCH BIT(0) /* VBUS boost to 5V */
+
enum {
CPCAP_CHARGER_IIO_BATTDET,
CPCAP_CHARGER_IIO_VOLTAGE,
@@ -130,7 +133,8 @@ struct cpcap_charger_ddata {
struct power_supply *usb;
struct phy_companion comparator; /* For USB VBUS */
- bool vbus_enabled;
+ unsigned int vbus_enabled:1;
+ unsigned int feeding_vbus:1;
atomic_t active;
int status;
@@ -325,7 +329,6 @@ static bool cpcap_charger_vbus_valid(struct cpcap_charger_ddata *ddata)
}
/* VBUS control functions for the USB PHY companion */
-
static void cpcap_charger_vbus_work(struct work_struct *work)
{
struct cpcap_charger_ddata *ddata;
@@ -343,6 +346,7 @@ static void cpcap_charger_vbus_work(struct work_struct *work)
return;
}
+ ddata->feeding_vbus = true;
cpcap_charger_set_cable_path(ddata, false);
cpcap_charger_set_inductive_path(ddata, false);
@@ -350,12 +354,23 @@ static void cpcap_charger_vbus_work(struct work_struct *work)
if (error)
goto out_err;
+ error = regmap_update_bits(ddata->reg, CPCAP_REG_VUSBC,
+ CPCAP_BIT_VBUS_SWITCH,
+ CPCAP_BIT_VBUS_SWITCH);
+ if (error)
+ goto out_err;
+
error = regmap_update_bits(ddata->reg, CPCAP_REG_CRM,
CPCAP_REG_CRM_RVRSMODE,
CPCAP_REG_CRM_RVRSMODE);
if (error)
goto out_err;
} else {
+ error = regmap_update_bits(ddata->reg, CPCAP_REG_VUSBC,
+ CPCAP_BIT_VBUS_SWITCH, 0);
+ if (error)
+ goto out_err;
+
error = regmap_update_bits(ddata->reg, CPCAP_REG_CRM,
CPCAP_REG_CRM_RVRSMODE, 0);
if (error)
@@ -363,6 +378,7 @@ static void cpcap_charger_vbus_work(struct work_struct *work)
cpcap_charger_set_cable_path(ddata, true);
cpcap_charger_set_inductive_path(ddata, true);
+ ddata->feeding_vbus = false;
}
return;
@@ -431,7 +447,8 @@ static void cpcap_usb_detect(struct work_struct *work)
if (error)
return;
- if (cpcap_charger_vbus_valid(ddata) && s.chrgcurr1) {
+ if (!ddata->feeding_vbus && cpcap_charger_vbus_valid(ddata) &&
+ s.chrgcurr1) {
int max_current;
if (cpcap_charger_battery_found(ddata))
diff --git a/drivers/power/supply/cros_usbpd-charger.c b/drivers/power/supply/cros_usbpd-charger.c
index 3a9ea94c3de3..6cc7c3910e09 100644
--- a/drivers/power/supply/cros_usbpd-charger.c
+++ b/drivers/power/supply/cros_usbpd-charger.c
@@ -5,9 +5,10 @@
* Copyright (c) 2014 - 2018 Google, Inc
*/
-#include <linux/module.h>
#include <linux/mfd/cros_ec.h>
-#include <linux/mfd/cros_ec_commands.h>
+#include <linux/module.h>
+#include <linux/platform_data/cros_ec_commands.h>
+#include <linux/platform_data/cros_ec_proto.h>
#include <linux/platform_device.h>
#include <linux/power_supply.h>
#include <linux/slab.h>
diff --git a/drivers/power/supply/isp1704_charger.c b/drivers/power/supply/isp1704_charger.c
index b48cb7aba97b..4812ac1ff2df 100644
--- a/drivers/power/supply/isp1704_charger.c
+++ b/drivers/power/supply/isp1704_charger.c
@@ -342,7 +342,7 @@ static inline int isp1704_test_ulpi(struct isp1704_charger *isp)
int vendor;
int product;
int i;
- int ret = -ENODEV;
+ int ret;
/* Test ULPI interface */
ret = isp1704_write(isp, ULPI_SCRATCH, 0xaa);
diff --git a/drivers/power/supply/jz4740-battery.c b/drivers/power/supply/jz4740-battery.c
deleted file mode 100644
index 6366bd61ea9f..000000000000
--- a/drivers/power/supply/jz4740-battery.c
+++ /dev/null
@@ -1,421 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Battery measurement code for Ingenic JZ SOC.
- *
- * Copyright (C) 2009 Jiejing Zhang <kzjeef@gmail.com>
- * Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
- *
- * based on tosa_battery.c
- *
- * Copyright (C) 2008 Marek Vasut <marek.vasut@gmail.com>
- */
-
-#include <linux/interrupt.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-#include <linux/io.h>
-
-#include <linux/delay.h>
-#include <linux/err.h>
-#include <linux/gpio.h>
-#include <linux/mfd/core.h>
-#include <linux/power_supply.h>
-
-#include <linux/power/jz4740-battery.h>
-#include <linux/jz4740-adc.h>
-
-struct jz_battery {
- struct jz_battery_platform_data *pdata;
- struct platform_device *pdev;
-
- void __iomem *base;
-
- int irq;
- int charge_irq;
-
- const struct mfd_cell *cell;
-
- int status;
- long voltage;
-
- struct completion read_completion;
-
- struct power_supply *battery;
- struct power_supply_desc battery_desc;
- struct delayed_work work;
-
- struct mutex lock;
-};
-
-static inline struct jz_battery *psy_to_jz_battery(struct power_supply *psy)
-{
- return power_supply_get_drvdata(psy);
-}
-
-static irqreturn_t jz_battery_irq_handler(int irq, void *devid)
-{
- struct jz_battery *battery = devid;
-
- complete(&battery->read_completion);
- return IRQ_HANDLED;
-}
-
-static long jz_battery_read_voltage(struct jz_battery *battery)
-{
- long t;
- unsigned long val;
- long voltage;
-
- mutex_lock(&battery->lock);
-
- reinit_completion(&battery->read_completion);
-
- enable_irq(battery->irq);
- battery->cell->enable(battery->pdev);
-
- t = wait_for_completion_interruptible_timeout(&battery->read_completion,
- HZ);
-
- if (t > 0) {
- val = readw(battery->base) & 0xfff;
-
- if (battery->pdata->info.voltage_max_design <= 2500000)
- val = (val * 78125UL) >> 7UL;
- else
- val = ((val * 924375UL) >> 9UL) + 33000;
- voltage = (long)val;
- } else {
- voltage = t ? t : -ETIMEDOUT;
- }
-
- battery->cell->disable(battery->pdev);
- disable_irq(battery->irq);
-
- mutex_unlock(&battery->lock);
-
- return voltage;
-}
-
-static int jz_battery_get_capacity(struct power_supply *psy)
-{
- struct jz_battery *jz_battery = psy_to_jz_battery(psy);
- struct power_supply_info *info = &jz_battery->pdata->info;
- long voltage;
- int ret;
- int voltage_span;
-
- voltage = jz_battery_read_voltage(jz_battery);
-
- if (voltage < 0)
- return voltage;
-
- voltage_span = info->voltage_max_design - info->voltage_min_design;
- ret = ((voltage - info->voltage_min_design) * 100) / voltage_span;
-
- if (ret > 100)
- ret = 100;
- else if (ret < 0)
- ret = 0;
-
- return ret;
-}
-
-static int jz_battery_get_property(struct power_supply *psy,
- enum power_supply_property psp, union power_supply_propval *val)
-{
- struct jz_battery *jz_battery = psy_to_jz_battery(psy);
- struct power_supply_info *info = &jz_battery->pdata->info;
- long voltage;
-
- switch (psp) {
- case POWER_SUPPLY_PROP_STATUS:
- val->intval = jz_battery->status;
- break;
- case POWER_SUPPLY_PROP_TECHNOLOGY:
- val->intval = jz_battery->pdata->info.technology;
- break;
- case POWER_SUPPLY_PROP_HEALTH:
- voltage = jz_battery_read_voltage(jz_battery);
- if (voltage < info->voltage_min_design)
- val->intval = POWER_SUPPLY_HEALTH_DEAD;
- else
- val->intval = POWER_SUPPLY_HEALTH_GOOD;
- break;
- case POWER_SUPPLY_PROP_CAPACITY:
- val->intval = jz_battery_get_capacity(psy);
- break;
- case POWER_SUPPLY_PROP_VOLTAGE_NOW:
- val->intval = jz_battery_read_voltage(jz_battery);
- if (val->intval < 0)
- return val->intval;
- break;
- case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN:
- val->intval = info->voltage_max_design;
- break;
- case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN:
- val->intval = info->voltage_min_design;
- break;
- case POWER_SUPPLY_PROP_PRESENT:
- val->intval = 1;
- break;
- default:
- return -EINVAL;
- }
- return 0;
-}
-
-static void jz_battery_external_power_changed(struct power_supply *psy)
-{
- struct jz_battery *jz_battery = psy_to_jz_battery(psy);
-
- mod_delayed_work(system_wq, &jz_battery->work, 0);
-}
-
-static irqreturn_t jz_battery_charge_irq(int irq, void *data)
-{
- struct jz_battery *jz_battery = data;
-
- mod_delayed_work(system_wq, &jz_battery->work, 0);
-
- return IRQ_HANDLED;
-}
-
-static void jz_battery_update(struct jz_battery *jz_battery)
-{
- int status;
- long voltage;
- bool has_changed = false;
- int is_charging;
-
- if (gpio_is_valid(jz_battery->pdata->gpio_charge)) {
- is_charging = gpio_get_value(jz_battery->pdata->gpio_charge);
- is_charging ^= jz_battery->pdata->gpio_charge_active_low;
- if (is_charging)
- status = POWER_SUPPLY_STATUS_CHARGING;
- else
- status = POWER_SUPPLY_STATUS_NOT_CHARGING;
-
- if (status != jz_battery->status) {
- jz_battery->status = status;
- has_changed = true;
- }
- }
-
- voltage = jz_battery_read_voltage(jz_battery);
- if (voltage >= 0 && abs(voltage - jz_battery->voltage) > 50000) {
- jz_battery->voltage = voltage;
- has_changed = true;
- }
-
- if (has_changed)
- power_supply_changed(jz_battery->battery);
-}
-
-static enum power_supply_property jz_battery_properties[] = {
- POWER_SUPPLY_PROP_STATUS,
- POWER_SUPPLY_PROP_TECHNOLOGY,
- POWER_SUPPLY_PROP_HEALTH,
- POWER_SUPPLY_PROP_CAPACITY,
- POWER_SUPPLY_PROP_VOLTAGE_NOW,
- POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN,
- POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
- POWER_SUPPLY_PROP_PRESENT,
-};
-
-static void jz_battery_work(struct work_struct *work)
-{
- /* Too small interval will increase system workload */
- const int interval = HZ * 30;
- struct jz_battery *jz_battery = container_of(work, struct jz_battery,
- work.work);
-
- jz_battery_update(jz_battery);
- schedule_delayed_work(&jz_battery->work, interval);
-}
-
-static int jz_battery_probe(struct platform_device *pdev)
-{
- int ret = 0;
- struct jz_battery_platform_data *pdata = pdev->dev.parent->platform_data;
- struct power_supply_config psy_cfg = {};
- struct jz_battery *jz_battery;
- struct power_supply_desc *battery_desc;
- struct resource *mem;
-
- if (!pdata) {
- dev_err(&pdev->dev, "No platform_data supplied\n");
- return -ENXIO;
- }
-
- jz_battery = devm_kzalloc(&pdev->dev, sizeof(*jz_battery), GFP_KERNEL);
- if (!jz_battery) {
- dev_err(&pdev->dev, "Failed to allocate driver structure\n");
- return -ENOMEM;
- }
-
- jz_battery->cell = mfd_get_cell(pdev);
-
- jz_battery->irq = platform_get_irq(pdev, 0);
- if (jz_battery->irq < 0) {
- dev_err(&pdev->dev, "Failed to get platform irq: %d\n", ret);
- return jz_battery->irq;
- }
-
- mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-
- jz_battery->base = devm_ioremap_resource(&pdev->dev, mem);
- if (IS_ERR(jz_battery->base))
- return PTR_ERR(jz_battery->base);
-
- battery_desc = &jz_battery->battery_desc;
- battery_desc->name = pdata->info.name;
- battery_desc->type = POWER_SUPPLY_TYPE_BATTERY;
- battery_desc->properties = jz_battery_properties;
- battery_desc->num_properties = ARRAY_SIZE(jz_battery_properties);
- battery_desc->get_property = jz_battery_get_property;
- battery_desc->external_power_changed =
- jz_battery_external_power_changed;
- battery_desc->use_for_apm = 1;
-
- psy_cfg.drv_data = jz_battery;
-
- jz_battery->pdata = pdata;
- jz_battery->pdev = pdev;
-
- init_completion(&jz_battery->read_completion);
- mutex_init(&jz_battery->lock);
-
- INIT_DELAYED_WORK(&jz_battery->work, jz_battery_work);
-
- ret = request_irq(jz_battery->irq, jz_battery_irq_handler, 0, pdev->name,
- jz_battery);
- if (ret) {
- dev_err(&pdev->dev, "Failed to request irq %d\n", ret);
- return ret;
- }
- disable_irq(jz_battery->irq);
-
- if (gpio_is_valid(pdata->gpio_charge)) {
- ret = gpio_request(pdata->gpio_charge, dev_name(&pdev->dev));
- if (ret) {
- dev_err(&pdev->dev, "charger state gpio request failed.\n");
- goto err_free_irq;
- }
- ret = gpio_direction_input(pdata->gpio_charge);
- if (ret) {
- dev_err(&pdev->dev, "charger state gpio set direction failed.\n");
- goto err_free_gpio;
- }
-
- jz_battery->charge_irq = gpio_to_irq(pdata->gpio_charge);
-
- if (jz_battery->charge_irq >= 0) {
- ret = request_irq(jz_battery->charge_irq,
- jz_battery_charge_irq,
- IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
- dev_name(&pdev->dev), jz_battery);
- if (ret) {
- dev_err(&pdev->dev, "Failed to request charge irq: %d\n", ret);
- goto err_free_gpio;
- }
- }
- } else {
- jz_battery->charge_irq = -1;
- }
-
- if (jz_battery->pdata->info.voltage_max_design <= 2500000)
- jz4740_adc_set_config(pdev->dev.parent, JZ_ADC_CONFIG_BAT_MB,
- JZ_ADC_CONFIG_BAT_MB);
- else
- jz4740_adc_set_config(pdev->dev.parent, JZ_ADC_CONFIG_BAT_MB, 0);
-
- jz_battery->battery = power_supply_register(&pdev->dev, battery_desc,
- &psy_cfg);
- if (IS_ERR(jz_battery->battery)) {
- dev_err(&pdev->dev, "power supply battery register failed.\n");
- ret = PTR_ERR(jz_battery->battery);
- goto err_free_charge_irq;
- }
-
- platform_set_drvdata(pdev, jz_battery);
- schedule_delayed_work(&jz_battery->work, 0);
-
- return 0;
-
-err_free_charge_irq:
- if (jz_battery->charge_irq >= 0)
- free_irq(jz_battery->charge_irq, jz_battery);
-err_free_gpio:
- if (gpio_is_valid(pdata->gpio_charge))
- gpio_free(jz_battery->pdata->gpio_charge);
-err_free_irq:
- free_irq(jz_battery->irq, jz_battery);
- return ret;
-}
-
-static int jz_battery_remove(struct platform_device *pdev)
-{
- struct jz_battery *jz_battery = platform_get_drvdata(pdev);
-
- cancel_delayed_work_sync(&jz_battery->work);
-
- if (gpio_is_valid(jz_battery->pdata->gpio_charge)) {
- if (jz_battery->charge_irq >= 0)
- free_irq(jz_battery->charge_irq, jz_battery);
- gpio_free(jz_battery->pdata->gpio_charge);
- }
-
- power_supply_unregister(jz_battery->battery);
-
- free_irq(jz_battery->irq, jz_battery);
-
- return 0;
-}
-
-#ifdef CONFIG_PM
-static int jz_battery_suspend(struct device *dev)
-{
- struct jz_battery *jz_battery = dev_get_drvdata(dev);
-
- cancel_delayed_work_sync(&jz_battery->work);
- jz_battery->status = POWER_SUPPLY_STATUS_UNKNOWN;
-
- return 0;
-}
-
-static int jz_battery_resume(struct device *dev)
-{
- struct jz_battery *jz_battery = dev_get_drvdata(dev);
-
- schedule_delayed_work(&jz_battery->work, 0);
-
- return 0;
-}
-
-static const struct dev_pm_ops jz_battery_pm_ops = {
- .suspend = jz_battery_suspend,
- .resume = jz_battery_resume,
-};
-
-#define JZ_BATTERY_PM_OPS (&jz_battery_pm_ops)
-#else
-#define JZ_BATTERY_PM_OPS NULL
-#endif
-
-static struct platform_driver jz_battery_driver = {
- .probe = jz_battery_probe,
- .remove = jz_battery_remove,
- .driver = {
- .name = "jz4740-battery",
- .pm = JZ_BATTERY_PM_OPS,
- },
-};
-
-module_platform_driver(jz_battery_driver);
-
-MODULE_ALIAS("platform:jz4740-battery");
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
-MODULE_DESCRIPTION("JZ4740 SoC battery driver");
diff --git a/drivers/power/supply/max17042_battery.c b/drivers/power/supply/max17042_battery.c
index 64f3358eaa3c..0dfad2cf13fe 100644
--- a/drivers/power/supply/max17042_battery.c
+++ b/drivers/power/supply/max17042_battery.c
@@ -511,7 +511,7 @@ static inline void max17042_override_por(struct regmap *map,
regmap_write(map, reg, value);
}
-static inline void max10742_unlock_model(struct max17042_chip *chip)
+static inline void max17042_unlock_model(struct max17042_chip *chip)
{
struct regmap *map = chip->regmap;
@@ -519,7 +519,7 @@ static inline void max10742_unlock_model(struct max17042_chip *chip)
regmap_write(map, MAX17042_MLOCKReg2, MODEL_UNLOCK2);
}
-static inline void max10742_lock_model(struct max17042_chip *chip)
+static inline void max17042_lock_model(struct max17042_chip *chip)
{
struct regmap *map = chip->regmap;
@@ -577,7 +577,7 @@ static int max17042_init_model(struct max17042_chip *chip)
if (!temp_data)
return -ENOMEM;
- max10742_unlock_model(chip);
+ max17042_unlock_model(chip);
max17042_write_model_data(chip, MAX17042_MODELChrTbl,
table_size);
max17042_read_model_data(chip, MAX17042_MODELChrTbl, temp_data,
@@ -589,7 +589,7 @@ static int max17042_init_model(struct max17042_chip *chip)
temp_data,
table_size);
- max10742_lock_model(chip);
+ max17042_lock_model(chip);
kfree(temp_data);
return ret;
diff --git a/drivers/power/supply/max77650-charger.c b/drivers/power/supply/max77650-charger.c
index e34714cb05ec..5f9477c5cf5a 100644
--- a/drivers/power/supply/max77650-charger.c
+++ b/drivers/power/supply/max77650-charger.c
@@ -366,3 +366,4 @@ module_platform_driver(max77650_charger_driver);
MODULE_DESCRIPTION("MAXIM 77650/77651 charger driver");
MODULE_AUTHOR("Bartosz Golaszewski <bgolaszewski@baylibre.com>");
MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:max77650-charger");
diff --git a/drivers/power/supply/power_supply_core.c b/drivers/power/supply/power_supply_core.c
index 82e84801264c..5c36c430ce8b 100644
--- a/drivers/power/supply/power_supply_core.c
+++ b/drivers/power/supply/power_supply_core.c
@@ -1051,14 +1051,14 @@ __power_supply_register(struct device *parent,
}
spin_lock_init(&psy->changed_lock);
- rc = device_init_wakeup(dev, ws);
- if (rc)
- goto wakeup_init_failed;
-
rc = device_add(dev);
if (rc)
goto device_add_failed;
+ rc = device_init_wakeup(dev, ws);
+ if (rc)
+ goto wakeup_init_failed;
+
rc = psy_register_thermal(psy);
if (rc)
goto register_thermal_failed;
@@ -1101,8 +1101,8 @@ register_cooler_failed:
psy_unregister_thermal(psy);
register_thermal_failed:
device_del(dev);
-device_add_failed:
wakeup_init_failed:
+device_add_failed:
check_supplies_failed:
dev_set_name_failed:
put_device(dev);
diff --git a/drivers/power/supply/power_supply_hwmon.c b/drivers/power/supply/power_supply_hwmon.c
index 51fe60440d12..75cf861ba492 100644
--- a/drivers/power/supply/power_supply_hwmon.c
+++ b/drivers/power/supply/power_supply_hwmon.c
@@ -284,6 +284,7 @@ int power_supply_add_hwmon_sysfs(struct power_supply *psy)
struct device *dev = &psy->dev;
struct device *hwmon;
int ret, i;
+ const char *name;
if (!devres_open_group(dev, power_supply_add_hwmon_sysfs,
GFP_KERNEL))
@@ -334,7 +335,19 @@ int power_supply_add_hwmon_sysfs(struct power_supply *psy)
}
}
- hwmon = devm_hwmon_device_register_with_info(dev, psy->desc->name,
+ name = psy->desc->name;
+ if (strchr(name, '-')) {
+ char *new_name;
+
+ new_name = devm_kstrdup(dev, name, GFP_KERNEL);
+ if (!new_name) {
+ ret = -ENOMEM;
+ goto error;
+ }
+ strreplace(new_name, '-', '_');
+ name = new_name;
+ }
+ hwmon = devm_hwmon_device_register_with_info(dev, name,
psyhw,
&power_supply_hwmon_chip_info,
NULL);
diff --git a/drivers/power/supply/sbs-battery.c b/drivers/power/supply/sbs-battery.c
index 048d205d7074..f8d74e9f7931 100644
--- a/drivers/power/supply/sbs-battery.c
+++ b/drivers/power/supply/sbs-battery.c
@@ -314,17 +314,22 @@ static int sbs_get_battery_presence_and_health(
{
int ret;
- if (psp == POWER_SUPPLY_PROP_PRESENT) {
- /* Dummy command; if it succeeds, battery is present. */
- ret = sbs_read_word_data(client, sbs_data[REG_STATUS].addr);
- if (ret < 0)
- val->intval = 0; /* battery disconnected */
- else
- val->intval = 1; /* battery present */
- } else { /* POWER_SUPPLY_PROP_HEALTH */
+ /* Dummy command; if it succeeds, battery is present. */
+ ret = sbs_read_word_data(client, sbs_data[REG_STATUS].addr);
+
+ if (ret < 0) { /* battery not present*/
+ if (psp == POWER_SUPPLY_PROP_PRESENT) {
+ val->intval = 0;
+ return 0;
+ }
+ return ret;
+ }
+
+ if (psp == POWER_SUPPLY_PROP_PRESENT)
+ val->intval = 1; /* battery present */
+ else /* POWER_SUPPLY_PROP_HEALTH */
/* SBS spec doesn't have a general health command. */
val->intval = POWER_SUPPLY_HEALTH_UNKNOWN;
- }
return 0;
}
@@ -620,12 +625,14 @@ static int sbs_get_property(struct power_supply *psy,
switch (psp) {
case POWER_SUPPLY_PROP_PRESENT:
case POWER_SUPPLY_PROP_HEALTH:
- if (client->flags & SBS_FLAGS_TI_BQ20Z75)
+ if (chip->flags & SBS_FLAGS_TI_BQ20Z75)
ret = sbs_get_ti_battery_presence_and_health(client,
psp, val);
else
ret = sbs_get_battery_presence_and_health(client, psp,
val);
+
+ /* this can only be true if no gpio is used */
if (psp == POWER_SUPPLY_PROP_PRESENT)
return 0;
break;
diff --git a/drivers/power/supply/sc27xx_fuel_gauge.c b/drivers/power/supply/sc27xx_fuel_gauge.c
index 24895cc3b41e..bc8f5bda5762 100644
--- a/drivers/power/supply/sc27xx_fuel_gauge.c
+++ b/drivers/power/supply/sc27xx_fuel_gauge.c
@@ -109,6 +109,9 @@ struct sc27xx_fgu_data {
};
static int sc27xx_fgu_cap_to_clbcnt(struct sc27xx_fgu_data *data, int capacity);
+static void sc27xx_fgu_capacity_calibration(struct sc27xx_fgu_data *data,
+ int cap, bool int_mode);
+static void sc27xx_fgu_adjust_cap(struct sc27xx_fgu_data *data, int cap);
static const char * const sc27xx_charger_supply_name[] = {
"sc2731_charger",
@@ -326,8 +329,6 @@ static int sc27xx_fgu_set_clbcnt(struct sc27xx_fgu_data *data, int clbcnt)
{
int ret;
- clbcnt *= SC27XX_FGU_SAMPLE_HZ;
-
ret = regmap_update_bits(data->regmap,
data->base + SC27XX_FGU_CLBCNT_SETL,
SC27XX_FGU_CLBCNT_MASK, clbcnt);
@@ -362,7 +363,6 @@ static int sc27xx_fgu_get_clbcnt(struct sc27xx_fgu_data *data, int *clb_cnt)
*clb_cnt = ccl & SC27XX_FGU_CLBCNT_MASK;
*clb_cnt |= (cch & SC27XX_FGU_CLBCNT_MASK) << SC27XX_FGU_CLBCNT_SHIFT;
- *clb_cnt /= SC27XX_FGU_SAMPLE_HZ;
return 0;
}
@@ -380,10 +380,10 @@ static int sc27xx_fgu_get_capacity(struct sc27xx_fgu_data *data, int *cap)
/*
* Convert coulomb counter to delta capacity (mAh), and set multiplier
- * as 100 to improve the precision.
+ * as 10 to improve the precision.
*/
- temp = DIV_ROUND_CLOSEST(delta_clbcnt, 360);
- temp = sc27xx_fgu_adc_to_current(data, temp);
+ temp = DIV_ROUND_CLOSEST(delta_clbcnt * 10, 36 * SC27XX_FGU_SAMPLE_HZ);
+ temp = sc27xx_fgu_adc_to_current(data, temp / 1000);
/*
* Convert to capacity percent of the battery total capacity,
@@ -392,6 +392,9 @@ static int sc27xx_fgu_get_capacity(struct sc27xx_fgu_data *data, int *cap)
delta_cap = DIV_ROUND_CLOSEST(temp * 100, data->total_cap);
*cap = delta_cap + data->init_cap;
+ /* Calibrate the battery capacity in a normal range. */
+ sc27xx_fgu_capacity_calibration(data, *cap, false);
+
return 0;
}
@@ -587,6 +590,10 @@ static int sc27xx_fgu_get_property(struct power_supply *psy,
val->intval = value * 1000;
break;
+ case POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN:
+ val->intval = data->total_cap * 1000;
+ break;
+
default:
ret = -EINVAL;
break;
@@ -604,17 +611,25 @@ static int sc27xx_fgu_set_property(struct power_supply *psy,
struct sc27xx_fgu_data *data = power_supply_get_drvdata(psy);
int ret;
- if (psp != POWER_SUPPLY_PROP_CAPACITY)
- return -EINVAL;
-
mutex_lock(&data->lock);
- ret = sc27xx_fgu_save_last_cap(data, val->intval);
+ switch (psp) {
+ case POWER_SUPPLY_PROP_CAPACITY:
+ ret = sc27xx_fgu_save_last_cap(data, val->intval);
+ if (ret < 0)
+ dev_err(data->dev, "failed to save battery capacity\n");
+ break;
- mutex_unlock(&data->lock);
+ case POWER_SUPPLY_PROP_CALIBRATE:
+ sc27xx_fgu_adjust_cap(data, val->intval);
+ ret = 0;
+ break;
- if (ret < 0)
- dev_err(data->dev, "failed to save battery capacity\n");
+ default:
+ ret = -EINVAL;
+ }
+
+ mutex_unlock(&data->lock);
return ret;
}
@@ -629,7 +644,8 @@ static void sc27xx_fgu_external_power_changed(struct power_supply *psy)
static int sc27xx_fgu_property_is_writeable(struct power_supply *psy,
enum power_supply_property psp)
{
- return psp == POWER_SUPPLY_PROP_CAPACITY;
+ return psp == POWER_SUPPLY_PROP_CAPACITY ||
+ psp == POWER_SUPPLY_PROP_CALIBRATE;
}
static enum power_supply_property sc27xx_fgu_props[] = {
@@ -644,6 +660,8 @@ static enum power_supply_property sc27xx_fgu_props[] = {
POWER_SUPPLY_PROP_CURRENT_NOW,
POWER_SUPPLY_PROP_CURRENT_AVG,
POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE,
+ POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN,
+ POWER_SUPPLY_PROP_CALIBRATE,
};
static const struct power_supply_desc sc27xx_fgu_desc = {
@@ -659,50 +677,62 @@ static const struct power_supply_desc sc27xx_fgu_desc = {
static void sc27xx_fgu_adjust_cap(struct sc27xx_fgu_data *data, int cap)
{
+ int ret;
+
data->init_cap = cap;
- data->init_clbcnt = sc27xx_fgu_cap_to_clbcnt(data, data->init_cap);
+ ret = sc27xx_fgu_get_clbcnt(data, &data->init_clbcnt);
+ if (ret)
+ dev_err(data->dev, "failed to get init coulomb counter\n");
}
-static irqreturn_t sc27xx_fgu_interrupt(int irq, void *dev_id)
+static void sc27xx_fgu_capacity_calibration(struct sc27xx_fgu_data *data,
+ int cap, bool int_mode)
{
- struct sc27xx_fgu_data *data = dev_id;
- int ret, cap, ocv, adc;
- u32 status;
+ int ret, ocv, chg_sts, adc;
- mutex_lock(&data->lock);
-
- ret = regmap_read(data->regmap, data->base + SC27XX_FGU_INT_STS,
- &status);
- if (ret)
- goto out;
+ ret = sc27xx_fgu_get_vbat_ocv(data, &ocv);
+ if (ret) {
+ dev_err(data->dev, "get battery ocv error.\n");
+ return;
+ }
- ret = regmap_update_bits(data->regmap, data->base + SC27XX_FGU_INT_CLR,
- status, status);
- if (ret)
- goto out;
+ ret = sc27xx_fgu_get_status(data, &chg_sts);
+ if (ret) {
+ dev_err(data->dev, "get charger status error.\n");
+ return;
+ }
/*
- * When low overload voltage interrupt happens, we should calibrate the
- * battery capacity in lower voltage stage.
+ * If we are in charging mode, then we do not need to calibrate the
+ * lower capacity.
*/
- if (!(status & SC27XX_FGU_LOW_OVERLOAD_INT))
- goto out;
-
- ret = sc27xx_fgu_get_capacity(data, &cap);
- if (ret)
- goto out;
+ if (chg_sts == POWER_SUPPLY_STATUS_CHARGING)
+ return;
- ret = sc27xx_fgu_get_vbat_ocv(data, &ocv);
- if (ret)
- goto out;
-
- /*
- * If current OCV value is less than the minimum OCV value in OCV table,
- * which means now battery capacity is 0%, and we should adjust the
- * inititial capacity to 0.
- */
- if (ocv <= data->cap_table[data->table_len - 1].ocv) {
+ if ((ocv > data->cap_table[0].ocv && cap < 100) || cap > 100) {
+ /*
+ * If current OCV value is larger than the max OCV value in
+ * OCV table, or the current capacity is larger than 100,
+ * we should force the inititial capacity to 100.
+ */
+ sc27xx_fgu_adjust_cap(data, 100);
+ } else if (ocv <= data->cap_table[data->table_len - 1].ocv) {
+ /*
+ * If current OCV value is leass than the minimum OCV value in
+ * OCV table, we should force the inititial capacity to 0.
+ */
sc27xx_fgu_adjust_cap(data, 0);
+ } else if ((ocv > data->cap_table[data->table_len - 1].ocv && cap <= 0) ||
+ (ocv > data->min_volt && cap <= data->alarm_cap)) {
+ /*
+ * If current OCV value is not matchable with current capacity,
+ * we should re-calculate current capacity by looking up the
+ * OCV table.
+ */
+ int cur_cap = power_supply_ocv2cap_simple(data->cap_table,
+ data->table_len, ocv);
+
+ sc27xx_fgu_adjust_cap(data, cur_cap);
} else if (ocv <= data->min_volt) {
/*
* If current OCV value is less than the low alarm voltage, but
@@ -711,7 +741,7 @@ static irqreturn_t sc27xx_fgu_interrupt(int irq, void *dev_id)
*/
if (cap > data->alarm_cap) {
sc27xx_fgu_adjust_cap(data, data->alarm_cap);
- } else if (cap <= 0) {
+ } else {
int cur_cap;
/*
@@ -726,15 +756,55 @@ static irqreturn_t sc27xx_fgu_interrupt(int irq, void *dev_id)
sc27xx_fgu_adjust_cap(data, cur_cap);
}
+ if (!int_mode)
+ return;
+
/*
* After adjusting the battery capacity, we should set the
* lowest alarm voltage instead.
*/
data->min_volt = data->cap_table[data->table_len - 1].ocv;
+ data->alarm_cap = power_supply_ocv2cap_simple(data->cap_table,
+ data->table_len,
+ data->min_volt);
+
adc = sc27xx_fgu_voltage_to_adc(data, data->min_volt / 1000);
- regmap_update_bits(data->regmap, data->base + SC27XX_FGU_LOW_OVERLOAD,
+ regmap_update_bits(data->regmap,
+ data->base + SC27XX_FGU_LOW_OVERLOAD,
SC27XX_FGU_LOW_OVERLOAD_MASK, adc);
}
+}
+
+static irqreturn_t sc27xx_fgu_interrupt(int irq, void *dev_id)
+{
+ struct sc27xx_fgu_data *data = dev_id;
+ int ret, cap;
+ u32 status;
+
+ mutex_lock(&data->lock);
+
+ ret = regmap_read(data->regmap, data->base + SC27XX_FGU_INT_STS,
+ &status);
+ if (ret)
+ goto out;
+
+ ret = regmap_update_bits(data->regmap, data->base + SC27XX_FGU_INT_CLR,
+ status, status);
+ if (ret)
+ goto out;
+
+ /*
+ * When low overload voltage interrupt happens, we should calibrate the
+ * battery capacity in lower voltage stage.
+ */
+ if (!(status & SC27XX_FGU_LOW_OVERLOAD_INT))
+ goto out;
+
+ ret = sc27xx_fgu_get_capacity(data, &cap);
+ if (ret)
+ goto out;
+
+ sc27xx_fgu_capacity_calibration(data, cap, true);
out:
mutex_unlock(&data->lock);
@@ -785,7 +855,7 @@ static int sc27xx_fgu_cap_to_clbcnt(struct sc27xx_fgu_data *data, int capacity)
* Convert current capacity (mAh) to coulomb counter according to the
* formula: 1 mAh =3.6 coulomb.
*/
- return DIV_ROUND_CLOSEST(cur_cap * 36 * data->cur_1000ma_adc, 10);
+ return DIV_ROUND_CLOSEST(cur_cap * 36 * data->cur_1000ma_adc * SC27XX_FGU_SAMPLE_HZ, 10);
}
static int sc27xx_fgu_calibration(struct sc27xx_fgu_data *data)
@@ -856,6 +926,8 @@ static int sc27xx_fgu_hw_init(struct sc27xx_fgu_data *data)
data->alarm_cap = power_supply_ocv2cap_simple(data->cap_table,
data->table_len,
data->min_volt);
+ if (!data->alarm_cap)
+ data->alarm_cap += 1;
power_supply_put_battery_info(data->battery, &info);
@@ -957,81 +1029,81 @@ disable_fgu:
static int sc27xx_fgu_probe(struct platform_device *pdev)
{
- struct device_node *np = pdev->dev.of_node;
+ struct device *dev = &pdev->dev;
+ struct device_node *np = dev->of_node;
struct power_supply_config fgu_cfg = { };
struct sc27xx_fgu_data *data;
int ret, irq;
- data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
+ data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
if (!data)
return -ENOMEM;
- data->regmap = dev_get_regmap(pdev->dev.parent, NULL);
+ data->regmap = dev_get_regmap(dev->parent, NULL);
if (!data->regmap) {
- dev_err(&pdev->dev, "failed to get regmap\n");
+ dev_err(dev, "failed to get regmap\n");
return -ENODEV;
}
- ret = device_property_read_u32(&pdev->dev, "reg", &data->base);
+ ret = device_property_read_u32(dev, "reg", &data->base);
if (ret) {
- dev_err(&pdev->dev, "failed to get fgu address\n");
+ dev_err(dev, "failed to get fgu address\n");
return ret;
}
- data->channel = devm_iio_channel_get(&pdev->dev, "bat-temp");
+ data->channel = devm_iio_channel_get(dev, "bat-temp");
if (IS_ERR(data->channel)) {
- dev_err(&pdev->dev, "failed to get IIO channel\n");
+ dev_err(dev, "failed to get IIO channel\n");
return PTR_ERR(data->channel);
}
- data->charge_chan = devm_iio_channel_get(&pdev->dev, "charge-vol");
+ data->charge_chan = devm_iio_channel_get(dev, "charge-vol");
if (IS_ERR(data->charge_chan)) {
- dev_err(&pdev->dev, "failed to get charge IIO channel\n");
+ dev_err(dev, "failed to get charge IIO channel\n");
return PTR_ERR(data->charge_chan);
}
- data->gpiod = devm_gpiod_get(&pdev->dev, "bat-detect", GPIOD_IN);
+ data->gpiod = devm_gpiod_get(dev, "bat-detect", GPIOD_IN);
if (IS_ERR(data->gpiod)) {
- dev_err(&pdev->dev, "failed to get battery detection GPIO\n");
+ dev_err(dev, "failed to get battery detection GPIO\n");
return PTR_ERR(data->gpiod);
}
ret = gpiod_get_value_cansleep(data->gpiod);
if (ret < 0) {
- dev_err(&pdev->dev, "failed to get gpio state\n");
+ dev_err(dev, "failed to get gpio state\n");
return ret;
}
data->bat_present = !!ret;
mutex_init(&data->lock);
- data->dev = &pdev->dev;
+ data->dev = dev;
platform_set_drvdata(pdev, data);
fgu_cfg.drv_data = data;
fgu_cfg.of_node = np;
- data->battery = devm_power_supply_register(&pdev->dev, &sc27xx_fgu_desc,
+ data->battery = devm_power_supply_register(dev, &sc27xx_fgu_desc,
&fgu_cfg);
if (IS_ERR(data->battery)) {
- dev_err(&pdev->dev, "failed to register power supply\n");
+ dev_err(dev, "failed to register power supply\n");
return PTR_ERR(data->battery);
}
ret = sc27xx_fgu_hw_init(data);
if (ret) {
- dev_err(&pdev->dev, "failed to initialize fgu hardware\n");
+ dev_err(dev, "failed to initialize fgu hardware\n");
return ret;
}
- ret = devm_add_action(&pdev->dev, sc27xx_fgu_disable, data);
+ ret = devm_add_action_or_reset(dev, sc27xx_fgu_disable, data);
if (ret) {
- sc27xx_fgu_disable(data);
- dev_err(&pdev->dev, "failed to add fgu disable action\n");
+ dev_err(dev, "failed to add fgu disable action\n");
return ret;
}
irq = platform_get_irq(pdev, 0);
if (irq < 0) {
- dev_err(&pdev->dev, "no irq resource specified\n");
+ dev_err(dev, "no irq resource specified\n");
return irq;
}
@@ -1046,17 +1118,17 @@ static int sc27xx_fgu_probe(struct platform_device *pdev)
irq = gpiod_to_irq(data->gpiod);
if (irq < 0) {
- dev_err(&pdev->dev, "failed to translate GPIO to IRQ\n");
+ dev_err(dev, "failed to translate GPIO to IRQ\n");
return irq;
}
- ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
+ ret = devm_request_threaded_irq(dev, irq, NULL,
sc27xx_fgu_bat_detection,
IRQF_ONESHOT | IRQF_TRIGGER_RISING |
IRQF_TRIGGER_FALLING,
pdev->name, data);
if (ret) {
- dev_err(&pdev->dev, "failed to request IRQ\n");
+ dev_err(dev, "failed to request IRQ\n");
return ret;
}
@@ -1093,7 +1165,8 @@ static int sc27xx_fgu_suspend(struct device *dev)
* If we are charging, then no need to enable the FGU interrupts to
* adjust the battery capacity.
*/
- if (status != POWER_SUPPLY_STATUS_NOT_CHARGING)
+ if (status != POWER_SUPPLY_STATUS_NOT_CHARGING &&
+ status != POWER_SUPPLY_STATUS_DISCHARGING)
return 0;
ret = regmap_update_bits(data->regmap, data->base + SC27XX_FGU_INT_EN,