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

Commit 264fe994 authored by Lijuan Gao's avatar Lijuan Gao Committed by Ashay Jaiswal
Browse files

platform: qpnp-power-on: Store device restart reason in PMIC register



Use the spare register in PMIC power-on peripheral to store the device
restart reason. The reason can be retained whenever executing a soft/hard
PMIC reset.

Change-Id: I5e639faaf4e2e84098e9dc5fe8ce9d4eede45e0b
Signed-off-by: default avatarLijuan Gao <lijuang@codeaurora.org>
parent 328f3b01
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -56,6 +56,10 @@ Optional properties:
				reset through qcom,system-reset property.
				This should not be defined along with the
				qcom,system-reset property.
- qcom,store-hard-reset-reason	Boolean property which if set will store the hardware
				reset reason to SOFT_RB_SPARE register of the core PMIC
				PON peripheral.


All the below properties are in the sub-node section (properties of the child
node).
@@ -113,6 +117,7 @@ Example:
		qcom,s3-debounce = <32>;
		qcom,s3-src = "resin";
		qcom,clear-warm-reset;
		qcom,store-hard-reset-reason;

		qcom,pon_1 {
			qcom,pon-type = <0>;
+63 −0
Original line number Diff line number Diff line
@@ -27,6 +27,11 @@
#include <linux/log2.h>
#include <linux/qpnp/power-on.h>

#define CREATE_MASK(NUM_BITS, POS) \
	((unsigned char) (((1 << (NUM_BITS)) - 1) << (POS)))
#define PON_MASK(MSB_BIT, LSB_BIT) \
	CREATE_MASK(MSB_BIT - LSB_BIT + 1, LSB_BIT)

#define PMIC_VER_8941           0x01
#define PMIC_VERSION_REG        0x0105
#define PMIC_VERSION_REV4_REG   0x0103
@@ -68,6 +73,7 @@
#define QPNP_PON_S3_DBC_CTL(base)		(base + 0x75)
#define QPNP_PON_TRIGGER_EN(base)		(base + 0x80)
#define QPNP_PON_XVDD_RB_SPARE(base)		(base + 0x8E)
#define QPNP_PON_SOFT_RB_SPARE(base)		(base + 0x8F)
#define QPNP_PON_SEC_ACCESS(base)		(base + 0xD0)

#define QPNP_PON_SEC_UNLOCK			0xA5
@@ -101,6 +107,7 @@
#define QPNP_PON_S3_SRC_KPDPWR_AND_RESIN	2
#define QPNP_PON_S3_SRC_KPDPWR_OR_RESIN		3
#define QPNP_PON_S3_SRC_MASK			0x3
#define QPNP_PON_HARD_RESET_MASK		PON_MASK(7, 5)

#define QPNP_PON_UVLO_DLOAD_EN		BIT(7)

@@ -160,6 +167,7 @@ struct qpnp_pon {
	u8 warm_reset_reason1;
	u8 warm_reset_reason2;
	bool is_spon;
	bool store_hard_reset_reason;
};

static struct qpnp_pon *sys_reset_dev;
@@ -235,6 +243,56 @@ qpnp_pon_masked_write(struct qpnp_pon *pon, u16 addr, u8 mask, u8 val)
	return rc;
}

/**
 * qpnp_pon_set_restart_reason - Store device restart reason in PMIC register.
 *
 * Returns = 0 if PMIC feature is not available or store restart reason
 * successfully.
 * Returns > 0 for errors
 *
 * This function is used to store device restart reason in PMIC register.
 * It checks here to see if the restart reason register has been specified.
 * If it hasn't, this function should immediately return 0
 */
int qpnp_pon_set_restart_reason(enum pon_restart_reason reason)
{
	int rc = 0;
	struct qpnp_pon *pon = sys_reset_dev;

	if (!pon)
		return 0;

	if (!pon->store_hard_reset_reason)
		return 0;

	rc = qpnp_pon_masked_write(pon, QPNP_PON_SOFT_RB_SPARE(pon->base),
					PON_MASK(7, 5), (reason << 5));
	if (rc)
		dev_err(&pon->spmi->dev,
				"Unable to write to addr=%x, rc(%d)\n",
				QPNP_PON_SOFT_RB_SPARE(pon->base), rc);
	return rc;
}
EXPORT_SYMBOL(qpnp_pon_set_restart_reason);

/*
 * qpnp_pon_check_hard_reset_stored - Checks if the PMIC need to
 * store hard reset reason.
 *
 * Returns true if reset reason can be stored, false if it cannot be stored
 *
 */
bool qpnp_pon_check_hard_reset_stored(void)
{
	struct qpnp_pon *pon = sys_reset_dev;

	if (!pon)
		return false;

	return pon->store_hard_reset_reason;
}
EXPORT_SYMBOL(qpnp_pon_check_hard_reset_stored);

static int qpnp_pon_set_dbc(struct qpnp_pon *pon, u32 delay)
{
	int rc = 0;
@@ -1722,6 +1780,11 @@ static int qpnp_pon_probe(struct spmi_device *spmi)
		pon->is_spon = true;
	}

	/* config whether store the hard reset reason */
	pon->store_hard_reset_reason = of_property_read_bool(
					spmi->dev.of_node,
					"qcom,store-hard-reset-reason");

	qpnp_pon_debugfs_init(spmi);
	return 0;
}
+19 −1
Original line number Diff line number Diff line
/* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved.
/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -47,11 +47,21 @@ enum pon_power_off_type {
	PON_POWER_OFF_HARD_RESET	= 0x07,
};

enum pon_restart_reason {
	PON_RESTART_REASON_UNKNOWN	= 0x00,
	PON_RESTART_REASON_RECOVERY	= 0x01,
	PON_RESTART_REASON_BOOTLOADER	= 0x02,
	PON_RESTART_REASON_RTC		= 0x03,
};

#ifdef CONFIG_QPNP_POWER_ON
int qpnp_pon_system_pwr_off(enum pon_power_off_type type);
int qpnp_pon_is_warm_reset(void);
int qpnp_pon_trigger_config(enum pon_trigger_source pon_src, bool enable);
int qpnp_pon_wd_config(bool enable);
int qpnp_pon_set_restart_reason(enum pon_restart_reason reason);
bool qpnp_pon_check_hard_reset_stored(void);

#else
static int qpnp_pon_system_pwr_off(enum pon_power_off_type type)
{
@@ -67,6 +77,14 @@ int qpnp_pon_wd_config(bool enable)
{
	return -ENODEV;
}
static inline int qpnp_pon_set_restart_reason(enum pon_restart_reason reason)
{
	return -ENODEV;
}
static inline bool qpnp_pon_check_hard_reset_stored(void)
{
	return false;
}
#endif

#endif