21
21
#include <linux/phy/phy.h>
22
22
#include <linux/idr.h>
23
23
#include <linux/pm_runtime.h>
24
+ #include <linux/regulator/consumer.h>
24
25
25
26
static struct class * phy_class ;
26
27
static DEFINE_MUTEX (phy_provider_mutex );
@@ -226,6 +227,12 @@ int phy_power_on(struct phy *phy)
226
227
if (!phy )
227
228
return 0 ;
228
229
230
+ if (phy -> pwr ) {
231
+ ret = regulator_enable (phy -> pwr );
232
+ if (ret )
233
+ return ret ;
234
+ }
235
+
229
236
ret = phy_pm_runtime_get_sync (phy );
230
237
if (ret < 0 && ret != - ENOTSUPP )
231
238
return ret ;
@@ -247,6 +254,8 @@ int phy_power_on(struct phy *phy)
247
254
out :
248
255
mutex_unlock (& phy -> mutex );
249
256
phy_pm_runtime_put_sync (phy );
257
+ if (phy -> pwr )
258
+ regulator_disable (phy -> pwr );
250
259
251
260
return ret ;
252
261
}
@@ -272,6 +281,9 @@ int phy_power_off(struct phy *phy)
272
281
mutex_unlock (& phy -> mutex );
273
282
phy_pm_runtime_put (phy );
274
283
284
+ if (phy -> pwr )
285
+ regulator_disable (phy -> pwr );
286
+
275
287
return 0 ;
276
288
}
277
289
EXPORT_SYMBOL_GPL (phy_power_off );
@@ -588,6 +600,16 @@ struct phy *phy_create(struct device *dev, const struct phy_ops *ops,
588
600
goto free_phy ;
589
601
}
590
602
603
+ /* phy-supply */
604
+ phy -> pwr = regulator_get_optional (dev , "phy" );
605
+ if (IS_ERR (phy -> pwr )) {
606
+ if (PTR_ERR (phy -> pwr ) == - EPROBE_DEFER ) {
607
+ ret = - EPROBE_DEFER ;
608
+ goto free_ida ;
609
+ }
610
+ phy -> pwr = NULL ;
611
+ }
612
+
591
613
device_initialize (& phy -> dev );
592
614
mutex_init (& phy -> mutex );
593
615
@@ -617,6 +639,9 @@ struct phy *phy_create(struct device *dev, const struct phy_ops *ops,
617
639
put_device (& phy -> dev ); /* calls phy_release() which frees resources */
618
640
return ERR_PTR (ret );
619
641
642
+ free_ida :
643
+ ida_simple_remove (& phy_ida , phy -> id );
644
+
620
645
free_phy :
621
646
kfree (phy );
622
647
return ERR_PTR (ret );
@@ -800,6 +825,7 @@ static void phy_release(struct device *dev)
800
825
801
826
phy = to_phy (dev );
802
827
dev_vdbg (dev , "releasing '%s'\n" , dev_name (dev ));
828
+ regulator_put (phy -> pwr );
803
829
ida_simple_remove (& phy_ida , phy -> id );
804
830
kfree (phy );
805
831
}
0 commit comments