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. ...@@ -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_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_get(struct device *dev, const char *string);
struct phy *devm_phy_optional_get(struct device *dev, struct phy *devm_phy_optional_get(struct device *dev,
const char *string); 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 phy *devm_of_phy_get_by_index(struct device *dev,
struct device_node *np, struct device_node *np,
int index); int index);
phy_get, phy_optional_get, devm_phy_get and devm_phy_optional_get can phy_get, devm_phy_get and devm_phy_optional_get can be used to get the PHY.
be used to get the PHY. In the case of dt boot, the string arguments 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 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 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. phy_optional_get and the devres data and devres data is freed.
devm_phy_optional_get should be used when the phy is optional. These The _optional_get variants should be used when the phy is optional. These
two functions will never return -ENODEV, but instead returns NULL when functions will never return -ENODEV, but instead return NULL when
the phy cannot be found.Some generic drivers, such as ehci, may use multiple the phy cannot be found.
phys and for such drivers referencing phy(s) by name(s) does not make sense. In Some generic drivers, such as ehci, may use multiple phys. In this case,
this case, devm_of_phy_get_by_index can be used to get a phy reference based on devm_of_phy_get or devm_of_phy_get_by_index can be used to get a phy
the index. reference based on name or index.
It should be noted that NULL is a valid phy reference. All phy 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, 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, ...@@ -1152,13 +1152,12 @@ int memac_initialization(struct mac_device *mac_dev,
else else
memac->sgmii_pcs = pcs; memac->sgmii_pcs = pcs;
memac->serdes = devm_of_phy_get(mac_dev->dev, mac_node, "serdes"); memac->serdes = devm_of_phy_optional_get(mac_dev->dev, mac_node,
err = PTR_ERR(memac->serdes); "serdes");
if (err == -ENODEV || err == -ENOSYS) { if (!memac->serdes) {
dev_dbg(mac_dev->dev, "could not get (optional) serdes\n"); dev_dbg(mac_dev->dev, "could not get (optional) serdes\n");
memac->serdes = NULL;
} else if (IS_ERR(memac->serdes)) { } 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; goto _return_fm_mac_free;
} }
......
...@@ -1147,9 +1147,8 @@ static int lan966x_probe(struct platform_device *pdev) ...@@ -1147,9 +1147,8 @@ static int lan966x_probe(struct platform_device *pdev)
lan966x->ports[p]->config.portmode = phy_mode; lan966x->ports[p]->config.portmode = phy_mode;
lan966x->ports[p]->fwnode = fwnode_handle_get(portnp); lan966x->ports[p]->fwnode = fwnode_handle_get(portnp);
serdes = devm_of_phy_get(lan966x->dev, to_of_node(portnp), NULL); serdes = devm_of_phy_optional_get(lan966x->dev,
if (PTR_ERR(serdes) == -ENODEV) to_of_node(portnp), NULL);
serdes = NULL;
if (IS_ERR(serdes)) { if (IS_ERR(serdes)) {
err = PTR_ERR(serdes); err = PTR_ERR(serdes);
goto cleanup_ports; goto cleanup_ports;
......
...@@ -1330,12 +1330,9 @@ static struct phy *devm_of_phy_optional_get_index(struct device *dev, ...@@ -1330,12 +1330,9 @@ static struct phy *devm_of_phy_optional_get_index(struct device *dev,
if (!name) if (!name)
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
phy = devm_of_phy_get(dev, np, name); phy = devm_of_phy_optional_get(dev, np, name);
kfree(name); kfree(name);
if (PTR_ERR(phy) == -ENODEV)
phy = NULL;
return phy; return phy;
} }
......
...@@ -766,27 +766,6 @@ struct phy *phy_get(struct device *dev, const char *string) ...@@ -766,27 +766,6 @@ struct phy *phy_get(struct device *dev, const char *string)
} }
EXPORT_SYMBOL_GPL(phy_get); 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. * devm_phy_get() - lookup and obtain a reference to a phy.
* @dev: device that requests this phy * @dev: device that requests this phy
...@@ -879,6 +858,36 @@ struct phy *devm_of_phy_get(struct device *dev, struct device_node *np, ...@@ -879,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
......
...@@ -80,19 +80,11 @@ static int exynos_ehci_get_phy(struct device *dev, ...@@ -80,19 +80,11 @@ static int exynos_ehci_get_phy(struct device *dev,
return -EINVAL; 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; exynos_ehci->phy[phy_number] = phy;
if (IS_ERR(phy)) { if (IS_ERR(phy)) {
ret = PTR_ERR(phy); of_node_put(child);
if (ret == -EPROBE_DEFER) { return PTR_ERR(phy);
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;
}
} }
} }
...@@ -108,12 +100,10 @@ static int exynos_ehci_phy_enable(struct device *dev) ...@@ -108,12 +100,10 @@ static int exynos_ehci_phy_enable(struct device *dev)
int ret = 0; int ret = 0;
for (i = 0; ret == 0 && i < PHY_NUMBER; i++) 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) if (ret)
for (i--; i >= 0; i--) 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; return ret;
} }
...@@ -125,8 +115,7 @@ static void exynos_ehci_phy_disable(struct device *dev) ...@@ -125,8 +115,7 @@ static void exynos_ehci_phy_disable(struct device *dev)
int i; int i;
for (i = 0; i < PHY_NUMBER; 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) static void exynos_setup_vbus_gpio(struct device *dev)
......
...@@ -69,19 +69,11 @@ static int exynos_ohci_get_phy(struct device *dev, ...@@ -69,19 +69,11 @@ static int exynos_ohci_get_phy(struct device *dev,
return -EINVAL; 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; exynos_ohci->phy[phy_number] = phy;
if (IS_ERR(phy)) { if (IS_ERR(phy)) {
ret = PTR_ERR(phy); of_node_put(child);
if (ret == -EPROBE_DEFER) { return PTR_ERR(phy);
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;
}
} }
} }
...@@ -97,12 +89,10 @@ static int exynos_ohci_phy_enable(struct device *dev) ...@@ -97,12 +89,10 @@ static int exynos_ohci_phy_enable(struct device *dev)
int ret = 0; int ret = 0;
for (i = 0; ret == 0 && i < PHY_NUMBER; i++) 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) if (ret)
for (i--; i >= 0; i--) 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; return ret;
} }
...@@ -114,8 +104,7 @@ static void exynos_ohci_phy_disable(struct device *dev) ...@@ -114,8 +104,7 @@ static void exynos_ohci_phy_disable(struct device *dev)
int i; int i;
for (i = 0; i < PHY_NUMBER; 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) 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) ...@@ -250,11 +250,12 @@ static inline void phy_set_bus_width(struct phy *phy, int bus_width)
phy->attrs.bus_width = bus_width; phy->attrs.bus_width = bus_width;
} }
struct phy *phy_get(struct device *dev, const char *string); 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_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);
...@@ -426,12 +427,6 @@ static inline struct phy *phy_get(struct device *dev, const char *string) ...@@ -426,12 +427,6 @@ static inline struct phy *phy_get(struct device *dev, const char *string)
return ERR_PTR(-ENOSYS); 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) static inline struct phy *devm_phy_get(struct device *dev, const char *string)
{ {
return ERR_PTR(-ENOSYS); return ERR_PTR(-ENOSYS);
...@@ -450,6 +445,13 @@ static inline struct phy *devm_of_phy_get(struct device *dev, ...@@ -450,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)
......
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