Commit cc94cc1c authored by Vinod Koul's avatar Vinod Koul

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
parents 05bd1834 41a435e3
......@@ -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,
......
......@@ -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;
}
......
......@@ -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;
......
......@@ -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;
}
......
......@@ -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
......
......@@ -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)
......
......@@ -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)
......
......@@ -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)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment