summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinux Build Service Account <lnxbuild@localhost>2017-02-11 01:25:23 -0800
committerGerrit - the friendly Code Review server <code-review@localhost>2017-02-11 01:25:23 -0800
commit58a2863f693f66bcacc67c87c05727977545a9cb (patch)
treede917cee1543fede692e9f7cfe99645579262b46
parent713e5d786eb40a063e314acd5f04890478f55b2c (diff)
parent2b9d6a362f9ae5f7e2228e3c1df9b9cf56417b7c (diff)
Merge "qcom: smb-lib: make smb_irq_info common for smb2 and smb138x chargers"
-rw-r--r--arch/arm/boot/dts/qcom/msm-smb138x.dtsi6
-rw-r--r--drivers/power/power_supply_sysfs.c1
-rw-r--r--drivers/power/supply/qcom/battery.c33
-rw-r--r--drivers/power/supply/qcom/qpnp-smb2.c94
-rw-r--r--drivers/power/supply/qcom/smb-lib.c61
-rw-r--r--drivers/power/supply/qcom/smb-lib.h55
-rw-r--r--drivers/power/supply/qcom/smb138x-charger.c102
-rw-r--r--drivers/power/supply/qcom/storm-watch.c11
-rw-r--r--drivers/power/supply/qcom/storm-watch.h16
-rw-r--r--include/linux/power_supply.h1
10 files changed, 243 insertions, 137 deletions
diff --git a/arch/arm/boot/dts/qcom/msm-smb138x.dtsi b/arch/arm/boot/dts/qcom/msm-smb138x.dtsi
index 138fa2b57248..8edc1fc61830 100644
--- a/arch/arm/boot/dts/qcom/msm-smb138x.dtsi
+++ b/arch/arm/boot/dts/qcom/msm-smb138x.dtsi
@@ -108,6 +108,12 @@
"connector_temp_thr3",
"charger_temp_max";
+ qcom,chgr@1000 {
+ reg = <0x1000 0x100>;
+ interrupts = <0x10 0x1 IRQ_TYPE_EDGE_RISING>;
+ interrupt-names = "chg-state-change";
+ };
+
qcom,chgr-misc@1600 {
reg = <0x1600 0x100>;
interrupts = <0x16 0x1 IRQ_TYPE_EDGE_RISING>,
diff --git a/drivers/power/power_supply_sysfs.c b/drivers/power/power_supply_sysfs.c
index 168119fcf7d1..201a53e66ef0 100644
--- a/drivers/power/power_supply_sysfs.c
+++ b/drivers/power/power_supply_sysfs.c
@@ -239,6 +239,7 @@ static struct device_attribute power_supply_attrs[] = {
POWER_SUPPLY_ATTR(input_current_max),
POWER_SUPPLY_ATTR(input_current_trim),
POWER_SUPPLY_ATTR(input_current_settled),
+ POWER_SUPPLY_ATTR(input_voltage_settled),
POWER_SUPPLY_ATTR(bypass_vchg_loop_debouncer),
POWER_SUPPLY_ATTR(charge_counter_shadow),
POWER_SUPPLY_ATTR(hi_power),
diff --git a/drivers/power/supply/qcom/battery.c b/drivers/power/supply/qcom/battery.c
index 6f083f1bbe80..35dc3842017b 100644
--- a/drivers/power/supply/qcom/battery.c
+++ b/drivers/power/supply/qcom/battery.c
@@ -247,12 +247,11 @@ done:
* FCC *
**********/
#define EFFICIENCY_PCT 80
-#define MICRO_5V 5000000
static void split_fcc(struct pl_data *chip, int total_ua,
int *master_ua, int *slave_ua)
{
int rc, effective_total_ua, slave_limited_ua, hw_cc_delta_ua = 0,
- aicl_settled_ua, input_limited_fcc_ua;
+ icl_ua, adapter_uv, bcl_ua;
union power_supply_propval pval = {0, };
rc = power_supply_get_property(chip->main_psy,
@@ -262,24 +261,30 @@ static void split_fcc(struct pl_data *chip, int total_ua,
else
hw_cc_delta_ua = pval.intval;
- input_limited_fcc_ua = INT_MAX;
+ bcl_ua = INT_MAX;
if (chip->pl_mode == POWER_SUPPLY_PARALLEL_MID_MID) {
rc = power_supply_get_property(chip->main_psy,
- POWER_SUPPLY_PROP_INPUT_CURRENT_SETTLED,
- &pval);
- if (rc < 0)
- aicl_settled_ua = 0;
- else
- aicl_settled_ua = pval.intval;
+ POWER_SUPPLY_PROP_INPUT_CURRENT_SETTLED, &pval);
+ if (rc < 0) {
+ pr_err("Couldn't get aicl settled value rc=%d\n", rc);
+ return;
+ }
+ icl_ua = pval.intval;
+
+ rc = power_supply_get_property(chip->main_psy,
+ POWER_SUPPLY_PROP_INPUT_VOLTAGE_SETTLED, &pval);
+ if (rc < 0) {
+ pr_err("Couldn't get adaptive voltage rc=%d\n", rc);
+ return;
+ }
+ adapter_uv = pval.intval;
- input_limited_fcc_ua = div64_s64(
- (s64)aicl_settled_ua * MICRO_5V * EFFICIENCY_PCT,
- (s64)get_effective_result(chip->fv_votable)
- * 100);
+ bcl_ua = div64_s64((s64)icl_ua * adapter_uv * EFFICIENCY_PCT,
+ (s64)get_effective_result(chip->fv_votable) * 100);
}
effective_total_ua = max(0, total_ua + hw_cc_delta_ua);
- slave_limited_ua = min(effective_total_ua, input_limited_fcc_ua);
+ slave_limited_ua = min(effective_total_ua, bcl_ua);
*slave_ua = (slave_limited_ua * chip->slave_pct) / 100;
*slave_ua = (*slave_ua * chip->taper_pct) / 100;
*master_ua = max(0, total_ua - *slave_ua);
diff --git a/drivers/power/supply/qcom/qpnp-smb2.c b/drivers/power/supply/qcom/qpnp-smb2.c
index 983bf4f3e08d..10e0ff89635b 100644
--- a/drivers/power/supply/qcom/qpnp-smb2.c
+++ b/drivers/power/supply/qcom/qpnp-smb2.c
@@ -16,7 +16,6 @@
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/power_supply.h>
-#include <linux/interrupt.h>
#include <linux/of.h>
#include <linux/of_irq.h>
#include <linux/qpnp/qpnp-revid.h>
@@ -615,6 +614,7 @@ static enum power_supply_property smb2_usb_main_props[] = {
POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX,
POWER_SUPPLY_PROP_TYPE,
POWER_SUPPLY_PROP_INPUT_CURRENT_SETTLED,
+ POWER_SUPPLY_PROP_INPUT_VOLTAGE_SETTLED,
POWER_SUPPLY_PROP_FCC_DELTA,
/*
* TODO move the TEMP and TEMP_MAX properties here,
@@ -647,6 +647,9 @@ static int smb2_usb_main_get_prop(struct power_supply *psy,
case POWER_SUPPLY_PROP_INPUT_CURRENT_SETTLED:
rc = smblib_get_prop_input_current_settled(chg, val);
break;
+ case POWER_SUPPLY_PROP_INPUT_VOLTAGE_SETTLED:
+ rc = smblib_get_prop_input_voltage_settled(chg, val);
+ break;
case POWER_SUPPLY_PROP_FCC_DELTA:
rc = smblib_get_prop_fcc_delta(chg, val);
break;
@@ -1664,180 +1667,172 @@ static int smb2_determine_initial_status(struct smb2 *chip)
* INTERRUPT REGISTRATION *
**************************/
-struct smb2_irq_info {
- const char *name;
- const irq_handler_t handler;
- const bool wake;
- const struct storm_watch storm_data;
- int irq;
-};
-
-static struct smb2_irq_info smb2_irqs[] = {
+static struct smb_irq_info smb2_irqs[] = {
/* CHARGER IRQs */
- {
+ [CHG_ERROR_IRQ] = {
.name = "chg-error",
.handler = smblib_handle_debug,
},
- {
+ [CHG_STATE_CHANGE_IRQ] = {
.name = "chg-state-change",
.handler = smblib_handle_chg_state_change,
.wake = true,
},
- {
+ [STEP_CHG_STATE_CHANGE_IRQ] = {
.name = "step-chg-state-change",
.handler = smblib_handle_step_chg_state_change,
.wake = true,
},
- {
+ [STEP_CHG_SOC_UPDATE_FAIL_IRQ] = {
.name = "step-chg-soc-update-fail",
.handler = smblib_handle_step_chg_soc_update_fail,
.wake = true,
},
- {
+ [STEP_CHG_SOC_UPDATE_REQ_IRQ] = {
.name = "step-chg-soc-update-request",
.handler = smblib_handle_step_chg_soc_update_request,
.wake = true,
},
/* OTG IRQs */
- {
+ [OTG_FAIL_IRQ] = {
.name = "otg-fail",
.handler = smblib_handle_debug,
},
- {
+ [OTG_OVERCURRENT_IRQ] = {
.name = "otg-overcurrent",
.handler = smblib_handle_otg_overcurrent,
},
- {
+ [OTG_OC_DIS_SW_STS_IRQ] = {
.name = "otg-oc-dis-sw-sts",
.handler = smblib_handle_debug,
},
- {
+ [TESTMODE_CHANGE_DET_IRQ] = {
.name = "testmode-change-detect",
.handler = smblib_handle_debug,
},
/* BATTERY IRQs */
- {
+ [BATT_TEMP_IRQ] = {
.name = "bat-temp",
.handler = smblib_handle_batt_temp_changed,
},
- {
+ [BATT_OCP_IRQ] = {
.name = "bat-ocp",
.handler = smblib_handle_batt_psy_changed,
},
- {
+ [BATT_OV_IRQ] = {
.name = "bat-ov",
.handler = smblib_handle_batt_psy_changed,
},
- {
+ [BATT_LOW_IRQ] = {
.name = "bat-low",
.handler = smblib_handle_batt_psy_changed,
},
- {
+ [BATT_THERM_ID_MISS_IRQ] = {
.name = "bat-therm-or-id-missing",
.handler = smblib_handle_batt_psy_changed,
},
- {
+ [BATT_TERM_MISS_IRQ] = {
.name = "bat-terminal-missing",
.handler = smblib_handle_batt_psy_changed,
},
/* USB INPUT IRQs */
- {
+ [USBIN_COLLAPSE_IRQ] = {
.name = "usbin-collapse",
.handler = smblib_handle_debug,
},
- {
+ [USBIN_LT_3P6V_IRQ] = {
.name = "usbin-lt-3p6v",
.handler = smblib_handle_debug,
},
- {
+ [USBIN_UV_IRQ] = {
.name = "usbin-uv",
.handler = smblib_handle_debug,
},
- {
+ [USBIN_OV_IRQ] = {
.name = "usbin-ov",
.handler = smblib_handle_debug,
},
- {
+ [USBIN_PLUGIN_IRQ] = {
.name = "usbin-plugin",
.handler = smblib_handle_usb_plugin,
.wake = true,
},
- {
+ [USBIN_SRC_CHANGE_IRQ] = {
.name = "usbin-src-change",
.handler = smblib_handle_usb_source_change,
.wake = true,
},
- {
+ [USBIN_ICL_CHANGE_IRQ] = {
.name = "usbin-icl-change",
.handler = smblib_handle_icl_change,
.wake = true,
},
- {
+ [TYPE_C_CHANGE_IRQ] = {
.name = "type-c-change",
.handler = smblib_handle_usb_typec_change,
.wake = true,
},
/* DC INPUT IRQs */
- {
+ [DCIN_COLLAPSE_IRQ] = {
.name = "dcin-collapse",
.handler = smblib_handle_debug,
},
- {
+ [DCIN_LT_3P6V_IRQ] = {
.name = "dcin-lt-3p6v",
.handler = smblib_handle_debug,
},
- {
+ [DCIN_UV_IRQ] = {
.name = "dcin-uv",
.handler = smblib_handle_debug,
},
- {
+ [DCIN_OV_IRQ] = {
.name = "dcin-ov",
.handler = smblib_handle_debug,
},
- {
+ [DCIN_PLUGIN_IRQ] = {
.name = "dcin-plugin",
.handler = smblib_handle_dc_plugin,
.wake = true,
},
- {
+ [DIV2_EN_DG_IRQ] = {
.name = "div2-en-dg",
.handler = smblib_handle_debug,
},
- {
+ [DCIN_ICL_CHANGE_IRQ] = {
.name = "dcin-icl-change",
.handler = smblib_handle_debug,
},
/* MISCELLANEOUS IRQs */
- {
+ [WDOG_SNARL_IRQ] = {
.name = "wdog-snarl",
.handler = NULL,
},
- {
+ [WDOG_BARK_IRQ] = {
.name = "wdog-bark",
.handler = NULL,
},
- {
+ [AICL_FAIL_IRQ] = {
.name = "aicl-fail",
.handler = smblib_handle_debug,
},
- {
+ [AICL_DONE_IRQ] = {
.name = "aicl-done",
.handler = smblib_handle_debug,
},
- {
+ [HIGH_DUTY_CYCLE_IRQ] = {
.name = "high-duty-cycle",
.handler = smblib_handle_high_duty_cycle,
.wake = true,
},
- {
+ [INPUT_CURRENT_LIMIT_IRQ] = {
.name = "input-current-limiting",
.handler = smblib_handle_debug,
},
- {
+ [TEMPERATURE_CHANGE_IRQ] = {
.name = "temperature-change",
.handler = smblib_handle_debug,
},
- {
+ [SWITCH_POWER_OK_IRQ] = {
.name = "switcher-power-ok",
.handler = smblib_handle_switcher_power_ok,
.storm_data = {true, 1000, 3},
@@ -1885,6 +1880,7 @@ static int smb2_request_interrupt(struct smb2 *chip,
irq_data->parent_data = chip;
irq_data->name = irq_name;
irq_data->storm_data = smb2_irqs[irq_index].storm_data;
+ mutex_init(&irq_data->storm_data.storm_lock);
rc = devm_request_threaded_irq(chg->dev, irq, NULL,
smb2_irqs[irq_index].handler,
@@ -1895,6 +1891,7 @@ static int smb2_request_interrupt(struct smb2 *chip,
}
smb2_irqs[irq_index].irq = irq;
+ smb2_irqs[irq_index].irq_data = irq_data;
if (smb2_irqs[irq_index].wake)
enable_irq_wake(irq);
@@ -2008,6 +2005,7 @@ static int smb2_probe(struct platform_device *pdev)
chg->param = v1_params;
chg->debug_mask = &__debug_mask;
chg->mode = PARALLEL_MASTER;
+ chg->irq_info = smb2_irqs;
chg->name = "PMI";
chg->regmap = dev_get_regmap(chg->dev->parent, NULL);
diff --git a/drivers/power/supply/qcom/smb-lib.c b/drivers/power/supply/qcom/smb-lib.c
index e440a9a561dd..8d6ffa5a3303 100644
--- a/drivers/power/supply/qcom/smb-lib.c
+++ b/drivers/power/supply/qcom/smb-lib.c
@@ -331,7 +331,6 @@ static const struct apsd_result *smblib_get_apsd_result(struct smb_charger *chg)
return result;
}
-
/********************
* REGISTER SETTERS *
********************/
@@ -1993,6 +1992,39 @@ int smblib_get_prop_input_current_settled(struct smb_charger *chg,
return smblib_get_charge_param(chg, &chg->param.icl_stat, &val->intval);
}
+#define HVDCP3_STEP_UV 200000
+int smblib_get_prop_input_voltage_settled(struct smb_charger *chg,
+ union power_supply_propval *val)
+{
+ const struct apsd_result *apsd_result = smblib_get_apsd_result(chg);
+ int rc, pulses;
+ u8 stat;
+
+ val->intval = MICRO_5V;
+ if (apsd_result == NULL) {
+ smblib_err(chg, "APSD result is NULL\n");
+ return 0;
+ }
+
+ switch (apsd_result->pst) {
+ case POWER_SUPPLY_TYPE_USB_HVDCP_3:
+ rc = smblib_read(chg, QC_PULSE_COUNT_STATUS_REG, &stat);
+ if (rc < 0) {
+ smblib_err(chg,
+ "Couldn't read QC_PULSE_COUNT rc=%d\n", rc);
+ return 0;
+ }
+ pulses = (stat & QC_PULSE_COUNT_MASK);
+ val->intval = MICRO_5V + HVDCP3_STEP_UV * pulses;
+ break;
+ default:
+ val->intval = MICRO_5V;
+ break;
+ }
+
+ return 0;
+}
+
int smblib_get_prop_pd_in_hard_reset(struct smb_charger *chg,
union power_supply_propval *val)
{
@@ -2840,22 +2872,20 @@ irqreturn_t smblib_handle_icl_change(int irq, void *data)
struct smb_charger *chg = irq_data->parent_data;
int rc, settled_ua;
- smblib_dbg(chg, PR_INTERRUPT, "IRQ: %s\n", irq_data->name);
-
rc = smblib_get_charge_param(chg, &chg->param.icl_stat, &settled_ua);
if (rc < 0) {
smblib_err(chg, "Couldn't get ICL status rc=%d\n", rc);
return IRQ_HANDLED;
}
- if (chg->mode != PARALLEL_MASTER)
- return IRQ_HANDLED;
-
- power_supply_changed(chg->usb_main_psy);
-
- vote(chg->pl_enable_votable_indirect, USBIN_I_VOTER,
- settled_ua >= USB_WEAK_INPUT_UA, 0);
+ if (chg->mode == PARALLEL_MASTER) {
+ power_supply_changed(chg->usb_main_psy);
+ vote(chg->pl_enable_votable_indirect, USBIN_I_VOTER,
+ settled_ua >= USB_WEAK_INPUT_UA, 0);
+ }
+ smblib_dbg(chg, PR_INTERRUPT, "IRQ: %s icl_settled=%d\n",
+ irq_data->name, settled_ua);
return IRQ_HANDLED;
}
@@ -2882,6 +2912,7 @@ static void smblib_hvdcp_adaptive_voltage_change(struct smb_charger *chg)
u8 stat;
int pulses;
+ power_supply_changed(chg->usb_main_psy);
if (chg->usb_psy_desc.type == POWER_SUPPLY_TYPE_USB_HVDCP) {
rc = smblib_read(chg, QC_CHANGE_STATUS_REG, &stat);
if (rc < 0) {
@@ -2934,13 +2965,6 @@ static void smblib_hvdcp_adaptive_voltage_change(struct smb_charger *chg)
}
}
-static void smblib_handle_adaptive_voltage_done(struct smb_charger *chg,
- bool rising)
-{
- smblib_dbg(chg, PR_INTERRUPT, "IRQ: adaptive-voltage-done %s\n",
- rising ? "rising" : "falling");
-}
-
/* triggers when HVDCP 3.0 authentication has finished */
static void smblib_handle_hvdcp_3p0_auth_done(struct smb_charger *chg,
bool rising)
@@ -3082,9 +3106,6 @@ irqreturn_t smblib_handle_usb_source_change(int irq, void *data)
smblib_handle_hvdcp_3p0_auth_done(chg,
(bool)(stat & QC_AUTH_DONE_STATUS_BIT));
- smblib_handle_adaptive_voltage_done(chg,
- (bool)(stat & VADP_CHANGE_DONE_AFTER_AUTH_BIT));
-
smblib_handle_sdp_enumeration_done(chg,
(bool)(stat & ENUMERATION_DONE_BIT));
diff --git a/drivers/power/supply/qcom/smb-lib.h b/drivers/power/supply/qcom/smb-lib.h
index 2d8e8835e937..113f8f3f1469 100644
--- a/drivers/power/supply/qcom/smb-lib.h
+++ b/drivers/power/supply/qcom/smb-lib.h
@@ -13,6 +13,7 @@
#ifndef __SMB2_CHARGER_H
#define __SMB2_CHARGER_H
#include <linux/types.h>
+#include <linux/interrupt.h>
#include <linux/irqreturn.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/consumer.h>
@@ -78,6 +79,57 @@ enum {
TYPEC_CC2_REMOVAL_WA_BIT = BIT(2),
};
+enum smb_irq_index {
+ CHG_ERROR_IRQ = 0,
+ CHG_STATE_CHANGE_IRQ,
+ STEP_CHG_STATE_CHANGE_IRQ,
+ STEP_CHG_SOC_UPDATE_FAIL_IRQ,
+ STEP_CHG_SOC_UPDATE_REQ_IRQ,
+ OTG_FAIL_IRQ,
+ OTG_OVERCURRENT_IRQ,
+ OTG_OC_DIS_SW_STS_IRQ,
+ TESTMODE_CHANGE_DET_IRQ,
+ BATT_TEMP_IRQ,
+ BATT_OCP_IRQ,
+ BATT_OV_IRQ,
+ BATT_LOW_IRQ,
+ BATT_THERM_ID_MISS_IRQ,
+ BATT_TERM_MISS_IRQ,
+ USBIN_COLLAPSE_IRQ,
+ USBIN_LT_3P6V_IRQ,
+ USBIN_UV_IRQ,
+ USBIN_OV_IRQ,
+ USBIN_PLUGIN_IRQ,
+ USBIN_SRC_CHANGE_IRQ,
+ USBIN_ICL_CHANGE_IRQ,
+ TYPE_C_CHANGE_IRQ,
+ DCIN_COLLAPSE_IRQ,
+ DCIN_LT_3P6V_IRQ,
+ DCIN_UV_IRQ,
+ DCIN_OV_IRQ,
+ DCIN_PLUGIN_IRQ,
+ DIV2_EN_DG_IRQ,
+ DCIN_ICL_CHANGE_IRQ,
+ WDOG_SNARL_IRQ,
+ WDOG_BARK_IRQ,
+ AICL_FAIL_IRQ,
+ AICL_DONE_IRQ,
+ HIGH_DUTY_CYCLE_IRQ,
+ INPUT_CURRENT_LIMIT_IRQ,
+ TEMPERATURE_CHANGE_IRQ,
+ SWITCH_POWER_OK_IRQ,
+ SMB_IRQ_MAX,
+};
+
+struct smb_irq_info {
+ const char *name;
+ const irq_handler_t handler;
+ const bool wake;
+ const struct storm_watch storm_data;
+ struct smb_irq_data *irq_data;
+ int irq;
+};
+
static const unsigned int smblib_extcon_cable[] = {
EXTCON_USB,
EXTCON_USB_HOST,
@@ -166,6 +218,7 @@ struct smb_charger {
struct device *dev;
char *name;
struct regmap *regmap;
+ struct smb_irq_info *irq_info;
struct smb_params param;
struct smb_iio iio;
int *debug_mask;
@@ -380,6 +433,8 @@ int smblib_get_prop_pd_allowed(struct smb_charger *chg,
union power_supply_propval *val);
int smblib_get_prop_input_current_settled(struct smb_charger *chg,
union power_supply_propval *val);
+int smblib_get_prop_input_voltage_settled(struct smb_charger *chg,
+ union power_supply_propval *val);
int smblib_get_prop_pd_in_hard_reset(struct smb_charger *chg,
union power_supply_propval *val);
int smblib_get_pe_start(struct smb_charger *chg,
diff --git a/drivers/power/supply/qcom/smb138x-charger.c b/drivers/power/supply/qcom/smb138x-charger.c
index 1bdae492f44c..554625adda7d 100644
--- a/drivers/power/supply/qcom/smb138x-charger.c
+++ b/drivers/power/supply/qcom/smb138x-charger.c
@@ -14,7 +14,6 @@
#include <linux/device.h>
#include <linux/iio/consumer.h>
-#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_device.h>
@@ -108,6 +107,17 @@ module_param_named(
debug_mask, __debug_mask, int, S_IRUSR | S_IWUSR
);
+irqreturn_t smb138x_handle_slave_chg_state_change(int irq, void *data)
+{
+ struct smb_irq_data *irq_data = data;
+ struct smb138x *chip = irq_data->parent_data;
+
+ if (chip->parallel_psy)
+ power_supply_changed(chip->parallel_psy);
+
+ return IRQ_HANDLED;
+}
+
static int smb138x_parse_dt(struct smb138x *chip)
{
struct smb_charger *chg = &chip->chg;
@@ -974,170 +984,164 @@ static int smb138x_determine_initial_status(struct smb138x *chip)
* INTERRUPT REGISTRATION *
**************************/
-struct smb138x_irq_info {
- const char *name;
- const irq_handler_t handler;
- const bool wake;
- const struct storm_watch storm_data;
-};
-
-static const struct smb138x_irq_info smb138x_irqs[] = {
+static struct smb_irq_info smb138x_irqs[] = {
/* CHARGER IRQs */
- {
+ [CHG_ERROR_IRQ] = {
.name = "chg-error",
.handler = smblib_handle_debug,
},
- {
+ [CHG_STATE_CHANGE_IRQ] = {
.name = "chg-state-change",
- .handler = smblib_handle_debug,
+ .handler = smb138x_handle_slave_chg_state_change,
+ .wake = true,
},
- {
+ [STEP_CHG_STATE_CHANGE_IRQ] = {
.name = "step-chg-state-change",
.handler = smblib_handle_debug,
},
- {
+ [STEP_CHG_SOC_UPDATE_FAIL_IRQ] = {
.name = "step-chg-soc-update-fail",
.handler = smblib_handle_debug,
},
- {
+ [STEP_CHG_SOC_UPDATE_REQ_IRQ] = {
.name = "step-chg-soc-update-request",
.handler = smblib_handle_debug,
},
/* OTG IRQs */
- {
+ [OTG_FAIL_IRQ] = {
.name = "otg-fail",
.handler = smblib_handle_debug,
},
- {
+ [OTG_OVERCURRENT_IRQ] = {
.name = "otg-overcurrent",
.handler = smblib_handle_debug,
},
- {
+ [OTG_OC_DIS_SW_STS_IRQ] = {
.name = "otg-oc-dis-sw-sts",
.handler = smblib_handle_debug,
},
- {
+ [TESTMODE_CHANGE_DET_IRQ] = {
.name = "testmode-change-detect",
.handler = smblib_handle_debug,
},
/* BATTERY IRQs */
- {
+ [BATT_TEMP_IRQ] = {
.name = "bat-temp",
.handler = smblib_handle_batt_psy_changed,
},
- {
+ [BATT_OCP_IRQ] = {
.name = "bat-ocp",
.handler = smblib_handle_batt_psy_changed,
},
- {
+ [BATT_OV_IRQ] = {
.name = "bat-ov",
.handler = smblib_handle_batt_psy_changed,
},
- {
+ [BATT_LOW_IRQ] = {
.name = "bat-low",
.handler = smblib_handle_batt_psy_changed,
},
- {
+ [BATT_THERM_ID_MISS_IRQ] = {
.name = "bat-therm-or-id-missing",
.handler = smblib_handle_batt_psy_changed,
},
- {
+ [BATT_TERM_MISS_IRQ] = {
.name = "bat-terminal-missing",
.handler = smblib_handle_batt_psy_changed,
},
/* USB INPUT IRQs */
- {
+ [USBIN_COLLAPSE_IRQ] = {
.name = "usbin-collapse",
.handler = smblib_handle_debug,
},
- {
+ [USBIN_LT_3P6V_IRQ] = {
.name = "usbin-lt-3p6v",
.handler = smblib_handle_debug,
},
- {
+ [USBIN_UV_IRQ] = {
.name = "usbin-uv",
.handler = smblib_handle_debug,
},
- {
+ [USBIN_OV_IRQ] = {
.name = "usbin-ov",
.handler = smblib_handle_debug,
},
- {
+ [USBIN_PLUGIN_IRQ] = {
.name = "usbin-plugin",
.handler = smblib_handle_usb_plugin,
},
- {
+ [USBIN_SRC_CHANGE_IRQ] = {
.name = "usbin-src-change",
.handler = smblib_handle_usb_source_change,
},
- {
+ [USBIN_ICL_CHANGE_IRQ] = {
.name = "usbin-icl-change",
.handler = smblib_handle_debug,
},
- {
+ [TYPE_C_CHANGE_IRQ] = {
.name = "type-c-change",
.handler = smblib_handle_usb_typec_change,
},
/* DC INPUT IRQs */
- {
+ [DCIN_COLLAPSE_IRQ] = {
.name = "dcin-collapse",
.handler = smblib_handle_debug,
},
- {
+ [DCIN_LT_3P6V_IRQ] = {
.name = "dcin-lt-3p6v",
.handler = smblib_handle_debug,
},
- {
+ [DCIN_UV_IRQ] = {
.name = "dcin-uv",
.handler = smblib_handle_debug,
},
- {
+ [DCIN_OV_IRQ] = {
.name = "dcin-ov",
.handler = smblib_handle_debug,
},
- {
+ [DCIN_PLUGIN_IRQ] = {
.name = "dcin-plugin",
.handler = smblib_handle_debug,
},
- {
+ [DIV2_EN_DG_IRQ] = {
.name = "div2-en-dg",
.handler = smblib_handle_debug,
},
- {
+ [DCIN_ICL_CHANGE_IRQ] = {
.name = "dcin-icl-change",
.handler = smblib_handle_debug,
},
/* MISCELLANEOUS IRQs */
- {
+ [WDOG_SNARL_IRQ] = {
.name = "wdog-snarl",
.handler = smblib_handle_debug,
},
- {
+ [WDOG_BARK_IRQ] = {
.name = "wdog-bark",
.handler = smblib_handle_wdog_bark,
.wake = true,
},
- {
+ [AICL_FAIL_IRQ] = {
.name = "aicl-fail",
.handler = smblib_handle_debug,
},
- {
+ [AICL_DONE_IRQ] = {
.name = "aicl-done",
.handler = smblib_handle_debug,
},
- {
+ [HIGH_DUTY_CYCLE_IRQ] = {
.name = "high-duty-cycle",
.handler = smblib_handle_debug,
},
- {
+ [INPUT_CURRENT_LIMIT_IRQ] = {
.name = "input-current-limiting",
.handler = smblib_handle_debug,
},
- {
+ [TEMPERATURE_CHANGE_IRQ] = {
.name = "temperature-change",
.handler = smb138x_handle_temperature_change,
},
- {
+ [SWITCH_POWER_OK_IRQ] = {
.name = "switcher-power-ok",
.handler = smblib_handle_debug,
},
@@ -1185,6 +1189,7 @@ static int smb138x_request_interrupt(struct smb138x *chip,
irq_data->parent_data = chip;
irq_data->name = irq_name;
irq_data->storm_data = smb138x_irqs[irq_index].storm_data;
+ mutex_init(&irq_data->storm_data.storm_lock);
rc = devm_request_threaded_irq(chg->dev, irq, NULL,
smb138x_irqs[irq_index].handler,
@@ -1398,6 +1403,7 @@ static int smb138x_probe(struct platform_device *pdev)
chip->chg.dev = &pdev->dev;
chip->chg.debug_mask = &__debug_mask;
+ chip->chg.irq_info = smb138x_irqs;
chip->chg.name = "SMB";
chip->chg.regmap = dev_get_regmap(chip->chg.dev->parent, NULL);
diff --git a/drivers/power/supply/qcom/storm-watch.c b/drivers/power/supply/qcom/storm-watch.c
index 90fec12bd742..5275079c53e0 100644
--- a/drivers/power/supply/qcom/storm-watch.c
+++ b/drivers/power/supply/qcom/storm-watch.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2016 The Linux Foundation. All rights reserved.
+/* Copyright (c) 2016-2017 The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -39,6 +39,7 @@ bool is_storming(struct storm_watch *data)
if (data->storm_period_ms <= 0)
return false;
+ mutex_lock(&data->storm_lock);
curr_kt = ktime_get_boottime();
delta_kt = ktime_sub(curr_kt, data->last_kt);
@@ -53,5 +54,13 @@ bool is_storming(struct storm_watch *data)
}
data->last_kt = curr_kt;
+ mutex_unlock(&data->storm_lock);
return is_storming;
}
+
+void reset_storm_count(struct storm_watch *data)
+{
+ mutex_lock(&data->storm_lock);
+ data->storm_count = 0;
+ mutex_unlock(&data->storm_lock);
+}
diff --git a/drivers/power/supply/qcom/storm-watch.h b/drivers/power/supply/qcom/storm-watch.h
index 44b9d64d8a87..ff05c4a661c3 100644
--- a/drivers/power/supply/qcom/storm-watch.h
+++ b/drivers/power/supply/qcom/storm-watch.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2016 The Linux Foundation. All rights reserved.
+/* Copyright (c) 2016-2017 The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -13,6 +13,7 @@
#ifndef __STORM_WATCH_H
#define __STORM_WATCH_H
#include <linux/ktime.h>
+#include <linux/mutex.h>
/**
* Data used to track an event storm.
@@ -23,14 +24,17 @@
* @max_storm_count: The number of chained events required to trigger a storm.
* @storm_count: The current number of chained events.
* @last_kt: Kernel time of the last event seen.
+ * @storm_lock: Mutex lock to protect storm_watch data.
*/
struct storm_watch {
- bool enabled;
- int storm_period_ms;
- int max_storm_count;
- int storm_count;
- ktime_t last_kt;
+ bool enabled;
+ int storm_period_ms;
+ int max_storm_count;
+ int storm_count;
+ ktime_t last_kt;
+ struct mutex storm_lock;
};
bool is_storming(struct storm_watch *data);
+void reset_storm_count(struct storm_watch *data);
#endif
diff --git a/include/linux/power_supply.h b/include/linux/power_supply.h
index b9b4c7b8fe06..457d862cb9a8 100644
--- a/include/linux/power_supply.h
+++ b/include/linux/power_supply.h
@@ -191,6 +191,7 @@ enum power_supply_property {
POWER_SUPPLY_PROP_INPUT_CURRENT_MAX,
POWER_SUPPLY_PROP_INPUT_CURRENT_TRIM,
POWER_SUPPLY_PROP_INPUT_CURRENT_SETTLED,
+ POWER_SUPPLY_PROP_INPUT_VOLTAGE_SETTLED,
POWER_SUPPLY_PROP_VCHG_LOOP_DBC_BYPASS,
POWER_SUPPLY_PROP_CHARGE_COUNTER_SHADOW,
POWER_SUPPLY_PROP_HI_POWER,