Loading drivers/regulator/qpnp-labibb-regulator.c +77 −2 Original line number Diff line number Diff line Loading @@ -597,6 +597,7 @@ struct qpnp_labibb { struct device *dev; struct platform_device *pdev; struct regmap *regmap; struct class labibb_class; struct pmic_revid_data *pmic_rev_id; u16 lab_base; u16 ibb_base; Loading Loading @@ -624,6 +625,8 @@ struct qpnp_labibb { bool notify_lab_vreg_ok_sts; bool detect_lab_sc; bool sc_detected; /* Tracks the secure UI mode entry/exit */ bool secure_mode; u32 swire_2nd_cmd_delay; u32 swire_ibb_ps_enable_delay; }; Loading Loading @@ -2463,6 +2466,9 @@ static int qpnp_lab_regulator_enable(struct regulator_dev *rdev) int rc; struct qpnp_labibb *labibb = rdev_get_drvdata(rdev); if (labibb->secure_mode) return 0; if (labibb->sc_detected) { pr_info("Short circuit detected: disabled LAB/IBB rails\n"); return 0; Loading Loading @@ -2500,6 +2506,9 @@ static int qpnp_lab_regulator_disable(struct regulator_dev *rdev) u8 val; struct qpnp_labibb *labibb = rdev_get_drvdata(rdev); if (labibb->secure_mode) return 0; if (labibb->lab_vreg.vreg_enabled && !labibb->swire_control) { if (!labibb->standalone) Loading Loading @@ -2693,7 +2702,7 @@ static int qpnp_lab_regulator_set_voltage(struct regulator_dev *rdev, u8 val; struct qpnp_labibb *labibb = rdev_get_drvdata(rdev); if (labibb->swire_control) if (labibb->swire_control || labibb->secure_mode) return 0; if (min_uV < labibb->lab_vreg.min_volt) { Loading Loading @@ -3072,6 +3081,8 @@ static int register_qpnp_lab_regulator(struct qpnp_labibb *labibb, } if (is_lab_vreg_ok_irq_available(labibb)) { irq_set_status_flags(labibb->lab_vreg.lab_vreg_ok_irq, IRQ_DISABLE_UNLAZY); rc = devm_request_threaded_irq(labibb->dev, labibb->lab_vreg.lab_vreg_ok_irq, NULL, lab_vreg_ok_handler, Loading @@ -3085,6 +3096,8 @@ static int register_qpnp_lab_regulator(struct qpnp_labibb *labibb, } if (labibb->lab_vreg.lab_sc_irq != -EINVAL) { irq_set_status_flags(labibb->lab_vreg.lab_sc_irq, IRQ_DISABLE_UNLAZY); rc = devm_request_threaded_irq(labibb->dev, labibb->lab_vreg.lab_sc_irq, NULL, labibb_sc_err_handler, Loading Loading @@ -3568,6 +3581,9 @@ static int qpnp_ibb_regulator_enable(struct regulator_dev *rdev) int rc = 0; struct qpnp_labibb *labibb = rdev_get_drvdata(rdev); if (labibb->secure_mode) return 0; if (labibb->sc_detected) { pr_info("Short circuit detected: disabled LAB/IBB rails\n"); return 0; Loading @@ -3593,6 +3609,9 @@ static int qpnp_ibb_regulator_disable(struct regulator_dev *rdev) int rc; struct qpnp_labibb *labibb = rdev_get_drvdata(rdev); if (labibb->secure_mode) return 0; if (labibb->ibb_vreg.vreg_enabled && !labibb->swire_control) { if (!labibb->standalone) Loading Loading @@ -3626,7 +3645,7 @@ static int qpnp_ibb_regulator_set_voltage(struct regulator_dev *rdev, struct qpnp_labibb *labibb = rdev_get_drvdata(rdev); if (labibb->swire_control) if (labibb->swire_control || labibb->secure_mode) return 0; rc = labibb->ibb_ver_ops->set_voltage(labibb, min_uV, max_uV); Loading Loading @@ -3855,6 +3874,8 @@ static int register_qpnp_ibb_regulator(struct qpnp_labibb *labibb, } if (labibb->ibb_vreg.ibb_sc_irq != -EINVAL) { irq_set_status_flags(labibb->ibb_vreg.ibb_sc_irq, IRQ_DISABLE_UNLAZY); rc = devm_request_threaded_irq(labibb->dev, labibb->ibb_vreg.ibb_sc_irq, NULL, labibb_sc_err_handler, Loading Loading @@ -4016,6 +4037,49 @@ static int qpnp_labibb_check_ttw_supported(struct qpnp_labibb *labibb) return rc; } static ssize_t qpnp_labibb_irq_control(struct class *c, struct class_attribute *attr, const char *buf, size_t count) { struct qpnp_labibb *labibb = container_of(c, struct qpnp_labibb, labibb_class); int val, rc; rc = kstrtouint(buf, 0, &val); if (rc < 0) return rc; if (val != 0 && val != 1) return count; /* Disable irqs */ if (val == 1 && !labibb->secure_mode) { if (labibb->lab_vreg.lab_vreg_ok_irq > 0) disable_irq(labibb->lab_vreg.lab_vreg_ok_irq); if (labibb->lab_vreg.lab_sc_irq > 0) disable_irq(labibb->lab_vreg.lab_sc_irq); if (labibb->ibb_vreg.ibb_sc_irq > 0) disable_irq(labibb->ibb_vreg.ibb_sc_irq); labibb->secure_mode = true; } else if (val == 0 && labibb->secure_mode) { if (labibb->lab_vreg.lab_vreg_ok_irq > 0) enable_irq(labibb->lab_vreg.lab_vreg_ok_irq); if (labibb->lab_vreg.lab_sc_irq > 0) enable_irq(labibb->lab_vreg.lab_sc_irq); if (labibb->ibb_vreg.ibb_sc_irq > 0) enable_irq(labibb->ibb_vreg.ibb_sc_irq); labibb->secure_mode = false; } return count; } static struct class_attribute labibb_attributes[] = { [0] = __ATTR(secure_mode, 0664, NULL, qpnp_labibb_irq_control), __ATTR_NULL, }; static int qpnp_labibb_regulator_probe(struct platform_device *pdev) { struct qpnp_labibb *labibb; Loading Loading @@ -4208,6 +4272,17 @@ static int qpnp_labibb_regulator_probe(struct platform_device *pdev) CLOCK_MONOTONIC, HRTIMER_MODE_REL); labibb->sc_err_check_timer.function = labibb_check_sc_err_count; dev_set_drvdata(&pdev->dev, labibb); labibb->labibb_class.name = "lcd_bias"; labibb->labibb_class.owner = THIS_MODULE; labibb->labibb_class.class_attrs = labibb_attributes; rc = class_register(&labibb->labibb_class); if (rc < 0) { pr_err("Failed to register labibb class rc=%d\n", rc); return rc; } pr_info("LAB/IBB registered successfully, lab_vreg enable=%d ibb_vreg enable=%d swire_control=%d\n", labibb->lab_vreg.vreg_enabled, labibb->ibb_vreg.vreg_enabled, Loading Loading
drivers/regulator/qpnp-labibb-regulator.c +77 −2 Original line number Diff line number Diff line Loading @@ -597,6 +597,7 @@ struct qpnp_labibb { struct device *dev; struct platform_device *pdev; struct regmap *regmap; struct class labibb_class; struct pmic_revid_data *pmic_rev_id; u16 lab_base; u16 ibb_base; Loading Loading @@ -624,6 +625,8 @@ struct qpnp_labibb { bool notify_lab_vreg_ok_sts; bool detect_lab_sc; bool sc_detected; /* Tracks the secure UI mode entry/exit */ bool secure_mode; u32 swire_2nd_cmd_delay; u32 swire_ibb_ps_enable_delay; }; Loading Loading @@ -2463,6 +2466,9 @@ static int qpnp_lab_regulator_enable(struct regulator_dev *rdev) int rc; struct qpnp_labibb *labibb = rdev_get_drvdata(rdev); if (labibb->secure_mode) return 0; if (labibb->sc_detected) { pr_info("Short circuit detected: disabled LAB/IBB rails\n"); return 0; Loading Loading @@ -2500,6 +2506,9 @@ static int qpnp_lab_regulator_disable(struct regulator_dev *rdev) u8 val; struct qpnp_labibb *labibb = rdev_get_drvdata(rdev); if (labibb->secure_mode) return 0; if (labibb->lab_vreg.vreg_enabled && !labibb->swire_control) { if (!labibb->standalone) Loading Loading @@ -2693,7 +2702,7 @@ static int qpnp_lab_regulator_set_voltage(struct regulator_dev *rdev, u8 val; struct qpnp_labibb *labibb = rdev_get_drvdata(rdev); if (labibb->swire_control) if (labibb->swire_control || labibb->secure_mode) return 0; if (min_uV < labibb->lab_vreg.min_volt) { Loading Loading @@ -3072,6 +3081,8 @@ static int register_qpnp_lab_regulator(struct qpnp_labibb *labibb, } if (is_lab_vreg_ok_irq_available(labibb)) { irq_set_status_flags(labibb->lab_vreg.lab_vreg_ok_irq, IRQ_DISABLE_UNLAZY); rc = devm_request_threaded_irq(labibb->dev, labibb->lab_vreg.lab_vreg_ok_irq, NULL, lab_vreg_ok_handler, Loading @@ -3085,6 +3096,8 @@ static int register_qpnp_lab_regulator(struct qpnp_labibb *labibb, } if (labibb->lab_vreg.lab_sc_irq != -EINVAL) { irq_set_status_flags(labibb->lab_vreg.lab_sc_irq, IRQ_DISABLE_UNLAZY); rc = devm_request_threaded_irq(labibb->dev, labibb->lab_vreg.lab_sc_irq, NULL, labibb_sc_err_handler, Loading Loading @@ -3568,6 +3581,9 @@ static int qpnp_ibb_regulator_enable(struct regulator_dev *rdev) int rc = 0; struct qpnp_labibb *labibb = rdev_get_drvdata(rdev); if (labibb->secure_mode) return 0; if (labibb->sc_detected) { pr_info("Short circuit detected: disabled LAB/IBB rails\n"); return 0; Loading @@ -3593,6 +3609,9 @@ static int qpnp_ibb_regulator_disable(struct regulator_dev *rdev) int rc; struct qpnp_labibb *labibb = rdev_get_drvdata(rdev); if (labibb->secure_mode) return 0; if (labibb->ibb_vreg.vreg_enabled && !labibb->swire_control) { if (!labibb->standalone) Loading Loading @@ -3626,7 +3645,7 @@ static int qpnp_ibb_regulator_set_voltage(struct regulator_dev *rdev, struct qpnp_labibb *labibb = rdev_get_drvdata(rdev); if (labibb->swire_control) if (labibb->swire_control || labibb->secure_mode) return 0; rc = labibb->ibb_ver_ops->set_voltage(labibb, min_uV, max_uV); Loading Loading @@ -3855,6 +3874,8 @@ static int register_qpnp_ibb_regulator(struct qpnp_labibb *labibb, } if (labibb->ibb_vreg.ibb_sc_irq != -EINVAL) { irq_set_status_flags(labibb->ibb_vreg.ibb_sc_irq, IRQ_DISABLE_UNLAZY); rc = devm_request_threaded_irq(labibb->dev, labibb->ibb_vreg.ibb_sc_irq, NULL, labibb_sc_err_handler, Loading Loading @@ -4016,6 +4037,49 @@ static int qpnp_labibb_check_ttw_supported(struct qpnp_labibb *labibb) return rc; } static ssize_t qpnp_labibb_irq_control(struct class *c, struct class_attribute *attr, const char *buf, size_t count) { struct qpnp_labibb *labibb = container_of(c, struct qpnp_labibb, labibb_class); int val, rc; rc = kstrtouint(buf, 0, &val); if (rc < 0) return rc; if (val != 0 && val != 1) return count; /* Disable irqs */ if (val == 1 && !labibb->secure_mode) { if (labibb->lab_vreg.lab_vreg_ok_irq > 0) disable_irq(labibb->lab_vreg.lab_vreg_ok_irq); if (labibb->lab_vreg.lab_sc_irq > 0) disable_irq(labibb->lab_vreg.lab_sc_irq); if (labibb->ibb_vreg.ibb_sc_irq > 0) disable_irq(labibb->ibb_vreg.ibb_sc_irq); labibb->secure_mode = true; } else if (val == 0 && labibb->secure_mode) { if (labibb->lab_vreg.lab_vreg_ok_irq > 0) enable_irq(labibb->lab_vreg.lab_vreg_ok_irq); if (labibb->lab_vreg.lab_sc_irq > 0) enable_irq(labibb->lab_vreg.lab_sc_irq); if (labibb->ibb_vreg.ibb_sc_irq > 0) enable_irq(labibb->ibb_vreg.ibb_sc_irq); labibb->secure_mode = false; } return count; } static struct class_attribute labibb_attributes[] = { [0] = __ATTR(secure_mode, 0664, NULL, qpnp_labibb_irq_control), __ATTR_NULL, }; static int qpnp_labibb_regulator_probe(struct platform_device *pdev) { struct qpnp_labibb *labibb; Loading Loading @@ -4208,6 +4272,17 @@ static int qpnp_labibb_regulator_probe(struct platform_device *pdev) CLOCK_MONOTONIC, HRTIMER_MODE_REL); labibb->sc_err_check_timer.function = labibb_check_sc_err_count; dev_set_drvdata(&pdev->dev, labibb); labibb->labibb_class.name = "lcd_bias"; labibb->labibb_class.owner = THIS_MODULE; labibb->labibb_class.class_attrs = labibb_attributes; rc = class_register(&labibb->labibb_class); if (rc < 0) { pr_err("Failed to register labibb class rc=%d\n", rc); return rc; } pr_info("LAB/IBB registered successfully, lab_vreg enable=%d ibb_vreg enable=%d swire_control=%d\n", labibb->lab_vreg.vreg_enabled, labibb->ibb_vreg.vreg_enabled, Loading