+ return (struct zilog_layout __iomem *) mapped_addr;
+}
+#else /* CONFIG_SPARC64 */
+
+/*
+ * XXX The sun4d case is utterly screwed: it tries to re-walk the tree
+ * (for the 3rd time) in order to find bootbus and cpu. Streamline it.
+ */
+static struct zilog_layout __iomem * __init get_zs_sun4cmd(int chip, int node)
+{
+ struct linux_prom_irqs irq_info[2];
+ void __iomem *mapped_addr = NULL;
+ int zsnode, cpunode, bbnode;
+ struct linux_prom_registers zsreg[4];
+ struct resource res;
+
+ if (sparc_cpu_model == sun4d) {
+ int walk;
+
+ zsnode = 0;
+ bbnode = 0;
+ cpunode = 0;
+ for (walk = prom_getchild(prom_root_node);
+ (walk = prom_searchsiblings(walk, "cpu-unit")) != 0;
+ walk = prom_getsibling(walk)) {
+ bbnode = prom_getchild(walk);
+ if (bbnode &&
+ (bbnode = prom_searchsiblings(bbnode, "bootbus"))) {
+ if ((zsnode = prom_getchild(bbnode)) == node) {
+ cpunode = walk;
+ break;
+ }
+ }
+ }
+ if (!walk) {
+ prom_printf("SunZilog: Cannot find the %d'th bootbus on sun4d.\n",
+ (chip / 2));
+ prom_halt();
+ }
+
+ if (prom_getproperty(zsnode, "reg",
+ (char *) zsreg, sizeof(zsreg)) == -1) {
+ prom_printf("SunZilog: Cannot map Zilog %d\n", chip);
+ prom_halt();
+ }
+ /* XXX Looks like an off by one? */
+ prom_apply_generic_ranges(bbnode, cpunode, zsreg, 1);
+ res.start = zsreg[0].phys_addr;
+ res.end = res.start + (8 - 1);
+ res.flags = zsreg[0].which_io | IORESOURCE_IO;
+ mapped_addr = sbus_ioremap(&res, 0, 8, "Zilog Serial");
+
+ } else {
+ zsnode = node;
+
+#if 0 /* XXX When was this used? */
+ if (prom_getintdefault(zsnode, "slave", -1) != chipid) {
+ zsnode = prom_getsibling(zsnode);
+ continue;
+ }
+#endif
+
+ /*
+ * "address" is only present on ports that OBP opened
+ * (from Mitch Bradley's "Hitchhiker's Guide to OBP").
+ * We do not use it.
+ */
+
+ if (prom_getproperty(zsnode, "reg",
+ (char *) zsreg, sizeof(zsreg)) == -1) {
+ prom_printf("SunZilog: Cannot map Zilog %d\n", chip);
+ prom_halt();
+ }
+ if (sparc_cpu_model == sun4m) /* Crude. Pass parent. XXX */
+ prom_apply_obio_ranges(zsreg, 1);
+ res.start = zsreg[0].phys_addr;
+ res.end = res.start + (8 - 1);
+ res.flags = zsreg[0].which_io | IORESOURCE_IO;
+ mapped_addr = sbus_ioremap(&res, 0, 8, "Zilog Serial");
+ }
+
+ if (prom_getproperty(zsnode, "intr",
+ (char *) irq_info, sizeof(irq_info))
+ % sizeof(struct linux_prom_irqs)) {
+ prom_printf("SunZilog: Cannot get IRQ property for Zilog %d.\n",
+ chip);
+ prom_halt();
+ }
+ if (zilog_irq == -1) {
+ zilog_irq = irq_info[0].pri;
+ } else if (zilog_irq != irq_info[0].pri) {
+ /* XXX. Dumb. Should handle per-chip IRQ, for add-ons. */
+ prom_printf("SunZilog: Inconsistent IRQ layout for Zilog %d.\n",
+ chip);
+ prom_halt();
+ }
+
+ return (struct zilog_layout __iomem *) mapped_addr;