@@ -1436,9 +1436,42 @@ static const struct of_device_id msm_otg_dt_match[] = {
14361436};
14371437MODULE_DEVICE_TABLE (of , msm_otg_dt_match );
14381438
1439+ static int msm_otg_vbus_notifier (struct notifier_block * nb , unsigned long event ,
1440+ void * ptr )
1441+ {
1442+ struct msm_usb_cable * vbus = container_of (nb , struct msm_usb_cable , nb );
1443+ struct msm_otg * motg = container_of (vbus , struct msm_otg , vbus );
1444+
1445+ if (event )
1446+ set_bit (B_SESS_VLD , & motg -> inputs );
1447+ else
1448+ clear_bit (B_SESS_VLD , & motg -> inputs );
1449+
1450+ schedule_work (& motg -> sm_work );
1451+
1452+ return NOTIFY_DONE ;
1453+ }
1454+
1455+ static int msm_otg_id_notifier (struct notifier_block * nb , unsigned long event ,
1456+ void * ptr )
1457+ {
1458+ struct msm_usb_cable * id = container_of (nb , struct msm_usb_cable , nb );
1459+ struct msm_otg * motg = container_of (id , struct msm_otg , id );
1460+
1461+ if (event )
1462+ clear_bit (ID , & motg -> inputs );
1463+ else
1464+ set_bit (ID , & motg -> inputs );
1465+
1466+ schedule_work (& motg -> sm_work );
1467+
1468+ return NOTIFY_DONE ;
1469+ }
1470+
14391471static int msm_otg_read_dt (struct platform_device * pdev , struct msm_otg * motg )
14401472{
14411473 struct msm_otg_platform_data * pdata ;
1474+ struct extcon_dev * ext_id , * ext_vbus ;
14421475 const struct of_device_id * id ;
14431476 struct device_node * node = pdev -> dev .of_node ;
14441477 struct property * prop ;
@@ -1487,6 +1520,52 @@ static int msm_otg_read_dt(struct platform_device *pdev, struct msm_otg *motg)
14871520 motg -> vdd_levels [VDD_LEVEL_MAX ] = tmp [VDD_LEVEL_MAX ];
14881521 }
14891522
1523+ ext_id = ERR_PTR (- ENODEV );
1524+ ext_vbus = ERR_PTR (- ENODEV );
1525+ if (of_property_read_bool (node , "extcon" )) {
1526+
1527+ /* Each one of them is not mandatory */
1528+ ext_vbus = extcon_get_edev_by_phandle (& pdev -> dev , 0 );
1529+ if (IS_ERR (ext_vbus ) && PTR_ERR (ext_vbus ) != - ENODEV )
1530+ return PTR_ERR (ext_vbus );
1531+
1532+ ext_id = extcon_get_edev_by_phandle (& pdev -> dev , 1 );
1533+ if (IS_ERR (ext_id ) && PTR_ERR (ext_id ) != - ENODEV )
1534+ return PTR_ERR (ext_id );
1535+ }
1536+
1537+ if (!IS_ERR (ext_vbus )) {
1538+ motg -> vbus .nb .notifier_call = msm_otg_vbus_notifier ;
1539+ ret = extcon_register_interest (& motg -> vbus .conn , ext_vbus -> name ,
1540+ "USB" , & motg -> vbus .nb );
1541+ if (ret < 0 ) {
1542+ dev_err (& pdev -> dev , "register VBUS notifier failed\n" );
1543+ return ret ;
1544+ }
1545+
1546+ ret = extcon_get_cable_state (ext_vbus , "USB" );
1547+ if (ret )
1548+ set_bit (B_SESS_VLD , & motg -> inputs );
1549+ else
1550+ clear_bit (B_SESS_VLD , & motg -> inputs );
1551+ }
1552+
1553+ if (!IS_ERR (ext_id )) {
1554+ motg -> id .nb .notifier_call = msm_otg_id_notifier ;
1555+ ret = extcon_register_interest (& motg -> id .conn , ext_id -> name ,
1556+ "USB-HOST" , & motg -> id .nb );
1557+ if (ret < 0 ) {
1558+ dev_err (& pdev -> dev , "register ID notifier failed\n" );
1559+ return ret ;
1560+ }
1561+
1562+ ret = extcon_get_cable_state (ext_id , "USB-HOST" );
1563+ if (ret )
1564+ clear_bit (ID , & motg -> inputs );
1565+ else
1566+ set_bit (ID , & motg -> inputs );
1567+ }
1568+
14901569 prop = of_find_property (node , "qcom,phy-init-sequence" , & len );
14911570 if (!prop || !len )
14921571 return 0 ;
@@ -1700,6 +1779,11 @@ static int msm_otg_remove(struct platform_device *pdev)
17001779 if (phy -> otg -> host || phy -> otg -> gadget )
17011780 return - EBUSY ;
17021781
1782+ if (motg -> id .conn .edev )
1783+ extcon_unregister_interest (& motg -> id .conn );
1784+ if (motg -> vbus .conn .edev )
1785+ extcon_unregister_interest (& motg -> vbus .conn );
1786+
17031787 msm_otg_debugfs_cleanup ();
17041788 cancel_delayed_work_sync (& motg -> chg_work );
17051789 cancel_work_sync (& motg -> sm_work );
0 commit comments