1 /* 2 * Board setup routines for the storcenter 3 * 4 * Copyright 2007 (C) Oyvind Repvik (nail@nslu2-linux.org) 5 * Copyright 2007 Andy Wilcox, Jon Loeliger 6 * 7 * Based on linkstation.c by G. Liakhovetski 8 * 9 * This file is licensed under the terms of the GNU General Public License 10 * version 2. This program is licensed "as is" without any warranty of 11 * any kind, whether express or implied. 12 */ 13 14 #include <linux/kernel.h> 15 #include <linux/pci.h> 16 #include <linux/initrd.h> 17 #include <linux/mtd/physmap.h> 18 #include <linux/of_platform.h> 19 20 #include <asm/system.h> 21 #include <asm/time.h> 22 #include <asm/prom.h> 23 #include <asm/mpic.h> 24 #include <asm/pci-bridge.h> 25 26 #include "mpc10x.h" 27 28 29 #ifdef CONFIG_MTD_PHYSMAP 30 static struct mtd_partition storcenter_physmap_partitions[] = { 31 { 32 .name = "kernel", 33 .offset = 0x000000, 34 .size = 0x170000, 35 }, 36 { 37 .name = "rootfs", 38 .offset = 0x170000, 39 .size = 0x590000, 40 }, 41 { 42 .name = "uboot", 43 .offset = 0x700000, 44 .size = 0x040000, 45 }, 46 { 47 .name = "config", 48 .offset = 0x740000, 49 .size = 0x0c0000, 50 }, 51 }; 52 #endif 53 54 55 static __initdata struct of_device_id storcenter_of_bus[] = { 56 { .name = "soc", }, 57 {}, 58 }; 59 60 static int __init storcenter_device_probe(void) 61 { 62 of_platform_bus_probe(NULL, storcenter_of_bus, NULL); 63 return 0; 64 } 65 machine_device_initcall(storcenter, storcenter_device_probe); 66 67 68 static int __init storcenter_add_bridge(struct device_node *dev) 69 { 70 #ifdef CONFIG_PCI 71 int len; 72 struct pci_controller *hose; 73 const int *bus_range; 74 75 printk("Adding PCI host bridge %s\n", dev->full_name); 76 77 hose = pcibios_alloc_controller(dev); 78 if (hose == NULL) 79 return -ENOMEM; 80 81 bus_range = of_get_property(dev, "bus-range", &len); 82 hose->first_busno = bus_range ? bus_range[0] : 0; 83 hose->last_busno = bus_range ? bus_range[1] : 0xff; 84 85 setup_indirect_pci(hose, MPC10X_MAPB_CNFG_ADDR, MPC10X_MAPB_CNFG_DATA, 0); 86 87 /* Interpret the "ranges" property */ 88 /* This also maps the I/O region and sets isa_io/mem_base */ 89 pci_process_bridge_OF_ranges(hose, dev, 1); 90 #endif 91 92 return 0; 93 } 94 95 static void __init storcenter_setup_arch(void) 96 { 97 struct device_node *np; 98 99 #ifdef CONFIG_MTD_PHYSMAP 100 physmap_set_partitions(storcenter_physmap_partitions, 101 ARRAY_SIZE(storcenter_physmap_partitions)); 102 #endif 103 104 /* Lookup PCI host bridges */ 105 for_each_compatible_node(np, "pci", "mpc10x-pci") 106 storcenter_add_bridge(np); 107 108 printk(KERN_INFO "IOMEGA StorCenter\n"); 109 } 110 111 /* 112 * Interrupt setup and service. Interrrupts on the turbostation come 113 * from the four PCI slots plus onboard 8241 devices: I2C, DUART. 114 */ 115 static void __init storcenter_init_IRQ(void) 116 { 117 struct mpic *mpic; 118 struct device_node *dnp; 119 const void *prop; 120 int size; 121 phys_addr_t paddr; 122 123 dnp = of_find_node_by_type(NULL, "open-pic"); 124 if (dnp == NULL) 125 return; 126 127 prop = of_get_property(dnp, "reg", &size); 128 if (prop == NULL) { 129 of_node_put(dnp); 130 return; 131 } 132 133 paddr = (phys_addr_t)of_translate_address(dnp, prop); 134 mpic = mpic_alloc(dnp, paddr, MPIC_PRIMARY | MPIC_WANTS_RESET, 135 16, 32, " OpenPIC "); 136 137 of_node_put(dnp); 138 139 BUG_ON(mpic == NULL); 140 141 /* 142 * 16 Serial Interrupts followed by 16 Internal Interrupts. 143 * I2C is the second internal, so it is at 17, 0x11020. 144 */ 145 mpic_assign_isu(mpic, 0, paddr + 0x10200); 146 mpic_assign_isu(mpic, 1, paddr + 0x11000); 147 148 mpic_init(mpic); 149 } 150 151 static void storcenter_restart(char *cmd) 152 { 153 local_irq_disable(); 154 155 /* Set exception prefix high - to the firmware */ 156 _nmask_and_or_msr(0, MSR_IP); 157 158 /* Wait for reset to happen */ 159 for (;;) ; 160 } 161 162 static int __init storcenter_probe(void) 163 { 164 unsigned long root = of_get_flat_dt_root(); 165 166 return of_flat_dt_is_compatible(root, "iomega,storcenter"); 167 } 168 169 define_machine(storcenter){ 170 .name = "IOMEGA StorCenter", 171 .probe = storcenter_probe, 172 .setup_arch = storcenter_setup_arch, 173 .init_IRQ = storcenter_init_IRQ, 174 .get_irq = mpic_get_irq, 175 .restart = storcenter_restart, 176 .calibrate_decr = generic_calibrate_decr, 177 }; 178