0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <linux/kernel.h>
0010 #include <linux/slab.h>
0011
0012 #include <asm/page.h>
0013 #include <asm/oplib.h>
0014 #include <asm/smp.h>
0015 #include <asm/upa.h>
0016 #include <asm/starfire.h>
0017
0018
0019
0020
0021
0022
0023 int this_is_starfire = 0;
0024
0025 void check_if_starfire(void)
0026 {
0027 phandle ssnode = prom_finddevice("/ssp-serial");
0028 if (ssnode != 0 && (s32)ssnode != -1)
0029 this_is_starfire = 1;
0030 }
0031
0032
0033
0034
0035
0036
0037
0038 struct starfire_irqinfo {
0039 unsigned long imap_slots[32];
0040 unsigned long tregs[32];
0041 struct starfire_irqinfo *next;
0042 int upaid, hwmid;
0043 };
0044
0045 static struct starfire_irqinfo *sflist = NULL;
0046
0047
0048 void starfire_hookup(int upaid)
0049 {
0050 struct starfire_irqinfo *p;
0051 unsigned long treg_base, hwmid, i;
0052
0053 p = kmalloc(sizeof(*p), GFP_KERNEL);
0054 if (!p) {
0055 prom_printf("starfire_hookup: No memory, this is insane.\n");
0056 prom_halt();
0057 }
0058 treg_base = 0x100fc000000UL;
0059 hwmid = ((upaid & 0x3c) << 1) |
0060 ((upaid & 0x40) >> 4) |
0061 (upaid & 0x3);
0062 p->hwmid = hwmid;
0063 treg_base += (hwmid << 33UL);
0064 treg_base += 0x200UL;
0065 for (i = 0; i < 32; i++) {
0066 p->imap_slots[i] = 0UL;
0067 p->tregs[i] = treg_base + (i * 0x10UL);
0068
0069 if (upa_readl(p->tregs[i]) != 0)
0070 p->imap_slots[i] = 0xdeadbeaf;
0071 }
0072 p->upaid = upaid;
0073 p->next = sflist;
0074 sflist = p;
0075 }
0076
0077 unsigned int starfire_translate(unsigned long imap,
0078 unsigned int upaid)
0079 {
0080 struct starfire_irqinfo *p;
0081 unsigned int bus_hwmid;
0082 unsigned int i;
0083
0084 bus_hwmid = (((unsigned long)imap) >> 33) & 0x7f;
0085 for (p = sflist; p != NULL; p = p->next)
0086 if (p->hwmid == bus_hwmid)
0087 break;
0088 if (p == NULL) {
0089 prom_printf("XFIRE: Cannot find irqinfo for imap %016lx\n",
0090 ((unsigned long)imap));
0091 prom_halt();
0092 }
0093 for (i = 0; i < 32; i++) {
0094 if (p->imap_slots[i] == imap ||
0095 p->imap_slots[i] == 0UL)
0096 break;
0097 }
0098 if (i == 32) {
0099 printk("starfire_translate: Are you kidding me?\n");
0100 panic("Lucy in the sky....");
0101 }
0102 p->imap_slots[i] = imap;
0103
0104
0105 upaid = (((upaid & 0x3c) << 1) |
0106 ((upaid & 0x40) >> 4) |
0107 (upaid & 0x3));
0108
0109 upa_writel(upaid, p->tregs[i]);
0110
0111 return i;
0112 }