diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/sparc/kernel/ioport.c | 46 | ||||
-rw-r--r-- | arch/sparc64/kernel/sbus.c | 21 |
2 files changed, 66 insertions, 1 deletions
diff --git a/arch/sparc/kernel/ioport.c b/arch/sparc/kernel/ioport.c index f9ff29734848..00cf41182912 100644 --- a/arch/sparc/kernel/ioport.c +++ b/arch/sparc/kernel/ioport.c | |||
@@ -224,10 +224,54 @@ static void _sparc_free_io(struct resource *res) | |||
224 | 224 | ||
225 | #ifdef CONFIG_SBUS | 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 | printk("sbus_set_sbus64: unsupported\n"); | 229 | printk("sbus_set_sbus64: unsupported\n"); |
229 | } | 230 | } |
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 | } | ||
273 | } | ||
274 | |||
231 | /* | 275 | /* |
232 | * Allocate a chunk of memory suitable for DMA. | 276 | * Allocate a chunk of memory suitable for DMA. |
233 | * Typically devices use them for control blocks. | 277 | * Typically devices use them for control blocks. |
diff --git a/arch/sparc64/kernel/sbus.c b/arch/sparc64/kernel/sbus.c index 8812417247d4..8f7877ac858f 100644 --- a/arch/sparc64/kernel/sbus.c +++ b/arch/sparc64/kernel/sbus.c | |||
@@ -1225,3 +1225,24 @@ void __init sbus_iommu_init(int prom_node, struct sbus_bus *sbus) | |||
1225 | 1225 | ||
1226 | sysio_register_error_handlers(sbus); | 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 | } | ||