00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00042 #include "dwc_os.h"
00043 #include "dwc_otg_regs.h"
00044 #include "dwc_otg_cil.h"
00045 #include "dwc_otg_driver.h"
00046 #include "dwc_otg_pcd.h"
00047 #include "dwc_otg_hcd.h"
00048
00049 #ifdef DEBUG
00050 inline const char *op_state_str(dwc_otg_core_if_t * core_if)
00051 {
00052 return (core_if->op_state == A_HOST ? "a_host" :
00053 (core_if->op_state == A_SUSPEND ? "a_suspend" :
00054 (core_if->op_state == A_PERIPHERAL ? "a_peripheral" :
00055 (core_if->op_state == B_PERIPHERAL ? "b_peripheral" :
00056 (core_if->op_state == B_HOST ? "b_host" : "unknown")))));
00057 }
00058 #endif
00059
00064 int32_t dwc_otg_handle_mode_mismatch_intr(dwc_otg_core_if_t * core_if)
00065 {
00066 gintsts_data_t gintsts;
00067 DWC_WARN("Mode Mismatch Interrupt: currently in %s mode\n",
00068 dwc_otg_mode(core_if) ? "Host" : "Device");
00069
00070
00071 gintsts.d32 = 0;
00072 gintsts.b.modemismatch = 1;
00073 DWC_WRITE_REG32(&core_if->core_global_regs->gintsts, gintsts.d32);
00074 return 1;
00075 }
00076
00084 int32_t dwc_otg_handle_otg_intr(dwc_otg_core_if_t * core_if)
00085 {
00086 dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
00087 gotgint_data_t gotgint;
00088 gotgctl_data_t gotgctl;
00089 gintmsk_data_t gintmsk;
00090 gpwrdn_data_t gpwrdn;
00091
00092 gotgint.d32 = DWC_READ_REG32(&global_regs->gotgint);
00093 gotgctl.d32 = DWC_READ_REG32(&global_regs->gotgctl);
00094 DWC_DEBUGPL(DBG_CIL, "++OTG Interrupt gotgint=%0x [%s]\n", gotgint.d32,
00095 op_state_str(core_if));
00096
00097 if (gotgint.b.sesenddet) {
00098 DWC_DEBUGPL(DBG_ANY, " ++OTG Interrupt: "
00099 "Session End Detected++ (%s)\n",
00100 op_state_str(core_if));
00101 gotgctl.d32 = DWC_READ_REG32(&global_regs->gotgctl);
00102
00103 if (core_if->op_state == B_HOST) {
00104 cil_pcd_start(core_if);
00105 core_if->op_state = B_PERIPHERAL;
00106 } else {
00107
00108
00109 if (gotgctl.b.devhnpen) {
00110 DWC_DEBUGPL(DBG_ANY, "Session End Detected\n");
00111 __DWC_ERROR("Device Not Connected/Responding!\n");
00112 }
00113
00114
00115
00116
00117
00118 core_if->lx_state = DWC_OTG_L0;
00119 DWC_SPINUNLOCK(core_if->lock);
00120 cil_pcd_stop(core_if);
00121 DWC_SPINLOCK(core_if->lock);
00122
00123 if (core_if->adp_enable) {
00124 if (core_if->power_down == 2) {
00125 gpwrdn.d32 = 0;
00126 gpwrdn.b.pwrdnswtch = 1;
00127 DWC_MODIFY_REG32(&core_if->
00128 core_global_regs->
00129 gpwrdn, gpwrdn.d32, 0);
00130 }
00131
00132 gpwrdn.d32 = 0;
00133 gpwrdn.b.pmuintsel = 1;
00134 gpwrdn.b.pmuactv = 1;
00135 DWC_MODIFY_REG32(&core_if->core_global_regs->
00136 gpwrdn, 0, gpwrdn.d32);
00137
00138 dwc_otg_adp_sense_start(core_if);
00139 }
00140 }
00141
00142 gotgctl.d32 = 0;
00143 gotgctl.b.devhnpen = 1;
00144 DWC_MODIFY_REG32(&global_regs->gotgctl, gotgctl.d32, 0);
00145 }
00146 if (gotgint.b.sesreqsucstschng) {
00147 DWC_DEBUGPL(DBG_ANY, " ++OTG Interrupt: "
00148 "Session Reqeust Success Status Change++\n");
00149 gotgctl.d32 = DWC_READ_REG32(&global_regs->gotgctl);
00150 if (gotgctl.b.sesreqscs) {
00151
00152 if ((core_if->core_params->phy_type ==
00153 DWC_PHY_TYPE_PARAM_FS) && (core_if->core_params->i2c_enable)) {
00154 core_if->srp_success = 1;
00155 } else {
00156 DWC_SPINUNLOCK(core_if->lock);
00157 cil_pcd_resume(core_if);
00158 DWC_SPINLOCK(core_if->lock);
00159
00160 gotgctl.d32 = 0;
00161 gotgctl.b.sesreq = 1;
00162 DWC_MODIFY_REG32(&global_regs->gotgctl,
00163 gotgctl.d32, 0);
00164 }
00165 }
00166 }
00167 if (gotgint.b.hstnegsucstschng) {
00168
00169
00170 gotgctl.d32 = DWC_READ_REG32(&global_regs->gotgctl);
00171 if (gotgctl.b.hstnegscs) {
00172 if (dwc_otg_is_host_mode(core_if)) {
00173 core_if->op_state = B_HOST;
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184 gintmsk.d32 = 0;
00185 gintmsk.b.sofintr = 1;
00186 DWC_MODIFY_REG32(&global_regs->gintmsk,
00187 gintmsk.d32, 0);
00188
00189 DWC_SPINUNLOCK(core_if->lock);
00190 cil_pcd_stop(core_if);
00191
00192
00193
00194 cil_hcd_start(core_if);
00195 DWC_SPINLOCK(core_if->lock);
00196 core_if->op_state = B_HOST;
00197 }
00198 } else {
00199 gotgctl.d32 = 0;
00200 gotgctl.b.hnpreq = 1;
00201 gotgctl.b.devhnpen = 1;
00202 DWC_MODIFY_REG32(&global_regs->gotgctl, gotgctl.d32, 0);
00203 DWC_DEBUGPL(DBG_ANY, "HNP Failed\n");
00204 __DWC_ERROR("Device Not Connected/Responding\n");
00205 }
00206 }
00207 if (gotgint.b.hstnegdet) {
00208
00209
00210
00211
00212
00213 DWC_DEBUGPL(DBG_ANY, " ++OTG Interrupt: "
00214 "Host Negotiation Detected++ (%s)\n",
00215 (dwc_otg_is_host_mode(core_if) ? "Host" :
00216 "Device"));
00217 if (dwc_otg_is_device_mode(core_if)) {
00218 DWC_DEBUGPL(DBG_ANY, "a_suspend->a_peripheral (%d)\n",
00219 core_if->op_state);
00220 DWC_SPINUNLOCK(core_if->lock);
00221 cil_hcd_disconnect(core_if);
00222 cil_pcd_start(core_if);
00223 DWC_SPINLOCK(core_if->lock);
00224 core_if->op_state = A_PERIPHERAL;
00225 } else {
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235 gintmsk.d32 = 0;
00236 gintmsk.b.sofintr = 1;
00237 DWC_MODIFY_REG32(&global_regs->gintmsk, gintmsk.d32, 0);
00238 DWC_SPINUNLOCK(core_if->lock);
00239 cil_pcd_stop(core_if);
00240 cil_hcd_start(core_if);
00241 DWC_SPINLOCK(core_if->lock);
00242 core_if->op_state = A_HOST;
00243 }
00244 }
00245 if (gotgint.b.adevtoutchng) {
00246 DWC_DEBUGPL(DBG_ANY, " ++OTG Interrupt: "
00247 "A-Device Timeout Change++\n");
00248 }
00249 if (gotgint.b.debdone) {
00250 DWC_DEBUGPL(DBG_ANY, " ++OTG Interrupt: " "Debounce Done++\n");
00251 }
00252
00253
00254 DWC_WRITE_REG32(&core_if->core_global_regs->gotgint, gotgint.d32);
00255
00256 return 1;
00257 }
00258
00259 void w_conn_id_status_change(void *p)
00260 {
00261 dwc_otg_core_if_t *core_if = p;
00262 uint32_t count = 0;
00263 gotgctl_data_t gotgctl = {.d32 = 0 };
00264
00265 gotgctl.d32 = DWC_READ_REG32(&core_if->core_global_regs->gotgctl);
00266 DWC_DEBUGPL(DBG_CIL, "gotgctl=%0x\n", gotgctl.d32);
00267 DWC_DEBUGPL(DBG_CIL, "gotgctl.b.conidsts=%d\n", gotgctl.b.conidsts);
00268
00269
00270 if (gotgctl.b.conidsts) {
00271
00272 while (!dwc_otg_is_device_mode(core_if)) {
00273 DWC_PRINTF("Waiting for Peripheral Mode, Mode=%s\n",
00274 (dwc_otg_is_host_mode(core_if) ? "Host" :
00275 "Peripheral"));
00276 dwc_mdelay(100);
00277 if (++count > 10000)
00278 break;
00279 }
00280 DWC_ASSERT(++count < 10000,
00281 "Connection id status change timed out");
00282 core_if->op_state = B_PERIPHERAL;
00283 dwc_otg_core_init(core_if);
00284 dwc_otg_enable_global_interrupts(core_if);
00285 cil_pcd_start(core_if);
00286 } else {
00287
00288 while (!dwc_otg_is_host_mode(core_if)) {
00289 DWC_PRINTF("Waiting for Host Mode, Mode=%s\n",
00290 (dwc_otg_is_host_mode(core_if) ? "Host" :
00291 "Peripheral"));
00292 dwc_mdelay(100);
00293 if (++count > 10000)
00294 break;
00295 }
00296 DWC_ASSERT(++count < 10000,
00297 "Connection id status change timed out");
00298 core_if->op_state = A_HOST;
00299
00300
00301
00302 dwc_otg_core_init(core_if);
00303 dwc_otg_enable_global_interrupts(core_if);
00304 cil_hcd_start(core_if);
00305 }
00306 }
00307
00319 int32_t dwc_otg_handle_conn_id_status_change_intr(dwc_otg_core_if_t * core_if)
00320 {
00321
00322
00323
00324
00325
00326
00327
00328
00329 gintmsk_data_t gintmsk = {.d32 = 0 };
00330 gintsts_data_t gintsts = {.d32 = 0 };
00331
00332 gintmsk.b.sofintr = 1;
00333 DWC_MODIFY_REG32(&core_if->core_global_regs->gintmsk, gintmsk.d32, 0);
00334
00335 DWC_DEBUGPL(DBG_CIL,
00336 " ++Connector ID Status Change Interrupt++ (%s)\n",
00337 (dwc_otg_is_host_mode(core_if) ? "Host" : "Device"));
00338
00339 DWC_SPINUNLOCK(core_if->lock);
00340
00341
00342
00343
00344
00345
00346 DWC_WORKQ_SCHEDULE(core_if->wq_otg, w_conn_id_status_change,
00347 core_if, "connection id status change");
00348 DWC_SPINLOCK(core_if->lock);
00349
00350
00351 gintsts.b.conidstschng = 1;
00352 DWC_WRITE_REG32(&core_if->core_global_regs->gintsts, gintsts.d32);
00353
00354 return 1;
00355 }
00356
00366 int32_t dwc_otg_handle_session_req_intr(dwc_otg_core_if_t * core_if)
00367 {
00368 gintsts_data_t gintsts;
00369
00370 #ifndef DWC_HOST_ONLY
00371 DWC_DEBUGPL(DBG_ANY, "++Session Request Interrupt++\n");
00372
00373 if (dwc_otg_is_device_mode(core_if)) {
00374 DWC_PRINTF("SRP: Device mode\n");
00375 } else {
00376 hprt0_data_t hprt0;
00377 DWC_PRINTF("SRP: Host mode\n");
00378
00379
00380 hprt0.d32 = dwc_otg_read_hprt0(core_if);
00381 hprt0.b.prtpwr = 1;
00382 DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32);
00383
00384
00385
00386 cil_hcd_session_start(core_if);
00387 }
00388 #endif
00389
00390
00391 gintsts.d32 = 0;
00392 gintsts.b.sessreqintr = 1;
00393 DWC_WRITE_REG32(&core_if->core_global_regs->gintsts, gintsts.d32);
00394
00395 return 1;
00396 }
00397
00398 void w_wakeup_detected(void *p)
00399 {
00400 dwc_otg_core_if_t *core_if = (dwc_otg_core_if_t *) p;
00401
00402
00403
00404
00405 hprt0_data_t hprt0 = {.d32 = 0 };
00406 #if 0
00407 pcgcctl_data_t pcgcctl = {.d32 = 0 };
00408
00409 pcgcctl.b.stoppclk = 1;
00410 DWC_MODIFY_REG32(core_if->pcgcctl, pcgcctl.d32, 0);
00411 dwc_udelay(10);
00412 #endif //0
00413 hprt0.d32 = dwc_otg_read_hprt0(core_if);
00414 DWC_DEBUGPL(DBG_ANY, "Resume: HPRT0=%0x\n", hprt0.d32);
00415
00416 hprt0.b.prtres = 0;
00417 DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32);
00418 DWC_DEBUGPL(DBG_ANY, "Clear Resume: HPRT0=%0x\n",
00419 DWC_READ_REG32(core_if->host_if->hprt0));
00420
00421 cil_hcd_resume(core_if);
00422
00424 core_if->lx_state = DWC_OTG_L0;
00425 }
00426
00434 int32_t dwc_otg_handle_wakeup_detected_intr(dwc_otg_core_if_t * core_if)
00435 {
00436 gintsts_data_t gintsts;
00437
00438 DWC_DEBUGPL(DBG_ANY,
00439 "++Resume and Remote Wakeup Detected Interrupt++\n");
00440
00441 DWC_PRINTF("%s lxstate = %d\n", __func__, core_if->lx_state);
00442
00443 if (dwc_otg_is_device_mode(core_if)) {
00444 dctl_data_t dctl = {.d32 = 0 };
00445 DWC_DEBUGPL(DBG_PCD, "DSTS=0x%0x\n",
00446 DWC_READ_REG32(&core_if->dev_if->
00447 dev_global_regs->dsts));
00448 if (core_if->lx_state == DWC_OTG_L2) {
00449 #ifdef PARTIAL_POWER_DOWN
00450 if (core_if->hwcfg4.b.power_optimiz) {
00451 pcgcctl_data_t power = {.d32 = 0 };
00452
00453 power.d32 = DWC_READ_REG32(core_if->pcgcctl);
00454 DWC_DEBUGPL(DBG_CIL, "PCGCCTL=%0x\n",
00455 power.d32);
00456
00457 power.b.stoppclk = 0;
00458 DWC_WRITE_REG32(core_if->pcgcctl, power.d32);
00459
00460 power.b.pwrclmp = 0;
00461 DWC_WRITE_REG32(core_if->pcgcctl, power.d32);
00462
00463 power.b.rstpdwnmodule = 0;
00464 DWC_WRITE_REG32(core_if->pcgcctl, power.d32);
00465 }
00466 #endif
00467
00468 dctl.b.rmtwkupsig = 1;
00469 DWC_MODIFY_REG32(&core_if->dev_if->
00470 dev_global_regs->dctl, dctl.d32, 0);
00471
00472 DWC_SPINUNLOCK(core_if->lock);
00473 if (core_if->pcd_cb && core_if->pcd_cb->resume_wakeup) {
00474 core_if->pcd_cb->resume_wakeup(core_if->pcd_cb->p);
00475 }
00476 DWC_SPINLOCK(core_if->lock);
00477 } else {
00478 glpmcfg_data_t lpmcfg;
00479 lpmcfg.d32 =
00480 DWC_READ_REG32(&core_if->core_global_regs->glpmcfg);
00481 lpmcfg.b.hird_thres &= (~(1 << 4));
00482 DWC_WRITE_REG32(&core_if->core_global_regs->glpmcfg,
00483 lpmcfg.d32);
00484 }
00486 core_if->lx_state = DWC_OTG_L0;
00487 } else {
00488 if (core_if->lx_state != DWC_OTG_L1) {
00489 pcgcctl_data_t pcgcctl = {.d32 = 0 };
00490
00491
00492 pcgcctl.b.stoppclk = 1;
00493 DWC_MODIFY_REG32(core_if->pcgcctl, pcgcctl.d32, 0);
00494 DWC_TIMER_SCHEDULE(core_if->wkp_timer, 71);
00495 } else {
00497 core_if->lx_state = DWC_OTG_L0;
00498 }
00499 }
00500
00501
00502 gintsts.d32 = 0;
00503 gintsts.b.wkupintr = 1;
00504 DWC_WRITE_REG32(&core_if->core_global_regs->gintsts, gintsts.d32);
00505
00506 return 1;
00507 }
00508
00513 static int32_t dwc_otg_handle_pwrdn_disconnect_intr(dwc_otg_core_if_t *core_if)
00514 {
00515 gpwrdn_data_t gpwrdn = { .d32 = 0 };
00516 gpwrdn_data_t gpwrdn_temp = { .d32 = 0 };
00517 gpwrdn_temp.d32 = DWC_READ_REG32(&core_if->core_global_regs->gpwrdn);
00518
00519 DWC_PRINTF("%s called\n", __FUNCTION__);
00520
00521 if (!core_if->hibernation_suspend) {
00522 DWC_PRINTF("Already exited from Hibernation\n");
00523 return 1;
00524 }
00525
00526
00527 gpwrdn.b.pwrdnswtch = 1;
00528 DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
00529 dwc_udelay(10);
00530
00531
00532 gpwrdn.d32 = 0;
00533 gpwrdn.b.pwrdnrstn = 1;
00534 DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
00535 dwc_udelay(10);
00536
00537
00538 gpwrdn.d32 = 0;
00539 gpwrdn.b.pwrdnclmp = 1;
00540 DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
00541
00542
00543 gpwrdn.d32 = 0;
00544 gpwrdn.b.pwrdnrstn = 1;
00545 DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, 0, gpwrdn.d32);
00546 dwc_udelay(10);
00547
00548
00549 gpwrdn.d32 = 0;
00550 gpwrdn.b.pmuintsel = 1;
00551 DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
00552
00553 core_if->hibernation_suspend = 0;
00554
00555
00556 gpwrdn.d32 = 0;
00557 gpwrdn.b.pmuactv = 1;
00558 DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
00559 dwc_udelay(10);
00560
00561 if (gpwrdn_temp.b.idsts) {
00562 core_if->op_state = B_PERIPHERAL;
00563 dwc_otg_core_init(core_if);
00564 dwc_otg_enable_global_interrupts(core_if);
00565 cil_pcd_start(core_if);
00566 } else {
00567 core_if->op_state = A_HOST;
00568 dwc_otg_core_init(core_if);
00569 dwc_otg_enable_global_interrupts(core_if);
00570 cil_hcd_start(core_if);
00571 }
00572
00573 return 1;
00574 }
00575
00580 static int32_t dwc_otg_handle_pwrdn_wakeup_detected_intr(dwc_otg_core_if_t * core_if)
00581 {
00582 gpwrdn_data_t gpwrdn = {.d32 = 0 };
00583 DWC_DEBUGPL(DBG_ANY,
00584 "++Powerdown Remote Wakeup Detected Interrupt++\n");
00585
00586 if (!core_if->hibernation_suspend) {
00587 DWC_PRINTF("Already exited from Hibernation\n");
00588 return 1;
00589 }
00590
00591 gpwrdn.d32 = DWC_READ_REG32(&core_if->core_global_regs->gpwrdn);
00592 if (gpwrdn.b.idsts) {
00593 if ((core_if->power_down == 2)
00594 && (core_if->hibernation_suspend == 1)) {
00595 dwc_otg_device_hibernation_restore(core_if, 0, 0);
00596 }
00597 } else {
00598 if ((core_if->power_down == 2)
00599 && (core_if->hibernation_suspend == 1)) {
00600 dwc_otg_host_hibernation_restore(core_if, 1, 0);
00601 }
00602 }
00603 return 1;
00604 }
00605
00606 static int32_t dwc_otg_handle_pwrdn_idsts_change(dwc_otg_device_t *otg_dev)
00607 {
00608 gpwrdn_data_t gpwrdn = {.d32 = 0 };
00609 gpwrdn_data_t gpwrdn_temp = {.d32 = 0 };
00610 dwc_otg_core_if_t *core_if = otg_dev->core_if;
00611
00612 DWC_DEBUGPL(DBG_ANY, "%s called\n", __FUNCTION__);
00613 gpwrdn_temp.d32 = DWC_READ_REG32(&core_if->core_global_regs->gpwrdn);
00614 if (core_if->power_down == 2)
00615 {
00616 if (!core_if->hibernation_suspend) {
00617 DWC_PRINTF("Already exited from Hibernation\n");
00618 return 1;
00619 }
00620 DWC_DEBUGPL(DBG_ANY, "Exit from hibernation on ID sts change\n");
00621
00622 gpwrdn.b.pwrdnswtch = 1;
00623 DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
00624 dwc_udelay(10);
00625
00626
00627 gpwrdn.d32 = 0;
00628 gpwrdn.b.pwrdnrstn = 1;
00629 DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
00630 dwc_udelay(10);
00631
00632
00633 gpwrdn.d32 = 0;
00634 gpwrdn.b.pwrdnclmp = 1;
00635 DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
00636
00637
00638 gpwrdn.d32 = 0;
00639 gpwrdn.b.pwrdnrstn = 1;
00640 DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, 0, gpwrdn.d32);
00641 dwc_udelay(10);
00642
00643
00644 gpwrdn.d32 = 0;
00645 gpwrdn.b.pmuintsel = 1;
00646 DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
00647
00648
00649 core_if->hibernation_suspend = 0;
00650
00651
00652 gpwrdn.d32 = 0;
00653 gpwrdn.b.pmuactv = 1;
00654 DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
00655 dwc_udelay(10);
00656
00657 gpwrdn.d32 = core_if->gr_backup->gpwrdn_local;
00658 if (gpwrdn.b.dis_vbus == 1) {
00659 gpwrdn.d32 = 0;
00660 gpwrdn.b.dis_vbus = 1;
00661 DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
00662 }
00663
00664 if (gpwrdn_temp.b.idsts) {
00665 core_if->op_state = B_PERIPHERAL;
00666 dwc_otg_core_init(core_if);
00667 dwc_otg_enable_global_interrupts(core_if);
00668 cil_pcd_start(core_if);
00669 } else {
00670 core_if->op_state = A_HOST;
00671 dwc_otg_core_init(core_if);
00672 dwc_otg_enable_global_interrupts(core_if);
00673 cil_hcd_start(core_if);
00674 }
00675 }
00676
00677 if (core_if->adp_enable)
00678 {
00679 uint8_t is_host = 0;
00680 DWC_SPINUNLOCK(core_if->lock);
00681
00682 #ifndef DWC_HOST_ONLY
00683 if (gpwrdn_temp.b.idsts)
00684 core_if->lock = otg_dev->pcd->lock;
00685 #endif
00686 #ifndef DWC_DEVICE_ONLY
00687 if (!gpwrdn_temp.b.idsts) {
00688 core_if->lock = otg_dev->hcd->lock;
00689 is_host = 1;
00690 }
00691 #endif
00692 DWC_PRINTF("RESTART ADP\n");
00693 if (core_if->adp.probe_enabled)
00694 dwc_otg_adp_probe_stop(core_if);
00695 if (core_if->adp.sense_enabled)
00696 dwc_otg_adp_sense_stop(core_if);
00697 if (core_if->adp.sense_timer_started)
00698 DWC_TIMER_CANCEL(core_if->adp.sense_timer);
00699 if (core_if->adp.vbuson_timer_started)
00700 DWC_TIMER_CANCEL(core_if->adp.vbuson_timer);
00701 core_if->adp.probe_timer_values[0] = -1;
00702 core_if->adp.probe_timer_values[1] = -1;
00703 core_if->adp.sense_timer_started = 0;
00704 core_if->adp.vbuson_timer_started = 0;
00705 core_if->adp.probe_counter = 0;
00706 core_if->adp.gpwrdn = 0;
00707
00708
00709 gpwrdn_temp.d32 = 0;
00710 gpwrdn_temp.b.pmuactv = 1;
00711 gpwrdn_temp.b.pmuintsel = 1;
00712 DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
00713 DWC_PRINTF("Check point 1\n");
00714 dwc_mdelay(110);
00715 dwc_otg_adp_start(core_if, is_host);
00716 DWC_SPINLOCK(core_if->lock);
00717 }
00718
00719
00720 return 1;
00721 }
00722
00723 static int32_t dwc_otg_handle_pwrdn_session_change(dwc_otg_core_if_t * core_if)
00724 {
00725 gpwrdn_data_t gpwrdn = {.d32 = 0 };
00726 int32_t otg_cap_param = core_if->core_params->otg_cap;
00727 DWC_DEBUGPL(DBG_ANY, "%s called\n", __FUNCTION__);
00728
00729 gpwrdn.d32 = DWC_READ_REG32(&core_if->core_global_regs->gpwrdn);
00730 if (core_if->power_down == 2) {
00731 if (!core_if->hibernation_suspend) {
00732 DWC_PRINTF("Already exited from Hibernation\n");
00733 return 1;
00734 }
00735
00736 if ((otg_cap_param != DWC_OTG_CAP_PARAM_HNP_SRP_CAPABLE ||
00737 otg_cap_param != DWC_OTG_CAP_PARAM_SRP_ONLY_CAPABLE) &&
00738 gpwrdn.b.bsessvld == 0) {
00739
00740 core_if->gr_backup->gpwrdn_local =
00741 DWC_READ_REG32(&core_if->core_global_regs->gpwrdn);
00742
00743 return 1;
00744 }
00745
00746
00747 gpwrdn.d32 = 0;
00748 gpwrdn.b.pwrdnswtch = 1;
00749 DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
00750 dwc_udelay(10);
00751
00752
00753 gpwrdn.d32 = 0;
00754 gpwrdn.b.pwrdnrstn = 1;
00755 DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
00756 dwc_udelay(10);
00757
00758
00759 gpwrdn.d32 = 0;
00760 gpwrdn.b.pwrdnclmp = 1;
00761 DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
00762
00763
00764 gpwrdn.d32 = 0;
00765 gpwrdn.b.pwrdnrstn = 1;
00766 DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, 0, gpwrdn.d32);
00767 dwc_udelay(10);
00768
00769
00770 gpwrdn.d32 = 0;
00771 gpwrdn.b.pmuintsel = 1;
00772 DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
00773 dwc_udelay(10);
00774
00775
00776 core_if->hibernation_suspend = 0;
00777
00778
00779 gpwrdn.d32 = 0;
00780 gpwrdn.b.pmuactv = 1;
00781 DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
00782 dwc_udelay(10);
00783
00784 core_if->op_state = B_PERIPHERAL;
00785 dwc_otg_core_init(core_if);
00786 dwc_otg_enable_global_interrupts(core_if);
00787 cil_pcd_start(core_if);
00788
00789 if (otg_cap_param == DWC_OTG_CAP_PARAM_HNP_SRP_CAPABLE ||
00790 otg_cap_param == DWC_OTG_CAP_PARAM_SRP_ONLY_CAPABLE) {
00791
00792
00793
00794 dwc_otg_initiate_srp(core_if);
00795 }
00796 }
00797
00798 return 1;
00799 }
00804 static uint32_t dwc_otg_handle_pwrdn_stschng_intr(dwc_otg_device_t *otg_dev)
00805 {
00806 int retval;
00807 gpwrdn_data_t gpwrdn = {.d32 = 0 };
00808 gpwrdn_data_t gpwrdn_temp = {.d32 = 0 };
00809 dwc_otg_core_if_t *core_if = otg_dev->core_if;
00810
00811 DWC_PRINTF("%s called\n", __FUNCTION__);
00812
00813 if (core_if->power_down == 2) {
00814 if (core_if->hibernation_suspend <= 0) {
00815 DWC_PRINTF("Already exited from Hibernation\n");
00816 return 1;
00817 } else
00818 gpwrdn_temp.d32 = core_if->gr_backup->gpwrdn_local;
00819
00820 } else {
00821 gpwrdn_temp.d32 = core_if->adp.gpwrdn;
00822 }
00823
00824 gpwrdn.d32 = DWC_READ_REG32(&core_if->core_global_regs->gpwrdn);
00825
00826 if (gpwrdn.b.idsts ^ gpwrdn_temp.b.idsts) {
00827 retval = dwc_otg_handle_pwrdn_idsts_change(otg_dev);
00828 } else if (gpwrdn.b.bsessvld ^ gpwrdn_temp.b.bsessvld) {
00829 retval = dwc_otg_handle_pwrdn_session_change(core_if);
00830 }
00831
00832 return retval;
00833 }
00834
00839 static int32_t dwc_otg_handle_pwrdn_srp_intr(dwc_otg_core_if_t * core_if)
00840 {
00841 gpwrdn_data_t gpwrdn = {.d32 = 0 };
00842
00843 DWC_PRINTF("%s called\n", __FUNCTION__);
00844
00845 if (!core_if->hibernation_suspend) {
00846 DWC_PRINTF("Already exited from Hibernation\n");
00847 return 1;
00848 }
00849 #ifdef DWC_DEV_SRPCAP
00850 if (core_if->pwron_timer_started) {
00851 core_if->pwron_timer_started = 0;
00852 DWC_TIMER_CANCEL(core_if->pwron_timer);
00853 }
00854 #endif
00855
00856
00857 gpwrdn.b.pwrdnswtch = 1;
00858 DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
00859 dwc_udelay(10);
00860
00861
00862 gpwrdn.d32 = 0;
00863 gpwrdn.b.pwrdnrstn = 1;
00864 DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
00865 dwc_udelay(10);
00866
00867
00868 gpwrdn.d32 = 0;
00869 gpwrdn.b.pwrdnclmp = 1;
00870 DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
00871
00872
00873 gpwrdn.d32 = 0;
00874 gpwrdn.b.pwrdnrstn = 1;
00875 DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, 0, gpwrdn.d32);
00876 dwc_udelay(10);
00877
00878
00879 gpwrdn.d32 = 0;
00880 gpwrdn.b.pmuintsel = 1;
00881 DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
00882
00883
00884 core_if->hibernation_suspend = 0;
00885
00886
00887 gpwrdn.d32 = 0;
00888 gpwrdn.b.pmuactv = 1;
00889 DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
00890 dwc_udelay(10);
00891
00892
00893 gpwrdn.d32 = 0;
00894 gpwrdn.b.dis_vbus = 1;
00895 DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
00896
00897
00898 core_if->op_state = A_HOST;
00899 dwc_otg_core_init(core_if);
00900 dwc_otg_enable_global_interrupts(core_if);
00901 cil_hcd_start(core_if);
00902
00903 return 1;
00904 }
00905
00908 int32_t dwc_otg_handle_restore_done_intr(dwc_otg_core_if_t * core_if)
00909 {
00910 pcgcctl_data_t pcgcctl;
00911 DWC_DEBUGPL(DBG_ANY, "++Restore Done Interrupt++\n");
00912
00913
00914 pcgcctl.d32 = DWC_READ_REG32(core_if->pcgcctl);
00915 if (pcgcctl.b.restoremode == 1) {
00916 gintmsk_data_t gintmsk = {.d32 = 0 };
00917
00918
00919
00920
00921 gintmsk.b.wkupintr = 1;
00922 DWC_MODIFY_REG32(&core_if->core_global_regs->gintmsk,
00923 0, gintmsk.d32);
00924 }
00925
00926 return 1;
00927 }
00928
00933 int32_t dwc_otg_handle_disconnect_intr(dwc_otg_core_if_t * core_if)
00934 {
00935 gintsts_data_t gintsts;
00936
00937 DWC_DEBUGPL(DBG_ANY, "++Disconnect Detected Interrupt++ (%s) %s\n",
00938 (dwc_otg_is_host_mode(core_if) ? "Host" : "Device"),
00939 op_state_str(core_if));
00940
00942 #ifndef DWC_HOST_ONLY
00943 if (core_if->op_state == B_HOST) {
00944
00945
00946 DWC_SPINUNLOCK(core_if->lock);
00947 cil_hcd_disconnect(core_if);
00948 cil_pcd_start(core_if);
00949 DWC_SPINLOCK(core_if->lock);
00950 core_if->op_state = B_PERIPHERAL;
00951 } else if (dwc_otg_is_device_mode(core_if)) {
00952 gotgctl_data_t gotgctl = {.d32 = 0 };
00953 gotgctl.d32 =
00954 DWC_READ_REG32(&core_if->core_global_regs->gotgctl);
00955 if (gotgctl.b.hstsethnpen == 1) {
00956
00957
00958
00959
00960 } else if (gotgctl.b.devhnpen == 0) {
00961
00962
00963 DWC_SPINUNLOCK(core_if->lock);
00964 cil_hcd_disconnect(core_if);
00965 cil_pcd_start(core_if);
00966 DWC_SPINLOCK(core_if->lock);
00967 core_if->op_state = B_PERIPHERAL;
00968 } else {
00969 DWC_DEBUGPL(DBG_ANY, "!a_peripheral && !devhnpen\n");
00970 }
00971 } else {
00972 if (core_if->op_state == A_HOST) {
00973
00974 cil_hcd_disconnect(core_if);
00975 if (core_if->adp_enable) {
00976 gpwrdn_data_t gpwrdn = { .d32 = 0 };
00977 cil_hcd_stop(core_if);
00978
00979 gpwrdn.b.pmuintsel = 1;
00980 gpwrdn.b.pmuactv = 1;
00981 DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, 0, gpwrdn.d32);
00982 dwc_otg_adp_probe_start(core_if);
00983
00984
00985 if (core_if->power_down == 2) {
00986 gpwrdn.d32 = 0;
00987 gpwrdn.b.pwrdnswtch = 1;
00988 DWC_MODIFY_REG32(&core_if->
00989 core_global_regs->
00990 gpwrdn, gpwrdn.d32, 0);
00991 }
00992 }
00993 }
00994 }
00995 #endif
00996
00997 core_if->lx_state = DWC_OTG_L3;
00998
00999 gintsts.d32 = 0;
01000 gintsts.b.disconnect = 1;
01001 DWC_WRITE_REG32(&core_if->core_global_regs->gintsts, gintsts.d32);
01002 return 1;
01003 }
01004
01015 int32_t dwc_otg_handle_usb_suspend_intr(dwc_otg_core_if_t * core_if)
01016 {
01017 dsts_data_t dsts;
01018 gintsts_data_t gintsts;
01019 dcfg_data_t dcfg;
01020
01021 DWC_DEBUGPL(DBG_ANY, "USB SUSPEND\n");
01022
01023 if (dwc_otg_is_device_mode(core_if)) {
01024
01025
01026 dsts.d32 =
01027 DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dsts);
01028 DWC_DEBUGPL(DBG_PCD, "DSTS=0x%0x\n", dsts.d32);
01029 DWC_DEBUGPL(DBG_PCD, "DSTS.Suspend Status=%d "
01030 "HWCFG4.power Optimize=%d\n",
01031 dsts.b.suspsts, core_if->hwcfg4.b.power_optimiz);
01032
01033 #ifdef PARTIAL_POWER_DOWN
01034
01036 if (dsts.b.suspsts && core_if->hwcfg4.b.power_optimiz) {
01037 pcgcctl_data_t power = {.d32 = 0 };
01038 DWC_DEBUGPL(DBG_CIL, "suspend\n");
01039
01040 power.b.pwrclmp = 1;
01041 DWC_WRITE_REG32(core_if->pcgcctl, power.d32);
01042
01043 power.b.rstpdwnmodule = 1;
01044 DWC_MODIFY_REG32(core_if->pcgcctl, 0, power.d32);
01045
01046 power.b.stoppclk = 1;
01047 DWC_MODIFY_REG32(core_if->pcgcctl, 0, power.d32);
01048
01049 } else {
01050 DWC_DEBUGPL(DBG_ANY, "disconnect?\n");
01051 }
01052 #endif
01053
01054 cil_pcd_suspend(core_if);
01055 if (core_if->power_down == 2)
01056 {
01057 dcfg.d32 = DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dcfg);
01058 DWC_DEBUGPL(DBG_ANY,"lx_state = %08x\n",core_if->lx_state);
01059 DWC_DEBUGPL(DBG_ANY," device address = %08d\n",dcfg.b.devaddr);
01060
01061 if (core_if->lx_state != DWC_OTG_L3 && dcfg.b.devaddr) {
01062 pcgcctl_data_t pcgcctl = {.d32 = 0 };
01063 gpwrdn_data_t gpwrdn = {.d32 = 0 };
01064 gusbcfg_data_t gusbcfg = {.d32 = 0 };
01065
01066
01067 core_if->lx_state = DWC_OTG_L2;
01068
01069
01070 gintsts.d32 = 0;
01071 gintsts.b.usbsuspend = 1;
01072 DWC_WRITE_REG32(&core_if->core_global_regs->
01073 gintsts, gintsts.d32);
01074 DWC_PRINTF("Start of hibernation completed\n");
01075 dwc_otg_save_global_regs(core_if);
01076 dwc_otg_save_dev_regs(core_if);
01077
01078 gusbcfg.d32 =
01079 DWC_READ_REG32(&core_if->core_global_regs->
01080 gusbcfg);
01081 if (gusbcfg.b.ulpi_utmi_sel == 1) {
01082
01083
01084 pcgcctl.d32 = 0;
01085 pcgcctl.b.stoppclk = 1;
01086 DWC_MODIFY_REG32(core_if->pcgcctl, 0,
01087 pcgcctl.d32);
01088 dwc_udelay(10);
01089 gpwrdn.b.pmuactv = 1;
01090 DWC_MODIFY_REG32(&core_if->
01091 core_global_regs->
01092 gpwrdn, 0, gpwrdn.d32);
01093 } else {
01094
01095 gpwrdn.b.pmuactv = 1;
01096 DWC_MODIFY_REG32(&core_if->
01097 core_global_regs->
01098 gpwrdn, 0, gpwrdn.d32);
01099 dwc_udelay(10);
01100 pcgcctl.b.stoppclk = 1;
01101 DWC_MODIFY_REG32(core_if->pcgcctl, 0,
01102 pcgcctl.d32);
01103 dwc_udelay(10);
01104 }
01105
01106
01107 core_if->hibernation_suspend = 1;
01108
01109 gpwrdn.d32 = 0;
01110 gpwrdn.b.pmuintsel = 1;
01111 DWC_MODIFY_REG32(&core_if->core_global_regs->
01112 gpwrdn, 0, gpwrdn.d32);
01113 dwc_udelay(10);
01114
01115
01116 gpwrdn.d32 = 0;
01117 gpwrdn.b.rst_det_msk = 1;
01118 gpwrdn.b.lnstchng_msk = 1;
01119 gpwrdn.b.sts_chngint_msk = 1;
01120 DWC_MODIFY_REG32(&core_if->core_global_regs->
01121 gpwrdn, 0, gpwrdn.d32);
01122 dwc_udelay(10);
01123
01124
01125 gpwrdn.d32 = 0;
01126 gpwrdn.b.pwrdnclmp = 1;
01127 DWC_MODIFY_REG32(&core_if->core_global_regs->
01128 gpwrdn, 0, gpwrdn.d32);
01129 dwc_udelay(10);
01130
01131
01132 gpwrdn.d32 = 0;
01133 gpwrdn.b.pwrdnswtch = 1;
01134 DWC_MODIFY_REG32(&core_if->core_global_regs->
01135 gpwrdn, 0, gpwrdn.d32);
01136
01137
01138 core_if->gr_backup->gpwrdn_local =
01139 DWC_READ_REG32(&core_if->core_global_regs->gpwrdn);
01140 DWC_PRINTF("Hibernation completed\n");
01141
01142 return 1;
01143 }
01144 }
01145 } else {
01146 if (core_if->op_state == A_PERIPHERAL) {
01147 DWC_DEBUGPL(DBG_ANY, "a_peripheral->a_host\n");
01148
01149 DWC_SPINUNLOCK(core_if->lock);
01150 cil_pcd_stop(core_if);
01151 cil_hcd_start(core_if);
01152 DWC_SPINLOCK(core_if->lock);
01153 core_if->op_state = A_HOST;
01154 }
01155 }
01156
01157
01158 core_if->lx_state = DWC_OTG_L2;
01159
01160
01161 gintsts.d32 = 0;
01162 gintsts.b.usbsuspend = 1;
01163 DWC_WRITE_REG32(&core_if->core_global_regs->gintsts, gintsts.d32);
01164
01165 return 1;
01166 }
01167
01168 #ifdef CONFIG_USB_DWC_OTG_LPM
01169
01172 static int32_t dwc_otg_handle_lpm_intr(dwc_otg_core_if_t * core_if)
01173 {
01174 glpmcfg_data_t lpmcfg;
01175 gintsts_data_t gintsts;
01176
01177 if (!core_if->core_params->lpm_enable) {
01178 DWC_PRINTF("Unexpected LPM interrupt\n");
01179 }
01180
01181 lpmcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->glpmcfg);
01182 DWC_PRINTF("LPM config register = 0x%08x\n", lpmcfg.d32);
01183
01184 if (dwc_otg_is_host_mode(core_if)) {
01185 cil_hcd_sleep(core_if);
01186 } else {
01187 lpmcfg.b.hird_thres |= (1 << 4);
01188 DWC_WRITE_REG32(&core_if->core_global_regs->glpmcfg,
01189 lpmcfg.d32);
01190 }
01191
01192
01193 dwc_udelay(10);
01194 lpmcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->glpmcfg);
01195 if (lpmcfg.b.prt_sleep_sts) {
01196
01197 core_if->lx_state = DWC_OTG_L1;
01198 }
01199
01200
01201 gintsts.d32 = 0;
01202 gintsts.b.lpmtranrcvd = 1;
01203 DWC_WRITE_REG32(&core_if->core_global_regs->gintsts, gintsts.d32);
01204 return 1;
01205 }
01206 #endif
01207
01211 static inline uint32_t dwc_otg_read_common_intr(dwc_otg_core_if_t * core_if)
01212 {
01213 gahbcfg_data_t gahbcfg = {.d32 = 0 };
01214 gintsts_data_t gintsts;
01215 gintmsk_data_t gintmsk;
01216 gintmsk_data_t gintmsk_common = {.d32 = 0 };
01217 gintmsk_common.b.wkupintr = 1;
01218 gintmsk_common.b.sessreqintr = 1;
01219 gintmsk_common.b.conidstschng = 1;
01220 gintmsk_common.b.otgintr = 1;
01221 gintmsk_common.b.modemismatch = 1;
01222 gintmsk_common.b.disconnect = 1;
01223 gintmsk_common.b.usbsuspend = 1;
01224 #ifdef CONFIG_USB_DWC_OTG_LPM
01225 gintmsk_common.b.lpmtranrcvd = 1;
01226 #endif
01227 gintmsk_common.b.restoredone = 1;
01231 gintmsk_common.b.portintr = 1;
01232
01233 gintsts.d32 = DWC_READ_REG32(&core_if->core_global_regs->gintsts);
01234 gintmsk.d32 = DWC_READ_REG32(&core_if->core_global_regs->gintmsk);
01235 gahbcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->gahbcfg);
01236
01237 #ifdef DEBUG
01238
01239 if (gintsts.d32 & gintmsk_common.d32) {
01240 DWC_DEBUGPL(DBG_ANY, "gintsts=%08x gintmsk=%08x\n",
01241 gintsts.d32, gintmsk.d32);
01242 }
01243 #endif
01244 if (gahbcfg.b.glblintrmsk)
01245 return ((gintsts.d32 & gintmsk.d32) & gintmsk_common.d32);
01246 else
01247 return 0;
01248
01249 }
01250
01251
01252 #define CLEAR_GPWRDN_INTR(__core_if,__intr) \
01253 do { \
01254 gpwrdn_data_t gpwrdn = {.d32=0}; \
01255 gpwrdn.b.__intr = 1; \
01256 DWC_MODIFY_REG32(&__core_if->core_global_regs->gpwrdn, \
01257 0, gpwrdn.d32); \
01258 } while (0)
01259
01275 int32_t dwc_otg_handle_common_intr(void *dev)
01276 {
01277 int retval = 0;
01278 gintsts_data_t gintsts;
01279 gpwrdn_data_t gpwrdn = {.d32 = 0 };
01280 dwc_otg_device_t *otg_dev = dev;
01281 dwc_otg_core_if_t *core_if = otg_dev->core_if;
01282 gpwrdn.d32 = DWC_READ_REG32(&core_if->core_global_regs->gpwrdn);
01283 if (dwc_otg_is_device_mode(core_if))
01284 core_if->frame_num = dwc_otg_get_frame_number(core_if);
01285
01286 if (core_if->lock)
01287 DWC_SPINLOCK(core_if->lock);
01288
01289 if (core_if->hibernation_suspend <= 0) {
01290 gintsts.d32 = dwc_otg_read_common_intr(core_if);
01291
01292 if (gintsts.b.modemismatch) {
01293 retval |= dwc_otg_handle_mode_mismatch_intr(core_if);
01294 }
01295 if (gintsts.b.otgintr) {
01296 retval |= dwc_otg_handle_otg_intr(core_if);
01297 }
01298 if (gintsts.b.conidstschng) {
01299 retval |= dwc_otg_handle_conn_id_status_change_intr(core_if);
01300 }
01301 if (gintsts.b.disconnect) {
01302 retval |= dwc_otg_handle_disconnect_intr(core_if);
01303 }
01304 if (gintsts.b.sessreqintr) {
01305 retval |= dwc_otg_handle_session_req_intr(core_if);
01306 }
01307 if (gintsts.b.wkupintr) {
01308 retval |= dwc_otg_handle_wakeup_detected_intr(core_if);
01309 }
01310 if (gintsts.b.usbsuspend) {
01311 retval |= dwc_otg_handle_usb_suspend_intr(core_if);
01312 }
01313 #ifdef CONFIG_USB_DWC_OTG_LPM
01314 if (gintsts.b.lpmtranrcvd) {
01315 retval |= dwc_otg_handle_lpm_intr(core_if);
01316 }
01317 #endif
01318 if (gintsts.b.restoredone) {
01319 gintsts.d32 = 0;
01320 if (core_if->power_down == 2)
01321 core_if->hibernation_suspend = -1;
01322 gintsts.b.restoredone = 1;
01323 DWC_WRITE_REG32(&core_if->core_global_regs->gintsts,gintsts.d32);
01324 DWC_PRINTF(" --Restore done interrupt received-- \n");
01325 retval |= 1;
01326 }
01327 if (gintsts.b.portintr && dwc_otg_is_device_mode(core_if)) {
01328
01329
01330
01331 gintsts.d32 = 0;
01332 gintsts.b.portintr = 1;
01333 DWC_WRITE_REG32(&core_if->core_global_regs->gintsts,gintsts.d32);
01334 retval |= 1;
01335
01336 }
01337 } else {
01338 DWC_DEBUGPL(DBG_ANY, "gpwrdn=%08x\n", gpwrdn.d32);
01339
01340 if (gpwrdn.b.disconn_det && gpwrdn.b.disconn_det_msk) {
01341 CLEAR_GPWRDN_INTR(core_if, disconn_det);
01342 if (gpwrdn.b.linestate == 0) {
01343 dwc_otg_handle_pwrdn_disconnect_intr(core_if);
01344 } else {
01345 DWC_PRINTF("Disconnect detected while linestate is not 0\n");
01346 }
01347
01348 retval |= 1;
01349 }
01350 if (gpwrdn.b.lnstschng && gpwrdn.b.lnstchng_msk) {
01351 CLEAR_GPWRDN_INTR(core_if, lnstschng);
01352
01353 if (gpwrdn.b.linestate == 2 || gpwrdn.b.linestate == 1) {
01354 dwc_otg_handle_pwrdn_wakeup_detected_intr(core_if);
01355 } else {
01356 DWC_PRINTF("gpwrdn.linestate = %d\n", gpwrdn.b.linestate);
01357 }
01358 retval |= 1;
01359 }
01360 if (gpwrdn.b.rst_det && gpwrdn.b.rst_det_msk) {
01361 CLEAR_GPWRDN_INTR(core_if, rst_det);
01362 if (gpwrdn.b.linestate == 0) {
01363 DWC_PRINTF("Reset detected\n");
01364 retval |= dwc_otg_device_hibernation_restore(core_if, 0, 1);
01365 }
01366 }
01367 if (gpwrdn.b.srp_det && gpwrdn.b.srp_det_msk) {
01368 CLEAR_GPWRDN_INTR(core_if, srp_det);
01369 dwc_otg_handle_pwrdn_srp_intr(core_if);
01370 retval |= 1;
01371 }
01372 }
01373
01374 if (gpwrdn.b.adp_int) {
01375 DWC_PRINTF("ADP interrupt\n");
01376 CLEAR_GPWRDN_INTR(core_if, adp_int);
01377 dwc_otg_adp_handle_intr(core_if);
01378 retval |= 1;
01379 }
01380 if (gpwrdn.b.sts_chngint && gpwrdn.b.sts_chngint_msk) {
01381 DWC_PRINTF("STS CHNG interrupt asserted\n");
01382 CLEAR_GPWRDN_INTR(core_if, sts_chngint);
01383 dwc_otg_handle_pwrdn_stschng_intr(otg_dev);
01384
01385 retval |= 1;
01386 }
01387 if (core_if->lock)
01388 DWC_SPINUNLOCK(core_if->lock);
01389
01390 return retval;
01391 }