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: <ed4210f4-7f67-4446-bda3-2ca0061daf12@kernel.org>
Date: Thu, 17 Apr 2025 07:26:47 +0200
From: Krzysztof Kozlowski <krzk@...nel.org>
To: Shubhi Garg <shgarg@...dia.com>, 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
Subject: Re: [PATCH 3/5] mfd: nvvrs: add NVVRS PSEQ MFD driver

On 16/04/2025 14:06, Shubhi Garg wrote:

> +
> +	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);

dev_dbg

> +
> +	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;

Syntax is: return dev_err_probe

> +	}
> +
> +	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");


Drop, useless message.

> +	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),

Drop of_mathc_ptr, you have warnings here.

> +	},
> +	.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_ */


Best regards,
Krzysztof

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ