From b95cf59a0f119268677a141accd3ebeb6c468fdc Mon Sep 17 00:00:00 2001 From: Nicholas Troast Date: Wed, 3 Aug 2016 09:49:36 -0700 Subject: [PATCH] qcom-charger: add storm watch to qpnp-smb2 and smb138x-charger Interrupts are subject to storming in bad or unexpected circumstances. Add the necessary structures to detect interrupt storms using storm watch. Change-Id: Id3491b6f8927cb1ae7cbc8260defa697ca555765 Signed-off-by: Nicholas Troast --- drivers/power/qcom-charger/qpnp-smb2.c | 213 +++++++++++++++++++++------ drivers/power/qcom-charger/smb-lib.c | 6 +- drivers/power/qcom-charger/smb-lib.h | 6 +- drivers/power/qcom-charger/smb138x-charger.c | 197 ++++++++++++++++++++----- 4 files changed, 332 insertions(+), 90 deletions(-) diff --git a/drivers/power/qcom-charger/qpnp-smb2.c b/drivers/power/qcom-charger/qpnp-smb2.c index b6a3e8600d7c..d5829f8077d4 100644 --- a/drivers/power/qcom-charger/qpnp-smb2.c +++ b/drivers/power/qcom-charger/qpnp-smb2.c @@ -24,6 +24,7 @@ #include #include "smb-reg.h" #include "smb-lib.h" +#include "storm-watch.h" #include "pmic-voter.h" #define SMB2_DEFAULT_WPWR_UW 8000000 @@ -1145,60 +1146,181 @@ static int smb2_determine_initial_status(struct smb2 *chip) **************************/ struct smb2_irq_info { - const char *name; - const irq_handler_t handler; - const bool wake; - int irq; + 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[] = { /* CHARGER IRQs */ - { "chg-error", smblib_handle_debug }, - { "chg-state-change", smblib_handle_chg_state_change, true }, - { "step-chg-state-change", smblib_handle_step_chg_state_change, - true }, - { "step-chg-soc-update-fail", smblib_handle_step_chg_soc_update_fail, - true }, - { "step-chg-soc-update-request", - smblib_handle_step_chg_soc_update_request, true }, + { + .name = "chg-error", + .handler = smblib_handle_debug, + }, + { + .name = "chg-state-change", + .handler = smblib_handle_chg_state_change, + .wake = true, + }, + { + .name = "step-chg-state-change", + .handler = smblib_handle_step_chg_state_change, + .wake = true, + }, + { + .name = "step-chg-soc-update-fail", + .handler = smblib_handle_step_chg_soc_update_fail, + .wake = true, + }, + { + .name = "step-chg-soc-update-request", + .handler = smblib_handle_step_chg_soc_update_request, + .wake = true, + }, /* OTG IRQs */ - { "otg-fail", smblib_handle_debug }, - { "otg-overcurrent", smblib_handle_debug }, - { "otg-oc-dis-sw-sts", smblib_handle_debug }, - { "testmode-change-detect", smblib_handle_debug }, + { + .name = "otg-fail", + .handler = smblib_handle_debug, + }, + { + .name = "otg-overcurrent", + .handler = smblib_handle_debug, + }, + { + .name = "otg-oc-dis-sw-sts", + .handler = smblib_handle_debug, + }, + { + .name = "testmode-change-detect", + .handler = smblib_handle_debug, + }, /* BATTERY IRQs */ - { "bat-temp", smblib_handle_batt_temp_changed }, - { "bat-ocp", smblib_handle_batt_psy_changed }, - { "bat-ov", smblib_handle_batt_psy_changed }, - { "bat-low", smblib_handle_batt_psy_changed }, - { "bat-therm-or-id-missing", smblib_handle_batt_psy_changed }, - { "bat-terminal-missing", smblib_handle_batt_psy_changed }, + { + .name = "bat-temp", + .handler = smblib_handle_batt_temp_changed, + }, + { + .name = "bat-ocp", + .handler = smblib_handle_batt_psy_changed, + }, + { + .name = "bat-ov", + .handler = smblib_handle_batt_psy_changed, + }, + { + .name = "bat-low", + .handler = smblib_handle_batt_psy_changed, + }, + { + .name = "bat-therm-or-id-missing", + .handler = smblib_handle_batt_psy_changed, + }, + { + .name = "bat-terminal-missing", + .handler = smblib_handle_batt_psy_changed, + }, /* USB INPUT IRQs */ - { "usbin-collapse", smblib_handle_debug }, - { "usbin-lt-3p6v", smblib_handle_debug }, - { "usbin-uv", smblib_handle_debug }, - { "usbin-ov", smblib_handle_debug }, - { "usbin-plugin", smblib_handle_usb_plugin, true }, - { "usbin-src-change", smblib_handle_usb_source_change, true }, - { "usbin-icl-change", smblib_handle_icl_change, true }, - { "type-c-change", smblib_handle_usb_typec_change, true }, + { + .name = "usbin-collapse", + .handler = smblib_handle_debug, + }, + { + .name = "usbin-lt-3p6v", + .handler = smblib_handle_debug, + }, + { + .name = "usbin-uv", + .handler = smblib_handle_debug, + }, + { + .name = "usbin-ov", + .handler = smblib_handle_debug, + }, + { + .name = "usbin-plugin", + .handler = smblib_handle_usb_plugin, + .wake = true, + }, + { + .name = "usbin-src-change", + .handler = smblib_handle_usb_source_change, + .wake = true, + }, + { + .name = "usbin-icl-change", + .handler = smblib_handle_icl_change, + .wake = true, + }, + { + .name = "type-c-change", + .handler = smblib_handle_usb_typec_change, + .wake = true, + }, /* DC INPUT IRQs */ - { "dcin-collapse", smblib_handle_debug }, - { "dcin-lt-3p6v", smblib_handle_debug }, - { "dcin-uv", smblib_handle_debug }, - { "dcin-ov", smblib_handle_debug }, - { "dcin-plugin", smblib_handle_debug }, - { "div2-en-dg", smblib_handle_debug }, - { "dcin-icl-change", smblib_handle_debug }, + { + .name = "dcin-collapse", + .handler = smblib_handle_debug, + }, + { + .name = "dcin-lt-3p6v", + .handler = smblib_handle_debug, + }, + { + .name = "dcin-uv", + .handler = smblib_handle_debug, + }, + { + .name = "dcin-ov", + .handler = smblib_handle_debug, + }, + { + .name = "dcin-plugin", + .handler = smblib_handle_debug, + }, + { + .name = "div2-en-dg", + .handler = smblib_handle_debug, + }, + { + .name = "dcin-icl-change", + .handler = smblib_handle_debug, + }, /* MISCELLANEOUS IRQs */ - { "wdog-snarl", NULL }, - { "wdog-bark", NULL }, - { "aicl-fail", smblib_handle_debug }, - { "aicl-done", smblib_handle_debug }, - { "high-duty-cycle", smblib_handle_high_duty_cycle, true }, - { "input-current-limiting", smblib_handle_debug }, - { "temperature-change", smblib_handle_debug }, - { "switcher-power-ok", smblib_handle_debug }, + { + .name = "wdog-snarl", + .handler = NULL, + }, + { + .name = "wdog-bark", + .handler = NULL, + }, + { + .name = "aicl-fail", + .handler = smblib_handle_debug, + }, + { + .name = "aicl-done", + .handler = smblib_handle_debug, + }, + { + .name = "high-duty-cycle", + .handler = smblib_handle_high_duty_cycle, + .wake = true, + }, + { + .name = "input-current-limiting", + .handler = smblib_handle_debug, + }, + { + .name = "temperature-change", + .handler = smblib_handle_debug, + }, + { + .name = "switcher-power-ok", + .handler = smblib_handle_debug, + }, }; static int smb2_get_irq_index_byname(const char *irq_name) @@ -1241,6 +1363,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; rc = devm_request_threaded_irq(chg->dev, irq, NULL, smb2_irqs[irq_index].handler, diff --git a/drivers/power/qcom-charger/smb-lib.c b/drivers/power/qcom-charger/smb-lib.c index baf40fe771b5..84235173cda0 100644 --- a/drivers/power/qcom-charger/smb-lib.c +++ b/drivers/power/qcom-charger/smb-lib.c @@ -18,6 +18,7 @@ #include #include "smb-lib.h" #include "smb-reg.h" +#include "storm-watch.h" #include "pmic-voter.h" #define smblib_dbg(chg, reason, fmt, ...) \ @@ -1643,7 +1644,6 @@ irqreturn_t smblib_handle_debug(int irq, void *data) struct smb_charger *chg = irq_data->parent_data; smblib_dbg(chg, PR_INTERRUPT, "IRQ: %s\n", irq_data->name); - return IRQ_HANDLED; } @@ -1753,7 +1753,7 @@ irqreturn_t smblib_handle_batt_psy_changed(int irq, void *data) struct smb_irq_data *irq_data = data; struct smb_charger *chg = irq_data->parent_data; - smblib_handle_debug(irq, data); + smblib_dbg(chg, PR_INTERRUPT, "IRQ: %s\n", irq_data->name); power_supply_changed(chg->batt_psy); return IRQ_HANDLED; } @@ -1763,7 +1763,7 @@ irqreturn_t smblib_handle_usb_psy_changed(int irq, void *data) struct smb_irq_data *irq_data = data; struct smb_charger *chg = irq_data->parent_data; - smblib_handle_debug(irq, data); + smblib_dbg(chg, PR_INTERRUPT, "IRQ: %s\n", irq_data->name); power_supply_changed(chg->usb_psy); return IRQ_HANDLED; } diff --git a/drivers/power/qcom-charger/smb-lib.h b/drivers/power/qcom-charger/smb-lib.h index a9703921e8b3..de3797644dc1 100644 --- a/drivers/power/qcom-charger/smb-lib.h +++ b/drivers/power/qcom-charger/smb-lib.h @@ -16,6 +16,7 @@ #include #include #include +#include "storm-watch.h" enum print_reason { PR_INTERRUPT = BIT(0), @@ -46,8 +47,9 @@ struct smb_regulator { }; struct smb_irq_data { - void *parent_data; - const char *name; + void *parent_data; + const char *name; + struct storm_watch storm_data; }; struct smb_chg_param { diff --git a/drivers/power/qcom-charger/smb138x-charger.c b/drivers/power/qcom-charger/smb138x-charger.c index 5b4e7bcccdce..33d759be9aeb 100644 --- a/drivers/power/qcom-charger/smb138x-charger.c +++ b/drivers/power/qcom-charger/smb138x-charger.c @@ -25,6 +25,7 @@ #include #include "smb-reg.h" #include "smb-lib.h" +#include "storm-watch.h" #include "pmic-voter.h" #define SMB138X_DEFAULT_FCC_UA 1000000 @@ -748,55 +749,170 @@ static int smb138x_determine_initial_status(struct smb138x *chip) **************************/ struct smb138x_irq_info { - const char *name; - const irq_handler_t handler; + const char *name; + const irq_handler_t handler; + const struct storm_watch storm_data; }; static const struct smb138x_irq_info smb138x_irqs[] = { /* CHARGER IRQs */ - { "chg-error", smblib_handle_debug }, - { "chg-state-change", smblib_handle_debug }, - { "step-chg-state-change", smblib_handle_debug }, - { "step-chg-soc-update-fail", smblib_handle_debug }, - { "step-chg-soc-update-request", smblib_handle_debug }, + { + .name = "chg-error", + .handler = smblib_handle_debug, + }, + { + .name = "chg-state-change", + .handler = smblib_handle_debug, + }, + { + .name = "step-chg-state-change", + .handler = smblib_handle_debug, + }, + { + .name = "step-chg-soc-update-fail", + .handler = smblib_handle_debug, + }, + { + .name = "step-chg-soc-update-request", + .handler = smblib_handle_debug, + }, /* OTG IRQs */ - { "otg-fail", smblib_handle_debug }, - { "otg-overcurrent", smblib_handle_debug }, - { "otg-oc-dis-sw-sts", smblib_handle_debug }, - { "testmode-change-detect", smblib_handle_debug }, + { + .name = "otg-fail", + .handler = smblib_handle_debug, + }, + { + .name = "otg-overcurrent", + .handler = smblib_handle_debug, + }, + { + .name = "otg-oc-dis-sw-sts", + .handler = smblib_handle_debug, + }, + { + .name = "testmode-change-detect", + .handler = smblib_handle_debug, + }, /* BATTERY IRQs */ - { "bat-temp", smblib_handle_batt_psy_changed }, - { "bat-ocp", smblib_handle_batt_psy_changed }, - { "bat-ov", smblib_handle_batt_psy_changed }, - { "bat-low", smblib_handle_batt_psy_changed }, - { "bat-therm-or-id-missing", smblib_handle_batt_psy_changed }, - { "bat-terminal-missing", smblib_handle_batt_psy_changed }, + { + .name = "bat-temp", + .handler = smblib_handle_batt_psy_changed, + }, + { + .name = "bat-ocp", + .handler = smblib_handle_batt_psy_changed, + }, + { + .name = "bat-ov", + .handler = smblib_handle_batt_psy_changed, + }, + { + .name = "bat-low", + .handler = smblib_handle_batt_psy_changed, + }, + { + .name = "bat-therm-or-id-missing", + .handler = smblib_handle_batt_psy_changed, + }, + { + .name = "bat-terminal-missing", + .handler = smblib_handle_batt_psy_changed, + }, /* USB INPUT IRQs */ - { "usbin-collapse", smblib_handle_debug }, - { "usbin-lt-3p6v", smblib_handle_debug }, - { "usbin-uv", smblib_handle_debug }, - { "usbin-ov", smblib_handle_debug }, - { "usbin-plugin", smblib_handle_usb_plugin }, - { "usbin-src-change", smblib_handle_usb_source_change }, - { "usbin-icl-change", smblib_handle_debug }, - { "type-c-change", smblib_handle_usb_typec_change }, + { + .name = "usbin-collapse", + .handler = smblib_handle_debug, + }, + { + .name = "usbin-lt-3p6v", + .handler = smblib_handle_debug, + }, + { + .name = "usbin-uv", + .handler = smblib_handle_debug, + }, + { + .name = "usbin-ov", + .handler = smblib_handle_debug, + }, + { + .name = "usbin-plugin", + .handler = smblib_handle_usb_plugin, + }, + { + .name = "usbin-src-change", + .handler = smblib_handle_usb_source_change, + }, + { + .name = "usbin-icl-change", + .handler = smblib_handle_debug, + }, + { + .name = "type-c-change", + .handler = smblib_handle_usb_typec_change, + }, /* DC INPUT IRQs */ - { "dcin-collapse", smblib_handle_debug }, - { "dcin-lt-3p6v", smblib_handle_debug }, - { "dcin-uv", smblib_handle_debug }, - { "dcin-ov", smblib_handle_debug }, - { "dcin-plugin", smblib_handle_debug }, - { "div2-en-dg", smblib_handle_debug }, - { "dcin-icl-change", smblib_handle_debug }, + { + .name = "dcin-collapse", + .handler = smblib_handle_debug, + }, + { + .name = "dcin-lt-3p6v", + .handler = smblib_handle_debug, + }, + { + .name = "dcin-uv", + .handler = smblib_handle_debug, + }, + { + .name = "dcin-ov", + .handler = smblib_handle_debug, + }, + { + .name = "dcin-plugin", + .handler = smblib_handle_debug, + }, + { + .name = "div2-en-dg", + .handler = smblib_handle_debug, + }, + { + .name = "dcin-icl-change", + .handler = smblib_handle_debug, + }, /* MISCELLANEOUS IRQs */ - { "wdog-snarl", smblib_handle_debug }, - { "wdog-bark", smblib_handle_debug }, - { "aicl-fail", smblib_handle_debug }, - { "aicl-done", smblib_handle_debug }, - { "high-duty-cycle", smblib_handle_debug }, - { "input-current-limiting", smblib_handle_debug }, - { "temperature-change", smblib_handle_debug }, - { "switcher-power-ok", smblib_handle_debug }, + { + .name = "wdog-snarl", + .handler = smblib_handle_debug, + }, + { + .name = "wdog-bark", + .handler = smblib_handle_debug, + }, + { + .name = "aicl-fail", + .handler = smblib_handle_debug, + }, + { + .name = "aicl-done", + .handler = smblib_handle_debug, + }, + { + .name = "high-duty-cycle", + .handler = smblib_handle_debug, + }, + { + .name = "input-current-limiting", + .handler = smblib_handle_debug, + }, + { + .name = "temperature-change", + .handler = smblib_handle_debug, + }, + { + .name = "switcher-power-ok", + .handler = smblib_handle_debug, + }, }; static int smb138x_get_irq_index_byname(const char *irq_name) @@ -837,6 +953,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; rc = devm_request_threaded_irq(chg->dev, irq, NULL, smb138x_irqs[irq_index].handler, -- 2.11.0