Phy tag for new devm_of_phy_optional_get() API

-----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCAAdFiEE+vs47OPLdNbVcHzyfBQHDyUjg0cFAmPc2iIACgkQfBQHDyUj
 g0fydA//ctw0/IOCWXjBZbJolT/lXJhWkLHKUIT10lMK70E9WJfDPZu1JIdSuxy4
 UShIumzEJwuf46Tfmj5S8gsbtFlsLFBmRJ5SlI4MQrqIRRyBjhR3LmxzWIk0Hc0i
 0wqeQPJMMj5ODFpMzUyiw0W+iwR5rxH6uVf/x76r2vZnpPkqa1MzJCDUdR+nTfVb
 QT802eQNfIfUepgBc6q4bhJ54EFyQzY0xCnBids+guBYHsSZfE6zJYfr2sNo2OQz
 lf1P5rCt86m5krNqZkiTiSG2qqAbd5IVEvV7BaKU7ZpL6I9f3SI28tvEDgAKjXgP
 1xGadkSV4Q2oRqWutPPde39rX5L4CmCcYdyptwEZf5jQl54lkmqnuJd4kZNbapP5
 d260I0cPcVtvLFTvuSoHcb/rV3btFB2pSeYXnbjmGvY1B6GBUpOJA0tXO73e539A
 zRSAC5PXbScIfYDgTNoqTlB9ZfNgEniWmZEEOya0zO9hysfROlFQpTyYV3cxiFCf
 MLh2oy/Z4gBXYRGzN1XMzB7DipKyuqLQUamY2mPDHKaQ3ALZhHB206LTDPrVAydV
 sCOmI1r4n4KSngvRHhP999H8Pf7R7mW+gJ65UVSwpLyZFkbUdN0q855y7hZOfolT
 SYo/c4UKoUwHxWjRb3IRqoOPQXspzFwR1uUe21JQO/U2iOV9VZw=
 =6NOF
 -----END PGP SIGNATURE-----

Merge tag 'phy-devm_of_phy_optional_get' into next

Merge tag phy-devm_of_phy_optional_get into next to bring in the new
devm_of_phy_optional_get() API and users
This commit is contained in:
Vinod Koul 2023-02-03 15:26:14 +05:30
commit cc94cc1c34
8 changed files with 72 additions and 84 deletions

View file

@ -103,27 +103,31 @@ it. This framework provides the following APIs to get a reference to the PHY.
::
struct phy *phy_get(struct device *dev, const char *string);
struct phy *phy_optional_get(struct device *dev, const char *string);
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_of_phy_get(struct device *dev, struct device_node *np,
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,
int index);
phy_get, phy_optional_get, devm_phy_get and devm_phy_optional_get can
be used to get the PHY. In the case of dt boot, the string arguments
phy_get, devm_phy_get and devm_phy_optional_get can be used to get the PHY.
In the case of dt boot, the string arguments
should contain the phy name as given in the dt data and in the case of
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
successful PHY get. On driver detach, release function is invoked on
the devres data and devres data is freed. phy_optional_get and
devm_phy_optional_get should be used when the phy is optional. These
two functions will never return -ENODEV, but instead returns NULL when
the phy cannot be found.Some generic drivers, such as ehci, may use multiple
phys and for such drivers referencing phy(s) by name(s) does not make sense. In
this case, devm_of_phy_get_by_index can be used to get a phy reference based on
the index.
the devres data and devres data is freed.
The _optional_get variants should be used when the phy is optional. These
functions will never return -ENODEV, but instead return NULL when
the phy cannot be found.
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
reference based on name or index.
It should be noted that NULL is a valid phy reference. All phy
consumer calls on the NULL phy become NOPs. That is the release calls,

View file

@ -1152,13 +1152,12 @@ int memac_initialization(struct mac_device *mac_dev,
else
memac->sgmii_pcs = pcs;
memac->serdes = devm_of_phy_get(mac_dev->dev, mac_node, "serdes");
err = PTR_ERR(memac->serdes);
if (err == -ENODEV || err == -ENOSYS) {
memac->serdes = devm_of_phy_optional_get(mac_dev->dev, mac_node,
"serdes");
if (!memac->serdes) {
dev_dbg(mac_dev->dev, "could not get (optional) serdes\n");
memac->serdes = NULL;
} else if (IS_ERR(memac->serdes)) {
dev_err_probe(mac_dev->dev, err, "could not get serdes\n");
err = PTR_ERR(memac->serdes);
goto _return_fm_mac_free;
}

View file

@ -1147,9 +1147,8 @@ static int lan966x_probe(struct platform_device *pdev)
lan966x->ports[p]->config.portmode = phy_mode;
lan966x->ports[p]->fwnode = fwnode_handle_get(portnp);
serdes = devm_of_phy_get(lan966x->dev, to_of_node(portnp), NULL);
if (PTR_ERR(serdes) == -ENODEV)
serdes = NULL;
serdes = devm_of_phy_optional_get(lan966x->dev,
to_of_node(portnp), NULL);
if (IS_ERR(serdes)) {
err = PTR_ERR(serdes);
goto cleanup_ports;

View file

@ -1330,12 +1330,9 @@ static struct phy *devm_of_phy_optional_get_index(struct device *dev,
if (!name)
return ERR_PTR(-ENOMEM);
phy = devm_of_phy_get(dev, np, name);
phy = devm_of_phy_optional_get(dev, np, name);
kfree(name);
if (PTR_ERR(phy) == -ENODEV)
phy = NULL;
return phy;
}

View file

@ -766,27 +766,6 @@ struct phy *phy_get(struct device *dev, const char *string)
}
EXPORT_SYMBOL_GPL(phy_get);
/**
* phy_optional_get() - lookup and obtain a reference to an optional phy.
* @dev: device that requests this phy
* @string: the phy name as given in the dt data or the name of the controller
* port for non-dt case
*
* Returns the phy driver, after getting a refcount to it; or
* NULL if there is no such phy. The caller is responsible for
* calling phy_put() to release that count.
*/
struct phy *phy_optional_get(struct device *dev, const char *string)
{
struct phy *phy = phy_get(dev, string);
if (PTR_ERR(phy) == -ENODEV)
phy = NULL;
return phy;
}
EXPORT_SYMBOL_GPL(phy_optional_get);
/**
* devm_phy_get() - lookup and obtain a reference to a phy.
* @dev: device that requests this phy
@ -879,6 +858,36 @@ struct phy *devm_of_phy_get(struct device *dev, struct device_node *np,
}
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.
* @dev: device that requests this phy

View file

@ -80,19 +80,11 @@ static int exynos_ehci_get_phy(struct device *dev,
return -EINVAL;
}
phy = devm_of_phy_get(dev, child, NULL);
phy = devm_of_phy_optional_get(dev, child, NULL);
exynos_ehci->phy[phy_number] = phy;
if (IS_ERR(phy)) {
ret = PTR_ERR(phy);
if (ret == -EPROBE_DEFER) {
of_node_put(child);
return ret;
} else if (ret != -ENOSYS && ret != -ENODEV) {
dev_err(dev,
"Error retrieving usb2 phy: %d\n", ret);
of_node_put(child);
return ret;
}
of_node_put(child);
return PTR_ERR(phy);
}
}
@ -108,12 +100,10 @@ static int exynos_ehci_phy_enable(struct device *dev)
int ret = 0;
for (i = 0; ret == 0 && i < PHY_NUMBER; i++)
if (!IS_ERR(exynos_ehci->phy[i]))
ret = phy_power_on(exynos_ehci->phy[i]);
ret = phy_power_on(exynos_ehci->phy[i]);
if (ret)
for (i--; i >= 0; i--)
if (!IS_ERR(exynos_ehci->phy[i]))
phy_power_off(exynos_ehci->phy[i]);
phy_power_off(exynos_ehci->phy[i]);
return ret;
}
@ -125,8 +115,7 @@ static void exynos_ehci_phy_disable(struct device *dev)
int i;
for (i = 0; i < PHY_NUMBER; i++)
if (!IS_ERR(exynos_ehci->phy[i]))
phy_power_off(exynos_ehci->phy[i]);
phy_power_off(exynos_ehci->phy[i]);
}
static void exynos_setup_vbus_gpio(struct device *dev)

View file

@ -69,19 +69,11 @@ static int exynos_ohci_get_phy(struct device *dev,
return -EINVAL;
}
phy = devm_of_phy_get(dev, child, NULL);
phy = devm_of_phy_optional_get(dev, child, NULL);
exynos_ohci->phy[phy_number] = phy;
if (IS_ERR(phy)) {
ret = PTR_ERR(phy);
if (ret == -EPROBE_DEFER) {
of_node_put(child);
return ret;
} else if (ret != -ENOSYS && ret != -ENODEV) {
dev_err(dev,
"Error retrieving usb2 phy: %d\n", ret);
of_node_put(child);
return ret;
}
of_node_put(child);
return PTR_ERR(phy);
}
}
@ -97,12 +89,10 @@ static int exynos_ohci_phy_enable(struct device *dev)
int ret = 0;
for (i = 0; ret == 0 && i < PHY_NUMBER; i++)
if (!IS_ERR(exynos_ohci->phy[i]))
ret = phy_power_on(exynos_ohci->phy[i]);
ret = phy_power_on(exynos_ohci->phy[i]);
if (ret)
for (i--; i >= 0; i--)
if (!IS_ERR(exynos_ohci->phy[i]))
phy_power_off(exynos_ohci->phy[i]);
phy_power_off(exynos_ohci->phy[i]);
return ret;
}
@ -114,8 +104,7 @@ static void exynos_ohci_phy_disable(struct device *dev)
int i;
for (i = 0; i < PHY_NUMBER; i++)
if (!IS_ERR(exynos_ohci->phy[i]))
phy_power_off(exynos_ohci->phy[i]);
phy_power_off(exynos_ohci->phy[i]);
}
static int exynos_ohci_probe(struct platform_device *pdev)

View file

@ -250,11 +250,12 @@ static inline void phy_set_bus_width(struct phy *phy, int bus_width)
phy->attrs.bus_width = bus_width;
}
struct phy *phy_get(struct device *dev, const char *string);
struct phy *phy_optional_get(struct device *dev, const char *string);
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_of_phy_get(struct device *dev, struct device_node *np,
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,
int index);
void of_phy_put(struct phy *phy);
@ -426,12 +427,6 @@ static inline struct phy *phy_get(struct device *dev, const char *string)
return ERR_PTR(-ENOSYS);
}
static inline struct phy *phy_optional_get(struct device *dev,
const char *string)
{
return ERR_PTR(-ENOSYS);
}
static inline struct phy *devm_phy_get(struct device *dev, const char *string)
{
return ERR_PTR(-ENOSYS);
@ -450,6 +445,13 @@ static inline struct phy *devm_of_phy_get(struct device *dev,
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,
struct device_node *np,
int index)