Merge tag 'reset-for-v6.11-2' of git://git.pengutronix.de/pza/linux into soc/drivers
Reset controller updates for v6.11, part 2 This tag adds USB VBUS regulator control for Renesas RZ/G2L SoCs, which also touches PHY driver and device tree, and pulls in a new regulator_hardware_enable() helper. The Tegra BPMP reset driver can be compiled under COMPILE_TEST now. * tag 'reset-for-v6.11-2' of git://git.pengutronix.de/pza/linux: arm64: dts: renesas: rz-smarc: Replace fixed regulator for USB VBUS phy: renesas: phy-rcar-gen3-usb2: Control VBUS for RZ/G2L SoCs reset: renesas: Add USB VBUS regulator device as child dt-bindings: reset: renesas,rzg2l-usbphy-ctrl: Document USB VBUS regulator reset: tegra-bpmp: allow building under COMPILE_TEST regulator: core: Add helper for allow HW access to enable/disable regulator Link: https://lore.kernel.org/r/20240703100809.2773890-1-p.zabel@pengutronix.de Signed-off-by: Arnd Bergmann <arnd@arndb.de>
This commit is contained in:
@@ -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";
|
||||
};
|
||||
};
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -10,10 +10,12 @@
|
||||
#include <linux/of.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/reset.h>
|
||||
#include <linux/reset-controller.h>
|
||||
|
||||
#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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user