diff options
author | David S. Miller <davem@sunset.davemloft.net> | 2006-06-21 02:23:28 +0400 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2006-06-24 10:15:00 +0400 |
commit | 8fae097debdf8ac9b66d220ac258535ea09f3898 (patch) | |
tree | 9c022cbf14e9174946a503b116fdf7376b8ce0ce /arch | |
parent | d384ea691fe4ea8c2dd5b9b8d9042eb181776f18 (diff) | |
download | linux-8fae097debdf8ac9b66d220ac258535ea09f3898.tar.xz |
[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>
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) #ifdef CONFIG_SBUS -void sbus_set_sbus64(struct sbus_dev *sdev, int x) { +void sbus_set_sbus64(struct sbus_dev *sdev, int x) +{ printk("sbus_set_sbus64: unsupported\n"); } +extern unsigned int sun4d_build_irq(struct sbus_dev *sdev, int irq); +void __init sbus_fill_device_irq(struct sbus_dev *sdev) +{ + struct linux_prom_irqs irqs[PROMINTR_MAX]; + int len; + + len = prom_getproperty(sdev->prom_node, "intr", + (char *)irqs, sizeof(irqs)); + if (len != -1) { + sdev->num_irqs = len / 8; + if (sdev->num_irqs == 0) { + sdev->irqs[0] = 0; + } else if (sparc_cpu_model == sun4d) { + for (len = 0; len < sdev->num_irqs; len++) + sdev->irqs[len] = + sun4d_build_irq(sdev, irqs[len].pri); + } else { + for (len = 0; len < sdev->num_irqs; len++) + sdev->irqs[len] = irqs[len].pri; + } + } else { + int interrupts[PROMINTR_MAX]; + + /* No "intr" node found-- check for "interrupts" node. + * This node contains SBus interrupt levels, not IPLs + * as in "intr", and no vector values. We convert + * SBus interrupt levels to PILs (platform specific). + */ + len = prom_getproperty(sdev->prom_node, "interrupts", + (char *)interrupts, sizeof(interrupts)); + if (len == -1) { + sdev->irqs[0] = 0; + sdev->num_irqs = 0; + } else { + sdev->num_irqs = len / sizeof(int); + for (len = 0; len < sdev->num_irqs; len++) { + sdev->irqs[len] = + sbint_to_irq(sdev, interrupts[len]); + } + } + } +} + /* * Allocate a chunk of memory suitable for DMA. * 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) sysio_register_error_handlers(sbus); } + +void sbus_fill_device_irq(struct sbus_dev *sdev) +{ + struct linux_prom_irqs irqs[PROMINTR_MAX]; + int len; + + len = prom_getproperty(sdev->prom_node, "interrupts", + (char *) irqs, sizeof(irqs)); + if (len == -1 || len == 0) { + sdev->irqs[0] = 0; + sdev->num_irqs = 0; + } else { + unsigned int pri = irqs[0].pri; + + sdev->num_irqs = 1; + if (pri < 0x20) + pri += sdev->slot * 8; + + sdev->irqs[0] = sbus_build_irq(sdev->bus, pri); + } +} |