aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/phy.txt6
-rw-r--r--drivers/phy/phy-core.c17
2 files changed, 22 insertions, 1 deletions
diff --git a/Documentation/phy.txt b/Documentation/phy.txt
index 0103e4b15b0e..2e24b993e95f 100644
--- a/Documentation/phy.txt
+++ b/Documentation/phy.txt
@@ -84,6 +84,12 @@ The only difference between the two APIs is that devm_phy_get associates the
84device with the PHY using devres on successful PHY get. On driver detach, 84device with the PHY using devres on successful PHY get. On driver detach,
85release function is invoked on the the devres data and devres data is freed. 85release function is invoked on the the devres data and devres data is freed.
86 86
87It should be noted that NULL is a valid phy reference. All phy
88consumer calls on the NULL phy become NOPs. That is the release calls,
89the phy_init() and phy_exit() calls, and phy_power_on() and
90phy_power_off() calls are all NOP when applied to a NULL phy. The NULL
91phy is useful in devices for handling optional phy devices.
92
875. Releasing a reference to the PHY 935. Releasing a reference to the PHY
88 94
89When the controller no longer needs the PHY, it has to release the reference 95When the controller no longer needs the PHY, it has to release the reference
diff --git a/drivers/phy/phy-core.c b/drivers/phy/phy-core.c
index 645c867c1257..a9cdeee20d91 100644
--- a/drivers/phy/phy-core.c
+++ b/drivers/phy/phy-core.c
@@ -162,6 +162,9 @@ int phy_init(struct phy *phy)
162{ 162{
163 int ret; 163 int ret;
164 164
165 if (!phy)
166 return 0;
167
165 ret = phy_pm_runtime_get_sync(phy); 168 ret = phy_pm_runtime_get_sync(phy);
166 if (ret < 0 && ret != -ENOTSUPP) 169 if (ret < 0 && ret != -ENOTSUPP)
167 return ret; 170 return ret;
@@ -187,6 +190,9 @@ int phy_exit(struct phy *phy)
187{ 190{
188 int ret; 191 int ret;
189 192
193 if (!phy)
194 return 0;
195
190 ret = phy_pm_runtime_get_sync(phy); 196 ret = phy_pm_runtime_get_sync(phy);
191 if (ret < 0 && ret != -ENOTSUPP) 197 if (ret < 0 && ret != -ENOTSUPP)
192 return ret; 198 return ret;
@@ -212,6 +218,9 @@ int phy_power_on(struct phy *phy)
212{ 218{
213 int ret; 219 int ret;
214 220
221 if (!phy)
222 return 0;
223
215 ret = phy_pm_runtime_get_sync(phy); 224 ret = phy_pm_runtime_get_sync(phy);
216 if (ret < 0 && ret != -ENOTSUPP) 225 if (ret < 0 && ret != -ENOTSUPP)
217 return ret; 226 return ret;
@@ -240,6 +249,9 @@ int phy_power_off(struct phy *phy)
240{ 249{
241 int ret; 250 int ret;
242 251
252 if (!phy)
253 return 0;
254
243 mutex_lock(&phy->mutex); 255 mutex_lock(&phy->mutex);
244 if (phy->power_count == 1 && phy->ops->power_off) { 256 if (phy->power_count == 1 && phy->ops->power_off) {
245 ret = phy->ops->power_off(phy); 257 ret = phy->ops->power_off(phy);
@@ -308,7 +320,7 @@ err0:
308 */ 320 */
309void phy_put(struct phy *phy) 321void phy_put(struct phy *phy)
310{ 322{
311 if (IS_ERR(phy)) 323 if (!phy || IS_ERR(phy))
312 return; 324 return;
313 325
314 module_put(phy->ops->owner); 326 module_put(phy->ops->owner);
@@ -328,6 +340,9 @@ void devm_phy_put(struct device *dev, struct phy *phy)
328{ 340{
329 int r; 341 int r;
330 342
343 if (!phy)
344 return;
345
331 r = devres_destroy(dev, devm_phy_release, devm_phy_match, phy); 346 r = devres_destroy(dev, devm_phy_release, devm_phy_match, phy);
332 dev_WARN_ONCE(dev, r, "couldn't find PHY resource\n"); 347 dev_WARN_ONCE(dev, r, "couldn't find PHY resource\n");
333} 348}