static int qpnp_pon_input_dispatch(struct qpnp_pon *pon, u32 pon_type) { int rc; struct qpnp_pon_config *cfg = NULL; u8 pon_rt_sts = 0, pon_rt_bit = 0; cfg = qpnp_get_cfg(pon, pon_type); if (!cfg) return -EINVAL; /* Check if key reporting is supported */ if (!cfg->key_code) return 0; /* check the RT status to get the current status of the line */ rc = spmi_ext_register_readl(pon->spmi->ctrl, pon->spmi->sid, QPNP_PON_RT_STS(pon->base), &pon_rt_sts, 1); if (rc) { dev_err(&pon->spmi->dev, "Unable to read PON RT status\n"); return rc; } switch (cfg->pon_type) { case PON_KPDPWR: pon_rt_bit = QPNP_PON_KPDPWR_N_SET; break; case PON_RESIN: pon_rt_bit = QPNP_PON_RESIN_N_SET; break; case PON_CBLPWR: pon_rt_bit = QPNP_PON_CBLPWR_N_SET; break; default: return -EINVAL; } input_report_key(pon->pon_input, cfg->key_code, (pon_rt_sts & pon_rt_bit)); input_sync(pon->pon_input); if((cfg->key_code == 116) && (pon_rt_sts & pon_rt_bit)){ pon->powerkey_state = 1; }else if((cfg->key_code == 116) && !(pon_rt_sts & pon_rt_bit)){ pon->powerkey_state = 0; } #if CONFIG_SEC_DEBUG sec_debug_check_crash_key(cfg->key_code, pon->powerkey_state); #endif #if defined(CONFIG_MACH_MONTBLANC) check_pkey_press=pon->powerkey_state; #endif return 0; }
static void bark_work_func(struct work_struct *work) { int rc; u8 pon_rt_sts = 0; struct qpnp_pon_config *cfg; struct qpnp_pon *pon = container_of(work, struct qpnp_pon, bark_work.work); /* enable reset */ rc = qpnp_pon_masked_write(pon, QPNP_PON_RESIN_S2_CNTL(pon->base), QPNP_PON_S2_CNTL_EN, QPNP_PON_S2_CNTL_EN); if (rc) { dev_err(&pon->spmi->dev, "Unable to configure S2 enable\n"); goto err_return; } /* bark RT status update delay */ msleep(100); /* read the bark RT status */ rc = spmi_ext_register_readl(pon->spmi->ctrl, pon->spmi->sid, QPNP_PON_RT_STS(pon->base), &pon_rt_sts, 1); if (rc) { dev_err(&pon->spmi->dev, "Unable to read PON RT status\n"); goto err_return; } if (!(pon_rt_sts & QPNP_PON_RESIN_BARK_N_SET)) { cfg = qpnp_get_cfg(pon, PON_RESIN); if (!cfg) { dev_err(&pon->spmi->dev, "Invalid config pointer\n"); goto err_return; } /* report the key event and enable the bark IRQ */ input_report_key(pon->pon_input, cfg->key_code, 0); input_sync(pon->pon_input); enable_irq(cfg->bark_irq); } else { /* disable reset */ rc = qpnp_pon_masked_write(pon, QPNP_PON_RESIN_S2_CNTL(pon->base), QPNP_PON_S2_CNTL_EN, 0); if (rc) { dev_err(&pon->spmi->dev, "Unable to configure S2 enable\n"); goto err_return; } /* re-arm the work */ schedule_delayed_work(&pon->bark_work, QPNP_KEY_STATUS_DELAY); } err_return: return; }
static void forcecrash_timeout(unsigned long data) { u8 pon_rt_sts = 0, rt_bit = QPNP_PON_KPDPWR_N_SET; int rc; rc = spmi_ext_register_readl(gspmi->ctrl, gspmi->sid, QPNP_PON_RT_STS(base), &pon_rt_sts, 1); if (rc) dev_err(dev, "Unable to read PON RT status\n"); dev_info(dev, "status %d\n", pon_rt_sts & rt_bit); if (pon_rt_sts & rt_bit) panic("Force crash triggered!!!\n"); else { del_timer(&forcecrash_timer); wake_unlock(&wakelock); } }