diff options
author | Andrew Lunn <andrew@lunn.ch> | 2014-02-04 12:33:12 -0500 |
---|---|---|
committer | Jason Cooper <jason@lakedaemon.net> | 2014-02-05 00:48:43 -0500 |
commit | 788a4d56ff378bff0b8e685d03a962b36903a149 (patch) | |
tree | d22d5b9e750448fb0d7695bf4c9360b326668a95 | |
parent | 04c2facad8fee66c981a51852806d8923336f362 (diff) |
drivers: phy: Add support for optional phys
Add devm_phy_optional_get and phy_optional_get, which should be used
when the phy is optional. They does not return an error when the phy
does not exist, rather they returns NULL, which is considered as a valid
phy, but results in NOPs when used with the consumer API.
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>
-rw-r--r-- | Documentation/phy.txt | 20 | ||||
-rw-r--r-- | drivers/phy/phy-core.c | 45 | ||||
-rw-r--r-- | include/linux/phy/phy.h | 14 |
3 files changed, 72 insertions, 7 deletions
diff --git a/Documentation/phy.txt b/Documentation/phy.txt index 2e24b993e95f..ebff6ee52441 100644 --- a/Documentation/phy.txt +++ b/Documentation/phy.txt | |||
@@ -75,14 +75,20 @@ Before the controller can make use of the PHY, it has to get a reference to | |||
75 | it. This framework provides the following APIs to get a reference to the PHY. | 75 | it. This framework provides the following APIs to get a reference to the PHY. |
76 | 76 | ||
77 | struct phy *phy_get(struct device *dev, const char *string); | 77 | struct phy *phy_get(struct device *dev, const char *string); |
78 | struct phy *phy_optional_get(struct device *dev, const char *string); | ||
78 | struct phy *devm_phy_get(struct device *dev, const char *string); | 79 | struct phy *devm_phy_get(struct device *dev, const char *string); |
79 | 80 | struct phy *devm_phy_optional_get(struct device *dev, const char *string); | |
80 | phy_get and devm_phy_get can be used to get the PHY. In the case of dt boot, | 81 | |
81 | the string arguments should contain the phy name as given in the dt data and | 82 | phy_get, phy_optional_get, devm_phy_get and devm_phy_optional_get can |
82 | in the case of non-dt boot, it should contain the label of the PHY. | 83 | be used to get the PHY. In the case of dt boot, the string arguments |
83 | The only difference between the two APIs is that devm_phy_get associates the | 84 | should contain the phy name as given in the dt data and in the case of |
84 | device with the PHY using devres on successful PHY get. On driver detach, | 85 | non-dt boot, it should contain the label of the PHY. The two |
85 | release function is invoked on the the devres data and devres data is freed. | 86 | devm_phy_get associates the device with the PHY using devres on |
87 | successful PHY get. On driver detach, release function is invoked on | ||
88 | the the devres data and devres data is freed. phy_optional_get and | ||
89 | devm_phy_optional_get should be used when the phy is optional. These | ||
90 | two functions will never return -ENODEV, but instead returns NULL when | ||
91 | the phy cannot be found. | ||
86 | 92 | ||
87 | It should be noted that NULL is a valid phy reference. All phy | 93 | It should be noted that NULL is a valid phy reference. All phy |
88 | consumer calls on the NULL phy become NOPs. That is the release calls, | 94 | consumer calls on the NULL phy become NOPs. That is the release calls, |
diff --git a/drivers/phy/phy-core.c b/drivers/phy/phy-core.c index a9cdeee20d91..5f5b0f4be5be 100644 --- a/drivers/phy/phy-core.c +++ b/drivers/phy/phy-core.c | |||
@@ -426,6 +426,27 @@ struct phy *phy_get(struct device *dev, const char *string) | |||
426 | EXPORT_SYMBOL_GPL(phy_get); | 426 | EXPORT_SYMBOL_GPL(phy_get); |
427 | 427 | ||
428 | /** | 428 | /** |
429 | * phy_optional_get() - lookup and obtain a reference to an optional phy. | ||
430 | * @dev: device that requests this phy | ||
431 | * @string: the phy name as given in the dt data or the name of the controller | ||
432 | * port for non-dt case | ||
433 | * | ||
434 | * Returns the phy driver, after getting a refcount to it; or | ||
435 | * NULL if there is no such phy. The caller is responsible for | ||
436 | * calling phy_put() to release that count. | ||
437 | */ | ||
438 | struct phy *phy_optional_get(struct device *dev, const char *string) | ||
439 | { | ||
440 | struct phy *phy = phy_get(dev, string); | ||
441 | |||
442 | if (PTR_ERR(phy) == -ENODEV) | ||
443 | phy = NULL; | ||
444 | |||
445 | return phy; | ||
446 | } | ||
447 | EXPORT_SYMBOL_GPL(phy_optional_get); | ||
448 | |||
449 | /** | ||
429 | * devm_phy_get() - lookup and obtain a reference to a phy. | 450 | * devm_phy_get() - lookup and obtain a reference to a phy. |
430 | * @dev: device that requests this phy | 451 | * @dev: device that requests this phy |
431 | * @string: the phy name as given in the dt data or phy device name | 452 | * @string: the phy name as given in the dt data or phy device name |
@@ -456,6 +477,30 @@ struct phy *devm_phy_get(struct device *dev, const char *string) | |||
456 | EXPORT_SYMBOL_GPL(devm_phy_get); | 477 | EXPORT_SYMBOL_GPL(devm_phy_get); |
457 | 478 | ||
458 | /** | 479 | /** |
480 | * devm_phy_optional_get() - lookup and obtain a reference to an optional phy. | ||
481 | * @dev: device that requests this phy | ||
482 | * @string: the phy name as given in the dt data or phy device name | ||
483 | * for non-dt case | ||
484 | * | ||
485 | * Gets the phy using phy_get(), and associates a device with it using | ||
486 | * devres. On driver detach, release function is invoked on the devres | ||
487 | * data, then, devres data is freed. This differs to devm_phy_get() in | ||
488 | * that if the phy does not exist, it is not considered an error and | ||
489 | * -ENODEV will not be returned. Instead the NULL phy is returned, | ||
490 | * which can be passed to all other phy consumer calls. | ||
491 | */ | ||
492 | struct phy *devm_phy_optional_get(struct device *dev, const char *string) | ||
493 | { | ||
494 | struct phy *phy = devm_phy_get(dev, string); | ||
495 | |||
496 | if (PTR_ERR(phy) == -ENODEV) | ||
497 | phy = NULL; | ||
498 | |||
499 | return phy; | ||
500 | } | ||
501 | EXPORT_SYMBOL_GPL(devm_phy_optional_get); | ||
502 | |||
503 | /** | ||
459 | * phy_create() - create a new phy | 504 | * phy_create() - create a new phy |
460 | * @dev: device that is creating the new phy | 505 | * @dev: device that is creating the new phy |
461 | * @ops: function pointers for performing phy operations | 506 | * @ops: function pointers for performing phy operations |
diff --git a/include/linux/phy/phy.h b/include/linux/phy/phy.h index e273e5ac19c9..3f83459dbb20 100644 --- a/include/linux/phy/phy.h +++ b/include/linux/phy/phy.h | |||
@@ -146,7 +146,9 @@ static inline void phy_set_bus_width(struct phy *phy, int bus_width) | |||
146 | phy->attrs.bus_width = bus_width; | 146 | phy->attrs.bus_width = bus_width; |
147 | } | 147 | } |
148 | struct phy *phy_get(struct device *dev, const char *string); | 148 | struct phy *phy_get(struct device *dev, const char *string); |
149 | struct phy *phy_optional_get(struct device *dev, const char *string); | ||
149 | struct phy *devm_phy_get(struct device *dev, const char *string); | 150 | struct phy *devm_phy_get(struct device *dev, const char *string); |
151 | struct phy *devm_phy_optional_get(struct device *dev, const char *string); | ||
150 | void phy_put(struct phy *phy); | 152 | void phy_put(struct phy *phy); |
151 | void devm_phy_put(struct device *dev, struct phy *phy); | 153 | void devm_phy_put(struct device *dev, struct phy *phy); |
152 | struct phy *of_phy_simple_xlate(struct device *dev, | 154 | struct phy *of_phy_simple_xlate(struct device *dev, |
@@ -232,11 +234,23 @@ static inline struct phy *phy_get(struct device *dev, const char *string) | |||
232 | return ERR_PTR(-ENOSYS); | 234 | return ERR_PTR(-ENOSYS); |
233 | } | 235 | } |
234 | 236 | ||
237 | static inline struct phy *phy_optional_get(struct device *dev, | ||
238 | const char *string) | ||
239 | { | ||
240 | return ERR_PTR(-ENOSYS); | ||
241 | } | ||
242 | |||
235 | static inline struct phy *devm_phy_get(struct device *dev, const char *string) | 243 | static inline struct phy *devm_phy_get(struct device *dev, const char *string) |
236 | { | 244 | { |
237 | return ERR_PTR(-ENOSYS); | 245 | return ERR_PTR(-ENOSYS); |
238 | } | 246 | } |
239 | 247 | ||
248 | static inline struct phy *devm_phy_optional_get(struct device *dev, | ||
249 | const char *string) | ||
250 | { | ||
251 | return ERR_PTR(-ENOSYS); | ||
252 | } | ||
253 | |||
240 | static inline void phy_put(struct phy *phy) | 254 | static inline void phy_put(struct phy *phy) |
241 | { | 255 | { |
242 | } | 256 | } |