LCOV - code coverage report
Current view: top level - drivers/usb/host/dwc_otg - dwc_otg_cil_intr.c (source / functions) Hit Total Coverage
Test: Real Lines: 61 656 9.3 %
Date: 2020-10-17 15:46:16 Functions: 1 19 5.3 %
Legend: Neither, QEMU, Real, Both Branches: 0 0 -

           Branch data     Line data    Source code
       1                 :            : /* ==========================================================================
       2                 :            :  * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_cil_intr.c $
       3                 :            :  * $Revision: #32 $
       4                 :            :  * $Date: 2012/08/10 $
       5                 :            :  * $Change: 2047372 $
       6                 :            :  *
       7                 :            :  * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
       8                 :            :  * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
       9                 :            :  * otherwise expressly agreed to in writing between Synopsys and you.
      10                 :            :  *
      11                 :            :  * The Software IS NOT an item of Licensed Software or Licensed Product under
      12                 :            :  * any End User Software License Agreement or Agreement for Licensed Product
      13                 :            :  * with Synopsys or any supplement thereto. You are permitted to use and
      14                 :            :  * redistribute this Software in source and binary forms, with or without
      15                 :            :  * modification, provided that redistributions of source code must retain this
      16                 :            :  * notice. You may not view, use, disclose, copy or distribute this file or
      17                 :            :  * any information contained herein except pursuant to this license grant from
      18                 :            :  * Synopsys. If you do not agree with this notice, including the disclaimer
      19                 :            :  * below, then you are not authorized to use the Software.
      20                 :            :  *
      21                 :            :  * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
      22                 :            :  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
      23                 :            :  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
      24                 :            :  * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
      25                 :            :  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
      26                 :            :  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
      27                 :            :  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
      28                 :            :  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
      29                 :            :  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
      30                 :            :  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
      31                 :            :  * DAMAGE.
      32                 :            :  * ========================================================================== */
      33                 :            : 
      34                 :            : /** @file
      35                 :            :  *
      36                 :            :  * The Core Interface Layer provides basic services for accessing and
      37                 :            :  * managing the DWC_otg hardware. These services are used by both the
      38                 :            :  * Host Controller Driver and the Peripheral Controller Driver.
      39                 :            :  *
      40                 :            :  * This file contains the Common Interrupt handlers.
      41                 :            :  */
      42                 :            : #include "dwc_os.h"
      43                 :            : #include "dwc_otg_regs.h"
      44                 :            : #include "dwc_otg_cil.h"
      45                 :            : #include "dwc_otg_driver.h"
      46                 :            : #include "dwc_otg_pcd.h"
      47                 :            : #include "dwc_otg_hcd.h"
      48                 :            : 
      49                 :            : #ifdef DEBUG
      50                 :            : inline const char *op_state_str(dwc_otg_core_if_t * core_if)
      51                 :            : {
      52                 :            :         return (core_if->op_state == A_HOST ? "a_host" :
      53                 :            :                 (core_if->op_state == A_SUSPEND ? "a_suspend" :
      54                 :            :                  (core_if->op_state == A_PERIPHERAL ? "a_peripheral" :
      55                 :            :                   (core_if->op_state == B_PERIPHERAL ? "b_peripheral" :
      56                 :            :                    (core_if->op_state == B_HOST ? "b_host" : "unknown")))));
      57                 :            : }
      58                 :            : #endif
      59                 :            : 
      60                 :            : /** This function will log a debug message
      61                 :            :  *
      62                 :            :  * @param core_if Programming view of DWC_otg controller.
      63                 :            :  */
      64                 :          0 : int32_t dwc_otg_handle_mode_mismatch_intr(dwc_otg_core_if_t * core_if)
      65                 :            : {
      66                 :            :         gintsts_data_t gintsts;
      67                 :          0 :         DWC_WARN("Mode Mismatch Interrupt: currently in %s mode\n",
      68                 :            :                  dwc_otg_mode(core_if) ? "Host" : "Device");
      69                 :            : 
      70                 :            :         /* Clear interrupt */
      71                 :          0 :         gintsts.d32 = 0;
      72                 :          0 :         gintsts.b.modemismatch = 1;
      73                 :          0 :         DWC_WRITE_REG32(&core_if->core_global_regs->gintsts, gintsts.d32);
      74                 :          0 :         return 1;
      75                 :            : }
      76                 :            : 
      77                 :            : /**
      78                 :            :  * This function handles the OTG Interrupts. It reads the OTG
      79                 :            :  * Interrupt Register (GOTGINT) to determine what interrupt has
      80                 :            :  * occurred.
      81                 :            :  *
      82                 :            :  * @param core_if Programming view of DWC_otg controller.
      83                 :            :  */
      84                 :          2 : int32_t dwc_otg_handle_otg_intr(dwc_otg_core_if_t * core_if)
      85                 :            : {
      86                 :          2 :         dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
      87                 :            :         gotgint_data_t gotgint;
      88                 :            :         gotgctl_data_t gotgctl;
      89                 :            :         gintmsk_data_t gintmsk;
      90                 :            :         gpwrdn_data_t gpwrdn;
      91                 :            : 
      92                 :          2 :         gotgint.d32 = DWC_READ_REG32(&global_regs->gotgint);
      93                 :          2 :         gotgctl.d32 = DWC_READ_REG32(&global_regs->gotgctl);
      94                 :            :         DWC_DEBUGPL(DBG_CIL, "++OTG Interrupt gotgint=%0x [%s]\n", gotgint.d32,
      95                 :            :                     op_state_str(core_if));
      96                 :            : 
      97                 :          2 :         if (gotgint.b.sesenddet) {
      98                 :            :                 DWC_DEBUGPL(DBG_ANY, " ++OTG Interrupt: "
      99                 :            :                             "Session End Detected++ (%s)\n",
     100                 :            :                             op_state_str(core_if));
     101                 :          0 :                 gotgctl.d32 = DWC_READ_REG32(&global_regs->gotgctl);
     102                 :            : 
     103                 :          0 :                 if (core_if->op_state == B_HOST) {
     104                 :            :                         cil_pcd_start(core_if);
     105                 :          0 :                         core_if->op_state = B_PERIPHERAL;
     106                 :            :                 } else {
     107                 :            :                         /* If not B_HOST and Device HNP still set. HNP
     108                 :            :                          * Did not succeed!*/
     109                 :          0 :                         if (gotgctl.b.devhnpen) {
     110                 :            :                                 DWC_DEBUGPL(DBG_ANY, "Session End Detected\n");
     111                 :          0 :                                 __DWC_ERROR("Device Not Connected/Responding!\n");
     112                 :            :                         }
     113                 :            : 
     114                 :            :                         /* If Session End Detected the B-Cable has
     115                 :            :                          * been disconnected. */
     116                 :            :                         /* Reset PCD and Gadget driver to a
     117                 :            :                          * clean state. */
     118                 :          0 :                         core_if->lx_state = DWC_OTG_L0;
     119                 :          0 :                         DWC_SPINUNLOCK(core_if->lock);
     120                 :            :                         cil_pcd_stop(core_if);
     121                 :          0 :                         DWC_SPINLOCK(core_if->lock);
     122                 :            : 
     123                 :          0 :                         if (core_if->adp_enable) {
     124                 :          0 :                                 if (core_if->power_down == 2) {
     125                 :          0 :                                         gpwrdn.d32 = 0;
     126                 :          0 :                                         gpwrdn.b.pwrdnswtch = 1;
     127                 :          0 :                                         DWC_MODIFY_REG32(&core_if->
     128                 :            :                                                          core_global_regs->
     129                 :            :                                                          gpwrdn, gpwrdn.d32, 0);
     130                 :            :                                 }
     131                 :            : 
     132                 :          0 :                                 gpwrdn.d32 = 0;
     133                 :          0 :                                 gpwrdn.b.pmuintsel = 1;
     134                 :          0 :                                 gpwrdn.b.pmuactv = 1;
     135                 :          0 :                                 DWC_MODIFY_REG32(&core_if->core_global_regs->
     136                 :            :                                                  gpwrdn, 0, gpwrdn.d32);
     137                 :            : 
     138                 :          0 :                                 dwc_otg_adp_sense_start(core_if);
     139                 :            :                         }
     140                 :            :                 }
     141                 :            : 
     142                 :          0 :                 gotgctl.d32 = 0;
     143                 :          0 :                 gotgctl.b.devhnpen = 1;
     144                 :          0 :                 DWC_MODIFY_REG32(&global_regs->gotgctl, gotgctl.d32, 0);
     145                 :            :         }
     146                 :          2 :         if (gotgint.b.sesreqsucstschng) {
     147                 :            :                 DWC_DEBUGPL(DBG_ANY, " ++OTG Interrupt: "
     148                 :            :                             "Session Reqeust Success Status Change++\n");
     149                 :          0 :                 gotgctl.d32 = DWC_READ_REG32(&global_regs->gotgctl);
     150                 :          0 :                 if (gotgctl.b.sesreqscs) {
     151                 :            : 
     152                 :          0 :                         if ((core_if->core_params->phy_type ==
     153                 :          0 :                              DWC_PHY_TYPE_PARAM_FS) && (core_if->core_params->i2c_enable)) {
     154                 :          0 :                                 core_if->srp_success = 1;
     155                 :            :                         } else {
     156                 :          0 :                                 DWC_SPINUNLOCK(core_if->lock);
     157                 :            :                                 cil_pcd_resume(core_if);
     158                 :          0 :                                 DWC_SPINLOCK(core_if->lock);
     159                 :            :                                 /* Clear Session Request */
     160                 :          0 :                                 gotgctl.d32 = 0;
     161                 :          0 :                                 gotgctl.b.sesreq = 1;
     162                 :          0 :                                 DWC_MODIFY_REG32(&global_regs->gotgctl,
     163                 :            :                                                  gotgctl.d32, 0);
     164                 :            :                         }
     165                 :            :                 }
     166                 :            :         }
     167                 :          2 :         if (gotgint.b.hstnegsucstschng) {
     168                 :            :                 /* Print statements during the HNP interrupt handling
     169                 :            :                  * can cause it to fail.*/
     170                 :          0 :                 gotgctl.d32 = DWC_READ_REG32(&global_regs->gotgctl);
     171                 :            :                 /* WA for 3.00a- HW is not setting cur_mode, even sometimes
     172                 :            :                  * this does not help*/
     173                 :          0 :                 if (core_if->snpsid >= OTG_CORE_REV_3_00a)
     174                 :          0 :                         dwc_udelay(100);
     175                 :          0 :                 if (gotgctl.b.hstnegscs) {
     176                 :          0 :                         if (dwc_otg_is_host_mode(core_if)) {
     177                 :          0 :                                 core_if->op_state = B_HOST;
     178                 :            :                                 /*
     179                 :            :                                  * Need to disable SOF interrupt immediately.
     180                 :            :                                  * When switching from device to host, the PCD
     181                 :            :                                  * interrupt handler won't handle the
     182                 :            :                                  * interrupt if host mode is already set. The
     183                 :            :                                  * HCD interrupt handler won't get called if
     184                 :            :                                  * the HCD state is HALT. This means that the
     185                 :            :                                  * interrupt does not get handled and Linux
     186                 :            :                                  * complains loudly.
     187                 :            :                                  */
     188                 :          0 :                                 gintmsk.d32 = 0;
     189                 :          0 :                                 gintmsk.b.sofintr = 1;
     190                 :          0 :                                 DWC_MODIFY_REG32(&global_regs->gintmsk,
     191                 :            :                                                  gintmsk.d32, 0);
     192                 :            :                                 /* Call callback function with spin lock released */
     193                 :          0 :                                 DWC_SPINUNLOCK(core_if->lock);
     194                 :            :                                 cil_pcd_stop(core_if);
     195                 :            :                                 /*
     196                 :            :                                  * Initialize the Core for Host mode.
     197                 :            :                                  */
     198                 :            :                                 cil_hcd_start(core_if);
     199                 :          0 :                                 DWC_SPINLOCK(core_if->lock);
     200                 :          0 :                                 core_if->op_state = B_HOST;
     201                 :            :                         }
     202                 :            :                 } else {
     203                 :          0 :                         gotgctl.d32 = 0;
     204                 :          0 :                         gotgctl.b.hnpreq = 1;
     205                 :          0 :                         gotgctl.b.devhnpen = 1;
     206                 :          0 :                         DWC_MODIFY_REG32(&global_regs->gotgctl, gotgctl.d32, 0);
     207                 :            :                         DWC_DEBUGPL(DBG_ANY, "HNP Failed\n");
     208                 :          0 :                         __DWC_ERROR("Device Not Connected/Responding\n");
     209                 :            :                 }
     210                 :            :         }
     211                 :          2 :         if (gotgint.b.hstnegdet) {
     212                 :            :                 /* The disconnect interrupt is set at the same time as
     213                 :            :                  * Host Negotiation Detected.  During the mode
     214                 :            :                  * switch all interrupts are cleared so the disconnect
     215                 :            :                  * interrupt handler will not get executed.
     216                 :            :                  */
     217                 :            :                 DWC_DEBUGPL(DBG_ANY, " ++OTG Interrupt: "
     218                 :            :                             "Host Negotiation Detected++ (%s)\n",
     219                 :            :                             (dwc_otg_is_host_mode(core_if) ? "Host" :
     220                 :            :                              "Device"));
     221                 :          0 :                 if (dwc_otg_is_device_mode(core_if)) {
     222                 :            :                         DWC_DEBUGPL(DBG_ANY, "a_suspend->a_peripheral (%d)\n",
     223                 :            :                                     core_if->op_state);
     224                 :          0 :                         DWC_SPINUNLOCK(core_if->lock);
     225                 :            :                         cil_hcd_disconnect(core_if);
     226                 :            :                         cil_pcd_start(core_if);
     227                 :          0 :                         DWC_SPINLOCK(core_if->lock);
     228                 :          0 :                         core_if->op_state = A_PERIPHERAL;
     229                 :            :                 } else {
     230                 :            :                         /*
     231                 :            :                          * Need to disable SOF interrupt immediately. When
     232                 :            :                          * switching from device to host, the PCD interrupt
     233                 :            :                          * handler won't handle the interrupt if host mode is
     234                 :            :                          * already set. The HCD interrupt handler won't get
     235                 :            :                          * called if the HCD state is HALT. This means that
     236                 :            :                          * the interrupt does not get handled and Linux
     237                 :            :                          * complains loudly.
     238                 :            :                          */
     239                 :          0 :                         gintmsk.d32 = 0;
     240                 :          0 :                         gintmsk.b.sofintr = 1;
     241                 :          0 :                         DWC_MODIFY_REG32(&global_regs->gintmsk, gintmsk.d32, 0);
     242                 :          0 :                         DWC_SPINUNLOCK(core_if->lock);
     243                 :            :                         cil_pcd_stop(core_if);
     244                 :            :                         cil_hcd_start(core_if);
     245                 :          0 :                         DWC_SPINLOCK(core_if->lock);
     246                 :          0 :                         core_if->op_state = A_HOST;
     247                 :            :                 }
     248                 :            :         }
     249                 :            :         if (gotgint.b.adevtoutchng) {
     250                 :            :                 DWC_DEBUGPL(DBG_ANY, " ++OTG Interrupt: "
     251                 :            :                             "A-Device Timeout Change++\n");
     252                 :            :         }
     253                 :            :         if (gotgint.b.debdone) {
     254                 :            :                 DWC_DEBUGPL(DBG_ANY, " ++OTG Interrupt: " "Debounce Done++\n");
     255                 :            :         }
     256                 :            : 
     257                 :            :         /* Clear GOTGINT */
     258                 :          2 :         DWC_WRITE_REG32(&core_if->core_global_regs->gotgint, gotgint.d32);
     259                 :            : 
     260                 :          2 :         return 1;
     261                 :            : }
     262                 :            : 
     263                 :          0 : void w_conn_id_status_change(void *p)
     264                 :            : {
     265                 :            :         dwc_otg_core_if_t *core_if = p;
     266                 :            :         uint32_t count = 0;
     267                 :            :         gotgctl_data_t gotgctl = {.d32 = 0 };
     268                 :            : 
     269                 :          0 :         gotgctl.d32 = DWC_READ_REG32(&core_if->core_global_regs->gotgctl);
     270                 :            :         DWC_DEBUGPL(DBG_CIL, "gotgctl=%0x\n", gotgctl.d32);
     271                 :            :         DWC_DEBUGPL(DBG_CIL, "gotgctl.b.conidsts=%d\n", gotgctl.b.conidsts);
     272                 :            : 
     273                 :            :         /* B-Device connector (Device Mode) */
     274                 :          0 :         if (gotgctl.b.conidsts) {
     275                 :            :                 /* Wait for switch to device mode. */
     276                 :          0 :                 while (!dwc_otg_is_device_mode(core_if)) {
     277                 :          0 :                         DWC_PRINTF("Waiting for Peripheral Mode, Mode=%s\n",
     278                 :          0 :                                    (dwc_otg_is_host_mode(core_if) ? "Host" :
     279                 :            :                                     "Peripheral"));
     280                 :          0 :                         dwc_mdelay(100);
     281                 :          0 :                         if (++count > 10000)
     282                 :            :                                 break;
     283                 :            :                 }
     284                 :            :                 DWC_ASSERT(++count < 10000,
     285                 :            :                            "Connection id status change timed out");
     286                 :          0 :                 core_if->op_state = B_PERIPHERAL;
     287                 :          0 :                 dwc_otg_core_init(core_if);
     288                 :          0 :                 dwc_otg_enable_global_interrupts(core_if);
     289                 :            :                 cil_pcd_start(core_if);
     290                 :            :         } else {
     291                 :            :                 /* A-Device connector (Host Mode) */
     292                 :          0 :                 while (!dwc_otg_is_host_mode(core_if)) {
     293                 :          0 :                         DWC_PRINTF("Waiting for Host Mode, Mode=%s\n",
     294                 :          0 :                                    (dwc_otg_is_host_mode(core_if) ? "Host" :
     295                 :            :                                     "Peripheral"));
     296                 :          0 :                         dwc_mdelay(100);
     297                 :          0 :                         if (++count > 10000)
     298                 :            :                                 break;
     299                 :            :                 }
     300                 :            :                 DWC_ASSERT(++count < 10000,
     301                 :            :                            "Connection id status change timed out");
     302                 :          0 :                 core_if->op_state = A_HOST;
     303                 :            :                 /*
     304                 :            :                  * Initialize the Core for Host mode.
     305                 :            :                  */
     306                 :          0 :                 dwc_otg_core_init(core_if);
     307                 :          0 :                 dwc_otg_enable_global_interrupts(core_if);
     308                 :            :                 cil_hcd_start(core_if);
     309                 :            :         }
     310                 :          0 : }
     311                 :            : 
     312                 :            : /**
     313                 :            :  * This function handles the Connector ID Status Change Interrupt.  It
     314                 :            :  * reads the OTG Interrupt Register (GOTCTL) to determine whether this
     315                 :            :  * is a Device to Host Mode transition or a Host Mode to Device
     316                 :            :  * Transition.
     317                 :            :  *
     318                 :            :  * This only occurs when the cable is connected/removed from the PHY
     319                 :            :  * connector.
     320                 :            :  *
     321                 :            :  * @param core_if Programming view of DWC_otg controller.
     322                 :            :  */
     323                 :          0 : int32_t dwc_otg_handle_conn_id_status_change_intr(dwc_otg_core_if_t * core_if)
     324                 :            : {
     325                 :            : 
     326                 :            :         /*
     327                 :            :          * Need to disable SOF interrupt immediately. If switching from device
     328                 :            :          * to host, the PCD interrupt handler won't handle the interrupt if
     329                 :            :          * host mode is already set. The HCD interrupt handler won't get
     330                 :            :          * called if the HCD state is HALT. This means that the interrupt does
     331                 :            :          * not get handled and Linux complains loudly.
     332                 :            :          */
     333                 :          0 :         gintmsk_data_t gintmsk = {.d32 = 0 };
     334                 :          0 :         gintsts_data_t gintsts = {.d32 = 0 };
     335                 :            : 
     336                 :          0 :         gintmsk.b.sofintr = 1;
     337                 :          0 :         DWC_MODIFY_REG32(&core_if->core_global_regs->gintmsk, gintmsk.d32, 0);
     338                 :            : 
     339                 :            :         DWC_DEBUGPL(DBG_CIL,
     340                 :            :                     " ++Connector ID Status Change Interrupt++  (%s)\n",
     341                 :            :                     (dwc_otg_is_host_mode(core_if) ? "Host" : "Device"));
     342                 :            : 
     343                 :          0 :         DWC_SPINUNLOCK(core_if->lock);
     344                 :            : 
     345                 :            :         /*
     346                 :            :          * Need to schedule a work, as there are possible DELAY function calls
     347                 :            :          * Release lock before scheduling workq as it holds spinlock during scheduling
     348                 :            :          */
     349                 :            : 
     350                 :          0 :         DWC_WORKQ_SCHEDULE(core_if->wq_otg, w_conn_id_status_change,
     351                 :            :                            core_if, "connection id status change");
     352                 :          0 :         DWC_SPINLOCK(core_if->lock);
     353                 :            : 
     354                 :            :         /* Set flag and clear interrupt */
     355                 :          0 :         gintsts.b.conidstschng = 1;
     356                 :          0 :         DWC_WRITE_REG32(&core_if->core_global_regs->gintsts, gintsts.d32);
     357                 :            : 
     358                 :          0 :         return 1;
     359                 :            : }
     360                 :            : 
     361                 :            : /**
     362                 :            :  * This interrupt indicates that a device is initiating the Session
     363                 :            :  * Request Protocol to request the host to turn on bus power so a new
     364                 :            :  * session can begin. The handler responds by turning on bus power. If
     365                 :            :  * the DWC_otg controller is in low power mode, the handler brings the
     366                 :            :  * controller out of low power mode before turning on bus power.
     367                 :            :  *
     368                 :            :  * @param core_if Programming view of DWC_otg controller.
     369                 :            :  */
     370                 :          0 : int32_t dwc_otg_handle_session_req_intr(dwc_otg_core_if_t * core_if)
     371                 :            : {
     372                 :            :         gintsts_data_t gintsts;
     373                 :            : 
     374                 :            : #ifndef DWC_HOST_ONLY
     375                 :            :         DWC_DEBUGPL(DBG_ANY, "++Session Request Interrupt++\n");
     376                 :            : 
     377                 :          0 :         if (dwc_otg_is_device_mode(core_if)) {
     378                 :          0 :                 DWC_PRINTF("SRP: Device mode\n");
     379                 :            :         } else {
     380                 :            :                 hprt0_data_t hprt0;
     381                 :          0 :                 DWC_PRINTF("SRP: Host mode\n");
     382                 :            : 
     383                 :            :                 /* Turn on the port power bit. */
     384                 :          0 :                 hprt0.d32 = dwc_otg_read_hprt0(core_if);
     385                 :          0 :                 hprt0.b.prtpwr = 1;
     386                 :          0 :                 DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32);
     387                 :            : 
     388                 :            :                 /* Start the Connection timer. So a message can be displayed
     389                 :            :                  * if connect does not occur within 10 seconds. */
     390                 :            :                 cil_hcd_session_start(core_if);
     391                 :            :         }
     392                 :            : #endif
     393                 :            : 
     394                 :            :         /* Clear interrupt */
     395                 :          0 :         gintsts.d32 = 0;
     396                 :          0 :         gintsts.b.sessreqintr = 1;
     397                 :          0 :         DWC_WRITE_REG32(&core_if->core_global_regs->gintsts, gintsts.d32);
     398                 :            : 
     399                 :          0 :         return 1;
     400                 :            : }
     401                 :            : 
     402                 :          0 : void w_wakeup_detected(void *p)
     403                 :            : {
     404                 :            :         dwc_otg_core_if_t *core_if = (dwc_otg_core_if_t *) p;
     405                 :            :         /*
     406                 :            :          * Clear the Resume after 70ms. (Need 20 ms minimum. Use 70 ms
     407                 :            :          * so that OPT tests pass with all PHYs).
     408                 :            :          */
     409                 :            :         hprt0_data_t hprt0 = {.d32 = 0 };
     410                 :            : #if 0
     411                 :            :         pcgcctl_data_t pcgcctl = {.d32 = 0 };
     412                 :            :         /* Restart the Phy Clock */
     413                 :            :         pcgcctl.b.stoppclk = 1;
     414                 :            :         DWC_MODIFY_REG32(core_if->pcgcctl, pcgcctl.d32, 0);
     415                 :            :         dwc_udelay(10);
     416                 :            : #endif //0
     417                 :          0 :         hprt0.d32 = dwc_otg_read_hprt0(core_if);
     418                 :            :         DWC_DEBUGPL(DBG_ANY, "Resume: HPRT0=%0x\n", hprt0.d32);
     419                 :            : //      dwc_mdelay(70);
     420                 :          0 :         hprt0.b.prtres = 0;     /* Resume */
     421                 :          0 :         DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32);
     422                 :            :         DWC_DEBUGPL(DBG_ANY, "Clear Resume: HPRT0=%0x\n",
     423                 :            :                     DWC_READ_REG32(core_if->host_if->hprt0));
     424                 :            : 
     425                 :            :         cil_hcd_resume(core_if);
     426                 :            : 
     427                 :            :         /** Change to L0 state*/
     428                 :          0 :         core_if->lx_state = DWC_OTG_L0;
     429                 :          0 : }
     430                 :            : 
     431                 :            : /**
     432                 :            :  * This interrupt indicates that the DWC_otg controller has detected a
     433                 :            :  * resume or remote wakeup sequence. If the DWC_otg controller is in
     434                 :            :  * low power mode, the handler must brings the controller out of low
     435                 :            :  * power mode. The controller automatically begins resume
     436                 :            :  * signaling. The handler schedules a time to stop resume signaling.
     437                 :            :  */
     438                 :          0 : int32_t dwc_otg_handle_wakeup_detected_intr(dwc_otg_core_if_t * core_if)
     439                 :            : {
     440                 :            :         gintsts_data_t gintsts;
     441                 :            : 
     442                 :            :         DWC_DEBUGPL(DBG_ANY,
     443                 :            :                     "++Resume and Remote Wakeup Detected Interrupt++\n");
     444                 :            : 
     445                 :          0 :         DWC_PRINTF("%s lxstate = %d\n", __func__, core_if->lx_state);
     446                 :            : 
     447                 :          0 :         if (dwc_otg_is_device_mode(core_if)) {
     448                 :          0 :                 dctl_data_t dctl = {.d32 = 0 };
     449                 :            :                 DWC_DEBUGPL(DBG_PCD, "DSTS=0x%0x\n",
     450                 :            :                             DWC_READ_REG32(&core_if->dev_if->dev_global_regs->
     451                 :            :                                            dsts));
     452                 :          0 :                 if (core_if->lx_state == DWC_OTG_L2) {
     453                 :            : #ifdef PARTIAL_POWER_DOWN
     454                 :            :                         if (core_if->hwcfg4.b.power_optimiz) {
     455                 :            :                                 pcgcctl_data_t power = {.d32 = 0 };
     456                 :            : 
     457                 :            :                                 power.d32 = DWC_READ_REG32(core_if->pcgcctl);
     458                 :            :                                 DWC_DEBUGPL(DBG_CIL, "PCGCCTL=%0x\n",
     459                 :            :                                             power.d32);
     460                 :            : 
     461                 :            :                                 power.b.stoppclk = 0;
     462                 :            :                                 DWC_WRITE_REG32(core_if->pcgcctl, power.d32);
     463                 :            : 
     464                 :            :                                 power.b.pwrclmp = 0;
     465                 :            :                                 DWC_WRITE_REG32(core_if->pcgcctl, power.d32);
     466                 :            : 
     467                 :            :                                 power.b.rstpdwnmodule = 0;
     468                 :            :                                 DWC_WRITE_REG32(core_if->pcgcctl, power.d32);
     469                 :            :                         }
     470                 :            : #endif
     471                 :            :                         /* Clear the Remote Wakeup Signaling */
     472                 :          0 :                         dctl.b.rmtwkupsig = 1;
     473                 :          0 :                         DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->
     474                 :            :                                          dctl, dctl.d32, 0);
     475                 :            : 
     476                 :          0 :                         DWC_SPINUNLOCK(core_if->lock);
     477                 :          0 :                         if (core_if->pcd_cb && core_if->pcd_cb->resume_wakeup) {
     478                 :          0 :                                 core_if->pcd_cb->resume_wakeup(core_if->pcd_cb->p);
     479                 :            :                         }
     480                 :          0 :                         DWC_SPINLOCK(core_if->lock);
     481                 :            :                 } else {
     482                 :            :                         glpmcfg_data_t lpmcfg;
     483                 :          0 :                         lpmcfg.d32 =
     484                 :          0 :                             DWC_READ_REG32(&core_if->core_global_regs->glpmcfg);
     485                 :          0 :                         lpmcfg.b.hird_thres &= (~(1 << 4));
     486                 :          0 :                         DWC_WRITE_REG32(&core_if->core_global_regs->glpmcfg,
     487                 :            :                                         lpmcfg.d32);
     488                 :            :                 }
     489                 :            :                 /** Change to L0 state*/
     490                 :          0 :                 core_if->lx_state = DWC_OTG_L0;
     491                 :            :         } else {
     492                 :          0 :                 if (core_if->lx_state != DWC_OTG_L1) {
     493                 :          0 :                         pcgcctl_data_t pcgcctl = {.d32 = 0 };
     494                 :            : 
     495                 :            :                         /* Restart the Phy Clock */
     496                 :          0 :                         pcgcctl.b.stoppclk = 1;
     497                 :          0 :                         DWC_MODIFY_REG32(core_if->pcgcctl, pcgcctl.d32, 0);
     498                 :          0 :                         DWC_TIMER_SCHEDULE(core_if->wkp_timer, 71);
     499                 :            :                 } else {
     500                 :            :                         /** Change to L0 state*/
     501                 :          0 :                         core_if->lx_state = DWC_OTG_L0;
     502                 :            :                 }
     503                 :            :         }
     504                 :            : 
     505                 :            :         /* Clear interrupt */
     506                 :          0 :         gintsts.d32 = 0;
     507                 :          0 :         gintsts.b.wkupintr = 1;
     508                 :          0 :         DWC_WRITE_REG32(&core_if->core_global_regs->gintsts, gintsts.d32);
     509                 :            : 
     510                 :          0 :         return 1;
     511                 :            : }
     512                 :            : 
     513                 :            : /**
     514                 :            :  * This interrupt indicates that the Wakeup Logic has detected a
     515                 :            :  * Device disconnect.
     516                 :            :  */
     517                 :          0 : static int32_t dwc_otg_handle_pwrdn_disconnect_intr(dwc_otg_core_if_t *core_if)
     518                 :            : {
     519                 :          0 :         gpwrdn_data_t gpwrdn = { .d32 = 0 };
     520                 :            :         gpwrdn_data_t gpwrdn_temp = { .d32 = 0 };
     521                 :          0 :         gpwrdn_temp.d32 = DWC_READ_REG32(&core_if->core_global_regs->gpwrdn);
     522                 :            : 
     523                 :          0 :         DWC_PRINTF("%s called\n", __FUNCTION__);
     524                 :            : 
     525                 :          0 :         if (!core_if->hibernation_suspend) {
     526                 :          0 :                 DWC_PRINTF("Already exited from Hibernation\n");
     527                 :          0 :                 return 1;
     528                 :            :         }
     529                 :            : 
     530                 :            :         /* Switch on the voltage to the core */
     531                 :          0 :         gpwrdn.b.pwrdnswtch = 1;
     532                 :          0 :         DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
     533                 :          0 :         dwc_udelay(10);
     534                 :            : 
     535                 :            :         /* Reset the core */
     536                 :          0 :         gpwrdn.d32 = 0;
     537                 :          0 :         gpwrdn.b.pwrdnrstn = 1;
     538                 :          0 :         DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
     539                 :          0 :         dwc_udelay(10);
     540                 :            : 
     541                 :            :         /* Disable power clamps*/
     542                 :          0 :         gpwrdn.d32 = 0;
     543                 :          0 :         gpwrdn.b.pwrdnclmp = 1;
     544                 :          0 :         DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
     545                 :            : 
     546                 :            :         /* Remove reset the core signal */
     547                 :          0 :         gpwrdn.d32 = 0;
     548                 :          0 :         gpwrdn.b.pwrdnrstn = 1;
     549                 :          0 :         DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, 0, gpwrdn.d32);
     550                 :          0 :         dwc_udelay(10);
     551                 :            : 
     552                 :            :         /* Disable PMU interrupt */
     553                 :          0 :         gpwrdn.d32 = 0;
     554                 :          0 :         gpwrdn.b.pmuintsel = 1;
     555                 :          0 :         DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
     556                 :            : 
     557                 :          0 :         core_if->hibernation_suspend = 0;
     558                 :            : 
     559                 :            :         /* Disable PMU */
     560                 :          0 :         gpwrdn.d32 = 0;
     561                 :          0 :         gpwrdn.b.pmuactv = 1;
     562                 :          0 :         DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
     563                 :          0 :         dwc_udelay(10);
     564                 :            : 
     565                 :          0 :         if (gpwrdn_temp.b.idsts) {
     566                 :          0 :                 core_if->op_state = B_PERIPHERAL;
     567                 :          0 :                 dwc_otg_core_init(core_if);
     568                 :          0 :                 dwc_otg_enable_global_interrupts(core_if);
     569                 :            :                 cil_pcd_start(core_if);
     570                 :            :         } else {
     571                 :          0 :                 core_if->op_state = A_HOST;
     572                 :          0 :                 dwc_otg_core_init(core_if);
     573                 :          0 :                 dwc_otg_enable_global_interrupts(core_if);
     574                 :            :                 cil_hcd_start(core_if);
     575                 :            :         }
     576                 :            : 
     577                 :            :         return 1;
     578                 :            : }
     579                 :            : 
     580                 :            : /**
     581                 :            :  * This interrupt indicates that the Wakeup Logic has detected a
     582                 :            :  * remote wakeup sequence.
     583                 :            :  */
     584                 :          0 : static int32_t dwc_otg_handle_pwrdn_wakeup_detected_intr(dwc_otg_core_if_t * core_if)
     585                 :            : {
     586                 :            :         gpwrdn_data_t gpwrdn = {.d32 = 0 };
     587                 :            :         DWC_DEBUGPL(DBG_ANY,
     588                 :            :                     "++Powerdown Remote Wakeup Detected Interrupt++\n");
     589                 :            : 
     590                 :          0 :         if (!core_if->hibernation_suspend) {
     591                 :          0 :                 DWC_PRINTF("Already exited from Hibernation\n");
     592                 :          0 :                 return 1;
     593                 :            :         }
     594                 :            : 
     595                 :          0 :         gpwrdn.d32 = DWC_READ_REG32(&core_if->core_global_regs->gpwrdn);
     596                 :          0 :         if (gpwrdn.b.idsts) {   // Device Mode
     597                 :          0 :                 if ((core_if->power_down == 2)
     598                 :          0 :                     && (core_if->hibernation_suspend == 1)) {
     599                 :          0 :                         dwc_otg_device_hibernation_restore(core_if, 0, 0);
     600                 :            :                 }
     601                 :            :         } else {
     602                 :          0 :                 if ((core_if->power_down == 2)
     603                 :          0 :                     && (core_if->hibernation_suspend == 1)) {
     604                 :          0 :                         dwc_otg_host_hibernation_restore(core_if, 1, 0);
     605                 :            :                 }
     606                 :            :         }
     607                 :            :         return 1;
     608                 :            : }
     609                 :            : 
     610                 :          0 : static int32_t dwc_otg_handle_pwrdn_idsts_change(dwc_otg_device_t *otg_dev)
     611                 :            : {
     612                 :          0 :         gpwrdn_data_t gpwrdn = {.d32 = 0 };
     613                 :            :         gpwrdn_data_t gpwrdn_temp = {.d32 = 0 };
     614                 :          0 :         dwc_otg_core_if_t *core_if = otg_dev->core_if;
     615                 :            : 
     616                 :            :         DWC_DEBUGPL(DBG_ANY, "%s called\n", __FUNCTION__);
     617                 :          0 :         gpwrdn_temp.d32 = DWC_READ_REG32(&core_if->core_global_regs->gpwrdn);
     618                 :          0 :         if (core_if->power_down == 2) {
     619                 :          0 :                 if (!core_if->hibernation_suspend) {
     620                 :          0 :                         DWC_PRINTF("Already exited from Hibernation\n");
     621                 :          0 :                         return 1;
     622                 :            :                 }
     623                 :            :                 DWC_DEBUGPL(DBG_ANY, "Exit from hibernation on ID sts change\n");
     624                 :            :                 /* Switch on the voltage to the core */
     625                 :          0 :                 gpwrdn.b.pwrdnswtch = 1;
     626                 :          0 :                 DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
     627                 :          0 :                 dwc_udelay(10);
     628                 :            : 
     629                 :            :                 /* Reset the core */
     630                 :          0 :                 gpwrdn.d32 = 0;
     631                 :          0 :                 gpwrdn.b.pwrdnrstn = 1;
     632                 :          0 :                 DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
     633                 :          0 :                 dwc_udelay(10);
     634                 :            : 
     635                 :            :                 /* Disable power clamps */
     636                 :          0 :                 gpwrdn.d32 = 0;
     637                 :          0 :                 gpwrdn.b.pwrdnclmp = 1;
     638                 :          0 :                 DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
     639                 :            : 
     640                 :            :                 /* Remove reset the core signal */
     641                 :          0 :                 gpwrdn.d32 = 0;
     642                 :          0 :                 gpwrdn.b.pwrdnrstn = 1;
     643                 :          0 :                 DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, 0, gpwrdn.d32);
     644                 :          0 :                 dwc_udelay(10);
     645                 :            : 
     646                 :            :                 /* Disable PMU interrupt */
     647                 :          0 :                 gpwrdn.d32 = 0;
     648                 :          0 :                 gpwrdn.b.pmuintsel = 1;
     649                 :          0 :                 DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
     650                 :            : 
     651                 :            :                 /*Indicates that we are exiting from hibernation */
     652                 :          0 :                 core_if->hibernation_suspend = 0;
     653                 :            : 
     654                 :            :                 /* Disable PMU */
     655                 :          0 :                 gpwrdn.d32 = 0;
     656                 :          0 :                 gpwrdn.b.pmuactv = 1;
     657                 :          0 :                 DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
     658                 :          0 :                 dwc_udelay(10);
     659                 :            : 
     660                 :          0 :                 gpwrdn.d32 = core_if->gr_backup->gpwrdn_local;
     661                 :          0 :                 if (gpwrdn.b.dis_vbus == 1) {
     662                 :          0 :                         gpwrdn.d32 = 0;
     663                 :          0 :                         gpwrdn.b.dis_vbus = 1;
     664                 :          0 :                         DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
     665                 :            :                 }
     666                 :            : 
     667                 :          0 :                 if (gpwrdn_temp.b.idsts) {
     668                 :          0 :                         core_if->op_state = B_PERIPHERAL;
     669                 :          0 :                         dwc_otg_core_init(core_if);
     670                 :          0 :                         dwc_otg_enable_global_interrupts(core_if);
     671                 :            :                         cil_pcd_start(core_if);
     672                 :            :                 } else {
     673                 :          0 :                         core_if->op_state = A_HOST;
     674                 :          0 :                         dwc_otg_core_init(core_if);
     675                 :          0 :                         dwc_otg_enable_global_interrupts(core_if);
     676                 :            :                         cil_hcd_start(core_if);
     677                 :            :                 }
     678                 :            :         }
     679                 :            : 
     680                 :          0 :         if (core_if->adp_enable) {
     681                 :            :                 uint8_t is_host = 0;
     682                 :          0 :                 DWC_SPINUNLOCK(core_if->lock);
     683                 :            :                 /* Change the core_if's lock to hcd/pcd lock depend on mode? */
     684                 :            : #ifndef DWC_HOST_ONLY
     685                 :          0 :                 if (gpwrdn_temp.b.idsts)
     686                 :          0 :                         core_if->lock = otg_dev->pcd->lock;
     687                 :            : #endif
     688                 :            : #ifndef DWC_DEVICE_ONLY
     689                 :          0 :                 if (!gpwrdn_temp.b.idsts) {
     690                 :          0 :                                 core_if->lock = otg_dev->hcd->lock;
     691                 :            :                                 is_host = 1;
     692                 :            :                 }
     693                 :            : #endif
     694                 :          0 :                 DWC_PRINTF("RESTART ADP\n");
     695                 :          0 :                 if (core_if->adp.probe_enabled)
     696                 :          0 :                         dwc_otg_adp_probe_stop(core_if);
     697                 :          0 :                 if (core_if->adp.sense_enabled)
     698                 :          0 :                         dwc_otg_adp_sense_stop(core_if);
     699                 :          0 :                 if (core_if->adp.sense_timer_started)
     700                 :          0 :                         DWC_TIMER_CANCEL(core_if->adp.sense_timer);
     701                 :          0 :                 if (core_if->adp.vbuson_timer_started)
     702                 :          0 :                         DWC_TIMER_CANCEL(core_if->adp.vbuson_timer);
     703                 :          0 :                 core_if->adp.probe_timer_values[0] = -1;
     704                 :          0 :                 core_if->adp.probe_timer_values[1] = -1;
     705                 :          0 :                 core_if->adp.sense_timer_started = 0;
     706                 :          0 :                 core_if->adp.vbuson_timer_started = 0;
     707                 :          0 :                 core_if->adp.probe_counter = 0;
     708                 :          0 :                 core_if->adp.gpwrdn = 0;
     709                 :            : 
     710                 :            :                 /* Disable PMU and restart ADP */
     711                 :            :                 gpwrdn_temp.d32 = 0;
     712                 :            :                 gpwrdn_temp.b.pmuactv = 1;
     713                 :            :                 gpwrdn_temp.b.pmuintsel = 1;
     714                 :          0 :                 DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
     715                 :          0 :                 DWC_PRINTF("Check point 1\n");
     716                 :          0 :                 dwc_mdelay(110);
     717                 :          0 :                 dwc_otg_adp_start(core_if, is_host);
     718                 :          0 :                 DWC_SPINLOCK(core_if->lock);
     719                 :            :         }
     720                 :            : 
     721                 :            : 
     722                 :            :         return 1;
     723                 :            : }
     724                 :            : 
     725                 :          0 : static int32_t dwc_otg_handle_pwrdn_session_change(dwc_otg_core_if_t * core_if)
     726                 :            : {
     727                 :            :         gpwrdn_data_t gpwrdn = {.d32 = 0 };
     728                 :          0 :         int32_t otg_cap_param = core_if->core_params->otg_cap;
     729                 :            :         DWC_DEBUGPL(DBG_ANY, "%s called\n", __FUNCTION__);
     730                 :            : 
     731                 :          0 :         gpwrdn.d32 = DWC_READ_REG32(&core_if->core_global_regs->gpwrdn);
     732                 :          0 :         if (core_if->power_down == 2) {
     733                 :          0 :                 if (!core_if->hibernation_suspend) {
     734                 :          0 :                         DWC_PRINTF("Already exited from Hibernation\n");
     735                 :          0 :                         return 1;
     736                 :            :                 }
     737                 :            : 
     738                 :          0 :                 if ((otg_cap_param != DWC_OTG_CAP_PARAM_HNP_SRP_CAPABLE ||
     739                 :          0 :                          otg_cap_param != DWC_OTG_CAP_PARAM_SRP_ONLY_CAPABLE) &&
     740                 :          0 :                         gpwrdn.b.bsessvld == 0) {
     741                 :            :                         /* Save gpwrdn register for further usage if stschng interrupt */
     742                 :          0 :                         core_if->gr_backup->gpwrdn_local =
     743                 :          0 :                                 DWC_READ_REG32(&core_if->core_global_regs->gpwrdn);
     744                 :            :                         /*Exit from ISR and wait for stschng interrupt with bsessvld = 1 */
     745                 :          0 :                         return 1;
     746                 :            :                 }
     747                 :            : 
     748                 :            :                 /* Switch on the voltage to the core */
     749                 :          0 :                 gpwrdn.d32 = 0;
     750                 :          0 :                 gpwrdn.b.pwrdnswtch = 1;
     751                 :          0 :                 DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
     752                 :          0 :                 dwc_udelay(10);
     753                 :            : 
     754                 :            :                 /* Reset the core */
     755                 :          0 :                 gpwrdn.d32 = 0;
     756                 :          0 :                 gpwrdn.b.pwrdnrstn = 1;
     757                 :          0 :                 DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
     758                 :          0 :                 dwc_udelay(10);
     759                 :            : 
     760                 :            :                 /* Disable power clamps */
     761                 :          0 :                 gpwrdn.d32 = 0;
     762                 :          0 :                 gpwrdn.b.pwrdnclmp = 1;
     763                 :          0 :                 DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
     764                 :            : 
     765                 :            :                 /* Remove reset the core signal */
     766                 :          0 :                 gpwrdn.d32 = 0;
     767                 :          0 :                 gpwrdn.b.pwrdnrstn = 1;
     768                 :          0 :                 DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, 0, gpwrdn.d32);
     769                 :          0 :                 dwc_udelay(10);
     770                 :            : 
     771                 :            :                 /* Disable PMU interrupt */
     772                 :          0 :                 gpwrdn.d32 = 0;
     773                 :          0 :                 gpwrdn.b.pmuintsel = 1;
     774                 :          0 :                 DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
     775                 :          0 :                 dwc_udelay(10);
     776                 :            : 
     777                 :            :                 /*Indicates that we are exiting from hibernation */
     778                 :          0 :                 core_if->hibernation_suspend = 0;
     779                 :            : 
     780                 :            :                 /* Disable PMU */
     781                 :          0 :                 gpwrdn.d32 = 0;
     782                 :          0 :                 gpwrdn.b.pmuactv = 1;
     783                 :          0 :                 DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
     784                 :          0 :                 dwc_udelay(10);
     785                 :            : 
     786                 :          0 :                 core_if->op_state = B_PERIPHERAL;
     787                 :          0 :                 dwc_otg_core_init(core_if);
     788                 :          0 :                 dwc_otg_enable_global_interrupts(core_if);
     789                 :            :                 cil_pcd_start(core_if);
     790                 :            : 
     791                 :          0 :                 if (otg_cap_param == DWC_OTG_CAP_PARAM_HNP_SRP_CAPABLE ||
     792                 :            :                         otg_cap_param == DWC_OTG_CAP_PARAM_SRP_ONLY_CAPABLE) {
     793                 :            :                         /*
     794                 :            :                          * Initiate SRP after initial ADP probe.
     795                 :            :                          */
     796                 :          0 :                         dwc_otg_initiate_srp(core_if);
     797                 :            :                 }
     798                 :            :         }
     799                 :            : 
     800                 :            :         return 1;
     801                 :            : }
     802                 :            : /**
     803                 :            :  * This interrupt indicates that the Wakeup Logic has detected a
     804                 :            :  * status change either on IDDIG or BSessVld.
     805                 :            :  */
     806                 :          0 : static uint32_t dwc_otg_handle_pwrdn_stschng_intr(dwc_otg_device_t *otg_dev)
     807                 :            : {
     808                 :            :         int retval;
     809                 :            :         gpwrdn_data_t gpwrdn = {.d32 = 0 };
     810                 :            :         gpwrdn_data_t gpwrdn_temp = {.d32 = 0 };
     811                 :          0 :         dwc_otg_core_if_t *core_if = otg_dev->core_if;
     812                 :            : 
     813                 :          0 :         DWC_PRINTF("%s called\n", __FUNCTION__);
     814                 :            : 
     815                 :          0 :         if (core_if->power_down == 2) {
     816                 :          0 :                 if (core_if->hibernation_suspend <= 0) {
     817                 :          0 :                         DWC_PRINTF("Already exited from Hibernation\n");
     818                 :          0 :                         return 1;
     819                 :            :                 } else
     820                 :          0 :                         gpwrdn_temp.d32 = core_if->gr_backup->gpwrdn_local;
     821                 :            : 
     822                 :            :         } else {
     823                 :          0 :                 gpwrdn_temp.d32 = core_if->adp.gpwrdn;
     824                 :            :         }
     825                 :            : 
     826                 :          0 :         gpwrdn.d32 = DWC_READ_REG32(&core_if->core_global_regs->gpwrdn);
     827                 :            : 
     828                 :          0 :         if (gpwrdn.b.idsts ^ gpwrdn_temp.b.idsts) {
     829                 :          0 :                 retval = dwc_otg_handle_pwrdn_idsts_change(otg_dev);
     830                 :          0 :         } else if (gpwrdn.b.bsessvld ^ gpwrdn_temp.b.bsessvld) {
     831                 :          0 :                 retval = dwc_otg_handle_pwrdn_session_change(core_if);
     832                 :            :         }
     833                 :            : 
     834                 :          0 :         return retval;
     835                 :            : }
     836                 :            : 
     837                 :            : /**
     838                 :            :  * This interrupt indicates that the Wakeup Logic has detected a
     839                 :            :  * SRP.
     840                 :            :  */
     841                 :          0 : static int32_t dwc_otg_handle_pwrdn_srp_intr(dwc_otg_core_if_t * core_if)
     842                 :            : {
     843                 :          0 :         gpwrdn_data_t gpwrdn = {.d32 = 0 };
     844                 :            : 
     845                 :          0 :         DWC_PRINTF("%s called\n", __FUNCTION__);
     846                 :            : 
     847                 :          0 :         if (!core_if->hibernation_suspend) {
     848                 :          0 :                 DWC_PRINTF("Already exited from Hibernation\n");
     849                 :          0 :                 return 1;
     850                 :            :         }
     851                 :            : #ifdef DWC_DEV_SRPCAP
     852                 :            :         if (core_if->pwron_timer_started) {
     853                 :            :                 core_if->pwron_timer_started = 0;
     854                 :            :                 DWC_TIMER_CANCEL(core_if->pwron_timer);
     855                 :            :         }
     856                 :            : #endif
     857                 :            : 
     858                 :            :         /* Switch on the voltage to the core */
     859                 :          0 :         gpwrdn.b.pwrdnswtch = 1;
     860                 :          0 :         DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
     861                 :          0 :         dwc_udelay(10);
     862                 :            : 
     863                 :            :         /* Reset the core */
     864                 :          0 :         gpwrdn.d32 = 0;
     865                 :          0 :         gpwrdn.b.pwrdnrstn = 1;
     866                 :          0 :         DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
     867                 :          0 :         dwc_udelay(10);
     868                 :            : 
     869                 :            :         /* Disable power clamps */
     870                 :          0 :         gpwrdn.d32 = 0;
     871                 :          0 :         gpwrdn.b.pwrdnclmp = 1;
     872                 :          0 :         DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
     873                 :            : 
     874                 :            :         /* Remove reset the core signal */
     875                 :          0 :         gpwrdn.d32 = 0;
     876                 :          0 :         gpwrdn.b.pwrdnrstn = 1;
     877                 :          0 :         DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, 0, gpwrdn.d32);
     878                 :          0 :         dwc_udelay(10);
     879                 :            : 
     880                 :            :         /* Disable PMU interrupt */
     881                 :          0 :         gpwrdn.d32 = 0;
     882                 :          0 :         gpwrdn.b.pmuintsel = 1;
     883                 :          0 :         DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
     884                 :            : 
     885                 :            :         /* Indicates that we are exiting from hibernation */
     886                 :          0 :         core_if->hibernation_suspend = 0;
     887                 :            : 
     888                 :            :         /* Disable PMU */
     889                 :          0 :         gpwrdn.d32 = 0;
     890                 :          0 :         gpwrdn.b.pmuactv = 1;
     891                 :          0 :         DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
     892                 :          0 :         dwc_udelay(10);
     893                 :            : 
     894                 :            :         /* Programm Disable VBUS to 0 */
     895                 :          0 :         gpwrdn.d32 = 0;
     896                 :          0 :         gpwrdn.b.dis_vbus = 1;
     897                 :          0 :         DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
     898                 :            : 
     899                 :            :         /*Initialize the core as Host */
     900                 :          0 :         core_if->op_state = A_HOST;
     901                 :          0 :         dwc_otg_core_init(core_if);
     902                 :          0 :         dwc_otg_enable_global_interrupts(core_if);
     903                 :            :         cil_hcd_start(core_if);
     904                 :            : 
     905                 :            :         return 1;
     906                 :            : }
     907                 :            : 
     908                 :            : /** This interrupt indicates that restore command after Hibernation
     909                 :            :  * was completed by the core. */
     910                 :          0 : int32_t dwc_otg_handle_restore_done_intr(dwc_otg_core_if_t * core_if)
     911                 :            : {
     912                 :            :         pcgcctl_data_t pcgcctl;
     913                 :            :         DWC_DEBUGPL(DBG_ANY, "++Restore Done Interrupt++\n");
     914                 :            : 
     915                 :            :         //TODO De-assert restore signal. 8.a
     916                 :          0 :         pcgcctl.d32 = DWC_READ_REG32(core_if->pcgcctl);
     917                 :          0 :         if (pcgcctl.b.restoremode == 1) {
     918                 :          0 :                 gintmsk_data_t gintmsk = {.d32 = 0 };
     919                 :            :                 /*
     920                 :            :                  * If restore mode is Remote Wakeup,
     921                 :            :                  * unmask Remote Wakeup interrupt.
     922                 :            :                  */
     923                 :          0 :                 gintmsk.b.wkupintr = 1;
     924                 :          0 :                 DWC_MODIFY_REG32(&core_if->core_global_regs->gintmsk,
     925                 :            :                                  0, gintmsk.d32);
     926                 :            :         }
     927                 :            : 
     928                 :          0 :         return 1;
     929                 :            : }
     930                 :            : 
     931                 :            : /**
     932                 :            :  * This interrupt indicates that a device has been disconnected from
     933                 :            :  * the root port.
     934                 :            :  */
     935                 :          0 : int32_t dwc_otg_handle_disconnect_intr(dwc_otg_core_if_t * core_if)
     936                 :            : {
     937                 :            :         gintsts_data_t gintsts;
     938                 :            : 
     939                 :            :         DWC_DEBUGPL(DBG_ANY, "++Disconnect Detected Interrupt++ (%s) %s\n",
     940                 :            :                     (dwc_otg_is_host_mode(core_if) ? "Host" : "Device"),
     941                 :            :                     op_state_str(core_if));
     942                 :            : 
     943                 :            : /** @todo Consolidate this if statement. */
     944                 :            : #ifndef DWC_HOST_ONLY
     945                 :          0 :         if (core_if->op_state == B_HOST) {
     946                 :            :                 /* If in device mode Disconnect and stop the HCD, then
     947                 :            :                  * start the PCD. */
     948                 :          0 :                 DWC_SPINUNLOCK(core_if->lock);
     949                 :            :                 cil_hcd_disconnect(core_if);
     950                 :            :                 cil_pcd_start(core_if);
     951                 :          0 :                 DWC_SPINLOCK(core_if->lock);
     952                 :          0 :                 core_if->op_state = B_PERIPHERAL;
     953                 :          0 :         } else if (dwc_otg_is_device_mode(core_if)) {
     954                 :            :                 gotgctl_data_t gotgctl = {.d32 = 0 };
     955                 :            :                 gotgctl.d32 =
     956                 :          0 :                     DWC_READ_REG32(&core_if->core_global_regs->gotgctl);
     957                 :          0 :                 if (gotgctl.b.hstsethnpen == 1) {
     958                 :            :                         /* Do nothing, if HNP in process the OTG
     959                 :            :                          * interrupt "Host Negotiation Detected"
     960                 :            :                          * interrupt will do the mode switch.
     961                 :            :                          */
     962                 :          0 :                 } else if (gotgctl.b.devhnpen == 0) {
     963                 :            :                         /* If in device mode Disconnect and stop the HCD, then
     964                 :            :                          * start the PCD. */
     965                 :          0 :                         DWC_SPINUNLOCK(core_if->lock);
     966                 :            :                         cil_hcd_disconnect(core_if);
     967                 :            :                         cil_pcd_start(core_if);
     968                 :          0 :                         DWC_SPINLOCK(core_if->lock);
     969                 :          0 :                         core_if->op_state = B_PERIPHERAL;
     970                 :            :                 } else {
     971                 :            :                         DWC_DEBUGPL(DBG_ANY, "!a_peripheral && !devhnpen\n");
     972                 :            :                 }
     973                 :            :         } else {
     974                 :          0 :                 if (core_if->op_state == A_HOST) {
     975                 :            :                         /* A-Cable still connected but device disconnected. */
     976                 :          0 :                         DWC_SPINUNLOCK(core_if->lock);
     977                 :            :                         cil_hcd_disconnect(core_if);
     978                 :          0 :                         DWC_SPINLOCK(core_if->lock);
     979                 :          0 :                         if (core_if->adp_enable) {
     980                 :          0 :                                 gpwrdn_data_t gpwrdn = { .d32 = 0 };
     981                 :            :                                 cil_hcd_stop(core_if);
     982                 :            :                                 /* Enable Power Down Logic */
     983                 :          0 :                                 gpwrdn.b.pmuintsel = 1;
     984                 :          0 :                                 gpwrdn.b.pmuactv = 1;
     985                 :          0 :                                 DWC_MODIFY_REG32(&core_if->core_global_regs->
     986                 :            :                                                  gpwrdn, 0, gpwrdn.d32);
     987                 :          0 :                                 dwc_otg_adp_probe_start(core_if);
     988                 :            : 
     989                 :            :                                 /* Power off the core */
     990                 :          0 :                                 if (core_if->power_down == 2) {
     991                 :          0 :                                         gpwrdn.d32 = 0;
     992                 :          0 :                                         gpwrdn.b.pwrdnswtch = 1;
     993                 :          0 :                                         DWC_MODIFY_REG32
     994                 :          0 :                                             (&core_if->core_global_regs->gpwrdn,
     995                 :            :                                              gpwrdn.d32, 0);
     996                 :            :                                 }
     997                 :            :                         }
     998                 :            :                 }
     999                 :            :         }
    1000                 :            : #endif
    1001                 :            :         /* Change to L3(OFF) state */
    1002                 :          0 :         core_if->lx_state = DWC_OTG_L3;
    1003                 :            : 
    1004                 :          0 :         gintsts.d32 = 0;
    1005                 :          0 :         gintsts.b.disconnect = 1;
    1006                 :          0 :         DWC_WRITE_REG32(&core_if->core_global_regs->gintsts, gintsts.d32);
    1007                 :          0 :         return 1;
    1008                 :            : }
    1009                 :            : 
    1010                 :            : /**
    1011                 :            :  * This interrupt indicates that SUSPEND state has been detected on
    1012                 :            :  * the USB.
    1013                 :            :  *
    1014                 :            :  * For HNP the USB Suspend interrupt signals the change from
    1015                 :            :  * "a_peripheral" to "a_host".
    1016                 :            :  *
    1017                 :            :  * When power management is enabled the core will be put in low power
    1018                 :            :  * mode.
    1019                 :            :  */
    1020                 :          0 : int32_t dwc_otg_handle_usb_suspend_intr(dwc_otg_core_if_t * core_if)
    1021                 :            : {
    1022                 :            :         dsts_data_t dsts;
    1023                 :            :         gintsts_data_t gintsts;
    1024                 :            :         dcfg_data_t dcfg;
    1025                 :            : 
    1026                 :            :         DWC_DEBUGPL(DBG_ANY, "USB SUSPEND\n");
    1027                 :            : 
    1028                 :          0 :         if (dwc_otg_is_device_mode(core_if)) {
    1029                 :            :                 /* Check the Device status register to determine if the Suspend
    1030                 :            :                  * state is active. */
    1031                 :            :                 dsts.d32 =
    1032                 :          0 :                     DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dsts);
    1033                 :            :                 DWC_DEBUGPL(DBG_PCD, "DSTS=0x%0x\n", dsts.d32);
    1034                 :            :                 DWC_DEBUGPL(DBG_PCD, "DSTS.Suspend Status=%d "
    1035                 :            :                             "HWCFG4.power Optimize=%d\n",
    1036                 :            :                             dsts.b.suspsts, core_if->hwcfg4.b.power_optimiz);
    1037                 :            : 
    1038                 :            : #ifdef PARTIAL_POWER_DOWN
    1039                 :            : /** @todo Add a module parameter for power management. */
    1040                 :            : 
    1041                 :            :                 if (dsts.b.suspsts && core_if->hwcfg4.b.power_optimiz) {
    1042                 :            :                         pcgcctl_data_t power = {.d32 = 0 };
    1043                 :            :                         DWC_DEBUGPL(DBG_CIL, "suspend\n");
    1044                 :            : 
    1045                 :            :                         power.b.pwrclmp = 1;
    1046                 :            :                         DWC_WRITE_REG32(core_if->pcgcctl, power.d32);
    1047                 :            : 
    1048                 :            :                         power.b.rstpdwnmodule = 1;
    1049                 :            :                         DWC_MODIFY_REG32(core_if->pcgcctl, 0, power.d32);
    1050                 :            : 
    1051                 :            :                         power.b.stoppclk = 1;
    1052                 :            :                         DWC_MODIFY_REG32(core_if->pcgcctl, 0, power.d32);
    1053                 :            : 
    1054                 :            :                 } else {
    1055                 :            :                         DWC_DEBUGPL(DBG_ANY, "disconnect?\n");
    1056                 :            :                 }
    1057                 :            : #endif
    1058                 :            :                 /* PCD callback for suspend. Release the lock inside of callback function */
    1059                 :            :                 cil_pcd_suspend(core_if);
    1060                 :          0 :                 if (core_if->power_down == 2)
    1061                 :            :                 {
    1062                 :          0 :                         dcfg.d32 = DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dcfg);
    1063                 :            :                         DWC_DEBUGPL(DBG_ANY,"lx_state = %08x\n",core_if->lx_state);
    1064                 :            :                         DWC_DEBUGPL(DBG_ANY," device address = %08d\n",dcfg.b.devaddr);
    1065                 :            : 
    1066                 :          0 :                         if (core_if->lx_state != DWC_OTG_L3 && dcfg.b.devaddr) {
    1067                 :          0 :                                 pcgcctl_data_t pcgcctl = {.d32 = 0 };
    1068                 :          0 :                                 gpwrdn_data_t gpwrdn = {.d32 = 0 };
    1069                 :            :                                 gusbcfg_data_t gusbcfg = {.d32 = 0 };
    1070                 :            : 
    1071                 :            :                                 /* Change to L2(suspend) state */
    1072                 :          0 :                                 core_if->lx_state = DWC_OTG_L2;
    1073                 :            : 
    1074                 :            :                                 /* Clear interrupt in gintsts */
    1075                 :          0 :                                 gintsts.d32 = 0;
    1076                 :          0 :                                 gintsts.b.usbsuspend = 1;
    1077                 :          0 :                                 DWC_WRITE_REG32(&core_if->core_global_regs->
    1078                 :            :                                                 gintsts, gintsts.d32);
    1079                 :          0 :                                 DWC_PRINTF("Start of hibernation completed\n");
    1080                 :          0 :                                 dwc_otg_save_global_regs(core_if);
    1081                 :          0 :                                 dwc_otg_save_dev_regs(core_if);
    1082                 :            : 
    1083                 :            :                                 gusbcfg.d32 =
    1084                 :          0 :                                     DWC_READ_REG32(&core_if->core_global_regs->
    1085                 :            :                                                    gusbcfg);
    1086                 :          0 :                                 if (gusbcfg.b.ulpi_utmi_sel == 1) {
    1087                 :            :                                         /* ULPI interface */
    1088                 :            :                                         /* Suspend the Phy Clock */
    1089                 :            :                                         pcgcctl.d32 = 0;
    1090                 :          0 :                                         pcgcctl.b.stoppclk = 1;
    1091                 :          0 :                                         DWC_MODIFY_REG32(core_if->pcgcctl, 0,
    1092                 :            :                                                          pcgcctl.d32);
    1093                 :          0 :                                         dwc_udelay(10);
    1094                 :          0 :                                         gpwrdn.b.pmuactv = 1;
    1095                 :          0 :                                         DWC_MODIFY_REG32(&core_if->
    1096                 :            :                                                          core_global_regs->
    1097                 :            :                                                          gpwrdn, 0, gpwrdn.d32);
    1098                 :            :                                 } else {
    1099                 :            :                                         /* UTMI+ Interface */
    1100                 :          0 :                                         gpwrdn.b.pmuactv = 1;
    1101                 :          0 :                                         DWC_MODIFY_REG32(&core_if->
    1102                 :            :                                                          core_global_regs->
    1103                 :            :                                                          gpwrdn, 0, gpwrdn.d32);
    1104                 :          0 :                                         dwc_udelay(10);
    1105                 :          0 :                                         pcgcctl.b.stoppclk = 1;
    1106                 :          0 :                                         DWC_MODIFY_REG32(core_if->pcgcctl, 0,
    1107                 :            :                                                          pcgcctl.d32);
    1108                 :          0 :                                         dwc_udelay(10);
    1109                 :            :                                 }
    1110                 :            : 
    1111                 :            :                                 /* Set flag to indicate that we are in hibernation */
    1112                 :          0 :                                 core_if->hibernation_suspend = 1;
    1113                 :            :                                 /* Enable interrupts from wake up logic */
    1114                 :          0 :                                 gpwrdn.d32 = 0;
    1115                 :          0 :                                 gpwrdn.b.pmuintsel = 1;
    1116                 :          0 :                                 DWC_MODIFY_REG32(&core_if->core_global_regs->
    1117                 :            :                                                  gpwrdn, 0, gpwrdn.d32);
    1118                 :          0 :                                 dwc_udelay(10);
    1119                 :            : 
    1120                 :            :                                 /* Unmask device mode interrupts in GPWRDN */
    1121                 :          0 :                                 gpwrdn.d32 = 0;
    1122                 :          0 :                                 gpwrdn.b.rst_det_msk = 1;
    1123                 :          0 :                                 gpwrdn.b.lnstchng_msk = 1;
    1124                 :          0 :                                 gpwrdn.b.sts_chngint_msk = 1;
    1125                 :          0 :                                 DWC_MODIFY_REG32(&core_if->core_global_regs->
    1126                 :            :                                                  gpwrdn, 0, gpwrdn.d32);
    1127                 :          0 :                                 dwc_udelay(10);
    1128                 :            : 
    1129                 :            :                                 /* Enable Power Down Clamp */
    1130                 :          0 :                                 gpwrdn.d32 = 0;
    1131                 :          0 :                                 gpwrdn.b.pwrdnclmp = 1;
    1132                 :          0 :                                 DWC_MODIFY_REG32(&core_if->core_global_regs->
    1133                 :            :                                                  gpwrdn, 0, gpwrdn.d32);
    1134                 :          0 :                                 dwc_udelay(10);
    1135                 :            : 
    1136                 :            :                                 /* Switch off VDD */
    1137                 :          0 :                                 gpwrdn.d32 = 0;
    1138                 :          0 :                                 gpwrdn.b.pwrdnswtch = 1;
    1139                 :          0 :                                 DWC_MODIFY_REG32(&core_if->core_global_regs->
    1140                 :            :                                                  gpwrdn, 0, gpwrdn.d32);
    1141                 :            : 
    1142                 :            :                                 /* Save gpwrdn register for further usage if stschng interrupt */
    1143                 :          0 :                                 core_if->gr_backup->gpwrdn_local =
    1144                 :          0 :                                                         DWC_READ_REG32(&core_if->core_global_regs->gpwrdn);
    1145                 :          0 :                                 DWC_PRINTF("Hibernation completed\n");
    1146                 :            : 
    1147                 :            :                                 return 1;
    1148                 :            :                         }
    1149                 :          0 :                 } else if (core_if->power_down == 3) {
    1150                 :          0 :                         pcgcctl_data_t pcgcctl = {.d32 = 0 };
    1151                 :          0 :                         dcfg.d32 = DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dcfg);
    1152                 :            :                         DWC_DEBUGPL(DBG_ANY, "lx_state = %08x\n",core_if->lx_state);
    1153                 :            :                         DWC_DEBUGPL(DBG_ANY, " device address = %08d\n",dcfg.b.devaddr);
    1154                 :            : 
    1155                 :          0 :                         if (core_if->lx_state != DWC_OTG_L3 && dcfg.b.devaddr) {
    1156                 :            :                                 DWC_DEBUGPL(DBG_ANY, "Start entering to extended hibernation\n");
    1157                 :          0 :                                 core_if->xhib = 1;
    1158                 :            : 
    1159                 :            :                                 /* Clear interrupt in gintsts */
    1160                 :          0 :                                 gintsts.d32 = 0;
    1161                 :          0 :                                 gintsts.b.usbsuspend = 1;
    1162                 :          0 :                                 DWC_WRITE_REG32(&core_if->core_global_regs->
    1163                 :            :                                         gintsts, gintsts.d32);
    1164                 :            : 
    1165                 :          0 :                                 dwc_otg_save_global_regs(core_if);
    1166                 :          0 :                                 dwc_otg_save_dev_regs(core_if);
    1167                 :            : 
    1168                 :            :                                 /* Wait for 10 PHY clocks */
    1169                 :          0 :                                 dwc_udelay(10);
    1170                 :            : 
    1171                 :            :                                 /* Program GPIO register while entering to xHib */
    1172                 :          0 :                                 DWC_WRITE_REG32(&core_if->core_global_regs->ggpio, 0x1);
    1173                 :            : 
    1174                 :          0 :                                 pcgcctl.b.enbl_extnd_hiber = 1;
    1175                 :          0 :                                 DWC_MODIFY_REG32(core_if->pcgcctl, 0, pcgcctl.d32);
    1176                 :          0 :                                 DWC_MODIFY_REG32(core_if->pcgcctl, 0, pcgcctl.d32);
    1177                 :            : 
    1178                 :          0 :                                 pcgcctl.d32 = 0;
    1179                 :          0 :                                 pcgcctl.b.extnd_hiber_pwrclmp = 1;
    1180                 :          0 :                                 DWC_MODIFY_REG32(core_if->pcgcctl, 0, pcgcctl.d32);
    1181                 :            : 
    1182                 :          0 :                                 pcgcctl.d32 = 0;
    1183                 :          0 :                                 pcgcctl.b.extnd_hiber_switch = 1;
    1184                 :          0 :                                 core_if->gr_backup->xhib_gpwrdn = DWC_READ_REG32(&core_if->core_global_regs->gpwrdn);
    1185                 :          0 :                                 core_if->gr_backup->xhib_pcgcctl = DWC_READ_REG32(core_if->pcgcctl) | pcgcctl.d32;
    1186                 :          0 :                                 DWC_MODIFY_REG32(core_if->pcgcctl, 0, pcgcctl.d32);
    1187                 :            : 
    1188                 :            :                                 DWC_DEBUGPL(DBG_ANY, "Finished entering to extended hibernation\n");
    1189                 :            : 
    1190                 :          0 :                                 return 1;
    1191                 :            :                         }
    1192                 :            :                 }
    1193                 :            :         } else {
    1194                 :          0 :                 if (core_if->op_state == A_PERIPHERAL) {
    1195                 :            :                         DWC_DEBUGPL(DBG_ANY, "a_peripheral->a_host\n");
    1196                 :            :                         /* Clear the a_peripheral flag, back to a_host. */
    1197                 :          0 :                         DWC_SPINUNLOCK(core_if->lock);
    1198                 :            :                         cil_pcd_stop(core_if);
    1199                 :            :                         cil_hcd_start(core_if);
    1200                 :          0 :                         DWC_SPINLOCK(core_if->lock);
    1201                 :          0 :                         core_if->op_state = A_HOST;
    1202                 :            :                 }
    1203                 :            :         }
    1204                 :            : 
    1205                 :            :         /* Change to L2(suspend) state */
    1206                 :          0 :         core_if->lx_state = DWC_OTG_L2;
    1207                 :            : 
    1208                 :            :         /* Clear interrupt */
    1209                 :          0 :         gintsts.d32 = 0;
    1210                 :          0 :         gintsts.b.usbsuspend = 1;
    1211                 :          0 :         DWC_WRITE_REG32(&core_if->core_global_regs->gintsts, gintsts.d32);
    1212                 :            : 
    1213                 :          0 :         return 1;
    1214                 :            : }
    1215                 :            : 
    1216                 :          0 : static int32_t dwc_otg_handle_xhib_exit_intr(dwc_otg_core_if_t * core_if)
    1217                 :            : {
    1218                 :            :         gpwrdn_data_t gpwrdn = {.d32 = 0 };
    1219                 :            :         pcgcctl_data_t pcgcctl = {.d32 = 0 };
    1220                 :            :         gahbcfg_data_t gahbcfg = {.d32 = 0 };
    1221                 :            : 
    1222                 :          0 :         dwc_udelay(10);
    1223                 :            : 
    1224                 :            :         /* Program GPIO register while entering to xHib */
    1225                 :          0 :         DWC_WRITE_REG32(&core_if->core_global_regs->ggpio, 0x0);
    1226                 :            : 
    1227                 :          0 :         pcgcctl.d32 = core_if->gr_backup->xhib_pcgcctl;
    1228                 :          0 :         pcgcctl.b.extnd_hiber_pwrclmp = 0;
    1229                 :          0 :         DWC_WRITE_REG32(core_if->pcgcctl, pcgcctl.d32);
    1230                 :          0 :         dwc_udelay(10);
    1231                 :            : 
    1232                 :          0 :         gpwrdn.d32 = core_if->gr_backup->xhib_gpwrdn;
    1233                 :          0 :         gpwrdn.b.restore = 1;
    1234                 :          0 :         DWC_WRITE_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32);
    1235                 :          0 :         dwc_udelay(10);
    1236                 :            : 
    1237                 :          0 :         restore_lpm_i2c_regs(core_if);
    1238                 :            : 
    1239                 :          0 :         pcgcctl.d32 = core_if->gr_backup->pcgcctl_local & (0x3FFFF << 14);
    1240                 :          0 :         pcgcctl.b.max_xcvrselect = 1;
    1241                 :          0 :         pcgcctl.b.ess_reg_restored = 0;
    1242                 :          0 :         pcgcctl.b.extnd_hiber_switch = 0;
    1243                 :          0 :         pcgcctl.b.extnd_hiber_pwrclmp = 0;
    1244                 :          0 :         pcgcctl.b.enbl_extnd_hiber = 1;
    1245                 :          0 :         DWC_WRITE_REG32(core_if->pcgcctl, pcgcctl.d32);
    1246                 :            : 
    1247                 :          0 :         gahbcfg.d32 = core_if->gr_backup->gahbcfg_local;
    1248                 :          0 :         gahbcfg.b.glblintrmsk = 1;
    1249                 :          0 :         DWC_WRITE_REG32(&core_if->core_global_regs->gahbcfg, gahbcfg.d32);
    1250                 :            : 
    1251                 :          0 :         DWC_WRITE_REG32(&core_if->core_global_regs->gintsts, 0xFFFFFFFF);
    1252                 :          0 :         DWC_WRITE_REG32(&core_if->core_global_regs->gintmsk, 0x1 << 16);
    1253                 :            : 
    1254                 :          0 :         DWC_WRITE_REG32(&core_if->core_global_regs->gusbcfg,
    1255                 :          0 :                         core_if->gr_backup->gusbcfg_local);
    1256                 :          0 :         DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->dcfg,
    1257                 :          0 :                         core_if->dr_backup->dcfg);
    1258                 :            : 
    1259                 :            :         pcgcctl.d32 = 0;
    1260                 :          0 :         pcgcctl.d32 = core_if->gr_backup->pcgcctl_local & (0x3FFFF << 14);
    1261                 :          0 :         pcgcctl.b.max_xcvrselect = 1;
    1262                 :          0 :         pcgcctl.d32 |= 0x608;
    1263                 :          0 :         DWC_WRITE_REG32(core_if->pcgcctl, pcgcctl.d32);
    1264                 :          0 :         dwc_udelay(10);
    1265                 :            : 
    1266                 :            :         pcgcctl.d32 = 0;
    1267                 :          0 :         pcgcctl.d32 = core_if->gr_backup->pcgcctl_local & (0x3FFFF << 14);
    1268                 :          0 :         pcgcctl.b.max_xcvrselect = 1;
    1269                 :          0 :         pcgcctl.b.ess_reg_restored = 1;
    1270                 :          0 :         pcgcctl.b.enbl_extnd_hiber = 1;
    1271                 :          0 :         pcgcctl.b.rstpdwnmodule = 1;
    1272                 :          0 :         pcgcctl.b.restoremode = 1;
    1273                 :          0 :         DWC_WRITE_REG32(core_if->pcgcctl, pcgcctl.d32);
    1274                 :            : 
    1275                 :            :         DWC_DEBUGPL(DBG_ANY, "%s called\n", __FUNCTION__);
    1276                 :            : 
    1277                 :          0 :         return 1;
    1278                 :            : }
    1279                 :            : 
    1280                 :            : #ifdef CONFIG_USB_DWC_OTG_LPM
    1281                 :            : /**
    1282                 :            :  * This function hadles LPM transaction received interrupt.
    1283                 :            :  */
    1284                 :            : static int32_t dwc_otg_handle_lpm_intr(dwc_otg_core_if_t * core_if)
    1285                 :            : {
    1286                 :            :         glpmcfg_data_t lpmcfg;
    1287                 :            :         gintsts_data_t gintsts;
    1288                 :            : 
    1289                 :            :         if (!core_if->core_params->lpm_enable) {
    1290                 :            :                 DWC_PRINTF("Unexpected LPM interrupt\n");
    1291                 :            :         }
    1292                 :            : 
    1293                 :            :         lpmcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->glpmcfg);
    1294                 :            :         DWC_PRINTF("LPM config register = 0x%08x\n", lpmcfg.d32);
    1295                 :            : 
    1296                 :            :         if (dwc_otg_is_host_mode(core_if)) {
    1297                 :            :                 cil_hcd_sleep(core_if);
    1298                 :            :         } else {
    1299                 :            :                 lpmcfg.b.hird_thres |= (1 << 4);
    1300                 :            :                 DWC_WRITE_REG32(&core_if->core_global_regs->glpmcfg,
    1301                 :            :                                 lpmcfg.d32);
    1302                 :            :         }
    1303                 :            : 
    1304                 :            :         /* Examine prt_sleep_sts after TL1TokenTetry period max (10 us) */
    1305                 :            :         dwc_udelay(10);
    1306                 :            :         lpmcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->glpmcfg);
    1307                 :            :         if (lpmcfg.b.prt_sleep_sts) {
    1308                 :            :                 /* Save the current state */
    1309                 :            :                 core_if->lx_state = DWC_OTG_L1;
    1310                 :            :         }
    1311                 :            : 
    1312                 :            :         /* Clear interrupt  */
    1313                 :            :         gintsts.d32 = 0;
    1314                 :            :         gintsts.b.lpmtranrcvd = 1;
    1315                 :            :         DWC_WRITE_REG32(&core_if->core_global_regs->gintsts, gintsts.d32);
    1316                 :            :         return 1;
    1317                 :            : }
    1318                 :            : #endif /* CONFIG_USB_DWC_OTG_LPM */
    1319                 :            : 
    1320                 :            : /**
    1321                 :            :  * This function returns the Core Interrupt register.
    1322                 :            :  */
    1323                 :          3 : static inline uint32_t dwc_otg_read_common_intr(dwc_otg_core_if_t * core_if, gintmsk_data_t *reenable_gintmsk, dwc_otg_hcd_t *hcd)
    1324                 :            : {
    1325                 :            :         gahbcfg_data_t gahbcfg = {.d32 = 0 };
    1326                 :            :         gintsts_data_t gintsts;
    1327                 :            :         gintmsk_data_t gintmsk;
    1328                 :          3 :         gintmsk_data_t gintmsk_common = {.d32 = 0 };
    1329                 :          3 :         gintmsk_common.b.wkupintr = 1;
    1330                 :          3 :         gintmsk_common.b.sessreqintr = 1;
    1331                 :          3 :         gintmsk_common.b.conidstschng = 1;
    1332                 :          3 :         gintmsk_common.b.otgintr = 1;
    1333                 :          3 :         gintmsk_common.b.modemismatch = 1;
    1334                 :          3 :         gintmsk_common.b.disconnect = 1;
    1335                 :          3 :         gintmsk_common.b.usbsuspend = 1;
    1336                 :            : #ifdef CONFIG_USB_DWC_OTG_LPM
    1337                 :            :         gintmsk_common.b.lpmtranrcvd = 1;
    1338                 :            : #endif
    1339                 :          3 :         gintmsk_common.b.restoredone = 1;
    1340                 :          3 :         if(dwc_otg_is_device_mode(core_if))
    1341                 :            :         {
    1342                 :            :                 /** @todo: The port interrupt occurs while in device
    1343                 :            :                  * mode. Added code to CIL to clear the interrupt for now!
    1344                 :            :                  */
    1345                 :          0 :                 gintmsk_common.b.portintr = 1;
    1346                 :            :         }
    1347                 :          3 :         if(fiq_enable) {
    1348                 :          3 :                 local_fiq_disable();
    1349                 :          3 :                 fiq_fsm_spin_lock(&hcd->fiq_state->lock);
    1350                 :          3 :                 gintsts.d32 = DWC_READ_REG32(&core_if->core_global_regs->gintsts);
    1351                 :          3 :                 gintmsk.d32 = DWC_READ_REG32(&core_if->core_global_regs->gintmsk);
    1352                 :            :                 /* Pull in the interrupts that the FIQ has masked */
    1353                 :          3 :                 gintmsk.d32 |= ~(hcd->fiq_state->gintmsk_saved.d32);
    1354                 :          3 :                 gintmsk.d32 |= gintmsk_common.d32;
    1355                 :            :                 /* for the upstairs function to reenable - have to read it here in case FIQ triggers again */
    1356                 :          3 :                 reenable_gintmsk->d32 = gintmsk.d32;
    1357                 :          3 :                 fiq_fsm_spin_unlock(&hcd->fiq_state->lock);
    1358                 :          3 :                 local_fiq_enable();
    1359                 :            :         } else {
    1360                 :          0 :                 gintsts.d32 = DWC_READ_REG32(&core_if->core_global_regs->gintsts);
    1361                 :          0 :                 gintmsk.d32 = DWC_READ_REG32(&core_if->core_global_regs->gintmsk);
    1362                 :            :         }
    1363                 :            : 
    1364                 :          3 :         gahbcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->gahbcfg);
    1365                 :            : 
    1366                 :            : #ifdef DEBUG
    1367                 :            :         /* if any common interrupts set */
    1368                 :            :         if (gintsts.d32 & gintmsk_common.d32) {
    1369                 :            :                 DWC_DEBUGPL(DBG_ANY, "common_intr: gintsts=%08x  gintmsk=%08x\n",
    1370                 :            :                             gintsts.d32, gintmsk.d32);
    1371                 :            :         }
    1372                 :            : #endif
    1373                 :          3 :         if (!fiq_enable){
    1374                 :          0 :                 if (gahbcfg.b.glblintrmsk)
    1375                 :          0 :                         return ((gintsts.d32 & gintmsk.d32) & gintmsk_common.d32);
    1376                 :            :                 else
    1377                 :            :                         return 0;
    1378                 :            :         } else {
    1379                 :            :                 /* Our IRQ kicker is no longer the USB hardware, it's the MPHI interface.
    1380                 :            :                  * Can't trust the global interrupt mask bit in this case.
    1381                 :            :                  */
    1382                 :          3 :                 return ((gintsts.d32 & gintmsk.d32) & gintmsk_common.d32);
    1383                 :            :         }
    1384                 :            : 
    1385                 :            : }
    1386                 :            : 
    1387                 :            : /* MACRO for clearing interupt bits in GPWRDN register */
    1388                 :            : #define CLEAR_GPWRDN_INTR(__core_if,__intr) \
    1389                 :            : do { \
    1390                 :            :                 gpwrdn_data_t gpwrdn = {.d32=0}; \
    1391                 :            :                 gpwrdn.b.__intr = 1; \
    1392                 :            :                 DWC_MODIFY_REG32(&__core_if->core_global_regs->gpwrdn, \
    1393                 :            :                 0, gpwrdn.d32); \
    1394                 :            : } while (0)
    1395                 :            : 
    1396                 :            : /**
    1397                 :            :  * Common interrupt handler.
    1398                 :            :  *
    1399                 :            :  * The common interrupts are those that occur in both Host and Device mode.
    1400                 :            :  * This handler handles the following interrupts:
    1401                 :            :  * - Mode Mismatch Interrupt
    1402                 :            :  * - Disconnect Interrupt
    1403                 :            :  * - OTG Interrupt
    1404                 :            :  * - Connector ID Status Change Interrupt
    1405                 :            :  * - Session Request Interrupt.
    1406                 :            :  * - Resume / Remote Wakeup Detected Interrupt.
    1407                 :            :  * - LPM Transaction Received Interrupt
    1408                 :            :  * - ADP Transaction Received Interrupt
    1409                 :            :  *
    1410                 :            :  */
    1411                 :          3 : int32_t dwc_otg_handle_common_intr(void *dev)
    1412                 :            : {
    1413                 :            :         int retval = 0;
    1414                 :            :         gintsts_data_t gintsts;
    1415                 :          3 :         gintmsk_data_t gintmsk_reenable = { .d32 = 0 };
    1416                 :            :         gpwrdn_data_t gpwrdn = {.d32 = 0 };
    1417                 :            :         dwc_otg_device_t *otg_dev = dev;
    1418                 :          3 :         dwc_otg_core_if_t *core_if = otg_dev->core_if;
    1419                 :          3 :         gpwrdn.d32 = DWC_READ_REG32(&core_if->core_global_regs->gpwrdn);
    1420                 :          3 :         if (dwc_otg_is_device_mode(core_if))
    1421                 :          0 :                 core_if->frame_num = dwc_otg_get_frame_number(core_if);
    1422                 :            : 
    1423                 :          3 :         if (core_if->lock)
    1424                 :          3 :                 DWC_SPINLOCK(core_if->lock);
    1425                 :            : 
    1426                 :          3 :         if (core_if->power_down == 3 && core_if->xhib == 1) {
    1427                 :            :                 DWC_DEBUGPL(DBG_ANY, "Exiting from xHIB state\n");
    1428                 :          0 :                 retval |= dwc_otg_handle_xhib_exit_intr(core_if);
    1429                 :          0 :                 core_if->xhib = 2;
    1430                 :          0 :                 if (core_if->lock)
    1431                 :          0 :                         DWC_SPINUNLOCK(core_if->lock);
    1432                 :            : 
    1433                 :          0 :                 return retval;
    1434                 :            :         }
    1435                 :            : 
    1436                 :          3 :         if (core_if->hibernation_suspend <= 0) {
    1437                 :            :                 /* read_common will have to poke the FIQ's saved mask. We must then clear this mask at the end
    1438                 :            :                  * of this handler - god only knows why it's done like this
    1439                 :            :                  */
    1440                 :          3 :                 gintsts.d32 = dwc_otg_read_common_intr(core_if, &gintmsk_reenable, otg_dev->hcd);
    1441                 :            : 
    1442                 :          3 :                 if (gintsts.b.modemismatch) {
    1443                 :          0 :                         retval |= dwc_otg_handle_mode_mismatch_intr(core_if);
    1444                 :            :                 }
    1445                 :          3 :                 if (gintsts.b.otgintr) {
    1446                 :          2 :                         retval |= dwc_otg_handle_otg_intr(core_if);
    1447                 :            :                 }
    1448                 :          3 :                 if (gintsts.b.conidstschng) {
    1449                 :          0 :                         retval |=
    1450                 :          0 :                             dwc_otg_handle_conn_id_status_change_intr(core_if);
    1451                 :            :                 }
    1452                 :          3 :                 if (gintsts.b.disconnect) {
    1453                 :          0 :                         retval |= dwc_otg_handle_disconnect_intr(core_if);
    1454                 :            :                 }
    1455                 :          3 :                 if (gintsts.b.sessreqintr) {
    1456                 :          0 :                         retval |= dwc_otg_handle_session_req_intr(core_if);
    1457                 :            :                 }
    1458                 :          3 :                 if (gintsts.b.wkupintr) {
    1459                 :          0 :                         retval |= dwc_otg_handle_wakeup_detected_intr(core_if);
    1460                 :            :                 }
    1461                 :          3 :                 if (gintsts.b.usbsuspend) {
    1462                 :          0 :                         retval |= dwc_otg_handle_usb_suspend_intr(core_if);
    1463                 :            :                 }
    1464                 :            : #ifdef CONFIG_USB_DWC_OTG_LPM
    1465                 :            :                 if (gintsts.b.lpmtranrcvd) {
    1466                 :            :                         retval |= dwc_otg_handle_lpm_intr(core_if);
    1467                 :            :                 }
    1468                 :            : #endif
    1469                 :          3 :                 if (gintsts.b.restoredone) {
    1470                 :          0 :                         gintsts.d32 = 0;
    1471                 :          0 :                         if (core_if->power_down == 2)
    1472                 :          0 :                                 core_if->hibernation_suspend = -1;
    1473                 :          0 :                         else if (core_if->power_down == 3 && core_if->xhib == 2) {
    1474                 :          0 :                                 gpwrdn_data_t gpwrdn = {.d32 = 0 };
    1475                 :          0 :                                 pcgcctl_data_t pcgcctl = {.d32 = 0 };
    1476                 :          0 :                                 dctl_data_t dctl = {.d32 = 0 };
    1477                 :            : 
    1478                 :          0 :                                 DWC_WRITE_REG32(&core_if->core_global_regs->
    1479                 :            :                                                 gintsts, 0xFFFFFFFF);
    1480                 :            : 
    1481                 :            :                                 DWC_DEBUGPL(DBG_ANY,
    1482                 :            :                                             "RESTORE DONE generated\n");
    1483                 :            : 
    1484                 :          0 :                                 gpwrdn.b.restore = 1;
    1485                 :          0 :                                 DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
    1486                 :          0 :                                 dwc_udelay(10);
    1487                 :            : 
    1488                 :          0 :                                 pcgcctl.b.rstpdwnmodule = 1;
    1489                 :          0 :                                 DWC_MODIFY_REG32(core_if->pcgcctl, pcgcctl.d32, 0);
    1490                 :            : 
    1491                 :          0 :                                 DWC_WRITE_REG32(&core_if->core_global_regs->gusbcfg, core_if->gr_backup->gusbcfg_local);
    1492                 :          0 :                                 DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->dcfg, core_if->dr_backup->dcfg);
    1493                 :          0 :                                 DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->dctl, core_if->dr_backup->dctl);
    1494                 :          0 :                                 dwc_udelay(50);
    1495                 :            : 
    1496                 :          0 :                                 dctl.b.pwronprgdone = 1;
    1497                 :          0 :                                 DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->dctl, 0, dctl.d32);
    1498                 :          0 :                                 dwc_udelay(10);
    1499                 :            : 
    1500                 :          0 :                                 dwc_otg_restore_global_regs(core_if);
    1501                 :          0 :                                 dwc_otg_restore_dev_regs(core_if, 0);
    1502                 :            : 
    1503                 :          0 :                                 dctl.d32 = 0;
    1504                 :          0 :                                 dctl.b.pwronprgdone = 1;
    1505                 :          0 :                                 DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->dctl, dctl.d32, 0);
    1506                 :          0 :                                 dwc_udelay(10);
    1507                 :            : 
    1508                 :          0 :                                 pcgcctl.d32 = 0;
    1509                 :          0 :                                 pcgcctl.b.enbl_extnd_hiber = 1;
    1510                 :          0 :                                 DWC_MODIFY_REG32(core_if->pcgcctl, pcgcctl.d32, 0);
    1511                 :            : 
    1512                 :            :                                 /* The core will be in ON STATE */
    1513                 :          0 :                                 core_if->lx_state = DWC_OTG_L0;
    1514                 :          0 :                                 core_if->xhib = 0;
    1515                 :            : 
    1516                 :          0 :                                 DWC_SPINUNLOCK(core_if->lock);
    1517                 :          0 :                                 if (core_if->pcd_cb && core_if->pcd_cb->resume_wakeup) {
    1518                 :          0 :                                         core_if->pcd_cb->resume_wakeup(core_if->pcd_cb->p);
    1519                 :            :                                 }
    1520                 :          0 :                                 DWC_SPINLOCK(core_if->lock);
    1521                 :            : 
    1522                 :            :                         }
    1523                 :            : 
    1524                 :          0 :                         gintsts.b.restoredone = 1;
    1525                 :          0 :                         DWC_WRITE_REG32(&core_if->core_global_regs->gintsts,gintsts.d32);
    1526                 :          0 :                         DWC_PRINTF(" --Restore done interrupt received-- \n");
    1527                 :          0 :                         retval |= 1;
    1528                 :            :                 }
    1529                 :          3 :                 if (gintsts.b.portintr && dwc_otg_is_device_mode(core_if)) {
    1530                 :            :                         /* The port interrupt occurs while in device mode with HPRT0
    1531                 :            :                          * Port Enable/Disable.
    1532                 :            :                          */
    1533                 :          0 :                         gintsts.d32 = 0;
    1534                 :          0 :                         gintsts.b.portintr = 1;
    1535                 :          0 :                         DWC_WRITE_REG32(&core_if->core_global_regs->gintsts,gintsts.d32);
    1536                 :          0 :                         retval |= 1;
    1537                 :          0 :                         gintmsk_reenable.b.portintr = 1;
    1538                 :            : 
    1539                 :            :                 }
    1540                 :            :                 /* Did we actually handle anything? if so, unmask the interrupt */
    1541                 :            : //              fiq_print(FIQDBG_INT, otg_dev->hcd->fiq_state, "CILOUT %1d", retval);
    1542                 :            : //              fiq_print(FIQDBG_INT, otg_dev->hcd->fiq_state, "%08x", gintsts.d32);
    1543                 :            : //              fiq_print(FIQDBG_INT, otg_dev->hcd->fiq_state, "%08x", gintmsk_reenable.d32);
    1544                 :          3 :                 if (retval && fiq_enable) {
    1545                 :          2 :                         DWC_WRITE_REG32(&core_if->core_global_regs->gintmsk, gintmsk_reenable.d32);
    1546                 :            :                 }
    1547                 :            : 
    1548                 :            :         } else {
    1549                 :            :                 DWC_DEBUGPL(DBG_ANY, "gpwrdn=%08x\n", gpwrdn.d32);
    1550                 :            : 
    1551                 :          0 :                 if (gpwrdn.b.disconn_det && gpwrdn.b.disconn_det_msk) {
    1552                 :          0 :                         CLEAR_GPWRDN_INTR(core_if, disconn_det);
    1553                 :          0 :                         if (gpwrdn.b.linestate == 0) {
    1554                 :          0 :                                 dwc_otg_handle_pwrdn_disconnect_intr(core_if);
    1555                 :            :                         } else {
    1556                 :          0 :                                 DWC_PRINTF("Disconnect detected while linestate is not 0\n");
    1557                 :            :                         }
    1558                 :            : 
    1559                 :            :                         retval |= 1;
    1560                 :            :                 }
    1561                 :          0 :                 if (gpwrdn.b.lnstschng && gpwrdn.b.lnstchng_msk) {
    1562                 :          0 :                         CLEAR_GPWRDN_INTR(core_if, lnstschng);
    1563                 :            :                         /* remote wakeup from hibernation */
    1564                 :          0 :                         if (gpwrdn.b.linestate == 2 || gpwrdn.b.linestate == 1) {
    1565                 :          0 :                                 dwc_otg_handle_pwrdn_wakeup_detected_intr(core_if);
    1566                 :            :                         } else {
    1567                 :          0 :                                 DWC_PRINTF("gpwrdn.linestate = %d\n", gpwrdn.b.linestate);
    1568                 :            :                         }
    1569                 :            :                         retval |= 1;
    1570                 :            :                 }
    1571                 :          0 :                 if (gpwrdn.b.rst_det && gpwrdn.b.rst_det_msk) {
    1572                 :          0 :                         CLEAR_GPWRDN_INTR(core_if, rst_det);
    1573                 :          0 :                         if (gpwrdn.b.linestate == 0) {
    1574                 :          0 :                                 DWC_PRINTF("Reset detected\n");
    1575                 :          0 :                                 retval |= dwc_otg_device_hibernation_restore(core_if, 0, 1);
    1576                 :            :                         }
    1577                 :            :                 }
    1578                 :          0 :                 if (gpwrdn.b.srp_det && gpwrdn.b.srp_det_msk) {
    1579                 :          0 :                         CLEAR_GPWRDN_INTR(core_if, srp_det);
    1580                 :          0 :                         dwc_otg_handle_pwrdn_srp_intr(core_if);
    1581                 :          0 :                         retval |= 1;
    1582                 :            :                 }
    1583                 :            :         }
    1584                 :            :         /* Handle ADP interrupt here */
    1585                 :          3 :         if (gpwrdn.b.adp_int) {
    1586                 :          0 :                 DWC_PRINTF("ADP interrupt\n");
    1587                 :          0 :                 CLEAR_GPWRDN_INTR(core_if, adp_int);
    1588                 :          0 :                 dwc_otg_adp_handle_intr(core_if);
    1589                 :          0 :                 retval |= 1;
    1590                 :            :         }
    1591                 :          3 :         if (gpwrdn.b.sts_chngint && gpwrdn.b.sts_chngint_msk) {
    1592                 :          0 :                 DWC_PRINTF("STS CHNG interrupt asserted\n");
    1593                 :          0 :                 CLEAR_GPWRDN_INTR(core_if, sts_chngint);
    1594                 :          0 :                 dwc_otg_handle_pwrdn_stschng_intr(otg_dev);
    1595                 :            : 
    1596                 :          0 :                 retval |= 1;
    1597                 :            :         }
    1598                 :          3 :         if (core_if->lock)
    1599                 :          3 :                 DWC_SPINUNLOCK(core_if->lock);
    1600                 :          3 :         return retval;
    1601                 :            : }
    

Generated by: LCOV version 1.14