linux/arch/powerpc/kernel/prom.c
<<
>>
Prefs
   1/*
   2 * Procedures for creating, accessing and interpreting the device tree.
   3 *
   4 * Paul Mackerras       August 1996.
   5 * Copyright (C) 1996-2005 Paul Mackerras.
   6 * 
   7 *  Adapted for 64bit PowerPC by Dave Engebretsen and Peter Bergner.
   8 *    {engebret|bergner}@us.ibm.com 
   9 *
  10 *      This program is free software; you can redistribute it and/or
  11 *      modify it under the terms of the GNU General Public License
  12 *      as published by the Free Software Foundation; either version
  13 *      2 of the License, or (at your option) any later version.
  14 */
  15
  16#undef DEBUG
  17
  18#include <stdarg.h>
  19#include <linux/kernel.h>
  20#include <linux/string.h>
  21#include <linux/init.h>
  22#include <linux/threads.h>
  23#include <linux/spinlock.h>
  24#include <linux/types.h>
  25#include <linux/pci.h>
  26#include <linux/stringify.h>
  27#include <linux/delay.h>
  28#include <linux/initrd.h>
  29#include <linux/bitops.h>
  30#include <linux/module.h>
  31#include <linux/kexec.h>
  32#include <linux/debugfs.h>
  33#include <linux/irq.h>
  34
  35#include <asm/prom.h>
  36#include <asm/rtas.h>
  37#include <asm/lmb.h>
  38#include <asm/page.h>
  39#include <asm/processor.h>
  40#include <asm/irq.h>
  41#include <asm/io.h>
  42#include <asm/kdump.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/btext.h>
  50#include <asm/sections.h>
  51#include <asm/machdep.h>
  52#include <asm/pSeries_reconfig.h>
  53#include <asm/pci-bridge.h>
  54#include <asm/kexec.h>
  55
  56#ifdef DEBUG
  57#define DBG(fmt...) printk(KERN_ERR fmt)
  58#else
  59#define DBG(fmt...)
  60#endif
  61
  62
  63static int __initdata dt_root_addr_cells;
  64static int __initdata dt_root_size_cells;
  65
  66#ifdef CONFIG_PPC64
  67int __initdata iommu_is_off;
  68int __initdata iommu_force_on;
  69unsigned long tce_alloc_start, tce_alloc_end;
  70#endif
  71
  72typedef u32 cell_t;
  73
  74#if 0
  75static struct boot_param_header *initial_boot_params __initdata;
  76#else
  77struct boot_param_header *initial_boot_params;
  78#endif
  79
  80static struct device_node *allnodes = NULL;
  81
  82/* use when traversing tree through the allnext, child, sibling,
  83 * or parent members of struct device_node.
  84 */
  85static DEFINE_RWLOCK(devtree_lock);
  86
  87/* export that to outside world */
  88struct device_node *of_chosen;
  89
  90static inline char *find_flat_dt_string(u32 offset)
  91{
  92        return ((char *)initial_boot_params) +
  93                initial_boot_params->off_dt_strings + offset;
  94}
  95
  96/**
  97 * This function is used to scan the flattened device-tree, it is
  98 * used to extract the memory informations at boot before we can
  99 * unflatten the tree
 100 */
 101int __init of_scan_flat_dt(int (*it)(unsigned long node,
 102                                     const char *uname, int depth,
 103                                     void *data),
 104                           void *data)
 105{
 106        unsigned long p = ((unsigned long)initial_boot_params) +
 107                initial_boot_params->off_dt_struct;
 108        int rc = 0;
 109        int depth = -1;
 110
 111        do {
 112                u32 tag = *((u32 *)p);
 113                char *pathp;
 114                
 115                p += 4;
 116                if (tag == OF_DT_END_NODE) {
 117                        depth --;
 118                        continue;
 119                }
 120                if (tag == OF_DT_NOP)
 121                        continue;
 122                if (tag == OF_DT_END)
 123                        break;
 124                if (tag == OF_DT_PROP) {
 125                        u32 sz = *((u32 *)p);
 126                        p += 8;
 127                        if (initial_boot_params->version < 0x10)
 128                                p = _ALIGN(p, sz >= 8 ? 8 : 4);
 129                        p += sz;
 130                        p = _ALIGN(p, 4);
 131                        continue;
 132                }
 133                if (tag != OF_DT_BEGIN_NODE) {
 134                        printk(KERN_WARNING "Invalid tag %x scanning flattened"
 135                               " device tree !\n", tag);
 136                        return -EINVAL;
 137                }
 138                depth++;
 139                pathp = (char *)p;
 140                p = _ALIGN(p + strlen(pathp) + 1, 4);
 141                if ((*pathp) == '/') {
 142                        char *lp, *np;
 143                        for (lp = NULL, np = pathp; *np; np++)
 144                                if ((*np) == '/')
 145                                        lp = np+1;
 146                        if (lp != NULL)
 147                                pathp = lp;
 148                }
 149                rc = it(p, pathp, depth, data);
 150                if (rc != 0)
 151                        break;          
 152        } while(1);
 153
 154        return rc;
 155}
 156
 157unsigned long __init of_get_flat_dt_root(void)
 158{
 159        unsigned long p = ((unsigned long)initial_boot_params) +
 160                initial_boot_params->off_dt_struct;
 161
 162        while(*((u32 *)p) == OF_DT_NOP)
 163                p += 4;
 164        BUG_ON (*((u32 *)p) != OF_DT_BEGIN_NODE);
 165        p += 4;
 166        return _ALIGN(p + strlen((char *)p) + 1, 4);
 167}
 168
 169/**
 170 * This  function can be used within scan_flattened_dt callback to get
 171 * access to properties
 172 */
 173void* __init of_get_flat_dt_prop(unsigned long node, const char *name,
 174                                 unsigned long *size)
 175{
 176        unsigned long p = node;
 177
 178        do {
 179                u32 tag = *((u32 *)p);
 180                u32 sz, noff;
 181                const char *nstr;
 182
 183                p += 4;
 184                if (tag == OF_DT_NOP)
 185                        continue;
 186                if (tag != OF_DT_PROP)
 187                        return NULL;
 188
 189                sz = *((u32 *)p);
 190                noff = *((u32 *)(p + 4));
 191                p += 8;
 192                if (initial_boot_params->version < 0x10)
 193                        p = _ALIGN(p, sz >= 8 ? 8 : 4);
 194
 195                nstr = find_flat_dt_string(noff);
 196                if (nstr == NULL) {
 197                        printk(KERN_WARNING "Can't find property index"
 198                               " name !\n");
 199                        return NULL;
 200                }
 201                if (strcmp(name, nstr) == 0) {
 202                        if (size)
 203                                *size = sz;
 204                        return (void *)p;
 205                }
 206                p += sz;
 207                p = _ALIGN(p, 4);
 208        } while(1);
 209}
 210
 211int __init of_flat_dt_is_compatible(unsigned long node, const char *compat)
 212{
 213        const char* cp;
 214        unsigned long cplen, l;
 215
 216        cp = of_get_flat_dt_prop(node, "compatible", &cplen);
 217        if (cp == NULL)
 218                return 0;
 219        while (cplen > 0) {
 220                if (strncasecmp(cp, compat, strlen(compat)) == 0)
 221                        return 1;
 222                l = strlen(cp) + 1;
 223                cp += l;
 224                cplen -= l;
 225        }
 226
 227        return 0;
 228}
 229
 230static void *__init unflatten_dt_alloc(unsigned long *mem, unsigned long size,
 231                                       unsigned long align)
 232{
 233        void *res;
 234
 235        *mem = _ALIGN(*mem, align);
 236        res = (void *)*mem;
 237        *mem += size;
 238
 239        return res;
 240}
 241
 242static unsigned long __init unflatten_dt_node(unsigned long mem,
 243                                              unsigned long *p,
 244                                              struct device_node *dad,
 245                                              struct device_node ***allnextpp,
 246                                              unsigned long fpsize)
 247{
 248        struct device_node *np;
 249        struct property *pp, **prev_pp = NULL;
 250        char *pathp;
 251        u32 tag;
 252        unsigned int l, allocl;
 253        int has_name = 0;
 254        int new_format = 0;
 255
 256        tag = *((u32 *)(*p));
 257        if (tag != OF_DT_BEGIN_NODE) {
 258                printk("Weird tag at start of node: %x\n", tag);
 259                return mem;
 260        }
 261        *p += 4;
 262        pathp = (char *)*p;
 263        l = allocl = strlen(pathp) + 1;
 264        *p = _ALIGN(*p + l, 4);
 265
 266        /* version 0x10 has a more compact unit name here instead of the full
 267         * path. we accumulate the full path size using "fpsize", we'll rebuild
 268         * it later. We detect this because the first character of the name is
 269         * not '/'.
 270         */
 271        if ((*pathp) != '/') {
 272                new_format = 1;
 273                if (fpsize == 0) {
 274                        /* root node: special case. fpsize accounts for path
 275                         * plus terminating zero. root node only has '/', so
 276                         * fpsize should be 2, but we want to avoid the first
 277                         * level nodes to have two '/' so we use fpsize 1 here
 278                         */
 279                        fpsize = 1;
 280                        allocl = 2;
 281                } else {
 282                        /* account for '/' and path size minus terminal 0
 283                         * already in 'l'
 284                         */
 285                        fpsize += l;
 286                        allocl = fpsize;
 287                }
 288        }
 289
 290
 291        np = unflatten_dt_alloc(&mem, sizeof(struct device_node) + allocl,
 292                                __alignof__(struct device_node));
 293        if (allnextpp) {
 294                memset(np, 0, sizeof(*np));
 295                np->full_name = ((char*)np) + sizeof(struct device_node);
 296                if (new_format) {
 297                        char *p = np->full_name;
 298                        /* rebuild full path for new format */
 299                        if (dad && dad->parent) {
 300                                strcpy(p, dad->full_name);
 301#ifdef DEBUG
 302                                if ((strlen(p) + l + 1) != allocl) {
 303                                        DBG("%s: p: %d, l: %d, a: %d\n",
 304                                            pathp, (int)strlen(p), l, allocl);
 305                                }
 306#endif
 307                                p += strlen(p);
 308                        }
 309                        *(p++) = '/';
 310                        memcpy(p, pathp, l);
 311                } else
 312                        memcpy(np->full_name, pathp, l);
 313                prev_pp = &np->properties;
 314                **allnextpp = np;
 315                *allnextpp = &np->allnext;
 316                if (dad != NULL) {
 317                        np->parent = dad;
 318                        /* we temporarily use the next field as `last_child'*/
 319                        if (dad->next == 0)
 320                                dad->child = np;
 321                        else
 322                                dad->next->sibling = np;
 323                        dad->next = np;
 324                }
 325                kref_init(&np->kref);
 326        }
 327        while(1) {
 328                u32 sz, noff;
 329                char *pname;
 330
 331                tag = *((u32 *)(*p));
 332                if (tag == OF_DT_NOP) {
 333                        *p += 4;
 334                        continue;
 335                }
 336                if (tag != OF_DT_PROP)
 337                        break;
 338                *p += 4;
 339                sz = *((u32 *)(*p));
 340                noff = *((u32 *)((*p) + 4));
 341                *p += 8;
 342                if (initial_boot_params->version < 0x10)
 343                        *p = _ALIGN(*p, sz >= 8 ? 8 : 4);
 344
 345                pname = find_flat_dt_string(noff);
 346                if (pname == NULL) {
 347                        printk("Can't find property name in list !\n");
 348                        break;
 349                }
 350                if (strcmp(pname, "name") == 0)
 351                        has_name = 1;
 352                l = strlen(pname) + 1;
 353                pp = unflatten_dt_alloc(&mem, sizeof(struct property),
 354                                        __alignof__(struct property));
 355                if (allnextpp) {
 356                        if (strcmp(pname, "linux,phandle") == 0) {
 357                                np->node = *((u32 *)*p);
 358                                if (np->linux_phandle == 0)
 359                                        np->linux_phandle = np->node;
 360                        }
 361                        if (strcmp(pname, "ibm,phandle") == 0)
 362                                np->linux_phandle = *((u32 *)*p);
 363                        pp->name = pname;
 364                        pp->length = sz;
 365                        pp->value = (void *)*p;
 366                        *prev_pp = pp;
 367                        prev_pp = &pp->next;
 368                }
 369                *p = _ALIGN((*p) + sz, 4);
 370        }
 371        /* with version 0x10 we may not have the name property, recreate
 372         * it here from the unit name if absent
 373         */
 374        if (!has_name) {
 375                char *p = pathp, *ps = pathp, *pa = NULL;
 376                int sz;
 377
 378                while (*p) {
 379                        if ((*p) == '@')
 380                                pa = p;
 381                        if ((*p) == '/')
 382                                ps = p + 1;
 383                        p++;
 384                }
 385                if (pa < ps)
 386                        pa = p;
 387                sz = (pa - ps) + 1;
 388                pp = unflatten_dt_alloc(&mem, sizeof(struct property) + sz,
 389                                        __alignof__(struct property));
 390                if (allnextpp) {
 391                        pp->name = "name";
 392                        pp->length = sz;
 393                        pp->value = pp + 1;
 394                        *prev_pp = pp;
 395                        prev_pp = &pp->next;
 396                        memcpy(pp->value, ps, sz - 1);
 397                        ((char *)pp->value)[sz - 1] = 0;
 398                        DBG("fixed up name for %s -> %s\n", pathp,
 399                                (char *)pp->value);
 400                }
 401        }
 402        if (allnextpp) {
 403                *prev_pp = NULL;
 404                np->name = of_get_property(np, "name", NULL);
 405                np->type = of_get_property(np, "device_type", NULL);
 406
 407                if (!np->name)
 408                        np->name = "<NULL>";
 409                if (!np->type)
 410                        np->type = "<NULL>";
 411        }
 412        while (tag == OF_DT_BEGIN_NODE) {
 413                mem = unflatten_dt_node(mem, p, np, allnextpp, fpsize);
 414                tag = *((u32 *)(*p));
 415        }
 416        if (tag != OF_DT_END_NODE) {
 417                printk("Weird tag at end of node: %x\n", tag);
 418                return mem;
 419        }
 420        *p += 4;
 421        return mem;
 422}
 423
 424static int __init early_parse_mem(char *p)
 425{
 426        if (!p)
 427                return 1;
 428
 429        memory_limit = PAGE_ALIGN(memparse(p, &p));
 430        DBG("memory limit = 0x%lx\n", memory_limit);
 431
 432        return 0;
 433}
 434early_param("mem", early_parse_mem);
 435
 436/*
 437 * The device tree may be allocated below our memory limit, or inside the
 438 * crash kernel region for kdump. If so, move it out now.
 439 */
 440static void move_device_tree(void)
 441{
 442        unsigned long start, size;
 443        void *p;
 444
 445        DBG("-> move_device_tree\n");
 446
 447        start = __pa(initial_boot_params);
 448        size = initial_boot_params->totalsize;
 449
 450        if ((memory_limit && (start + size) > memory_limit) ||
 451                        overlaps_crashkernel(start, size)) {
 452                p = __va(lmb_alloc_base(size, PAGE_SIZE, lmb.rmo_size));
 453                memcpy(p, initial_boot_params, size);
 454                initial_boot_params = (struct boot_param_header *)p;
 455                DBG("Moved device tree to 0x%p\n", p);
 456        }
 457
 458        DBG("<- move_device_tree\n");
 459}
 460
 461/**
 462 * unflattens the device-tree passed by the firmware, creating the
 463 * tree of struct device_node. It also fills the "name" and "type"
 464 * pointers of the nodes so the normal device-tree walking functions
 465 * can be used (this used to be done by finish_device_tree)
 466 */
 467void __init unflatten_device_tree(void)
 468{
 469        unsigned long start, mem, size;
 470        struct device_node **allnextp = &allnodes;
 471
 472        DBG(" -> unflatten_device_tree()\n");
 473
 474        /* First pass, scan for size */
 475        start = ((unsigned long)initial_boot_params) +
 476                initial_boot_params->off_dt_struct;
 477        size = unflatten_dt_node(0, &start, NULL, NULL, 0);
 478        size = (size | 3) + 1;
 479
 480        DBG("  size is %lx, allocating...\n", size);
 481
 482        /* Allocate memory for the expanded device tree */
 483        mem = lmb_alloc(size + 4, __alignof__(struct device_node));
 484        mem = (unsigned long) __va(mem);
 485
 486        ((u32 *)mem)[size / 4] = 0xdeadbeef;
 487
 488        DBG("  unflattening %lx...\n", mem);
 489
 490        /* Second pass, do actual unflattening */
 491        start = ((unsigned long)initial_boot_params) +
 492                initial_boot_params->off_dt_struct;
 493        unflatten_dt_node(mem, &start, NULL, &allnextp, 0);
 494        if (*((u32 *)start) != OF_DT_END)
 495                printk(KERN_WARNING "Weird tag at end of tree: %08x\n", *((u32 *)start));
 496        if (((u32 *)mem)[size / 4] != 0xdeadbeef)
 497                printk(KERN_WARNING "End of tree marker overwritten: %08x\n",
 498                       ((u32 *)mem)[size / 4] );
 499        *allnextp = NULL;
 500
 501        /* Get pointer to OF "/chosen" node for use everywhere */
 502        of_chosen = of_find_node_by_path("/chosen");
 503        if (of_chosen == NULL)
 504                of_chosen = of_find_node_by_path("/chosen@0");
 505
 506        DBG(" <- unflatten_device_tree()\n");
 507}
 508
 509/*
 510 * ibm,pa-features is a per-cpu property that contains a string of
 511 * attribute descriptors, each of which has a 2 byte header plus up
 512 * to 254 bytes worth of processor attribute bits.  First header
 513 * byte specifies the number of bytes following the header.
 514 * Second header byte is an "attribute-specifier" type, of which
 515 * zero is the only currently-defined value.
 516 * Implementation:  Pass in the byte and bit offset for the feature
 517 * that we are interested in.  The function will return -1 if the
 518 * pa-features property is missing, or a 1/0 to indicate if the feature
 519 * is supported/not supported.  Note that the bit numbers are
 520 * big-endian to match the definition in PAPR.
 521 */
 522static struct ibm_pa_feature {
 523        unsigned long   cpu_features;   /* CPU_FTR_xxx bit */
 524        unsigned int    cpu_user_ftrs;  /* PPC_FEATURE_xxx bit */
 525        unsigned char   pabyte;         /* byte number in ibm,pa-features */
 526        unsigned char   pabit;          /* bit number (big-endian) */
 527        unsigned char   invert;         /* if 1, pa bit set => clear feature */
 528} ibm_pa_features[] __initdata = {
 529        {0, PPC_FEATURE_HAS_MMU,        0, 0, 0},
 530        {0, PPC_FEATURE_HAS_FPU,        0, 1, 0},
 531        {CPU_FTR_SLB, 0,                0, 2, 0},
 532        {CPU_FTR_CTRL, 0,               0, 3, 0},
 533        {CPU_FTR_NOEXECUTE, 0,          0, 6, 0},
 534        {CPU_FTR_NODSISRALIGN, 0,       1, 1, 1},
 535#if 0
 536        /* put this back once we know how to test if firmware does 64k IO */
 537        {CPU_FTR_CI_LARGE_PAGE, 0,      1, 2, 0},
 538#endif
 539        {CPU_FTR_REAL_LE, PPC_FEATURE_TRUE_LE, 5, 0, 0},
 540};
 541
 542static void __init scan_features(unsigned long node, unsigned char *ftrs,
 543                                 unsigned long tablelen,
 544                                 struct ibm_pa_feature *fp,
 545                                 unsigned long ft_size)
 546{
 547        unsigned long i, len, bit;
 548
 549        /* find descriptor with type == 0 */
 550        for (;;) {
 551                if (tablelen < 3)
 552                        return;
 553                len = 2 + ftrs[0];
 554                if (tablelen < len)
 555                        return;         /* descriptor 0 not found */
 556                if (ftrs[1] == 0)
 557                        break;
 558                tablelen -= len;
 559                ftrs += len;
 560        }
 561
 562        /* loop over bits we know about */
 563        for (i = 0; i < ft_size; ++i, ++fp) {
 564                if (fp->pabyte >= ftrs[0])
 565                        continue;
 566                bit = (ftrs[2 + fp->pabyte] >> (7 - fp->pabit)) & 1;
 567                if (bit ^ fp->invert) {
 568                        cur_cpu_spec->cpu_features |= fp->cpu_features;
 569                        cur_cpu_spec->cpu_user_features |= fp->cpu_user_ftrs;
 570                } else {
 571                        cur_cpu_spec->cpu_features &= ~fp->cpu_features;
 572                        cur_cpu_spec->cpu_user_features &= ~fp->cpu_user_ftrs;
 573                }
 574        }
 575}
 576
 577static void __init check_cpu_pa_features(unsigned long node)
 578{
 579        unsigned char *pa_ftrs;
 580        unsigned long tablelen;
 581
 582        pa_ftrs = of_get_flat_dt_prop(node, "ibm,pa-features", &tablelen);
 583        if (pa_ftrs == NULL)
 584                return;
 585
 586        scan_features(node, pa_ftrs, tablelen,
 587                      ibm_pa_features, ARRAY_SIZE(ibm_pa_features));
 588}
 589
 590static struct feature_property {
 591        const char *name;
 592        u32 min_value;
 593        unsigned long cpu_feature;
 594        unsigned long cpu_user_ftr;
 595} feature_properties[] __initdata = {
 596#ifdef CONFIG_ALTIVEC
 597        {"altivec", 0, CPU_FTR_ALTIVEC, PPC_FEATURE_HAS_ALTIVEC},
 598        {"ibm,vmx", 1, CPU_FTR_ALTIVEC, PPC_FEATURE_HAS_ALTIVEC},
 599#endif /* CONFIG_ALTIVEC */
 600#ifdef CONFIG_PPC64
 601        {"ibm,dfp", 1, 0, PPC_FEATURE_HAS_DFP},
 602        {"ibm,purr", 1, CPU_FTR_PURR, 0},
 603        {"ibm,spurr", 1, CPU_FTR_SPURR, 0},
 604#endif /* CONFIG_PPC64 */
 605};
 606
 607static void __init check_cpu_feature_properties(unsigned long node)
 608{
 609        unsigned long i;
 610        struct feature_property *fp = feature_properties;
 611        const u32 *prop;
 612
 613        for (i = 0; i < ARRAY_SIZE(feature_properties); ++i, ++fp) {
 614                prop = of_get_flat_dt_prop(node, fp->name, NULL);
 615                if (prop && *prop >= fp->min_value) {
 616                        cur_cpu_spec->cpu_features |= fp->cpu_feature;
 617                        cur_cpu_spec->cpu_user_features |= fp->cpu_user_ftr;
 618                }
 619        }
 620}
 621
 622static int __init early_init_dt_scan_cpus(unsigned long node,
 623                                          const char *uname, int depth,
 624                                          void *data)
 625{
 626        static int logical_cpuid = 0;
 627        char *type = of_get_flat_dt_prop(node, "device_type", NULL);
 628        const u32 *prop;
 629        const u32 *intserv;
 630        int i, nthreads;
 631        unsigned long len;
 632        int found = 0;
 633
 634        /* We are scanning "cpu" nodes only */
 635        if (type == NULL || strcmp(type, "cpu") != 0)
 636                return 0;
 637
 638        /* Get physical cpuid */
 639        intserv = of_get_flat_dt_prop(node, "ibm,ppc-interrupt-server#s", &len);
 640        if (intserv) {
 641                nthreads = len / sizeof(int);
 642        } else {
 643                intserv = of_get_flat_dt_prop(node, "reg", NULL);
 644                nthreads = 1;
 645        }
 646
 647        /*
 648         * Now see if any of these threads match our boot cpu.
 649         * NOTE: This must match the parsing done in smp_setup_cpu_maps.
 650         */
 651        for (i = 0; i < nthreads; i++) {
 652                /*
 653                 * version 2 of the kexec param format adds the phys cpuid of
 654                 * booted proc.
 655                 */
 656                if (initial_boot_params && initial_boot_params->version >= 2) {
 657                        if (intserv[i] ==
 658                                        initial_boot_params->boot_cpuid_phys) {
 659                                found = 1;
 660                                break;
 661                        }
 662                } else {
 663                        /*
 664                         * Check if it's the boot-cpu, set it's hw index now,
 665                         * unfortunately this format did not support booting
 666                         * off secondary threads.
 667                         */
 668                        if (of_get_flat_dt_prop(node,
 669                                        "linux,boot-cpu", NULL) != NULL) {
 670                                found = 1;
 671                                break;
 672                        }
 673                }
 674
 675#ifdef CONFIG_SMP
 676                /* logical cpu id is always 0 on UP kernels */
 677                logical_cpuid++;
 678#endif
 679        }
 680
 681        if (found) {
 682                DBG("boot cpu: logical %d physical %d\n", logical_cpuid,
 683                        intserv[i]);
 684                boot_cpuid = logical_cpuid;
 685                set_hard_smp_processor_id(boot_cpuid, intserv[i]);
 686
 687                /*
 688                 * PAPR defines "logical" PVR values for cpus that
 689                 * meet various levels of the architecture:
 690                 * 0x0f000001   Architecture version 2.04
 691                 * 0x0f000002   Architecture version 2.05
 692                 * If the cpu-version property in the cpu node contains
 693                 * such a value, we call identify_cpu again with the
 694                 * logical PVR value in order to use the cpu feature
 695                 * bits appropriate for the architecture level.
 696                 *
 697                 * A POWER6 partition in "POWER6 architected" mode
 698                 * uses the 0x0f000002 PVR value; in POWER5+ mode
 699                 * it uses 0x0f000001.
 700                 */
 701                prop = of_get_flat_dt_prop(node, "cpu-version", NULL);
 702                if (prop && (*prop & 0xff000000) == 0x0f000000)
 703                        identify_cpu(0, *prop);
 704        }
 705
 706        check_cpu_feature_properties(node);
 707        check_cpu_pa_features(node);
 708
 709#ifdef CONFIG_PPC_PSERIES
 710        if (nthreads > 1)
 711                cur_cpu_spec->cpu_features |= CPU_FTR_SMT;
 712        else
 713                cur_cpu_spec->cpu_features &= ~CPU_FTR_SMT;
 714#endif
 715
 716        return 0;
 717}
 718
 719#ifdef CONFIG_BLK_DEV_INITRD
 720static void __init early_init_dt_check_for_initrd(unsigned long node)
 721{
 722        unsigned long l;
 723        u32 *prop;
 724
 725        DBG("Looking for initrd properties... ");
 726
 727        prop = of_get_flat_dt_prop(node, "linux,initrd-start", &l);
 728        if (prop) {
 729                initrd_start = (unsigned long)__va(of_read_ulong(prop, l/4));
 730
 731                prop = of_get_flat_dt_prop(node, "linux,initrd-end", &l);
 732                if (prop) {
 733                        initrd_end = (unsigned long)
 734                                        __va(of_read_ulong(prop, l/4));
 735                        initrd_below_start_ok = 1;
 736                } else {
 737                        initrd_start = 0;
 738                }
 739        }
 740
 741        DBG("initrd_start=0x%lx  initrd_end=0x%lx\n", initrd_start, initrd_end);
 742}
 743#else
 744static inline void early_init_dt_check_for_initrd(unsigned long node)
 745{
 746}
 747#endif /* CONFIG_BLK_DEV_INITRD */
 748
 749static int __init early_init_dt_scan_chosen(unsigned long node,
 750                                            const char *uname, int depth, void *data)
 751{
 752        unsigned long *lprop;
 753        unsigned long l;
 754        char *p;
 755
 756        DBG("search \"chosen\", depth: %d, uname: %s\n", depth, uname);
 757
 758        if (depth != 1 ||
 759            (strcmp(uname, "chosen") != 0 && strcmp(uname, "chosen@0") != 0))
 760                return 0;
 761
 762#ifdef CONFIG_PPC64
 763        /* check if iommu is forced on or off */
 764        if (of_get_flat_dt_prop(node, "linux,iommu-off", NULL) != NULL)
 765                iommu_is_off = 1;
 766        if (of_get_flat_dt_prop(node, "linux,iommu-force-on", NULL) != NULL)
 767                iommu_force_on = 1;
 768#endif
 769
 770        /* mem=x on the command line is the preferred mechanism */
 771        lprop = of_get_flat_dt_prop(node, "linux,memory-limit", NULL);
 772        if (lprop)
 773                memory_limit = *lprop;
 774
 775#ifdef CONFIG_PPC64
 776        lprop = of_get_flat_dt_prop(node, "linux,tce-alloc-start", NULL);
 777        if (lprop)
 778                tce_alloc_start = *lprop;
 779        lprop = of_get_flat_dt_prop(node, "linux,tce-alloc-end", NULL);
 780        if (lprop)
 781                tce_alloc_end = *lprop;
 782#endif
 783
 784#ifdef CONFIG_KEXEC
 785       lprop = (u64*)of_get_flat_dt_prop(node, "linux,crashkernel-base", NULL);
 786       if (lprop)
 787               crashk_res.start = *lprop;
 788
 789       lprop = (u64*)of_get_flat_dt_prop(node, "linux,crashkernel-size", NULL);
 790       if (lprop)
 791               crashk_res.end = crashk_res.start + *lprop - 1;
 792#endif
 793
 794        early_init_dt_check_for_initrd(node);
 795
 796        /* Retreive command line */
 797        p = of_get_flat_dt_prop(node, "bootargs", &l);
 798        if (p != NULL && l > 0)
 799                strlcpy(cmd_line, p, min((int)l, COMMAND_LINE_SIZE));
 800
 801#ifdef CONFIG_CMDLINE
 802        if (p == NULL || l == 0 || (l == 1 && (*p) == 0))
 803                strlcpy(cmd_line, CONFIG_CMDLINE, COMMAND_LINE_SIZE);
 804#endif /* CONFIG_CMDLINE */
 805
 806        DBG("Command line is: %s\n", cmd_line);
 807
 808        /* break now */
 809        return 1;
 810}
 811
 812static int __init early_init_dt_scan_root(unsigned long node,
 813                                          const char *uname, int depth, void *data)
 814{
 815        u32 *prop;
 816
 817        if (depth != 0)
 818                return 0;
 819
 820        prop = of_get_flat_dt_prop(node, "#size-cells", NULL);
 821        dt_root_size_cells = (prop == NULL) ? 1 : *prop;
 822        DBG("dt_root_size_cells = %x\n", dt_root_size_cells);
 823
 824        prop = of_get_flat_dt_prop(node, "#address-cells", NULL);
 825        dt_root_addr_cells = (prop == NULL) ? 2 : *prop;
 826        DBG("dt_root_addr_cells = %x\n", dt_root_addr_cells);
 827        
 828        /* break now */
 829        return 1;
 830}
 831
 832static unsigned long __init dt_mem_next_cell(int s, cell_t **cellp)
 833{
 834        cell_t *p = *cellp;
 835
 836        *cellp = p + s;
 837        return of_read_ulong(p, s);
 838}
 839
 840#ifdef CONFIG_PPC_PSERIES
 841/*
 842 * Interpret the ibm,dynamic-memory property in the
 843 * /ibm,dynamic-reconfiguration-memory node.
 844 * This contains a list of memory blocks along with NUMA affinity
 845 * information.
 846 */
 847static int __init early_init_dt_scan_drconf_memory(unsigned long node)
 848{
 849        cell_t *dm, *ls;
 850        unsigned long l, n;
 851        unsigned long base, size, lmb_size, flags;
 852
 853        ls = (cell_t *)of_get_flat_dt_prop(node, "ibm,lmb-size", &l);
 854        if (ls == NULL || l < dt_root_size_cells * sizeof(cell_t))
 855                return 0;
 856        lmb_size = dt_mem_next_cell(dt_root_size_cells, &ls);
 857
 858        dm = (cell_t *)of_get_flat_dt_prop(node, "ibm,dynamic-memory", &l);
 859        if (dm == NULL || l < sizeof(cell_t))
 860                return 0;
 861
 862        n = *dm++;      /* number of entries */
 863        if (l < (n * (dt_root_addr_cells + 4) + 1) * sizeof(cell_t))
 864                return 0;
 865
 866        for (; n != 0; --n) {
 867                base = dt_mem_next_cell(dt_root_addr_cells, &dm);
 868                flags = dm[3];
 869                /* skip DRC index, pad, assoc. list index, flags */
 870                dm += 4;
 871                /* skip this block if the reserved bit is set in flags (0x80)
 872                   or if the block is not assigned to this partition (0x8) */
 873                if ((flags & 0x80) || !(flags & 0x8))
 874                        continue;
 875                size = lmb_size;
 876                if (iommu_is_off) {
 877                        if (base >= 0x80000000ul)
 878                                continue;
 879                        if ((base + size) > 0x80000000ul)
 880                                size = 0x80000000ul - base;
 881                }
 882                lmb_add(base, size);
 883        }
 884        lmb_dump_all();
 885        return 0;
 886}
 887#else
 888#define early_init_dt_scan_drconf_memory(node)  0
 889#endif /* CONFIG_PPC_PSERIES */
 890
 891static int __init early_init_dt_scan_memory(unsigned long node,
 892                                            const char *uname, int depth, void *data)
 893{
 894        char *type = of_get_flat_dt_prop(node, "device_type", NULL);
 895        cell_t *reg, *endp;
 896        unsigned long l;
 897
 898        /* Look for the ibm,dynamic-reconfiguration-memory node */
 899        if (depth == 1 &&
 900            strcmp(uname, "ibm,dynamic-reconfiguration-memory") == 0)
 901                return early_init_dt_scan_drconf_memory(node);
 902
 903        /* We are scanning "memory" nodes only */
 904        if (type == NULL) {
 905                /*
 906                 * The longtrail doesn't have a device_type on the
 907                 * /memory node, so look for the node called /memory@0.
 908                 */
 909                if (depth != 1 || strcmp(uname, "memory@0") != 0)
 910                        return 0;
 911        } else if (strcmp(type, "memory") != 0)
 912                return 0;
 913
 914        reg = (cell_t *)of_get_flat_dt_prop(node, "linux,usable-memory", &l);
 915        if (reg == NULL)
 916                reg = (cell_t *)of_get_flat_dt_prop(node, "reg", &l);
 917        if (reg == NULL)
 918                return 0;
 919
 920        endp = reg + (l / sizeof(cell_t));
 921
 922        DBG("memory scan node %s, reg size %ld, data: %x %x %x %x,\n",
 923            uname, l, reg[0], reg[1], reg[2], reg[3]);
 924
 925        while ((endp - reg) >= (dt_root_addr_cells + dt_root_size_cells)) {
 926                unsigned long base, size;
 927
 928                base = dt_mem_next_cell(dt_root_addr_cells, &reg);
 929                size = dt_mem_next_cell(dt_root_size_cells, &reg);
 930
 931                if (size == 0)
 932                        continue;
 933                DBG(" - %lx ,  %lx\n", base, size);
 934#ifdef CONFIG_PPC64
 935                if (iommu_is_off) {
 936                        if (base >= 0x80000000ul)
 937                                continue;
 938                        if ((base + size) > 0x80000000ul)
 939                                size = 0x80000000ul - base;
 940                }
 941#endif
 942                lmb_add(base, size);
 943        }
 944        return 0;
 945}
 946
 947static void __init early_reserve_mem(void)
 948{
 949        u64 base, size;
 950        u64 *reserve_map;
 951        unsigned long self_base;
 952        unsigned long self_size;
 953
 954        reserve_map = (u64 *)(((unsigned long)initial_boot_params) +
 955                                        initial_boot_params->off_mem_rsvmap);
 956
 957        /* before we do anything, lets reserve the dt blob */
 958        self_base = __pa((unsigned long)initial_boot_params);
 959        self_size = initial_boot_params->totalsize;
 960        lmb_reserve(self_base, self_size);
 961
 962#ifdef CONFIG_BLK_DEV_INITRD
 963        /* then reserve the initrd, if any */
 964        if (initrd_start && (initrd_end > initrd_start))
 965                lmb_reserve(__pa(initrd_start), initrd_end - initrd_start);
 966#endif /* CONFIG_BLK_DEV_INITRD */
 967
 968#ifdef CONFIG_PPC32
 969        /* 
 970         * Handle the case where we might be booting from an old kexec
 971         * image that setup the mem_rsvmap as pairs of 32-bit values
 972         */
 973        if (*reserve_map > 0xffffffffull) {
 974                u32 base_32, size_32;
 975                u32 *reserve_map_32 = (u32 *)reserve_map;
 976
 977                while (1) {
 978                        base_32 = *(reserve_map_32++);
 979                        size_32 = *(reserve_map_32++);
 980                        if (size_32 == 0)
 981                                break;
 982                        /* skip if the reservation is for the blob */
 983                        if (base_32 == self_base && size_32 == self_size)
 984                                continue;
 985                        DBG("reserving: %x -> %x\n", base_32, size_32);
 986                        lmb_reserve(base_32, size_32);
 987                }
 988                return;
 989        }
 990#endif
 991        while (1) {
 992                base = *(reserve_map++);
 993                size = *(reserve_map++);
 994                if (size == 0)
 995                        break;
 996                DBG("reserving: %llx -> %llx\n", base, size);
 997                lmb_reserve(base, size);
 998        }
 999
1000#if 0
1001        DBG("memory reserved, lmbs :\n");
1002        lmb_dump_all();
1003#endif
1004}
1005
1006void __init early_init_devtree(void *params)
1007{
1008        DBG(" -> early_init_devtree()\n");
1009
1010        /* Setup flat device-tree pointer */
1011        initial_boot_params = params;
1012
1013#ifdef CONFIG_PPC_RTAS
1014        /* Some machines might need RTAS info for debugging, grab it now. */
1015        of_scan_flat_dt(early_init_dt_scan_rtas, NULL);
1016#endif
1017
1018        /* Retrieve various informations from the /chosen node of the
1019         * device-tree, including the platform type, initrd location and
1020         * size, TCE reserve, and more ...
1021         */
1022        of_scan_flat_dt(early_init_dt_scan_chosen, NULL);
1023
1024        /* Scan memory nodes and rebuild LMBs */
1025        lmb_init();
1026        of_scan_flat_dt(early_init_dt_scan_root, NULL);
1027        of_scan_flat_dt(early_init_dt_scan_memory, NULL);
1028
1029        /* Save command line for /proc/cmdline and then parse parameters */
1030        strlcpy(boot_command_line, cmd_line, COMMAND_LINE_SIZE);
1031        parse_early_param();
1032
1033        /* Reserve LMB regions used by kernel, initrd, dt, etc... */
1034        lmb_reserve(PHYSICAL_START, __pa(klimit) - PHYSICAL_START);
1035        reserve_kdump_trampoline();
1036        reserve_crashkernel();
1037        early_reserve_mem();
1038
1039        lmb_enforce_memory_limit(memory_limit);
1040        lmb_analyze();
1041
1042        DBG("Phys. mem: %lx\n", lmb_phys_mem_size());
1043
1044        /* We may need to relocate the flat tree, do it now.
1045         * FIXME .. and the initrd too? */
1046        move_device_tree();
1047
1048        DBG("Scanning CPUs ...\n");
1049
1050        /* Retreive CPU related informations from the flat tree
1051         * (altivec support, boot CPU ID, ...)
1052         */
1053        of_scan_flat_dt(early_init_dt_scan_cpus, NULL);
1054
1055        DBG(" <- early_init_devtree()\n");
1056}
1057
1058#undef printk
1059
1060int of_n_addr_cells(struct device_node* np)
1061{
1062        const int *ip;
1063        do {
1064                if (np->parent)
1065                        np = np->parent;
1066                ip = of_get_property(np, "#address-cells", NULL);
1067                if (ip != NULL)
1068                        return *ip;
1069        } while (np->parent);
1070        /* No #address-cells property for the root node, default to 1 */
1071        return 1;
1072}
1073EXPORT_SYMBOL(of_n_addr_cells);
1074
1075int of_n_size_cells(struct device_node* np)
1076{
1077        const int* ip;
1078        do {
1079                if (np->parent)
1080                        np = np->parent;
1081                ip = of_get_property(np, "#size-cells", NULL);
1082                if (ip != NULL)
1083                        return *ip;
1084        } while (np->parent);
1085        /* No #size-cells property for the root node, default to 1 */
1086        return 1;
1087}
1088EXPORT_SYMBOL(of_n_size_cells);
1089
1090/** Checks if the given "compat" string matches one of the strings in
1091 * the device's "compatible" property
1092 */
1093int of_device_is_compatible(const struct device_node *device,
1094                const char *compat)
1095{
1096        const char* cp;
1097        int cplen, l;
1098
1099        cp = of_get_property(device, "compatible", &cplen);
1100        if (cp == NULL)
1101                return 0;
1102        while (cplen > 0) {
1103                if (strncasecmp(cp, compat, strlen(compat)) == 0)
1104                        return 1;
1105                l = strlen(cp) + 1;
1106                cp += l;
1107                cplen -= l;
1108        }
1109
1110        return 0;
1111}
1112EXPORT_SYMBOL(of_device_is_compatible);
1113
1114
1115/**
1116 * Indicates whether the root node has a given value in its
1117 * compatible property.
1118 */
1119int machine_is_compatible(const char *compat)
1120{
1121        struct device_node *root;
1122        int rc = 0;
1123
1124        root = of_find_node_by_path("/");
1125        if (root) {
1126                rc = of_device_is_compatible(root, compat);
1127                of_node_put(root);
1128        }
1129        return rc;
1130}
1131EXPORT_SYMBOL(machine_is_compatible);
1132
1133/*******
1134 *
1135 * New implementation of the OF "find" APIs, return a refcounted
1136 * object, call of_node_put() when done.  The device tree and list
1137 * are protected by a rw_lock.
1138 *
1139 * Note that property management will need some locking as well,
1140 * this isn't dealt with yet.
1141 *
1142 *******/
1143
1144/**
1145 *      of_find_node_by_name - Find a node by its "name" property
1146 *      @from:  The node to start searching from or NULL, the node
1147 *              you pass will not be searched, only the next one
1148 *              will; typically, you pass what the previous call
1149 *              returned. of_node_put() will be called on it
1150 *      @name:  The name string to match against
1151 *
1152 *      Returns a node pointer with refcount incremented, use
1153 *      of_node_put() on it when done.
1154 */
1155struct device_node *of_find_node_by_name(struct device_node *from,
1156        const char *name)
1157{
1158        struct device_node *np;
1159
1160        read_lock(&devtree_lock);
1161        np = from ? from->allnext : allnodes;
1162        for (; np != NULL; np = np->allnext)
1163                if (np->name != NULL && strcasecmp(np->name, name) == 0
1164                    && of_node_get(np))
1165                        break;
1166        of_node_put(from);
1167        read_unlock(&devtree_lock);
1168        return np;
1169}
1170EXPORT_SYMBOL(of_find_node_by_name);
1171
1172/**
1173 *      of_find_node_by_type - Find a node by its "device_type" property
1174 *      @from:  The node to start searching from, or NULL to start searching
1175 *              the entire device tree. The node you pass will not be
1176 *              searched, only the next one will; typically, you pass
1177 *              what the previous call returned. of_node_put() will be
1178 *              called on from for you.
1179 *      @type:  The type string to match against
1180 *
1181 *      Returns a node pointer with refcount incremented, use
1182 *      of_node_put() on it when done.
1183 */
1184struct device_node *of_find_node_by_type(struct device_node *from,
1185        const char *type)
1186{
1187        struct device_node *np;
1188
1189        read_lock(&devtree_lock);
1190        np = from ? from->allnext : allnodes;
1191        for (; np != 0; np = np->allnext)
1192                if (np->type != 0 && strcasecmp(np->type, type) == 0
1193                    && of_node_get(np))
1194                        break;
1195        of_node_put(from);
1196        read_unlock(&devtree_lock);
1197        return np;
1198}
1199EXPORT_SYMBOL(of_find_node_by_type);
1200
1201/**
1202 *      of_find_compatible_node - Find a node based on type and one of the
1203 *                                tokens in its "compatible" property
1204 *      @from:          The node to start searching from or NULL, the node
1205 *                      you pass will not be searched, only the next one
1206 *                      will; typically, you pass what the previous call
1207 *                      returned. of_node_put() will be called on it
1208 *      @type:          The type string to match "device_type" or NULL to ignore
1209 *      @compatible:    The string to match to one of the tokens in the device
1210 *                      "compatible" list.
1211 *
1212 *      Returns a node pointer with refcount incremented, use
1213 *      of_node_put() on it when done.
1214 */
1215struct device_node *of_find_compatible_node(struct device_node *from,
1216        const char *type, const char *compatible)
1217{
1218        struct device_node *np;
1219
1220        read_lock(&devtree_lock);
1221        np = from ? from->allnext : allnodes;
1222        for (; np != 0; np = np->allnext) {
1223                if (type != NULL
1224                    && !(np->type != 0 && strcasecmp(np->type, type) == 0))
1225                        continue;
1226                if (of_device_is_compatible(np, compatible) && of_node_get(np))
1227                        break;
1228        }
1229        of_node_put(from);
1230        read_unlock(&devtree_lock);
1231        return np;
1232}
1233EXPORT_SYMBOL(of_find_compatible_node);
1234
1235/**
1236 *      of_find_node_by_path - Find a node matching a full OF path
1237 *      @path:  The full path to match
1238 *
1239 *      Returns a node pointer with refcount incremented, use
1240 *      of_node_put() on it when done.
1241 */
1242struct device_node *of_find_node_by_path(const char *path)
1243{
1244        struct device_node *np = allnodes;
1245
1246        read_lock(&devtree_lock);
1247        for (; np != 0; np = np->allnext) {
1248                if (np->full_name != 0 && strcasecmp(np->full_name, path) == 0
1249                    && of_node_get(np))
1250                        break;
1251        }
1252        read_unlock(&devtree_lock);
1253        return np;
1254}
1255EXPORT_SYMBOL(of_find_node_by_path);
1256
1257/**
1258 *      of_find_node_by_phandle - Find a node given a phandle
1259 *      @handle:        phandle of the node to find
1260 *
1261 *      Returns a node pointer with refcount incremented, use
1262 *      of_node_put() on it when done.
1263 */
1264struct device_node *of_find_node_by_phandle(phandle handle)
1265{
1266        struct device_node *np;
1267
1268        read_lock(&devtree_lock);
1269        for (np = allnodes; np != 0; np = np->allnext)
1270                if (np->linux_phandle == handle)
1271                        break;
1272        of_node_get(np);
1273        read_unlock(&devtree_lock);
1274        return np;
1275}
1276EXPORT_SYMBOL(of_find_node_by_phandle);
1277
1278/**
1279 *      of_find_all_nodes - Get next node in global list
1280 *      @prev:  Previous node or NULL to start iteration
1281 *              of_node_put() will be called on it
1282 *
1283 *      Returns a node pointer with refcount incremented, use
1284 *      of_node_put() on it when done.
1285 */
1286struct device_node *of_find_all_nodes(struct device_node *prev)
1287{
1288        struct device_node *np;
1289
1290        read_lock(&devtree_lock);
1291        np = prev ? prev->allnext : allnodes;
1292        for (; np != 0; np = np->allnext)
1293                if (of_node_get(np))
1294                        break;
1295        of_node_put(prev);
1296        read_unlock(&devtree_lock);
1297        return np;
1298}
1299EXPORT_SYMBOL(of_find_all_nodes);
1300
1301/**
1302 *      of_get_parent - Get a node's parent if any
1303 *      @node:  Node to get parent
1304 *
1305 *      Returns a node pointer with refcount incremented, use
1306 *      of_node_put() on it when done.
1307 */
1308struct device_node *of_get_parent(const struct device_node *node)
1309{
1310        struct device_node *np;
1311
1312        if (!node)
1313                return NULL;
1314
1315        read_lock(&devtree_lock);
1316        np = of_node_get(node->parent);
1317        read_unlock(&devtree_lock);
1318        return np;
1319}
1320EXPORT_SYMBOL(of_get_parent);
1321
1322/**
1323 *      of_get_next_child - Iterate a node childs
1324 *      @node:  parent node
1325 *      @prev:  previous child of the parent node, or NULL to get first
1326 *
1327 *      Returns a node pointer with refcount incremented, use
1328 *      of_node_put() on it when done.
1329 */
1330struct device_node *of_get_next_child(const struct device_node *node,
1331        struct device_node *prev)
1332{
1333        struct device_node *next;
1334
1335        read_lock(&devtree_lock);
1336        next = prev ? prev->sibling : node->child;
1337        for (; next != 0; next = next->sibling)
1338                if (of_node_get(next))
1339                        break;
1340        of_node_put(prev);
1341        read_unlock(&devtree_lock);
1342        return next;
1343}
1344EXPORT_SYMBOL(of_get_next_child);
1345
1346/**
1347 *      of_node_get - Increment refcount of a node
1348 *      @node:  Node to inc refcount, NULL is supported to
1349 *              simplify writing of callers
1350 *
1351 *      Returns node.
1352 */
1353struct device_node *of_node_get(struct device_node *node)
1354{
1355        if (node)
1356                kref_get(&node->kref);
1357        return node;
1358}
1359EXPORT_SYMBOL(of_node_get);
1360
1361static inline struct device_node * kref_to_device_node(struct kref *kref)
1362{
1363        return container_of(kref, struct device_node, kref);
1364}
1365
1366/**
1367 *      of_node_release - release a dynamically allocated node
1368 *      @kref:  kref element of the node to be released
1369 *
1370 *      In of_node_put() this function is passed to kref_put()
1371 *      as the destructor.
1372 */
1373static void of_node_release(struct kref *kref)
1374{
1375        struct device_node *node = kref_to_device_node(kref);
1376        struct property *prop = node->properties;
1377
1378        if (!OF_IS_DYNAMIC(node))
1379                return;
1380        while (prop) {
1381                struct property *next = prop->next;
1382                kfree(prop->name);
1383                kfree(prop->value);
1384                kfree(prop);
1385                prop = next;
1386
1387                if (!prop) {
1388                        prop = node->deadprops;
1389                        node->deadprops = NULL;
1390                }
1391        }
1392        kfree(node->full_name);
1393        kfree(node->data);
1394        kfree(node);
1395}
1396
1397/**
1398 *      of_node_put - Decrement refcount of a node
1399 *      @node:  Node to dec refcount, NULL is supported to
1400 *              simplify writing of callers
1401 *
1402 */
1403void of_node_put(struct device_node *node)
1404{
1405        if (node)
1406                kref_put(&node->kref, of_node_release);
1407}
1408EXPORT_SYMBOL(of_node_put);
1409
1410/*
1411 * Plug a device node into the tree and global list.
1412 */
1413void of_attach_node(struct device_node *np)
1414{
1415        write_lock(&devtree_lock);
1416        np->sibling = np->parent->child;
1417        np->allnext = allnodes;
1418        np->parent->child = np;
1419        allnodes = np;
1420        write_unlock(&devtree_lock);
1421}
1422
1423/*
1424 * "Unplug" a node from the device tree.  The caller must hold
1425 * a reference to the node.  The memory associated with the node
1426 * is not freed until its refcount goes to zero.
1427 */
1428void of_detach_node(const struct device_node *np)
1429{
1430        struct device_node *parent;
1431
1432        write_lock(&devtree_lock);
1433
1434        parent = np->parent;
1435
1436        if (allnodes == np)
1437                allnodes = np->allnext;
1438        else {
1439                struct device_node *prev;
1440                for (prev = allnodes;
1441                     prev->allnext != np;
1442                     prev = prev->allnext)
1443                        ;
1444                prev->allnext = np->allnext;
1445        }
1446
1447        if (parent->child == np)
1448                parent->child = np->sibling;
1449        else {
1450                struct device_node *prevsib;
1451                for (prevsib = np->parent->child;
1452                     prevsib->sibling != np;
1453                     prevsib = prevsib->sibling)
1454                        ;
1455                prevsib->sibling = np->sibling;
1456        }
1457
1458        write_unlock(&devtree_lock);
1459}
1460
1461#ifdef CONFIG_PPC_PSERIES
1462/*
1463 * Fix up the uninitialized fields in a new device node:
1464 * name, type and pci-specific fields
1465 */
1466
1467static int of_finish_dynamic_node(struct device_node *node)
1468{
1469        struct device_node *parent = of_get_parent(node);
1470        int err = 0;
1471        const phandle *ibm_phandle;
1472
1473        node->name = of_get_property(node, "name", NULL);
1474        node->type = of_get_property(node, "device_type", NULL);
1475
1476        if (!node->name)
1477                node->name = "<NULL>";
1478        if (!node->type)
1479                node->type = "<NULL>";
1480
1481        if (!parent) {
1482                err = -ENODEV;
1483                goto out;
1484        }
1485
1486        /* We don't support that function on PowerMac, at least
1487         * not yet
1488         */
1489        if (machine_is(powermac))
1490                return -ENODEV;
1491
1492        /* fix up new node's linux_phandle field */
1493        if ((ibm_phandle = of_get_property(node, "ibm,phandle", NULL)))
1494                node->linux_phandle = *ibm_phandle;
1495
1496out:
1497        of_node_put(parent);
1498        return err;
1499}
1500
1501static int prom_reconfig_notifier(struct notifier_block *nb,
1502                                  unsigned long action, void *node)
1503{
1504        int err;
1505
1506        switch (action) {
1507        case PSERIES_RECONFIG_ADD:
1508                err = of_finish_dynamic_node(node);
1509                if (err < 0) {
1510                        printk(KERN_ERR "finish_node returned %d\n", err);
1511                        err = NOTIFY_BAD;
1512                }
1513                break;
1514        default:
1515                err = NOTIFY_DONE;
1516                break;
1517        }
1518        return err;
1519}
1520
1521static struct notifier_block prom_reconfig_nb = {
1522        .notifier_call = prom_reconfig_notifier,
1523        .priority = 10, /* This one needs to run first */
1524};
1525
1526static int __init prom_reconfig_setup(void)
1527{
1528        return pSeries_reconfig_notifier_register(&prom_reconfig_nb);
1529}
1530__initcall(prom_reconfig_setup);
1531#endif
1532
1533struct property *of_find_property(const struct device_node *np,
1534                                  const char *name,
1535                                  int *lenp)
1536{
1537        struct property *pp;
1538
1539        read_lock(&devtree_lock);
1540        for (pp = np->properties; pp != 0; pp = pp->next)
1541                if (strcmp(pp->name, name) == 0) {
1542                        if (lenp != 0)
1543                                *lenp = pp->length;
1544                        break;
1545                }
1546        read_unlock(&devtree_lock);
1547
1548        return pp;
1549}
1550EXPORT_SYMBOL(of_find_property);
1551
1552/*
1553 * Find a property with a given name for a given node
1554 * and return the value.
1555 */
1556const void *of_get_property(const struct device_node *np, const char *name,
1557                         int *lenp)
1558{
1559        struct property *pp = of_find_property(np,name,lenp);
1560        return pp ? pp->value : NULL;
1561}
1562EXPORT_SYMBOL(of_get_property);
1563
1564/*
1565 * Add a property to a node
1566 */
1567int prom_add_property(struct device_node* np, struct property* prop)
1568{
1569        struct property **next;
1570
1571        prop->next = NULL;      
1572        write_lock(&devtree_lock);
1573        next = &np->properties;
1574        while (*next) {
1575                if (strcmp(prop->name, (*next)->name) == 0) {
1576                        /* duplicate ! don't insert it */
1577                        write_unlock(&devtree_lock);
1578                        return -1;
1579                }
1580                next = &(*next)->next;
1581        }
1582        *next = prop;
1583        write_unlock(&devtree_lock);
1584
1585#ifdef CONFIG_PROC_DEVICETREE
1586        /* try to add to proc as well if it was initialized */
1587        if (np->pde)
1588                proc_device_tree_add_prop(np->pde, prop);
1589#endif /* CONFIG_PROC_DEVICETREE */
1590
1591        return 0;
1592}
1593
1594/*
1595 * Remove a property from a node.  Note that we don't actually
1596 * remove it, since we have given out who-knows-how-many pointers
1597 * to the data using get-property.  Instead we just move the property
1598 * to the "dead properties" list, so it won't be found any more.
1599 */
1600int prom_remove_property(struct device_node *np, struct property *prop)
1601{
1602        struct property **next;
1603        int found = 0;
1604
1605        write_lock(&devtree_lock);
1606        next = &np->properties;
1607        while (*next) {
1608                if (*next == prop) {
1609                        /* found the node */
1610                        *next = prop->next;
1611                        prop->next = np->deadprops;
1612                        np->deadprops = prop;
1613                        found = 1;
1614                        break;
1615                }
1616                next = &(*next)->next;
1617        }
1618        write_unlock(&devtree_lock);
1619
1620        if (!found)
1621                return -ENODEV;
1622
1623#ifdef CONFIG_PROC_DEVICETREE
1624        /* try to remove the proc node as well */
1625        if (np->pde)
1626                proc_device_tree_remove_prop(np->pde, prop);
1627#endif /* CONFIG_PROC_DEVICETREE */
1628
1629        return 0;
1630}
1631
1632/*
1633 * Update a property in a node.  Note that we don't actually
1634 * remove it, since we have given out who-knows-how-many pointers
1635 * to the data using get-property.  Instead we just move the property
1636 * to the "dead properties" list, and add the new property to the
1637 * property list
1638 */
1639int prom_update_property(struct device_node *np,
1640                         struct property *newprop,
1641                         struct property *oldprop)
1642{
1643        struct property **next;
1644        int found = 0;
1645
1646        write_lock(&devtree_lock);
1647        next = &np->properties;
1648        while (*next) {
1649                if (*next == oldprop) {
1650                        /* found the node */
1651                        newprop->next = oldprop->next;
1652                        *next = newprop;
1653                        oldprop->next = np->deadprops;
1654                        np->deadprops = oldprop;
1655                        found = 1;
1656                        break;
1657                }
1658                next = &(*next)->next;
1659        }
1660        write_unlock(&devtree_lock);
1661
1662        if (!found)
1663                return -ENODEV;
1664
1665#ifdef CONFIG_PROC_DEVICETREE
1666        /* try to add to proc as well if it was initialized */
1667        if (np->pde)
1668                proc_device_tree_update_prop(np->pde, newprop, oldprop);
1669#endif /* CONFIG_PROC_DEVICETREE */
1670
1671        return 0;
1672}
1673
1674
1675/* Find the device node for a given logical cpu number, also returns the cpu
1676 * local thread number (index in ibm,interrupt-server#s) if relevant and
1677 * asked for (non NULL)
1678 */
1679struct device_node *of_get_cpu_node(int cpu, unsigned int *thread)
1680{
1681        int hardid;
1682        struct device_node *np;
1683
1684        hardid = get_hard_smp_processor_id(cpu);
1685
1686        for_each_node_by_type(np, "cpu") {
1687                const u32 *intserv;
1688                unsigned int plen, t;
1689
1690                /* Check for ibm,ppc-interrupt-server#s. If it doesn't exist
1691                 * fallback to "reg" property and assume no threads
1692                 */
1693                intserv = of_get_property(np, "ibm,ppc-interrupt-server#s",
1694                                &plen);
1695                if (intserv == NULL) {
1696                        const u32 *reg = of_get_property(np, "reg", NULL);
1697                        if (reg == NULL)
1698                                continue;
1699                        if (*reg == hardid) {
1700                                if (thread)
1701                                        *thread = 0;
1702                                return np;
1703                        }
1704                } else {
1705                        plen /= sizeof(u32);
1706                        for (t = 0; t < plen; t++) {
1707                                if (hardid == intserv[t]) {
1708                                        if (thread)
1709                                                *thread = t;
1710                                        return np;
1711                                }
1712                        }
1713                }
1714        }
1715        return NULL;
1716}
1717EXPORT_SYMBOL(of_get_cpu_node);
1718
1719#ifdef DEBUG
1720static struct debugfs_blob_wrapper flat_dt_blob;
1721
1722static int __init export_flat_device_tree(void)
1723{
1724        struct dentry *d;
1725
1726        d = debugfs_create_dir("powerpc", NULL);
1727        if (!d)
1728                return 1;
1729
1730        flat_dt_blob.data = initial_boot_params;
1731        flat_dt_blob.size = initial_boot_params->totalsize;
1732
1733        d = debugfs_create_blob("flat-device-tree", S_IFREG | S_IRUSR,
1734                                d, &flat_dt_blob);
1735        if (!d)
1736                return 1;
1737
1738        return 0;
1739}
1740__initcall(export_flat_device_tree);
1741#endif
1742
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.