X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=arch%2Fsparc64%2Fkernel%2Fsbus.c;fp=arch%2Fsparc64%2Fkernel%2Fsbus.c;h=d95a1bcf163d86f3f86e4505c3bff1faf937b341;hb=64ba3f394c830ec48a1c31b53dcae312c56f1604;hp=c49a57795743bcf3616b07663c2b593532f85d21;hpb=be1e6109ac94a859551f8e1774eb9a8469fe055c;p=linux-2.6.git diff --git a/arch/sparc64/kernel/sbus.c b/arch/sparc64/kernel/sbus.c index c49a57795..d95a1bcf1 100644 --- a/arch/sparc64/kernel/sbus.c +++ b/arch/sparc64/kernel/sbus.c @@ -19,7 +19,6 @@ #include #include #include -#include #include #include "iommu_common.h" @@ -692,6 +691,36 @@ void sbus_set_sbus64(struct sbus_dev *sdev, int bursts) upa_writeq(val, cfg_reg); } +/* SBUS SYSIO INO number to Sparc PIL level. */ +static unsigned char sysio_ino_to_pil[] = { + 0, 4, 4, 7, 5, 7, 8, 9, /* SBUS slot 0 */ + 0, 4, 4, 7, 5, 7, 8, 9, /* SBUS slot 1 */ + 0, 4, 4, 7, 5, 7, 8, 9, /* SBUS slot 2 */ + 0, 4, 4, 7, 5, 7, 8, 9, /* SBUS slot 3 */ + 4, /* Onboard SCSI */ + 5, /* Onboard Ethernet */ +/*XXX*/ 8, /* Onboard BPP */ + 0, /* Bogon */ + 13, /* Audio */ +/*XXX*/15, /* PowerFail */ + 0, /* Bogon */ + 0, /* Bogon */ + 12, /* Zilog Serial Channels (incl. Keyboard/Mouse lines) */ + 11, /* Floppy */ + 0, /* Spare Hardware (bogon for now) */ + 0, /* Keyboard (bogon for now) */ + 0, /* Mouse (bogon for now) */ + 0, /* Serial (bogon for now) */ + 0, 0, /* Bogon, Bogon */ + 10, /* Timer 0 */ + 11, /* Timer 1 */ + 0, 0, /* Bogon, Bogon */ + 15, /* Uncorrectable SBUS Error */ + 15, /* Correctable SBUS Error */ + 15, /* SBUS Error */ +/*XXX*/ 0, /* Power Management (bogon for now) */ +}; + /* INO number to IMAP register offset for SYSIO external IRQ's. * This should conform to both Sunfire/Wildfire server and Fusion * desktop designs. @@ -783,12 +812,21 @@ unsigned int sbus_build_irq(void *buscookie, unsigned int ino) struct sbus_iommu *iommu = sbus->iommu; unsigned long reg_base = iommu->sbus_control_reg - 0x2000UL; unsigned long imap, iclr; - int sbus_level = 0; + int pil, sbus_level = 0; + + pil = sysio_ino_to_pil[ino]; + if (!pil) { + printk("sbus_irq_build: Bad SYSIO INO[%x]\n", ino); + panic("Bad SYSIO IRQ translations..."); + } + + if (PIL_RESERVED(pil)) + BUG(); imap = sysio_irq_offsets[ino]; if (imap == ((unsigned long)-1)) { - prom_printf("get_irq_translations: Bad SYSIO INO[%x]\n", - ino); + prom_printf("get_irq_translations: Bad SYSIO INO[%x] cpu[%d]\n", + ino, pil); prom_halt(); } imap += reg_base; @@ -822,7 +860,7 @@ unsigned int sbus_build_irq(void *buscookie, unsigned int ino) iclr += ((unsigned long)sbus_level - 1UL) * 8UL; } - return build_irq(sbus_level, iclr, imap); + return build_irq(pil, sbus_level, iclr, imap); } /* Error interrupt handling. */ @@ -1065,7 +1103,7 @@ static void __init sysio_register_error_handlers(struct sbus_bus *sbus) irq = sbus_build_irq(sbus, SYSIO_UE_INO); if (request_irq(irq, sysio_ue_handler, - IRQF_SHARED, "SYSIO UE", sbus) < 0) { + SA_SHIRQ, "SYSIO UE", sbus) < 0) { prom_printf("SYSIO[%x]: Cannot register UE interrupt.\n", sbus->portid); prom_halt(); @@ -1073,7 +1111,7 @@ static void __init sysio_register_error_handlers(struct sbus_bus *sbus) irq = sbus_build_irq(sbus, SYSIO_CE_INO); if (request_irq(irq, sysio_ce_handler, - IRQF_SHARED, "SYSIO CE", sbus) < 0) { + SA_SHIRQ, "SYSIO CE", sbus) < 0) { prom_printf("SYSIO[%x]: Cannot register CE interrupt.\n", sbus->portid); prom_halt(); @@ -1081,7 +1119,7 @@ static void __init sysio_register_error_handlers(struct sbus_bus *sbus) irq = sbus_build_irq(sbus, SYSIO_SBUSERR_INO); if (request_irq(irq, sysio_sbus_error_handler, - IRQF_SHARED, "SYSIO SBUS Error", sbus) < 0) { + SA_SHIRQ, "SYSIO SBUS Error", sbus) < 0) { prom_printf("SYSIO[%x]: Cannot register SBUS Error interrupt.\n", sbus->portid); prom_halt(); @@ -1099,25 +1137,24 @@ static void __init sysio_register_error_handlers(struct sbus_bus *sbus) } /* Boot time initialization. */ -static void __init sbus_iommu_init(int __node, struct sbus_bus *sbus) +void __init sbus_iommu_init(int prom_node, struct sbus_bus *sbus) { - struct linux_prom64_registers *pr; - struct device_node *dp; + struct linux_prom64_registers rprop; struct sbus_iommu *iommu; unsigned long regs, tsb_base; u64 control; - int i; + int err, i; - dp = of_find_node_by_phandle(__node); + sbus->portid = prom_getintdefault(sbus->prom_node, + "upa-portid", -1); - sbus->portid = of_getintprop_default(dp, "upa-portid", -1); - - pr = of_get_property(dp, "reg", NULL); - if (!pr) { + err = prom_getproperty(prom_node, "reg", + (char *)&rprop, sizeof(rprop)); + if (err < 0) { prom_printf("sbus_iommu_init: Cannot map SYSIO control registers.\n"); prom_halt(); } - regs = pr->phys_addr; + regs = rprop.phys_addr; iommu = kmalloc(sizeof(*iommu) + SMP_CACHE_BYTES, GFP_ATOMIC); if (iommu == NULL) { @@ -1221,52 +1258,9 @@ static void __init sbus_iommu_init(int __node, struct sbus_bus *sbus) /* Now some Xfire specific grot... */ if (this_is_starfire) - starfire_hookup(sbus->portid); + sbus->starfire_cookie = starfire_hookup(sbus->portid); + else + sbus->starfire_cookie = NULL; sysio_register_error_handlers(sbus); } - -void sbus_fill_device_irq(struct sbus_dev *sdev) -{ - struct device_node *dp = of_find_node_by_phandle(sdev->prom_node); - struct linux_prom_irqs *irqs; - - irqs = of_get_property(dp, "interrupts", NULL); - if (!irqs) { - 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); - } -} - -void __init sbus_arch_bus_ranges_init(struct device_node *pn, struct sbus_bus *sbus) -{ -} - -void __init sbus_setup_iommu(struct sbus_bus *sbus, struct device_node *dp) -{ - sbus_iommu_init(dp->node, sbus); -} - -void __init sbus_setup_arch_props(struct sbus_bus *sbus, struct device_node *dp) -{ -} - -int __init sbus_arch_preinit(void) -{ - return 0; -} - -void __init sbus_arch_postinit(void) -{ - extern void firetruck_init(void); - - firetruck_init(); -}