aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/usb/chipidea/otg.c46
-rw-r--r--include/linux/usb/chipidea.h2
2 files changed, 43 insertions, 5 deletions
diff --git a/drivers/usb/chipidea/otg.c b/drivers/usb/chipidea/otg.c
index a829607c3e4d..0cf149edddd8 100644
--- a/drivers/usb/chipidea/otg.c
+++ b/drivers/usb/chipidea/otg.c
@@ -44,12 +44,15 @@ u32 hw_read_otgsc(struct ci_hdrc *ci, u32 mask)
44 else 44 else
45 val &= ~OTGSC_BSVIS; 45 val &= ~OTGSC_BSVIS;
46 46
47 cable->changed = false;
48
49 if (cable->state) 47 if (cable->state)
50 val |= OTGSC_BSV; 48 val |= OTGSC_BSV;
51 else 49 else
52 val &= ~OTGSC_BSV; 50 val &= ~OTGSC_BSV;
51
52 if (cable->enabled)
53 val |= OTGSC_BSVIE;
54 else
55 val &= ~OTGSC_BSVIE;
53 } 56 }
54 57
55 cable = &ci->platdata->id_extcon; 58 cable = &ci->platdata->id_extcon;
@@ -59,15 +62,18 @@ u32 hw_read_otgsc(struct ci_hdrc *ci, u32 mask)
59 else 62 else
60 val &= ~OTGSC_IDIS; 63 val &= ~OTGSC_IDIS;
61 64
62 cable->changed = false;
63
64 if (cable->state) 65 if (cable->state)
65 val |= OTGSC_ID; 66 val |= OTGSC_ID;
66 else 67 else
67 val &= ~OTGSC_ID; 68 val &= ~OTGSC_ID;
69
70 if (cable->enabled)
71 val |= OTGSC_IDIE;
72 else
73 val &= ~OTGSC_IDIE;
68 } 74 }
69 75
70 return val; 76 return val & mask;
71} 77}
72 78
73/** 79/**
@@ -77,6 +83,36 @@ u32 hw_read_otgsc(struct ci_hdrc *ci, u32 mask)
77 */ 83 */
78void hw_write_otgsc(struct ci_hdrc *ci, u32 mask, u32 data) 84void hw_write_otgsc(struct ci_hdrc *ci, u32 mask, u32 data)
79{ 85{
86 struct ci_hdrc_cable *cable;
87
88 cable = &ci->platdata->vbus_extcon;
89 if (!IS_ERR(cable->edev)) {
90 if (data & mask & OTGSC_BSVIS)
91 cable->changed = false;
92
93 /* Don't enable vbus interrupt if using external notifier */
94 if (data & mask & OTGSC_BSVIE) {
95 cable->enabled = true;
96 data &= ~OTGSC_BSVIE;
97 } else if (mask & OTGSC_BSVIE) {
98 cable->enabled = false;
99 }
100 }
101
102 cable = &ci->platdata->id_extcon;
103 if (!IS_ERR(cable->edev)) {
104 if (data & mask & OTGSC_IDIS)
105 cable->changed = false;
106
107 /* Don't enable id interrupt if using external notifier */
108 if (data & mask & OTGSC_IDIE) {
109 cable->enabled = true;
110 data &= ~OTGSC_IDIE;
111 } else if (mask & OTGSC_IDIE) {
112 cable->enabled = false;
113 }
114 }
115
80 hw_write(ci, OP_OTGSC, mask | OTGSC_INT_STATUS_BITS, data); 116 hw_write(ci, OP_OTGSC, mask | OTGSC_INT_STATUS_BITS, data);
81} 117}
82 118
diff --git a/include/linux/usb/chipidea.h b/include/linux/usb/chipidea.h
index 5dd75fa47dd8..f9be467d6695 100644
--- a/include/linux/usb/chipidea.h
+++ b/include/linux/usb/chipidea.h
@@ -14,6 +14,7 @@ struct ci_hdrc;
14 * struct ci_hdrc_cable - structure for external connector cable state tracking 14 * struct ci_hdrc_cable - structure for external connector cable state tracking
15 * @state: current state of the line 15 * @state: current state of the line
16 * @changed: set to true when extcon event happen 16 * @changed: set to true when extcon event happen
17 * @enabled: set to true if we've enabled the vbus or id interrupt
17 * @edev: device which generate events 18 * @edev: device which generate events
18 * @ci: driver state of the chipidea device 19 * @ci: driver state of the chipidea device
19 * @nb: hold event notification callback 20 * @nb: hold event notification callback
@@ -22,6 +23,7 @@ struct ci_hdrc;
22struct ci_hdrc_cable { 23struct ci_hdrc_cable {
23 bool state; 24 bool state;
24 bool changed; 25 bool changed;
26 bool enabled;
25 struct extcon_dev *edev; 27 struct extcon_dev *edev;
26 struct ci_hdrc *ci; 28 struct ci_hdrc *ci;
27 struct notifier_block nb; 29 struct notifier_block nb;