mirror of
https://source.denx.de/u-boot/u-boot.git
synced 2026-06-13 15:03:58 +03:00
Revert "power-domain: Add refcounting"
Unfortunately this change breaks boot on K3 platform.
U-Boot will hang after:
U-Boot SPL 2025.04-01050-ga40fc5afaec0 (Apr 14 2025 - 07:31:32 +0000)
SYSFW ABI: 3.1 (firmware rev 0x0009 '9.2.7--v09.02.07 (Kool Koala)')
This reverts commit 197376fbf3 as
suggested in [1].
[1] https://lists.denx.de/pipermail/u-boot/2025-April/587032.html
Signed-off-by: Wadim Egorov <w.egorov@phytec.de>
Acked-by: Miquel Raynal <miquel.raynal@bootlin.com>
This commit is contained in:
@@ -163,5 +163,4 @@ U_BOOT_DRIVER(sandbox_scmi_devices) = {
|
||||
.priv_auto = sizeof(struct sandbox_scmi_device_priv),
|
||||
.remove = sandbox_scmi_devices_remove,
|
||||
.probe = sandbox_scmi_devices_probe,
|
||||
.flags = DM_FLAG_DEFAULT_PD_CTRL_OFF,
|
||||
};
|
||||
|
||||
@@ -12,10 +12,6 @@
|
||||
#include <power-domain-uclass.h>
|
||||
#include <dm/device-internal.h>
|
||||
|
||||
struct power_domain_priv {
|
||||
int on_count;
|
||||
};
|
||||
|
||||
static inline struct power_domain_ops *power_domain_dev_ops(struct udevice *dev)
|
||||
{
|
||||
return (struct power_domain_ops *)dev->driver->ops;
|
||||
@@ -111,49 +107,22 @@ int power_domain_free(struct power_domain *power_domain)
|
||||
return ops->rfree ? ops->rfree(power_domain) : 0;
|
||||
}
|
||||
|
||||
int power_domain_on_lowlevel(struct power_domain *power_domain)
|
||||
int power_domain_on(struct power_domain *power_domain)
|
||||
{
|
||||
struct power_domain_priv *priv = dev_get_uclass_priv(power_domain->dev);
|
||||
struct power_domain_ops *ops = power_domain_dev_ops(power_domain->dev);
|
||||
int ret;
|
||||
|
||||
debug("%s(power_domain=%p)\n", __func__, power_domain);
|
||||
|
||||
if (priv->on_count++ > 0)
|
||||
return -EALREADY;
|
||||
|
||||
ret = ops->on ? ops->on(power_domain) : 0;
|
||||
if (ret) {
|
||||
priv->on_count--;
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return ops->on ? ops->on(power_domain) : 0;
|
||||
}
|
||||
|
||||
int power_domain_off_lowlevel(struct power_domain *power_domain)
|
||||
int power_domain_off(struct power_domain *power_domain)
|
||||
{
|
||||
struct power_domain_priv *priv = dev_get_uclass_priv(power_domain->dev);
|
||||
struct power_domain_ops *ops = power_domain_dev_ops(power_domain->dev);
|
||||
int ret;
|
||||
|
||||
debug("%s(power_domain=%p)\n", __func__, power_domain);
|
||||
|
||||
if (priv->on_count <= 0) {
|
||||
debug("Power domain %s already off.\n", power_domain->dev->name);
|
||||
return -EALREADY;
|
||||
}
|
||||
|
||||
if (priv->on_count-- > 1)
|
||||
return -EBUSY;
|
||||
|
||||
ret = ops->off ? ops->off(power_domain) : 0;
|
||||
if (ret) {
|
||||
priv->on_count++;
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return ops->off ? ops->off(power_domain) : 0;
|
||||
}
|
||||
|
||||
#if CONFIG_IS_ENABLED(OF_REAL)
|
||||
@@ -211,5 +180,4 @@ int dev_power_domain_off(struct udevice *dev)
|
||||
UCLASS_DRIVER(power_domain) = {
|
||||
.id = UCLASS_POWER_DOMAIN,
|
||||
.name = "power_domain",
|
||||
.per_device_auto = sizeof(struct power_domain_priv),
|
||||
};
|
||||
|
||||
@@ -51,5 +51,4 @@ U_BOOT_DRIVER(sandbox_power_domain_test) = {
|
||||
.id = UCLASS_MISC,
|
||||
.of_match = sandbox_power_domain_test_ids,
|
||||
.priv_auto = sizeof(struct sandbox_power_domain_test),
|
||||
.flags = DM_FLAG_DEFAULT_PD_CTRL_OFF,
|
||||
};
|
||||
|
||||
@@ -147,80 +147,36 @@ static inline int power_domain_free(struct power_domain *power_domain)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* power_domain_on_lowlevel - Enable power to a power domain (with refcounting)
|
||||
* power_domain_on - Enable power to a power domain.
|
||||
*
|
||||
* @power_domain: A power domain struct that was previously successfully
|
||||
* requested by power_domain_get().
|
||||
* Return: 0 if the transition has been performed correctly,
|
||||
* -EALREADY if the domain is already on,
|
||||
* a negative error code otherwise.
|
||||
* Return: 0 if OK, or a negative error code.
|
||||
*/
|
||||
#if CONFIG_IS_ENABLED(POWER_DOMAIN)
|
||||
int power_domain_on_lowlevel(struct power_domain *power_domain);
|
||||
int power_domain_on(struct power_domain *power_domain);
|
||||
#else
|
||||
static inline int power_domain_on_lowlevel(struct power_domain *power_domain)
|
||||
{
|
||||
return -ENOSYS;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* power_domain_on - Enable power to a power domain (ignores the actual state
|
||||
* of the power domain)
|
||||
*
|
||||
* @power_domain: A power domain struct that was previously successfully
|
||||
* requested by power_domain_get().
|
||||
* Return: a negative error code upon error during the transition, 0 otherwise.
|
||||
*/
|
||||
static inline int power_domain_on(struct power_domain *power_domain)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = power_domain_on_lowlevel(power_domain);
|
||||
if (ret == -EALREADY)
|
||||
ret = 0;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* power_domain_off_lowlevel - Disable power to a power domain (with refcounting)
|
||||
*
|
||||
* @power_domain: A power domain struct that was previously successfully
|
||||
* requested by power_domain_get().
|
||||
* Return: 0 if the transition has been performed correctly,
|
||||
* -EALREADY if the domain is already off,
|
||||
* -EBUSY if another device is keeping the domain on (but the refcounter
|
||||
* is decremented),
|
||||
* a negative error code otherwise.
|
||||
*/
|
||||
#if CONFIG_IS_ENABLED(POWER_DOMAIN)
|
||||
int power_domain_off_lowlevel(struct power_domain *power_domain);
|
||||
#else
|
||||
static inline int power_domain_off_lowlevel(struct power_domain *power_domain)
|
||||
{
|
||||
return -ENOSYS;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* power_domain_off - Disable power to a power domain (ignores the actual state
|
||||
* of the power domain)
|
||||
* power_domain_off - Disable power to a power domain.
|
||||
*
|
||||
* @power_domain: A power domain struct that was previously successfully
|
||||
* requested by power_domain_get().
|
||||
* Return: a negative error code upon error during the transition, 0 otherwise.
|
||||
* Return: 0 if OK, or a negative error code.
|
||||
*/
|
||||
#if CONFIG_IS_ENABLED(POWER_DOMAIN)
|
||||
int power_domain_off(struct power_domain *power_domain);
|
||||
#else
|
||||
static inline int power_domain_off(struct power_domain *power_domain)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = power_domain_off_lowlevel(power_domain);
|
||||
if (ret == -EALREADY || ret == -EBUSY)
|
||||
ret = 0;
|
||||
|
||||
return ret;
|
||||
return -ENOSYS;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* dev_power_domain_on - Enable power domains for a device .
|
||||
|
||||
@@ -27,7 +27,7 @@ static int dm_test_power_domain(struct unit_test_state *uts)
|
||||
|
||||
ut_assertok(uclass_get_device_by_name(UCLASS_MISC, "power-domain-test",
|
||||
&dev_test));
|
||||
ut_asserteq(0, sandbox_power_domain_query(dev_power_domain,
|
||||
ut_asserteq(1, sandbox_power_domain_query(dev_power_domain,
|
||||
TEST_POWER_DOMAIN));
|
||||
ut_assertok(sandbox_power_domain_test_get(dev_test));
|
||||
|
||||
|
||||
Reference in New Issue
Block a user