1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
|
--- linux-2.6.24.org/arch/arm/mach-oxnas/pci.c 2009-03-09 14:26:43.000000000 +0100
+++ linux-2.6.24/arch/arm/mach-oxnas/pci.c 2009-03-09 14:31:12.000000000 +0100
@@ -25,6 +25,7 @@
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/delay.h>
+#include <linux/jiffies.h>
#include <asm/io.h>
#include <asm/hardware.h>
@@ -71,6 +72,12 @@
extern spinlock_t oxnas_gpio_spinlock;
+#ifdef CONFIG_OXNAS_PCI_RESET
+static unsigned long pci_trhfa_startwait = 0;
+static unsigned long pci_trhfa_msec = 0;
+static unsigned long pci_trhfa_timeout = 0;
+#endif // CONFIG_OXNAS_PCI_RESET
+
#define PCI_BUS_NONMEM_START 0x00000000
#define PCI_BUS_NONMEM_SIZE 0x00080000
@@ -505,6 +512,15 @@
struct pci_bus *oxnas_pci_scan_bus(int nr, struct pci_sys_data *sys)
{
// printk(KERN_DEBUG "PCI: oxnas_pci_scan_bus\n");
+
+#ifdef CONFIG_OXNAS_PCI_RESET
+ printk(KERN_DEBUG "PCI: oxnas_pci_scan_bus now it's %lu, still waiting till %lu to become ready for config\n", jiffies, pci_trhfa_timeout);
+ if (time_after_eq(jiffies + msecs_to_jiffies(pci_trhfa_msec), pci_trhfa_timeout)) /* ensure not wrap */
+ while(time_before(jiffies, pci_trhfa_timeout))
+ udelay(100);
+ printk(KERN_DEBUG "PCI: oxnas_pci_scan_bus waited from %lu to %lu to become ready for config\n", pci_trhfa_startwait, jiffies);
+#endif // CONFIG_OXNAS_PCI_RESET
+
return pci_scan_bus(sys->busnr, &oxnas_pci_ops, sys);
}
@@ -651,6 +667,16 @@
static int __init oxnas_pci_init(void)
{
+#ifdef CONFIG_OXNAS_PCI_RESET
+ // CPU has reset PCI bus via GPIO.
+ // According to PCI spec, we have to wait for 2^25 PCI clocks to meet
+ // the PCI timing parameter Trhfa (RST# high to first access).
+ pci_trhfa_startwait = jiffies;
+ pci_trhfa_msec = 1000; // 1 sec should be fine for 33MHz
+ pci_trhfa_timeout = jiffies + msecs_to_jiffies(pci_trhfa_msec);
+ printk(KERN_DEBUG "PCI: oxnas_pci_init now it's %lu, will wait till %lu to become ready for config\n", pci_trhfa_startwait, pci_trhfa_timeout);
+#endif // CONFIG_OXNAS_PCI_RESET
+
pci_common_init(&oxnas_pci);
return 0;
}
|