phy: Add devm_of_phy_optional_get() helper

Add an optional variant of devm_of_phy_get() that also takes care of
printing real errors, so drivers no longer have to open-code this
operation.

Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
Link: https://lore.kernel.org/r/4cd0069bcff424ffc5c3a102397c02370b91985b.1674584626.git.geert+renesas@glider.be
Signed-off-by: Vinod Koul <vkoul@kernel.org>
This commit is contained in:
Geert Uytterhoeven 2023-01-24 19:37:22 +01:00 committed by Vinod Koul
parent 59c3d3d00d
commit d02aa181ee
3 changed files with 44 additions and 2 deletions

View File

@ -108,6 +108,9 @@ it. This framework provides the following APIs to get a reference to the PHY.
const char *string); const char *string);
struct phy *devm_of_phy_get(struct device *dev, struct device_node *np, struct phy *devm_of_phy_get(struct device *dev, struct device_node *np,
const char *con_id); const char *con_id);
struct phy *devm_of_phy_optional_get(struct device *dev,
struct device_node *np,
const char *con_id);
struct phy *devm_of_phy_get_by_index(struct device *dev, struct phy *devm_of_phy_get_by_index(struct device *dev,
struct device_node *np, struct device_node *np,
int index); int index);
@ -119,8 +122,8 @@ non-dt boot, it should contain the label of the PHY. The two
devm_phy_get associates the device with the PHY using devres on devm_phy_get associates the device with the PHY using devres on
successful PHY get. On driver detach, release function is invoked on successful PHY get. On driver detach, release function is invoked on
the devres data and devres data is freed. the devres data and devres data is freed.
devm_phy_optional_get should be used when the phy is optional. This The _optional_get variants should be used when the phy is optional. These
function will never return -ENODEV, but instead returns NULL when functions will never return -ENODEV, but instead return NULL when
the phy cannot be found. the phy cannot be found.
Some generic drivers, such as ehci, may use multiple phys. In this case, Some generic drivers, such as ehci, may use multiple phys. In this case,
devm_of_phy_get or devm_of_phy_get_by_index can be used to get a phy devm_of_phy_get or devm_of_phy_get_by_index can be used to get a phy

View File

@ -858,6 +858,36 @@ struct phy *devm_of_phy_get(struct device *dev, struct device_node *np,
} }
EXPORT_SYMBOL_GPL(devm_of_phy_get); EXPORT_SYMBOL_GPL(devm_of_phy_get);
/**
* devm_of_phy_optional_get() - lookup and obtain a reference to an optional
* phy.
* @dev: device that requests this phy
* @np: node containing the phy
* @con_id: name of the phy from device's point of view
*
* Gets the phy using of_phy_get(), and associates a device with it using
* devres. On driver detach, release function is invoked on the devres data,
* then, devres data is freed. This differs to devm_of_phy_get() in
* that if the phy does not exist, it is not considered an error and
* -ENODEV will not be returned. Instead the NULL phy is returned,
* which can be passed to all other phy consumer calls.
*/
struct phy *devm_of_phy_optional_get(struct device *dev, struct device_node *np,
const char *con_id)
{
struct phy *phy = devm_of_phy_get(dev, np, con_id);
if (PTR_ERR(phy) == -ENODEV)
phy = NULL;
if (IS_ERR(phy))
dev_err_probe(dev, PTR_ERR(phy), "failed to get PHY %pOF:%s",
np, con_id);
return phy;
}
EXPORT_SYMBOL_GPL(devm_of_phy_optional_get);
/** /**
* devm_of_phy_get_by_index() - lookup and obtain a reference to a phy by index. * devm_of_phy_get_by_index() - lookup and obtain a reference to a phy by index.
* @dev: device that requests this phy * @dev: device that requests this phy

View File

@ -254,6 +254,8 @@ struct phy *devm_phy_get(struct device *dev, const char *string);
struct phy *devm_phy_optional_get(struct device *dev, const char *string); struct phy *devm_phy_optional_get(struct device *dev, const char *string);
struct phy *devm_of_phy_get(struct device *dev, struct device_node *np, struct phy *devm_of_phy_get(struct device *dev, struct device_node *np,
const char *con_id); const char *con_id);
struct phy *devm_of_phy_optional_get(struct device *dev, struct device_node *np,
const char *con_id);
struct phy *devm_of_phy_get_by_index(struct device *dev, struct device_node *np, struct phy *devm_of_phy_get_by_index(struct device *dev, struct device_node *np,
int index); int index);
void of_phy_put(struct phy *phy); void of_phy_put(struct phy *phy);
@ -443,6 +445,13 @@ static inline struct phy *devm_of_phy_get(struct device *dev,
return ERR_PTR(-ENOSYS); return ERR_PTR(-ENOSYS);
} }
static inline struct phy *devm_of_phy_optional_get(struct device *dev,
struct device_node *np,
const char *con_id)
{
return NULL;
}
static inline struct phy *devm_of_phy_get_by_index(struct device *dev, static inline struct phy *devm_of_phy_get_by_index(struct device *dev,
struct device_node *np, struct device_node *np,
int index) int index)