| .. | .. |
|---|
| 23 | 23 | |
|---|
| 24 | 24 | /** |
|---|
| 25 | 25 | * hw_read_otgsc returns otgsc register bits value. |
|---|
| 26 | + * @ci: the controller |
|---|
| 26 | 27 | * @mask: bitfield mask |
|---|
| 27 | 28 | */ |
|---|
| 28 | 29 | u32 hw_read_otgsc(struct ci_hdrc *ci, u32 mask) |
|---|
| .. | .. |
|---|
| 35 | 36 | * detection overwrite OTGSC register value |
|---|
| 36 | 37 | */ |
|---|
| 37 | 38 | cable = &ci->platdata->vbus_extcon; |
|---|
| 38 | | - if (!IS_ERR(cable->edev)) { |
|---|
| 39 | + if (!IS_ERR(cable->edev) || ci->role_switch) { |
|---|
| 39 | 40 | if (cable->changed) |
|---|
| 40 | 41 | val |= OTGSC_BSVIS; |
|---|
| 41 | 42 | else |
|---|
| .. | .. |
|---|
| 53 | 54 | } |
|---|
| 54 | 55 | |
|---|
| 55 | 56 | cable = &ci->platdata->id_extcon; |
|---|
| 56 | | - if (!IS_ERR(cable->edev)) { |
|---|
| 57 | + if (!IS_ERR(cable->edev) || ci->role_switch) { |
|---|
| 57 | 58 | if (cable->changed) |
|---|
| 58 | 59 | val |= OTGSC_IDIS; |
|---|
| 59 | 60 | else |
|---|
| .. | .. |
|---|
| 75 | 76 | |
|---|
| 76 | 77 | /** |
|---|
| 77 | 78 | * hw_write_otgsc updates target bits of OTGSC register. |
|---|
| 79 | + * @ci: the controller |
|---|
| 78 | 80 | * @mask: bitfield mask |
|---|
| 79 | 81 | * @data: to be written |
|---|
| 80 | 82 | */ |
|---|
| .. | .. |
|---|
| 83 | 85 | struct ci_hdrc_cable *cable; |
|---|
| 84 | 86 | |
|---|
| 85 | 87 | cable = &ci->platdata->vbus_extcon; |
|---|
| 86 | | - if (!IS_ERR(cable->edev)) { |
|---|
| 88 | + if (!IS_ERR(cable->edev) || ci->role_switch) { |
|---|
| 87 | 89 | if (data & mask & OTGSC_BSVIS) |
|---|
| 88 | 90 | cable->changed = false; |
|---|
| 89 | 91 | |
|---|
| .. | .. |
|---|
| 97 | 99 | } |
|---|
| 98 | 100 | |
|---|
| 99 | 101 | cable = &ci->platdata->id_extcon; |
|---|
| 100 | | - if (!IS_ERR(cable->edev)) { |
|---|
| 102 | + if (!IS_ERR(cable->edev) || ci->role_switch) { |
|---|
| 101 | 103 | if (data & mask & OTGSC_IDIS) |
|---|
| 102 | 104 | cable->changed = false; |
|---|
| 103 | 105 | |
|---|
| .. | .. |
|---|
| 170 | 172 | dev_dbg(ci->dev, "switching from %s to %s\n", |
|---|
| 171 | 173 | ci_role(ci)->name, ci->roles[role]->name); |
|---|
| 172 | 174 | |
|---|
| 175 | + if (ci->vbus_active && ci->role == CI_ROLE_GADGET) |
|---|
| 176 | + /* |
|---|
| 177 | + * vbus disconnect event is lost due to role |
|---|
| 178 | + * switch occurs during system suspend. |
|---|
| 179 | + */ |
|---|
| 180 | + usb_gadget_vbus_disconnect(&ci->gadget); |
|---|
| 181 | + |
|---|
| 173 | 182 | ci_role_stop(ci); |
|---|
| 174 | 183 | |
|---|
| 175 | 184 | if (role == CI_ROLE_GADGET && |
|---|
| .. | .. |
|---|
| 222 | 231 | |
|---|
| 223 | 232 | /** |
|---|
| 224 | 233 | * ci_hdrc_otg_init - initialize otg struct |
|---|
| 225 | | - * ci: the controller |
|---|
| 234 | + * @ci: the controller |
|---|
| 226 | 235 | */ |
|---|
| 227 | 236 | int ci_hdrc_otg_init(struct ci_hdrc *ci) |
|---|
| 228 | 237 | { |
|---|
| .. | .. |
|---|
| 241 | 250 | |
|---|
| 242 | 251 | /** |
|---|
| 243 | 252 | * ci_hdrc_otg_destroy - destroy otg struct |
|---|
| 244 | | - * ci: the controller |
|---|
| 253 | + * @ci: the controller |
|---|
| 245 | 254 | */ |
|---|
| 246 | 255 | void ci_hdrc_otg_destroy(struct ci_hdrc *ci) |
|---|
| 247 | 256 | { |
|---|