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

Commit d3041ac1 authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "leds: qpnp-flash-v2: Acquire the bms_psy handle at runtime"

parents 6e7cb1d2 d43e3bdb
Loading
Loading
Loading
Loading
+5 −46
Original line number Diff line number Diff line
@@ -800,8 +800,11 @@ static int get_property_from_fg(struct qpnp_flash_led *led,
	union power_supply_propval pval = {0, };

	if (!led->bms_psy) {
		pr_err("no bms psy found\n");
		return -EINVAL;
		led->bms_psy = power_supply_get_by_name("bms");
		if (!led->bms_psy) {
			pr_err_ratelimited("Couldn't get bms_psy\n");
			return -ENODEV;
		}
	}

	rc = power_supply_get_property(led->bms_psy, prop, &pval);
@@ -1871,41 +1874,6 @@ static struct device_attribute qpnp_flash_led_attrs[] = {
	__ATTR(enable, 0664, NULL, qpnp_flash_led_prepare_store),
};

static int flash_led_psy_notifier_call(struct notifier_block *nb,
		unsigned long ev, void *v)
{
	struct power_supply *psy = v;
	struct qpnp_flash_led *led =
			container_of(nb, struct qpnp_flash_led, nb);

	if (ev != PSY_EVENT_PROP_CHANGED)
		return NOTIFY_OK;

	if (!strcmp(psy->desc->name, "bms")) {
		led->bms_psy = power_supply_get_by_name("bms");
		if (!led->bms_psy)
			pr_err("Failed to get bms power_supply\n");
		else
			power_supply_unreg_notifier(&led->nb);
	}

	return NOTIFY_OK;
}

static int flash_led_psy_register_notifier(struct qpnp_flash_led *led)
{
	int rc;

	led->nb.notifier_call = flash_led_psy_notifier_call;
	rc = power_supply_reg_notifier(&led->nb);
	if (rc < 0) {
		pr_err("Couldn't register psy notifier, rc = %d\n", rc);
		return rc;
	}

	return 0;
}

/* irq handler */
static irqreturn_t qpnp_flash_led_irq_handler(int irq, void *_led)
{
@@ -3090,15 +3058,6 @@ static int qpnp_flash_led_probe(struct platform_device *pdev)
	if (rc < 0)
		goto error_switch_register;

	led->bms_psy = power_supply_get_by_name("bms");
	if (!led->bms_psy) {
		rc = flash_led_psy_register_notifier(led);
		if (rc < 0) {
			pr_err("Couldn't register psy notifier, rc = %d\n", rc);
			goto error_switch_register;
		}
	}

	rc = qpnp_flash_led_init_settings(led);
	if (rc < 0) {
		pr_err("Failed to initialize flash LED, rc=%d\n", rc);
+85 −4
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) {
@@ -2886,8 +2895,11 @@ static bool is_lab_vreg_ok_irq_available(struct qpnp_labibb *labibb)
		return true;

	if (labibb->pmic_rev_id->pmic_subtype == PMI8998_SUBTYPE &&
		labibb->mode == QPNP_LABIBB_LCD_MODE)
		labibb->mode == QPNP_LABIBB_LCD_MODE) {
		if (labibb->ttw_en)
			return false;
		return true;
	}

	return false;
}
@@ -3013,6 +3025,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 +3040,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 +3736,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 +3764,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 +3800,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 +4085,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 +4247,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 +4481,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);