0091-dwc_otg-FIQ-support-on-SMP.-Set-up-FIQ-stack-and-han.patch 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. From e9898a39fce7db84ae56329d4f90da92af3bd584 Mon Sep 17 00:00:00 2001
  2. From: P33M <P33M@github.com>
  3. Date: Wed, 24 Sep 2014 11:57:51 +0100
  4. Subject: [PATCH 091/114] dwc_otg: FIQ support on SMP. Set up FIQ stack and
  5. handler on Core 0 only.
  6. ---
  7. drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c | 96 ++++++++++++++--------------
  8. 1 file changed, 49 insertions(+), 47 deletions(-)
  9. --- a/drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c
  10. +++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c
  11. @@ -397,7 +397,55 @@ static struct fiq_handler fh = {
  12. .name = "usb_fiq",
  13. };
  14. +static void hcd_init_fiq(void *cookie)
  15. +{
  16. + dwc_otg_device_t *otg_dev = cookie;
  17. + dwc_otg_hcd_t *dwc_otg_hcd = otg_dev->hcd;
  18. + struct pt_regs regs;
  19. +
  20. + if (claim_fiq(&fh)) {
  21. + DWC_ERROR("Can't claim FIQ");
  22. + BUG();
  23. + }
  24. + DWC_WARN("FIQ at 0x%08x", (fiq_fsm_enable ? (int)&dwc_otg_fiq_fsm : (int)&dwc_otg_fiq_nop));
  25. + DWC_WARN("FIQ ASM at 0x%08x length %d", (int)&_dwc_otg_fiq_stub, (int)(&_dwc_otg_fiq_stub_end - &_dwc_otg_fiq_stub));
  26. + set_fiq_handler((void *) &_dwc_otg_fiq_stub, &_dwc_otg_fiq_stub_end - &_dwc_otg_fiq_stub);
  27. + memset(&regs,0,sizeof(regs));
  28. +
  29. + regs.ARM_r8 = (long) dwc_otg_hcd->fiq_state;
  30. + if (fiq_fsm_enable) {
  31. + regs.ARM_r9 = dwc_otg_hcd->core_if->core_params->host_channels;
  32. + //regs.ARM_r10 = dwc_otg_hcd->dma;
  33. + regs.ARM_fp = (long) dwc_otg_fiq_fsm;
  34. + } else {
  35. + regs.ARM_fp = (long) dwc_otg_fiq_nop;
  36. + }
  37. +
  38. + regs.ARM_sp = (long) dwc_otg_hcd->fiq_stack + (sizeof(struct fiq_stack) - 4);
  39. +
  40. +// __show_regs(&regs);
  41. + set_fiq_regs(&regs);
  42. + //Set the mphi periph to the required registers
  43. + dwc_otg_hcd->fiq_state->mphi_regs.base = otg_dev->os_dep.mphi_base;
  44. + dwc_otg_hcd->fiq_state->mphi_regs.ctrl = otg_dev->os_dep.mphi_base + 0x4c;
  45. + dwc_otg_hcd->fiq_state->mphi_regs.outdda = otg_dev->os_dep.mphi_base + 0x28;
  46. + dwc_otg_hcd->fiq_state->mphi_regs.outddb = otg_dev->os_dep.mphi_base + 0x2c;
  47. + dwc_otg_hcd->fiq_state->mphi_regs.intstat = otg_dev->os_dep.mphi_base + 0x50;
  48. + dwc_otg_hcd->fiq_state->dwc_regs_base = otg_dev->os_dep.base;
  49. + DWC_WARN("MPHI regs_base at 0x%08x", (int)dwc_otg_hcd->fiq_state->mphi_regs.base);
  50. + //Enable mphi peripheral
  51. + writel((1<<31),dwc_otg_hcd->fiq_state->mphi_regs.ctrl);
  52. +#ifdef DEBUG
  53. + if (readl(dwc_otg_hcd->fiq_state->mphi_regs.ctrl) & 0x80000000)
  54. + DWC_WARN("MPHI periph has been enabled");
  55. + else
  56. + DWC_WARN("MPHI periph has NOT been enabled");
  57. +#endif
  58. + // Enable FIQ interrupt from USB peripheral
  59. + enable_fiq(INTERRUPT_VC_USB);
  60. + local_fiq_enable();
  61. +}
  62. /**
  63. * Initializes the HCD. This function allocates memory for and initializes the
  64. @@ -412,7 +460,6 @@ int hcd_init(dwc_bus_dev_t *_dev)
  65. dwc_otg_device_t *otg_dev = DWC_OTG_BUSDRVDATA(_dev);
  66. int retval = 0;
  67. u64 dmamask;
  68. - struct pt_regs regs;
  69. DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD INIT otg_dev=%p\n", otg_dev);
  70. @@ -464,52 +511,7 @@ int hcd_init(dwc_bus_dev_t *_dev)
  71. }
  72. if (fiq_enable)
  73. - {
  74. - if (claim_fiq(&fh)) {
  75. - DWC_ERROR("Can't claim FIQ");
  76. - goto error2;
  77. - }
  78. -
  79. - DWC_WARN("FIQ at 0x%08x", (fiq_fsm_enable ? (int)&dwc_otg_fiq_fsm : (int)&dwc_otg_fiq_nop));
  80. - DWC_WARN("FIQ ASM at 0x%08x length %d", (int)&_dwc_otg_fiq_stub, (int)(&_dwc_otg_fiq_stub_end - &_dwc_otg_fiq_stub));
  81. -
  82. - set_fiq_handler((void *) &_dwc_otg_fiq_stub, &_dwc_otg_fiq_stub_end - &_dwc_otg_fiq_stub);
  83. - memset(&regs,0,sizeof(regs));
  84. -
  85. - regs.ARM_r8 = (long) dwc_otg_hcd->fiq_state;
  86. - if (fiq_fsm_enable) {
  87. - regs.ARM_r9 = dwc_otg_hcd->core_if->core_params->host_channels;
  88. - //regs.ARM_r10 = dwc_otg_hcd->dma;
  89. - regs.ARM_fp = (long) dwc_otg_fiq_fsm;
  90. - } else {
  91. - regs.ARM_fp = (long) dwc_otg_fiq_nop;
  92. - }
  93. -
  94. - regs.ARM_sp = (long) dwc_otg_hcd->fiq_stack + (sizeof(struct fiq_stack) - 4);
  95. -
  96. -// __show_regs(&regs);
  97. - set_fiq_regs(&regs);
  98. -
  99. - //Set the mphi periph to the required registers
  100. - dwc_otg_hcd->fiq_state->mphi_regs.base = otg_dev->os_dep.mphi_base;
  101. - dwc_otg_hcd->fiq_state->mphi_regs.ctrl = otg_dev->os_dep.mphi_base + 0x4c;
  102. - dwc_otg_hcd->fiq_state->mphi_regs.outdda = otg_dev->os_dep.mphi_base + 0x28;
  103. - dwc_otg_hcd->fiq_state->mphi_regs.outddb = otg_dev->os_dep.mphi_base + 0x2c;
  104. - dwc_otg_hcd->fiq_state->mphi_regs.intstat = otg_dev->os_dep.mphi_base + 0x50;
  105. - dwc_otg_hcd->fiq_state->dwc_regs_base = otg_dev->os_dep.base;
  106. - DWC_WARN("MPHI regs_base at 0x%08x", (int)dwc_otg_hcd->fiq_state->mphi_regs.base);
  107. - //Enable mphi peripheral
  108. - writel((1<<31),dwc_otg_hcd->fiq_state->mphi_regs.ctrl);
  109. -#ifdef DEBUG
  110. - if (readl(dwc_otg_hcd->fiq_state->mphi_regs.ctrl) & 0x80000000)
  111. - DWC_WARN("MPHI periph has been enabled");
  112. - else
  113. - DWC_WARN("MPHI periph has NOT been enabled");
  114. -#endif
  115. - // Enable FIQ interrupt from USB peripheral
  116. - enable_fiq(INTERRUPT_VC_USB);
  117. - local_fiq_enable();
  118. - }
  119. + smp_call_function_single(0, hcd_init_fiq, otg_dev, 1);
  120. otg_dev->hcd->otg_dev = otg_dev;