Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit fe6ba9b9 authored by Kiran Gunda's avatar Kiran Gunda
Browse files

regulator: qpnp-labibb: Add sysfs class to enable/disable the irq



LAB/IBB interrupts need to be disabled and enabled during the entry and
exit of the secure display use case respectively. Add sysfs property
to allow the userspace to perform this operation

To disable the interrupts:
 echo 1 > /sys/class/lcd_bias/secure_mode

To enable the interrupts:
 echo 0 > /sys/class/lcd_bias/secure_mode

Change-Id: Iddd5630c0ff6d3191f2cc0d45bd4e72b938728b0
Signed-off-by: default avatarKiran Gunda <kgunda@codeaurora.org>
parent e4648711
Loading
Loading
Loading
Loading
+77 −2
Original line number Diff line number Diff line
@@ -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;
@@ -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;
};
@@ -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;
@@ -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)
@@ -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) {
@@ -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,
@@ -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,
@@ -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;
@@ -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)
@@ -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);
@@ -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,
@@ -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;
@@ -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,