OpenCores
URL https://opencores.org/ocsvn/or1k_soc_on_altera_embedded_dev_kit/or1k_soc_on_altera_embedded_dev_kit/trunk

Subversion Repositories or1k_soc_on_altera_embedded_dev_kit

[/] [or1k_soc_on_altera_embedded_dev_kit/] [trunk/] [linux-2.6/] [linux-2.6.24/] [arch/] [sparc/] [kernel/] [ebus.c] - Blame information for rev 3

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 3 xianfeng
/* $Id: ebus.c,v 1.20 2002/01/05 01:13:43 davem Exp $
2
 * ebus.c: PCI to EBus bridge device.
3
 *
4
 * Copyright (C) 1997  Eddie C. Dost  (ecd@skynet.be)
5
 *
6
 * Adopted for sparc by V. Roganov and G. Raiko.
7
 * Fixes for different platforms by Pete Zaitcev.
8
 */
9
 
10
#include <linux/kernel.h>
11
#include <linux/types.h>
12
#include <linux/init.h>
13
#include <linux/slab.h>
14
#include <linux/string.h>
15
 
16
#include <asm/system.h>
17
#include <asm/page.h>
18
#include <asm/pbm.h>
19
#include <asm/ebus.h>
20
#include <asm/io.h>
21
#include <asm/oplib.h>
22
#include <asm/prom.h>
23
#include <asm/bpp.h>
24
 
25
struct linux_ebus *ebus_chain = NULL;
26
 
27
/* We are together with pcic.c under CONFIG_PCI. */
28
extern unsigned int pcic_pin_to_irq(unsigned int, const char *name);
29
 
30
/*
31
 * IRQ Blacklist
32
 * Here we list PROMs and systems that are known to supply crap as IRQ numbers.
33
 */
34
struct ebus_device_irq {
35
        char *name;
36
        unsigned int pin;
37
};
38
 
39
struct ebus_system_entry {
40
        char *esname;
41
        struct ebus_device_irq *ipt;
42
};
43
 
44
static struct ebus_device_irq je1_1[] = {
45
        { "8042",                3 },
46
        { "SUNW,CS4231",         0 },
47
        { "parallel",            0 },
48
        { "se",                  2 },
49
        { NULL, 0 }
50
};
51
 
52
/*
53
 * Gleb's JE1 supplied reasonable pin numbers, but mine did not (OBP 2.32).
54
 * Blacklist the sucker... Note that Gleb's system will work.
55
 */
56
static struct ebus_system_entry ebus_blacklist[] = {
57
        { "SUNW,JavaEngine1", je1_1 },
58
        { NULL, NULL }
59
};
60
 
61
static struct ebus_device_irq *ebus_blackp = NULL;
62
 
63
/*
64
 */
65
static inline unsigned long ebus_alloc(size_t size)
66
{
67
        return (unsigned long)kmalloc(size, GFP_ATOMIC);
68
}
69
 
70
/*
71
 */
72
int __init ebus_blacklist_irq(const char *name)
73
{
74
        struct ebus_device_irq *dp;
75
 
76
        if ((dp = ebus_blackp) != NULL) {
77
                for (; dp->name != NULL; dp++) {
78
                        if (strcmp(name, dp->name) == 0) {
79
                                return pcic_pin_to_irq(dp->pin, name);
80
                        }
81
                }
82
        }
83
        return 0;
84
}
85
 
86
void __init fill_ebus_child(struct device_node *dp,
87
                            struct linux_ebus_child *dev)
88
{
89
        const int *regs;
90
        const int *irqs;
91
        int i, len;
92
 
93
        dev->prom_node = dp;
94
        regs = of_get_property(dp, "reg", &len);
95
        if (!regs)
96
                len = 0;
97
        dev->num_addrs = len / sizeof(regs[0]);
98
 
99
        for (i = 0; i < dev->num_addrs; i++) {
100
                if (regs[i] >= dev->parent->num_addrs) {
101
                        prom_printf("UGH: property for %s was %d, need < %d\n",
102
                                    dev->prom_node->name, len,
103
                                    dev->parent->num_addrs);
104
                        panic(__FUNCTION__);
105
                }
106
 
107
                /* XXX resource */
108
                dev->resource[i].start =
109
                        dev->parent->resource[regs[i]].start;
110
        }
111
 
112
        for (i = 0; i < PROMINTR_MAX; i++)
113
                dev->irqs[i] = PCI_IRQ_NONE;
114
 
115
        if ((dev->irqs[0] = ebus_blacklist_irq(dev->prom_node->name)) != 0) {
116
                dev->num_irqs = 1;
117
        } else {
118
                irqs = of_get_property(dp, "interrupts", &len);
119
                if (!irqs) {
120
                        dev->num_irqs = 0;
121
                        dev->irqs[0] = 0;
122
                        if (dev->parent->num_irqs != 0) {
123
                                dev->num_irqs = 1;
124
                                dev->irqs[0] = dev->parent->irqs[0];
125
                        }
126
                } else {
127
                        dev->num_irqs = len / sizeof(irqs[0]);
128
                        if (irqs[0] == 0 || irqs[0] >= 8) {
129
                                /*
130
                                 * XXX Zero is a valid pin number...
131
                                 * This works as long as Ebus is not wired
132
                                 * to INTA#.
133
                                 */
134
                                printk("EBUS: %s got bad irq %d from PROM\n",
135
                                       dev->prom_node->name, irqs[0]);
136
                                dev->num_irqs = 0;
137
                                dev->irqs[0] = 0;
138
                        } else {
139
                                dev->irqs[0] =
140
                                        pcic_pin_to_irq(irqs[0],
141
                                                        dev->prom_node->name);
142
                        }
143
                }
144
        }
145
}
146
 
147
void __init fill_ebus_device(struct device_node *dp, struct linux_ebus_device *dev)
148
{
149
        const struct linux_prom_registers *regs;
150
        struct linux_ebus_child *child;
151
        struct dev_archdata *sd;
152
        const int *irqs;
153
        int i, n, len;
154
        unsigned long baseaddr;
155
 
156
        dev->prom_node = dp;
157
 
158
        regs = of_get_property(dp, "reg", &len);
159
        if (!regs)
160
                len = 0;
161
        if (len % sizeof(struct linux_prom_registers)) {
162
                prom_printf("UGH: proplen for %s was %d, need multiple of %d\n",
163
                            dev->prom_node->name, len,
164
                            (int)sizeof(struct linux_prom_registers));
165
                panic(__FUNCTION__);
166
        }
167
        dev->num_addrs = len / sizeof(struct linux_prom_registers);
168
 
169
        for (i = 0; i < dev->num_addrs; i++) {
170
                /*
171
                 * XXX Collect JE-1 PROM
172
                 *
173
                 * Example - JS-E with 3.11:
174
                 *  /ebus
175
                 *      regs
176
                 *        0x00000000, 0x0, 0x00000000, 0x0, 0x00000000,
177
                 *        0x82000010, 0x0, 0xf0000000, 0x0, 0x01000000,
178
                 *        0x82000014, 0x0, 0x38800000, 0x0, 0x00800000,
179
                 *      ranges
180
                 *        0x00, 0x00000000, 0x02000010, 0x0, 0x0, 0x01000000,
181
                 *        0x01, 0x01000000, 0x02000014, 0x0, 0x0, 0x00800000,
182
                 *  /ebus/8042
183
                 *      regs
184
                 *        0x00000001, 0x00300060, 0x00000008,
185
                 *        0x00000001, 0x00300060, 0x00000008,
186
                 */
187
                n = regs[i].which_io;
188
                if (n >= 4) {
189
                        /* XXX This is copied from old JE-1 by Gleb. */
190
                        n = (regs[i].which_io - 0x10) >> 2;
191
                } else {
192
                        ;
193
                }
194
 
195
/*
196
 * XXX Now as we have regions, why don't we make an on-demand allocation...
197
 */
198
                dev->resource[i].start = 0;
199
                if ((baseaddr = dev->bus->self->resource[n].start +
200
                    regs[i].phys_addr) != 0) {
201
                        /* dev->resource[i].name = dev->prom_name; */
202
                        if ((baseaddr = (unsigned long) ioremap(baseaddr,
203
                            regs[i].reg_size)) == 0) {
204
                                panic("ebus: unable to remap dev %s",
205
                                      dev->prom_node->name);
206
                        }
207
                }
208
                dev->resource[i].start = baseaddr;      /* XXX Unaligned */
209
        }
210
 
211
        for (i = 0; i < PROMINTR_MAX; i++)
212
                dev->irqs[i] = PCI_IRQ_NONE;
213
 
214
        if ((dev->irqs[0] = ebus_blacklist_irq(dev->prom_node->name)) != 0) {
215
                dev->num_irqs = 1;
216
        } else {
217
                irqs = of_get_property(dp, "interrupts", &len);
218
                if (!irqs) {
219
                        dev->num_irqs = 0;
220
                        if ((dev->irqs[0] = dev->bus->self->irq) != 0) {
221
                                dev->num_irqs = 1;
222
/* P3 */ /* printk("EBUS: child %s irq %d from parent\n", dev->prom_name, dev->irqs[0]); */
223
                        }
224
                } else {
225
                        dev->num_irqs = 1;  /* dev->num_irqs = len / sizeof(irqs[0]); */
226
                        if (irqs[0] == 0 || irqs[0] >= 8) {
227
                                /* See above for the parent. XXX */
228
                                printk("EBUS: %s got bad irq %d from PROM\n",
229
                                       dev->prom_node->name, irqs[0]);
230
                                dev->num_irqs = 0;
231
                                dev->irqs[0] = 0;
232
                        } else {
233
                                dev->irqs[0] =
234
                                        pcic_pin_to_irq(irqs[0],
235
                                                        dev->prom_node->name);
236
                        }
237
                }
238
        }
239
 
240
        sd = &dev->ofdev.dev.archdata;
241
        sd->prom_node = dp;
242
        sd->op = &dev->ofdev;
243
        sd->iommu = dev->bus->ofdev.dev.parent->archdata.iommu;
244
 
245
        dev->ofdev.node = dp;
246
        dev->ofdev.dev.parent = &dev->bus->ofdev.dev;
247
        dev->ofdev.dev.bus = &ebus_bus_type;
248
        sprintf(dev->ofdev.dev.bus_id, "ebus[%08x]", dp->node);
249
 
250
        /* Register with core */
251
        if (of_device_register(&dev->ofdev) != 0)
252
                printk(KERN_DEBUG "ebus: device registration error for %s!\n",
253
                       dp->path_component_name);
254
 
255
        if ((dp = dp->child) != NULL) {
256
                dev->children = (struct linux_ebus_child *)
257
                        ebus_alloc(sizeof(struct linux_ebus_child));
258
 
259
                child = dev->children;
260
                child->next = NULL;
261
                child->parent = dev;
262
                child->bus = dev->bus;
263
                fill_ebus_child(dp, child);
264
 
265
                while ((dp = dp->sibling) != NULL) {
266
                        child->next = (struct linux_ebus_child *)
267
                                ebus_alloc(sizeof(struct linux_ebus_child));
268
 
269
                        child = child->next;
270
                        child->next = NULL;
271
                        child->parent = dev;
272
                        child->bus = dev->bus;
273
                        fill_ebus_child(dp, child);
274
                }
275
        }
276
}
277
 
278
void __init ebus_init(void)
279
{
280
        const struct linux_prom_pci_registers *regs;
281
        struct linux_pbm_info *pbm;
282
        struct linux_ebus_device *dev;
283
        struct linux_ebus *ebus;
284
        struct ebus_system_entry *sp;
285
        struct pci_dev *pdev;
286
        struct pcidev_cookie *cookie;
287
        struct device_node *dp;
288
        struct resource *p;
289
        unsigned short pci_command;
290
        int len, reg, nreg;
291
        int num_ebus = 0;
292
 
293
        dp = of_find_node_by_path("/");
294
        for (sp = ebus_blacklist; sp->esname != NULL; sp++) {
295
                if (strcmp(dp->name, sp->esname) == 0) {
296
                        ebus_blackp = sp->ipt;
297
                        break;
298
                }
299
        }
300
 
301
        pdev = pci_get_device(PCI_VENDOR_ID_SUN, PCI_DEVICE_ID_SUN_EBUS, NULL);
302
        if (!pdev)
303
                return;
304
 
305
        cookie = pdev->sysdata;
306
        dp = cookie->prom_node;
307
 
308
        ebus_chain = ebus = (struct linux_ebus *)
309
                        ebus_alloc(sizeof(struct linux_ebus));
310
        ebus->next = NULL;
311
 
312
        while (dp) {
313
                struct device_node *nd;
314
 
315
                ebus->prom_node = dp;
316
                ebus->self = pdev;
317
                ebus->parent = pbm = cookie->pbm;
318
 
319
                /* Enable BUS Master. */
320
                pci_read_config_word(pdev, PCI_COMMAND, &pci_command);
321
                pci_command |= PCI_COMMAND_MASTER;
322
                pci_write_config_word(pdev, PCI_COMMAND, pci_command);
323
 
324
                regs = of_get_property(dp, "reg", &len);
325
                if (!regs) {
326
                        prom_printf("%s: can't find reg property\n",
327
                                    __FUNCTION__);
328
                        prom_halt();
329
                }
330
                nreg = len / sizeof(struct linux_prom_pci_registers);
331
 
332
                p = &ebus->self->resource[0];
333
                for (reg = 0; reg < nreg; reg++) {
334
                        if (!(regs[reg].which_io & 0x03000000))
335
                                continue;
336
 
337
                        (p++)->start = regs[reg].phys_lo;
338
                }
339
 
340
                ebus->ofdev.node = dp;
341
                ebus->ofdev.dev.parent = &pdev->dev;
342
                ebus->ofdev.dev.bus = &ebus_bus_type;
343
                sprintf(ebus->ofdev.dev.bus_id, "ebus%d", num_ebus);
344
 
345
                /* Register with core */
346
                if (of_device_register(&ebus->ofdev) != 0)
347
                        printk(KERN_DEBUG "ebus: device registration error for %s!\n",
348
                               dp->path_component_name);
349
 
350
 
351
                nd = dp->child;
352
                if (!nd)
353
                        goto next_ebus;
354
 
355
                ebus->devices = (struct linux_ebus_device *)
356
                                ebus_alloc(sizeof(struct linux_ebus_device));
357
 
358
                dev = ebus->devices;
359
                dev->next = NULL;
360
                dev->children = NULL;
361
                dev->bus = ebus;
362
                fill_ebus_device(nd, dev);
363
 
364
                while ((nd = nd->sibling) != NULL) {
365
                        dev->next = (struct linux_ebus_device *)
366
                                ebus_alloc(sizeof(struct linux_ebus_device));
367
 
368
                        dev = dev->next;
369
                        dev->next = NULL;
370
                        dev->children = NULL;
371
                        dev->bus = ebus;
372
                        fill_ebus_device(nd, dev);
373
                }
374
 
375
        next_ebus:
376
                pdev = pci_get_device(PCI_VENDOR_ID_SUN,
377
                                       PCI_DEVICE_ID_SUN_EBUS, pdev);
378
                if (!pdev)
379
                        break;
380
 
381
                cookie = pdev->sysdata;
382
                dp = cookie->prom_node;
383
 
384
                ebus->next = (struct linux_ebus *)
385
                        ebus_alloc(sizeof(struct linux_ebus));
386
                ebus = ebus->next;
387
                ebus->next = NULL;
388
                ++num_ebus;
389
        }
390
        if (pdev)
391
                pci_dev_put(pdev);
392
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.