lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20250416120619.483793-4-shgarg@nvidia.com>
Date: Wed, 16 Apr 2025 12:06:17 +0000
From: Shubhi Garg <shgarg@...dia.com>
To: <lee@...nel.org>, <alexandre.belloni@...tlin.com>,
	<thierry.reding@...il.com>, <jonathanh@...dia.com>,
	<devicetree@...r.kernel.org>, <linux-kernel@...r.kernel.org>,
	<linux-tegra@...r.kernel.org>
CC: <shgarg@...dia.com>
Subject: [PATCH 3/5] mfd: nvvrs: add NVVRS PSEQ MFD driver

Add support for NVIDIA VRS (Voltage Regulator Specification) power
sequencer device driver. This driver manages ON/OFF and suspend/resume
power sequencing of system power rails for NVIDIA Tegra234 SoC. It also
provides 32kHz RTC clock support with backup battery for system timing.

Signed-off-by: Shubhi Garg <shgarg@...dia.com>
---
 drivers/mfd/Kconfig                 |  12 ++
 drivers/mfd/Makefile                |   1 +
 drivers/mfd/nvidia-vrs-pseq.c       | 279 ++++++++++++++++++++++++++++
 include/linux/mfd/nvidia-vrs-pseq.h | 127 +++++++++++++
 4 files changed, 419 insertions(+)
 create mode 100644 drivers/mfd/nvidia-vrs-pseq.c
 create mode 100644 include/linux/mfd/nvidia-vrs-pseq.h

diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 22b936310039..b7357ff398f2 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -1396,6 +1396,18 @@ config MFD_SC27XX_PMIC
 	  This driver provides common support for accessing the SC27xx PMICs,
 	  and it also adds the irq_chip parts for handling the PMIC chip events.
 
+config MFD_NVVRS_PSEQ
+	tristate "NVIDIA Voltage Regulator Specification Power Sequencer"
+	depends on I2C=y
+	select MFD_CORE
+	select REGMAP_I2C
+	select REGMAP_IRQ
+	help
+	  Say Y here to add support for NVIDIA Voltage Regulator Specification
+	  Power Sequencer. NVVRS_PSEQ supports ON/OFF, suspend/resume sequence of
+	  system power rails. It provides 32kHz RTC clock support with backup
+	  battery for system timing.
+
 config RZ_MTU3
 	tristate "Renesas RZ/G2L MTU3a core driver"
 	depends on (ARCH_RZG2L && OF) || COMPILE_TEST
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index 948cbdf42a18..93bb2c34e341 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -182,6 +182,7 @@ obj-$(CONFIG_MFD_MT6360)	+= mt6360-core.o
 obj-$(CONFIG_MFD_MT6370)	+= mt6370.o
 mt6397-objs			:= mt6397-core.o mt6397-irq.o mt6358-irq.o
 obj-$(CONFIG_MFD_MT6397)	+= mt6397.o
+obj-$(CONFIG_MFD_NVVRS_PSEQ)    += nvidia-vrs-pseq.o
 
 obj-$(CONFIG_RZ_MTU3)		+= rz-mtu3.o
 obj-$(CONFIG_ABX500_CORE)	+= abx500-core.o
diff --git a/drivers/mfd/nvidia-vrs-pseq.c b/drivers/mfd/nvidia-vrs-pseq.c
new file mode 100644
index 000000000000..c93730168dcb
--- /dev/null
+++ b/drivers/mfd/nvidia-vrs-pseq.c
@@ -0,0 +1,279 @@
+// SPDX-License-Identifier: GPL-2.0-only
+// SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
+// NVIDIA VRS Power Sequencer driver.
+
+#include <linux/i2c.h>
+#include <linux/interrupt.h>
+#include <linux/mfd/core.h>
+#include <linux/mfd/nvidia-vrs-pseq.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
+#include <linux/err.h>
+
+static const struct resource rtc_resources[] = {
+	DEFINE_RES_IRQ(NVVRS_PSEQ_INT_SRC1_RTC),
+};
+
+static const struct regmap_irq nvvrs_pseq_irqs[] = {
+	REGMAP_IRQ_REG(NVVRS_PSEQ_INT_SRC1_RSTIRQ, 0, NVVRS_PSEQ_INT_SRC1_RSTIRQ_MASK),
+	REGMAP_IRQ_REG(NVVRS_PSEQ_INT_SRC1_OSC, 0, NVVRS_PSEQ_INT_SRC1_OSC_MASK),
+	REGMAP_IRQ_REG(NVVRS_PSEQ_INT_SRC1_EN, 0, NVVRS_PSEQ_INT_SRC1_EN_MASK),
+	REGMAP_IRQ_REG(NVVRS_PSEQ_INT_SRC1_RTC, 0, NVVRS_PSEQ_INT_SRC1_RTC_MASK),
+	REGMAP_IRQ_REG(NVVRS_PSEQ_INT_SRC1_PEC, 0, NVVRS_PSEQ_INT_SRC1_PEC_MASK),
+	REGMAP_IRQ_REG(NVVRS_PSEQ_INT_SRC1_WDT, 0, NVVRS_PSEQ_INT_SRC1_WDT_MASK),
+	REGMAP_IRQ_REG(NVVRS_PSEQ_INT_SRC1_EM_PD, 0, NVVRS_PSEQ_INT_SRC1_EM_PD_MASK),
+	REGMAP_IRQ_REG(NVVRS_PSEQ_INT_SRC1_INTERNAL, 0, NVVRS_PSEQ_INT_SRC1_INTERNAL_MASK),
+	REGMAP_IRQ_REG(NVVRS_PSEQ_INT_SRC2_PBSP, 1, NVVRS_PSEQ_INT_SRC2_PBSP_MASK),
+	REGMAP_IRQ_REG(NVVRS_PSEQ_INT_SRC2_ECC_DED, 1, NVVRS_PSEQ_INT_SRC2_ECC_DED_MASK),
+	REGMAP_IRQ_REG(NVVRS_PSEQ_INT_SRC2_TSD, 1, NVVRS_PSEQ_INT_SRC2_TSD_MASK),
+	REGMAP_IRQ_REG(NVVRS_PSEQ_INT_SRC2_LDO, 1, NVVRS_PSEQ_INT_SRC2_LDO_MASK),
+	REGMAP_IRQ_REG(NVVRS_PSEQ_INT_SRC2_BIST, 1, NVVRS_PSEQ_INT_SRC2_BIST_MASK),
+	REGMAP_IRQ_REG(NVVRS_PSEQ_INT_SRC2_RT_CRC, 1, NVVRS_PSEQ_INT_SRC2_RT_CRC_MASK),
+	REGMAP_IRQ_REG(NVVRS_PSEQ_INT_SRC2_VENDOR, 1, NVVRS_PSEQ_INT_SRC2_VENDOR_MASK),
+	REGMAP_IRQ_REG(NVVRS_PSEQ_INT_VENDOR0, 2, NVVRS_PSEQ_INT_VENDOR0_MASK),
+	REGMAP_IRQ_REG(NVVRS_PSEQ_INT_VENDOR1, 2, NVVRS_PSEQ_INT_VENDOR1_MASK),
+	REGMAP_IRQ_REG(NVVRS_PSEQ_INT_VENDOR2, 2, NVVRS_PSEQ_INT_VENDOR2_MASK),
+	REGMAP_IRQ_REG(NVVRS_PSEQ_INT_VENDOR3, 2, NVVRS_PSEQ_INT_VENDOR3_MASK),
+	REGMAP_IRQ_REG(NVVRS_PSEQ_INT_VENDOR4, 2, NVVRS_PSEQ_INT_VENDOR4_MASK),
+	REGMAP_IRQ_REG(NVVRS_PSEQ_INT_VENDOR5, 2, NVVRS_PSEQ_INT_VENDOR5_MASK),
+	REGMAP_IRQ_REG(NVVRS_PSEQ_INT_VENDOR6, 2, NVVRS_PSEQ_INT_VENDOR6_MASK),
+	REGMAP_IRQ_REG(NVVRS_PSEQ_INT_VENDOR7, 2, NVVRS_PSEQ_INT_VENDOR7_MASK),
+};
+
+static const struct mfd_cell nvvrs_pseq_children[] = {
+	{
+		.name = "nvvrs-pseq-rtc",
+		.resources = rtc_resources,
+		.num_resources = ARRAY_SIZE(rtc_resources),
+	},
+};
+
+static const struct regmap_range nvvrs_pseq_readable_ranges[] = {
+	regmap_reg_range(NVVRS_PSEQ_REG_VENDOR_ID, NVVRS_PSEQ_REG_MODEL_REV),
+	regmap_reg_range(NVVRS_PSEQ_REG_INT_SRC1, NVVRS_PSEQ_REG_LAST_RST),
+	regmap_reg_range(NVVRS_PSEQ_REG_EN_ALT_F, NVVRS_PSEQ_REG_IEN_VENDOR),
+	regmap_reg_range(NVVRS_PSEQ_REG_RTC_T3, NVVRS_PSEQ_REG_RTC_A0),
+	regmap_reg_range(NVVRS_PSEQ_REG_WDT_CFG, NVVRS_PSEQ_REG_WDTKEY),
+};
+
+static const struct regmap_access_table nvvrs_pseq_readable_table = {
+	.yes_ranges = nvvrs_pseq_readable_ranges,
+	.n_yes_ranges = ARRAY_SIZE(nvvrs_pseq_readable_ranges),
+};
+
+static const struct regmap_range nvvrs_pseq_writable_ranges[] = {
+	regmap_reg_range(NVVRS_PSEQ_REG_INT_SRC1, NVVRS_PSEQ_REG_INT_VENDOR),
+	regmap_reg_range(NVVRS_PSEQ_REG_GP_OUT, NVVRS_PSEQ_REG_IEN_VENDOR),
+	regmap_reg_range(NVVRS_PSEQ_REG_RTC_T3, NVVRS_PSEQ_REG_RTC_A0),
+	regmap_reg_range(NVVRS_PSEQ_REG_WDT_CFG, NVVRS_PSEQ_REG_WDTKEY),
+};
+
+static const struct regmap_access_table nvvrs_pseq_writable_table = {
+	.yes_ranges = nvvrs_pseq_writable_ranges,
+	.n_yes_ranges = ARRAY_SIZE(nvvrs_pseq_writable_ranges),
+};
+
+static const struct regmap_config nvvrs_pseq_regmap_config = {
+	.name = "nvvrs-pseq",
+	.reg_bits = 8,
+	.val_bits = 8,
+	.max_register = NVVRS_PSEQ_REG_WDTKEY + 1,
+	.cache_type = REGCACHE_RBTREE,
+	.rd_table = &nvvrs_pseq_readable_table,
+	.wr_table = &nvvrs_pseq_writable_table,
+};
+
+static int nvvrs_pseq_irq_clear(void *irq_drv_data)
+{
+	struct nvvrs_pseq_chip *chip = (struct nvvrs_pseq_chip *)irq_drv_data;
+	struct i2c_client *client = chip->client;
+	u8 reg, val;
+	unsigned int i;
+	int ret = 0;
+
+	/* Write 1 to clear the interrupt bit in the Interrupt
+	 * Source Register, writing 0 has no effect, writing 1 to a bit
+	 * which is already at 0 has no effect
+	 */
+
+	for (i = 0; i < chip->irq_chip->num_regs; i++) {
+		reg = (u8)(chip->irq_chip->status_base + i);
+		ret = i2c_smbus_read_byte_data(client, reg);
+		if (ret < 0) {
+			dev_err(chip->dev, "Failed to read interrupt register: 0x%02x, ret=%d\n",
+				reg, ret);
+			return ret;
+		} else if (ret > 0) {
+			val = (u8)ret;
+			dev_dbg(chip->dev, "Clearing interrupts! Interrupt status reg 0x%02x = 0x%02x\n",
+				reg, val);
+
+			/* Clear interrupt */
+			ret = i2c_smbus_write_byte_data(client, reg, val);
+			if (ret < 0) {
+				dev_err(chip->dev, "Failed to write interrupt register: 0x%02x, ret= %d\n",
+					reg, ret);
+				return ret;
+			}
+		}
+	}
+
+	return 0;
+}
+
+static const struct regmap_irq_chip nvvrs_pseq_irq_chip = {
+	.name = "nvvrs-pseq-irq",
+	.irqs = nvvrs_pseq_irqs,
+	.num_irqs = ARRAY_SIZE(nvvrs_pseq_irqs),
+	.num_regs = 3,
+	.status_base = NVVRS_PSEQ_REG_INT_SRC1,
+	.handle_post_irq = nvvrs_pseq_irq_clear,
+};
+
+static int nvvrs_pseq_vendor_info(struct nvvrs_pseq_chip *chip)
+{
+	struct i2c_client *client = chip->client;
+	u8 vendor_id, model_rev;
+	int ret;
+
+	ret = i2c_smbus_read_byte_data(client, NVVRS_PSEQ_REG_VENDOR_ID);
+	if (ret < 0) {
+		dev_err(chip->dev, "Failed to read Vendor ID: %d\n", ret);
+		return ret;
+	}
+
+	vendor_id = (u8)ret;
+
+	ret = i2c_smbus_read_byte_data(client, NVVRS_PSEQ_REG_MODEL_REV);
+	if (ret < 0) {
+		dev_err(chip->dev, "Failed to read Model Rev: %d\n", ret);
+		return ret;
+	}
+
+	model_rev = (u8)ret;
+
+	if (model_rev < 0x40) {
+		dev_err(chip->dev, "Chip revision 0x%02x is not supported!\n",
+			model_rev);
+		return -ENODEV;
+	}
+
+	dev_info(chip->dev, "NVVRS Vendor ID: 0x%02x, Model Rev: 0x%02x\n",
+		 vendor_id, model_rev);
+
+	return 0;
+}
+
+static int nvvrs_pseq_probe(struct i2c_client *client)
+{
+	const struct regmap_config *rmap_config;
+	struct nvvrs_pseq_chip *nvvrs_chip;
+	const struct mfd_cell *mfd_cells;
+	int n_mfd_cells;
+	int ret;
+
+	nvvrs_chip = devm_kzalloc(&client->dev, sizeof(*nvvrs_chip), GFP_KERNEL);
+	if (!nvvrs_chip)
+		return -ENOMEM;
+
+	/* Set PEC flag for SMBUS transfer with PEC enabled */
+	client->flags |= I2C_CLIENT_PEC;
+
+	i2c_set_clientdata(client, nvvrs_chip);
+	nvvrs_chip->client = client;
+	nvvrs_chip->dev = &client->dev;
+	nvvrs_chip->chip_irq = client->irq;
+	mfd_cells = nvvrs_pseq_children;
+	n_mfd_cells = ARRAY_SIZE(nvvrs_pseq_children);
+	rmap_config = &nvvrs_pseq_regmap_config;
+	nvvrs_chip->irq_chip = &nvvrs_pseq_irq_chip;
+
+	nvvrs_chip->rmap = devm_regmap_init_i2c(client, rmap_config);
+	if (IS_ERR(nvvrs_chip->rmap)) {
+		ret = PTR_ERR(nvvrs_chip->rmap);
+		dev_err(nvvrs_chip->dev, "Failed to initialise regmap: %d\n", ret);
+		return ret;
+	}
+
+	ret = nvvrs_pseq_vendor_info(nvvrs_chip);
+	if (ret < 0)
+		return ret;
+
+	nvvrs_chip->irq_drv_data = nvvrs_chip;
+	ret = devm_regmap_add_irq_chip(nvvrs_chip->dev, nvvrs_chip->rmap, client->irq,
+				       IRQF_ONESHOT | IRQF_SHARED, 0,
+				       &nvvrs_pseq_irq_chip,
+				       &nvvrs_chip->irq_data);
+	if (ret < 0) {
+		dev_err(nvvrs_chip->dev, "Failed to add regmap irq: %d\n", ret);
+		return ret;
+	}
+
+	ret =  devm_mfd_add_devices(nvvrs_chip->dev, PLATFORM_DEVID_NONE,
+				    mfd_cells, n_mfd_cells, NULL, 0,
+				    regmap_irq_get_domain(nvvrs_chip->irq_data));
+	if (ret < 0) {
+		dev_err(nvvrs_chip->dev, "Failed to add MFD children: %d\n", ret);
+		return ret;
+	}
+
+	dev_info(nvvrs_chip->dev, "NVVRS PSEQ probe successful");
+	return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int nvvrs_pseq_i2c_suspend(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+
+	/*
+	 * IRQ must be disabled during suspend because if it happens
+	 * while suspended it will be handled before resuming I2C.
+	 *
+	 * When device is woken up from suspend (e.g. by RTC wake alarm),
+	 * an interrupt occurs before resuming I2C bus controller.
+	 * Interrupt handler tries to read registers but this read
+	 * will fail because I2C is still suspended.
+	 */
+	disable_irq(client->irq);
+
+	return 0;
+}
+
+static int nvvrs_pseq_i2c_resume(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+
+	enable_irq(client->irq);
+	return 0;
+}
+#endif
+
+static const struct dev_pm_ops nvvrs_pseq_pm_ops = {
+	SET_SYSTEM_SLEEP_PM_OPS(nvvrs_pseq_i2c_suspend, nvvrs_pseq_i2c_resume)
+};
+
+static const struct of_device_id nvvrs_dt_match[] = {
+	{ .compatible = "nvidia,vrs-pseq" },
+	{}
+};
+MODULE_DEVICE_TABLE(of, nvvrs_dt_match);
+
+static struct i2c_driver nvvrs_pseq_driver = {
+	.driver = {
+		.name = "nvvrs_pseq",
+		.pm = &nvvrs_pseq_pm_ops,
+		.of_match_table = of_match_ptr(nvvrs_dt_match),
+	},
+	.probe = nvvrs_pseq_probe,
+};
+
+module_i2c_driver(nvvrs_pseq_driver);
+
+MODULE_AUTHOR("Shubhi Garg <shgarg@...dia.com>");
+MODULE_DESCRIPTION("NVIDIA Voltage Regulator Specification Power Sequencer Driver");
+MODULE_LICENSE("GPL");
diff --git a/include/linux/mfd/nvidia-vrs-pseq.h b/include/linux/mfd/nvidia-vrs-pseq.h
new file mode 100644
index 000000000000..7e6f3aa940e7
--- /dev/null
+++ b/include/linux/mfd/nvidia-vrs-pseq.h
@@ -0,0 +1,127 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+// SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved
+
+#ifndef _MFD_NVIDIA_VRS_PSEQ_H_
+#define _MFD_NVIDIA_VRS_PSEQ_H_
+
+#include <linux/types.h>
+
+/* Vendor ID */
+#define NVVRS_PSEQ_REG_VENDOR_ID		0x00
+#define NVVRS_PSEQ_REG_MODEL_REV		0x01
+
+/*  Interrupts and Status registers */
+#define NVVRS_PSEQ_REG_INT_SRC1			0x10
+#define NVVRS_PSEQ_REG_INT_SRC2			0x11
+#define NVVRS_PSEQ_REG_INT_VENDOR		0x12
+#define NVVRS_PSEQ_REG_CTL_STAT			0x13
+#define NVVRS_PSEQ_REG_EN_STDR1			0x14
+#define NVVRS_PSEQ_REG_EN_STDR2			0x15
+#define NVVRS_PSEQ_REG_EN_STRD1			0x16
+#define NVVRS_PSEQ_REG_EN_STRD2			0x17
+#define NVVRS_PSEQ_REG_WDT_STAT			0x18
+#define NVVRS_PSEQ_REG_TEST_STAT		0x19
+#define NVVRS_PSEQ_REG_LAST_RST			0x1A
+
+/* Configuration Registers */
+#define NVVRS_PSEQ_REG_EN_ALT_F			0x20
+#define NVVRS_PSEQ_REG_AF_IN_OUT		0x21
+#define NVVRS_PSEQ_REG_EN_CFG1			0x22
+#define NVVRS_PSEQ_REG_EN_CFG2			0x23
+#define NVVRS_PSEQ_REG_CLK_CFG			0x24
+#define NVVRS_PSEQ_REG_GP_OUT			0x25
+#define NVVRS_PSEQ_REG_DEB_IN			0x26
+#define NVVRS_PSEQ_REG_LP_TTSHLD		0x27
+#define NVVRS_PSEQ_REG_CTL_1			0x28
+#define NVVRS_PSEQ_REG_CTL_2			0x29
+#define NVVRS_PSEQ_REG_TEST_CFG			0x2A
+#define NVVRS_PSEQ_REG_IEN_VENDOR		0x2B
+
+/* RTC */
+#define NVVRS_PSEQ_REG_RTC_T3			0x70
+#define NVVRS_PSEQ_REG_RTC_T2			0x71
+#define NVVRS_PSEQ_REG_RTC_T1			0x72
+#define NVVRS_PSEQ_REG_RTC_T0			0x73
+#define NVVRS_PSEQ_REG_RTC_A3			0x74
+#define NVVRS_PSEQ_REG_RTC_A2			0x75
+#define NVVRS_PSEQ_REG_RTC_A1			0x76
+#define NVVRS_PSEQ_REG_RTC_A0			0x77
+
+/* WDT */
+#define NVVRS_PSEQ_REG_WDT_CFG			0x80
+#define NVVRS_PSEQ_REG_WDT_CLOSE		0x81
+#define NVVRS_PSEQ_REG_WDT_OPEN			0x82
+#define NVVRS_PSEQ_REG_WDTKEY			0x83
+
+/* Interrupt Mask */
+#define NVVRS_PSEQ_INT_SRC1_RSTIRQ_MASK		BIT(0)
+#define NVVRS_PSEQ_INT_SRC1_OSC_MASK		BIT(1)
+#define NVVRS_PSEQ_INT_SRC1_EN_MASK		BIT(2)
+#define NVVRS_PSEQ_INT_SRC1_RTC_MASK		BIT(3)
+#define NVVRS_PSEQ_INT_SRC1_PEC_MASK		BIT(4)
+#define NVVRS_PSEQ_INT_SRC1_WDT_MASK		BIT(5)
+#define NVVRS_PSEQ_INT_SRC1_EM_PD_MASK		BIT(6)
+#define NVVRS_PSEQ_INT_SRC1_INTERNAL_MASK	BIT(7)
+#define NVVRS_PSEQ_INT_SRC2_PBSP_MASK		BIT(0)
+#define NVVRS_PSEQ_INT_SRC2_ECC_DED_MASK	BIT(1)
+#define NVVRS_PSEQ_INT_SRC2_TSD_MASK		BIT(2)
+#define NVVRS_PSEQ_INT_SRC2_LDO_MASK		BIT(3)
+#define NVVRS_PSEQ_INT_SRC2_BIST_MASK		BIT(4)
+#define NVVRS_PSEQ_INT_SRC2_RT_CRC_MASK		BIT(5)
+#define NVVRS_PSEQ_INT_SRC2_VENDOR_MASK		BIT(7)
+#define NVVRS_PSEQ_INT_VENDOR0_MASK		BIT(0)
+#define NVVRS_PSEQ_INT_VENDOR1_MASK		BIT(1)
+#define NVVRS_PSEQ_INT_VENDOR2_MASK		BIT(2)
+#define NVVRS_PSEQ_INT_VENDOR3_MASK		BIT(3)
+#define NVVRS_PSEQ_INT_VENDOR4_MASK		BIT(4)
+#define NVVRS_PSEQ_INT_VENDOR5_MASK		BIT(5)
+#define NVVRS_PSEQ_INT_VENDOR6_MASK		BIT(6)
+#define NVVRS_PSEQ_INT_VENDOR7_MASK		BIT(7)
+
+/* Controller Register Mask */
+#define NVVRS_PSEQ_REG_CTL_1_FORCE_SHDN		(BIT(0) | BIT(1))
+#define NVVRS_PSEQ_REG_CTL_1_FORCE_ACT		BIT(2)
+#define NVVRS_PSEQ_REG_CTL_1_FORCE_INT		BIT(3)
+#define NVVRS_PSEQ_REG_CTL_2_EN_PEC		BIT(0)
+#define NVVRS_PSEQ_REG_CTL_2_REQ_PEC		BIT(1)
+#define NVVRS_PSEQ_REG_CTL_2_RTC_PU		BIT(2)
+#define NVVRS_PSEQ_REG_CTL_2_RTC_WAKE		BIT(3)
+#define NVVRS_PSEQ_REG_CTL_2_RST_DLY		0xF0
+
+enum {
+	NVVRS_PSEQ_INT_SRC1_RSTIRQ,		/* Reset or Interrupt Pin Fault */
+	NVVRS_PSEQ_INT_SRC1_OSC,		/* Crystal Oscillator Fault */
+	NVVRS_PSEQ_INT_SRC1_EN,			/* Enable Output Pin Fault */
+	NVVRS_PSEQ_INT_SRC1_RTC,		/* RTC Alarm */
+	NVVRS_PSEQ_INT_SRC1_PEC,		/* Packet Error Checking */
+	NVVRS_PSEQ_INT_SRC1_WDT,		/* Watchdog Violation */
+	NVVRS_PSEQ_INT_SRC1_EM_PD,		/* Emergency Power Down */
+	NVVRS_PSEQ_INT_SRC1_INTERNAL,		/* Internal Fault*/
+	NVVRS_PSEQ_INT_SRC2_PBSP,		/* PWR_BTN Short Pulse Detection */
+	NVVRS_PSEQ_INT_SRC2_ECC_DED,		/* ECC Double-Error Detection */
+	NVVRS_PSEQ_INT_SRC2_TSD,		/* Thermal Shutdown */
+	NVVRS_PSEQ_INT_SRC2_LDO,		/* LDO Fault */
+	NVVRS_PSEQ_INT_SRC2_BIST,		/* Built-In Self Test Fault */
+	NVVRS_PSEQ_INT_SRC2_RT_CRC,		/* Runtime Register CRC Fault */
+	NVVRS_PSEQ_INT_SRC2_VENDOR,		/* Vendor Specific Internal Fault */
+	NVVRS_PSEQ_INT_VENDOR0,			/* Vendor Internal Fault Bit 0 */
+	NVVRS_PSEQ_INT_VENDOR1,			/* Vendor Internal Fault Bit 1 */
+	NVVRS_PSEQ_INT_VENDOR2,			/* Vendor Internal Fault Bit 2 */
+	NVVRS_PSEQ_INT_VENDOR3,			/* Vendor Internal Fault Bit 3 */
+	NVVRS_PSEQ_INT_VENDOR4,			/* Vendor Internal Fault Bit 4 */
+	NVVRS_PSEQ_INT_VENDOR5,			/* Vendor Internal Fault Bit 5 */
+	NVVRS_PSEQ_INT_VENDOR6,			/* Vendor Internal Fault Bit 6 */
+	NVVRS_PSEQ_INT_VENDOR7,			/* Vendor Internal Fault Bit 7 */
+};
+
+struct nvvrs_pseq_chip {
+	struct device *dev;
+	struct regmap *rmap;
+	int chip_irq;
+	struct i2c_client *client;
+	struct regmap_irq_chip_data *irq_data;
+	const struct regmap_irq_chip *irq_chip;
+	void *irq_drv_data;
+};
+
+#endif /* _MFD_NVIDIA_VRS_PSEQ_H_ */
-- 
2.25.1


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ