File: /usr/src/linux/arch/ppc/kernel/gemini_pci.c

1     /*
2      * BK Id: SCCS/s.gemini_pci.c 1.5 05/17/01 18:14:21 cort
3      */
4     #include <linux/kernel.h>
5     #include <linux/init.h>
6     #include <linux/pci.h>
7     #include <linux/malloc.h>
8     
9     #include <asm/machdep.h>
10     #include <asm/gemini.h>
11     #include <asm/byteorder.h>
12     #include <asm/io.h>
13     #include <asm/uaccess.h>
14     #include <asm/pci-bridge.h>
15     
16     #include "pci.h"
17     
18     #define pci_config_addr(bus,dev,offset) \
19             (0x80000000 | (bus<<16) | (dev<<8) | offset)
20     
21     
22     int
23     gemini_pcibios_read_config_byte(struct pci_dev *dev, int offset, u8 *val)
24     {
25     	unsigned long reg;
26     	reg = grackle_read(pci_config_addr(dev->bus->number, dev->devfn,
27     					   (offset & ~(0x3))));
28     	*val = ((reg >> ((offset & 0x3) << 3)) & 0xff);
29     	return PCIBIOS_SUCCESSFUL;
30     }
31     
32     int
33     gemini_pcibios_read_config_word(struct pci_dev *dev, int offset, u16 *val)
34     {
35     	unsigned long reg;
36     	reg = grackle_read(pci_config_addr(dev->bus->number, dev->devfn,
37     					   (offset & ~(0x3))));
38     	*val = ((reg >> ((offset & 0x3) << 3)) & 0xffff);
39     	return PCIBIOS_SUCCESSFUL;
40     }
41     
42     int
43     gemini_pcibios_read_config_dword(struct pci_dev *dev, int offset, u32 *val)
44     {
45     	*val = grackle_read(pci_config_addr(dev->bus->number, dev->devfn,
46     					    (offset & ~(0x3))));
47     	return PCIBIOS_SUCCESSFUL;
48     }
49     
50     int
51     gemini_pcibios_write_config_byte(struct pci_dev *dev, int offset, u8 val)
52     {
53     	unsigned long reg;
54     	int shifts = offset & 0x3;
55     	unsigned int addr = pci_config_addr(dev->bus->number, dev->devfn,
56     					    (offset & ~(0x3)));
57     
58     	reg = grackle_read(addr);
59     	reg = (reg & ~(0xff << (shifts << 3))) | (val << (shifts << 3));
60     	grackle_write(addr, reg );
61     	return PCIBIOS_SUCCESSFUL;
62     }
63     
64     int
65     gemini_pcibios_write_config_word(struct pci_dev *dev, int offset, u16 val)
66     {
67     	unsigned long reg;
68     	int shifts = offset & 0x3;
69     	unsigned int addr = pci_config_addr(dev->bus->number, dev->devfn,
70     					    (offset & ~(0x3)));
71     
72     	reg = grackle_read(addr);
73     	reg = (reg & ~(0xffff << (shifts << 3))) | (val << (shifts << 3));
74     	grackle_write(addr, reg );
75     	return PCIBIOS_SUCCESSFUL;
76     }
77     
78     int
79     gemini_pcibios_write_config_dword(struct pci_dev *dev, int offset, u32 val)
80     {
81     	grackle_write(pci_config_addr(dev->bus->number, dev->devfn,
82     				      (offset & ~(0x3))), val);
83     	return PCIBIOS_SUCCESSFUL;
84     }
85     
86     static struct pci_ops gemini_pci_ops =
87     {
88     	gemini_pcibios_read_config_byte,
89     	gemini_pcibios_read_config_word,
90     	gemini_pcibios_read_config_dword,
91     	gemini_pcibios_write_config_byte,
92     	gemini_pcibios_write_config_word,
93     	gemini_pcibios_write_config_dword
94     };
95     
96     void __init gemini_pcibios_fixup(void)
97     {
98     	int i;
99     	struct pci_dev *dev;
100     	
101     	pci_for_each_dev(dev) {
102     		for(i = 0; i < 6; i++) {
103     			if (dev->resource[i].flags & IORESOURCE_IO) {
104     				dev->resource[i].start |= (0xfe << 24);
105     				dev->resource[i].end |= (0xfe << 24);
106     			}
107     		}
108     	}
109     }
110     
111     
112     /* The "bootloader" for Synergy boards does none of this for us, so we need to
113        lay it all out ourselves... --Dan */
114     void __init gemini_find_bridges(void)
115     {
116     	struct pci_controller* hose;
117     	
118     	ppc_md.pcibios_fixup = gemini_pcibios_fixup;
119     
120     	hose = pcibios_alloc_controller();
121     	if (!hose)
122     		return;
123     	hose->ops = &gemini_pci_ops;
124     }
125