diff options
author | Linux Build Service Account <lnxbuild@localhost> | 2017-02-11 01:25:23 -0800 |
---|---|---|
committer | Gerrit - the friendly Code Review server <code-review@localhost> | 2017-02-11 01:25:23 -0800 |
commit | 58a2863f693f66bcacc67c87c05727977545a9cb (patch) | |
tree | de917cee1543fede692e9f7cfe99645579262b46 | |
parent | 713e5d786eb40a063e314acd5f04890478f55b2c (diff) | |
parent | 2b9d6a362f9ae5f7e2228e3c1df9b9cf56417b7c (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.dtsi | 6 | ||||
-rw-r--r-- | drivers/power/power_supply_sysfs.c | 1 | ||||
-rw-r--r-- | drivers/power/supply/qcom/battery.c | 33 | ||||
-rw-r--r-- | drivers/power/supply/qcom/qpnp-smb2.c | 94 | ||||
-rw-r--r-- | drivers/power/supply/qcom/smb-lib.c | 61 | ||||
-rw-r--r-- | drivers/power/supply/qcom/smb-lib.h | 55 | ||||
-rw-r--r-- | drivers/power/supply/qcom/smb138x-charger.c | 102 | ||||
-rw-r--r-- | drivers/power/supply/qcom/storm-watch.c | 11 | ||||
-rw-r--r-- | drivers/power/supply/qcom/storm-watch.h | 16 | ||||
-rw-r--r-- | include/linux/power_supply.h | 1 |
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, |