drivers: phy: Make NULL a valid phy reference
authorAndrew Lunn <andrew@lunn.ch>
Tue, 4 Feb 2014 17:33:11 +0000 (18:33 +0100)
committerJason Cooper <jason@lakedaemon.net>
Wed, 5 Feb 2014 05:27:54 +0000 (05:27 +0000)
The common clock framework considers NULL a valid clock
reference. This makes handling optional clocks simple, in that if the
optional clock is not available, a NULL reference can be used in the
place of a real clock, simplifying the clock consumer.

Extend this concept to the phy consumer API. A NULL can be passed to
the release calls, the phy_init() and phy_exit() calls, and
phy_power_on() and phy_power_off() and a NOP is performed.

Signed-off-by: Andrew Lunn <andrew@lunn.ch>
Tested-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
Acked-by: Kishon Vijay Abraham I <kishon@ti.com>
Signed-off-by: Jason Cooper <jason@lakedaemon.net>
Documentation/phy.txt
drivers/phy/phy-core.c

index 0103e4b..2e24b99 100644 (file)
@@ -84,6 +84,12 @@ The only difference between the two APIs is that devm_phy_get associates the
 device with the PHY using devres on successful PHY get. On driver detach,
 release function is invoked on the the devres data and devres data is freed.
 
+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,
+the phy_init() and phy_exit() calls, and phy_power_on() and
+phy_power_off() calls are all NOP when applied to a NULL phy. The NULL
+phy is useful in devices for handling optional phy devices.
+
 5. Releasing a reference to the PHY
 
 When the controller no longer needs the PHY, it has to release the reference
index 645c867..a9cdeee 100644 (file)
@@ -162,6 +162,9 @@ int phy_init(struct phy *phy)
 {
        int ret;
 
+       if (!phy)
+               return 0;
+
        ret = phy_pm_runtime_get_sync(phy);
        if (ret < 0 && ret != -ENOTSUPP)
                return ret;
@@ -187,6 +190,9 @@ int phy_exit(struct phy *phy)
 {
        int ret;
 
+       if (!phy)
+               return 0;
+
        ret = phy_pm_runtime_get_sync(phy);
        if (ret < 0 && ret != -ENOTSUPP)
                return ret;
@@ -212,6 +218,9 @@ int phy_power_on(struct phy *phy)
 {
        int ret;
 
+       if (!phy)
+               return 0;
+
        ret = phy_pm_runtime_get_sync(phy);
        if (ret < 0 && ret != -ENOTSUPP)
                return ret;
@@ -240,6 +249,9 @@ int phy_power_off(struct phy *phy)
 {
        int ret;
 
+       if (!phy)
+               return 0;
+
        mutex_lock(&phy->mutex);
        if (phy->power_count == 1 && phy->ops->power_off) {
                ret =  phy->ops->power_off(phy);
@@ -308,7 +320,7 @@ err0:
  */
 void phy_put(struct phy *phy)
 {
-       if (IS_ERR(phy))
+       if (!phy || IS_ERR(phy))
                return;
 
        module_put(phy->ops->owner);
@@ -328,6 +340,9 @@ void devm_phy_put(struct device *dev, struct phy *phy)
 {
        int r;
 
+       if (!phy)
+               return;
+
        r = devres_destroy(dev, devm_phy_release, devm_phy_match, phy);
        dev_WARN_ONCE(dev, r, "couldn't find PHY resource\n");
 }