linux/arch/ppc64/kernel/prom.c
<<
>>
Prefs
   1/*
   2 * 
   3 *
   4 * Procedures for interfacing to Open Firmware.
   5 *
   6 * Paul Mackerras       August 1996.
   7 * Copyright (C) 1996 Paul Mackerras.
   8 * 
   9 *  Adapted for 64bit PowerPC by Dave Engebretsen and Peter Bergner.
  10 *    {engebret|bergner}@us.ibm.com 
  11 *
  12 *      This program is free software; you can redistribute it and/or
  13 *      modify it under the terms of the GNU General Public License
  14 *      as published by the Free Software Foundation; either version
  15 *      2 of the License, or (at your option) any later version.
  16 */
  17
  18#undef DEBUG
  19
  20#include <stdarg.h>
  21#include <linux/config.h>
  22#include <linux/kernel.h>
  23#include <linux/string.h>
  24#include <linux/init.h>
  25#include <linux/version.h>
  26#include <linux/threads.h>
  27#include <linux/spinlock.h>
  28#include <linux/types.h>
  29#include <linux/pci.h>
  30#include <linux/proc_fs.h>
  31#include <linux/stringify.h>
  32#include <linux/delay.h>
  33#include <linux/initrd.h>
  34#include <linux/bitops.h>
  35#include <asm/prom.h>
  36#include <asm/rtas.h>
  37#include <asm/lmb.h>
  38#include <asm/abs_addr.h>
  39#include <asm/page.h>
  40#include <asm/processor.h>
  41#include <asm/irq.h>
  42#include <asm/io.h>
  43#include <asm/smp.h>
  44#include <asm/system.h>
  45#include <asm/mmu.h>
  46#include <asm/pgtable.h>
  47#include <asm/pci.h>
  48#include <asm/iommu.h>
  49#include <asm/bootinfo.h>
  50#include <asm/ppcdebug.h>
  51#include <asm/btext.h>
  52#include <asm/sections.h>
  53#include <asm/machdep.h>
  54
  55#ifdef DEBUG
  56#define DBG(fmt...) udbg_printf(fmt)
  57#else
  58#define DBG(fmt...)
  59#endif
  60
  61struct pci_reg_property {
  62        struct pci_address addr;
  63        u32 size_hi;
  64        u32 size_lo;
  65};
  66
  67struct isa_reg_property {
  68        u32 space;
  69        u32 address;
  70        u32 size;
  71};
  72
  73
  74typedef unsigned long interpret_func(struct device_node *, unsigned long,
  75                                     int, int, int);
  76
  77extern struct rtas_t rtas;
  78extern struct lmb lmb;
  79extern unsigned long klimit;
  80
  81static int __initdata dt_root_addr_cells;
  82static int __initdata dt_root_size_cells;
  83static int __initdata iommu_is_off;
  84int __initdata iommu_force_on;
  85typedef u32 cell_t;
  86
  87#if 0
  88static struct boot_param_header *initial_boot_params __initdata;
  89#else
  90struct boot_param_header *initial_boot_params;
  91#endif
  92
  93static struct device_node *allnodes = NULL;
  94
  95/* use when traversing tree through the allnext, child, sibling,
  96 * or parent members of struct device_node.
  97 */
  98static DEFINE_RWLOCK(devtree_lock);
  99
 100/* export that to outside world */
 101struct device_node *of_chosen;
 102
 103/*
 104 * Find the device_node with a given phandle.
 105 */
 106static struct device_node * find_phandle(phandle ph)
 107{
 108        struct device_node *np;
 109
 110        for (np = allnodes; np != 0; np = np->allnext)
 111                if (np->linux_phandle == ph)
 112                        return np;
 113        return NULL;
 114}
 115
 116/*
 117 * Find the interrupt parent of a node.
 118 */
 119static struct device_node * __devinit intr_parent(struct device_node *p)
 120{
 121        phandle *parp;
 122
 123        parp = (phandle *) get_property(p, "interrupt-parent", NULL);
 124        if (parp == NULL)
 125                return p->parent;
 126        return find_phandle(*parp);
 127}
 128
 129/*
 130 * Find out the size of each entry of the interrupts property
 131 * for a node.
 132 */
 133int __devinit prom_n_intr_cells(struct device_node *np)
 134{
 135        struct device_node *p;
 136        unsigned int *icp;
 137
 138        for (p = np; (p = intr_parent(p)) != NULL; ) {
 139                icp = (unsigned int *)
 140                        get_property(p, "#interrupt-cells", NULL);
 141                if (icp != NULL)
 142                        return *icp;
 143                if (get_property(p, "interrupt-controller", NULL) != NULL
 144                    || get_property(p, "interrupt-map", NULL) != NULL) {
 145                        printk("oops, node %s doesn't have #interrupt-cells\n",
 146                               p->full_name);
 147                        return 1;
 148                }
 149        }
 150#ifdef DEBUG_IRQ
 151        printk("prom_n_intr_cells failed for %s\n", np->full_name);
 152#endif
 153        return 1;
 154}
 155
 156/*
 157 * Map an interrupt from a device up to the platform interrupt
 158 * descriptor.
 159 */
 160static int __devinit map_interrupt(unsigned int **irq, struct device_node **ictrler,
 161                                   struct device_node *np, unsigned int *ints,
 162                                   int nintrc)
 163{
 164        struct device_node *p, *ipar;
 165        unsigned int *imap, *imask, *ip;
 166        int i, imaplen, match;
 167        int newintrc = 0, newaddrc = 0;
 168        unsigned int *reg;
 169        int naddrc;
 170
 171        reg = (unsigned int *) get_property(np, "reg", NULL);
 172        naddrc = prom_n_addr_cells(np);
 173        p = intr_parent(np);
 174        while (p != NULL) {
 175                if (get_property(p, "interrupt-controller", NULL) != NULL)
 176                        /* this node is an interrupt controller, stop here */
 177                        break;
 178                imap = (unsigned int *)
 179                        get_property(p, "interrupt-map", &imaplen);
 180                if (imap == NULL) {
 181                        p = intr_parent(p);
 182                        continue;
 183                }
 184                imask = (unsigned int *)
 185                        get_property(p, "interrupt-map-mask", NULL);
 186                if (imask == NULL) {
 187                        printk("oops, %s has interrupt-map but no mask\n",
 188                               p->full_name);
 189                        return 0;
 190                }
 191                imaplen /= sizeof(unsigned int);
 192                match = 0;
 193                ipar = NULL;
 194                while (imaplen > 0 && !match) {
 195                        /* check the child-interrupt field */
 196                        match = 1;
 197                        for (i = 0; i < naddrc && match; ++i)
 198                                match = ((reg[i] ^ imap[i]) & imask[i]) == 0;
 199                        for (; i < naddrc + nintrc && match; ++i)
 200                                match = ((ints[i-naddrc] ^ imap[i]) & imask[i]) == 0;
 201                        imap += naddrc + nintrc;
 202                        imaplen -= naddrc + nintrc;
 203                        /* grab the interrupt parent */
 204                        ipar = find_phandle((phandle) *imap++);
 205                        --imaplen;
 206                        if (ipar == NULL) {
 207                                printk("oops, no int parent %x in map of %s\n",
 208                                       imap[-1], p->full_name);
 209                                return 0;
 210                        }
 211                        /* find the parent's # addr and intr cells */
 212                        ip = (unsigned int *)
 213                                get_property(ipar, "#interrupt-cells", NULL);
 214                        if (ip == NULL) {
 215                                printk("oops, no #interrupt-cells on %s\n",
 216                                       ipar->full_name);
 217                                return 0;
 218                        }
 219                        newintrc = *ip;
 220                        ip = (unsigned int *)
 221                                get_property(ipar, "#address-cells", NULL);
 222                        newaddrc = (ip == NULL)? 0: *ip;
 223                        imap += newaddrc + newintrc;
 224                        imaplen -= newaddrc + newintrc;
 225                }
 226                if (imaplen < 0) {
 227                        printk("oops, error decoding int-map on %s, len=%d\n",
 228                               p->full_name, imaplen);
 229                        return 0;
 230                }
 231                if (!match) {
 232#ifdef DEBUG_IRQ
 233                        printk("oops, no match in %s int-map for %s\n",
 234                               p->full_name, np->full_name);
 235#endif
 236                        return 0;
 237                }
 238                p = ipar;
 239                naddrc = newaddrc;
 240                nintrc = newintrc;
 241                ints = imap - nintrc;
 242                reg = ints - naddrc;
 243        }
 244        if (p == NULL) {
 245#ifdef DEBUG_IRQ
 246                printk("hmmm, int tree for %s doesn't have ctrler\n",
 247                       np->full_name);
 248#endif
 249                return 0;
 250        }
 251        *irq = ints;
 252        *ictrler = p;
 253        return nintrc;
 254}
 255
 256static unsigned long __init finish_node_interrupts(struct device_node *np,
 257                                                   unsigned long mem_start,
 258                                                   int measure_only)
 259{
 260        unsigned int *ints;
 261        int intlen, intrcells, intrcount;
 262        int i, j, n;
 263        unsigned int *irq, virq;
 264        struct device_node *ic;
 265
 266        ints = (unsigned int *) get_property(np, "interrupts", &intlen);
 267        if (ints == NULL)
 268                return mem_start;
 269        intrcells = prom_n_intr_cells(np);
 270        intlen /= intrcells * sizeof(unsigned int);
 271        np->intrs = (struct interrupt_info *) mem_start;
 272        mem_start += intlen * sizeof(struct interrupt_info);
 273
 274        if (measure_only)
 275                return mem_start;
 276
 277        intrcount = 0;
 278        for (i = 0; i < intlen; ++i, ints += intrcells) {
 279                n = map_interrupt(&irq, &ic, np, ints, intrcells);
 280                if (n <= 0)
 281                        continue;
 282
 283                /* don't map IRQ numbers under a cascaded 8259 controller */
 284                if (ic && device_is_compatible(ic, "chrp,iic")) {
 285                        np->intrs[intrcount].line = irq[0];
 286                } else {
 287                        virq = virt_irq_create_mapping(irq[0]);
 288                        if (virq == NO_IRQ) {
 289                                printk(KERN_CRIT "Could not allocate interrupt"
 290                                       " number for %s\n", np->full_name);
 291                                continue;
 292                        }
 293                        np->intrs[intrcount].line = irq_offset_up(virq);
 294                }
 295
 296                /* We offset irq numbers for the u3 MPIC by 128 in PowerMac */
 297                if (systemcfg->platform == PLATFORM_POWERMAC && ic && ic->parent) {
 298                        char *name = get_property(ic->parent, "name", NULL);
 299                        if (name && !strcmp(name, "u3"))
 300                                np->intrs[intrcount].line += 128;
 301                }
 302                np->intrs[intrcount].sense = 1;
 303                if (n > 1)
 304                        np->intrs[intrcount].sense = irq[1];
 305                if (n > 2) {
 306                        printk("hmmm, got %d intr cells for %s:", n,
 307                               np->full_name);
 308                        for (j = 0; j < n; ++j)
 309                                printk(" %d", irq[j]);
 310                        printk("\n");
 311                }
 312                ++intrcount;
 313        }
 314        np->n_intrs = intrcount;
 315
 316        return mem_start;
 317}
 318
 319static unsigned long __init interpret_pci_props(struct device_node *np,
 320                                                unsigned long mem_start,
 321                                                int naddrc, int nsizec,
 322                                                int measure_only)
 323{
 324        struct address_range *adr;
 325        struct pci_reg_property *pci_addrs;
 326        int i, l;
 327
 328        pci_addrs = (struct pci_reg_property *)
 329                get_property(np, "assigned-addresses", &l);
 330        if (pci_addrs != 0 && l >= sizeof(struct pci_reg_property)) {
 331                i = 0;
 332                adr = (struct address_range *) mem_start;
 333                while ((l -= sizeof(struct pci_reg_property)) >= 0) {
 334                        if (!measure_only) {
 335                                adr[i].space = pci_addrs[i].addr.a_hi;
 336                                adr[i].address = pci_addrs[i].addr.a_lo;
 337                                adr[i].size = pci_addrs[i].size_lo;
 338                        }
 339                        ++i;
 340                }
 341                np->addrs = adr;
 342                np->n_addrs = i;
 343                mem_start += i * sizeof(struct address_range);
 344        }
 345        return mem_start;
 346}
 347
 348static unsigned long __init interpret_dbdma_props(struct device_node *np,
 349                                                  unsigned long mem_start,
 350                                                  int naddrc, int nsizec,
 351                                                  int measure_only)
 352{
 353        struct reg_property32 *rp;
 354        struct address_range *adr;
 355        unsigned long base_address;
 356        int i, l;
 357        struct device_node *db;
 358
 359        base_address = 0;
 360        if (!measure_only) {
 361                for (db = np->parent; db != NULL; db = db->parent) {
 362                        if (!strcmp(db->type, "dbdma") && db->n_addrs != 0) {
 363                                base_address = db->addrs[0].address;
 364                                break;
 365                        }
 366                }
 367        }
 368
 369        rp = (struct reg_property32 *) get_property(np, "reg", &l);
 370        if (rp != 0 && l >= sizeof(struct reg_property32)) {
 371                i = 0;
 372                adr = (struct address_range *) mem_start;
 373                while ((l -= sizeof(struct reg_property32)) >= 0) {
 374                        if (!measure_only) {
 375                                adr[i].space = 2;
 376                                adr[i].address = rp[i].address + base_address;
 377                                adr[i].size = rp[i].size;
 378                        }
 379                        ++i;
 380                }
 381                np->addrs = adr;
 382                np->n_addrs = i;
 383                mem_start += i * sizeof(struct address_range);
 384        }
 385
 386        return mem_start;
 387}
 388
 389static unsigned long __init interpret_macio_props(struct device_node *np,
 390                                                  unsigned long mem_start,
 391                                                  int naddrc, int nsizec,
 392                                                  int measure_only)
 393{
 394        struct reg_property32 *rp;
 395        struct address_range *adr;
 396        unsigned long base_address;
 397        int i, l;
 398        struct device_node *db;
 399
 400        base_address = 0;
 401        if (!measure_only) {
 402                for (db = np->parent; db != NULL; db = db->parent) {
 403                        if (!strcmp(db->type, "mac-io") && db->n_addrs != 0) {
 404                                base_address = db->addrs[0].address;
 405                                break;
 406                        }
 407                }
 408        }
 409
 410        rp = (struct reg_property32 *) get_property(np, "reg", &l);
 411        if (rp != 0 && l >= sizeof(struct reg_property32)) {
 412                i = 0;
 413                adr = (struct address_range *) mem_start;
 414                while ((l -= sizeof(struct reg_property32)) >= 0) {
 415                        if (!measure_only) {
 416                                adr[i].space = 2;
 417                                adr[i].address = rp[i].address + base_address;
 418                                adr[i].size = rp[i].size;
 419                        }
 420                        ++i;
 421                }
 422                np->addrs = adr;
 423                np->n_addrs = i;
 424                mem_start += i * sizeof(struct address_range);
 425        }
 426
 427        return mem_start;
 428}
 429
 430static unsigned long __init interpret_isa_props(struct device_node *np,
 431                                                unsigned long mem_start,
 432                                                int naddrc, int nsizec,
 433                                                int measure_only)
 434{
 435        struct isa_reg_property *rp;
 436        struct address_range *adr;
 437        int i, l;
 438
 439        rp = (struct isa_reg_property *) get_property(np, "reg", &l);
 440        if (rp != 0 && l >= sizeof(struct isa_reg_property)) {
 441                i = 0;
 442                adr = (struct address_range *) mem_start;
 443                while ((l -= sizeof(struct isa_reg_property)) >= 0) {
 444                        if (!measure_only) {
 445                                adr[i].space = rp[i].space;
 446                                adr[i].address = rp[i].address;
 447                                adr[i].size = rp[i].size;
 448                        }
 449                        ++i;
 450                }
 451                np->addrs = adr;
 452                np->n_addrs = i;
 453                mem_start += i * sizeof(struct address_range);
 454        }
 455
 456        return mem_start;
 457}
 458
 459static unsigned long __init interpret_root_props(struct device_node *np,
 460                                                 unsigned long mem_start,
 461                                                 int naddrc, int nsizec,
 462                                                 int measure_only)
 463{
 464        struct address_range *adr;
 465        int i, l;
 466        unsigned int *rp;
 467        int rpsize = (naddrc + nsizec) * sizeof(unsigned int);
 468
 469        rp = (unsigned int *) get_property(np, "reg", &l);
 470        if (rp != 0 && l >= rpsize) {
 471                i = 0;
 472                adr = (struct address_range *) mem_start;
 473                while ((l -= rpsize) >= 0) {
 474                        if (!measure_only) {
 475                                adr[i].space = 0;
 476                                adr[i].address = rp[naddrc - 1];
 477                                adr[i].size = rp[naddrc + nsizec - 1];
 478                        }
 479                        ++i;
 480                        rp += naddrc + nsizec;
 481                }
 482                np->addrs = adr;
 483                np->n_addrs = i;
 484                mem_start += i * sizeof(struct address_range);
 485        }
 486
 487        return mem_start;
 488}
 489
 490static unsigned long __init finish_node(struct device_node *np,
 491                                        unsigned long mem_start,
 492                                        interpret_func *ifunc,
 493                                        int naddrc, int nsizec,
 494                                        int measure_only)
 495{
 496        struct device_node *child;
 497        int *ip;
 498
 499        /* get the device addresses and interrupts */
 500        if (ifunc != NULL)
 501                mem_start = ifunc(np, mem_start, naddrc, nsizec, measure_only);
 502
 503        mem_start = finish_node_interrupts(np, mem_start, measure_only);
 504
 505        /* Look for #address-cells and #size-cells properties. */
 506        ip = (int *) get_property(np, "#address-cells", NULL);
 507        if (ip != NULL)
 508                naddrc = *ip;
 509        ip = (int *) get_property(np, "#size-cells", NULL);
 510        if (ip != NULL)
 511                nsizec = *ip;
 512
 513        /* the f50 sets the name to 'display' and 'compatible' to what we
 514         * expect for the name -- Cort
 515         */
 516        if (!strcmp(np->name, "display"))
 517                np->name = get_property(np, "compatible", NULL);
 518
 519        if (!strcmp(np->name, "device-tree") || np->parent == NULL)
 520                ifunc = interpret_root_props;
 521        else if (np->type == 0)
 522                ifunc = NULL;
 523        else if (!strcmp(np->type, "pci") || !strcmp(np->type, "vci"))
 524                ifunc = interpret_pci_props;
 525        else if (!strcmp(np->type, "dbdma"))
 526                ifunc = interpret_dbdma_props;
 527        else if (!strcmp(np->type, "mac-io") || ifunc == interpret_macio_props)
 528                ifunc = interpret_macio_props;
 529        else if (!strcmp(np->type, "isa"))
 530                ifunc = interpret_isa_props;
 531        else if (!strcmp(np->name, "uni-n") || !strcmp(np->name, "u3"))
 532                ifunc = interpret_root_props;
 533        else if (!((ifunc == interpret_dbdma_props
 534                    || ifunc == interpret_macio_props)
 535                   && (!strcmp(np->type, "escc")
 536                       || !strcmp(np->type, "media-bay"))))
 537                ifunc = NULL;
 538
 539        for (child = np->child; child != NULL; child = child->sibling)
 540                mem_start = finish_node(child, mem_start, ifunc,
 541                                        naddrc, nsizec, measure_only);
 542
 543        return mem_start;
 544}
 545
 546/**
 547 * finish_device_tree is called once things are running normally
 548 * (i.e. with text and data mapped to the address they were linked at).
 549 * It traverses the device tree and fills in some of the additional,
 550 * fields in each node like {n_}addrs and {n_}intrs, the virt interrupt
 551 * mapping is also initialized at this point.
 552 */
 553void __init finish_device_tree(void)
 554{
 555        unsigned long mem, size;
 556
 557        DBG(" -> finish_device_tree\n");
 558
 559        if (ppc64_interrupt_controller == IC_INVALID) {
 560                DBG("failed to configure interrupt controller type\n");
 561                panic("failed to configure interrupt controller type\n");
 562        }
 563        
 564        /* Initialize virtual IRQ map */
 565        virt_irq_init();
 566
 567        /* Finish device-tree (pre-parsing some properties etc...) */
 568        size = finish_node(allnodes, 0, NULL, 0, 0, 1);
 569        mem = (unsigned long)abs_to_virt(lmb_alloc(size, 128));
 570        if (finish_node(allnodes, mem, NULL, 0, 0, 0) != mem + size)
 571                BUG();
 572
 573        DBG(" <- finish_device_tree\n");
 574}
 575
 576#ifdef DEBUG
 577#define printk udbg_printf
 578#endif
 579
 580static inline char *find_flat_dt_string(u32 offset)
 581{
 582        return ((char *)initial_boot_params) + initial_boot_params->off_dt_strings
 583                + offset;
 584}
 585
 586/**
 587 * This function is used to scan the flattened device-tree, it is
 588 * used to extract the memory informations at boot before we can
 589 * unflatten the tree
 590 */
 591static int __init scan_flat_dt(int (*it)(unsigned long node,
 592                                         const char *full_path, void *data),
 593                               void *data)
 594{
 595        unsigned long p = ((unsigned long)initial_boot_params) +
 596                initial_boot_params->off_dt_struct;
 597        int rc = 0;
 598
 599        do {
 600                u32 tag = *((u32 *)p);
 601                char *pathp;
 602                
 603                p += 4;
 604                if (tag == OF_DT_END_NODE)
 605                        continue;
 606                if (tag == OF_DT_END)
 607                        break;
 608                if (tag == OF_DT_PROP) {
 609                        u32 sz = *((u32 *)p);
 610                        p += 8;
 611                        p = _ALIGN(p, sz >= 8 ? 8 : 4);
 612                        p += sz;
 613                        p = _ALIGN(p, 4);
 614                        continue;
 615                }
 616                if (tag != OF_DT_BEGIN_NODE) {
 617                        printk(KERN_WARNING "Invalid tag %x scanning flattened"
 618                               " device tree !\n", tag);
 619                        return -EINVAL;
 620                }
 621                pathp = (char *)p;
 622                p = _ALIGN(p + strlen(pathp) + 1, 4);
 623                rc = it(p, pathp, data);
 624                if (rc != 0)
 625                        break;          
 626        } while(1);
 627
 628        return rc;
 629}
 630
 631/**
 632 * This  function can be used within scan_flattened_dt callback to get
 633 * access to properties
 634 */
 635static void* __init get_flat_dt_prop(unsigned long node, const char *name,
 636                                     unsigned long *size)
 637{
 638        unsigned long p = node;
 639
 640        do {
 641                u32 tag = *((u32 *)p);
 642                u32 sz, noff;
 643                const char *nstr;
 644
 645                p += 4;
 646                if (tag != OF_DT_PROP)
 647                        return NULL;
 648
 649                sz = *((u32 *)p);
 650                noff = *((u32 *)(p + 4));
 651                p += 8;
 652                p = _ALIGN(p, sz >= 8 ? 8 : 4);
 653
 654                nstr = find_flat_dt_string(noff);
 655                if (nstr == NULL) {
 656                        printk(KERN_WARNING "Can't find property index name !\n");
 657                        return NULL;
 658                }
 659                if (strcmp(name, nstr) == 0) {
 660                        if (size)
 661                                *size = sz;
 662                        return (void *)p;
 663                }
 664                p += sz;
 665                p = _ALIGN(p, 4);
 666        } while(1);
 667}
 668
 669static void *__init unflatten_dt_alloc(unsigned long *mem, unsigned long size,
 670                                               unsigned long align)
 671{
 672        void *res;
 673
 674        *mem = _ALIGN(*mem, align);
 675        res = (void *)*mem;
 676        *mem += size;
 677
 678        return res;
 679}
 680
 681static unsigned long __init unflatten_dt_node(unsigned long mem,
 682                                              unsigned long *p,
 683                                              struct device_node *dad,
 684                                              struct device_node ***allnextpp)
 685{
 686        struct device_node *np;
 687        struct property *pp, **prev_pp = NULL;
 688        char *pathp;
 689        u32 tag;
 690        unsigned int l;
 691
 692        tag = *((u32 *)(*p));
 693        if (tag != OF_DT_BEGIN_NODE) {
 694                printk("Weird tag at start of node: %x\n", tag);
 695                return mem;
 696        }
 697        *p += 4;
 698        pathp = (char *)*p;
 699        l = strlen(pathp) + 1;
 700        *p = _ALIGN(*p + l, 4);
 701
 702        np = unflatten_dt_alloc(&mem, sizeof(struct device_node) + l,
 703                                __alignof__(struct device_node));
 704        if (allnextpp) {
 705                memset(np, 0, sizeof(*np));
 706                np->full_name = ((char*)np) + sizeof(struct device_node);
 707                memcpy(np->full_name, pathp, l);
 708                prev_pp = &np->properties;
 709                **allnextpp = np;
 710                *allnextpp = &np->allnext;
 711                if (dad != NULL) {
 712                        np->parent = dad;
 713                        /* we temporarily use the `next' field as `last_child'. */
 714                        if (dad->next == 0)
 715                                dad->child = np;
 716                        else
 717                                dad->next->sibling = np;
 718                        dad->next = np;
 719                }
 720                kref_init(&np->kref);
 721        }
 722        while(1) {
 723                u32 sz, noff;
 724                char *pname;
 725
 726                tag = *((u32 *)(*p));
 727                if (tag != OF_DT_PROP)
 728                        break;
 729                *p += 4;
 730                sz = *((u32 *)(*p));
 731                noff = *((u32 *)((*p) + 4));
 732                *p = _ALIGN((*p) + 8, sz >= 8 ? 8 : 4);
 733
 734                pname = find_flat_dt_string(noff);
 735                if (pname == NULL) {
 736                        printk("Can't find property name in list !\n");
 737                        break;
 738                }
 739                l = strlen(pname) + 1;
 740                pp = unflatten_dt_alloc(&mem, sizeof(struct property),
 741                                        __alignof__(struct property));
 742                if (allnextpp) {
 743                        if (strcmp(pname, "linux,phandle") == 0) {
 744                                np->node = *((u32 *)*p);
 745                                if (np->linux_phandle == 0)
 746                                        np->linux_phandle = np->node;
 747                        }
 748                        if (strcmp(pname, "ibm,phandle") == 0)
 749                                np->linux_phandle = *((u32 *)*p);
 750                        pp->name = pname;
 751                        pp->length = sz;
 752                        pp->value = (void *)*p;
 753                        *prev_pp = pp;
 754                        prev_pp = &pp->next;
 755                }
 756                *p = _ALIGN((*p) + sz, 4);
 757        }
 758        if (allnextpp) {
 759                *prev_pp = NULL;
 760                np->name = get_property(np, "name", NULL);
 761                np->type = get_property(np, "device_type", NULL);
 762
 763                if (!np->name)
 764                        np->name = "<NULL>";
 765                if (!np->type)
 766                        np->type = "<NULL>";
 767        }
 768        while (tag == OF_DT_BEGIN_NODE) {
 769                mem = unflatten_dt_node(mem, p, np, allnextpp);
 770                tag = *((u32 *)(*p));
 771        }
 772        if (tag != OF_DT_END_NODE) {
 773                printk("Weird tag at start of node: %x\n", tag);
 774                return mem;
 775        }
 776        *p += 4;
 777        return mem;
 778}
 779
 780
 781/**
 782 * unflattens the device-tree passed by the firmware, creating the
 783 * tree of struct device_node. It also fills the "name" and "type"
 784 * pointers of the nodes so the normal device-tree walking functions
 785 * can be used (this used to be done by finish_device_tree)
 786 */
 787void __init unflatten_device_tree(void)
 788{
 789        unsigned long start, mem, size;
 790        struct device_node **allnextp = &allnodes;
 791        char *p;
 792        int l = 0;
 793
 794        DBG(" -> unflatten_device_tree()\n");
 795
 796        /* First pass, scan for size */
 797        start = ((unsigned long)initial_boot_params) +
 798                initial_boot_params->off_dt_struct;
 799        size = unflatten_dt_node(0, &start, NULL, NULL);
 800
 801        DBG("  size is %lx, allocating...\n", size);
 802
 803        /* Allocate memory for the expanded device tree */
 804        mem = (unsigned long)abs_to_virt(lmb_alloc(size,
 805                                                   __alignof__(struct device_node)));
 806        DBG("  unflattening...\n", mem);
 807
 808        /* Second pass, do actual unflattening */
 809        start = ((unsigned long)initial_boot_params) +
 810                initial_boot_params->off_dt_struct;
 811        unflatten_dt_node(mem, &start, NULL, &allnextp);
 812        if (*((u32 *)start) != OF_DT_END)
 813                printk(KERN_WARNING "Weird tag at end of tree: %x\n", *((u32 *)start));
 814        *allnextp = NULL;
 815
 816        /* Get pointer to OF "/chosen" node for use everywhere */
 817        of_chosen = of_find_node_by_path("/chosen");
 818
 819        /* Retreive command line */
 820        if (of_chosen != NULL) {
 821                p = (char *)get_property(of_chosen, "bootargs", &l);
 822                if (p != NULL && l > 0)
 823                        strlcpy(cmd_line, p, min(l, COMMAND_LINE_SIZE));
 824        }
 825#ifdef CONFIG_CMDLINE
 826        if (l == 0 || (l == 1 && (*p) == 0))
 827                strlcpy(cmd_line, CONFIG_CMDLINE, COMMAND_LINE_SIZE);
 828#endif /* CONFIG_CMDLINE */
 829
 830        DBG("Command line is: %s\n", cmd_line);
 831
 832        DBG(" <- unflatten_device_tree()\n");
 833}
 834
 835
 836static int __init early_init_dt_scan_cpus(unsigned long node,
 837                                          const char *full_path, void *data)
 838{
 839        char *type = get_flat_dt_prop(node, "device_type", NULL);
 840
 841        /* We are scanning "cpu" nodes only */
 842        if (type == NULL || strcmp(type, "cpu") != 0)
 843                return 0;
 844
 845        /* On LPAR, look for the first ibm,pft-size property for the  hash table size
 846         */
 847        if (systemcfg->platform == PLATFORM_PSERIES_LPAR && ppc64_pft_size == 0) {
 848                u32 *pft_size;
 849                pft_size = (u32 *)get_flat_dt_prop(node, "ibm,pft-size", NULL);
 850                if (pft_size != NULL) {
 851                        /* pft_size[0] is the NUMA CEC cookie */
 852                        ppc64_pft_size = pft_size[1];
 853                }
 854        }
 855
 856        if (initial_boot_params && initial_boot_params->version >= 2) {
 857                /* version 2 of the kexec param format adds the phys cpuid
 858                 * of booted proc.
 859                 */
 860                boot_cpuid_phys = initial_boot_params->boot_cpuid_phys;
 861                boot_cpuid = 0;
 862        } else {
 863                /* Check if it's the boot-cpu, set it's hw index in paca now */
 864                if (get_flat_dt_prop(node, "linux,boot-cpu", NULL) != NULL) {
 865                        u32 *prop = get_flat_dt_prop(node, "reg", NULL);
 866                        set_hard_smp_processor_id(0, prop == NULL ? 0 : *prop);
 867                        boot_cpuid_phys = get_hard_smp_processor_id(0);
 868                }
 869        }
 870
 871        return 0;
 872}
 873
 874static int __init early_init_dt_scan_chosen(unsigned long node,
 875                                            const char *full_path, void *data)
 876{
 877        u32 *prop;
 878
 879        if (strcmp(full_path, "/chosen") != 0)
 880                return 0;
 881
 882        /* get platform type */
 883        prop = (u32 *)get_flat_dt_prop(node, "linux,platform", NULL);
 884        if (prop == NULL)
 885                return 0;
 886        systemcfg->platform = *prop;
 887
 888        /* check if iommu is forced on or off */
 889        if (get_flat_dt_prop(node, "linux,iommu-off", NULL) != NULL)
 890                iommu_is_off = 1;
 891        if (get_flat_dt_prop(node, "linux,iommu-force-on", NULL) != NULL)
 892                iommu_force_on = 1;
 893
 894#ifdef CONFIG_PPC_PSERIES
 895        /* To help early debugging via the front panel, we retreive a minimal
 896         * set of RTAS infos now if available
 897         */
 898        {
 899                u64 *basep, *entryp;
 900
 901                basep = (u64*)get_flat_dt_prop(node, "linux,rtas-base", NULL);
 902                entryp = (u64*)get_flat_dt_prop(node, "linux,rtas-entry", NULL);
 903                prop = (u32*)get_flat_dt_prop(node, "linux,rtas-size", NULL);
 904                if (basep && entryp && prop) {
 905                        rtas.base = *basep;
 906                        rtas.entry = *entryp;
 907                        rtas.size = *prop;
 908                }
 909        }
 910#endif /* CONFIG_PPC_PSERIES */
 911
 912        /* break now */
 913        return 1;
 914}
 915
 916static int __init early_init_dt_scan_root(unsigned long node,
 917                                          const char *full_path, void *data)
 918{
 919        u32 *prop;
 920
 921        if (strcmp(full_path, "/") != 0)
 922                return 0;
 923
 924        prop = (u32 *)get_flat_dt_prop(node, "#size-cells", NULL);
 925        dt_root_size_cells = (prop == NULL) ? 1 : *prop;
 926                
 927        prop = (u32 *)get_flat_dt_prop(node, "#address-cells", NULL);
 928        dt_root_addr_cells = (prop == NULL) ? 2 : *prop;
 929        
 930        /* break now */
 931        return 1;
 932}
 933
 934static unsigned long __init dt_mem_next_cell(int s, cell_t **cellp)
 935{
 936        cell_t *p = *cellp;
 937        unsigned long r = 0;
 938
 939        /* Ignore more than 2 cells */
 940        while (s > 2) {
 941                p++;
 942                s--;
 943        }
 944        while (s) {
 945                r <<= 32;
 946                r |= *(p++);
 947                s--;
 948        }
 949
 950        *cellp = p;
 951        return r;
 952}
 953
 954
 955static int __init early_init_dt_scan_memory(unsigned long node,
 956                                            const char *full_path, void *data)
 957{
 958        char *type = get_flat_dt_prop(node, "device_type", NULL);
 959        cell_t *reg, *endp;
 960        unsigned long l;
 961
 962        /* We are scanning "memory" nodes only */
 963        if (type == NULL || strcmp(type, "memory") != 0)
 964                return 0;
 965
 966        reg = (cell_t *)get_flat_dt_prop(node, "reg", &l);
 967        if (reg == NULL)
 968                return 0;
 969
 970        endp = reg + (l / sizeof(cell_t));
 971
 972        DBG("memory scan node %s ...\n", full_path);
 973        while ((endp - reg) >= (dt_root_addr_cells + dt_root_size_cells)) {
 974                unsigned long base, size;
 975
 976                base = dt_mem_next_cell(dt_root_addr_cells, &reg);
 977                size = dt_mem_next_cell(dt_root_size_cells, &reg);
 978
 979                if (size == 0)
 980                        continue;
 981                DBG(" - %lx ,  %lx\n", base, size);
 982                if (iommu_is_off) {
 983                        if (base >= 0x80000000ul)
 984                                continue;
 985                        if ((base + size) > 0x80000000ul)
 986                                size = 0x80000000ul - base;
 987                }
 988                lmb_add(base, size);
 989        }
 990        return 0;
 991}
 992
 993static void __init early_reserve_mem(void)
 994{
 995        u64 base, size;
 996        u64 *reserve_map = (u64 *)(((unsigned long)initial_boot_params) +
 997                                   initial_boot_params->off_mem_rsvmap);
 998        while (1) {
 999                base = *(reserve_map++);
1000                size = *(reserve_map++);
1001                if (size == 0)
1002                        break;
1003                DBG("reserving: %lx -> %lx\n", base, size);
1004                lmb_reserve(base, size);
1005        }
1006
1007#if 0
1008        DBG("memory reserved, lmbs :\n");
1009        lmb_dump_all();
1010#endif
1011}
1012
1013void __init early_init_devtree(void *params)
1014{
1015        DBG(" -> early_init_devtree()\n");
1016
1017        /* Setup flat device-tree pointer */
1018        initial_boot_params = params;
1019
1020        /* By default, hash size is not set */
1021        ppc64_pft_size = 0;
1022
1023        /* Retreive various informations from the /chosen node of the
1024         * device-tree, including the platform type, initrd location and
1025         * size, TCE reserve, and more ...
1026         */
1027        scan_flat_dt(early_init_dt_scan_chosen, NULL);
1028
1029        /* Scan memory nodes and rebuild LMBs */
1030        lmb_init();
1031        scan_flat_dt(early_init_dt_scan_root, NULL);
1032        scan_flat_dt(early_init_dt_scan_memory, NULL);
1033        lmb_analyze();
1034        systemcfg->physicalMemorySize = lmb_phys_mem_size();
1035        lmb_reserve(0, __pa(klimit));
1036
1037        DBG("Phys. mem: %lx\n", systemcfg->physicalMemorySize);
1038
1039        /* Reserve LMB regions used by kernel, initrd, dt, etc... */
1040        early_reserve_mem();
1041
1042        DBG("Scanning CPUs ...\n");
1043
1044        /* Retreive hash table size from flattened tree */
1045        scan_flat_dt(early_init_dt_scan_cpus, NULL);
1046
1047        /* If hash size wasn't obtained above, we calculate it now based on
1048         * the total RAM size
1049         */
1050        if (ppc64_pft_size == 0) {
1051                unsigned long rnd_mem_size, pteg_count;
1052
1053                /* round mem_size up to next power of 2 */
1054                rnd_mem_size = 1UL << __ilog2(systemcfg->physicalMemorySize);
1055                if (rnd_mem_size < systemcfg->physicalMemorySize)
1056                        rnd_mem_size <<= 1;
1057
1058                /* # pages / 2 */
1059                pteg_count = max(rnd_mem_size >> (12 + 1), 1UL << 11);
1060
1061                ppc64_pft_size = __ilog2(pteg_count << 7);
1062        }
1063
1064        DBG("Hash pftSize: %x\n", (int)ppc64_pft_size);
1065        DBG(" <- early_init_devtree()\n");
1066}
1067
1068#undef printk
1069
1070int
1071prom_n_addr_cells(struct device_node* np)
1072{
1073        int* ip;
1074        do {
1075                if (np->parent)
1076                        np = np->parent;
1077                ip = (int *) get_property(np, "#address-cells", NULL);
1078                if (ip != NULL)
1079                        return *ip;
1080        } while (np->parent);
1081        /* No #address-cells property for the root node, default to 1 */
1082        return 1;
1083}
1084
1085int
1086prom_n_size_cells(struct device_node* np)
1087{
1088        int* ip;
1089        do {
1090                if (np->parent)
1091                        np = np->parent;
1092                ip = (int *) get_property(np, "#size-cells", NULL);
1093                if (ip != NULL)
1094                        return *ip;
1095        } while (np->parent);
1096        /* No #size-cells property for the root node, default to 1 */
1097        return 1;
1098}
1099
1100/**
1101 * Work out the sense (active-low level / active-high edge)
1102 * of each interrupt from the device tree.
1103 */
1104void __init prom_get_irq_senses(unsigned char *senses, int off, int max)
1105{
1106        struct device_node *np;
1107        int i, j;
1108
1109        /* default to level-triggered */
1110        memset(senses, 1, max - off);
1111
1112        for (np = allnodes; np != 0; np = np->allnext) {
1113                for (j = 0; j < np->n_intrs; j++) {
1114                        i = np->intrs[j].line;
1115                        if (i >= off && i < max)
1116                                senses[i-off] = np->intrs[j].sense ?
1117                                        IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE :
1118                                        IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE;
1119                }
1120        }
1121}
1122
1123/**
1124 * Construct and return a list of the device_nodes with a given name.
1125 */
1126struct device_node *
1127find_devices(const char *name)
1128{
1129        struct device_node *head, **prevp, *np;
1130
1131        prevp = &head;
1132        for (np = allnodes; np != 0; np = np->allnext) {
1133                if (np->name != 0 && strcasecmp(np->name, name) == 0) {
1134                        *prevp = np;
1135                        prevp = &np->next;
1136                }
1137        }
1138        *prevp = NULL;
1139        return head;
1140}
1141
1142/**
1143 * Construct and return a list of the device_nodes with a given type.
1144 */
1145struct device_node *
1146find_type_devices(const char *type)
1147{
1148        struct device_node *head, **prevp, *np;
1149
1150        prevp = &head;
1151        for (np = allnodes; np != 0; np = np->allnext) {
1152                if (np->type != 0 && strcasecmp(np->type, type) == 0) {
1153                        *prevp = np;
1154                        prevp = &np->next;
1155                }
1156        }
1157        *prevp = NULL;
1158        return head;
1159}
1160
1161/**
1162 * Returns all nodes linked together
1163 */
1164struct device_node *
1165find_all_nodes(void)
1166{
1167        struct device_node *head, **prevp, *np;
1168
1169        prevp = &head;
1170        for (np = allnodes; np != 0; np = np->allnext) {
1171                *prevp = np;
1172                prevp = &np->next;
1173        }
1174        *prevp = NULL;
1175        return head;
1176}
1177
1178/** Checks if the given "compat" string matches one of the strings in
1179 * the device's "compatible" property
1180 */
1181int
1182device_is_compatible(struct device_node *device, const char *compat)
1183{
1184        const char* cp;
1185        int cplen, l;
1186
1187        cp = (char *) get_property(device, "compatible", &cplen);
1188        if (cp == NULL)
1189                return 0;
1190        while (cplen > 0) {
1191                if (strncasecmp(cp, compat, strlen(compat)) == 0)
1192                        return 1;
1193                l = strlen(cp) + 1;
1194                cp += l;
1195                cplen -= l;
1196        }
1197
1198        return 0;
1199}
1200
1201
1202/**
1203 * Indicates whether the root node has a given value in its
1204 * compatible property.
1205 */
1206int
1207machine_is_compatible(const char *compat)
1208{
1209        struct device_node *root;
1210        int rc = 0;
1211
1212        root = of_find_node_by_path("/");
1213        if (root) {
1214                rc = device_is_compatible(root, compat);
1215                of_node_put(root);
1216        }
1217        return rc;
1218}
1219
1220/**
1221 * Construct and return a list of the device_nodes with a given type
1222 * and compatible property.
1223 */
1224struct device_node *
1225find_compatible_devices(const char *type, const char *compat)
1226{
1227        struct device_node *head, **prevp, *np;
1228
1229        prevp = &head;
1230        for (np = allnodes; np != 0; np = np->allnext) {
1231                if (type != NULL
1232                    && !(np->type != 0 && strcasecmp(np->type, type) == 0))
1233                        continue;
1234                if (device_is_compatible(np, compat)) {
1235                        *prevp = np;
1236                        prevp = &np->next;
1237                }
1238        }
1239        *prevp = NULL;
1240        return head;
1241}
1242
1243/**
1244 * Find the device_node with a given full_name.
1245 */
1246struct device_node *
1247find_path_device(const char *path)
1248{
1249        struct device_node *np;
1250
1251        for (np = allnodes; np != 0; np = np->allnext)
1252                if (np->full_name != 0 && strcasecmp(np->full_name, path) == 0)
1253                        return np;
1254        return NULL;
1255}
1256
1257/*******
1258 *
1259 * New implementation of the OF "find" APIs, return a refcounted
1260 * object, call of_node_put() when done.  The device tree and list
1261 * are protected by a rw_lock.
1262 *
1263 * Note that property management will need some locking as well,
1264 * this isn't dealt with yet.
1265 *
1266 *******/
1267
1268/**
1269 *      of_find_node_by_name - Find a node by its "name" property
1270 *      @from:  The node to start searching from or NULL, the node
1271 *              you pass will not be searched, only the next one
1272 *              will; typically, you pass what the previous call
1273 *              returned. of_node_put() will be called on it
1274 *      @name:  The name string to match against
1275 *
1276 *      Returns a node pointer with refcount incremented, use
1277 *      of_node_put() on it when done.
1278 */
1279struct device_node *of_find_node_by_name(struct device_node *from,
1280        const char *name)
1281{
1282        struct device_node *np;
1283
1284        read_lock(&devtree_lock);
1285        np = from ? from->allnext : allnodes;
1286        for (; np != 0; np = np->allnext)
1287                if (np->name != 0 && strcasecmp(np->name, name) == 0
1288                    && of_node_get(np))
1289                        break;
1290        if (from)
1291                of_node_put(from);
1292        read_unlock(&devtree_lock);
1293        return np;
1294}
1295EXPORT_SYMBOL(of_find_node_by_name);
1296
1297/**
1298 *      of_find_node_by_type - Find a node by its "device_type" property
1299 *      @from:  The node to start searching from or NULL, the node
1300 *              you pass will not be searched, only the next one
1301 *              will; typically, you pass what the previous call
1302 *              returned. of_node_put() will be called on it
1303 *      @name:  The type string to match against
1304 *
1305 *      Returns a node pointer with refcount incremented, use
1306 *      of_node_put() on it when done.
1307 */
1308struct device_node *of_find_node_by_type(struct device_node *from,
1309        const char *type)
1310{
1311        struct device_node *np;
1312
1313        read_lock(&devtree_lock);
1314        np = from ? from->allnext : allnodes;
1315        for (; np != 0; np = np->allnext)
1316                if (np->type != 0 && strcasecmp(np->type, type) == 0
1317                    && of_node_get(np))
1318                        break;
1319        if (from)
1320                of_node_put(from);
1321        read_unlock(&devtree_lock);
1322        return np;
1323}
1324EXPORT_SYMBOL(of_find_node_by_type);
1325
1326/**
1327 *      of_find_compatible_node - Find a node based on type and one of the
1328 *                                tokens in its "compatible" property
1329 *      @from:          The node to start searching from or NULL, the node
1330 *                      you pass will not be searched, only the next one
1331 *                      will; typically, you pass what the previous call
1332 *                      returned. of_node_put() will be called on it
1333 *      @type:          The type string to match "device_type" or NULL to ignore
1334 *      @compatible:    The string to match to one of the tokens in the device
1335 *                      "compatible" list.
1336 *
1337 *      Returns a node pointer with refcount incremented, use
1338 *      of_node_put() on it when done.
1339 */
1340struct device_node *of_find_compatible_node(struct device_node *from,
1341        const char *type, const char *compatible)
1342{
1343        struct device_node *np;
1344
1345        read_lock(&devtree_lock);
1346        np = from ? from->allnext : allnodes;
1347        for (; np != 0; np = np->allnext) {
1348                if (type != NULL
1349                    && !(np->type != 0 && strcasecmp(np->type, type) == 0))
1350                        continue;
1351                if (device_is_compatible(np, compatible) && of_node_get(np))
1352                        break;
1353        }
1354        if (from)
1355                of_node_put(from);
1356        read_unlock(&devtree_lock);
1357        return np;
1358}
1359EXPORT_SYMBOL(of_find_compatible_node);
1360
1361/**
1362 *      of_find_node_by_path - Find a node matching a full OF path
1363 *      @path:  The full path to match
1364 *
1365 *      Returns a node pointer with refcount incremented, use
1366 *      of_node_put() on it when done.
1367 */
1368struct device_node *of_find_node_by_path(const char *path)
1369{
1370        struct device_node *np = allnodes;
1371
1372        read_lock(&devtree_lock);
1373        for (; np != 0; np = np->allnext)
1374                if (np->full_name != 0 && strcasecmp(np->full_name, path) == 0
1375                    && of_node_get(np))
1376                        break;
1377        read_unlock(&devtree_lock);
1378        return np;
1379}
1380EXPORT_SYMBOL(of_find_node_by_path);
1381
1382/**
1383 *      of_find_node_by_phandle - Find a node given a phandle
1384 *      @handle:        phandle of the node to find
1385 *
1386 *      Returns a node pointer with refcount incremented, use
1387 *      of_node_put() on it when done.
1388 */
1389struct device_node *of_find_node_by_phandle(phandle handle)
1390{
1391        struct device_node *np;
1392
1393        read_lock(&devtree_lock);
1394        for (np = allnodes; np != 0; np = np->allnext)
1395                if (np->linux_phandle == handle)
1396                        break;
1397        if (np)
1398                of_node_get(np);
1399        read_unlock(&devtree_lock);
1400        return np;
1401}
1402EXPORT_SYMBOL(of_find_node_by_phandle);
1403
1404/**
1405 *      of_find_all_nodes - Get next node in global list
1406 *      @prev:  Previous node or NULL to start iteration
1407 *              of_node_put() will be called on it
1408 *
1409 *      Returns a node pointer with refcount incremented, use
1410 *      of_node_put() on it when done.
1411 */
1412struct device_node *of_find_all_nodes(struct device_node *prev)
1413{
1414        struct device_node *np;
1415
1416        read_lock(&devtree_lock);
1417        np = prev ? prev->allnext : allnodes;
1418        for (; np != 0; np = np->allnext)
1419                if (of_node_get(np))
1420                        break;
1421        if (prev)
1422                of_node_put(prev);
1423        read_unlock(&devtree_lock);
1424        return np;
1425}
1426EXPORT_SYMBOL(of_find_all_nodes);
1427
1428/**
1429 *      of_get_parent - Get a node's parent if any
1430 *      @node:  Node to get parent
1431 *
1432 *      Returns a node pointer with refcount incremented, use
1433 *      of_node_put() on it when done.
1434 */
1435struct device_node *of_get_parent(const struct device_node *node)
1436{
1437        struct device_node *np;
1438
1439        if (!node)
1440                return NULL;
1441
1442        read_lock(&devtree_lock);
1443        np = of_node_get(node->parent);
1444        read_unlock(&devtree_lock);
1445        return np;
1446}
1447EXPORT_SYMBOL(of_get_parent);
1448
1449/**
1450 *      of_get_next_child - Iterate a node childs
1451 *      @node:  parent node
1452 *      @prev:  previous child of the parent node, or NULL to get first
1453 *
1454 *      Returns a node pointer with refcount incremented, use
1455 *      of_node_put() on it when done.
1456 */
1457struct device_node *of_get_next_child(const struct device_node *node,
1458        struct device_node *prev)
1459{
1460        struct device_node *next;
1461
1462        read_lock(&devtree_lock);
1463        next = prev ? prev->sibling : node->child;
1464        for (; next != 0; next = next->sibling)
1465                if (of_node_get(next))
1466                        break;
1467        if (prev)
1468                of_node_put(prev);
1469        read_unlock(&devtree_lock);
1470        return next;
1471}
1472EXPORT_SYMBOL(of_get_next_child);
1473
1474/**
1475 *      of_node_get - Increment refcount of a node
1476 *      @node:  Node to inc refcount, NULL is supported to
1477 *              simplify writing of callers
1478 *
1479 *      Returns node.
1480 */
1481struct device_node *of_node_get(struct device_node *node)
1482{
1483        if (node)
1484                kref_get(&node->kref);
1485        return node;
1486}
1487EXPORT_SYMBOL(of_node_get);
1488
1489static inline struct device_node * kref_to_device_node(struct kref *kref)
1490{
1491        return container_of(kref, struct device_node, kref);
1492}
1493
1494/**
1495 *      of_node_release - release a dynamically allocated node
1496 *      @kref:  kref element of the node to be released
1497 *
1498 *      In of_node_put() this function is passed to kref_put()
1499 *      as the destructor.
1500 */
1501static void of_node_release(struct kref *kref)
1502{
1503        struct device_node *node = kref_to_device_node(kref);
1504        struct property *prop = node->properties;
1505
1506        if (!OF_IS_DYNAMIC(node))
1507                return;
1508        while (prop) {
1509                struct property *next = prop->next;
1510                kfree(prop->name);
1511                kfree(prop->value);
1512                kfree(prop);
1513                prop = next;
1514        }
1515        kfree(node->intrs);
1516        kfree(node->addrs);
1517        kfree(node->full_name);
1518        kfree(node);
1519}
1520
1521/**
1522 *      of_node_put - Decrement refcount of a node
1523 *      @node:  Node to dec refcount, NULL is supported to
1524 *              simplify writing of callers
1525 *
1526 */
1527void of_node_put(struct device_node *node)
1528{
1529        if (node)
1530                kref_put(&node->kref, of_node_release);
1531}
1532EXPORT_SYMBOL(of_node_put);
1533
1534/**
1535 *      derive_parent - basically like dirname(1)
1536 *      @path:  the full_name of a node to be added to the tree
1537 *
1538 *      Returns the node which should be the parent of the node
1539 *      described by path.  E.g., for path = "/foo/bar", returns
1540 *      the node with full_name = "/foo".
1541 */
1542static struct device_node *derive_parent(const char *path)
1543{
1544        struct device_node *parent = NULL;
1545        char *parent_path = "/";
1546        size_t parent_path_len = strrchr(path, '/') - path + 1;
1547
1548        /* reject if path is "/" */
1549        if (!strcmp(path, "/"))
1550                return NULL;
1551
1552        if (strrchr(path, '/') != path) {
1553                parent_path = kmalloc(parent_path_len, GFP_KERNEL);
1554                if (!parent_path)
1555                        return NULL;
1556                strlcpy(parent_path, path, parent_path_len);
1557        }
1558        parent = of_find_node_by_path(parent_path);
1559        if (strcmp(parent_path, "/"))
1560                kfree(parent_path);
1561        return parent;
1562}
1563
1564/*
1565 * Routines for "runtime" addition and removal of device tree nodes.
1566 */
1567#ifdef CONFIG_PROC_DEVICETREE
1568/*
1569 * Add a node to /proc/device-tree.
1570 */
1571static void add_node_proc_entries(struct device_node *np)
1572{
1573        struct proc_dir_entry *ent;
1574
1575        ent = proc_mkdir(strrchr(np->full_name, '/') + 1, np->parent->pde);
1576        if (ent)
1577                proc_device_tree_add_node(np, ent);
1578}
1579
1580static void remove_node_proc_entries(struct device_node *np)
1581{
1582        struct property *pp = np->properties;
1583        struct device_node *parent = np->parent;
1584
1585        while (pp) {
1586                remove_proc_entry(pp->name, np->pde);
1587                pp = pp->next;
1588        }
1589
1590        /* Assuming that symlinks have the same parent directory as
1591         * np->pde.
1592         */
1593        if (np->name_link)
1594                remove_proc_entry(np->name_link->name, parent->pde);
1595        if (np->addr_link)
1596                remove_proc_entry(np->addr_link->name, parent->pde);
1597        if (np->pde)
1598                remove_proc_entry(np->pde->name, parent->pde);
1599}
1600#else /* !CONFIG_PROC_DEVICETREE */
1601static void add_node_proc_entries(struct device_node *np)
1602{
1603        return;
1604}
1605
1606static void remove_node_proc_entries(struct device_node *np)
1607{
1608        return;
1609}
1610#endif /* CONFIG_PROC_DEVICETREE */
1611
1612/*
1613 * Fix up n_intrs and intrs fields in a new device node
1614 *
1615 */
1616static int of_finish_dynamic_node_interrupts(struct device_node *node)
1617{
1618        int intrcells, intlen, i;
1619        unsigned *irq, *ints, virq;
1620        struct device_node *ic;
1621
1622        ints = (unsigned int *)get_property(node, "interrupts", &intlen);
1623        intrcells = prom_n_intr_cells(node);
1624        intlen /= intrcells * sizeof(unsigned int);
1625        node->n_intrs = intlen;
1626        node->intrs = kmalloc(sizeof(struct interrupt_info) * intlen,
1627                              GFP_KERNEL);
1628        if (!node->intrs)
1629                return -ENOMEM;
1630
1631        for (i = 0; i < intlen; ++i) {
1632                int n, j;
1633                node->intrs[i].line = 0;
1634                node->intrs[i].sense = 1;
1635                n = map_interrupt(&irq, &ic, node, ints, intrcells);
1636                if (n <= 0)
1637                        continue;
1638                virq = virt_irq_create_mapping(irq[0]);
1639                if (virq == NO_IRQ) {
1640                        printk(KERN_CRIT "Could not allocate interrupt "
1641                               "number for %s\n", node->full_name);
1642                        return -ENOMEM;
1643                }
1644                node->intrs[i].line = irq_offset_up(virq);
1645                if (n > 1)
1646                        node->intrs[i].sense = irq[1];
1647                if (n > 2) {
1648                        printk(KERN_DEBUG "hmmm, got %d intr cells for %s:", n,
1649                               node->full_name);
1650                        for (j = 0; j < n; ++j)
1651                                printk(" %d", irq[j]);
1652                        printk("\n");
1653                }
1654                ints += intrcells;
1655        }
1656        return 0;
1657}
1658
1659
1660/*
1661 * Fix up the uninitialized fields in a new device node:
1662 * name, type, n_addrs, addrs, n_intrs, intrs, and pci-specific fields
1663 *
1664 * A lot of boot-time code is duplicated here, because functions such
1665 * as finish_node_interrupts, interpret_pci_props, etc. cannot use the
1666 * slab allocator.
1667 *
1668 * This should probably be split up into smaller chunks.
1669 */
1670
1671static int of_finish_dynamic_node(struct device_node *node)
1672{
1673        struct device_node *parent = of_get_parent(node);
1674        u32 *regs;
1675        int err = 0;
1676        phandle *ibm_phandle;
1677
1678        node->name = get_property(node, "name", NULL);
1679        node->type = get_property(node, "device_type", NULL);
1680
1681        if (!parent) {
1682                err = -ENODEV;
1683                goto out;
1684        }
1685
1686        /* We don't support that function on PowerMac, at least
1687         * not yet
1688         */
1689        if (systemcfg->platform == PLATFORM_POWERMAC)
1690                return -ENODEV;
1691
1692        /* fix up new node's linux_phandle field */
1693        if ((ibm_phandle = (unsigned int *)get_property(node, "ibm,phandle", NULL)))
1694                node->linux_phandle = *ibm_phandle;
1695
1696        /* do the work of interpret_pci_props */
1697        if (parent->type && !strcmp(parent->type, "pci")) {
1698                struct address_range *adr;
1699                struct pci_reg_property *pci_addrs;
1700                int i, l;
1701
1702                pci_addrs = (struct pci_reg_property *)
1703                        get_property(node, "assigned-addresses", &l);
1704                if (pci_addrs != 0 && l >= sizeof(struct pci_reg_property)) {
1705                        i = 0;
1706                        adr = kmalloc(sizeof(struct address_range) * 
1707                                      (l / sizeof(struct pci_reg_property)),
1708                                      GFP_KERNEL);
1709                        if (!adr) {
1710                                err = -ENOMEM;
1711                                goto out;
1712                        }
1713                        while ((l -= sizeof(struct pci_reg_property)) >= 0) {
1714                                adr[i].space = pci_addrs[i].addr.a_hi;
1715                                adr[i].address = pci_addrs[i].addr.a_lo;
1716                                adr[i].size = pci_addrs[i].size_lo;
1717                                ++i;
1718                        }
1719                        node->addrs = adr;
1720                        node->n_addrs = i;
1721                }
1722        }
1723
1724        /* now do the work of finish_node_interrupts */
1725        if (get_property(node, "interrupts", NULL)) {
1726                err = of_finish_dynamic_node_interrupts(node);
1727                if (err) goto out;
1728        }
1729
1730        /* now do the rough equivalent of update_dn_pci_info, this
1731         * probably is not correct for phb's, but should work for
1732         * IOAs and slots.
1733         */
1734
1735        node->phb = parent->phb;
1736
1737        regs = (u32 *)get_property(node, "reg", NULL);
1738        if (regs) {
1739                node->busno = (regs[0] >> 16) & 0xff;
1740                node->devfn = (regs[0] >> 8) & 0xff;
1741        }
1742
1743out:
1744        of_node_put(parent);
1745        return err;
1746}
1747
1748/*
1749 * Given a path and a property list, construct an OF device node, add
1750 * it to the device tree and global list, and place it in
1751 * /proc/device-tree.  This function may sleep.
1752 */
1753int of_add_node(const char *path, struct property *proplist)
1754{
1755        struct device_node *np;
1756        int err = 0;
1757
1758        np = kmalloc(sizeof(struct device_node), GFP_KERNEL);
1759        if (!np)
1760                return -ENOMEM;
1761
1762        memset(np, 0, sizeof(*np));
1763
1764        np->full_name = kmalloc(strlen(path) + 1, GFP_KERNEL);
1765        if (!np->full_name) {
1766                kfree(np);
1767                return -ENOMEM;
1768        }
1769        strcpy(np->full_name, path);
1770
1771        np->properties = proplist;
1772        OF_MARK_DYNAMIC(np);
1773        kref_init(&np->kref);
1774        of_node_get(np);
1775        np->parent = derive_parent(path);
1776        if (!np->parent) {
1777                kfree(np);
1778                return -EINVAL; /* could also be ENOMEM, though */
1779        }
1780
1781        if (0 != (err = of_finish_dynamic_node(np))) {
1782                kfree(np);
1783                return err;
1784        }
1785
1786        write_lock(&devtree_lock);
1787        np->sibling = np->parent->child;
1788        np->allnext = allnodes;
1789        np->parent->child = np;
1790        allnodes = np;
1791        write_unlock(&devtree_lock);
1792
1793        add_node_proc_entries(np);
1794
1795        of_node_put(np->parent);
1796        of_node_put(np);
1797        return 0;
1798}
1799
1800/*
1801 * Prepare an OF node for removal from system
1802 */
1803static void of_cleanup_node(struct device_node *np)
1804{
1805        if (np->iommu_table && get_property(np, "ibm,dma-window", NULL))
1806                iommu_free_table(np);
1807}
1808
1809/*
1810 * "Unplug" a node from the device tree.  The caller must hold
1811 * a reference to the node.  The memory associated with the node
1812 * is not freed until its refcount goes to zero.
1813 */
1814int of_remove_node(struct device_node *np)
1815{
1816        struct device_node *parent, *child;
1817
1818        parent = of_get_parent(np);
1819        if (!parent)
1820                return -EINVAL;
1821
1822        if ((child = of_get_next_child(np, NULL))) {
1823                of_node_put(child);
1824                return -EBUSY;
1825        }
1826
1827        of_cleanup_node(np);
1828
1829        write_lock(&devtree_lock);
1830        remove_node_proc_entries(np);
1831        if (allnodes == np)
1832                allnodes = np->allnext;
1833        else {
1834                struct device_node *prev;
1835                for (prev = allnodes;
1836                     prev->allnext != np;
1837                     prev = prev->allnext)
1838                        ;
1839                prev->allnext = np->allnext;
1840        }
1841
1842        if (parent->child == np)
1843                parent->child = np->sibling;
1844        else {
1845                struct device_node *prevsib;
1846                for (prevsib = np->parent->child;
1847                     prevsib->sibling != np;
1848                     prevsib = prevsib->sibling)
1849                        ;
1850                prevsib->sibling = np->sibling;
1851        }
1852        write_unlock(&devtree_lock);
1853        of_node_put(parent);
1854        of_node_put(np); /* Must decrement the refcount */
1855        return 0;
1856}
1857
1858/*
1859 * Find a property with a given name for a given node
1860 * and return the value.
1861 */
1862unsigned char *
1863get_property(struct device_node *np, const char *name, int *lenp)
1864{
1865        struct property *pp;
1866
1867        for (pp = np->properties; pp != 0; pp = pp->next)
1868                if (strcmp(pp->name, name) == 0) {
1869                        if (lenp != 0)
1870                                *lenp = pp->length;
1871                        return pp->value;
1872                }
1873        return NULL;
1874}
1875
1876/*
1877 * Add a property to a node
1878 */
1879void
1880prom_add_property(struct device_node* np, struct property* prop)
1881{
1882        struct property **next = &np->properties;
1883
1884        prop->next = NULL;      
1885        while (*next)
1886                next = &(*next)->next;
1887        *next = prop;
1888}
1889
1890#if 0
1891void
1892print_properties(struct device_node *np)
1893{
1894        struct property *pp;
1895        char *cp;
1896        int i, n;
1897
1898        for (pp = np->properties; pp != 0; pp = pp->next) {
1899                printk(KERN_INFO "%s", pp->name);
1900                for (i = strlen(pp->name); i < 16; ++i)
1901                        printk(" ");
1902                cp = (char *) pp->value;
1903                for (i = pp->length; i > 0; --i, ++cp)
1904                        if ((i > 1 && (*cp < 0x20 || *cp > 0x7e))
1905                            || (i == 1 && *cp != 0))
1906                                break;
1907                if (i == 0 && pp->length > 1) {
1908                        /* looks like a string */
1909                        printk(" %s\n", (char *) pp->value);
1910                } else {
1911                        /* dump it in hex */
1912                        n = pp->length;
1913                        if (n > 64)
1914                                n = 64;
1915                        if (pp->length % 4 == 0) {
1916                                unsigned int *p = (unsigned int *) pp->value;
1917
1918                                n /= 4;
1919                                for (i = 0; i < n; ++i) {
1920                                        if (i != 0 && (i % 4) == 0)
1921                                                printk("\n                ");
1922                                        printk(" %08x", *p++);
1923                                }
1924                        } else {
1925                                unsigned char *bp = pp->value;
1926
1927                                for (i = 0; i < n; ++i) {
1928                                        if (i != 0 && (i % 16) == 0)
1929                                                printk("\n                ");
1930                                        printk(" %02x", *bp++);
1931                                }
1932                        }
1933                        printk("\n");
1934                        if (pp->length > 64)
1935                                printk("                 ... (length = %d)\n",
1936                                       pp->length);
1937                }
1938        }
1939}
1940#endif
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.