root/arch/sparc/kernel/starfire.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. check_if_starfire
  2. starfire_hookup
  3. starfire_translate

   1 // SPDX-License-Identifier: GPL-2.0
   2 /*
   3  * starfire.c: Starfire/E10000 support.
   4  *
   5  * Copyright (C) 1998 David S. Miller (davem@redhat.com)
   6  * Copyright (C) 2000 Anton Blanchard (anton@samba.org)
   7  */
   8 
   9 #include <linux/kernel.h>
  10 #include <linux/slab.h>
  11 
  12 #include <asm/page.h>
  13 #include <asm/oplib.h>
  14 #include <asm/smp.h>
  15 #include <asm/upa.h>
  16 #include <asm/starfire.h>
  17 
  18 /*
  19  * A few places around the kernel check this to see if
  20  * they need to call us to do things in a Starfire specific
  21  * way.
  22  */
  23 int this_is_starfire = 0;
  24 
  25 void check_if_starfire(void)
  26 {
  27         phandle ssnode = prom_finddevice("/ssp-serial");
  28         if (ssnode != 0 && (s32)ssnode != -1)
  29                 this_is_starfire = 1;
  30 }
  31 
  32 /*
  33  * Each Starfire board has 32 registers which perform translation
  34  * and delivery of traditional interrupt packets into the extended
  35  * Starfire hardware format.  Essentially UPAID's now have 2 more
  36  * bits than in all previous Sun5 systems.
  37  */
  38 struct starfire_irqinfo {
  39         unsigned long imap_slots[32];
  40         unsigned long tregs[32];
  41         struct starfire_irqinfo *next;
  42         int upaid, hwmid;
  43 };
  44 
  45 static struct starfire_irqinfo *sflist = NULL;
  46 
  47 /* Beam me up Scott(McNeil)y... */
  48 void starfire_hookup(int upaid)
  49 {
  50         struct starfire_irqinfo *p;
  51         unsigned long treg_base, hwmid, i;
  52 
  53         p = kmalloc(sizeof(*p), GFP_KERNEL);
  54         if (!p) {
  55                 prom_printf("starfire_hookup: No memory, this is insane.\n");
  56                 prom_halt();
  57         }
  58         treg_base = 0x100fc000000UL;
  59         hwmid = ((upaid & 0x3c) << 1) |
  60                 ((upaid & 0x40) >> 4) |
  61                 (upaid & 0x3);
  62         p->hwmid = hwmid;
  63         treg_base += (hwmid << 33UL);
  64         treg_base += 0x200UL;
  65         for (i = 0; i < 32; i++) {
  66                 p->imap_slots[i] = 0UL;
  67                 p->tregs[i] = treg_base + (i * 0x10UL);
  68                 /* Lets play it safe and not overwrite existing mappings */
  69                 if (upa_readl(p->tregs[i]) != 0)
  70                         p->imap_slots[i] = 0xdeadbeaf;
  71         }
  72         p->upaid = upaid;
  73         p->next = sflist;
  74         sflist = p;
  75 }
  76 
  77 unsigned int starfire_translate(unsigned long imap,
  78                                 unsigned int upaid)
  79 {
  80         struct starfire_irqinfo *p;
  81         unsigned int bus_hwmid;
  82         unsigned int i;
  83 
  84         bus_hwmid = (((unsigned long)imap) >> 33) & 0x7f;
  85         for (p = sflist; p != NULL; p = p->next)
  86                 if (p->hwmid == bus_hwmid)
  87                         break;
  88         if (p == NULL) {
  89                 prom_printf("XFIRE: Cannot find irqinfo for imap %016lx\n",
  90                             ((unsigned long)imap));
  91                 prom_halt();
  92         }
  93         for (i = 0; i < 32; i++) {
  94                 if (p->imap_slots[i] == imap ||
  95                     p->imap_slots[i] == 0UL)
  96                         break;
  97         }
  98         if (i == 32) {
  99                 printk("starfire_translate: Are you kidding me?\n");
 100                 panic("Lucy in the sky....");
 101         }
 102         p->imap_slots[i] = imap;
 103 
 104         /* map to real upaid */
 105         upaid = (((upaid & 0x3c) << 1) |
 106                  ((upaid & 0x40) >> 4) |
 107                  (upaid & 0x3));
 108 
 109         upa_writel(upaid, p->tregs[i]);
 110 
 111         return i;
 112 }

/* [<][>][^][v][top][bottom][index][help] */