GNU Linux-libre 6.8.7-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                             !hsotg->params.no_clock_gating)
302                                 dwc2_gadget_exit_clock_gating(hsotg, 0);
303                 }
304
305                 /*
306                  * Report disconnect if there is any previous session
307                  * established
308                  */
309                 dwc2_hsotg_disconnect(hsotg);
310         } else {
311                 /* Turn on the port power bit. */
312                 hprt0 = dwc2_read_hprt0(hsotg);
313                 hprt0 |= HPRT0_PWR;
314                 dwc2_writel(hsotg, hprt0, HPRT0);
315                 /* Connect hcd after port power is set. */
316                 dwc2_hcd_connect(hsotg);
317         }
318 }
319
320 /**
321  * dwc2_wakeup_from_lpm_l1 - Exit the device from LPM L1 state
322  *
323  * @hsotg: Programming view of DWC_otg controller
324  *
325  */
326 void dwc2_wakeup_from_lpm_l1(struct dwc2_hsotg *hsotg, bool remotewakeup)
327 {
328         u32 glpmcfg;
329         u32 pcgctl;
330         u32 dctl;
331
332         if (hsotg->lx_state != DWC2_L1) {
333                 dev_err(hsotg->dev, "Core isn't in DWC2_L1 state\n");
334                 return;
335         }
336
337         glpmcfg = dwc2_readl(hsotg, GLPMCFG);
338         if (dwc2_is_device_mode(hsotg)) {
339                 dev_dbg(hsotg->dev, "Exit from L1 state, remotewakeup=%d\n", remotewakeup);
340                 glpmcfg &= ~GLPMCFG_ENBLSLPM;
341                 glpmcfg &= ~GLPMCFG_HIRD_THRES_MASK;
342                 dwc2_writel(hsotg, glpmcfg, GLPMCFG);
343
344                 pcgctl = dwc2_readl(hsotg, PCGCTL);
345                 pcgctl &= ~PCGCTL_ENBL_SLEEP_GATING;
346                 dwc2_writel(hsotg, pcgctl, PCGCTL);
347
348                 glpmcfg = dwc2_readl(hsotg, GLPMCFG);
349                 if (glpmcfg & GLPMCFG_ENBESL) {
350                         glpmcfg |= GLPMCFG_RSTRSLPSTS;
351                         dwc2_writel(hsotg, glpmcfg, GLPMCFG);
352                 }
353
354                 if (remotewakeup) {
355                         if (dwc2_hsotg_wait_bit_set(hsotg, GLPMCFG, GLPMCFG_L1RESUMEOK, 1000)) {
356                                 dev_warn(hsotg->dev, "%s: timeout GLPMCFG_L1RESUMEOK\n", __func__);
357                                 goto fail;
358                                 return;
359                         }
360
361                         dctl = dwc2_readl(hsotg, DCTL);
362                         dctl |= DCTL_RMTWKUPSIG;
363                         dwc2_writel(hsotg, dctl, DCTL);
364
365                         if (dwc2_hsotg_wait_bit_set(hsotg, GINTSTS, GINTSTS_WKUPINT, 1000)) {
366                                 dev_warn(hsotg->dev, "%s: timeout GINTSTS_WKUPINT\n", __func__);
367                                 goto fail;
368                                 return;
369                         }
370                 }
371
372                 glpmcfg = dwc2_readl(hsotg, GLPMCFG);
373                 if (glpmcfg & GLPMCFG_COREL1RES_MASK || glpmcfg & GLPMCFG_SLPSTS ||
374                     glpmcfg & GLPMCFG_L1RESUMEOK) {
375                         goto fail;
376                         return;
377                 }
378
379                 /* Inform gadget to exit from L1 */
380                 call_gadget(hsotg, resume);
381                 /* Change to L0 state */
382                 hsotg->lx_state = DWC2_L0;
383                 hsotg->bus_suspended = false;
384 fail:           dwc2_gadget_init_lpm(hsotg);
385         } else {
386                 /* TODO */
387                 dev_err(hsotg->dev, "Host side LPM is not supported.\n");
388                 return;
389         }
390 }
391
392 /*
393  * This interrupt indicates that the DWC_otg controller has detected a
394  * resume or remote wakeup sequence. If the DWC_otg controller is in
395  * low power mode, the handler must brings the controller out of low
396  * power mode. The controller automatically begins resume signaling.
397  * The handler schedules a time to stop resume signaling.
398  */
399 static void dwc2_handle_wakeup_detected_intr(struct dwc2_hsotg *hsotg)
400 {
401         int ret;
402
403         /* Clear interrupt */
404         dwc2_writel(hsotg, GINTSTS_WKUPINT, GINTSTS);
405
406         dev_dbg(hsotg->dev, "++Resume or Remote Wakeup Detected Interrupt++\n");
407         dev_dbg(hsotg->dev, "%s lxstate = %d\n", __func__, hsotg->lx_state);
408
409         if (hsotg->lx_state == DWC2_L1) {
410                 dwc2_wakeup_from_lpm_l1(hsotg, false);
411                 return;
412         }
413
414         if (dwc2_is_device_mode(hsotg)) {
415                 dev_dbg(hsotg->dev, "DSTS=0x%0x\n",
416                         dwc2_readl(hsotg, DSTS));
417                 if (hsotg->lx_state == DWC2_L2) {
418                         if (hsotg->in_ppd) {
419                                 u32 dctl = dwc2_readl(hsotg, DCTL);
420                                 /* Clear Remote Wakeup Signaling */
421                                 dctl &= ~DCTL_RMTWKUPSIG;
422                                 dwc2_writel(hsotg, dctl, DCTL);
423                                 ret = dwc2_exit_partial_power_down(hsotg, 1,
424                                                                    true);
425                                 if (ret)
426                                         dev_err(hsotg->dev,
427                                                 "exit partial_power_down failed\n");
428                                 call_gadget(hsotg, resume);
429                         }
430
431                         /* Exit gadget mode clock gating. */
432                         if (hsotg->params.power_down ==
433                             DWC2_POWER_DOWN_PARAM_NONE && hsotg->bus_suspended &&
434                             !hsotg->params.no_clock_gating)
435                                 dwc2_gadget_exit_clock_gating(hsotg, 0);
436                 } else {
437                         /* Change to L0 state */
438                         hsotg->lx_state = DWC2_L0;
439                 }
440         } else {
441                 if (hsotg->lx_state == DWC2_L2) {
442                         if (hsotg->in_ppd) {
443                                 ret = dwc2_exit_partial_power_down(hsotg, 1,
444                                                                    true);
445                                 if (ret)
446                                         dev_err(hsotg->dev,
447                                                 "exit partial_power_down failed\n");
448                         }
449
450                         if (hsotg->params.power_down ==
451                             DWC2_POWER_DOWN_PARAM_NONE && hsotg->bus_suspended &&
452                             !hsotg->params.no_clock_gating)
453                                 dwc2_host_exit_clock_gating(hsotg, 1);
454
455                         /*
456                          * If we've got this quirk then the PHY is stuck upon
457                          * wakeup.  Assert reset.  This will propagate out and
458                          * eventually we'll re-enumerate the device.  Not great
459                          * but the best we can do.  We can't call phy_reset()
460                          * at interrupt time but there's no hurry, so we'll
461                          * schedule it for later.
462                          */
463                         if (hsotg->reset_phy_on_wake)
464                                 dwc2_host_schedule_phy_reset(hsotg);
465
466                         mod_timer(&hsotg->wkp_timer,
467                                   jiffies + msecs_to_jiffies(71));
468                 } else {
469                         /* Change to L0 state */
470                         hsotg->lx_state = DWC2_L0;
471                 }
472         }
473 }
474
475 /*
476  * This interrupt indicates that a device has been disconnected from the
477  * root port
478  */
479 static void dwc2_handle_disconnect_intr(struct dwc2_hsotg *hsotg)
480 {
481         dwc2_writel(hsotg, GINTSTS_DISCONNINT, GINTSTS);
482
483         dev_dbg(hsotg->dev, "++Disconnect Detected Interrupt++ (%s) %s\n",
484                 dwc2_is_host_mode(hsotg) ? "Host" : "Device",
485                 dwc2_op_state_str(hsotg));
486
487         if (hsotg->op_state == OTG_STATE_A_HOST)
488                 dwc2_hcd_disconnect(hsotg, false);
489 }
490
491 /*
492  * This interrupt indicates that SUSPEND state has been detected on the USB.
493  *
494  * For HNP the USB Suspend interrupt signals the change from "a_peripheral"
495  * to "a_host".
496  *
497  * When power management is enabled the core will be put in low power mode.
498  */
499 static void dwc2_handle_usb_suspend_intr(struct dwc2_hsotg *hsotg)
500 {
501         u32 dsts;
502         int ret;
503
504         /* Clear interrupt */
505         dwc2_writel(hsotg, GINTSTS_USBSUSP, GINTSTS);
506
507         dev_dbg(hsotg->dev, "USB SUSPEND\n");
508
509         if (dwc2_is_device_mode(hsotg)) {
510                 /*
511                  * Check the Device status register to determine if the Suspend
512                  * state is active
513                  */
514                 dsts = dwc2_readl(hsotg, DSTS);
515                 dev_dbg(hsotg->dev, "%s: DSTS=0x%0x\n", __func__, dsts);
516                 dev_dbg(hsotg->dev,
517                         "DSTS.Suspend Status=%d HWCFG4.Power Optimize=%d HWCFG4.Hibernation=%d\n",
518                         !!(dsts & DSTS_SUSPSTS),
519                         hsotg->hw_params.power_optimized,
520                         hsotg->hw_params.hibernation);
521
522                 /* Ignore suspend request before enumeration */
523                 if (!dwc2_is_device_connected(hsotg)) {
524                         dev_dbg(hsotg->dev,
525                                 "ignore suspend request before enumeration\n");
526                         return;
527                 }
528                 if (dsts & DSTS_SUSPSTS) {
529                         switch (hsotg->params.power_down) {
530                         case DWC2_POWER_DOWN_PARAM_PARTIAL:
531                                 ret = dwc2_enter_partial_power_down(hsotg);
532                                 if (ret)
533                                         dev_err(hsotg->dev,
534                                                 "enter partial_power_down failed\n");
535
536                                 udelay(100);
537
538                                 /* Ask phy to be suspended */
539                                 if (!IS_ERR_OR_NULL(hsotg->uphy))
540                                         usb_phy_set_suspend(hsotg->uphy, true);
541                                 break;
542                         case DWC2_POWER_DOWN_PARAM_HIBERNATION:
543                                 ret = dwc2_enter_hibernation(hsotg, 0);
544                                 if (ret)
545                                         dev_err(hsotg->dev,
546                                                 "enter hibernation failed\n");
547                                 break;
548                         case DWC2_POWER_DOWN_PARAM_NONE:
549                                 /*
550                                  * If neither hibernation nor partial power down are supported,
551                                  * clock gating is used to save power.
552                                  */
553                                 if (!hsotg->params.no_clock_gating)
554                                         dwc2_gadget_enter_clock_gating(hsotg);
555                         }
556
557                         /*
558                          * Change to L2 (suspend) state before releasing
559                          * spinlock
560                          */
561                         hsotg->lx_state = DWC2_L2;
562
563                         /* Call gadget suspend callback */
564                         call_gadget(hsotg, suspend);
565                 }
566         } else {
567                 if (hsotg->op_state == OTG_STATE_A_PERIPHERAL) {
568                         dev_dbg(hsotg->dev, "a_peripheral->a_host\n");
569
570                         /* Change to L2 (suspend) state */
571                         hsotg->lx_state = DWC2_L2;
572                         /* Clear the a_peripheral flag, back to a_host */
573                         spin_unlock(&hsotg->lock);
574                         dwc2_hcd_start(hsotg);
575                         spin_lock(&hsotg->lock);
576                         hsotg->op_state = OTG_STATE_A_HOST;
577                 }
578         }
579 }
580
581 /**
582  * dwc2_handle_lpm_intr - GINTSTS_LPMTRANRCVD Interrupt handler
583  *
584  * @hsotg: Programming view of DWC_otg controller
585  *
586  */
587 static void dwc2_handle_lpm_intr(struct dwc2_hsotg *hsotg)
588 {
589         u32 glpmcfg;
590         u32 pcgcctl;
591         u32 hird;
592         u32 hird_thres;
593         u32 hird_thres_en;
594         u32 enslpm;
595
596         /* Clear interrupt */
597         dwc2_writel(hsotg, GINTSTS_LPMTRANRCVD, GINTSTS);
598
599         glpmcfg = dwc2_readl(hsotg, GLPMCFG);
600
601         if (!(glpmcfg & GLPMCFG_LPMCAP)) {
602                 dev_err(hsotg->dev, "Unexpected LPM interrupt\n");
603                 return;
604         }
605
606         hird = (glpmcfg & GLPMCFG_HIRD_MASK) >> GLPMCFG_HIRD_SHIFT;
607         hird_thres = (glpmcfg & GLPMCFG_HIRD_THRES_MASK &
608                         ~GLPMCFG_HIRD_THRES_EN) >> GLPMCFG_HIRD_THRES_SHIFT;
609         hird_thres_en = glpmcfg & GLPMCFG_HIRD_THRES_EN;
610         enslpm = glpmcfg & GLPMCFG_ENBLSLPM;
611
612         if (dwc2_is_device_mode(hsotg)) {
613                 dev_dbg(hsotg->dev, "HIRD_THRES_EN = %d\n", hird_thres_en);
614
615                 if (hird_thres_en && hird >= hird_thres) {
616                         dev_dbg(hsotg->dev, "L1 with utmi_l1_suspend_n\n");
617                 } else if (enslpm) {
618                         dev_dbg(hsotg->dev, "L1 with utmi_sleep_n\n");
619                 } else {
620                         dev_dbg(hsotg->dev, "Entering Sleep with L1 Gating\n");
621
622                         pcgcctl = dwc2_readl(hsotg, PCGCTL);
623                         pcgcctl |= PCGCTL_ENBL_SLEEP_GATING;
624                         dwc2_writel(hsotg, pcgcctl, PCGCTL);
625                 }
626                 /**
627                  * Examine prt_sleep_sts after TL1TokenTetry period max (10 us)
628                  */
629                 udelay(10);
630
631                 glpmcfg = dwc2_readl(hsotg, GLPMCFG);
632
633                 if (glpmcfg & GLPMCFG_SLPSTS) {
634                         /* Save the current state */
635                         hsotg->lx_state = DWC2_L1;
636                         dev_dbg(hsotg->dev,
637                                 "Core is in L1 sleep glpmcfg=%08x\n", glpmcfg);
638
639                         /* Inform gadget that we are in L1 state */
640                         call_gadget(hsotg, suspend);
641                 }
642         }
643 }
644
645 #define GINTMSK_COMMON  (GINTSTS_WKUPINT | GINTSTS_SESSREQINT |         \
646                          GINTSTS_CONIDSTSCHNG | GINTSTS_OTGINT |        \
647                          GINTSTS_MODEMIS | GINTSTS_DISCONNINT |         \
648                          GINTSTS_USBSUSP | GINTSTS_PRTINT |             \
649                          GINTSTS_LPMTRANRCVD)
650
651 /*
652  * This function returns the Core Interrupt register
653  */
654 static u32 dwc2_read_common_intr(struct dwc2_hsotg *hsotg)
655 {
656         u32 gintsts;
657         u32 gintmsk;
658         u32 gahbcfg;
659         u32 gintmsk_common = GINTMSK_COMMON;
660
661         gintsts = dwc2_readl(hsotg, GINTSTS);
662         gintmsk = dwc2_readl(hsotg, GINTMSK);
663         gahbcfg = dwc2_readl(hsotg, GAHBCFG);
664
665         /* If any common interrupts set */
666         if (gintsts & gintmsk_common)
667                 dev_dbg(hsotg->dev, "gintsts=%08x  gintmsk=%08x\n",
668                         gintsts, gintmsk);
669
670         if (gahbcfg & GAHBCFG_GLBL_INTR_EN)
671                 return gintsts & gintmsk & gintmsk_common;
672         else
673                 return 0;
674 }
675
676 /**
677  * dwc_handle_gpwrdn_disc_det() - Handles the gpwrdn disconnect detect.
678  * Exits hibernation without restoring registers.
679  *
680  * @hsotg: Programming view of DWC_otg controller
681  * @gpwrdn: GPWRDN register
682  */
683 static inline void dwc_handle_gpwrdn_disc_det(struct dwc2_hsotg *hsotg,
684                                               u32 gpwrdn)
685 {
686         u32 gpwrdn_tmp;
687
688         /* Switch-on voltage to the core */
689         gpwrdn_tmp = dwc2_readl(hsotg, GPWRDN);
690         gpwrdn_tmp &= ~GPWRDN_PWRDNSWTCH;
691         dwc2_writel(hsotg, gpwrdn_tmp, GPWRDN);
692         udelay(5);
693
694         /* Reset core */
695         gpwrdn_tmp = dwc2_readl(hsotg, GPWRDN);
696         gpwrdn_tmp &= ~GPWRDN_PWRDNRSTN;
697         dwc2_writel(hsotg, gpwrdn_tmp, GPWRDN);
698         udelay(5);
699
700         /* Disable Power Down Clamp */
701         gpwrdn_tmp = dwc2_readl(hsotg, GPWRDN);
702         gpwrdn_tmp &= ~GPWRDN_PWRDNCLMP;
703         dwc2_writel(hsotg, gpwrdn_tmp, GPWRDN);
704         udelay(5);
705
706         /* Deassert reset core */
707         gpwrdn_tmp = dwc2_readl(hsotg, GPWRDN);
708         gpwrdn_tmp |= GPWRDN_PWRDNRSTN;
709         dwc2_writel(hsotg, gpwrdn_tmp, GPWRDN);
710         udelay(5);
711
712         /* Disable PMU interrupt */
713         gpwrdn_tmp = dwc2_readl(hsotg, GPWRDN);
714         gpwrdn_tmp &= ~GPWRDN_PMUINTSEL;
715         dwc2_writel(hsotg, gpwrdn_tmp, GPWRDN);
716
717         /* De-assert Wakeup Logic */
718         gpwrdn_tmp = dwc2_readl(hsotg, GPWRDN);
719         gpwrdn_tmp &= ~GPWRDN_PMUACTV;
720         dwc2_writel(hsotg, gpwrdn_tmp, GPWRDN);
721
722         hsotg->hibernated = 0;
723         hsotg->bus_suspended = 0;
724
725         if (gpwrdn & GPWRDN_IDSTS) {
726                 hsotg->op_state = OTG_STATE_B_PERIPHERAL;
727                 dwc2_core_init(hsotg, false);
728                 dwc2_enable_global_interrupts(hsotg);
729                 dwc2_hsotg_core_init_disconnected(hsotg, false);
730                 dwc2_hsotg_core_connect(hsotg);
731         } else {
732                 hsotg->op_state = OTG_STATE_A_HOST;
733
734                 /* Initialize the Core for Host mode */
735                 dwc2_core_init(hsotg, false);
736                 dwc2_enable_global_interrupts(hsotg);
737                 dwc2_hcd_start(hsotg);
738         }
739 }
740
741 /*
742  * GPWRDN interrupt handler.
743  *
744  * The GPWRDN interrupts are those that occur in both Host and
745  * Device mode while core is in hibernated state.
746  */
747 static int dwc2_handle_gpwrdn_intr(struct dwc2_hsotg *hsotg)
748 {
749         u32 gpwrdn;
750         int linestate;
751         int ret = 0;
752
753         gpwrdn = dwc2_readl(hsotg, GPWRDN);
754         /* clear all interrupt */
755         dwc2_writel(hsotg, gpwrdn, GPWRDN);
756         linestate = (gpwrdn & GPWRDN_LINESTATE_MASK) >> GPWRDN_LINESTATE_SHIFT;
757         dev_dbg(hsotg->dev,
758                 "%s: dwc2_handle_gpwrdwn_intr called gpwrdn= %08x\n", __func__,
759                 gpwrdn);
760
761         if ((gpwrdn & GPWRDN_DISCONN_DET) &&
762             (gpwrdn & GPWRDN_DISCONN_DET_MSK) && !linestate) {
763                 dev_dbg(hsotg->dev, "%s: GPWRDN_DISCONN_DET\n", __func__);
764                 /*
765                  * Call disconnect detect function to exit from
766                  * hibernation
767                  */
768                 dwc_handle_gpwrdn_disc_det(hsotg, gpwrdn);
769         } else if ((gpwrdn & GPWRDN_LNSTSCHG) &&
770                    (gpwrdn & GPWRDN_LNSTSCHG_MSK) && linestate) {
771                 dev_dbg(hsotg->dev, "%s: GPWRDN_LNSTSCHG\n", __func__);
772                 if (hsotg->hw_params.hibernation &&
773                     hsotg->hibernated) {
774                         if (gpwrdn & GPWRDN_IDSTS) {
775                                 ret = dwc2_exit_hibernation(hsotg, 0, 0, 0);
776                                 if (ret)
777                                         dev_err(hsotg->dev,
778                                                 "exit hibernation failed.\n");
779                                 call_gadget(hsotg, resume);
780                         } else {
781                                 ret = dwc2_exit_hibernation(hsotg, 1, 0, 1);
782                                 if (ret)
783                                         dev_err(hsotg->dev,
784                                                 "exit hibernation failed.\n");
785                         }
786                 }
787         } else if ((gpwrdn & GPWRDN_RST_DET) &&
788                    (gpwrdn & GPWRDN_RST_DET_MSK)) {
789                 dev_dbg(hsotg->dev, "%s: GPWRDN_RST_DET\n", __func__);
790                 if (!linestate) {
791                         ret = dwc2_exit_hibernation(hsotg, 0, 1, 0);
792                         if (ret)
793                                 dev_err(hsotg->dev,
794                                         "exit hibernation failed.\n");
795                 }
796         } else if ((gpwrdn & GPWRDN_STS_CHGINT) &&
797                    (gpwrdn & GPWRDN_STS_CHGINT_MSK)) {
798                 dev_dbg(hsotg->dev, "%s: GPWRDN_STS_CHGINT\n", __func__);
799                 /*
800                  * As GPWRDN_STS_CHGINT exit from hibernation flow is
801                  * the same as in GPWRDN_DISCONN_DET flow. Call
802                  * disconnect detect helper function to exit from
803                  * hibernation.
804                  */
805                 dwc_handle_gpwrdn_disc_det(hsotg, gpwrdn);
806         }
807
808         return ret;
809 }
810
811 /*
812  * Common interrupt handler
813  *
814  * The common interrupts are those that occur in both Host and Device mode.
815  * This handler handles the following interrupts:
816  * - Mode Mismatch Interrupt
817  * - OTG Interrupt
818  * - Connector ID Status Change Interrupt
819  * - Disconnect Interrupt
820  * - Session Request Interrupt
821  * - Resume / Remote Wakeup Detected Interrupt
822  * - Suspend Interrupt
823  */
824 irqreturn_t dwc2_handle_common_intr(int irq, void *dev)
825 {
826         struct dwc2_hsotg *hsotg = dev;
827         u32 gintsts;
828         irqreturn_t retval = IRQ_NONE;
829
830         spin_lock(&hsotg->lock);
831
832         if (!dwc2_is_controller_alive(hsotg)) {
833                 dev_warn(hsotg->dev, "Controller is dead\n");
834                 goto out;
835         }
836
837         /* Reading current frame number value in device or host modes. */
838         if (dwc2_is_device_mode(hsotg))
839                 hsotg->frame_number = (dwc2_readl(hsotg, DSTS)
840                                        & DSTS_SOFFN_MASK) >> DSTS_SOFFN_SHIFT;
841         else
842                 hsotg->frame_number = (dwc2_readl(hsotg, HFNUM)
843                                        & HFNUM_FRNUM_MASK) >> HFNUM_FRNUM_SHIFT;
844
845         gintsts = dwc2_read_common_intr(hsotg);
846         if (gintsts & ~GINTSTS_PRTINT)
847                 retval = IRQ_HANDLED;
848
849         /* In case of hibernated state gintsts must not work */
850         if (hsotg->hibernated) {
851                 dwc2_handle_gpwrdn_intr(hsotg);
852                 retval = IRQ_HANDLED;
853                 goto out;
854         }
855
856         if (gintsts & GINTSTS_MODEMIS)
857                 dwc2_handle_mode_mismatch_intr(hsotg);
858         if (gintsts & GINTSTS_OTGINT)
859                 dwc2_handle_otg_intr(hsotg);
860         if (gintsts & GINTSTS_CONIDSTSCHNG)
861                 dwc2_handle_conn_id_status_change_intr(hsotg);
862         if (gintsts & GINTSTS_DISCONNINT)
863                 dwc2_handle_disconnect_intr(hsotg);
864         if (gintsts & GINTSTS_SESSREQINT)
865                 dwc2_handle_session_req_intr(hsotg);
866         if (gintsts & GINTSTS_WKUPINT)
867                 dwc2_handle_wakeup_detected_intr(hsotg);
868         if (gintsts & GINTSTS_USBSUSP)
869                 dwc2_handle_usb_suspend_intr(hsotg);
870         if (gintsts & GINTSTS_LPMTRANRCVD)
871                 dwc2_handle_lpm_intr(hsotg);
872
873         if (gintsts & GINTSTS_PRTINT) {
874                 /*
875                  * The port interrupt occurs while in device mode with HPRT0
876                  * Port Enable/Disable
877                  */
878                 if (dwc2_is_device_mode(hsotg)) {
879                         dev_dbg(hsotg->dev,
880                                 " --Port interrupt received in Device mode--\n");
881                         dwc2_handle_usb_port_intr(hsotg);
882                         retval = IRQ_HANDLED;
883                 }
884         }
885
886 out:
887         spin_unlock(&hsotg->lock);
888         return retval;
889 }