mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-11-10 15:14:43 +00:00
phy: Add API for a bulk of phys
This patch adds a "bulk" API to the phy API in order to get/init/exit/power on/off a group of phys associated with a device. The bulk API will avoid adding a copy of the same code to manage a group of phys in drivers. Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com> Signed-off-by: Frank Wunderlich <frank-w@public-files.de> Reviewed-by: Weijie Gao <weijie.gao@mediatek.com> Reviewed-by: Jagan Teki <jagan@amarulasolutions.com>
This commit is contained in:
parent
bf6ad91629
commit
b13307b470
2 changed files with 189 additions and 0 deletions
|
@ -6,6 +6,7 @@
|
|||
|
||||
#include <common.h>
|
||||
#include <dm.h>
|
||||
#include <dm/devres.h>
|
||||
#include <generic-phy.h>
|
||||
|
||||
static inline struct phy_ops *phy_dev_ops(struct udevice *dev)
|
||||
|
@ -167,6 +168,102 @@ int generic_phy_power_off(struct phy *phy)
|
|||
return ops->power_off ? ops->power_off(phy) : 0;
|
||||
}
|
||||
|
||||
int generic_phy_get_bulk(struct udevice *dev, struct phy_bulk *bulk)
|
||||
{
|
||||
int i, ret, count;
|
||||
|
||||
bulk->count = 0;
|
||||
|
||||
/* Return if no phy declared */
|
||||
if (!dev_read_prop(dev, "phys", NULL))
|
||||
return 0;
|
||||
|
||||
count = dev_count_phandle_with_args(dev, "phys", "#phy-cells");
|
||||
if (count < 1)
|
||||
return count;
|
||||
|
||||
bulk->phys = devm_kcalloc(dev, count, sizeof(struct phy), GFP_KERNEL);
|
||||
if (!bulk->phys)
|
||||
return -ENOMEM;
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
ret = generic_phy_get_by_index(dev, i, &bulk->phys[i]);
|
||||
if (ret) {
|
||||
pr_err("Failed to get PHY%d for %s\n", i, dev->name);
|
||||
return ret;
|
||||
}
|
||||
bulk->count++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int generic_phy_init_bulk(struct phy_bulk *bulk)
|
||||
{
|
||||
struct phy *phys = bulk->phys;
|
||||
int i, ret;
|
||||
|
||||
for (i = 0; i < bulk->count; i++) {
|
||||
ret = generic_phy_init(&phys[i]);
|
||||
if (ret) {
|
||||
pr_err("Can't init PHY%d\n", i);
|
||||
goto phys_init_err;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
phys_init_err:
|
||||
for (; i > 0; i--)
|
||||
generic_phy_exit(&phys[i - 1]);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int generic_phy_exit_bulk(struct phy_bulk *bulk)
|
||||
{
|
||||
struct phy *phys = bulk->phys;
|
||||
int i, ret = 0;
|
||||
|
||||
for (i = 0; i < bulk->count; i++)
|
||||
ret |= generic_phy_exit(&phys[i]);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int generic_phy_power_on_bulk(struct phy_bulk *bulk)
|
||||
{
|
||||
struct phy *phys = bulk->phys;
|
||||
int i, ret;
|
||||
|
||||
for (i = 0; i < bulk->count; i++) {
|
||||
ret = generic_phy_power_on(&phys[i]);
|
||||
if (ret) {
|
||||
pr_err("Can't power on PHY%d\n", i);
|
||||
goto phys_poweron_err;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
phys_poweron_err:
|
||||
for (; i > 0; i--)
|
||||
generic_phy_power_off(&phys[i - 1]);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int generic_phy_power_off_bulk(struct phy_bulk *bulk)
|
||||
{
|
||||
struct phy *phys = bulk->phys;
|
||||
int i, ret = 0;
|
||||
|
||||
for (i = 0; i < bulk->count; i++)
|
||||
ret |= generic_phy_power_off(&phys[i]);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
UCLASS_DRIVER(phy) = {
|
||||
.id = UCLASS_PHY,
|
||||
.name = "phy",
|
||||
|
|
|
@ -124,6 +124,23 @@ struct phy_ops {
|
|||
int (*power_off)(struct phy *phy);
|
||||
};
|
||||
|
||||
/**
|
||||
* struct phy_bulk - A handle to (allowing control of) a bulk of phys.
|
||||
*
|
||||
* Consumers provide storage for the phy bulk. The content of the structure is
|
||||
* managed solely by the phy API. A phy bulk struct is initialized
|
||||
* by "get"ing the phy bulk struct.
|
||||
* The phy bulk struct is passed to all other bulk phy APIs to apply
|
||||
* the API to all the phy in the bulk struct.
|
||||
*
|
||||
* @phys: An array of phy handles.
|
||||
* @count: The number of phy handles in the phys array.
|
||||
*/
|
||||
struct phy_bulk {
|
||||
struct phy *phys;
|
||||
unsigned int count;
|
||||
};
|
||||
|
||||
#ifdef CONFIG_PHY
|
||||
|
||||
/**
|
||||
|
@ -250,6 +267,55 @@ int generic_phy_get_by_node(ofnode node, int index, struct phy *phy);
|
|||
int generic_phy_get_by_name(struct udevice *user, const char *phy_name,
|
||||
struct phy *phy);
|
||||
|
||||
/**
|
||||
* generic_phy_get_bulk - Get all phys of a device.
|
||||
*
|
||||
* This looks up and gets all phys of the consumer device; each device is
|
||||
* assumed to have n phys associated with it somehow, and this function finds
|
||||
* and gets all of them in a separate structure.
|
||||
*
|
||||
* @dev: The consumer device.
|
||||
* @bulk A pointer to a phy bulk struct to initialize.
|
||||
* @return 0 if OK, or a negative error code.
|
||||
*/
|
||||
int generic_phy_get_bulk(struct udevice *dev, struct phy_bulk *bulk);
|
||||
|
||||
/**
|
||||
* generic_phy_init_bulk() - Initialize all phys in a phy bulk struct.
|
||||
*
|
||||
* @bulk: A phy bulk struct that was previously successfully requested
|
||||
* by generic_phy_get_bulk().
|
||||
* @return 0 if OK, or negative error code.
|
||||
*/
|
||||
int generic_phy_init_bulk(struct phy_bulk *bulk);
|
||||
|
||||
/**
|
||||
* generic_phy_exit_bulk() - de-initialize all phys in a phy bulk struct.
|
||||
*
|
||||
* @bulk: A phy bulk struct that was previously successfully requested
|
||||
* by generic_phy_get_bulk().
|
||||
* @return 0 if OK, or negative error code.
|
||||
*/
|
||||
int generic_phy_exit_bulk(struct phy_bulk *bulk);
|
||||
|
||||
/**
|
||||
* generic_phy_power_on_bulk() - Power on all phys in a phy bulk struct.
|
||||
*
|
||||
* @bulk: A phy bulk struct that was previously successfully requested
|
||||
* by generic_phy_get_bulk().
|
||||
* @return 0 if OK, or negative error code.
|
||||
*/
|
||||
int generic_phy_power_on_bulk(struct phy_bulk *bulk);
|
||||
|
||||
/**
|
||||
* generic_phy_power_off_bulk() - Power off all phys in a phy bulk struct.
|
||||
*
|
||||
* @bulk: A phy bulk struct that was previously successfully requested
|
||||
* by generic_phy_get_bulk().
|
||||
* @return 0 if OK, or negative error code.
|
||||
*/
|
||||
int generic_phy_power_off_bulk(struct phy_bulk *bulk);
|
||||
|
||||
#else /* CONFIG_PHY */
|
||||
|
||||
static inline int generic_phy_init(struct phy *phy)
|
||||
|
@ -289,6 +355,32 @@ static inline int generic_phy_get_by_name(struct udevice *user, const char *phy_
|
|||
return 0;
|
||||
}
|
||||
|
||||
static inline int
|
||||
generic_phy_get_bulk(struct udevice *dev, struct phy_bulk *bulk)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int generic_phy_init_bulk(struct phy_bulk *bulk)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int generic_phy_exit_bulk(struct phy_bulk *bulk)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int generic_phy_power_on_bulk(struct phy_bulk *bulk)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int generic_phy_power_off_bulk(struct phy_bulk *bulk)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_PHY */
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in a new issue