Commit 8fae097debdf8ac9b66d220ac258535ea09f3898

Authored by David S. Miller
1 parent d384ea691f

[SBUS]: Start cleaning up generic sbus support layer.

In particular, move the IRQ probing out to sparc32/sparc64
arch specific code where it belongs.

Signed-off-by: David S. Miller <davem@davemloft.net>

Showing 5 changed files with 87 additions and 125 deletions Side-by-side Diff

arch/sparc/kernel/ioport.c
... ... @@ -224,8 +224,52 @@
224 224  
225 225 #ifdef CONFIG_SBUS
226 226  
227   -void sbus_set_sbus64(struct sbus_dev *sdev, int x) {
  227 +void sbus_set_sbus64(struct sbus_dev *sdev, int x)
  228 +{
228 229 printk("sbus_set_sbus64: unsupported\n");
  230 +}
  231 +
  232 +extern unsigned int sun4d_build_irq(struct sbus_dev *sdev, int irq);
  233 +void __init sbus_fill_device_irq(struct sbus_dev *sdev)
  234 +{
  235 + struct linux_prom_irqs irqs[PROMINTR_MAX];
  236 + int len;
  237 +
  238 + len = prom_getproperty(sdev->prom_node, "intr",
  239 + (char *)irqs, sizeof(irqs));
  240 + if (len != -1) {
  241 + sdev->num_irqs = len / 8;
  242 + if (sdev->num_irqs == 0) {
  243 + sdev->irqs[0] = 0;
  244 + } else if (sparc_cpu_model == sun4d) {
  245 + for (len = 0; len < sdev->num_irqs; len++)
  246 + sdev->irqs[len] =
  247 + sun4d_build_irq(sdev, irqs[len].pri);
  248 + } else {
  249 + for (len = 0; len < sdev->num_irqs; len++)
  250 + sdev->irqs[len] = irqs[len].pri;
  251 + }
  252 + } else {
  253 + int interrupts[PROMINTR_MAX];
  254 +
  255 + /* No "intr" node found-- check for "interrupts" node.
  256 + * This node contains SBus interrupt levels, not IPLs
  257 + * as in "intr", and no vector values. We convert
  258 + * SBus interrupt levels to PILs (platform specific).
  259 + */
  260 + len = prom_getproperty(sdev->prom_node, "interrupts",
  261 + (char *)interrupts, sizeof(interrupts));
  262 + if (len == -1) {
  263 + sdev->irqs[0] = 0;
  264 + sdev->num_irqs = 0;
  265 + } else {
  266 + sdev->num_irqs = len / sizeof(int);
  267 + for (len = 0; len < sdev->num_irqs; len++) {
  268 + sdev->irqs[len] =
  269 + sbint_to_irq(sdev, interrupts[len]);
  270 + }
  271 + }
  272 + }
229 273 }
230 274  
231 275 /*
arch/sparc64/kernel/sbus.c
... ... @@ -1225,4 +1225,25 @@
1225 1225  
1226 1226 sysio_register_error_handlers(sbus);
1227 1227 }
  1228 +
  1229 +void sbus_fill_device_irq(struct sbus_dev *sdev)
  1230 +{
  1231 + struct linux_prom_irqs irqs[PROMINTR_MAX];
  1232 + int len;
  1233 +
  1234 + len = prom_getproperty(sdev->prom_node, "interrupts",
  1235 + (char *) irqs, sizeof(irqs));
  1236 + if (len == -1 || len == 0) {
  1237 + sdev->irqs[0] = 0;
  1238 + sdev->num_irqs = 0;
  1239 + } else {
  1240 + unsigned int pri = irqs[0].pri;
  1241 +
  1242 + sdev->num_irqs = 1;
  1243 + if (pri < 0x20)
  1244 + pri += sdev->slot * 8;
  1245 +
  1246 + sdev->irqs[0] = sbus_build_irq(sdev->bus, pri);
  1247 + }
  1248 +}
1   -/* $Id: sbus.c,v 1.100 2002/01/24 15:36:24 davem Exp $
2   - * sbus.c: SBus support routines.
  1 +/* sbus.c: SBus support routines.
3 2 *
4   - * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
  3 + * Copyright (C) 1995, 2006 David S. Miller (davem@davemloft.net)
5 4 */
6 5  
7 6 #include <linux/kernel.h>
8 7  
9 8  
... ... @@ -17,29 +16,12 @@
17 16 #include <asm/bpp.h>
18 17 #include <asm/irq.h>
19 18  
20   -struct sbus_bus *sbus_root = NULL;
  19 +struct sbus_bus *sbus_root;
21 20  
22   -static struct linux_prom_irqs irqs[PROMINTR_MAX] __initdata = { { 0 } };
23   -#ifdef CONFIG_SPARC32
24   -static int interrupts[PROMINTR_MAX] __initdata = { 0 };
25   -#endif
26   -
27 21 #ifdef CONFIG_PCI
28 22 extern int pcic_present(void);
29 23 #endif
30 24  
31   -/* Perhaps when I figure out more about the iommu we'll put a
32   - * device registration routine here that probe_sbus() calls to
33   - * setup the iommu for each Sbus.
34   - */
35   -
36   -/* We call this for each SBus device, and fill the structure based
37   - * upon the prom device tree. We return the start of memory after
38   - * the things we have allocated.
39   - */
40   -
41   -/* #define DEBUG_FILL */
42   -
43 25 static void __init fill_sbus_device(int prom_node, struct sbus_dev *sdev)
44 26 {
45 27 unsigned long address, base;
46 28  
47 29  
48 30  
49 31  
50 32  
... ... @@ -52,117 +34,30 @@
52 34 len = prom_getproperty(prom_node, "reg",
53 35 (char *) sdev->reg_addrs,
54 36 sizeof(sdev->reg_addrs));
55   - if (len == -1) {
56   - sdev->num_registers = 0;
57   - goto no_regs;
58   - }
  37 + sdev->num_registers = 0;
  38 + if (len != -1) {
  39 + sdev->num_registers =
  40 + len / sizeof(struct linux_prom_registers);
  41 + sdev->ranges_applied = 0;
59 42  
60   - if (len % sizeof(struct linux_prom_registers)) {
61   - prom_printf("fill_sbus_device: proplen for regs of %s "
62   - " was %d, need multiple of %d\n",
63   - sdev->prom_name, len,
64   - (int) sizeof(struct linux_prom_registers));
65   - prom_halt();
66   - }
67   - if (len > (sizeof(struct linux_prom_registers) * PROMREG_MAX)) {
68   - prom_printf("fill_sbus_device: Too many register properties "
69   - "for device %s, len=%d\n",
70   - sdev->prom_name, len);
71   - prom_halt();
72   - }
73   - sdev->num_registers = len / sizeof(struct linux_prom_registers);
74   - sdev->ranges_applied = 0;
  43 + base = (unsigned long) sdev->reg_addrs[0].phys_addr;
75 44  
76   - base = (unsigned long) sdev->reg_addrs[0].phys_addr;
77   -
78   - /* Compute the slot number. */
79   - if (base >= SUN_SBUS_BVADDR && sparc_cpu_model == sun4m) {
80   - sdev->slot = sbus_dev_slot(base);
81   - } else {
82   - sdev->slot = sdev->reg_addrs[0].which_io;
  45 + /* Compute the slot number. */
  46 + if (base >= SUN_SBUS_BVADDR && sparc_cpu_model == sun4m)
  47 + sdev->slot = sbus_dev_slot(base);
  48 + else
  49 + sdev->slot = sdev->reg_addrs[0].which_io;
83 50 }
84 51  
85   -no_regs:
86 52 len = prom_getproperty(prom_node, "ranges",
87 53 (char *)sdev->device_ranges,
88 54 sizeof(sdev->device_ranges));
89   - if (len == -1) {
90   - sdev->num_device_ranges = 0;
91   - goto no_ranges;
92   - }
93   - if (len % sizeof(struct linux_prom_ranges)) {
94   - prom_printf("fill_sbus_device: proplen for ranges of %s "
95   - " was %d, need multiple of %d\n",
96   - sdev->prom_name, len,
97   - (int) sizeof(struct linux_prom_ranges));
98   - prom_halt();
99   - }
100   - if (len > (sizeof(struct linux_prom_ranges) * PROMREG_MAX)) {
101   - prom_printf("fill_sbus_device: Too many range properties "
102   - "for device %s, len=%d\n",
103   - sdev->prom_name, len);
104   - prom_halt();
105   - }
106   - sdev->num_device_ranges =
107   - len / sizeof(struct linux_prom_ranges);
  55 + sdev->num_device_ranges = 0;
  56 + if (len != -1)
  57 + sdev->num_device_ranges =
  58 + len / sizeof(struct linux_prom_ranges);
108 59  
109   -no_ranges:
110   - /* XXX Unfortunately, IRQ issues are very arch specific.
111   - * XXX Pull this crud out into an arch specific area
112   - * XXX at some point. -DaveM
113   - */
114   -#ifdef CONFIG_SPARC64
115   - len = prom_getproperty(prom_node, "interrupts",
116   - (char *) irqs, sizeof(irqs));
117   - if (len == -1 || len == 0) {
118   - sdev->irqs[0] = 0;
119   - sdev->num_irqs = 0;
120   - } else {
121   - unsigned int pri = irqs[0].pri;
122   -
123   - sdev->num_irqs = 1;
124   - if (pri < 0x20)
125   - pri += sdev->slot * 8;
126   -
127   - sdev->irqs[0] = sbus_build_irq(sdev->bus, pri);
128   - }
129   -#endif /* CONFIG_SPARC64 */
130   -
131   -#ifdef CONFIG_SPARC32
132   - len = prom_getproperty(prom_node, "intr",
133   - (char *)irqs, sizeof(irqs));
134   - if (len != -1) {
135   - sdev->num_irqs = len / 8;
136   - if (sdev->num_irqs == 0) {
137   - sdev->irqs[0] = 0;
138   - } else if (sparc_cpu_model == sun4d) {
139   - extern unsigned int sun4d_build_irq(struct sbus_dev *sdev, int irq);
140   -
141   - for (len = 0; len < sdev->num_irqs; len++)
142   - sdev->irqs[len] = sun4d_build_irq(sdev, irqs[len].pri);
143   - } else {
144   - for (len = 0; len < sdev->num_irqs; len++)
145   - sdev->irqs[len] = irqs[len].pri;
146   - }
147   - } else {
148   - /* No "intr" node found-- check for "interrupts" node.
149   - * This node contains SBus interrupt levels, not IPLs
150   - * as in "intr", and no vector values. We convert
151   - * SBus interrupt levels to PILs (platform specific).
152   - */
153   - len = prom_getproperty(prom_node, "interrupts",
154   - (char *)interrupts, sizeof(interrupts));
155   - if (len == -1) {
156   - sdev->irqs[0] = 0;
157   - sdev->num_irqs = 0;
158   - } else {
159   - sdev->num_irqs = len / sizeof(int);
160   - for (len = 0; len < sdev->num_irqs; len++) {
161   - sdev->irqs[len] = sbint_to_irq(sdev, interrupts[len]);
162   - }
163   - }
164   - }
165   -#endif /* CONFIG_SPARC32 */
  60 + sbus_fill_device_irq(sdev);
166 61 }
167 62  
168 63 /* This routine gets called from whoever needs the sbus first, to scan
include/asm-sparc/sbus.h
... ... @@ -102,6 +102,7 @@
102 102 #define sbus_can_dma_64bit(sdev) (0) /* actually, sparc_cpu_model==sun4d */
103 103 #define sbus_can_burst64(sdev) (0) /* actually, sparc_cpu_model==sun4d */
104 104 extern void sbus_set_sbus64(struct sbus_dev *, int);
  105 +extern void sbus_fill_device_irq(struct sbus_dev *);
105 106  
106 107 /* These yield IOMMU mappings in consistent mode. */
107 108 extern void *sbus_alloc_consistent(struct sbus_dev *, long, u32 *dma_addrp);
include/asm-sparc64/sbus.h
... ... @@ -95,6 +95,7 @@
95 95 #define sbus_can_dma_64bit(sdev) (1)
96 96 #define sbus_can_burst64(sdev) (1)
97 97 extern void sbus_set_sbus64(struct sbus_dev *, int);
  98 +extern void sbus_fill_device_irq(struct sbus_dev *);
98 99  
99 100 /* These yield IOMMU mappings in consistent mode. */
100 101 extern void *sbus_alloc_consistent(struct sbus_dev *, size_t, dma_addr_t *dma_addrp);