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

Commit 928ccd2a authored by Kiran Gunda's avatar Kiran Gunda Committed by Gerrit - the friendly Code Review server
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>
Signed-off-by: default avatarShilpa Suresh <sbsure@codeaurora.org>
parent e0875305
Loading
Loading
Loading
Loading
+81 −3
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (c) 2014-2019, The Linux Foundation. All rights reserved.
 * Copyright (c) 2014-2020, The Linux Foundation. All rights reserved.
 */

#define pr_fmt(fmt)	"%s: " fmt, __func__
@@ -590,6 +590,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;
@@ -617,6 +618,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;
};
@@ -2509,6 +2512,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_warn("Short circuit detected: disabled LAB/IBB rails\n");
		return 0;
@@ -2546,6 +2552,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)
@@ -2739,7 +2748,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) {
@@ -3013,6 +3022,8 @@ static int qpnp_lab_register_interrupts(struct qpnp_labibb *labibb)
	int rc;

	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,
@@ -3026,6 +3037,8 @@ static int qpnp_lab_register_interrupts(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,
@@ -3720,6 +3733,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_warn("Short circuit detected: disabled LAB/IBB rails\n");
		return 0;
@@ -3745,6 +3761,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)
@@ -3778,7 +3797,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);
@@ -4063,6 +4082,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,
@@ -4223,6 +4244,52 @@ static int qpnp_labibb_check_ttw_supported(struct qpnp_labibb *labibb)
	return rc;
}

static ssize_t secure_mode_store(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 CLASS_ATTR_WO(secure_mode);

static struct attribute *labibb_attrs[] = {
	&class_attr_secure_mode.attr,
	NULL,
};
ATTRIBUTE_GROUPS(labibb);


static int qpnp_labibb_regulator_probe(struct platform_device *pdev)
{
	struct qpnp_labibb *labibb;
@@ -4411,6 +4478,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_groups = labibb_groups;

	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,
		labibb->swire_control);