/*
 * This file is subject to the terms and conditions of the GNU General Public
 * License.  See the file "COPYING" in the main directory of this archive
 * for more details.
 *
 * PROM component device tree code.
 *
 * Copyright (C) 1996 David S. Miller (davem@davemloft.net)
 * Copyright (C) 1999 Ralf Baechle (ralf@gnu.org)
 * Copyright (C) 1999 Silicon Graphics, Inc.
 */
#include <linux/init.h>
#include <asm/fw/arc/types.h>
#include <asm/sgialib.h>

#undef DEBUG_PROM_TREE

pcomponent * __init
ArcGetPeer(pcomponent *Current)
{
	if (Current == PROM_NULL_COMPONENT)
		return PROM_NULL_COMPONENT;

	return (pcomponent *) ARC_CALL1(next_component, Current);
}

pcomponent * __init
ArcGetChild(pcomponent *Current)
{
	return (pcomponent *) ARC_CALL1(child_component, Current);
}

pcomponent * __init
ArcGetParent(pcomponent *Current)
{
	if (Current == PROM_NULL_COMPONENT)
		return PROM_NULL_COMPONENT;

	return (pcomponent *) ARC_CALL1(parent_component, Current);
}

LONG __init
ArcGetConfigurationData(VOID *Buffer, pcomponent *Current)
{
	return ARC_CALL2(component_data, Buffer, Current);
}

pcomponent * __init
ArcAddChild(pcomponent *Current, pcomponent *Template, VOID *ConfigurationData)
{
	return (pcomponent *)
	       ARC_CALL3(child_add, Current, Template, ConfigurationData);
}

LONG __init
ArcDeleteComponent(pcomponent *ComponentToDelete)
{
	return ARC_CALL1(comp_del, ComponentToDelete);
}

pcomponent * __init
ArcGetComponent(CHAR *Path)
{
	return (pcomponent *)ARC_CALL1(component_by_path, Path);
}

#ifdef DEBUG_PROM_TREE

static char *classes[] = {
	"system", "processor", "cache", "adapter", "controller", "peripheral",
	"memory"
};

static char *types[] = {
	"arc", "cpu", "fpu", "picache", "pdcache", "sicache", "sdcache",
	"sccache", "memdev", "eisa adapter", "tc adapter", "scsi adapter",
	"dti adapter", "multi-func adapter", "disk controller",
	"tp controller", "cdrom controller", "worm controller",
	"serial controller", "net controller", "display controller",
	"parallel controller", "pointer controller", "keyboard controller",
	"audio controller", "misc controller", "disk peripheral",
	"floppy peripheral", "tp peripheral", "modem peripheral",
	"monitor peripheral", "printer peripheral", "pointer peripheral",
	"keyboard peripheral", "terminal peripheral", "line peripheral",
	"net peripheral", "misc peripheral", "anonymous"
};

static char *iflags[] = {
	"bogus", "read only", "removable", "console in", "console out",
	"input", "output"
};

static void __init
dump_component(pcomponent *p)
{
	printk("[%p]:class<%s>type<%s>flags<%s>ver<%d>rev<%d>",
	       p, classes[p->class], types[p->type],
	       iflags[p->iflags], p->vers, p->rev);
	printk("key<%08lx>\n\tamask<%08lx>cdsize<%d>ilen<%d>iname<%s>\n",
	       p->key, p->amask, (int)p->cdsize, (int)p->ilen, p->iname);
}

static void __init
traverse(pcomponent *p, int op)
{
	dump_component(p);
	if(ArcGetChild(p))
		traverse(ArcGetChild(p), 1);
	if(ArcGetPeer(p) && op)
		traverse(ArcGetPeer(p), 1);
}

void __init
prom_testtree(void)
{
	pcomponent *p;

	p = ArcGetChild(PROM_NULL_COMPONENT);
	dump_component(p);
	p = ArcGetChild(p);
	while(p) {
		dump_component(p);
		p = ArcGetPeer(p);
	}
}

#endif /* DEBUG_PROM_TREE  */
