summaryrefslogtreecommitdiffstats
path: root/drivers/usb/phy/phy.c
diff options
context:
space:
mode:
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)
return *phy == match_data;
}
+static int usb_add_extcon(struct usb_phy *x)
+{
+ int ret;
+
+ if (of_property_read_bool(x->dev->of_node, "extcon")) {
+ x->edev = extcon_get_edev_by_phandle(x->dev, 0);
+ if (IS_ERR(x->edev))
+ return PTR_ERR(x->edev);
+
+ x->id_edev = extcon_get_edev_by_phandle(x->dev, 1);
+ if (IS_ERR(x->id_edev)) {
+ x->id_edev = NULL;
+ dev_info(x->dev, "No separate ID extcon device\n");
+ }
+
+ if (x->vbus_nb.notifier_call) {
+ ret = devm_extcon_register_notifier(x->dev, x->edev,
+ EXTCON_USB,
+ &x->vbus_nb);
+ if (ret < 0) {
+ dev_err(x->dev,
+ "register VBUS notifier failed\n");
+ return ret;
+ }
+ }
+
+ if (x->id_nb.notifier_call) {
+ struct extcon_dev *id_ext;
+
+ if (x->id_edev)
+ id_ext = x->id_edev;
+ else
+ id_ext = x->edev;
+
+ ret = devm_extcon_register_notifier(x->dev, id_ext,
+ EXTCON_USB_HOST,
+ &x->id_nb);
+ if (ret < 0) {
+ dev_err(x->dev,
+ "register ID notifier failed\n");
+ return ret;
+ }
+ }
+ }
+
+ return 0;
+}
+
/**
* devm_usb_get_phy - find the USB PHY
* @dev - device that requests this phy
@@ -388,6 +436,10 @@ int usb_add_phy(struct usb_phy *x, enum usb_phy_type type)
return -EINVAL;
}
+ ret = usb_add_extcon(x);
+ if (ret)
+ return ret;
+
ATOMIC_INIT_NOTIFIER_HEAD(&x->notifier);
spin_lock_irqsave(&phy_lock, flags);
@@ -422,12 +474,17 @@ int usb_add_phy_dev(struct usb_phy *x)
{
struct usb_phy_bind *phy_bind;
unsigned long flags;
+ int ret;
if (!x->dev) {
dev_err(x->dev, "no device provided for PHY\n");
return -EINVAL;
}
+ ret = usb_add_extcon(x);
+ if (ret)
+ return ret;
+
ATOMIC_INIT_NOTIFIER_HEAD(&x->notifier);
spin_lock_irqsave(&phy_lock, flags);