powerpc: Merge maple support code to arch/powerpc/platforms/maple
authorPaul Mackerras <paulus@samba.org>
Sat, 29 Oct 2005 12:07:56 +0000 (22:07 +1000)
committerPaul Mackerras <paulus@samba.org>
Sat, 29 Oct 2005 12:07:56 +0000 (22:07 +1000)
Signed-off-by: Paul Mackerras <paulus@samba.org>
arch/powerpc/platforms/Makefile
arch/powerpc/platforms/maple/Makefile [new file with mode: 0644]
arch/powerpc/platforms/maple/maple.h [new file with mode: 0644]
arch/powerpc/platforms/maple/pci.c [new file with mode: 0644]
arch/powerpc/platforms/maple/setup.c [new file with mode: 0644]
arch/powerpc/platforms/maple/time.c [new file with mode: 0644]
arch/ppc64/kernel/Makefile
arch/ppc64/kernel/maple_pci.c [deleted file]
arch/ppc64/kernel/maple_setup.c [deleted file]
arch/ppc64/kernel/maple_time.c [deleted file]

index 01723d491b5dfde5beea3dd32120bbd7d526f9c6..172c0db635041b025261893f99b26b06da65333e 100644 (file)
@@ -10,3 +10,4 @@ obj-$(CONFIG_4xx)             += 4xx/
 obj-$(CONFIG_85xx)             += 85xx/
 obj-$(CONFIG_PPC_PSERIES)      += pseries/
 obj-$(CONFIG_PPC_ISERIES)      += iseries/
+obj-$(CONFIG_PPC_MAPLE)                += maple/
diff --git a/arch/powerpc/platforms/maple/Makefile b/arch/powerpc/platforms/maple/Makefile
new file mode 100644 (file)
index 0000000..1be1a99
--- /dev/null
@@ -0,0 +1 @@
+obj-y  += setup.o pci.o time.o
diff --git a/arch/powerpc/platforms/maple/maple.h b/arch/powerpc/platforms/maple/maple.h
new file mode 100644 (file)
index 0000000..0657c57
--- /dev/null
@@ -0,0 +1,12 @@
+/*
+ * Declarations for maple-specific code.
+ *
+ * Maple is the name of a PPC970 evaluation board.
+ */
+extern int maple_set_rtc_time(struct rtc_time *tm);
+extern void maple_get_rtc_time(struct rtc_time *tm);
+extern unsigned long maple_get_boot_time(void);
+extern void maple_calibrate_decr(void);
+extern void maple_pci_init(void);
+extern void maple_pcibios_fixup(void);
+extern int maple_pci_get_legacy_ide_irq(struct pci_dev *dev, int channel);
diff --git a/arch/powerpc/platforms/maple/pci.c b/arch/powerpc/platforms/maple/pci.c
new file mode 100644 (file)
index 0000000..340c21c
--- /dev/null
@@ -0,0 +1,522 @@
+/*
+ * Copyright (C) 2004 Benjamin Herrenschmuidt (benh@kernel.crashing.org),
+ *                   IBM Corp.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#define DEBUG
+
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/delay.h>
+#include <linux/string.h>
+#include <linux/init.h>
+#include <linux/bootmem.h>
+
+#include <asm/sections.h>
+#include <asm/io.h>
+#include <asm/prom.h>
+#include <asm/pci-bridge.h>
+#include <asm/machdep.h>
+#include <asm/iommu.h>
+#include <asm/ppc-pci.h>
+
+#include "maple.h"
+
+#ifdef DEBUG
+#define DBG(x...) printk(x)
+#else
+#define DBG(x...)
+#endif
+
+static struct pci_controller *u3_agp, *u3_ht;
+
+static int __init fixup_one_level_bus_range(struct device_node *node, int higher)
+{
+       for (; node != 0;node = node->sibling) {
+               int * bus_range;
+               unsigned int *class_code;
+               int len;
+
+               /* For PCI<->PCI bridges or CardBus bridges, we go down */
+               class_code = (unsigned int *) get_property(node, "class-code", NULL);
+               if (!class_code || ((*class_code >> 8) != PCI_CLASS_BRIDGE_PCI &&
+                       (*class_code >> 8) != PCI_CLASS_BRIDGE_CARDBUS))
+                       continue;
+               bus_range = (int *) get_property(node, "bus-range", &len);
+               if (bus_range != NULL && len > 2 * sizeof(int)) {
+                       if (bus_range[1] > higher)
+                               higher = bus_range[1];
+               }
+               higher = fixup_one_level_bus_range(node->child, higher);
+       }
+       return higher;
+}
+
+/* This routine fixes the "bus-range" property of all bridges in the
+ * system since they tend to have their "last" member wrong on macs
+ *
+ * Note that the bus numbers manipulated here are OF bus numbers, they
+ * are not Linux bus numbers.
+ */
+static void __init fixup_bus_range(struct device_node *bridge)
+{
+       int * bus_range;
+       int len;
+
+       /* Lookup the "bus-range" property for the hose */
+       bus_range = (int *) get_property(bridge, "bus-range", &len);
+       if (bus_range == NULL || len < 2 * sizeof(int)) {
+               printk(KERN_WARNING "Can't get bus-range for %s\n",
+                              bridge->full_name);
+               return;
+       }
+       bus_range[1] = fixup_one_level_bus_range(bridge->child, bus_range[1]);
+}
+
+
+#define U3_AGP_CFA0(devfn, off)        \
+       ((1 << (unsigned long)PCI_SLOT(dev_fn)) \
+       | (((unsigned long)PCI_FUNC(dev_fn)) << 8) \
+       | (((unsigned long)(off)) & 0xFCUL))
+
+#define U3_AGP_CFA1(bus, devfn, off)   \
+       ((((unsigned long)(bus)) << 16) \
+       |(((unsigned long)(devfn)) << 8) \
+       |(((unsigned long)(off)) & 0xFCUL) \
+       |1UL)
+
+static unsigned long u3_agp_cfg_access(struct pci_controller* hose,
+                                      u8 bus, u8 dev_fn, u8 offset)
+{
+       unsigned int caddr;
+
+       if (bus == hose->first_busno) {
+               if (dev_fn < (11 << 3))
+                       return 0;
+               caddr = U3_AGP_CFA0(dev_fn, offset);
+       } else
+               caddr = U3_AGP_CFA1(bus, dev_fn, offset);
+
+       /* Uninorth will return garbage if we don't read back the value ! */
+       do {
+               out_le32(hose->cfg_addr, caddr);
+       } while (in_le32(hose->cfg_addr) != caddr);
+
+       offset &= 0x07;
+       return ((unsigned long)hose->cfg_data) + offset;
+}
+
+static int u3_agp_read_config(struct pci_bus *bus, unsigned int devfn,
+                             int offset, int len, u32 *val)
+{
+       struct pci_controller *hose;
+       unsigned long addr;
+
+       hose = pci_bus_to_host(bus);
+       if (hose == NULL)
+               return PCIBIOS_DEVICE_NOT_FOUND;
+
+       addr = u3_agp_cfg_access(hose, bus->number, devfn, offset);
+       if (!addr)
+               return PCIBIOS_DEVICE_NOT_FOUND;
+       /*
+        * Note: the caller has already checked that offset is
+        * suitably aligned and that len is 1, 2 or 4.
+        */
+       switch (len) {
+       case 1:
+               *val = in_8((u8 *)addr);
+               break;
+       case 2:
+               *val = in_le16((u16 *)addr);
+               break;
+       default:
+               *val = in_le32((u32 *)addr);
+               break;
+       }
+       return PCIBIOS_SUCCESSFUL;
+}
+
+static int u3_agp_write_config(struct pci_bus *bus, unsigned int devfn,
+                              int offset, int len, u32 val)
+{
+       struct pci_controller *hose;
+       unsigned long addr;
+
+       hose = pci_bus_to_host(bus);
+       if (hose == NULL)
+               return PCIBIOS_DEVICE_NOT_FOUND;
+
+       addr = u3_agp_cfg_access(hose, bus->number, devfn, offset);
+       if (!addr)
+               return PCIBIOS_DEVICE_NOT_FOUND;
+       /*
+        * Note: the caller has already checked that offset is
+        * suitably aligned and that len is 1, 2 or 4.
+        */
+       switch (len) {
+       case 1:
+               out_8((u8 *)addr, val);
+               (void) in_8((u8 *)addr);
+               break;
+       case 2:
+               out_le16((u16 *)addr, val);
+               (void) in_le16((u16 *)addr);
+               break;
+       default:
+               out_le32((u32 *)addr, val);
+               (void) in_le32((u32 *)addr);
+               break;
+       }
+       return PCIBIOS_SUCCESSFUL;
+}
+
+static struct pci_ops u3_agp_pci_ops =
+{
+       u3_agp_read_config,
+       u3_agp_write_config
+};
+
+
+#define U3_HT_CFA0(devfn, off)         \
+               ((((unsigned long)devfn) << 8) | offset)
+#define U3_HT_CFA1(bus, devfn, off)    \
+               (U3_HT_CFA0(devfn, off) \
+               + (((unsigned long)bus) << 16) \
+               + 0x01000000UL)
+
+static unsigned long u3_ht_cfg_access(struct pci_controller* hose,
+                                     u8 bus, u8 devfn, u8 offset)
+{
+       if (bus == hose->first_busno) {
+               if (PCI_SLOT(devfn) == 0)
+                       return 0;
+               return ((unsigned long)hose->cfg_data) + U3_HT_CFA0(devfn, offset);
+       } else
+               return ((unsigned long)hose->cfg_data) + U3_HT_CFA1(bus, devfn, offset);
+}
+
+static int u3_ht_read_config(struct pci_bus *bus, unsigned int devfn,
+                            int offset, int len, u32 *val)
+{
+       struct pci_controller *hose;
+       unsigned long addr;
+
+       hose = pci_bus_to_host(bus);
+       if (hose == NULL)
+               return PCIBIOS_DEVICE_NOT_FOUND;
+
+       addr = u3_ht_cfg_access(hose, bus->number, devfn, offset);
+       if (!addr)
+               return PCIBIOS_DEVICE_NOT_FOUND;
+
+       /*
+        * Note: the caller has already checked that offset is
+        * suitably aligned and that len is 1, 2 or 4.
+        */
+       switch (len) {
+       case 1:
+               *val = in_8((u8 *)addr);
+               break;
+       case 2:
+               *val = in_le16((u16 *)addr);
+               break;
+       default:
+               *val = in_le32((u32 *)addr);
+               break;
+       }
+       return PCIBIOS_SUCCESSFUL;
+}
+
+static int u3_ht_write_config(struct pci_bus *bus, unsigned int devfn,
+                             int offset, int len, u32 val)
+{
+       struct pci_controller *hose;
+       unsigned long addr;
+
+       hose = pci_bus_to_host(bus);
+       if (hose == NULL)
+               return PCIBIOS_DEVICE_NOT_FOUND;
+
+       addr = u3_ht_cfg_access(hose, bus->number, devfn, offset);
+       if (!addr)
+               return PCIBIOS_DEVICE_NOT_FOUND;
+       /*
+        * Note: the caller has already checked that offset is
+        * suitably aligned and that len is 1, 2 or 4.
+        */
+       switch (len) {
+       case 1:
+               out_8((u8 *)addr, val);
+               (void) in_8((u8 *)addr);
+               break;
+       case 2:
+               out_le16((u16 *)addr, val);
+               (void) in_le16((u16 *)addr);
+               break;
+       default:
+               out_le32((u32 *)addr, val);
+               (void) in_le32((u32 *)addr);
+               break;
+       }
+       return PCIBIOS_SUCCESSFUL;
+}
+
+static struct pci_ops u3_ht_pci_ops =
+{
+       u3_ht_read_config,
+       u3_ht_write_config
+};
+
+static void __init setup_u3_agp(struct pci_controller* hose)
+{
+       /* On G5, we move AGP up to high bus number so we don't need
+        * to reassign bus numbers for HT. If we ever have P2P bridges
+        * on AGP, we'll have to move pci_assign_all_buses to the
+        * pci_controller structure so we enable it for AGP and not for
+        * HT childs.
+        * We hard code the address because of the different size of
+        * the reg address cell, we shall fix that by killing struct
+        * reg_property and using some accessor functions instead
+        */
+       hose->first_busno = 0xf0;
+       hose->last_busno = 0xff;
+       hose->ops = &u3_agp_pci_ops;
+       hose->cfg_addr = ioremap(0xf0000000 + 0x800000, 0x1000);
+       hose->cfg_data = ioremap(0xf0000000 + 0xc00000, 0x1000);
+
+       u3_agp = hose;
+}
+
+static void __init setup_u3_ht(struct pci_controller* hose)
+{
+       hose->ops = &u3_ht_pci_ops;
+
+       /* We hard code the address because of the different size of
+        * the reg address cell, we shall fix that by killing struct
+        * reg_property and using some accessor functions instead
+        */
+       hose->cfg_data = (volatile unsigned char *)ioremap(0xf2000000, 0x02000000);
+
+       hose->first_busno = 0;
+       hose->last_busno = 0xef;
+
+       u3_ht = hose;
+}
+
+static int __init add_bridge(struct device_node *dev)
+{
+       int len;
+       struct pci_controller *hose;
+       char* disp_name;
+       int *bus_range;
+       int primary = 1;
+       struct property *of_prop;
+
+       DBG("Adding PCI host bridge %s\n", dev->full_name);
+
+       bus_range = (int *) get_property(dev, "bus-range", &len);
+       if (bus_range == NULL || len < 2 * sizeof(int)) {
+               printk(KERN_WARNING "Can't get bus-range for %s, assume bus 0\n",
+               dev->full_name);
+       }
+
+       hose = alloc_bootmem(sizeof(struct pci_controller));
+       if (hose == NULL)
+               return -ENOMEM;
+       pci_setup_pci_controller(hose);
+
+       hose->arch_data = dev;
+       hose->first_busno = bus_range ? bus_range[0] : 0;
+       hose->last_busno = bus_range ? bus_range[1] : 0xff;
+
+       of_prop = alloc_bootmem(sizeof(struct property) +
+                               sizeof(hose->global_number));
+       if (of_prop) {
+               memset(of_prop, 0, sizeof(struct property));
+               of_prop->name = "linux,pci-domain";
+               of_prop->length = sizeof(hose->global_number);
+               of_prop->value = (unsigned char *)&of_prop[1];
+               memcpy(of_prop->value, &hose->global_number, sizeof(hose->global_number));
+               prom_add_property(dev, of_prop);
+       }
+
+       disp_name = NULL;
+       if (device_is_compatible(dev, "u3-agp")) {
+               setup_u3_agp(hose);
+               disp_name = "U3-AGP";
+               primary = 0;
+       } else if (device_is_compatible(dev, "u3-ht")) {
+               setup_u3_ht(hose);
+               disp_name = "U3-HT";
+               primary = 1;
+       }
+       printk(KERN_INFO "Found %s PCI host bridge. Firmware bus number: %d->%d\n",
+               disp_name, hose->first_busno, hose->last_busno);
+
+       /* Interpret the "ranges" property */
+       /* This also maps the I/O region and sets isa_io/mem_base */
+       pci_process_bridge_OF_ranges(hose, dev, primary);
+       pci_setup_phb_io(hose, primary);
+
+       /* Fixup "bus-range" OF property */
+       fixup_bus_range(dev);
+
+       return 0;
+}
+
+
+void __init maple_pcibios_fixup(void)
+{
+       struct pci_dev *dev = NULL;
+
+       DBG(" -> maple_pcibios_fixup\n");
+
+       for_each_pci_dev(dev)
+               pci_read_irq_line(dev);
+
+       /* Do the mapping of the IO space */
+       phbs_remap_io();
+
+       DBG(" <- maple_pcibios_fixup\n");
+}
+
+static void __init maple_fixup_phb_resources(void)
+{
+       struct pci_controller *hose, *tmp;
+       
+       list_for_each_entry_safe(hose, tmp, &hose_list, list_node) {
+               unsigned long offset = (unsigned long)hose->io_base_virt - pci_io_base;
+               hose->io_resource.start += offset;
+               hose->io_resource.end += offset;
+               printk(KERN_INFO "PCI Host %d, io start: %lx; io end: %lx\n",
+                      hose->global_number,
+                      hose->io_resource.start, hose->io_resource.end);
+       }
+}
+
+void __init maple_pci_init(void)
+{
+       struct device_node *np, *root;
+       struct device_node *ht = NULL;
+
+       /* Probe root PCI hosts, that is on U3 the AGP host and the
+        * HyperTransport host. That one is actually "kept" around
+        * and actually added last as it's resource management relies
+        * on the AGP resources to have been setup first
+        */
+       root = of_find_node_by_path("/");
+       if (root == NULL) {
+               printk(KERN_CRIT "maple_find_bridges: can't find root of device tree\n");
+               return;
+       }
+       for (np = NULL; (np = of_get_next_child(root, np)) != NULL;) {
+               if (np->name == NULL)
+                       continue;
+               if (strcmp(np->name, "pci") == 0) {
+                       if (add_bridge(np) == 0)
+                               of_node_get(np);
+               }
+               if (strcmp(np->name, "ht") == 0) {
+                       of_node_get(np);
+                       ht = np;
+               }
+       }
+       of_node_put(root);
+
+       /* Now setup the HyperTransport host if we found any
+        */
+       if (ht && add_bridge(ht) != 0)
+               of_node_put(ht);
+
+       /* Fixup the IO resources on our host bridges as the common code
+        * does it only for childs of the host bridges
+        */
+       maple_fixup_phb_resources();
+
+       /* Setup the linkage between OF nodes and PHBs */ 
+       pci_devs_phb_init();
+
+       /* Fixup the PCI<->OF mapping for U3 AGP due to bus renumbering. We
+        * assume there is no P2P bridge on the AGP bus, which should be a
+        * safe assumptions hopefully.
+        */
+       if (u3_agp) {
+               struct device_node *np = u3_agp->arch_data;
+               PCI_DN(np)->busno = 0xf0;
+               for (np = np->child; np; np = np->sibling)
+                       PCI_DN(np)->busno = 0xf0;
+       }
+
+       /* Tell pci.c to use the common resource allocation mecanism */
+       pci_probe_only = 0;
+       
+       /* Allow all IO */
+       io_page_mask = -1;
+}
+
+int maple_pci_get_legacy_ide_irq(struct pci_dev *pdev, int channel)
+{
+       struct device_node *np;
+       int irq = channel ? 15 : 14;
+
+       if (pdev->vendor != PCI_VENDOR_ID_AMD ||
+           pdev->device != PCI_DEVICE_ID_AMD_8111_IDE)
+               return irq;
+
+       np = pci_device_to_OF_node(pdev);
+       if (np == NULL)
+               return irq;
+       if (np->n_intrs < 2)
+               return irq;
+       return np->intrs[channel & 0x1].line;
+}
+
+/* XXX: To remove once all firmwares are ok */
+static void fixup_maple_ide(struct pci_dev* dev)
+{
+#if 0 /* Enable this to enable IDE port 0 */
+       {
+               u8 v;
+
+               pci_read_config_byte(dev, 0x40, &v);
+               v |= 2;
+               pci_write_config_byte(dev, 0x40, v);
+       }
+#endif
+#if 0 /* fix bus master base */
+       pci_write_config_dword(dev, 0x20, 0xcc01);
+       printk("old ide resource: %lx -> %lx \n",
+              dev->resource[4].start, dev->resource[4].end);
+       dev->resource[4].start = 0xcc00;
+       dev->resource[4].end = 0xcc10;
+#endif
+#if 1 /* Enable this to fixup IDE sense/polarity of irqs in IO-APICs */
+       {
+               struct pci_dev *apicdev;
+               u32 v;
+
+               apicdev = pci_get_slot (dev->bus, PCI_DEVFN(5,0));
+               if (apicdev == NULL)
+                       printk("IDE Fixup IRQ: Can't find IO-APIC !\n");
+               else {
+                       pci_write_config_byte(apicdev, 0xf2, 0x10 + 2*14);
+                       pci_read_config_dword(apicdev, 0xf4, &v);
+                       v &= ~0x00000022;
+                       pci_write_config_dword(apicdev, 0xf4, v);
+                       pci_write_config_byte(apicdev, 0xf2, 0x10 + 2*15);
+                       pci_read_config_dword(apicdev, 0xf4, &v);
+                       v &= ~0x00000022;
+                       pci_write_config_dword(apicdev, 0xf4, v);
+                       pci_dev_put(apicdev);
+               }
+       }
+#endif
+}
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8111_IDE,
+                        fixup_maple_ide);
diff --git a/arch/powerpc/platforms/maple/setup.c b/arch/powerpc/platforms/maple/setup.c
new file mode 100644 (file)
index 0000000..7ece898
--- /dev/null
@@ -0,0 +1,295 @@
+/*
+ *  Maple (970 eval board) setup code
+ *
+ *  (c) Copyright 2004 Benjamin Herrenschmidt (benh@kernel.crashing.org),
+ *                     IBM Corp. 
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU General Public License
+ *  as published by the Free Software Foundation; either version
+ *  2 of the License, or (at your option) any later version.
+ *
+ */
+
+#define DEBUG
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/stddef.h>
+#include <linux/unistd.h>
+#include <linux/ptrace.h>
+#include <linux/slab.h>
+#include <linux/user.h>
+#include <linux/a.out.h>
+#include <linux/tty.h>
+#include <linux/string.h>
+#include <linux/delay.h>
+#include <linux/ioport.h>
+#include <linux/major.h>
+#include <linux/initrd.h>
+#include <linux/vt_kern.h>
+#include <linux/console.h>
+#include <linux/ide.h>
+#include <linux/pci.h>
+#include <linux/adb.h>
+#include <linux/cuda.h>
+#include <linux/pmu.h>
+#include <linux/irq.h>
+#include <linux/seq_file.h>
+#include <linux/root_dev.h>
+#include <linux/serial.h>
+#include <linux/smp.h>
+
+#include <asm/processor.h>
+#include <asm/sections.h>
+#include <asm/prom.h>
+#include <asm/system.h>
+#include <asm/pgtable.h>
+#include <asm/bitops.h>
+#include <asm/io.h>
+#include <asm/pci-bridge.h>
+#include <asm/iommu.h>
+#include <asm/machdep.h>
+#include <asm/dma.h>
+#include <asm/cputable.h>
+#include <asm/time.h>
+#include <asm/of_device.h>
+#include <asm/lmb.h>
+#include <asm/mpic.h>
+#include <asm/udbg.h>
+
+#include "maple.h"
+
+#ifdef DEBUG
+#define DBG(fmt...) udbg_printf(fmt)
+#else
+#define DBG(fmt...)
+#endif
+
+extern void generic_find_legacy_serial_ports(u64 *physport,
+               unsigned int *default_speed);
+
+static void maple_restart(char *cmd)
+{
+       unsigned int maple_nvram_base;
+       unsigned int maple_nvram_offset;
+       unsigned int maple_nvram_command;
+       struct device_node *rtcs;
+
+       /* find NVRAM device */
+       rtcs = find_compatible_devices("nvram", "AMD8111");
+       if (rtcs && rtcs->addrs) {
+               maple_nvram_base = rtcs->addrs[0].address;
+       } else {
+               printk(KERN_EMERG "Maple: Unable to find NVRAM\n");
+               printk(KERN_EMERG "Maple: Manual Restart Required\n");
+               return;
+       }
+
+       /* find service processor device */
+       rtcs = find_devices("service-processor");
+       if (!rtcs) {
+               printk(KERN_EMERG "Maple: Unable to find Service Processor\n");
+               printk(KERN_EMERG "Maple: Manual Restart Required\n");
+               return;
+       }
+       maple_nvram_offset = *(unsigned int*) get_property(rtcs,
+                       "restart-addr", NULL);
+       maple_nvram_command = *(unsigned int*) get_property(rtcs,
+                       "restart-value", NULL);
+
+       /* send command */
+       outb_p(maple_nvram_command, maple_nvram_base + maple_nvram_offset);
+       for (;;) ;
+}
+
+static void maple_power_off(void)
+{
+       unsigned int maple_nvram_base;
+       unsigned int maple_nvram_offset;
+       unsigned int maple_nvram_command;
+       struct device_node *rtcs;
+
+       /* find NVRAM device */
+       rtcs = find_compatible_devices("nvram", "AMD8111");
+       if (rtcs && rtcs->addrs) {
+               maple_nvram_base = rtcs->addrs[0].address;
+       } else {
+               printk(KERN_EMERG "Maple: Unable to find NVRAM\n");
+               printk(KERN_EMERG "Maple: Manual Power-Down Required\n");
+               return;
+       }
+
+       /* find service processor device */
+       rtcs = find_devices("service-processor");
+       if (!rtcs) {
+               printk(KERN_EMERG "Maple: Unable to find Service Processor\n");
+               printk(KERN_EMERG "Maple: Manual Power-Down Required\n");
+               return;
+       }
+       maple_nvram_offset = *(unsigned int*) get_property(rtcs,
+                       "power-off-addr", NULL);
+       maple_nvram_command = *(unsigned int*) get_property(rtcs,
+                       "power-off-value", NULL);
+
+       /* send command */
+       outb_p(maple_nvram_command, maple_nvram_base + maple_nvram_offset);
+       for (;;) ;
+}
+
+static void maple_halt(void)
+{
+       maple_power_off();
+}
+
+#ifdef CONFIG_SMP
+struct smp_ops_t maple_smp_ops = {
+       .probe          = smp_mpic_probe,
+       .message_pass   = smp_mpic_message_pass,
+       .kick_cpu       = smp_generic_kick_cpu,
+       .setup_cpu      = smp_mpic_setup_cpu,
+       .give_timebase  = smp_generic_give_timebase,
+       .take_timebase  = smp_generic_take_timebase,
+};
+#endif /* CONFIG_SMP */
+
+void __init maple_setup_arch(void)
+{
+       /* init to some ~sane value until calibrate_delay() runs */
+       loops_per_jiffy = 50000000;
+
+       /* Setup SMP callback */
+#ifdef CONFIG_SMP
+       smp_ops = &maple_smp_ops;
+#endif
+       /* Lookup PCI hosts */
+               maple_pci_init();
+
+#ifdef CONFIG_DUMMY_CONSOLE
+       conswitchp = &dummy_con;
+#endif
+
+       printk(KERN_INFO "Using native/NAP idle loop\n");
+}
+
+/* 
+ * Early initialization.
+ */
+static void __init maple_init_early(void)
+{
+       unsigned int default_speed;
+       u64 physport;
+
+       DBG(" -> maple_init_early\n");
+
+       /* Initialize hash table, from now on, we can take hash faults
+        * and call ioremap
+        */
+       hpte_init_native();
+
+       /* Find the serial port */
+       generic_find_legacy_serial_ports(&physport, &default_speed);
+
+       DBG("phys port addr: %lx\n", (long)physport);
+
+       if (physport) {
+               void *comport;
+               /* Map the uart for udbg. */
+               comport = (void *)ioremap(physport, 16);
+               udbg_init_uart(comport, default_speed);
+
+               DBG("Hello World !\n");
+       }
+
+       /* Setup interrupt mapping options */
+       ppc64_interrupt_controller = IC_OPEN_PIC;
+
+       iommu_init_early_u3();
+
+       DBG(" <- maple_init_early\n");
+}
+
+
+static __init void maple_init_IRQ(void)
+{
+       struct device_node *root;
+       unsigned int *opprop;
+       unsigned long opic_addr;
+       struct mpic *mpic;
+       unsigned char senses[128];
+       int n;
+
+       DBG(" -> maple_init_IRQ\n");
+
+       /* XXX: Non standard, replace that with a proper openpic/mpic node
+        * in the device-tree. Find the Open PIC if present */
+       root = of_find_node_by_path("/");
+       opprop = (unsigned int *) get_property(root,
+                               "platform-open-pic", NULL);
+       if (opprop == 0)
+               panic("OpenPIC not found !\n");
+
+       n = prom_n_addr_cells(root);
+       for (opic_addr = 0; n > 0; --n)
+               opic_addr = (opic_addr << 32) + *opprop++;
+       of_node_put(root);
+
+       /* Obtain sense values from device-tree */
+       prom_get_irq_senses(senses, 0, 128);
+
+       mpic = mpic_alloc(opic_addr,
+                         MPIC_PRIMARY | MPIC_BIG_ENDIAN |
+                         MPIC_BROKEN_U3 | MPIC_WANTS_RESET,
+                         0, 0, 128, 128, senses, 128, "U3-MPIC");
+       BUG_ON(mpic == NULL);
+       mpic_init(mpic);
+
+       DBG(" <- maple_init_IRQ\n");
+}
+
+static void __init maple_progress(char *s, unsigned short hex)
+{
+       printk("*** %04x : %s\n", hex, s ? s : "");
+}
+
+
+/*
+ * Called very early, MMU is off, device-tree isn't unflattened
+ */
+static int __init maple_probe(int platform)
+{
+       if (platform != PLATFORM_MAPLE)
+               return 0;
+       /*
+        * On U3, the DART (iommu) must be allocated now since it
+        * has an impact on htab_initialize (due to the large page it
+        * occupies having to be broken up so the DART itself is not
+        * part of the cacheable linar mapping
+        */
+       alloc_u3_dart_table();
+
+       return 1;
+}
+
+struct machdep_calls __initdata maple_md = {
+       .probe                  = maple_probe,
+       .setup_arch             = maple_setup_arch,
+       .init_early             = maple_init_early,
+       .init_IRQ               = maple_init_IRQ,
+       .get_irq                = mpic_get_irq,
+       .pcibios_fixup          = maple_pcibios_fixup,
+       .pci_get_legacy_ide_irq = maple_pci_get_legacy_ide_irq,
+       .restart                = maple_restart,
+       .power_off              = maple_power_off,
+       .halt                   = maple_halt,
+               .get_boot_time          = maple_get_boot_time,
+               .set_rtc_time           = maple_set_rtc_time,
+               .get_rtc_time           = maple_get_rtc_time,
+       .calibrate_decr         = generic_calibrate_decr,
+       .progress               = maple_progress,
+       .idle_loop              = native_idle,
+};
diff --git a/arch/powerpc/platforms/maple/time.c b/arch/powerpc/platforms/maple/time.c
new file mode 100644 (file)
index 0000000..40fc07a
--- /dev/null
@@ -0,0 +1,180 @@
+/*
+ *  arch/ppc64/kernel/maple_time.c
+ *
+ *  (c) Copyright 2004 Benjamin Herrenschmidt (benh@kernel.crashing.org),
+ *                     IBM Corp. 
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU General Public License
+ *  as published by the Free Software Foundation; either version
+ *  2 of the License, or (at your option) any later version.
+ *
+ */
+
+#undef DEBUG
+
+#include <linux/config.h>
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/param.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/init.h>
+#include <linux/time.h>
+#include <linux/adb.h>
+#include <linux/pmu.h>
+#include <linux/interrupt.h>
+#include <linux/mc146818rtc.h>
+#include <linux/bcd.h>
+
+#include <asm/sections.h>
+#include <asm/prom.h>
+#include <asm/system.h>
+#include <asm/io.h>
+#include <asm/pgtable.h>
+#include <asm/machdep.h>
+#include <asm/time.h>
+
+#include "maple.h"
+
+#ifdef DEBUG
+#define DBG(x...) printk(x)
+#else
+#define DBG(x...)
+#endif
+
+extern void GregorianDay(struct rtc_time * tm);
+
+static int maple_rtc_addr;
+
+static int maple_clock_read(int addr)
+{
+       outb_p(addr, maple_rtc_addr);
+       return inb_p(maple_rtc_addr+1);
+}
+
+static void maple_clock_write(unsigned long val, int addr)
+{
+       outb_p(addr, maple_rtc_addr);
+       outb_p(val, maple_rtc_addr+1);
+}
+
+void maple_get_rtc_time(struct rtc_time *tm)
+{
+       int uip, i;
+
+       /* The Linux interpretation of the CMOS clock register contents:
+        * When the Update-In-Progress (UIP) flag goes from 1 to 0, the
+        * RTC registers show the second which has precisely just started.
+        * Let's hope other operating systems interpret the RTC the same way.
+        */
+
+       /* Since the UIP flag is set for about 2.2 ms and the clock
+        * is typically written with a precision of 1 jiffy, trying
+        * to obtain a precision better than a few milliseconds is
+        * an illusion. Only consistency is interesting, this also
+        * allows to use the routine for /dev/rtc without a potential
+        * 1 second kernel busy loop triggered by any reader of /dev/rtc.
+        */
+
+       for (i = 0; i<1000000; i++) {
+               uip = maple_clock_read(RTC_FREQ_SELECT);
+               tm->tm_sec = maple_clock_read(RTC_SECONDS);
+               tm->tm_min = maple_clock_read(RTC_MINUTES);
+               tm->tm_hour = maple_clock_read(RTC_HOURS);
+               tm->tm_mday = maple_clock_read(RTC_DAY_OF_MONTH);
+               tm->tm_mon = maple_clock_read(RTC_MONTH);
+               tm->tm_year = maple_clock_read(RTC_YEAR);
+               uip |= maple_clock_read(RTC_FREQ_SELECT);
+               if ((uip & RTC_UIP)==0)
+                       break;
+       }
+
+       if (!(maple_clock_read(RTC_CONTROL) & RTC_DM_BINARY)
+           || RTC_ALWAYS_BCD) {
+               BCD_TO_BIN(tm->tm_sec);
+               BCD_TO_BIN(tm->tm_min);
+               BCD_TO_BIN(tm->tm_hour);
+               BCD_TO_BIN(tm->tm_mday);
+               BCD_TO_BIN(tm->tm_mon);
+               BCD_TO_BIN(tm->tm_year);
+         }
+       if ((tm->tm_year + 1900) < 1970)
+               tm->tm_year += 100;
+
+       GregorianDay(tm);
+}
+
+int maple_set_rtc_time(struct rtc_time *tm)
+{
+       unsigned char save_control, save_freq_select;
+       int sec, min, hour, mon, mday, year;
+
+       spin_lock(&rtc_lock);
+
+       save_control = maple_clock_read(RTC_CONTROL); /* tell the clock it's being set */
+
+       maple_clock_write((save_control|RTC_SET), RTC_CONTROL);
+
+       save_freq_select = maple_clock_read(RTC_FREQ_SELECT); /* stop and reset prescaler */
+
+       maple_clock_write((save_freq_select|RTC_DIV_RESET2), RTC_FREQ_SELECT);
+
+       sec = tm->tm_sec;
+       min = tm->tm_min;
+       hour = tm->tm_hour;
+       mon = tm->tm_mon;
+       mday = tm->tm_mday;
+       year = tm->tm_year;
+
+       if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {
+               BIN_TO_BCD(sec);
+               BIN_TO_BCD(min);
+               BIN_TO_BCD(hour);
+               BIN_TO_BCD(mon);
+               BIN_TO_BCD(mday);
+               BIN_TO_BCD(year);
+       }
+       maple_clock_write(sec, RTC_SECONDS);
+       maple_clock_write(min, RTC_MINUTES);
+       maple_clock_write(hour, RTC_HOURS);
+       maple_clock_write(mon, RTC_MONTH);
+       maple_clock_write(mday, RTC_DAY_OF_MONTH);
+       maple_clock_write(year, RTC_YEAR);
+
+       /* The following flags have to be released exactly in this order,
+        * otherwise the DS12887 (popular MC146818A clone with integrated
+        * battery and quartz) will not reset the oscillator and will not
+        * update precisely 500 ms later. You won't find this mentioned in
+        * the Dallas Semiconductor data sheets, but who believes data
+        * sheets anyway ...                           -- Markus Kuhn
+        */
+       maple_clock_write(save_control, RTC_CONTROL);
+       maple_clock_write(save_freq_select, RTC_FREQ_SELECT);
+
+       spin_unlock(&rtc_lock);
+
+       return 0;
+}
+
+unsigned long __init maple_get_boot_time(void)
+{
+       struct rtc_time tm;
+       struct device_node *rtcs;
+
+       rtcs = find_compatible_devices("rtc", "pnpPNP,b00");
+       if (rtcs && rtcs->addrs) {
+               maple_rtc_addr = rtcs->addrs[0].address;
+               printk(KERN_INFO "Maple: Found RTC at 0x%x\n", maple_rtc_addr);
+       } else {
+               maple_rtc_addr = RTC_PORT(0); /* legacy address */
+               printk(KERN_INFO "Maple: No device node for RTC, assuming "
+                      "legacy address (0x%x)\n", maple_rtc_addr);
+       }
+       
+       maple_get_rtc_time(&tm);
+       return mktime(tm.tm_year+1900, tm.tm_mon+1, tm.tm_mday,
+                     tm.tm_hour, tm.tm_min, tm.tm_sec);
+}
+
index 3cf7f3dab511454381d1edb59634d8a71be0a000..327c08ce429169ba5f1fbb0e473bb5cdb72a6bec 100644 (file)
@@ -55,8 +55,7 @@ obj-$(CONFIG_HVCS)            += hvcserver.o
 
 obj-$(CONFIG_PPC_PMAC)         += udbg_scc.o
 
-obj-$(CONFIG_PPC_MAPLE)                += maple_setup.o maple_pci.o maple_time.o \
-                                  udbg_16550.o
+obj-$(CONFIG_PPC_MAPLE)                += udbg_16550.o
 
 ifdef CONFIG_SMP
 obj-$(CONFIG_PPC_PMAC)         += smp-tbsync.o
diff --git a/arch/ppc64/kernel/maple_pci.c b/arch/ppc64/kernel/maple_pci.c
deleted file mode 100644 (file)
index 633324b..0000000
+++ /dev/null
@@ -1,520 +0,0 @@
-/*
- * Copyright (C) 2004 Benjamin Herrenschmuidt (benh@kernel.crashing.org),
- *                   IBM Corp.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
-
-#define DEBUG
-
-#include <linux/kernel.h>
-#include <linux/pci.h>
-#include <linux/delay.h>
-#include <linux/string.h>
-#include <linux/init.h>
-#include <linux/bootmem.h>
-
-#include <asm/sections.h>
-#include <asm/io.h>
-#include <asm/prom.h>
-#include <asm/pci-bridge.h>
-#include <asm/machdep.h>
-#include <asm/iommu.h>
-#include <asm/ppc-pci.h>
-
-#ifdef DEBUG
-#define DBG(x...) printk(x)
-#else
-#define DBG(x...)
-#endif
-
-static struct pci_controller *u3_agp, *u3_ht;
-
-static int __init fixup_one_level_bus_range(struct device_node *node, int higher)
-{
-       for (; node != 0;node = node->sibling) {
-               int * bus_range;
-               unsigned int *class_code;
-               int len;
-
-               /* For PCI<->PCI bridges or CardBus bridges, we go down */
-               class_code = (unsigned int *) get_property(node, "class-code", NULL);
-               if (!class_code || ((*class_code >> 8) != PCI_CLASS_BRIDGE_PCI &&
-                       (*class_code >> 8) != PCI_CLASS_BRIDGE_CARDBUS))
-                       continue;
-               bus_range = (int *) get_property(node, "bus-range", &len);
-               if (bus_range != NULL && len > 2 * sizeof(int)) {
-                       if (bus_range[1] > higher)
-                               higher = bus_range[1];
-               }
-               higher = fixup_one_level_bus_range(node->child, higher);
-       }
-       return higher;
-}
-
-/* This routine fixes the "bus-range" property of all bridges in the
- * system since they tend to have their "last" member wrong on macs
- *
- * Note that the bus numbers manipulated here are OF bus numbers, they
- * are not Linux bus numbers.
- */
-static void __init fixup_bus_range(struct device_node *bridge)
-{
-       int * bus_range;
-       int len;
-
-       /* Lookup the "bus-range" property for the hose */
-       bus_range = (int *) get_property(bridge, "bus-range", &len);
-       if (bus_range == NULL || len < 2 * sizeof(int)) {
-               printk(KERN_WARNING "Can't get bus-range for %s\n",
-                              bridge->full_name);
-               return;
-       }
-       bus_range[1] = fixup_one_level_bus_range(bridge->child, bus_range[1]);
-}
-
-
-#define U3_AGP_CFA0(devfn, off)        \
-       ((1 << (unsigned long)PCI_SLOT(dev_fn)) \
-       | (((unsigned long)PCI_FUNC(dev_fn)) << 8) \
-       | (((unsigned long)(off)) & 0xFCUL))
-
-#define U3_AGP_CFA1(bus, devfn, off)   \
-       ((((unsigned long)(bus)) << 16) \
-       |(((unsigned long)(devfn)) << 8) \
-       |(((unsigned long)(off)) & 0xFCUL) \
-       |1UL)
-
-static unsigned long u3_agp_cfg_access(struct pci_controller* hose,
-                                      u8 bus, u8 dev_fn, u8 offset)
-{
-       unsigned int caddr;
-
-       if (bus == hose->first_busno) {
-               if (dev_fn < (11 << 3))
-                       return 0;
-               caddr = U3_AGP_CFA0(dev_fn, offset);
-       } else
-               caddr = U3_AGP_CFA1(bus, dev_fn, offset);
-
-       /* Uninorth will return garbage if we don't read back the value ! */
-       do {
-               out_le32(hose->cfg_addr, caddr);
-       } while (in_le32(hose->cfg_addr) != caddr);
-
-       offset &= 0x07;
-       return ((unsigned long)hose->cfg_data) + offset;
-}
-
-static int u3_agp_read_config(struct pci_bus *bus, unsigned int devfn,
-                             int offset, int len, u32 *val)
-{
-       struct pci_controller *hose;
-       unsigned long addr;
-
-       hose = pci_bus_to_host(bus);
-       if (hose == NULL)
-               return PCIBIOS_DEVICE_NOT_FOUND;
-
-       addr = u3_agp_cfg_access(hose, bus->number, devfn, offset);
-       if (!addr)
-               return PCIBIOS_DEVICE_NOT_FOUND;
-       /*
-        * Note: the caller has already checked that offset is
-        * suitably aligned and that len is 1, 2 or 4.
-        */
-       switch (len) {
-       case 1:
-               *val = in_8((u8 *)addr);
-               break;
-       case 2:
-               *val = in_le16((u16 *)addr);
-               break;
-       default:
-               *val = in_le32((u32 *)addr);
-               break;
-       }
-       return PCIBIOS_SUCCESSFUL;
-}
-
-static int u3_agp_write_config(struct pci_bus *bus, unsigned int devfn,
-                              int offset, int len, u32 val)
-{
-       struct pci_controller *hose;
-       unsigned long addr;
-
-       hose = pci_bus_to_host(bus);
-       if (hose == NULL)
-               return PCIBIOS_DEVICE_NOT_FOUND;
-
-       addr = u3_agp_cfg_access(hose, bus->number, devfn, offset);
-       if (!addr)
-               return PCIBIOS_DEVICE_NOT_FOUND;
-       /*
-        * Note: the caller has already checked that offset is
-        * suitably aligned and that len is 1, 2 or 4.
-        */
-       switch (len) {
-       case 1:
-               out_8((u8 *)addr, val);
-               (void) in_8((u8 *)addr);
-               break;
-       case 2:
-               out_le16((u16 *)addr, val);
-               (void) in_le16((u16 *)addr);
-               break;
-       default:
-               out_le32((u32 *)addr, val);
-               (void) in_le32((u32 *)addr);
-               break;
-       }
-       return PCIBIOS_SUCCESSFUL;
-}
-
-static struct pci_ops u3_agp_pci_ops =
-{
-       u3_agp_read_config,
-       u3_agp_write_config
-};
-
-
-#define U3_HT_CFA0(devfn, off)         \
-               ((((unsigned long)devfn) << 8) | offset)
-#define U3_HT_CFA1(bus, devfn, off)    \
-               (U3_HT_CFA0(devfn, off) \
-               + (((unsigned long)bus) << 16) \
-               + 0x01000000UL)
-
-static unsigned long u3_ht_cfg_access(struct pci_controller* hose,
-                                     u8 bus, u8 devfn, u8 offset)
-{
-       if (bus == hose->first_busno) {
-               if (PCI_SLOT(devfn) == 0)
-                       return 0;
-               return ((unsigned long)hose->cfg_data) + U3_HT_CFA0(devfn, offset);
-       } else
-               return ((unsigned long)hose->cfg_data) + U3_HT_CFA1(bus, devfn, offset);
-}
-
-static int u3_ht_read_config(struct pci_bus *bus, unsigned int devfn,
-                            int offset, int len, u32 *val)
-{
-       struct pci_controller *hose;
-       unsigned long addr;
-
-       hose = pci_bus_to_host(bus);
-       if (hose == NULL)
-               return PCIBIOS_DEVICE_NOT_FOUND;
-
-       addr = u3_ht_cfg_access(hose, bus->number, devfn, offset);
-       if (!addr)
-               return PCIBIOS_DEVICE_NOT_FOUND;
-
-       /*
-        * Note: the caller has already checked that offset is
-        * suitably aligned and that len is 1, 2 or 4.
-        */
-       switch (len) {
-       case 1:
-               *val = in_8((u8 *)addr);
-               break;
-       case 2:
-               *val = in_le16((u16 *)addr);
-               break;
-       default:
-               *val = in_le32((u32 *)addr);
-               break;
-       }
-       return PCIBIOS_SUCCESSFUL;
-}
-
-static int u3_ht_write_config(struct pci_bus *bus, unsigned int devfn,
-                             int offset, int len, u32 val)
-{
-       struct pci_controller *hose;
-       unsigned long addr;
-
-       hose = pci_bus_to_host(bus);
-       if (hose == NULL)
-               return PCIBIOS_DEVICE_NOT_FOUND;
-
-       addr = u3_ht_cfg_access(hose, bus->number, devfn, offset);
-       if (!addr)
-               return PCIBIOS_DEVICE_NOT_FOUND;
-       /*
-        * Note: the caller has already checked that offset is
-        * suitably aligned and that len is 1, 2 or 4.
-        */
-       switch (len) {
-       case 1:
-               out_8((u8 *)addr, val);
-               (void) in_8((u8 *)addr);
-               break;
-       case 2:
-               out_le16((u16 *)addr, val);
-               (void) in_le16((u16 *)addr);
-               break;
-       default:
-               out_le32((u32 *)addr, val);
-               (void) in_le32((u32 *)addr);
-               break;
-       }
-       return PCIBIOS_SUCCESSFUL;
-}
-
-static struct pci_ops u3_ht_pci_ops =
-{
-       u3_ht_read_config,
-       u3_ht_write_config
-};
-
-static void __init setup_u3_agp(struct pci_controller* hose)
-{
-       /* On G5, we move AGP up to high bus number so we don't need
-        * to reassign bus numbers for HT. If we ever have P2P bridges
-        * on AGP, we'll have to move pci_assign_all_buses to the
-        * pci_controller structure so we enable it for AGP and not for
-        * HT childs.
-        * We hard code the address because of the different size of
-        * the reg address cell, we shall fix that by killing struct
-        * reg_property and using some accessor functions instead
-        */
-       hose->first_busno = 0xf0;
-       hose->last_busno = 0xff;
-       hose->ops = &u3_agp_pci_ops;
-       hose->cfg_addr = ioremap(0xf0000000 + 0x800000, 0x1000);
-       hose->cfg_data = ioremap(0xf0000000 + 0xc00000, 0x1000);
-
-       u3_agp = hose;
-}
-
-static void __init setup_u3_ht(struct pci_controller* hose)
-{
-       hose->ops = &u3_ht_pci_ops;
-
-       /* We hard code the address because of the different size of
-        * the reg address cell, we shall fix that by killing struct
-        * reg_property and using some accessor functions instead
-        */
-       hose->cfg_data = (volatile unsigned char *)ioremap(0xf2000000, 0x02000000);
-
-       hose->first_busno = 0;
-       hose->last_busno = 0xef;
-
-       u3_ht = hose;
-}
-
-static int __init add_bridge(struct device_node *dev)
-{
-       int len;
-       struct pci_controller *hose;
-       char* disp_name;
-       int *bus_range;
-       int primary = 1;
-       struct property *of_prop;
-
-       DBG("Adding PCI host bridge %s\n", dev->full_name);
-
-       bus_range = (int *) get_property(dev, "bus-range", &len);
-       if (bus_range == NULL || len < 2 * sizeof(int)) {
-               printk(KERN_WARNING "Can't get bus-range for %s, assume bus 0\n",
-               dev->full_name);
-       }
-
-       hose = alloc_bootmem(sizeof(struct pci_controller));
-       if (hose == NULL)
-               return -ENOMEM;
-       pci_setup_pci_controller(hose);
-
-       hose->arch_data = dev;
-       hose->first_busno = bus_range ? bus_range[0] : 0;
-       hose->last_busno = bus_range ? bus_range[1] : 0xff;
-
-       of_prop = alloc_bootmem(sizeof(struct property) +
-                               sizeof(hose->global_number));
-       if (of_prop) {
-               memset(of_prop, 0, sizeof(struct property));
-               of_prop->name = "linux,pci-domain";
-               of_prop->length = sizeof(hose->global_number);
-               of_prop->value = (unsigned char *)&of_prop[1];
-               memcpy(of_prop->value, &hose->global_number, sizeof(hose->global_number));
-               prom_add_property(dev, of_prop);
-       }
-
-       disp_name = NULL;
-       if (device_is_compatible(dev, "u3-agp")) {
-               setup_u3_agp(hose);
-               disp_name = "U3-AGP";
-               primary = 0;
-       } else if (device_is_compatible(dev, "u3-ht")) {
-               setup_u3_ht(hose);
-               disp_name = "U3-HT";
-               primary = 1;
-       }
-       printk(KERN_INFO "Found %s PCI host bridge. Firmware bus number: %d->%d\n",
-               disp_name, hose->first_busno, hose->last_busno);
-
-       /* Interpret the "ranges" property */
-       /* This also maps the I/O region and sets isa_io/mem_base */
-       pci_process_bridge_OF_ranges(hose, dev, primary);
-       pci_setup_phb_io(hose, primary);
-
-       /* Fixup "bus-range" OF property */
-       fixup_bus_range(dev);
-
-       return 0;
-}
-
-
-void __init maple_pcibios_fixup(void)
-{
-       struct pci_dev *dev = NULL;
-
-       DBG(" -> maple_pcibios_fixup\n");
-
-       for_each_pci_dev(dev)
-               pci_read_irq_line(dev);
-
-       /* Do the mapping of the IO space */
-       phbs_remap_io();
-
-       DBG(" <- maple_pcibios_fixup\n");
-}
-
-static void __init maple_fixup_phb_resources(void)
-{
-       struct pci_controller *hose, *tmp;
-       
-       list_for_each_entry_safe(hose, tmp, &hose_list, list_node) {
-               unsigned long offset = (unsigned long)hose->io_base_virt - pci_io_base;
-               hose->io_resource.start += offset;
-               hose->io_resource.end += offset;
-               printk(KERN_INFO "PCI Host %d, io start: %lx; io end: %lx\n",
-                      hose->global_number,
-                      hose->io_resource.start, hose->io_resource.end);
-       }
-}
-
-void __init maple_pci_init(void)
-{
-       struct device_node *np, *root;
-       struct device_node *ht = NULL;
-
-       /* Probe root PCI hosts, that is on U3 the AGP host and the
-        * HyperTransport host. That one is actually "kept" around
-        * and actually added last as it's resource management relies
-        * on the AGP resources to have been setup first
-        */
-       root = of_find_node_by_path("/");
-       if (root == NULL) {
-               printk(KERN_CRIT "maple_find_bridges: can't find root of device tree\n");
-               return;
-       }
-       for (np = NULL; (np = of_get_next_child(root, np)) != NULL;) {
-               if (np->name == NULL)
-                       continue;
-               if (strcmp(np->name, "pci") == 0) {
-                       if (add_bridge(np) == 0)
-                               of_node_get(np);
-               }
-               if (strcmp(np->name, "ht") == 0) {
-                       of_node_get(np);
-                       ht = np;
-               }
-       }
-       of_node_put(root);
-
-       /* Now setup the HyperTransport host if we found any
-        */
-       if (ht && add_bridge(ht) != 0)
-               of_node_put(ht);
-
-       /* Fixup the IO resources on our host bridges as the common code
-        * does it only for childs of the host bridges
-        */
-       maple_fixup_phb_resources();
-
-       /* Setup the linkage between OF nodes and PHBs */ 
-       pci_devs_phb_init();
-
-       /* Fixup the PCI<->OF mapping for U3 AGP due to bus renumbering. We
-        * assume there is no P2P bridge on the AGP bus, which should be a
-        * safe assumptions hopefully.
-        */
-       if (u3_agp) {
-               struct device_node *np = u3_agp->arch_data;
-               PCI_DN(np)->busno = 0xf0;
-               for (np = np->child; np; np = np->sibling)
-                       PCI_DN(np)->busno = 0xf0;
-       }
-
-       /* Tell pci.c to use the common resource allocation mecanism */
-       pci_probe_only = 0;
-       
-       /* Allow all IO */
-       io_page_mask = -1;
-}
-
-int maple_pci_get_legacy_ide_irq(struct pci_dev *pdev, int channel)
-{
-       struct device_node *np;
-       int irq = channel ? 15 : 14;
-
-       if (pdev->vendor != PCI_VENDOR_ID_AMD ||
-           pdev->device != PCI_DEVICE_ID_AMD_8111_IDE)
-               return irq;
-
-       np = pci_device_to_OF_node(pdev);
-       if (np == NULL)
-               return irq;
-       if (np->n_intrs < 2)
-               return irq;
-       return np->intrs[channel & 0x1].line;
-}
-
-/* XXX: To remove once all firmwares are ok */
-static void fixup_maple_ide(struct pci_dev* dev)
-{
-#if 0 /* Enable this to enable IDE port 0 */
-       {
-               u8 v;
-
-               pci_read_config_byte(dev, 0x40, &v);
-               v |= 2;
-               pci_write_config_byte(dev, 0x40, v);
-       }
-#endif
-#if 0 /* fix bus master base */
-       pci_write_config_dword(dev, 0x20, 0xcc01);
-       printk("old ide resource: %lx -> %lx \n",
-              dev->resource[4].start, dev->resource[4].end);
-       dev->resource[4].start = 0xcc00;
-       dev->resource[4].end = 0xcc10;
-#endif
-#if 1 /* Enable this to fixup IDE sense/polarity of irqs in IO-APICs */
-       {
-               struct pci_dev *apicdev;
-               u32 v;
-
-               apicdev = pci_get_slot (dev->bus, PCI_DEVFN(5,0));
-               if (apicdev == NULL)
-                       printk("IDE Fixup IRQ: Can't find IO-APIC !\n");
-               else {
-                       pci_write_config_byte(apicdev, 0xf2, 0x10 + 2*14);
-                       pci_read_config_dword(apicdev, 0xf4, &v);
-                       v &= ~0x00000022;
-                       pci_write_config_dword(apicdev, 0xf4, v);
-                       pci_write_config_byte(apicdev, 0xf2, 0x10 + 2*15);
-                       pci_read_config_dword(apicdev, 0xf4, &v);
-                       v &= ~0x00000022;
-                       pci_write_config_dword(apicdev, 0xf4, v);
-                       pci_dev_put(apicdev);
-               }
-       }
-#endif
-}
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8111_IDE,
-                        fixup_maple_ide);
diff --git a/arch/ppc64/kernel/maple_setup.c b/arch/ppc64/kernel/maple_setup.c
deleted file mode 100644 (file)
index a107ed6..0000000
+++ /dev/null
@@ -1,300 +0,0 @@
-/*
- *  arch/ppc64/kernel/maple_setup.c
- *
- *  (c) Copyright 2004 Benjamin Herrenschmidt (benh@kernel.crashing.org),
- *                     IBM Corp. 
- *
- *  This program is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU General Public License
- *  as published by the Free Software Foundation; either version
- *  2 of the License, or (at your option) any later version.
- *
- */
-
-#define DEBUG
-
-#include <linux/config.h>
-#include <linux/init.h>
-#include <linux/errno.h>
-#include <linux/sched.h>
-#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <linux/stddef.h>
-#include <linux/unistd.h>
-#include <linux/ptrace.h>
-#include <linux/slab.h>
-#include <linux/user.h>
-#include <linux/a.out.h>
-#include <linux/tty.h>
-#include <linux/string.h>
-#include <linux/delay.h>
-#include <linux/ioport.h>
-#include <linux/major.h>
-#include <linux/initrd.h>
-#include <linux/vt_kern.h>
-#include <linux/console.h>
-#include <linux/ide.h>
-#include <linux/pci.h>
-#include <linux/adb.h>
-#include <linux/cuda.h>
-#include <linux/pmu.h>
-#include <linux/irq.h>
-#include <linux/seq_file.h>
-#include <linux/root_dev.h>
-#include <linux/serial.h>
-#include <linux/smp.h>
-
-#include <asm/processor.h>
-#include <asm/sections.h>
-#include <asm/prom.h>
-#include <asm/system.h>
-#include <asm/pgtable.h>
-#include <asm/bitops.h>
-#include <asm/io.h>
-#include <asm/pci-bridge.h>
-#include <asm/iommu.h>
-#include <asm/machdep.h>
-#include <asm/dma.h>
-#include <asm/cputable.h>
-#include <asm/time.h>
-#include <asm/of_device.h>
-#include <asm/lmb.h>
-#include <asm/mpic.h>
-#include <asm/udbg.h>
-
-#ifdef DEBUG
-#define DBG(fmt...) udbg_printf(fmt)
-#else
-#define DBG(fmt...)
-#endif
-
-extern int maple_set_rtc_time(struct rtc_time *tm);
-extern void maple_get_rtc_time(struct rtc_time *tm);
-extern unsigned long maple_get_boot_time(void);
-extern void maple_calibrate_decr(void);
-extern void maple_pci_init(void);
-extern void maple_pcibios_fixup(void);
-extern int maple_pci_get_legacy_ide_irq(struct pci_dev *dev, int channel);
-extern void generic_find_legacy_serial_ports(u64 *physport,
-               unsigned int *default_speed);
-
-static void maple_restart(char *cmd)
-{
-       unsigned int maple_nvram_base;
-       unsigned int maple_nvram_offset;
-       unsigned int maple_nvram_command;
-       struct device_node *rtcs;
-
-       /* find NVRAM device */
-       rtcs = find_compatible_devices("nvram", "AMD8111");
-       if (rtcs && rtcs->addrs) {
-               maple_nvram_base = rtcs->addrs[0].address;
-       } else {
-               printk(KERN_EMERG "Maple: Unable to find NVRAM\n");
-               printk(KERN_EMERG "Maple: Manual Restart Required\n");
-               return;
-       }
-
-       /* find service processor device */
-       rtcs = find_devices("service-processor");
-       if (!rtcs) {
-               printk(KERN_EMERG "Maple: Unable to find Service Processor\n");
-               printk(KERN_EMERG "Maple: Manual Restart Required\n");
-               return;
-       }
-       maple_nvram_offset = *(unsigned int*) get_property(rtcs,
-                       "restart-addr", NULL);
-       maple_nvram_command = *(unsigned int*) get_property(rtcs,
-                       "restart-value", NULL);
-
-       /* send command */
-       outb_p(maple_nvram_command, maple_nvram_base + maple_nvram_offset);
-       for (;;) ;
-}
-
-static void maple_power_off(void)
-{
-       unsigned int maple_nvram_base;
-       unsigned int maple_nvram_offset;
-       unsigned int maple_nvram_command;
-       struct device_node *rtcs;
-
-       /* find NVRAM device */
-       rtcs = find_compatible_devices("nvram", "AMD8111");
-       if (rtcs && rtcs->addrs) {
-               maple_nvram_base = rtcs->addrs[0].address;
-       } else {
-               printk(KERN_EMERG "Maple: Unable to find NVRAM\n");
-               printk(KERN_EMERG "Maple: Manual Power-Down Required\n");
-               return;
-       }
-
-       /* find service processor device */
-       rtcs = find_devices("service-processor");
-       if (!rtcs) {
-               printk(KERN_EMERG "Maple: Unable to find Service Processor\n");
-               printk(KERN_EMERG "Maple: Manual Power-Down Required\n");
-               return;
-       }
-       maple_nvram_offset = *(unsigned int*) get_property(rtcs,
-                       "power-off-addr", NULL);
-       maple_nvram_command = *(unsigned int*) get_property(rtcs,
-                       "power-off-value", NULL);
-
-       /* send command */
-       outb_p(maple_nvram_command, maple_nvram_base + maple_nvram_offset);
-       for (;;) ;
-}
-
-static void maple_halt(void)
-{
-       maple_power_off();
-}
-
-#ifdef CONFIG_SMP
-struct smp_ops_t maple_smp_ops = {
-       .probe          = smp_mpic_probe,
-       .message_pass   = smp_mpic_message_pass,
-       .kick_cpu       = smp_generic_kick_cpu,
-       .setup_cpu      = smp_mpic_setup_cpu,
-       .give_timebase  = smp_generic_give_timebase,
-       .take_timebase  = smp_generic_take_timebase,
-};
-#endif /* CONFIG_SMP */
-
-void __init maple_setup_arch(void)
-{
-       /* init to some ~sane value until calibrate_delay() runs */
-       loops_per_jiffy = 50000000;
-
-       /* Setup SMP callback */
-#ifdef CONFIG_SMP
-       smp_ops = &maple_smp_ops;
-#endif
-       /* Lookup PCI hosts */
-               maple_pci_init();
-
-#ifdef CONFIG_DUMMY_CONSOLE
-       conswitchp = &dummy_con;
-#endif
-
-       printk(KERN_INFO "Using native/NAP idle loop\n");
-}
-
-/* 
- * Early initialization.
- */
-static void __init maple_init_early(void)
-{
-       unsigned int default_speed;
-       u64 physport;
-
-       DBG(" -> maple_init_early\n");
-
-       /* Initialize hash table, from now on, we can take hash faults
-        * and call ioremap
-        */
-       hpte_init_native();
-
-       /* Find the serial port */
-       generic_find_legacy_serial_ports(&physport, &default_speed);
-
-       DBG("phys port addr: %lx\n", (long)physport);
-
-       if (physport) {
-               void *comport;
-               /* Map the uart for udbg. */
-               comport = (void *)ioremap(physport, 16);
-               udbg_init_uart(comport, default_speed);
-
-               DBG("Hello World !\n");
-       }
-
-       /* Setup interrupt mapping options */
-       ppc64_interrupt_controller = IC_OPEN_PIC;
-
-       iommu_init_early_u3();
-
-       DBG(" <- maple_init_early\n");
-}
-
-
-static __init void maple_init_IRQ(void)
-{
-       struct device_node *root;
-       unsigned int *opprop;
-       unsigned long opic_addr;
-       struct mpic *mpic;
-       unsigned char senses[128];
-       int n;
-
-       DBG(" -> maple_init_IRQ\n");
-
-       /* XXX: Non standard, replace that with a proper openpic/mpic node
-        * in the device-tree. Find the Open PIC if present */
-       root = of_find_node_by_path("/");
-       opprop = (unsigned int *) get_property(root,
-                               "platform-open-pic", NULL);
-       if (opprop == 0)
-               panic("OpenPIC not found !\n");
-
-       n = prom_n_addr_cells(root);
-       for (opic_addr = 0; n > 0; --n)
-               opic_addr = (opic_addr << 32) + *opprop++;
-       of_node_put(root);
-
-       /* Obtain sense values from device-tree */
-       prom_get_irq_senses(senses, 0, 128);
-
-       mpic = mpic_alloc(opic_addr,
-                         MPIC_PRIMARY | MPIC_BIG_ENDIAN |
-                         MPIC_BROKEN_U3 | MPIC_WANTS_RESET,
-                         0, 0, 128, 128, senses, 128, "U3-MPIC");
-       BUG_ON(mpic == NULL);
-       mpic_init(mpic);
-
-       DBG(" <- maple_init_IRQ\n");
-}
-
-static void __init maple_progress(char *s, unsigned short hex)
-{
-       printk("*** %04x : %s\n", hex, s ? s : "");
-}
-
-
-/*
- * Called very early, MMU is off, device-tree isn't unflattened
- */
-static int __init maple_probe(int platform)
-{
-       if (platform != PLATFORM_MAPLE)
-               return 0;
-       /*
-        * On U3, the DART (iommu) must be allocated now since it
-        * has an impact on htab_initialize (due to the large page it
-        * occupies having to be broken up so the DART itself is not
-        * part of the cacheable linar mapping
-        */
-       alloc_u3_dart_table();
-
-       return 1;
-}
-
-struct machdep_calls __initdata maple_md = {
-       .probe                  = maple_probe,
-       .setup_arch             = maple_setup_arch,
-       .init_early             = maple_init_early,
-       .init_IRQ               = maple_init_IRQ,
-       .get_irq                = mpic_get_irq,
-       .pcibios_fixup          = maple_pcibios_fixup,
-       .pci_get_legacy_ide_irq = maple_pci_get_legacy_ide_irq,
-       .restart                = maple_restart,
-       .power_off              = maple_power_off,
-       .halt                   = maple_halt,
-               .get_boot_time          = maple_get_boot_time,
-               .set_rtc_time           = maple_set_rtc_time,
-               .get_rtc_time           = maple_get_rtc_time,
-       .calibrate_decr         = generic_calibrate_decr,
-       .progress               = maple_progress,
-       .idle_loop              = native_idle,
-};
diff --git a/arch/ppc64/kernel/maple_time.c b/arch/ppc64/kernel/maple_time.c
deleted file mode 100644 (file)
index 445cb74..0000000
+++ /dev/null
@@ -1,178 +0,0 @@
-/*
- *  arch/ppc64/kernel/maple_time.c
- *
- *  (c) Copyright 2004 Benjamin Herrenschmidt (benh@kernel.crashing.org),
- *                     IBM Corp. 
- *
- *  This program is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU General Public License
- *  as published by the Free Software Foundation; either version
- *  2 of the License, or (at your option) any later version.
- *
- */
-
-#undef DEBUG
-
-#include <linux/config.h>
-#include <linux/errno.h>
-#include <linux/sched.h>
-#include <linux/kernel.h>
-#include <linux/param.h>
-#include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/init.h>
-#include <linux/time.h>
-#include <linux/adb.h>
-#include <linux/pmu.h>
-#include <linux/interrupt.h>
-#include <linux/mc146818rtc.h>
-#include <linux/bcd.h>
-
-#include <asm/sections.h>
-#include <asm/prom.h>
-#include <asm/system.h>
-#include <asm/io.h>
-#include <asm/pgtable.h>
-#include <asm/machdep.h>
-#include <asm/time.h>
-
-#ifdef DEBUG
-#define DBG(x...) printk(x)
-#else
-#define DBG(x...)
-#endif
-
-extern void GregorianDay(struct rtc_time * tm);
-
-static int maple_rtc_addr;
-
-static int maple_clock_read(int addr)
-{
-       outb_p(addr, maple_rtc_addr);
-       return inb_p(maple_rtc_addr+1);
-}
-
-static void maple_clock_write(unsigned long val, int addr)
-{
-       outb_p(addr, maple_rtc_addr);
-       outb_p(val, maple_rtc_addr+1);
-}
-
-void maple_get_rtc_time(struct rtc_time *tm)
-{
-       int uip, i;
-
-       /* The Linux interpretation of the CMOS clock register contents:
-        * When the Update-In-Progress (UIP) flag goes from 1 to 0, the
-        * RTC registers show the second which has precisely just started.
-        * Let's hope other operating systems interpret the RTC the same way.
-        */
-
-       /* Since the UIP flag is set for about 2.2 ms and the clock
-        * is typically written with a precision of 1 jiffy, trying
-        * to obtain a precision better than a few milliseconds is
-        * an illusion. Only consistency is interesting, this also
-        * allows to use the routine for /dev/rtc without a potential
-        * 1 second kernel busy loop triggered by any reader of /dev/rtc.
-        */
-
-       for (i = 0; i<1000000; i++) {
-               uip = maple_clock_read(RTC_FREQ_SELECT);
-               tm->tm_sec = maple_clock_read(RTC_SECONDS);
-               tm->tm_min = maple_clock_read(RTC_MINUTES);
-               tm->tm_hour = maple_clock_read(RTC_HOURS);
-               tm->tm_mday = maple_clock_read(RTC_DAY_OF_MONTH);
-               tm->tm_mon = maple_clock_read(RTC_MONTH);
-               tm->tm_year = maple_clock_read(RTC_YEAR);
-               uip |= maple_clock_read(RTC_FREQ_SELECT);
-               if ((uip & RTC_UIP)==0)
-                       break;
-       }
-
-       if (!(maple_clock_read(RTC_CONTROL) & RTC_DM_BINARY)
-           || RTC_ALWAYS_BCD) {
-               BCD_TO_BIN(tm->tm_sec);
-               BCD_TO_BIN(tm->tm_min);
-               BCD_TO_BIN(tm->tm_hour);
-               BCD_TO_BIN(tm->tm_mday);
-               BCD_TO_BIN(tm->tm_mon);
-               BCD_TO_BIN(tm->tm_year);
-         }
-       if ((tm->tm_year + 1900) < 1970)
-               tm->tm_year += 100;
-
-       GregorianDay(tm);
-}
-
-int maple_set_rtc_time(struct rtc_time *tm)
-{
-       unsigned char save_control, save_freq_select;
-       int sec, min, hour, mon, mday, year;
-
-       spin_lock(&rtc_lock);
-
-       save_control = maple_clock_read(RTC_CONTROL); /* tell the clock it's being set */
-
-       maple_clock_write((save_control|RTC_SET), RTC_CONTROL);
-
-       save_freq_select = maple_clock_read(RTC_FREQ_SELECT); /* stop and reset prescaler */
-
-       maple_clock_write((save_freq_select|RTC_DIV_RESET2), RTC_FREQ_SELECT);
-
-       sec = tm->tm_sec;
-       min = tm->tm_min;
-       hour = tm->tm_hour;
-       mon = tm->tm_mon;
-       mday = tm->tm_mday;
-       year = tm->tm_year;
-
-       if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {
-               BIN_TO_BCD(sec);
-               BIN_TO_BCD(min);
-               BIN_TO_BCD(hour);
-               BIN_TO_BCD(mon);
-               BIN_TO_BCD(mday);
-               BIN_TO_BCD(year);
-       }
-       maple_clock_write(sec, RTC_SECONDS);
-       maple_clock_write(min, RTC_MINUTES);
-       maple_clock_write(hour, RTC_HOURS);
-       maple_clock_write(mon, RTC_MONTH);
-       maple_clock_write(mday, RTC_DAY_OF_MONTH);
-       maple_clock_write(year, RTC_YEAR);
-
-       /* The following flags have to be released exactly in this order,
-        * otherwise the DS12887 (popular MC146818A clone with integrated
-        * battery and quartz) will not reset the oscillator and will not
-        * update precisely 500 ms later. You won't find this mentioned in
-        * the Dallas Semiconductor data sheets, but who believes data
-        * sheets anyway ...                           -- Markus Kuhn
-        */
-       maple_clock_write(save_control, RTC_CONTROL);
-       maple_clock_write(save_freq_select, RTC_FREQ_SELECT);
-
-       spin_unlock(&rtc_lock);
-
-       return 0;
-}
-
-unsigned long __init maple_get_boot_time(void)
-{
-       struct rtc_time tm;
-       struct device_node *rtcs;
-
-       rtcs = find_compatible_devices("rtc", "pnpPNP,b00");
-       if (rtcs && rtcs->addrs) {
-               maple_rtc_addr = rtcs->addrs[0].address;
-               printk(KERN_INFO "Maple: Found RTC at 0x%x\n", maple_rtc_addr);
-       } else {
-               maple_rtc_addr = RTC_PORT(0); /* legacy address */
-               printk(KERN_INFO "Maple: No device node for RTC, assuming "
-                      "legacy address (0x%x)\n", maple_rtc_addr);
-       }
-       
-       maple_get_rtc_time(&tm);
-       return mktime(tm.tm_year+1900, tm.tm_mon+1, tm.tm_mday,
-                     tm.tm_hour, tm.tm_min, tm.tm_sec);
-}
-