summaryrefslogtreecommitdiff
path: root/drivers/usb/phy
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/phy')
-rw-r--r--drivers/usb/phy/Kconfig6
-rw-r--r--drivers/usb/phy/phy-msm-usb.c85
-rw-r--r--drivers/usb/phy/phy-qcom-8x16-usb.c20
-rw-r--r--drivers/usb/phy/phy.c57
4 files changed, 83 insertions, 85 deletions
diff --git a/drivers/usb/phy/Kconfig b/drivers/usb/phy/Kconfig
index 3006f569c068..aff702c0eb9f 100644
--- a/drivers/usb/phy/Kconfig
+++ b/drivers/usb/phy/Kconfig
@@ -4,6 +4,7 @@
menu "USB Physical Layer drivers"
config USB_PHY
+ select EXTCON
def_bool n
#
@@ -109,7 +110,7 @@ config OMAP_OTG
config TAHVO_USB
tristate "Tahvo USB transceiver driver"
- depends on MFD_RETU && EXTCON
+ depends on MFD_RETU
depends on USB_GADGET || !USB_GADGET # if USB_GADGET=m, this can't be 'y'
select USB_PHY
help
@@ -141,7 +142,6 @@ config USB_MSM_OTG
depends on (USB || USB_GADGET) && (ARCH_QCOM || COMPILE_TEST)
depends on USB_GADGET || !USB_GADGET # if USB_GADGET=m, this can't be 'y'
depends on RESET_CONTROLLER
- depends on EXTCON
select USB_PHY
help
Enable this to support the USB OTG transceiver on Qualcomm chips. It
@@ -155,7 +155,7 @@ config USB_MSM_OTG
config USB_QCOM_8X16_PHY
tristate "Qualcomm APQ8016/MSM8916 on-chip USB PHY controller support"
depends on ARCH_QCOM || COMPILE_TEST
- depends on RESET_CONTROLLER && EXTCON
+ depends on RESET_CONTROLLER
select USB_PHY
select USB_ULPI_VIEWPORT
help
diff --git a/drivers/usb/phy/phy-msm-usb.c b/drivers/usb/phy/phy-msm-usb.c
index 93d9aaad2994..8fb86a5f458e 100644
--- a/drivers/usb/phy/phy-msm-usb.c
+++ b/drivers/usb/phy/phy-msm-usb.c
@@ -146,17 +146,6 @@ struct msm_otg_platform_data {
};
/**
- * struct msm_usb_cable - structure for exteternal connector cable
- * state tracking
- * @nb: hold event notification callback
- * @conn: used for notification registration
- */
-struct msm_usb_cable {
- struct notifier_block nb;
- struct extcon_dev *extcon;
-};
-
-/**
* struct msm_otg: OTG driver data. Shared by HCD and DCD.
* @otg: USB OTG Transceiver structure.
* @pdata: otg device platform data.
@@ -215,9 +204,6 @@ struct msm_otg {
bool manual_pullup;
- struct msm_usb_cable vbus;
- struct msm_usb_cable id;
-
struct gpio_desc *switch_gpio;
struct notifier_block reboot;
};
@@ -1612,8 +1598,8 @@ MODULE_DEVICE_TABLE(of, msm_otg_dt_match);
static int msm_otg_vbus_notifier(struct notifier_block *nb, unsigned long event,
void *ptr)
{
- struct msm_usb_cable *vbus = container_of(nb, struct msm_usb_cable, nb);
- struct msm_otg *motg = container_of(vbus, struct msm_otg, vbus);
+ struct usb_phy *usb_phy = container_of(nb, struct usb_phy, vbus_nb);
+ struct msm_otg *motg = container_of(usb_phy, struct msm_otg, phy);
if (event)
set_bit(B_SESS_VLD, &motg->inputs);
@@ -1636,8 +1622,8 @@ static int msm_otg_vbus_notifier(struct notifier_block *nb, unsigned long event,
static int msm_otg_id_notifier(struct notifier_block *nb, unsigned long event,
void *ptr)
{
- struct msm_usb_cable *id = container_of(nb, struct msm_usb_cable, nb);
- struct msm_otg *motg = container_of(id, struct msm_otg, id);
+ struct usb_phy *usb_phy = container_of(nb, struct usb_phy, id_nb);
+ struct msm_otg *motg = container_of(usb_phy, struct msm_otg, phy);
if (event)
clear_bit(ID, &motg->inputs);
@@ -1652,7 +1638,6 @@ static int msm_otg_id_notifier(struct notifier_block *nb, unsigned long event,
static int msm_otg_read_dt(struct platform_device *pdev, struct msm_otg *motg)
{
struct msm_otg_platform_data *pdata;
- struct extcon_dev *ext_id, *ext_vbus;
struct device_node *node = pdev->dev.of_node;
struct property *prop;
int len, ret, words;
@@ -1708,54 +1693,6 @@ static int msm_otg_read_dt(struct platform_device *pdev, struct msm_otg *motg)
if (IS_ERR(motg->switch_gpio))
return PTR_ERR(motg->switch_gpio);
- ext_id = ERR_PTR(-ENODEV);
- ext_vbus = ERR_PTR(-ENODEV);
- if (of_property_read_bool(node, "extcon")) {
-
- /* Each one of them is not mandatory */
- ext_vbus = extcon_get_edev_by_phandle(&pdev->dev, 0);
- if (IS_ERR(ext_vbus) && PTR_ERR(ext_vbus) != -ENODEV)
- return PTR_ERR(ext_vbus);
-
- ext_id = extcon_get_edev_by_phandle(&pdev->dev, 1);
- if (IS_ERR(ext_id) && PTR_ERR(ext_id) != -ENODEV)
- return PTR_ERR(ext_id);
- }
-
- if (!IS_ERR(ext_vbus)) {
- motg->vbus.extcon = ext_vbus;
- motg->vbus.nb.notifier_call = msm_otg_vbus_notifier;
- ret = devm_extcon_register_notifier(&pdev->dev, ext_vbus,
- EXTCON_USB, &motg->vbus.nb);
- if (ret < 0) {
- dev_err(&pdev->dev, "register VBUS notifier failed\n");
- return ret;
- }
-
- ret = extcon_get_state(ext_vbus, EXTCON_USB);
- if (ret)
- set_bit(B_SESS_VLD, &motg->inputs);
- else
- clear_bit(B_SESS_VLD, &motg->inputs);
- }
-
- if (!IS_ERR(ext_id)) {
- motg->id.extcon = ext_id;
- motg->id.nb.notifier_call = msm_otg_id_notifier;
- ret = devm_extcon_register_notifier(&pdev->dev, ext_id,
- EXTCON_USB_HOST, &motg->id.nb);
- if (ret < 0) {
- dev_err(&pdev->dev, "register ID notifier failed\n");
- return ret;
- }
-
- ret = extcon_get_state(ext_id, EXTCON_USB_HOST);
- if (ret)
- clear_bit(ID, &motg->inputs);
- else
- set_bit(ID, &motg->inputs);
- }
-
prop = of_find_property(node, "qcom,phy-init-sequence", &len);
if (!prop || !len)
return 0;
@@ -1932,6 +1869,8 @@ static int msm_otg_probe(struct platform_device *pdev)
phy->init = msm_phy_init;
phy->notify_disconnect = msm_phy_notify_disconnect;
phy->type = USB_PHY_TYPE_USB2;
+ phy->vbus_nb.notifier_call = msm_otg_vbus_notifier;
+ phy->id_nb.notifier_call = msm_otg_id_notifier;
phy->io_ops = &msm_otg_io_ops;
@@ -1947,6 +1886,18 @@ static int msm_otg_probe(struct platform_device *pdev)
goto disable_ldo;
}
+ ret = extcon_get_state(phy->edev, EXTCON_USB);
+ if (ret)
+ set_bit(B_SESS_VLD, &motg->inputs);
+ else
+ clear_bit(B_SESS_VLD, &motg->inputs);
+
+ ret = extcon_get_state(phy->id_edev, EXTCON_USB_HOST);
+ if (ret)
+ clear_bit(ID, &motg->inputs);
+ else
+ set_bit(ID, &motg->inputs);
+
platform_set_drvdata(pdev, motg);
device_init_wakeup(&pdev->dev, 1);
diff --git a/drivers/usb/phy/phy-qcom-8x16-usb.c b/drivers/usb/phy/phy-qcom-8x16-usb.c
index fdf686398772..b6a83a5cbad3 100644
--- a/drivers/usb/phy/phy-qcom-8x16-usb.c
+++ b/drivers/usb/phy/phy-qcom-8x16-usb.c
@@ -69,9 +69,6 @@ struct phy_8x16 {
struct reset_control *phy_reset;
- struct extcon_dev *vbus_edev;
- struct notifier_block vbus_notify;
-
struct gpio_desc *switch_gpio;
struct notifier_block reboot_notify;
};
@@ -131,7 +128,8 @@ static int phy_8x16_vbus_off(struct phy_8x16 *qphy)
static int phy_8x16_vbus_notify(struct notifier_block *nb, unsigned long event,
void *ptr)
{
- struct phy_8x16 *qphy = container_of(nb, struct phy_8x16, vbus_notify);
+ struct usb_phy *usb_phy = container_of(nb, struct usb_phy, vbus_nb);
+ struct phy_8x16 *qphy = container_of(usb_phy, struct phy_8x16, phy);
if (event)
phy_8x16_vbus_on(qphy);
@@ -187,7 +185,7 @@ static int phy_8x16_init(struct usb_phy *phy)
val = ULPI_PWR_OTG_COMP_DISABLE;
usb_phy_io_write(phy, val, ULPI_SET(ULPI_PWR_CLK_MNG_REG));
- state = extcon_get_state(qphy->vbus_edev, EXTCON_USB);
+ state = extcon_get_state(qphy->phy.edev, EXTCON_USB);
if (state)
phy_8x16_vbus_on(qphy);
else
@@ -289,15 +287,13 @@ static int phy_8x16_probe(struct platform_device *pdev)
phy->io_priv = qphy->regs + HSPHY_ULPI_VIEWPORT;
phy->io_ops = &ulpi_viewport_access_ops;
phy->type = USB_PHY_TYPE_USB2;
+ phy->vbus_nb.notifier_call = phy_8x16_vbus_notify;
+ phy->id_nb.notifier_call = NULL;
ret = phy_8x16_read_devicetree(qphy);
if (ret < 0)
return ret;
- qphy->vbus_edev = extcon_get_edev_by_phandle(phy->dev, 0);
- if (IS_ERR(qphy->vbus_edev))
- return PTR_ERR(qphy->vbus_edev);
-
ret = clk_set_rate(qphy->core_clk, INT_MAX);
if (ret < 0)
dev_dbg(phy->dev, "Can't boost core clock\n");
@@ -315,12 +311,6 @@ static int phy_8x16_probe(struct platform_device *pdev)
if (WARN_ON(ret))
goto off_clks;
- qphy->vbus_notify.notifier_call = phy_8x16_vbus_notify;
- ret = devm_extcon_register_notifier(&pdev->dev, qphy->vbus_edev,
- EXTCON_USB, &qphy->vbus_notify);
- if (ret < 0)
- goto off_power;
-
ret = usb_add_phy_dev(&qphy->phy);
if (ret)
goto off_power;
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);