aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/phy/phy.c
diff options
context:
space:
mode:
authorBaolin Wang <baolin.wang@linaro.org>2017-05-05 02:12:24 -0400
committerFelipe Balbi <felipe.balbi@linux.intel.com>2017-05-17 07:15:28 -0400
commit7d21114dc6a2d53babef43a84a8d8db2905d283d (patch)
treeef0fafad5f3db96621d415b46bf5315fe1ddd8b2 /drivers/usb/phy/phy.c
parent05853ad68e66ab3dc7ed510005203672d7db292f (diff)
usb: phy: Introduce one extcon device into usb phy
Usually usb phy need register one extcon device to get the connection notifications. It will remove some duplicate code if the extcon device is registered using common code instead of each phy driver having its own related extcon APIs. So we add one pointer of extcon device into usb phy structure, and some other helper functions to register extcon. Signed-off-by: Baolin Wang <baolin.wang@linaro.org> Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
Diffstat (limited to 'drivers/usb/phy/phy.c')
-rw-r--r--drivers/usb/phy/phy.c57
1 files changed, 57 insertions, 0 deletions
diff --git a/drivers/usb/phy/phy.c b/drivers/usb/phy/phy.c
index 98f75d2842b7..032f5afaad4b 100644
--- a/drivers/usb/phy/phy.c
+++ b/drivers/usb/phy/phy.c
@@ -100,6 +100,54 @@ static int devm_usb_phy_match(struct device *dev, void *res, void *match_data)
100 return *phy == match_data; 100 return *phy == match_data;
101} 101}
102 102
103static int usb_add_extcon(struct usb_phy *x)
104{
105 int ret;
106
107 if (of_property_read_bool(x->dev->of_node, "extcon")) {
108 x->edev = extcon_get_edev_by_phandle(x->dev, 0);
109 if (IS_ERR(x->edev))
110 return PTR_ERR(x->edev);
111
112 x->id_edev = extcon_get_edev_by_phandle(x->dev, 1);
113 if (IS_ERR(x->id_edev)) {
114 x->id_edev = NULL;
115 dev_info(x->dev, "No separate ID extcon device\n");
116 }
117
118 if (x->vbus_nb.notifier_call) {
119 ret = devm_extcon_register_notifier(x->dev, x->edev,
120 EXTCON_USB,
121 &x->vbus_nb);
122 if (ret < 0) {
123 dev_err(x->dev,
124 "register VBUS notifier failed\n");
125 return ret;
126 }
127 }
128
129 if (x->id_nb.notifier_call) {
130 struct extcon_dev *id_ext;
131
132 if (x->id_edev)
133 id_ext = x->id_edev;
134 else
135 id_ext = x->edev;
136
137 ret = devm_extcon_register_notifier(x->dev, id_ext,
138 EXTCON_USB_HOST,
139 &x->id_nb);
140 if (ret < 0) {
141 dev_err(x->dev,
142 "register ID notifier failed\n");
143 return ret;
144 }
145 }
146 }
147
148 return 0;
149}
150
103/** 151/**
104 * devm_usb_get_phy - find the USB PHY 152 * devm_usb_get_phy - find the USB PHY
105 * @dev - device that requests this phy 153 * @dev - device that requests this phy
@@ -388,6 +436,10 @@ int usb_add_phy(struct usb_phy *x, enum usb_phy_type type)
388 return -EINVAL; 436 return -EINVAL;
389 } 437 }
390 438
439 ret = usb_add_extcon(x);
440 if (ret)
441 return ret;
442
391 ATOMIC_INIT_NOTIFIER_HEAD(&x->notifier); 443 ATOMIC_INIT_NOTIFIER_HEAD(&x->notifier);
392 444
393 spin_lock_irqsave(&phy_lock, flags); 445 spin_lock_irqsave(&phy_lock, flags);
@@ -422,12 +474,17 @@ int usb_add_phy_dev(struct usb_phy *x)
422{ 474{
423 struct usb_phy_bind *phy_bind; 475 struct usb_phy_bind *phy_bind;
424 unsigned long flags; 476 unsigned long flags;
477 int ret;
425 478
426 if (!x->dev) { 479 if (!x->dev) {
427 dev_err(x->dev, "no device provided for PHY\n"); 480 dev_err(x->dev, "no device provided for PHY\n");
428 return -EINVAL; 481 return -EINVAL;
429 } 482 }
430 483
484 ret = usb_add_extcon(x);
485 if (ret)
486 return ret;
487
431 ATOMIC_INIT_NOTIFIER_HEAD(&x->notifier); 488 ATOMIC_INIT_NOTIFIER_HEAD(&x->notifier);
432 489
433 spin_lock_irqsave(&phy_lock, flags); 490 spin_lock_irqsave(&phy_lock, flags);