common.c 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. // SPDX-License-Identifier: GPL-2.0
  2. #include <linux/pci.h>
  3. #include <linux/interrupt.h>
  4. #include <linux/timer.h>
  5. #include <linux/kernel.h>
  6. /*
  7. * These functions are used early on before PCI scanning is done
  8. * and all of the pci_dev and pci_bus structures have been created.
  9. */
  10. static struct pci_dev *fake_pci_dev(struct pci_channel *hose,
  11. int top_bus, int busnr, int devfn)
  12. {
  13. static struct pci_dev dev;
  14. static struct pci_bus bus;
  15. dev.bus = &bus;
  16. dev.sysdata = hose;
  17. dev.devfn = devfn;
  18. bus.number = busnr;
  19. bus.sysdata = hose;
  20. bus.ops = hose->pci_ops;
  21. if(busnr != top_bus)
  22. /* Fake a parent bus structure. */
  23. bus.parent = &bus;
  24. else
  25. bus.parent = NULL;
  26. return &dev;
  27. }
  28. #define EARLY_PCI_OP(rw, size, type) \
  29. int __init early_##rw##_config_##size(struct pci_channel *hose, \
  30. int top_bus, int bus, int devfn, int offset, type value) \
  31. { \
  32. return pci_##rw##_config_##size( \
  33. fake_pci_dev(hose, top_bus, bus, devfn), \
  34. offset, value); \
  35. }
  36. EARLY_PCI_OP(read, byte, u8 *)
  37. EARLY_PCI_OP(read, word, u16 *)
  38. EARLY_PCI_OP(read, dword, u32 *)
  39. EARLY_PCI_OP(write, byte, u8)
  40. EARLY_PCI_OP(write, word, u16)
  41. EARLY_PCI_OP(write, dword, u32)
  42. int __init pci_is_66mhz_capable(struct pci_channel *hose,
  43. int top_bus, int current_bus)
  44. {
  45. u32 pci_devfn;
  46. unsigned short vid;
  47. int cap66 = -1;
  48. u16 stat;
  49. pr_info("PCI: Checking 66MHz capabilities...\n");
  50. for (pci_devfn = 0; pci_devfn < 0xff; pci_devfn++) {
  51. if (PCI_FUNC(pci_devfn))
  52. continue;
  53. if (early_read_config_word(hose, top_bus, current_bus,
  54. pci_devfn, PCI_VENDOR_ID, &vid) !=
  55. PCIBIOS_SUCCESSFUL)
  56. continue;
  57. if (vid == 0xffff)
  58. continue;
  59. /* check 66MHz capability */
  60. if (cap66 < 0)
  61. cap66 = 1;
  62. if (cap66) {
  63. early_read_config_word(hose, top_bus, current_bus,
  64. pci_devfn, PCI_STATUS, &stat);
  65. if (!(stat & PCI_STATUS_66MHZ)) {
  66. printk(KERN_DEBUG
  67. "PCI: %02x:%02x not 66MHz capable.\n",
  68. current_bus, pci_devfn);
  69. cap66 = 0;
  70. break;
  71. }
  72. }
  73. }
  74. return cap66 > 0;
  75. }
  76. static void pcibios_enable_err(struct timer_list *t)
  77. {
  78. struct pci_channel *hose = from_timer(hose, t, err_timer);
  79. del_timer(&hose->err_timer);
  80. printk(KERN_DEBUG "PCI: re-enabling error IRQ.\n");
  81. enable_irq(hose->err_irq);
  82. }
  83. static void pcibios_enable_serr(struct timer_list *t)
  84. {
  85. struct pci_channel *hose = from_timer(hose, t, serr_timer);
  86. del_timer(&hose->serr_timer);
  87. printk(KERN_DEBUG "PCI: re-enabling system error IRQ.\n");
  88. enable_irq(hose->serr_irq);
  89. }
  90. void pcibios_enable_timers(struct pci_channel *hose)
  91. {
  92. if (hose->err_irq) {
  93. timer_setup(&hose->err_timer, pcibios_enable_err, 0);
  94. }
  95. if (hose->serr_irq) {
  96. timer_setup(&hose->serr_timer, pcibios_enable_serr, 0);
  97. }
  98. }
  99. /*
  100. * A simple handler for the regular PCI status errors, called from IRQ
  101. * context.
  102. */
  103. unsigned int pcibios_handle_status_errors(unsigned long addr,
  104. unsigned int status,
  105. struct pci_channel *hose)
  106. {
  107. unsigned int cmd = 0;
  108. if (status & PCI_STATUS_REC_MASTER_ABORT) {
  109. printk(KERN_DEBUG "PCI: master abort, pc=0x%08lx\n", addr);
  110. cmd |= PCI_STATUS_REC_MASTER_ABORT;
  111. }
  112. if (status & PCI_STATUS_REC_TARGET_ABORT) {
  113. printk(KERN_DEBUG "PCI: target abort: ");
  114. pcibios_report_status(PCI_STATUS_REC_TARGET_ABORT |
  115. PCI_STATUS_SIG_TARGET_ABORT |
  116. PCI_STATUS_REC_MASTER_ABORT, 1);
  117. pr_cont("\n");
  118. cmd |= PCI_STATUS_REC_TARGET_ABORT;
  119. }
  120. if (status & (PCI_STATUS_PARITY | PCI_STATUS_DETECTED_PARITY)) {
  121. printk(KERN_DEBUG "PCI: parity error detected: ");
  122. pcibios_report_status(PCI_STATUS_PARITY |
  123. PCI_STATUS_DETECTED_PARITY, 1);
  124. pr_cont("\n");
  125. cmd |= PCI_STATUS_PARITY | PCI_STATUS_DETECTED_PARITY;
  126. /* Now back off of the IRQ for awhile */
  127. if (hose->err_irq) {
  128. disable_irq_nosync(hose->err_irq);
  129. hose->err_timer.expires = jiffies + HZ;
  130. add_timer(&hose->err_timer);
  131. }
  132. }
  133. return cmd;
  134. }