1/* sbus.c: SBus support routines. 2 * 3 * Copyright (C) 1995, 2006 David S. Miller (davem@davemloft.net) 4 */ 5 6#include <linux/kernel.h> 7#include <linux/slab.h> 8#include <linux/init.h> 9#include <linux/device.h> 10 11#include <asm/system.h> 12#include <asm/sbus.h> 13#include <asm/dma.h> 14#include <asm/oplib.h> 15#include <asm/prom.h> 16#include <asm/of_device.h> 17#include <asm/bpp.h> 18#include <asm/irq.h> 19 20static ssize_t 21show_sbusobppath_attr(struct device * dev, struct device_attribute * attr, char * buf) 22{ 23 struct sbus_dev *sbus; 24 25 sbus = to_sbus_device(dev); 26 27 return snprintf (buf, PAGE_SIZE, "%s\n", sbus->ofdev.node->full_name); 28} 29 30static DEVICE_ATTR(obppath, S_IRUSR | S_IRGRP | S_IROTH, show_sbusobppath_attr, NULL); 31 32struct sbus_bus *sbus_root; 33 34static void __init fill_sbus_device(struct device_node *dp, struct sbus_dev *sdev) 35{ 36 unsigned long base; 37 const void *pval; 38 int len, err; 39 40 sdev->prom_node = dp->node; 41 strcpy(sdev->prom_name, dp->name); 42 43 pval = of_get_property(dp, "reg", &len); 44 sdev->num_registers = 0; 45 if (pval) { 46 memcpy(sdev->reg_addrs, pval, len); 47 48 sdev->num_registers = 49 len / sizeof(struct linux_prom_registers); 50 51 base = (unsigned long) sdev->reg_addrs[0].phys_addr; 52 53 /* Compute the slot number. */ 54 if (base >= SUN_SBUS_BVADDR && sparc_cpu_model == sun4m) 55 sdev->slot = sbus_dev_slot(base); 56 else 57 sdev->slot = sdev->reg_addrs[0].which_io; 58 } 59 60 pval = of_get_property(dp, "ranges", &len); 61 sdev->num_device_ranges = 0; 62 if (pval) { 63 memcpy(sdev->device_ranges, pval, len); 64 sdev->num_device_ranges = 65 len / sizeof(struct linux_prom_ranges); 66 } 67 68 sbus_fill_device_irq(sdev); 69 70 sdev->ofdev.node = dp; 71 if (sdev->parent) 72 sdev->ofdev.dev.parent = &sdev->parent->ofdev.dev; 73 else 74 sdev->ofdev.dev.parent = &sdev->bus->ofdev.dev; 75 sdev->ofdev.dev.bus = &sbus_bus_type; 76 sprintf(sdev->ofdev.dev.bus_id, "sbus[%08x]", dp->node); 77 78 if (of_device_register(&sdev->ofdev) != 0) 79 printk(KERN_DEBUG "sbus: device registration error for %s!\n", 80 dp->path_component_name); 81 82 /* WE HAVE BEEN INVADED BY ALIENS! */ 83 err = sysfs_create_file(&sdev->ofdev.dev.kobj, &dev_attr_obppath.attr); 84} 85 86static void __init sbus_bus_ranges_init(struct device_node *dp, struct sbus_bus *sbus) 87{ 88 const void *pval; 89 int len; 90 91 pval = of_get_property(dp, "ranges", &len); 92 sbus->num_sbus_ranges = 0; 93 if (pval) { 94 memcpy(sbus->sbus_ranges, pval, len); 95 sbus->num_sbus_ranges = 96 len / sizeof(struct linux_prom_ranges); 97 98 sbus_arch_bus_ranges_init(dp->parent, sbus); 99 } 100} 101 102static void __init __apply_ranges_to_regs(struct linux_prom_ranges *ranges, 103 int num_ranges, 104 struct linux_prom_registers *regs, 105 int num_regs) 106{ 107 if (num_ranges) { 108 int regnum; 109 110 for (regnum = 0; regnum < num_regs; regnum++) { 111 int rngnum; 112 113 for (rngnum = 0; rngnum < num_ranges; rngnum++) { 114 if (regs[regnum].which_io == ranges[rngnum].ot_child_space) 115 break; 116 } 117 if (rngnum == num_ranges) { 118 /* We used to flag this as an error. Actually 119 * some devices do not report the regs as we expect. 120 * For example, see SUNW,pln device. In that case 121 * the reg property is in a format internal to that 122 * node, ie. it is not in the SBUS register space 123 * per se. -DaveM 124 */ 125 return; 126 } 127 regs[regnum].which_io = ranges[rngnum].ot_parent_space; 128 regs[regnum].phys_addr -= ranges[rngnum].ot_child_base; 129 regs[regnum].phys_addr += ranges[rngnum].ot_parent_base; 130 } 131 } 132} 133 134static void __init __fixup_regs_sdev(struct sbus_dev *sdev) 135{ 136 if (sdev->num_registers != 0) { 137 struct sbus_dev *parent = sdev->parent; 138 int i; 139 140 while (parent != NULL) { 141 __apply_ranges_to_regs(parent->device_ranges, 142 parent->num_device_ranges, 143 sdev->reg_addrs, 144 sdev->num_registers); 145 146 parent = parent->parent; 147 } 148 149 __apply_ranges_to_regs(sdev->bus->sbus_ranges, 150 sdev->bus->num_sbus_ranges, 151 sdev->reg_addrs, 152 sdev->num_registers); 153 154 for (i = 0; i < sdev->num_registers; i++) { 155 struct resource *res = &sdev->resource[i]; 156 157 res->start = sdev->reg_addrs[i].phys_addr; 158 res->end = (res->start + 159 (unsigned long)sdev->reg_addrs[i].reg_size - 1UL); 160 res->flags = IORESOURCE_IO | 161 (sdev->reg_addrs[i].which_io & 0xff); 162 } 163 } 164} 165 166static void __init sbus_fixup_all_regs(struct sbus_dev *first_sdev) 167{ 168 struct sbus_dev *sdev; 169 170 for (sdev = first_sdev; sdev; sdev = sdev->next) { 171 if (sdev->child) 172 sbus_fixup_all_regs(sdev->child); 173 __fixup_regs_sdev(sdev); 174 } 175} 176 177/* We preserve the "probe order" of these bus and device lists to give 178 * the same ordering as the old code. 179 */ 180static void __init sbus_insert(struct sbus_bus *sbus, struct sbus_bus **root) 181{ 182 while (*root) 183 root = &(*root)->next; 184 *root = sbus; 185 sbus->next = NULL; 186} 187 188static void __init sdev_insert(struct sbus_dev *sdev, struct sbus_dev **root) 189{ 190 while (*root) 191 root = &(*root)->next; 192 *root = sdev; 193 sdev->next = NULL; 194} 195 196static void __init walk_children(struct device_node *dp, struct sbus_dev *parent, struct sbus_bus *sbus) 197{ 198 dp = dp->child; 199 while (dp) { 200 struct sbus_dev *sdev; 201 202 sdev = kzalloc(sizeof(struct sbus_dev), GFP_ATOMIC); 203 if (sdev) { 204 sdev_insert(sdev, &parent->child); 205 206 sdev->bus = sbus; 207 sdev->parent = parent; 208 209 fill_sbus_device(dp, sdev); 210 211 walk_children(dp, sdev, sbus); 212 } 213 dp = dp->sibling; 214 } 215} 216 217static void __init build_one_sbus(struct device_node *dp, int num_sbus) 218{ 219 struct sbus_bus *sbus; 220 unsigned int sbus_clock; 221 struct device_node *dev_dp; 222 223 sbus = kzalloc(sizeof(struct sbus_bus), GFP_ATOMIC); 224 if (!sbus) 225 return; 226 227 sbus_insert(sbus, &sbus_root); 228 sbus->prom_node = dp->node; 229 230 sbus_setup_iommu(sbus, dp); 231 232 printk("sbus%d: ", num_sbus); 233 234 sbus_clock = of_getintprop_default(dp, "clock-frequency", 235 (25*1000*1000)); 236 sbus->clock_freq = sbus_clock; 237 238 printk("Clock %d.%d MHz\n", (int) ((sbus_clock/1000)/1000), 239 (int) (((sbus_clock/1000)%1000 != 0) ? 240 (((sbus_clock/1000)%1000) + 1000) : 0)); 241 242 strcpy(sbus->prom_name, dp->name); 243 244 sbus_setup_arch_props(sbus, dp); 245 246 sbus_bus_ranges_init(dp, sbus); 247 248 sbus->ofdev.node = dp; 249 sbus->ofdev.dev.parent = NULL; 250 sbus->ofdev.dev.bus = &sbus_bus_type; 251 sprintf(sbus->ofdev.dev.bus_id, "sbus%d", num_sbus); 252 253 if (of_device_register(&sbus->ofdev) != 0) 254 printk(KERN_DEBUG "sbus: device registration error for %s!\n", 255 sbus->ofdev.dev.bus_id); 256 257 dev_dp = dp->child; 258 while (dev_dp) { 259 struct sbus_dev *sdev; 260 261 sdev = kzalloc(sizeof(struct sbus_dev), GFP_ATOMIC); 262 if (sdev) { 263 sdev_insert(sdev, &sbus->devices); 264 265 sdev->bus = sbus; 266 sdev->parent = NULL; 267 fill_sbus_device(dev_dp, sdev); 268 269 walk_children(dev_dp, sdev, sbus); 270 } 271 dev_dp = dev_dp->sibling; 272 } 273 274 sbus_fixup_all_regs(sbus->devices); 275 276 dvma_init(sbus); 277} 278 279static int __init sbus_init(void) 280{ 281 struct device_node *dp; 282 const char *sbus_name = "sbus"; 283 int num_sbus = 0; 284 285 if (sbus_arch_preinit()) 286 return 0; 287 288 if (sparc_cpu_model == sun4d) 289 sbus_name = "sbi"; 290 291 for_each_node_by_name(dp, sbus_name) { 292 build_one_sbus(dp, num_sbus); 293 num_sbus++; 294 295 } 296 297 sbus_arch_postinit(); 298 299 return 0; 300} 301 302subsys_initcall(sbus_init); 303