GNU Linux-libre 6.7.9-gnu
[releases.git] / drivers / usb / dwc2 / core_intr.c
1 // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
2 /*
3  * core_intr.c - DesignWare HS OTG Controller common interrupt handling
4  *
5  * Copyright (C) 2004-2013 Synopsys, Inc.
6  */
7
8 /*
9  * This file contains the common interrupt handlers
10  */
11 #include <linux/kernel.h>
12 #include <linux/module.h>
13 #include <linux/moduleparam.h>
14 #include <linux/spinlock.h>
15 #include <linux/interrupt.h>
16 #include <linux/dma-mapping.h>
17 #include <linux/io.h>
18 #include <linux/slab.h>
19 #include <linux/usb.h>
20
21 #include <linux/usb/hcd.h>
22 #include <linux/usb/ch11.h>
23
24 #include "core.h"
25 #include "hcd.h"
26
27 static const char *dwc2_op_state_str(struct dwc2_hsotg *hsotg)
28 {
29         switch (hsotg->op_state) {
30         case OTG_STATE_A_HOST:
31                 return "a_host";
32         case OTG_STATE_A_SUSPEND:
33                 return "a_suspend";
34         case OTG_STATE_A_PERIPHERAL:
35                 return "a_peripheral";
36         case OTG_STATE_B_PERIPHERAL:
37                 return "b_peripheral";
38         case OTG_STATE_B_HOST:
39                 return "b_host";
40         default:
41                 return "unknown";
42         }
43 }
44
45 /**
46  * dwc2_handle_usb_port_intr - handles OTG PRTINT interrupts.
47  * When the PRTINT interrupt fires, there are certain status bits in the Host
48  * Port that needs to get cleared.
49  *
50  * @hsotg: Programming view of DWC_otg controller
51  */
52 static void dwc2_handle_usb_port_intr(struct dwc2_hsotg *hsotg)
53 {
54         u32 hprt0 = dwc2_readl(hsotg, HPRT0);
55
56         if (hprt0 & HPRT0_ENACHG) {
57                 hprt0 &= ~HPRT0_ENA;
58                 dwc2_writel(hsotg, hprt0, HPRT0);
59         }
60 }
61
62 /**
63  * dwc2_handle_mode_mismatch_intr() - Logs a mode mismatch warning message
64  *
65  * @hsotg: Programming view of DWC_otg controller
66  */
67 static void dwc2_handle_mode_mismatch_intr(struct dwc2_hsotg *hsotg)
68 {
69         /* Clear interrupt */
70         dwc2_writel(hsotg, GINTSTS_MODEMIS, GINTSTS);
71
72         dev_warn(hsotg->dev, "Mode Mismatch Interrupt: currently in %s mode\n",
73                  dwc2_is_host_mode(hsotg) ? "Host" : "Device");
74 }
75
76 /**
77  * dwc2_handle_otg_intr() - Handles the OTG Interrupts. It reads the OTG
78  * Interrupt Register (GOTGINT) to determine what interrupt has occurred.
79  *
80  * @hsotg: Programming view of DWC_otg controller
81  */
82 static void dwc2_handle_otg_intr(struct dwc2_hsotg *hsotg)
83 {
84         u32 gotgint;
85         u32 gotgctl;
86         u32 gintmsk;
87
88         gotgint = dwc2_readl(hsotg, GOTGINT);
89         gotgctl = dwc2_readl(hsotg, GOTGCTL);
90         dev_dbg(hsotg->dev, "++OTG Interrupt gotgint=%0x [%s]\n", gotgint,
91                 dwc2_op_state_str(hsotg));
92
93         if (gotgint & GOTGINT_SES_END_DET) {
94                 dev_dbg(hsotg->dev,
95                         " ++OTG Interrupt: Session End Detected++ (%s)\n",
96                         dwc2_op_state_str(hsotg));
97                 gotgctl = dwc2_readl(hsotg, GOTGCTL);
98
99                 if (dwc2_is_device_mode(hsotg))
100                         dwc2_hsotg_disconnect(hsotg);
101
102                 if (hsotg->op_state == OTG_STATE_B_HOST) {
103                         hsotg->op_state = OTG_STATE_B_PERIPHERAL;
104                 } else {
105                         /*
106                          * If not B_HOST and Device HNP still set, HNP did
107                          * not succeed!
108                          */
109                         if (gotgctl & GOTGCTL_DEVHNPEN) {
110                                 dev_dbg(hsotg->dev, "Session End Detected\n");
111                                 dev_err(hsotg->dev,
112                                         "Device Not Connected/Responding!\n");
113                         }
114
115                         /*
116                          * If Session End Detected the B-Cable has been
117                          * disconnected
118                          */
119                         /* Reset to a clean state */
120                         hsotg->lx_state = DWC2_L0;
121                 }
122
123                 gotgctl = dwc2_readl(hsotg, GOTGCTL);
124                 gotgctl &= ~GOTGCTL_DEVHNPEN;
125                 dwc2_writel(hsotg, gotgctl, GOTGCTL);
126         }
127
128         if (gotgint & GOTGINT_SES_REQ_SUC_STS_CHNG) {
129                 dev_dbg(hsotg->dev,
130                         " ++OTG Interrupt: Session Request Success Status Change++\n");
131                 gotgctl = dwc2_readl(hsotg, GOTGCTL);
132                 if (gotgctl & GOTGCTL_SESREQSCS) {
133                         if (hsotg->params.phy_type == DWC2_PHY_TYPE_PARAM_FS &&
134                             hsotg->params.i2c_enable) {
135                                 hsotg->srp_success = 1;
136                         } else {
137                                 /* Clear Session Request */
138                                 gotgctl = dwc2_readl(hsotg, GOTGCTL);
139                                 gotgctl &= ~GOTGCTL_SESREQ;
140                                 dwc2_writel(hsotg, gotgctl, GOTGCTL);
141                         }
142                 }
143         }
144
145         if (gotgint & GOTGINT_HST_NEG_SUC_STS_CHNG) {
146                 /*
147                  * Print statements during the HNP interrupt handling
148                  * can cause it to fail
149                  */
150                 gotgctl = dwc2_readl(hsotg, GOTGCTL);
151                 /*
152                  * WA for 3.00a- HW is not setting cur_mode, even sometimes
153                  * this does not help
154                  */
155                 if (hsotg->hw_params.snpsid >= DWC2_CORE_REV_3_00a)
156                         udelay(100);
157                 if (gotgctl & GOTGCTL_HSTNEGSCS) {
158                         if (dwc2_is_host_mode(hsotg)) {
159                                 hsotg->op_state = OTG_STATE_B_HOST;
160                                 /*
161                                  * Need to disable SOF interrupt immediately.
162                                  * When switching from device to host, the PCD
163                                  * interrupt handler won't handle the interrupt
164                                  * if host mode is already set. The HCD
165                                  * interrupt handler won't get called if the
166                                  * HCD state is HALT. This means that the
167                                  * interrupt does not get handled and Linux
168                                  * complains loudly.
169                                  */
170                                 gintmsk = dwc2_readl(hsotg, GINTMSK);
171                                 gintmsk &= ~GINTSTS_SOF;
172                                 dwc2_writel(hsotg, gintmsk, GINTMSK);
173
174                                 /*
175                                  * Call callback function with spin lock
176                                  * released
177                                  */
178                                 spin_unlock(&hsotg->lock);
179
180                                 /* Initialize the Core for Host mode */
181                                 dwc2_hcd_start(hsotg);
182                                 spin_lock(&hsotg->lock);
183                                 hsotg->op_state = OTG_STATE_B_HOST;
184                         }
185                 } else {
186                         gotgctl = dwc2_readl(hsotg, GOTGCTL);
187                         gotgctl &= ~(GOTGCTL_HNPREQ | GOTGCTL_DEVHNPEN);
188                         dwc2_writel(hsotg, gotgctl, GOTGCTL);
189                         dev_dbg(hsotg->dev, "HNP Failed\n");
190                         dev_err(hsotg->dev,
191                                 "Device Not Connected/Responding\n");
192                 }
193         }
194
195         if (gotgint & GOTGINT_HST_NEG_DET) {
196                 /*
197                  * The disconnect interrupt is set at the same time as
198                  * Host Negotiation Detected. During the mode switch all
199                  * interrupts are cleared so the disconnect interrupt
200                  * handler will not get executed.
201                  */
202                 dev_dbg(hsotg->dev,
203                         " ++OTG Interrupt: Host Negotiation Detected++ (%s)\n",
204                         (dwc2_is_host_mode(hsotg) ? "Host" : "Device"));
205                 if (dwc2_is_device_mode(hsotg)) {
206                         dev_dbg(hsotg->dev, "a_suspend->a_peripheral (%d)\n",
207                                 hsotg->op_state);
208                         spin_unlock(&hsotg->lock);
209                         dwc2_hcd_disconnect(hsotg, false);
210                         spin_lock(&hsotg->lock);
211                         hsotg->op_state = OTG_STATE_A_PERIPHERAL;
212                 } else {
213                         /* Need to disable SOF interrupt immediately */
214                         gintmsk = dwc2_readl(hsotg, GINTMSK);
215                         gintmsk &= ~GINTSTS_SOF;
216                         dwc2_writel(hsotg, gintmsk, GINTMSK);
217                         spin_unlock(&hsotg->lock);
218                         dwc2_hcd_start(hsotg);
219                         spin_lock(&hsotg->lock);
220                         hsotg->op_state = OTG_STATE_A_HOST;
221                 }
222         }
223
224         if (gotgint & GOTGINT_A_DEV_TOUT_CHG)
225                 dev_dbg(hsotg->dev,
226                         " ++OTG Interrupt: A-Device Timeout Change++\n");
227         if (gotgint & GOTGINT_DBNCE_DONE)
228                 dev_dbg(hsotg->dev, " ++OTG Interrupt: Debounce Done++\n");
229
230         /* Clear GOTGINT */
231         dwc2_writel(hsotg, gotgint, GOTGINT);
232 }
233
234 /**
235  * dwc2_handle_conn_id_status_change_intr() - Handles the Connector ID Status
236  * Change Interrupt
237  *
238  * @hsotg: Programming view of DWC_otg controller
239  *
240  * Reads the OTG Interrupt Register (GOTCTL) to determine whether this is a
241  * Device to Host Mode transition or a Host to Device Mode transition. This only
242  * occurs when the cable is connected/removed from the PHY connector.
243  */
244 static void dwc2_handle_conn_id_status_change_intr(struct dwc2_hsotg *hsotg)
245 {
246         u32 gintmsk;
247
248         /* Clear interrupt */
249         dwc2_writel(hsotg, GINTSTS_CONIDSTSCHNG, GINTSTS);
250
251         /* Need to disable SOF interrupt immediately */
252         gintmsk = dwc2_readl(hsotg, GINTMSK);
253         gintmsk &= ~GINTSTS_SOF;
254         dwc2_writel(hsotg, gintmsk, GINTMSK);
255
256         dev_dbg(hsotg->dev, " ++Connector ID Status Change Interrupt++  (%s)\n",
257                 dwc2_is_host_mode(hsotg) ? "Host" : "Device");
258
259         /*
260          * Need to schedule a work, as there are possible DELAY function calls.
261          */
262         if (hsotg->wq_otg)
263                 queue_work(hsotg->wq_otg, &hsotg->wf_otg);
264 }
265
266 /**
267  * dwc2_handle_session_req_intr() - This interrupt indicates that a device is
268  * initiating the Session Request Protocol to request the host to turn on bus
269  * power so a new session can begin
270  *
271  * @hsotg: Programming view of DWC_otg controller
272  *
273  * This handler responds by turning on bus power. If the DWC_otg controller is
274  * in low power mode, this handler brings the controller out of low power mode
275  * before turning on bus power.
276  */
277 static void dwc2_handle_session_req_intr(struct dwc2_hsotg *hsotg)
278 {
279         int ret;
280         u32 hprt0;
281
282         /* Clear interrupt */
283         dwc2_writel(hsotg, GINTSTS_SESSREQINT, GINTSTS);
284
285         dev_dbg(hsotg->dev, "Session request interrupt - lx_state=%d\n",
286                 hsotg->lx_state);
287
288         if (dwc2_is_device_mode(hsotg)) {
289                 if (hsotg->lx_state == DWC2_L2) {
290                         if (hsotg->in_ppd) {
291                                 ret = dwc2_exit_partial_power_down(hsotg, 0,
292                                                                    true);
293                                 if (ret)
294                                         dev_err(hsotg->dev,
295                                                 "exit power_down failed\n");
296                         }
297
298                         /* Exit gadget mode clock gating. */
299                         if (hsotg->params.power_down ==
300                             DWC2_POWER_DOWN_PARAM_NONE && hsotg->bus_suspended)
301                                 dwc2_gadget_exit_clock_gating(hsotg, 0);
302                 }
303
304                 /*
305                  * Report disconnect if there is any previous session
306                  * established
307                  */
308                 dwc2_hsotg_disconnect(hsotg);
309         } else {
310                 /* Turn on the port power bit. */
311                 hprt0 = dwc2_read_hprt0(hsotg);
312                 hprt0 |= HPRT0_PWR;
313                 dwc2_writel(hsotg, hprt0, HPRT0);
314                 /* Connect hcd after port power is set. */
315                 dwc2_hcd_connect(hsotg);
316         }
317 }
318
319 /**
320  * dwc2_wakeup_from_lpm_l1 - Exit the device from LPM L1 state
321  *
322  * @hsotg: Programming view of DWC_otg controller
323  *
324  */
325 static void dwc2_wakeup_from_lpm_l1(struct dwc2_hsotg *hsotg)
326 {
327         u32 glpmcfg;
328         u32 i = 0;
329
330         if (hsotg->lx_state != DWC2_L1) {
331                 dev_err(hsotg->dev, "Core isn't in DWC2_L1 state\n");
332                 return;
333         }
334
335         glpmcfg = dwc2_readl(hsotg, GLPMCFG);
336         if (dwc2_is_device_mode(hsotg)) {
337                 dev_dbg(hsotg->dev, "Exit from L1 state\n");
338                 glpmcfg &= ~GLPMCFG_ENBLSLPM;
339                 glpmcfg &= ~GLPMCFG_HIRD_THRES_EN;
340                 dwc2_writel(hsotg, glpmcfg, GLPMCFG);
341
342                 do {
343                         glpmcfg = dwc2_readl(hsotg, GLPMCFG);
344
345                         if (!(glpmcfg & (GLPMCFG_COREL1RES_MASK |
346                                          GLPMCFG_L1RESUMEOK | GLPMCFG_SLPSTS)))
347                                 break;
348
349                         udelay(1);
350                 } while (++i < 200);
351
352                 if (i == 200) {
353                         dev_err(hsotg->dev, "Failed to exit L1 sleep state in 200us.\n");
354                         return;
355                 }
356                 dwc2_gadget_init_lpm(hsotg);
357         } else {
358                 /* TODO */
359                 dev_err(hsotg->dev, "Host side LPM is not supported.\n");
360                 return;
361         }
362
363         /* Change to L0 state */
364         hsotg->lx_state = DWC2_L0;
365
366         /* Inform gadget to exit from L1 */
367         call_gadget(hsotg, resume);
368 }
369
370 /*
371  * This interrupt indicates that the DWC_otg controller has detected a
372  * resume or remote wakeup sequence. If the DWC_otg controller is in
373  * low power mode, the handler must brings the controller out of low
374  * power mode. The controller automatically begins resume signaling.
375  * The handler schedules a time to stop resume signaling.
376  */
377 static void dwc2_handle_wakeup_detected_intr(struct dwc2_hsotg *hsotg)
378 {
379         int ret;
380
381         /* Clear interrupt */
382         dwc2_writel(hsotg, GINTSTS_WKUPINT, GINTSTS);
383
384         dev_dbg(hsotg->dev, "++Resume or Remote Wakeup Detected Interrupt++\n");
385         dev_dbg(hsotg->dev, "%s lxstate = %d\n", __func__, hsotg->lx_state);
386
387         if (hsotg->lx_state == DWC2_L1) {
388                 dwc2_wakeup_from_lpm_l1(hsotg);
389                 return;
390         }
391
392         if (dwc2_is_device_mode(hsotg)) {
393                 dev_dbg(hsotg->dev, "DSTS=0x%0x\n",
394                         dwc2_readl(hsotg, DSTS));
395                 if (hsotg->lx_state == DWC2_L2) {
396                         if (hsotg->in_ppd) {
397                                 u32 dctl = dwc2_readl(hsotg, DCTL);
398                                 /* Clear Remote Wakeup Signaling */
399                                 dctl &= ~DCTL_RMTWKUPSIG;
400                                 dwc2_writel(hsotg, dctl, DCTL);
401                                 ret = dwc2_exit_partial_power_down(hsotg, 1,
402                                                                    true);
403                                 if (ret)
404                                         dev_err(hsotg->dev,
405                                                 "exit partial_power_down failed\n");
406                                 call_gadget(hsotg, resume);
407                         }
408
409                         /* Exit gadget mode clock gating. */
410                         if (hsotg->params.power_down ==
411                             DWC2_POWER_DOWN_PARAM_NONE && hsotg->bus_suspended)
412                                 dwc2_gadget_exit_clock_gating(hsotg, 0);
413                 } else {
414                         /* Change to L0 state */
415                         hsotg->lx_state = DWC2_L0;
416                 }
417         } else {
418                 if (hsotg->lx_state == DWC2_L2) {
419                         if (hsotg->in_ppd) {
420                                 ret = dwc2_exit_partial_power_down(hsotg, 1,
421                                                                    true);
422                                 if (ret)
423                                         dev_err(hsotg->dev,
424                                                 "exit partial_power_down failed\n");
425                         }
426
427                         if (hsotg->params.power_down ==
428                             DWC2_POWER_DOWN_PARAM_NONE && hsotg->bus_suspended)
429                                 dwc2_host_exit_clock_gating(hsotg, 1);
430
431                         /*
432                          * If we've got this quirk then the PHY is stuck upon
433                          * wakeup.  Assert reset.  This will propagate out and
434                          * eventually we'll re-enumerate the device.  Not great
435                          * but the best we can do.  We can't call phy_reset()
436                          * at interrupt time but there's no hurry, so we'll
437                          * schedule it for later.
438                          */
439                         if (hsotg->reset_phy_on_wake)
440                                 dwc2_host_schedule_phy_reset(hsotg);
441
442                         mod_timer(&hsotg->wkp_timer,
443                                   jiffies + msecs_to_jiffies(71));
444                 } else {
445                         /* Change to L0 state */
446                         hsotg->lx_state = DWC2_L0;
447                 }
448         }
449 }
450
451 /*
452  * This interrupt indicates that a device has been disconnected from the
453  * root port
454  */
455 static void dwc2_handle_disconnect_intr(struct dwc2_hsotg *hsotg)
456 {
457         dwc2_writel(hsotg, GINTSTS_DISCONNINT, GINTSTS);
458
459         dev_dbg(hsotg->dev, "++Disconnect Detected Interrupt++ (%s) %s\n",
460                 dwc2_is_host_mode(hsotg) ? "Host" : "Device",
461                 dwc2_op_state_str(hsotg));
462
463         if (hsotg->op_state == OTG_STATE_A_HOST)
464                 dwc2_hcd_disconnect(hsotg, false);
465 }
466
467 /*
468  * This interrupt indicates that SUSPEND state has been detected on the USB.
469  *
470  * For HNP the USB Suspend interrupt signals the change from "a_peripheral"
471  * to "a_host".
472  *
473  * When power management is enabled the core will be put in low power mode.
474  */
475 static void dwc2_handle_usb_suspend_intr(struct dwc2_hsotg *hsotg)
476 {
477         u32 dsts;
478         int ret;
479
480         /* Clear interrupt */
481         dwc2_writel(hsotg, GINTSTS_USBSUSP, GINTSTS);
482
483         dev_dbg(hsotg->dev, "USB SUSPEND\n");
484
485         if (dwc2_is_device_mode(hsotg)) {
486                 /*
487                  * Check the Device status register to determine if the Suspend
488                  * state is active
489                  */
490                 dsts = dwc2_readl(hsotg, DSTS);
491                 dev_dbg(hsotg->dev, "%s: DSTS=0x%0x\n", __func__, dsts);
492                 dev_dbg(hsotg->dev,
493                         "DSTS.Suspend Status=%d HWCFG4.Power Optimize=%d HWCFG4.Hibernation=%d\n",
494                         !!(dsts & DSTS_SUSPSTS),
495                         hsotg->hw_params.power_optimized,
496                         hsotg->hw_params.hibernation);
497
498                 /* Ignore suspend request before enumeration */
499                 if (!dwc2_is_device_connected(hsotg)) {
500                         dev_dbg(hsotg->dev,
501                                 "ignore suspend request before enumeration\n");
502                         return;
503                 }
504                 if (dsts & DSTS_SUSPSTS) {
505                         switch (hsotg->params.power_down) {
506                         case DWC2_POWER_DOWN_PARAM_PARTIAL:
507                                 ret = dwc2_enter_partial_power_down(hsotg);
508                                 if (ret)
509                                         dev_err(hsotg->dev,
510                                                 "enter partial_power_down failed\n");
511
512                                 udelay(100);
513
514                                 /* Ask phy to be suspended */
515                                 if (!IS_ERR_OR_NULL(hsotg->uphy))
516                                         usb_phy_set_suspend(hsotg->uphy, true);
517                                 break;
518                         case DWC2_POWER_DOWN_PARAM_HIBERNATION:
519                                 ret = dwc2_enter_hibernation(hsotg, 0);
520                                 if (ret)
521                                         dev_err(hsotg->dev,
522                                                 "enter hibernation failed\n");
523                                 break;
524                         case DWC2_POWER_DOWN_PARAM_NONE:
525                                 /*
526                                  * If neither hibernation nor partial power down are supported,
527                                  * clock gating is used to save power.
528                                  */
529                                 if (!hsotg->params.no_clock_gating)
530                                         dwc2_gadget_enter_clock_gating(hsotg);
531                         }
532
533                         /*
534                          * Change to L2 (suspend) state before releasing
535                          * spinlock
536                          */
537                         hsotg->lx_state = DWC2_L2;
538
539                         /* Call gadget suspend callback */
540                         call_gadget(hsotg, suspend);
541                 }
542         } else {
543                 if (hsotg->op_state == OTG_STATE_A_PERIPHERAL) {
544                         dev_dbg(hsotg->dev, "a_peripheral->a_host\n");
545
546                         /* Change to L2 (suspend) state */
547                         hsotg->lx_state = DWC2_L2;
548                         /* Clear the a_peripheral flag, back to a_host */
549                         spin_unlock(&hsotg->lock);
550                         dwc2_hcd_start(hsotg);
551                         spin_lock(&hsotg->lock);
552                         hsotg->op_state = OTG_STATE_A_HOST;
553                 }
554         }
555 }
556
557 /**
558  * dwc2_handle_lpm_intr - GINTSTS_LPMTRANRCVD Interrupt handler
559  *
560  * @hsotg: Programming view of DWC_otg controller
561  *
562  */
563 static void dwc2_handle_lpm_intr(struct dwc2_hsotg *hsotg)
564 {
565         u32 glpmcfg;
566         u32 pcgcctl;
567         u32 hird;
568         u32 hird_thres;
569         u32 hird_thres_en;
570         u32 enslpm;
571
572         /* Clear interrupt */
573         dwc2_writel(hsotg, GINTSTS_LPMTRANRCVD, GINTSTS);
574
575         glpmcfg = dwc2_readl(hsotg, GLPMCFG);
576
577         if (!(glpmcfg & GLPMCFG_LPMCAP)) {
578                 dev_err(hsotg->dev, "Unexpected LPM interrupt\n");
579                 return;
580         }
581
582         hird = (glpmcfg & GLPMCFG_HIRD_MASK) >> GLPMCFG_HIRD_SHIFT;
583         hird_thres = (glpmcfg & GLPMCFG_HIRD_THRES_MASK &
584                         ~GLPMCFG_HIRD_THRES_EN) >> GLPMCFG_HIRD_THRES_SHIFT;
585         hird_thres_en = glpmcfg & GLPMCFG_HIRD_THRES_EN;
586         enslpm = glpmcfg & GLPMCFG_ENBLSLPM;
587
588         if (dwc2_is_device_mode(hsotg)) {
589                 dev_dbg(hsotg->dev, "HIRD_THRES_EN = %d\n", hird_thres_en);
590
591                 if (hird_thres_en && hird >= hird_thres) {
592                         dev_dbg(hsotg->dev, "L1 with utmi_l1_suspend_n\n");
593                 } else if (enslpm) {
594                         dev_dbg(hsotg->dev, "L1 with utmi_sleep_n\n");
595                 } else {
596                         dev_dbg(hsotg->dev, "Entering Sleep with L1 Gating\n");
597
598                         pcgcctl = dwc2_readl(hsotg, PCGCTL);
599                         pcgcctl |= PCGCTL_ENBL_SLEEP_GATING;
600                         dwc2_writel(hsotg, pcgcctl, PCGCTL);
601                 }
602                 /**
603                  * Examine prt_sleep_sts after TL1TokenTetry period max (10 us)
604                  */
605                 udelay(10);
606
607                 glpmcfg = dwc2_readl(hsotg, GLPMCFG);
608
609                 if (glpmcfg & GLPMCFG_SLPSTS) {
610                         /* Save the current state */
611                         hsotg->lx_state = DWC2_L1;
612                         dev_dbg(hsotg->dev,
613                                 "Core is in L1 sleep glpmcfg=%08x\n", glpmcfg);
614
615                         /* Inform gadget that we are in L1 state */
616                         call_gadget(hsotg, suspend);
617                 }
618         }
619 }
620
621 #define GINTMSK_COMMON  (GINTSTS_WKUPINT | GINTSTS_SESSREQINT |         \
622                          GINTSTS_CONIDSTSCHNG | GINTSTS_OTGINT |        \
623                          GINTSTS_MODEMIS | GINTSTS_DISCONNINT |         \
624                          GINTSTS_USBSUSP | GINTSTS_PRTINT |             \
625                          GINTSTS_LPMTRANRCVD)
626
627 /*
628  * This function returns the Core Interrupt register
629  */
630 static u32 dwc2_read_common_intr(struct dwc2_hsotg *hsotg)
631 {
632         u32 gintsts;
633         u32 gintmsk;
634         u32 gahbcfg;
635         u32 gintmsk_common = GINTMSK_COMMON;
636
637         gintsts = dwc2_readl(hsotg, GINTSTS);
638         gintmsk = dwc2_readl(hsotg, GINTMSK);
639         gahbcfg = dwc2_readl(hsotg, GAHBCFG);
640
641         /* If any common interrupts set */
642         if (gintsts & gintmsk_common)
643                 dev_dbg(hsotg->dev, "gintsts=%08x  gintmsk=%08x\n",
644                         gintsts, gintmsk);
645
646         if (gahbcfg & GAHBCFG_GLBL_INTR_EN)
647                 return gintsts & gintmsk & gintmsk_common;
648         else
649                 return 0;
650 }
651
652 /**
653  * dwc_handle_gpwrdn_disc_det() - Handles the gpwrdn disconnect detect.
654  * Exits hibernation without restoring registers.
655  *
656  * @hsotg: Programming view of DWC_otg controller
657  * @gpwrdn: GPWRDN register
658  */
659 static inline void dwc_handle_gpwrdn_disc_det(struct dwc2_hsotg *hsotg,
660                                               u32 gpwrdn)
661 {
662         u32 gpwrdn_tmp;
663
664         /* Switch-on voltage to the core */
665         gpwrdn_tmp = dwc2_readl(hsotg, GPWRDN);
666         gpwrdn_tmp &= ~GPWRDN_PWRDNSWTCH;
667         dwc2_writel(hsotg, gpwrdn_tmp, GPWRDN);
668         udelay(5);
669
670         /* Reset core */
671         gpwrdn_tmp = dwc2_readl(hsotg, GPWRDN);
672         gpwrdn_tmp &= ~GPWRDN_PWRDNRSTN;
673         dwc2_writel(hsotg, gpwrdn_tmp, GPWRDN);
674         udelay(5);
675
676         /* Disable Power Down Clamp */
677         gpwrdn_tmp = dwc2_readl(hsotg, GPWRDN);
678         gpwrdn_tmp &= ~GPWRDN_PWRDNCLMP;
679         dwc2_writel(hsotg, gpwrdn_tmp, GPWRDN);
680         udelay(5);
681
682         /* Deassert reset core */
683         gpwrdn_tmp = dwc2_readl(hsotg, GPWRDN);
684         gpwrdn_tmp |= GPWRDN_PWRDNRSTN;
685         dwc2_writel(hsotg, gpwrdn_tmp, GPWRDN);
686         udelay(5);
687
688         /* Disable PMU interrupt */
689         gpwrdn_tmp = dwc2_readl(hsotg, GPWRDN);
690         gpwrdn_tmp &= ~GPWRDN_PMUINTSEL;
691         dwc2_writel(hsotg, gpwrdn_tmp, GPWRDN);
692
693         /* De-assert Wakeup Logic */
694         gpwrdn_tmp = dwc2_readl(hsotg, GPWRDN);
695         gpwrdn_tmp &= ~GPWRDN_PMUACTV;
696         dwc2_writel(hsotg, gpwrdn_tmp, GPWRDN);
697
698         hsotg->hibernated = 0;
699         hsotg->bus_suspended = 0;
700
701         if (gpwrdn & GPWRDN_IDSTS) {
702                 hsotg->op_state = OTG_STATE_B_PERIPHERAL;
703                 dwc2_core_init(hsotg, false);
704                 dwc2_enable_global_interrupts(hsotg);
705                 dwc2_hsotg_core_init_disconnected(hsotg, false);
706                 dwc2_hsotg_core_connect(hsotg);
707         } else {
708                 hsotg->op_state = OTG_STATE_A_HOST;
709
710                 /* Initialize the Core for Host mode */
711                 dwc2_core_init(hsotg, false);
712                 dwc2_enable_global_interrupts(hsotg);
713                 dwc2_hcd_start(hsotg);
714         }
715 }
716
717 /*
718  * GPWRDN interrupt handler.
719  *
720  * The GPWRDN interrupts are those that occur in both Host and
721  * Device mode while core is in hibernated state.
722  */
723 static int dwc2_handle_gpwrdn_intr(struct dwc2_hsotg *hsotg)
724 {
725         u32 gpwrdn;
726         int linestate;
727         int ret = 0;
728
729         gpwrdn = dwc2_readl(hsotg, GPWRDN);
730         /* clear all interrupt */
731         dwc2_writel(hsotg, gpwrdn, GPWRDN);
732         linestate = (gpwrdn & GPWRDN_LINESTATE_MASK) >> GPWRDN_LINESTATE_SHIFT;
733         dev_dbg(hsotg->dev,
734                 "%s: dwc2_handle_gpwrdwn_intr called gpwrdn= %08x\n", __func__,
735                 gpwrdn);
736
737         if ((gpwrdn & GPWRDN_DISCONN_DET) &&
738             (gpwrdn & GPWRDN_DISCONN_DET_MSK) && !linestate) {
739                 dev_dbg(hsotg->dev, "%s: GPWRDN_DISCONN_DET\n", __func__);
740                 /*
741                  * Call disconnect detect function to exit from
742                  * hibernation
743                  */
744                 dwc_handle_gpwrdn_disc_det(hsotg, gpwrdn);
745         } else if ((gpwrdn & GPWRDN_LNSTSCHG) &&
746                    (gpwrdn & GPWRDN_LNSTSCHG_MSK) && linestate) {
747                 dev_dbg(hsotg->dev, "%s: GPWRDN_LNSTSCHG\n", __func__);
748                 if (hsotg->hw_params.hibernation &&
749                     hsotg->hibernated) {
750                         if (gpwrdn & GPWRDN_IDSTS) {
751                                 ret = dwc2_exit_hibernation(hsotg, 0, 0, 0);
752                                 if (ret)
753                                         dev_err(hsotg->dev,
754                                                 "exit hibernation failed.\n");
755                                 call_gadget(hsotg, resume);
756                         } else {
757                                 ret = dwc2_exit_hibernation(hsotg, 1, 0, 1);
758                                 if (ret)
759                                         dev_err(hsotg->dev,
760                                                 "exit hibernation failed.\n");
761                         }
762                 }
763         } else if ((gpwrdn & GPWRDN_RST_DET) &&
764                    (gpwrdn & GPWRDN_RST_DET_MSK)) {
765                 dev_dbg(hsotg->dev, "%s: GPWRDN_RST_DET\n", __func__);
766                 if (!linestate) {
767                         ret = dwc2_exit_hibernation(hsotg, 0, 1, 0);
768                         if (ret)
769                                 dev_err(hsotg->dev,
770                                         "exit hibernation failed.\n");
771                 }
772         } else if ((gpwrdn & GPWRDN_STS_CHGINT) &&
773                    (gpwrdn & GPWRDN_STS_CHGINT_MSK)) {
774                 dev_dbg(hsotg->dev, "%s: GPWRDN_STS_CHGINT\n", __func__);
775                 /*
776                  * As GPWRDN_STS_CHGINT exit from hibernation flow is
777                  * the same as in GPWRDN_DISCONN_DET flow. Call
778                  * disconnect detect helper function to exit from
779                  * hibernation.
780                  */
781                 dwc_handle_gpwrdn_disc_det(hsotg, gpwrdn);
782         }
783
784         return ret;
785 }
786
787 /*
788  * Common interrupt handler
789  *
790  * The common interrupts are those that occur in both Host and Device mode.
791  * This handler handles the following interrupts:
792  * - Mode Mismatch Interrupt
793  * - OTG Interrupt
794  * - Connector ID Status Change Interrupt
795  * - Disconnect Interrupt
796  * - Session Request Interrupt
797  * - Resume / Remote Wakeup Detected Interrupt
798  * - Suspend Interrupt
799  */
800 irqreturn_t dwc2_handle_common_intr(int irq, void *dev)
801 {
802         struct dwc2_hsotg *hsotg = dev;
803         u32 gintsts;
804         irqreturn_t retval = IRQ_NONE;
805
806         spin_lock(&hsotg->lock);
807
808         if (!dwc2_is_controller_alive(hsotg)) {
809                 dev_warn(hsotg->dev, "Controller is dead\n");
810                 goto out;
811         }
812
813         /* Reading current frame number value in device or host modes. */
814         if (dwc2_is_device_mode(hsotg))
815                 hsotg->frame_number = (dwc2_readl(hsotg, DSTS)
816                                        & DSTS_SOFFN_MASK) >> DSTS_SOFFN_SHIFT;
817         else
818                 hsotg->frame_number = (dwc2_readl(hsotg, HFNUM)
819                                        & HFNUM_FRNUM_MASK) >> HFNUM_FRNUM_SHIFT;
820
821         gintsts = dwc2_read_common_intr(hsotg);
822         if (gintsts & ~GINTSTS_PRTINT)
823                 retval = IRQ_HANDLED;
824
825         /* In case of hibernated state gintsts must not work */
826         if (hsotg->hibernated) {
827                 dwc2_handle_gpwrdn_intr(hsotg);
828                 retval = IRQ_HANDLED;
829                 goto out;
830         }
831
832         if (gintsts & GINTSTS_MODEMIS)
833                 dwc2_handle_mode_mismatch_intr(hsotg);
834         if (gintsts & GINTSTS_OTGINT)
835                 dwc2_handle_otg_intr(hsotg);
836         if (gintsts & GINTSTS_CONIDSTSCHNG)
837                 dwc2_handle_conn_id_status_change_intr(hsotg);
838         if (gintsts & GINTSTS_DISCONNINT)
839                 dwc2_handle_disconnect_intr(hsotg);
840         if (gintsts & GINTSTS_SESSREQINT)
841                 dwc2_handle_session_req_intr(hsotg);
842         if (gintsts & GINTSTS_WKUPINT)
843                 dwc2_handle_wakeup_detected_intr(hsotg);
844         if (gintsts & GINTSTS_USBSUSP)
845                 dwc2_handle_usb_suspend_intr(hsotg);
846         if (gintsts & GINTSTS_LPMTRANRCVD)
847                 dwc2_handle_lpm_intr(hsotg);
848
849         if (gintsts & GINTSTS_PRTINT) {
850                 /*
851                  * The port interrupt occurs while in device mode with HPRT0
852                  * Port Enable/Disable
853                  */
854                 if (dwc2_is_device_mode(hsotg)) {
855                         dev_dbg(hsotg->dev,
856                                 " --Port interrupt received in Device mode--\n");
857                         dwc2_handle_usb_port_intr(hsotg);
858                         retval = IRQ_HANDLED;
859                 }
860         }
861
862 out:
863         spin_unlock(&hsotg->lock);
864         return retval;
865 }