Devicetree
 help / color / mirror / Atom feed
* [PATCH v2 0/2] power: sequencing: Add support for Nvidia Tegra modem pwrseq
@ 2026-05-23  8:51 Svyatoslav Ryhel
  2026-05-23  8:51 ` [PATCH v2 1/2] dt-bindings: soc: tegra: Document " Svyatoslav Ryhel
  2026-05-23  8:51 ` [PATCH v2 2/2] power: sequencing: Add support for " Svyatoslav Ryhel
  0 siblings, 2 replies; 5+ messages in thread
From: Svyatoslav Ryhel @ 2026-05-23  8:51 UTC (permalink / raw)
  To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Thierry Reding,
	Jonathan Hunter, Bartosz Golaszewski, Svyatoslav Ryhel
  Cc: devicetree, linux-tegra, linux-kernel, linux-pm

Patchset implements support for the Tegra-specific modem powerseqence,
which handles the registration and unregistration of the USB controller.

This patchset is a part of larger series aiming to bring XMM6260 modem
support for Tegra devices:
https://lore.kernel.org/lkml/20260511135703.62470-1-clamor95@gmail.com/

---
Changes in v2:
- previous phy driver reshaped into pwrseq driver
---

Svyatoslav Ryhel (2):
  dt-bindings: soc: tegra: Document Nvidia Tegra modem pwrseq
  power: sequencing: Add support for Nvidia Tegra modem pwrseq

 .../soc/tegra/nvidia,tegra-modem-pwrseq.yaml  |  49 ++++
 drivers/power/sequencing/Kconfig              |  12 +
 drivers/power/sequencing/Makefile             |   1 +
 drivers/power/sequencing/pwrseq-tegra-modem.c | 209 ++++++++++++++++++
 4 files changed, 271 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/soc/tegra/nvidia,tegra-modem-pwrseq.yaml
 create mode 100644 drivers/power/sequencing/pwrseq-tegra-modem.c

-- 
2.51.0


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH v2 1/2] dt-bindings: soc: tegra: Document Nvidia Tegra modem pwrseq
  2026-05-23  8:51 [PATCH v2 0/2] power: sequencing: Add support for Nvidia Tegra modem pwrseq Svyatoslav Ryhel
@ 2026-05-23  8:51 ` Svyatoslav Ryhel
  2026-05-23  9:00   ` sashiko-bot
  2026-05-23  8:51 ` [PATCH v2 2/2] power: sequencing: Add support for " Svyatoslav Ryhel
  1 sibling, 1 reply; 5+ messages in thread
From: Svyatoslav Ryhel @ 2026-05-23  8:51 UTC (permalink / raw)
  To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Thierry Reding,
	Jonathan Hunter, Bartosz Golaszewski, Svyatoslav Ryhel
  Cc: devicetree, linux-tegra, linux-kernel, linux-pm

Document the Tegra modem pwseq used by various devices based on the Nvidia
Tegra SoC, describing its usage. The power sequence provides interaction
between the modem and SoC-specific interface configurations.

Signed-off-by: Svyatoslav Ryhel <clamor95@gmail.com>
---
 .../soc/tegra/nvidia,tegra-modem-pwrseq.yaml  | 49 +++++++++++++++++++
 1 file changed, 49 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/soc/tegra/nvidia,tegra-modem-pwrseq.yaml

diff --git a/Documentation/devicetree/bindings/soc/tegra/nvidia,tegra-modem-pwrseq.yaml b/Documentation/devicetree/bindings/soc/tegra/nvidia,tegra-modem-pwrseq.yaml
new file mode 100644
index 000000000000..3770fd6dc2cf
--- /dev/null
+++ b/Documentation/devicetree/bindings/soc/tegra/nvidia,tegra-modem-pwrseq.yaml
@@ -0,0 +1,49 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/soc/tegra/nvidia,tegra-modem-pwrseq.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Nvidia Tegra modem power sequence
+
+description:
+  A configuration sequence used in Tegra SoCs to provide proper interaction
+  between the application processor and the modem, as well as control over
+  one of the SoC's USB lines for the modem.
+
+maintainers:
+  - Svyatoslav Ryhel <clamor95@gmail.com>
+
+properties:
+  compatible:
+    const: nvidia,tegra-modem-pwrseq
+
+  enable-gpios:
+    description: GPIO connected to the modem EINT1 pin
+    maxItems: 1
+
+  nvidia,usb-bus:
+    description:
+      Contains phandle pointing to the Host's USB controller
+    $ref: /schemas/types.yaml#/definitions/phandle
+
+  power-supply: true
+
+required:
+  - compatible
+  - nvidia,usb-bus
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/gpio/gpio.h>
+
+    pwrseq-modem {
+        compatible = "nvidia,tegra-modem-pwrseq";
+
+        enable-gpios = <&gpio 165 GPIO_ACTIVE_HIGH>;
+        power-supply = <&vdd_3v3_vbat>;
+
+        nvidia,usb-bus = <&usb2>;
+    };
-- 
2.51.0


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH v2 2/2] power: sequencing: Add support for Nvidia Tegra modem pwrseq
  2026-05-23  8:51 [PATCH v2 0/2] power: sequencing: Add support for Nvidia Tegra modem pwrseq Svyatoslav Ryhel
  2026-05-23  8:51 ` [PATCH v2 1/2] dt-bindings: soc: tegra: Document " Svyatoslav Ryhel
@ 2026-05-23  8:51 ` Svyatoslav Ryhel
  2026-05-23  9:30   ` sashiko-bot
  1 sibling, 1 reply; 5+ messages in thread
From: Svyatoslav Ryhel @ 2026-05-23  8:51 UTC (permalink / raw)
  To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Thierry Reding,
	Jonathan Hunter, Bartosz Golaszewski, Svyatoslav Ryhel
  Cc: devicetree, linux-tegra, linux-kernel, linux-pm

Nvidia Tegra modem power sequence is a set of configurations used in Tegra
SoCs to provide proper interaction between the application processor and
the modem, as well as control over one of the SoC's USB lines for the
modem.

Signed-off-by: Svyatoslav Ryhel <clamor95@gmail.com>
---
 drivers/power/sequencing/Kconfig              |  12 +
 drivers/power/sequencing/Makefile             |   1 +
 drivers/power/sequencing/pwrseq-tegra-modem.c | 209 ++++++++++++++++++
 3 files changed, 222 insertions(+)
 create mode 100644 drivers/power/sequencing/pwrseq-tegra-modem.c

diff --git a/drivers/power/sequencing/Kconfig b/drivers/power/sequencing/Kconfig
index 1c5f5820f5b7..e04a6bacb476 100644
--- a/drivers/power/sequencing/Kconfig
+++ b/drivers/power/sequencing/Kconfig
@@ -46,4 +46,16 @@ config POWER_SEQUENCING_PCIE_M2
 	  connectors. This driver handles the power sequencing for the M.2
 	  connectors exposing multiple interfaces like PCIe, SATA, UART, etc...
 
+config POWER_SEQUENCING_TEGRA_MODEM
+	tristate "NVIDIA Tegra modem power sequencing driver"
+	depends on ARCH_TEGRA && USB_NET_XMM6260 && USB_SUPPORT
+	help
+	  Enable this to support power sequence for XMM6260 modem found in
+	  various Tegra devices with cellular capabilities, like
+	  LG Optimus 4X P880, LG Optimus Vu P895, Google Nexus 7 (2012) 3G
+	  and ASUS Transformer Pad 3G TF300TG.
+
+	  To compile this driver as a module, choose M here: the module will
+	  be called pwrseq-tegra-modem.
+
 endif
diff --git a/drivers/power/sequencing/Makefile b/drivers/power/sequencing/Makefile
index 0911d4618298..c36be7edb8ca 100644
--- a/drivers/power/sequencing/Makefile
+++ b/drivers/power/sequencing/Makefile
@@ -6,3 +6,4 @@ pwrseq-core-y				:= core.o
 obj-$(CONFIG_POWER_SEQUENCING_QCOM_WCN)	+= pwrseq-qcom-wcn.o
 obj-$(CONFIG_POWER_SEQUENCING_TH1520_GPU) += pwrseq-thead-gpu.o
 obj-$(CONFIG_POWER_SEQUENCING_PCIE_M2)	+= pwrseq-pcie-m2.o
+obj-$(CONFIG_POWER_SEQUENCING_TEGRA_MODEM) += pwrseq-tegra-modem.o
diff --git a/drivers/power/sequencing/pwrseq-tegra-modem.c b/drivers/power/sequencing/pwrseq-tegra-modem.c
new file mode 100644
index 000000000000..61df645e642d
--- /dev/null
+++ b/drivers/power/sequencing/pwrseq-tegra-modem.c
@@ -0,0 +1,209 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/export.h>
+#include <linux/gpio/consumer.h>
+#include <linux/mod_devicetable.h>
+#include <linux/module.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/property.h>
+#include <linux/pwrseq/provider.h>
+#include <linux/regulator/consumer.h>
+#include <linux/usb.h>
+#include <linux/usb/chipidea.h>
+#include <linux/usb/tegra_usb_phy.h>
+
+struct pwrseq_tegra_modem_ctx {
+	struct device *dev;
+	struct pwrseq_device *pwrseq;
+
+	struct gpio_desc *enable_gpio;
+	struct regulator *power_supply;
+
+	struct platform_device *usb_dev;
+	struct tegra_usb *usb;
+};
+
+static int pwrseq_tegra_modem_power_enable(struct pwrseq_device *pwrseq)
+{
+	struct pwrseq_tegra_modem_ctx *ctx = pwrseq_device_get_drvdata(pwrseq);
+
+	return regulator_enable(ctx->power_supply);
+}
+
+static int pwrseq_tegra_modem_power_disable(struct pwrseq_device *pwrseq)
+{
+	struct pwrseq_tegra_modem_ctx *ctx = pwrseq_device_get_drvdata(pwrseq);
+
+	return regulator_disable(ctx->power_supply);
+}
+
+static const struct pwrseq_unit_data pwrseq_tegra_modem_power_unit_data = {
+	.name = "power-enable",
+	.enable = pwrseq_tegra_modem_power_enable,
+	.disable = pwrseq_tegra_modem_power_disable,
+};
+
+static const struct pwrseq_unit_data *pwrseq_tegra_modem_unit_deps[] = {
+	&pwrseq_tegra_modem_power_unit_data,
+	NULL,
+};
+
+static int pwrseq_tegra_modem_enable(struct pwrseq_device *pwrseq)
+{
+	struct pwrseq_tegra_modem_ctx *ctx = pwrseq_device_get_drvdata(pwrseq);
+	struct tegra_usb *usb = ctx->usb;
+	int ret;
+
+	/*
+	 * USB controller registers shouldn't be touched before PHY is
+	 * initialized, otherwise CPU will hang because clocks are gated.
+	 * PHY driver controls gating of internal USB clocks on Tegra.
+	 */
+	ret = usb_phy_init(usb->phy);
+	if (ret) {
+		dev_err(ctx->dev, "failed to init USB PHY\n");
+		return ret;
+	}
+
+	usb->dev = ci_hdrc_add_device(&ctx->usb_dev->dev,
+				      ctx->usb_dev->resource,
+				      ctx->usb_dev->num_resources,
+				      &usb->data);
+	if (IS_ERR(usb->dev)) {
+		usb_phy_shutdown(usb->phy);
+		dev_err(ctx->dev, "failed to register USB controller\n");
+		return PTR_ERR(usb->dev);
+	}
+
+	gpiod_set_value_cansleep(ctx->enable_gpio, 1);
+
+	return 0;
+}
+
+static int pwrseq_tegra_modem_disable(struct pwrseq_device *pwrseq)
+{
+	struct pwrseq_tegra_modem_ctx *ctx = pwrseq_device_get_drvdata(pwrseq);
+	struct tegra_usb *usb = ctx->usb;
+
+	gpiod_set_value_cansleep(ctx->enable_gpio, 0);
+	ci_hdrc_remove_device(usb->dev);
+	usb_phy_shutdown(usb->phy);
+
+	/* For USB to settle after turning off */
+	msleep(500);
+
+	return 0;
+}
+
+static const struct pwrseq_unit_data pwrseq_tegra_modem_unit = {
+	.name = "modem-power-sequence",
+	.deps = pwrseq_tegra_modem_unit_deps,
+	.enable = pwrseq_tegra_modem_enable,
+	.disable = pwrseq_tegra_modem_disable,
+};
+
+static const struct pwrseq_target_data pwrseq_tegra_modem_target = {
+	.name = "modem-power",
+	.unit = &pwrseq_tegra_modem_unit,
+};
+
+static const struct pwrseq_target_data *pwrseq_tegra_modem_targets[] = {
+	&pwrseq_tegra_modem_target,
+	NULL
+};
+
+static int pwrseq_tegra_modem_match(struct pwrseq_device *pwrseq,
+				    struct device *dev)
+{
+	/* We only match the specific modem compatible for now */
+	if (!of_device_is_compatible(dev->of_node, "infineon,xmm6260"))
+		return PWRSEQ_NO_MATCH;
+
+	return PWRSEQ_MATCH_OK;
+}
+
+static void pwrseq_tegra_modem_put_device(void *dev)
+{
+	put_device(dev);
+}
+
+static int pwrseq_tegra_modem_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct device_node *usb_node;
+	struct pwrseq_tegra_modem_ctx *ctx;
+	struct pwrseq_config config = { };
+	int ret;
+
+	ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
+	if (!ctx)
+		return -ENOMEM;
+
+	ctx->dev = dev;
+
+	ctx->enable_gpio = devm_gpiod_get_optional(dev, "enable",
+						   GPIOD_OUT_LOW);
+	if (IS_ERR(ctx->enable_gpio))
+		return dev_err_probe(dev, PTR_ERR(ctx->enable_gpio),
+				     "failed to get enable GPIO\n");
+
+	ctx->power_supply = devm_regulator_get(dev, "power");
+	if (IS_ERR(ctx->power_supply))
+		return dev_err_probe(dev, PTR_ERR(ctx->power_supply),
+				     "failed to get power supply\n");
+
+	usb_node = of_parse_phandle(dev->of_node, "nvidia,usb-bus", 0);
+	if (!usb_node)
+		return dev_err_probe(dev, -ENODEV,
+				     "failed to parse modem USB bus\n");
+
+	ctx->usb_dev = of_find_device_by_node(usb_node);
+	of_node_put(usb_node);
+	if (!ctx->usb_dev)
+		return -EPROBE_DEFER;
+
+	ret = devm_add_action_or_reset(dev, pwrseq_tegra_modem_put_device,
+				       &ctx->usb_dev->dev);
+	if (ret)
+		return ret;
+
+	ctx->usb = platform_get_drvdata(ctx->usb_dev);
+	if (!ctx->usb)
+		return -EPROBE_DEFER;
+
+	config.parent = dev;
+	config.owner = THIS_MODULE;
+	config.drvdata = ctx;
+	config.match = pwrseq_tegra_modem_match;
+	config.targets = pwrseq_tegra_modem_targets;
+
+	ctx->pwrseq = devm_pwrseq_device_register(dev, &config);
+	if (IS_ERR(ctx->pwrseq))
+		return dev_err_probe(dev, PTR_ERR(ctx->pwrseq),
+				     "failed to register the power sequencer\n");
+
+	return 0;
+}
+
+static const struct of_device_id pwrseq_tegra_modem_of_match[] = {
+	{ .compatible = "nvidia,tegra-modem-pwrseq" },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, pwrseq_tegra_modem_of_match);
+
+static struct platform_driver pwrseq_tegra_modem_driver = {
+	.driver = {
+		.name = "pwrseq-tegra-modem",
+		.of_match_table = pwrseq_tegra_modem_of_match,
+	},
+	.probe = pwrseq_tegra_modem_probe,
+};
+module_platform_driver(pwrseq_tegra_modem_driver);
+
+MODULE_AUTHOR("Svyatolsav Ryhel <clamor95@gmail.com>");
+MODULE_DESCRIPTION("Tegra modem power sequencer driver");
+MODULE_LICENSE("GPL");
-- 
2.51.0


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH v2 1/2] dt-bindings: soc: tegra: Document Nvidia Tegra modem pwrseq
  2026-05-23  8:51 ` [PATCH v2 1/2] dt-bindings: soc: tegra: Document " Svyatoslav Ryhel
@ 2026-05-23  9:00   ` sashiko-bot
  0 siblings, 0 replies; 5+ messages in thread
From: sashiko-bot @ 2026-05-23  9:00 UTC (permalink / raw)
  To: Svyatoslav Ryhel; +Cc: robh, conor+dt, devicetree

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] Modeling a software power sequence as a virtual standalone device tree node, bypassing physical bus topology.
--

commit 5baacde1b782878f582e887bcf988caf135487f5
Author: Svyatoslav Ryhel <clamor95@gmail.com>

dt-bindings: soc: tegra: Document Nvidia Tegra modem pwrseq

This commit documents the Tegra modem power sequence configuration. It provides
a node to manage interaction between the application processor and the modem,
including control over the USB lines.

> diff --git a/Documentation/devicetree/bindings/soc/tegra/nvidia,tegra-modem-pwrseq.yaml b/Documentation/devicetree/bindings/soc/tegra/nvidia,tegra-modem-pwrseq.yaml
> new file mode 100644
> index 0000000000000..3770fd6dc2cf9
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/soc/tegra/nvidia,tegra-modem-pwrseq.yaml
[ ... ]
> +properties:
> +  compatible:
> +    const: nvidia,tegra-modem-pwrseq
> +
> +  enable-gpios:
> +    description: GPIO connected to the modem EINT1 pin
> +    maxItems: 1
> +
> +  nvidia,usb-bus:
> +    description:
> +      Contains phandle pointing to the Host's USB controller
> +    $ref: /schemas/types.yaml#/definitions/phandle

[Severity: High]
Does this binding model a software power sequence rather than the physical
hardware layout?

The device tree typically describes physical topology. Under standard bus
architecture, would a USB-connected modem be modeled as a child node under
the corresponding USB controller or hub port, including its required
power-supplies and enable-gpios as properties of that physical child node?

By introducing a standalone virtual node that points backwards to the USB
controller via the nvidia,usb-bus phandle, does this bypass the driver core's
standard bus hierarchy and device link management?

Without a structural dependency established through device links, if the USB
controller driver is unbound, could the power sequencer retain a dangling
pointer to the USB bus device and trigger a use-after-free during the next
enable or disable sequence?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260523085102.51000-1-clamor95@gmail.com?part=1

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH v2 2/2] power: sequencing: Add support for Nvidia Tegra modem pwrseq
  2026-05-23  8:51 ` [PATCH v2 2/2] power: sequencing: Add support for " Svyatoslav Ryhel
@ 2026-05-23  9:30   ` sashiko-bot
  0 siblings, 0 replies; 5+ messages in thread
From: sashiko-bot @ 2026-05-23  9:30 UTC (permalink / raw)
  To: Svyatoslav Ryhel; +Cc: conor+dt, devicetree, robh

Thank you for your contribution! Sashiko AI review found 6 potential issue(s) to consider:
- [High] Hijacking and modifying the private state of the `tegra-usb` driver causes resource conflicts, memory leaks, and double-frees.
- [High] Missing device link allows the provider driver to unbind, leaving a dangling pointer.
- [High] Storing an `ERR_PTR` in `usb->dev` guarantees a crash during device removal.
- [High] Blindly casting driver data of an arbitrary platform device to `struct tegra_usb *` without validating the device type.
- [Low] Dereferencing incomplete type `struct tegra_usb` causes a compilation error.
- [Low] The Kconfig symbol depends on a non-existent symbol `USB_NET_XMM6260`.
--

commit 5c2fd594a3aa6ab625a68ba4bb3f25750e538e63
Author: Svyatoslav Ryhel <clamor95@gmail.com>

power: sequencing: Add support for Nvidia Tegra modem pwrseq

Nvidia Tegra modem power sequence is a set of configurations used in Tegra
SoCs to provide proper interaction between the application processor and
the modem, as well as control over one of the SoC's USB lines for the
modem.

> diff --git a/drivers/power/sequencing/Kconfig b/drivers/power/sequencing/Kconfig
> index 1c5f5820f5b76..e04a6bacb476f 100644
> --- a/drivers/power/sequencing/Kconfig
> +++ b/drivers/power/sequencing/Kconfig
> @@ -46,4 +46,16 @@ config POWER_SEQUENCING_PCIE_M2
>  	  connectors. This driver handles the power sequencing for the M.2
>  	  connectors exposing multiple interfaces like PCIe, SATA, UART, etc...
>  
> +config POWER_SEQUENCING_TEGRA_MODEM
> +	tristate "NVIDIA Tegra modem power sequencing driver"
> +	depends on ARCH_TEGRA && USB_NET_XMM6260 && USB_SUPPORT

[Severity: Low]
Does the USB_NET_XMM6260 config symbol exist in the kernel tree? If this
symbol is not present, this driver will be permanently disabled due to an
unsatisfied dependency.

> +	help
> +	  Enable this to support power sequence for XMM6260 modem found in
> +	  various Tegra devices with cellular capabilities, like
> +	  LG Optimus 4X P880, LG Optimus Vu P895, Google Nexus 7 (2012) 3G
> +	  and ASUS Transformer Pad 3G TF300TG.

[ ... ]

> diff --git a/drivers/power/sequencing/pwrseq-tegra-modem.c b/drivers/power/sequencing/pwrseq-tegra-modem.c
> new file mode 100644
> index 0000000000000..0b212ec8b643e
> --- /dev/null
> +++ b/drivers/power/sequencing/pwrseq-tegra-modem.c
> @@ -0,0 +1,209 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +
> +#include <linux/delay.h>
> +#include <linux/device.h>

[ ... ]

> +struct pwrseq_tegra_modem_ctx {
> +	struct device *dev;
> +	struct pwrseq_device *pwrseq;
> +
> +	struct gpio_desc *enable_gpio;
> +	struct regulator *power_supply;
> +
> +	struct platform_device *usb_dev;
> +	struct tegra_usb *usb;
> +};

[ ... ]

> +static int pwrseq_tegra_modem_enable(struct pwrseq_device *pwrseq)
> +{
> +	struct pwrseq_tegra_modem_ctx *ctx = pwrseq_device_get_drvdata(pwrseq);
> +	struct tegra_usb *usb = ctx->usb;
> +	int ret;
> +
> +	/*
> +	 * USB controller registers shouldn't be touched before PHY is
> +	 * initialized, otherwise CPU will hang because clocks are gated.
> +	 * PHY driver controls gating of internal USB clocks on Tegra.
> +	 */
> +	ret = usb_phy_init(usb->phy);

[Severity: Low]
Is struct tegra_usb defined in a public header? It appears to be a private
structure defined only in drivers/usb/chipidea/ci_hdrc_tegra.c. Will accessing
usb->phy here cause a compilation error due to dereferencing an incomplete
type?

> +	if (ret) {
> +		dev_err(ctx->dev, "failed to init USB PHY\n");
> +		return ret;
> +	}
> +
> +	usb->dev = ci_hdrc_add_device(&ctx->usb_dev->dev,
> +				      ctx->usb_dev->resource,
> +				      ctx->usb_dev->num_resources,
> +				      &usb->data);

[Severity: High]
Does modifying the tegra-usb driver's private state directly create resource
conflicts?

If tegra_usb_probe() already initialized the PHY and registered a child
device, calling ci_hdrc_add_device() here and overwriting usb->dev could leak
the originally registered device. Furthermore, if both drivers independently
attempt to call ci_hdrc_remove_device(usb->dev) during teardown, could this
lead to use-after-free and double-free bugs?

> +	if (IS_ERR(usb->dev)) {

[Severity: High]
If ci_hdrc_add_device() fails, usb->dev is left containing an ERR_PTR. If the
tegra-usb driver is subsequently unbound, its remove path:

tegra_usb_remove()
   ci_hdrc_remove_device(usb->dev)

will unconditionally dereference this pointer since it expects a valid device.
Could this lead to a fatal invalid pointer dereference?

> +		usb_phy_shutdown(usb->phy);
> +		dev_err(ctx->dev, "failed to register USB controller\n");
> +		return PTR_ERR(usb->dev);
> +	}
> +
> +	gpiod_set_value_cansleep(ctx->enable_gpio, 1);
> +
> +	return 0;
> +}

[ ... ]

> +static int pwrseq_tegra_modem_probe(struct platform_device *pdev)
> +{
> +	struct device *dev = &pdev->dev;
> +	struct device_node *usb_node;
> +	struct pwrseq_tegra_modem_ctx *ctx;
> +	struct pwrseq_config config = { };
> +	int ret;
> +
> +	ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
> +	if (!ctx)
> +		return -ENOMEM;
> +
> +	ctx->dev = dev;
> +
> +	ctx->enable_gpio = devm_gpiod_get_optional(dev, "enable",
> +						   GPIOD_OUT_LOW);
> +	if (IS_ERR(ctx->enable_gpio))
> +		return dev_err_probe(dev, PTR_ERR(ctx->enable_gpio),
> +				     "failed to get enable GPIO\n");
> +
> +	ctx->power_supply = devm_regulator_get(dev, "power");
> +	if (IS_ERR(ctx->power_supply))
> +		return dev_err_probe(dev, PTR_ERR(ctx->power_supply),
> +				     "failed to get power supply\n");
> +
> +	usb_node = of_parse_phandle(dev->of_node, "nvidia,usb-bus", 0);
> +	if (!usb_node)
> +		return dev_err_probe(dev, -ENODEV,
> +				     "failed to parse modem USB bus\n");
> +
> +	ctx->usb_dev = of_find_device_by_node(usb_node);
> +	of_node_put(usb_node);
> +	if (!ctx->usb_dev)
> +		return -EPROBE_DEFER;
> +
> +	ret = devm_add_action_or_reset(dev, pwrseq_tegra_modem_put_device,
> +				       &ctx->usb_dev->dev);
> +	if (ret)
> +		return ret;
> +
> +	ctx->usb = platform_get_drvdata(ctx->usb_dev);

[Severity: High]
Is it safe to cast the driver data of this platform device to
struct tegra_usb * without first verifying the device type (for example, by
checking its compatible string)?

If the phandle incorrectly points to an unrelated device, ctx->usb will point
to the wrong driver data. Could this cause type confusion and crashes when
fields like usb->phy are accessed later?

[Severity: High]
Should there be a device link established here using device_link_add() to
enforce a consumer-supplier relationship?

Without a device link, the tegra-usb driver can be unbound at any time.
If unbound, the devres-managed struct tegra_usb is freed. Would this leave
ctx->usb as a dangling pointer, leading to a use-after-free during subsequent
power sequence operations?

> +	if (!ctx->usb)
> +		return -EPROBE_DEFER;
> +
> +	config.parent = dev;
> +	config.owner = THIS_MODULE;

[ ... ]

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260523085102.51000-1-clamor95@gmail.com?part=2

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2026-05-23  9:30 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-05-23  8:51 [PATCH v2 0/2] power: sequencing: Add support for Nvidia Tegra modem pwrseq Svyatoslav Ryhel
2026-05-23  8:51 ` [PATCH v2 1/2] dt-bindings: soc: tegra: Document " Svyatoslav Ryhel
2026-05-23  9:00   ` sashiko-bot
2026-05-23  8:51 ` [PATCH v2 2/2] power: sequencing: Add support for " Svyatoslav Ryhel
2026-05-23  9:30   ` sashiko-bot

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox