File: /usr/src/linux/arch/sparc64/kernel/isa.c

1     #include <linux/kernel.h>
2     #include <linux/init.h>
3     #include <linux/pci.h>
4     #include <linux/slab.h>
5     #include <asm/oplib.h>
6     #include <asm/isa.h>
7     
8     struct isa_bridge *isa_chain;
9     
10     static void __init fatal_err(const char *reason)
11     {
12     	prom_printf("ISA: fatal error, %s.\n", reason);
13     }
14     
15     static void __init report_dev(struct isa_device *isa_dev, int child)
16     {
17     	if (child)
18     		printk(" (%s)", isa_dev->prom_name);
19     	else
20     		printk(" [%s", isa_dev->prom_name);
21     }
22     
23     static void __init isa_dev_get_resource(struct isa_device *isa_dev)
24     {
25     	struct linux_prom_registers regs[PROMREG_MAX];
26     	unsigned long base, len;
27     	int prop_len;
28     
29     	prop_len = prom_getproperty(isa_dev->prom_node, "reg",
30     				    (char *) regs, sizeof(regs));
31     
32     	if (prop_len <= 0)
33     		return;
34     
35     	/* Only the first one is interesting. */
36     	len = regs[0].reg_size;
37     	base = (((unsigned long)regs[0].which_io << 32) |
38     		(unsigned long)regs[0].phys_addr);
39     	base += isa_dev->bus->parent->io_space.start;
40     
41     	isa_dev->resource.start = base;
42     	isa_dev->resource.end   = (base + len - 1UL);
43     	isa_dev->resource.flags = IORESOURCE_IO;
44     	isa_dev->resource.name  = isa_dev->prom_name;
45     
46     	request_resource(&isa_dev->bus->parent->io_space,
47     			 &isa_dev->resource);
48     }
49     
50     /* I can't believe they didn't put a real INO in the isa device
51      * interrupts property.  The whole point of the OBP properties
52      * is to shield the kernel from IRQ routing details.
53      *
54      * The P1275 standard for ISA devices seems to also have been
55      * totally ignored.
56      */
57     static struct {
58     	int	obp_irq;
59     	int	pci_ino;
60     } grover_irq_table[] = {
61     	{ 1, 0x00 },	/* dma, unknown ino at this point */
62     	{ 2, 0x27 },	/* floppy */
63     	{ 3, 0x22 },	/* parallel */
64     	{ 4, 0x2b },	/* serial */
65     	{ 5, 0x25 },	/* acpi power management */
66     
67     	{ 0, 0x00 }	/* end of table */
68     };
69     
70     static void __init isa_dev_get_irq(struct isa_device *isa_dev)
71     {
72     	int irq_prop;
73     
74     	irq_prop = prom_getintdefault(isa_dev->prom_node,
75     				      "interrupts", -1);
76     	if (irq_prop <= 0) {
77     		isa_dev->irq = 0;
78     	} else {
79     		int i;
80     
81     		for (i = 0; grover_irq_table[i].obp_irq != 0; i++) {
82     			if (grover_irq_table[i].obp_irq == irq_prop) {
83     				struct pci_controller_info *pcic;
84     				struct pci_pbm_info *pbm;
85     				int ino = grover_irq_table[i].pci_ino;
86     
87     				if (ino == 0) {
88     					isa_dev->irq = 0;
89     				} else {
90     					pbm = isa_dev->bus->parent;
91     					pcic = pbm->parent;
92     					isa_dev->irq = pcic->irq_build(pbm, NULL, ino);
93     				}
94     			}
95     		}
96     	}
97     }
98     
99     static void __init isa_fill_children(struct isa_device *parent_isa_dev)
100     {
101     	int node = prom_getchild(parent_isa_dev->prom_node);
102     
103     	if (node == 0)
104     		return;
105     
106     	printk(" ->");
107     	while (node != 0) {
108     		struct isa_device *isa_dev;
109     		int prop_len;
110     
111     		isa_dev = kmalloc(sizeof(*isa_dev), GFP_KERNEL);
112     		if (!isa_dev) {
113     			fatal_err("cannot allocate child isa_dev");
114     			prom_halt();
115     		}
116     
117     		memset(isa_dev, 0, sizeof(*isa_dev));
118     
119     		/* Link it in to parent. */
120     		isa_dev->next = parent_isa_dev->child;
121     		parent_isa_dev->child = isa_dev;
122     
123     		isa_dev->bus = parent_isa_dev->bus;
124     		isa_dev->prom_node = node;
125     		prop_len = prom_getproperty(node, "name",
126     					    (char *) isa_dev->prom_name,
127     					    sizeof(isa_dev->prom_name));
128     		if (prop_len <= 0) {
129     			fatal_err("cannot get child isa_dev OBP node name");
130     			prom_halt();
131     		}
132     
133     		prop_len = prom_getproperty(node, "compatible",
134     					    (char *) isa_dev->compatible,
135     					    sizeof(isa_dev->compatible));
136     
137     		/* Not having this is OK. */
138     		if (prop_len <= 0)
139     			isa_dev->compatible[0] = '\0';
140     
141     		isa_dev_get_resource(isa_dev);
142     		isa_dev_get_irq(isa_dev);
143     
144     		report_dev(isa_dev, 1);
145     
146     		node = prom_getsibling(node);
147     	}
148     }
149     
150     static void __init isa_fill_devices(struct isa_bridge *isa_br)
151     {
152     	int node = prom_getchild(isa_br->prom_node);
153     
154     	while (node != 0) {
155     		struct isa_device *isa_dev;
156     		int prop_len;
157     
158     		isa_dev = kmalloc(sizeof(*isa_dev), GFP_KERNEL);
159     		if (!isa_dev) {
160     			fatal_err("cannot allocate isa_dev");
161     			prom_halt();
162     		}
163     
164     		memset(isa_dev, 0, sizeof(*isa_dev));
165     
166     		/* Link it in. */
167     		isa_dev->next = NULL;
168     		if (isa_br->devices == NULL) {
169     			isa_br->devices = isa_dev;
170     		} else {
171     			struct isa_device *tmp = isa_br->devices;
172     
173     			while (tmp->next)
174     				tmp = tmp->next;
175     
176     			tmp->next = isa_dev;
177     		}
178     
179     		isa_dev->bus = isa_br;
180     		isa_dev->prom_node = node;
181     		prop_len = prom_getproperty(node, "name",
182     					    (char *) isa_dev->prom_name,
183     					    sizeof(isa_dev->prom_name));
184     		if (prop_len <= 0) {
185     			fatal_err("cannot get isa_dev OBP node name");
186     			prom_halt();
187     		}
188     
189     		prop_len = prom_getproperty(node, "compatible",
190     					    (char *) isa_dev->compatible,
191     					    sizeof(isa_dev->compatible));
192     
193     		/* Not having this is OK. */
194     		if (prop_len <= 0)
195     			isa_dev->compatible[0] = '\0';
196     
197     		isa_dev_get_resource(isa_dev);
198     		isa_dev_get_irq(isa_dev);
199     
200     		report_dev(isa_dev, 0);
201     
202     		isa_fill_children(isa_dev);
203     
204     		printk("]");
205     
206     		node = prom_getsibling(node);
207     	}
208     }
209     
210     void __init isa_init(void)
211     {
212     	struct pci_dev *pdev;
213     	unsigned short vendor, device;
214     	int index = 0;
215     
216     	vendor = PCI_VENDOR_ID_AL;
217     	device = PCI_DEVICE_ID_AL_M1533;
218     
219     	pdev = NULL;
220     	while ((pdev = pci_find_device(vendor, device, pdev)) != NULL) {
221     		struct pcidev_cookie *pdev_cookie;
222     		struct pci_pbm_info *pbm;
223     		struct isa_bridge *isa_br;
224     		int prop_len;
225     
226     		pdev_cookie = pdev->sysdata;
227     		if (!pdev_cookie) {
228     			printk("ISA: Warning, ISA bridge ignored due to "
229     			       "lack of OBP data.\n");
230     			continue;
231     		}
232     		pbm = pdev_cookie->pbm;
233     
234     		isa_br = kmalloc(sizeof(*isa_br), GFP_KERNEL);
235     		if (!isa_br) {
236     			fatal_err("cannot allocate isa_bridge");
237     			prom_halt();
238     		}
239     
240     		memset(isa_br, 0, sizeof(*isa_br));
241     
242     		/* Link it in. */
243     		isa_br->next = isa_chain;
244     		isa_chain = isa_br;
245     
246     		isa_br->parent = pbm;
247     		isa_br->self = pdev;
248     		isa_br->index = index++;
249     		isa_br->prom_node = pdev_cookie->prom_node;
250     		strncpy(isa_br->prom_name, pdev_cookie->prom_name,
251     			sizeof(isa_br->prom_name));
252     
253     		prop_len = prom_getproperty(isa_br->prom_node,
254     					    "ranges",
255     					    (char *) isa_br->isa_ranges,
256     					    sizeof(isa_br->isa_ranges));
257     		if (prop_len <= 0)
258     			isa_br->num_isa_ranges = 0;
259     		else
260     			isa_br->num_isa_ranges =
261     				(prop_len / sizeof(struct linux_prom_isa_ranges));
262     
263     		printk("isa%d:", isa_br->index);
264     
265     		isa_fill_devices(isa_br);
266     
267     		printk("\n");
268     	}
269     }
270