From 1cb7d29157603561af4c38535e936850ceb99f0f Mon Sep 17 00:00:00 2001 From: Biju Das Date: Sun, 16 Jun 2024 11:53:55 +0100 Subject: [PATCH 1/6] regulator: core: Add helper for allow HW access to enable/disable regulator Add a helper function that allow regulator consumers to allow low-level HW access, in order to enable/disable regulator in atomic context. The use-case for RZ/G2L SoC is to enable VBUS selection register based on vbus detection that happens in interrupt context. Signed-off-by: Biju Das Link: https://patch.msgid.link/20240616105402.45211-4-biju.das.jz@bp.renesas.com Signed-off-by: Mark Brown --- Documentation/power/regulator/consumer.rst | 6 +++++ drivers/regulator/core.c | 28 ++++++++++++++++++++++ include/linux/regulator/consumer.h | 7 ++++++ 3 files changed, 41 insertions(+) diff --git a/Documentation/power/regulator/consumer.rst b/Documentation/power/regulator/consumer.rst index 85c2bf5ac07e..9d2416f63f6e 100644 --- a/Documentation/power/regulator/consumer.rst +++ b/Documentation/power/regulator/consumer.rst @@ -227,3 +227,9 @@ directly written to the voltage selector register, use:: int regulator_list_hardware_vsel(struct regulator *regulator, unsigned selector); + +To access the hardware for enabling/disabling the regulator, consumers must +use regulator_get_exclusive(), as it can't work if there's more than one +consumer. To enable/disable regulator use:: + + int regulator_hardware_enable(struct regulator *regulator, bool enable); diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 844e9587a880..7674b7f2df14 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -3408,6 +3408,34 @@ int regulator_list_hardware_vsel(struct regulator *regulator, } EXPORT_SYMBOL_GPL(regulator_list_hardware_vsel); +/** + * regulator_hardware_enable - access the HW for enable/disable regulator + * @regulator: regulator source + * @enable: true for enable, false for disable + * + * Request that the regulator be enabled/disabled with the regulator output at + * the predefined voltage or current value. + * + * On success 0 is returned, otherwise a negative errno is returned. + */ +int regulator_hardware_enable(struct regulator *regulator, bool enable) +{ + struct regulator_dev *rdev = regulator->rdev; + const struct regulator_ops *ops = rdev->desc->ops; + int ret = -EOPNOTSUPP; + + if (!rdev->exclusive || !ops || !ops->enable || !ops->disable) + return ret; + + if (enable) + ret = ops->enable(rdev); + else + ret = ops->disable(rdev); + + return ret; +} +EXPORT_SYMBOL_GPL(regulator_hardware_enable); + /** * regulator_get_linear_step - return the voltage step size between VSEL values * @regulator: regulator source diff --git a/include/linux/regulator/consumer.h b/include/linux/regulator/consumer.h index 59d0b9a79e6e..550a0e6523ae 100644 --- a/include/linux/regulator/consumer.h +++ b/include/linux/regulator/consumer.h @@ -250,6 +250,7 @@ int regulator_get_hardware_vsel_register(struct regulator *regulator, unsigned *vsel_mask); int regulator_list_hardware_vsel(struct regulator *regulator, unsigned selector); +int regulator_hardware_enable(struct regulator *regulator, bool enable); /* regulator notifier block */ int regulator_register_notifier(struct regulator *regulator, @@ -571,6 +572,12 @@ static inline int regulator_list_hardware_vsel(struct regulator *regulator, return -EOPNOTSUPP; } +static inline int regulator_hardware_enable(struct regulator *regulator, + bool enable) +{ + return -EOPNOTSUPP; +} + static inline int regulator_register_notifier(struct regulator *regulator, struct notifier_block *nb) { From fd88137bfbb83bee678abef840dcafa13262f5ca Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Tue, 25 Jun 2024 14:51:41 +0200 Subject: [PATCH 2/6] reset: tegra-bpmp: allow building under COMPILE_TEST The Tegra BPMP reset driver can be compiled without TEGRA_BPMP being enabled. Allow it to be built under COMPILE_TEST. Acked-by: Thierry Reding Link: https://lore.kernel.org/r/20240625-reset-compile-bpmp-v1-1-647e846303d8@pengutronix.de Signed-off-by: Philipp Zabel --- drivers/reset/Makefile | 2 +- drivers/reset/tegra/Kconfig | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile index 1b814f08fed7..27b0bbdfcc04 100644 --- a/drivers/reset/Makefile +++ b/drivers/reset/Makefile @@ -3,7 +3,7 @@ obj-y += core.o obj-y += hisilicon/ obj-y += starfive/ obj-y += sti/ -obj-$(CONFIG_ARCH_TEGRA) += tegra/ +obj-y += tegra/ obj-$(CONFIG_RESET_A10SR) += reset-a10sr.o obj-$(CONFIG_RESET_ATH79) += reset-ath79.o obj-$(CONFIG_RESET_AXS10X) += reset-axs10x.o diff --git a/drivers/reset/tegra/Kconfig b/drivers/reset/tegra/Kconfig index e4a9a389e98c..4a2d26d1210a 100644 --- a/drivers/reset/tegra/Kconfig +++ b/drivers/reset/tegra/Kconfig @@ -1,3 +1,4 @@ # SPDX-License-Identifier: GPL-2.0-only config RESET_TEGRA_BPMP - def_bool TEGRA_BPMP + bool "Tegra BPMP Reset Driver" if COMPILE_TEST + default TEGRA_BPMP From f64f2d6fdda459b10bc8f774ed87e9980a5021e5 Mon Sep 17 00:00:00 2001 From: Biju Das Date: Tue, 2 Jul 2024 19:00:15 +0100 Subject: [PATCH 3/6] dt-bindings: reset: renesas,rzg2l-usbphy-ctrl: Document USB VBUS regulator The VBUS enable can be controlled by the VBOUT bit of the VBUS control register. This register is part of usbphy-ctrl IP. Document the USB VBUS regulator object. Signed-off-by: Biju Das Reviewed-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20240702180032.207275-2-biju.das.jz@bp.renesas.com Signed-off-by: Philipp Zabel --- .../bindings/reset/renesas,rzg2l-usbphy-ctrl.yaml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/Documentation/devicetree/bindings/reset/renesas,rzg2l-usbphy-ctrl.yaml b/Documentation/devicetree/bindings/reset/renesas,rzg2l-usbphy-ctrl.yaml index 03c18611e42d..b0b20af15313 100644 --- a/Documentation/devicetree/bindings/reset/renesas,rzg2l-usbphy-ctrl.yaml +++ b/Documentation/devicetree/bindings/reset/renesas,rzg2l-usbphy-ctrl.yaml @@ -42,6 +42,12 @@ properties: 0 = Port 1 Phy reset 1 = Port 2 Phy reset + regulator-vbus: + type: object + description: USB VBUS regulator + $ref: /schemas/regulator/regulator.yaml# + unevaluatedProperties: false + required: - compatible - reg @@ -49,6 +55,7 @@ required: - resets - power-domains - '#reset-cells' + - regulator-vbus additionalProperties: false @@ -64,4 +71,7 @@ examples: resets = <&cpg R9A07G044_USB_PRESETN>; power-domains = <&cpg>; #reset-cells = <1>; + regulator-vbus { + regulator-name = "vbus"; + }; }; From 4068f22e4b47f7352fc369c22800e04d2860416b Mon Sep 17 00:00:00 2001 From: Biju Das Date: Tue, 2 Jul 2024 19:00:16 +0100 Subject: [PATCH 4/6] reset: renesas: Add USB VBUS regulator device as child As per RZ/G2L HW manual, VBUS enable can be controlled by the VBOUT bit of the VBUS Control Register(VBENCTL) register in the USBPHY Control. Expose this register as regmap and instantiate the USB VBUS regulator device, so that consumer can control the vbus using regulator API's Signed-off-by: Biju Das Link: https://lore.kernel.org/r/20240702180032.207275-3-biju.das.jz@bp.renesas.com Signed-off-by: Philipp Zabel --- drivers/reset/reset-rzg2l-usbphy-ctrl.c | 31 +++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/drivers/reset/reset-rzg2l-usbphy-ctrl.c b/drivers/reset/reset-rzg2l-usbphy-ctrl.c index bea3270fb698..255c894a4782 100644 --- a/drivers/reset/reset-rzg2l-usbphy-ctrl.c +++ b/drivers/reset/reset-rzg2l-usbphy-ctrl.c @@ -10,10 +10,12 @@ #include #include #include +#include #include #include #define RESET 0x000 +#define VBENCTL 0x03c #define RESET_SEL_PLLRESET BIT(12) #define RESET_PLLRESET BIT(8) @@ -32,6 +34,7 @@ struct rzg2l_usbphy_ctrl_priv { struct reset_controller_dev rcdev; struct reset_control *rstc; void __iomem *base; + struct platform_device *vdev; spinlock_t lock; }; @@ -100,10 +103,19 @@ static const struct reset_control_ops rzg2l_usbphy_ctrl_reset_ops = { .status = rzg2l_usbphy_ctrl_status, }; +static const struct regmap_config rzg2l_usb_regconf = { + .reg_bits = 32, + .val_bits = 32, + .reg_stride = 4, + .max_register = 1, +}; + static int rzg2l_usbphy_ctrl_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct rzg2l_usbphy_ctrl_priv *priv; + struct platform_device *vdev; + struct regmap *regmap; unsigned long flags; int error; u32 val; @@ -116,6 +128,10 @@ static int rzg2l_usbphy_ctrl_probe(struct platform_device *pdev) if (IS_ERR(priv->base)) return PTR_ERR(priv->base); + regmap = devm_regmap_init_mmio(dev, priv->base + VBENCTL, &rzg2l_usb_regconf); + if (IS_ERR(regmap)) + return PTR_ERR(regmap); + priv->rstc = devm_reset_control_get_exclusive(&pdev->dev, NULL); if (IS_ERR(priv->rstc)) return dev_err_probe(dev, PTR_ERR(priv->rstc), @@ -152,8 +168,22 @@ static int rzg2l_usbphy_ctrl_probe(struct platform_device *pdev) if (error) goto err_pm_runtime_put; + vdev = platform_device_alloc("rzg2l-usb-vbus-regulator", pdev->id); + if (!vdev) { + error = -ENOMEM; + goto err_pm_runtime_put; + } + vdev->dev.parent = dev; + priv->vdev = vdev; + + error = platform_device_add(vdev); + if (error) + goto err_device_put; + return 0; +err_device_put: + platform_device_put(vdev); err_pm_runtime_put: pm_runtime_put(&pdev->dev); err_pm_disable_reset_deassert: @@ -166,6 +196,7 @@ static int rzg2l_usbphy_ctrl_remove(struct platform_device *pdev) { struct rzg2l_usbphy_ctrl_priv *priv = dev_get_drvdata(&pdev->dev); + platform_device_unregister(priv->vdev); pm_runtime_put(&pdev->dev); pm_runtime_disable(&pdev->dev); reset_control_assert(priv->rstc); From 24843404efe47eab1ee88d7475a0be0f2f6fd9db Mon Sep 17 00:00:00 2001 From: Biju Das Date: Tue, 2 Jul 2024 19:00:17 +0100 Subject: [PATCH 5/6] phy: renesas: phy-rcar-gen3-usb2: Control VBUS for RZ/G2L SoCs Use regulator_hardware_enable() for controlling VBUS enable for RZ/G2L alike SoCs in interrupt context. Signed-off-by: Biju Das Acked-by: Vinod Koul Link: https://lore.kernel.org/r/20240702180032.207275-4-biju.das.jz@bp.renesas.com Signed-off-by: Philipp Zabel --- drivers/phy/renesas/phy-rcar-gen3-usb2.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/phy/renesas/phy-rcar-gen3-usb2.c b/drivers/phy/renesas/phy-rcar-gen3-usb2.c index fbab6ac0f0d1..7594f64eb737 100644 --- a/drivers/phy/renesas/phy-rcar-gen3-usb2.c +++ b/drivers/phy/renesas/phy-rcar-gen3-usb2.c @@ -188,6 +188,9 @@ static void rcar_gen3_enable_vbus_ctrl(struct rcar_gen3_chan *ch, int vbus) dev_vdbg(ch->dev, "%s: %08x, %d\n", __func__, val, vbus); if (ch->soc_no_adp_ctrl) { + if (ch->vbus) + regulator_hardware_enable(ch->vbus, vbus); + vbus_ctrl_reg = USB2_VBCTRL; vbus_ctrl_val = USB2_VBCTRL_VBOUT; } @@ -718,7 +721,10 @@ static int rcar_gen3_phy_usb2_probe(struct platform_device *pdev) phy_set_drvdata(channel->rphys[i].phy, &channel->rphys[i]); } - channel->vbus = devm_regulator_get_optional(dev, "vbus"); + if (channel->soc_no_adp_ctrl && channel->is_otg_channel) + channel->vbus = devm_regulator_get_exclusive(dev, "vbus"); + else + channel->vbus = devm_regulator_get_optional(dev, "vbus"); if (IS_ERR(channel->vbus)) { if (PTR_ERR(channel->vbus) == -EPROBE_DEFER) { ret = PTR_ERR(channel->vbus); From c1267e1afae60e0b1d17d3a2e55515ecccb22a3e Mon Sep 17 00:00:00 2001 From: Biju Das Date: Tue, 2 Jul 2024 19:00:18 +0100 Subject: [PATCH 6/6] arm64: dts: renesas: rz-smarc: Replace fixed regulator for USB VBUS Replace the fixed regulator for USB VBUS and use the proper one that controls regulator based on VBUS detection. Signed-off-by: Biju Das Reviewed-by: Geert Uytterhoeven Acked-by: Geert Uytterhoeven Link: https://lore.kernel.org/r/20240702180032.207275-5-biju.das.jz@bp.renesas.com Signed-off-by: Philipp Zabel --- arch/arm64/boot/dts/renesas/rz-smarc-common.dtsi | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/arch/arm64/boot/dts/renesas/rz-smarc-common.dtsi b/arch/arm64/boot/dts/renesas/rz-smarc-common.dtsi index b7a3e6caa386..b34855956ae0 100644 --- a/arch/arm64/boot/dts/renesas/rz-smarc-common.dtsi +++ b/arch/arm64/boot/dts/renesas/rz-smarc-common.dtsi @@ -54,14 +54,6 @@ }; }; - usb0_vbus_otg: regulator-usb0-vbus-otg { - compatible = "regulator-fixed"; - - regulator-name = "USB0_VBUS_OTG"; - regulator-min-microvolt = <5000000>; - regulator-max-microvolt = <5000000>; - }; - vccq_sdhi1: regulator-vccq-sdhi1 { compatible = "regulator-gpio"; regulator-name = "SDHI1 VccQ"; @@ -139,6 +131,9 @@ &phyrst { status = "okay"; + usb0_vbus_otg: regulator-vbus { + regulator-name = "vbus"; + }; }; &scif0 {