/* sbus.c: SBus support routines.
 *
 * Copyright (C) 1995, 2006 David S. Miller (davem@davemloft.net)
 */

#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/init.h>
#include <linux/device.h>
#include <linux/of_device.h>

#include <asm/system.h>
#include <asm/sbus.h>
#include <asm/dma.h>
#include <asm/oplib.h>
#include <asm/prom.h>
#include <asm/bpp.h>
#include <asm/irq.h>

static ssize_t
show_sbusobppath_attr(struct device * dev, struct device_attribute * attr, char * buf)
{
	struct sbus_dev *sbus;

	sbus = to_sbus_device(dev);

	return snprintf (buf, PAGE_SIZE, "%s\n", sbus->ofdev.node->full_name);
}

static DEVICE_ATTR(obppath, S_IRUSR | S_IRGRP | S_IROTH, show_sbusobppath_attr, NULL);

struct sbus_bus *sbus_root;

static void __init fill_sbus_device(struct device_node *dp, struct sbus_dev *sdev)
{
	struct dev_archdata *sd;
	unsigned long base;
	const void *pval;
	int len, err;

	sdev->prom_node = dp->node;
	strcpy(sdev->prom_name, dp->name);

	pval = of_get_property(dp, "reg", &len);
	sdev->num_registers = 0;
	if (pval) {
		memcpy(sdev->reg_addrs, pval, len);

		sdev->num_registers =
			len / sizeof(struct linux_prom_registers);

		base = (unsigned long) sdev->reg_addrs[0].phys_addr;

		/* Compute the slot number. */
		if (base >= SUN_SBUS_BVADDR && sparc_cpu_model == sun4m)
			sdev->slot = sbus_dev_slot(base);
		else
			sdev->slot = sdev->reg_addrs[0].which_io;
	}

	pval = of_get_property(dp, "ranges", &len);
	sdev->num_device_ranges = 0;
	if (pval) {
		memcpy(sdev->device_ranges, pval, len);
		sdev->num_device_ranges =
			len / sizeof(struct linux_prom_ranges);
	}

	sbus_fill_device_irq(sdev);

	sd = &sdev->ofdev.dev.archdata;
	sd->prom_node = dp;
	sd->op = &sdev->ofdev;

	sdev->ofdev.node = dp;
	if (sdev->parent)
		sdev->ofdev.dev.parent = &sdev->parent->ofdev.dev;
	else
		sdev->ofdev.dev.parent = &sdev->bus->ofdev.dev;
	sdev->ofdev.dev.bus = &sbus_bus_type;
	dev_set_name(&sdev->ofdev.dev, "sbus[%08x]", dp->node);

	if (of_device_register(&sdev->ofdev) != 0)
		printk(KERN_DEBUG "sbus: device registration error for %s!\n",
		       dp->path_component_name);

	/* WE HAVE BEEN INVADED BY ALIENS! */
	err = sysfs_create_file(&sdev->ofdev.dev.kobj, &dev_attr_obppath.attr);
}

static void __init sbus_bus_ranges_init(struct device_node *dp, struct sbus_bus *sbus)
{
	const void *pval;
	int len;

	pval = of_get_property(dp, "ranges", &len);
	sbus->num_sbus_ranges = 0;
	if (pval) {
		memcpy(sbus->sbus_ranges, pval, len);
		sbus->num_sbus_ranges =
			len / sizeof(struct linux_prom_ranges);

		sbus_arch_bus_ranges_init(dp->parent, sbus);
	}
}

static void __init __apply_ranges_to_regs(struct linux_prom_ranges *ranges,
					  int num_ranges,
					  struct linux_prom_registers *regs,
					  int num_regs)
{
	if (num_ranges) {
		int regnum;

		for (regnum = 0; regnum < num_regs; regnum++) {
			int rngnum;

			for (rngnum = 0; rngnum < num_ranges; rngnum++) {
				if (regs[regnum].which_io == ranges[rngnum].ot_child_space)
					break;
			}
			if (rngnum == num_ranges) {
				/* We used to flag this as an error.  Actually
				 * some devices do not report the regs as we expect.
				 * For example, see SUNW,pln device.  In that case
				 * the reg property is in a format internal to that
				 * node, ie. it is not in the SBUS register space
				 * per se. -DaveM
				 */
				return;
			}
			regs[regnum].which_io = ranges[rngnum].ot_parent_space;
			regs[regnum].phys_addr -= ranges[rngnum].ot_child_base;
			regs[regnum].phys_addr += ranges[rngnum].ot_parent_base;
		}
	}
}

static void __init __fixup_regs_sdev(struct sbus_dev *sdev)
{
	if (sdev->num_registers != 0) {
		struct sbus_dev *parent = sdev->parent;
		int i;

		while (parent != NULL) {
			__apply_ranges_to_regs(parent->device_ranges,
					       parent->num_device_ranges,
					       sdev->reg_addrs,
					       sdev->num_registers);

			parent = parent->parent;
		}

		__apply_ranges_to_regs(sdev->bus->sbus_ranges,
				       sdev->bus->num_sbus_ranges,
				       sdev->reg_addrs,
				       sdev->num_registers);

		for (i = 0; i < sdev->num_registers; i++) {
			struct resource *res = &sdev->resource[i];

			res->start = sdev->reg_addrs[i].phys_addr;
			res->end = (res->start +
				    (unsigned long)sdev->reg_addrs[i].reg_size - 1UL);
			res->flags = IORESOURCE_IO |
				(sdev->reg_addrs[i].which_io & 0xff);
		}
	}
}

static void __init sbus_fixup_all_regs(struct sbus_dev *first_sdev)
{
	struct sbus_dev *sdev;

	for (sdev = first_sdev; sdev; sdev = sdev->next) {
		if (sdev->child)
			sbus_fixup_all_regs(sdev->child);
		__fixup_regs_sdev(sdev);
	}
}

/* We preserve the "probe order" of these bus and device lists to give
 * the same ordering as the old code.
 */
static void __init sbus_insert(struct sbus_bus *sbus, struct sbus_bus **root)
{
	while (*root)
		root = &(*root)->next;
	*root = sbus;
	sbus->next = NULL;
}

static void __init sdev_insert(struct sbus_dev *sdev, struct sbus_dev **root)
{
	while (*root)
		root = &(*root)->next;
	*root = sdev;
	sdev->next = NULL;
}

static void __init walk_children(struct device_node *dp, struct sbus_dev *parent, struct sbus_bus *sbus)
{
	dp = dp->child;
	while (dp) {
		struct sbus_dev *sdev;

		sdev = kzalloc(sizeof(struct sbus_dev), GFP_ATOMIC);
		if (sdev) {
			sdev_insert(sdev, &parent->child);

			sdev->bus = sbus;
			sdev->parent = parent;
			sdev->ofdev.dev.archdata.iommu =
				sbus->ofdev.dev.archdata.iommu;
			sdev->ofdev.dev.archdata.stc =
				sbus->ofdev.dev.archdata.stc;

			fill_sbus_device(dp, sdev);

			walk_children(dp, sdev, sbus);
		}
		dp = dp->sibling;
	}
}

static void __init build_one_sbus(struct device_node *dp, int num_sbus)
{
	struct sbus_bus *sbus;
	unsigned int sbus_clock;
	struct device_node *dev_dp;

	sbus = kzalloc(sizeof(struct sbus_bus), GFP_ATOMIC);
	if (!sbus)
		return;

	sbus_insert(sbus, &sbus_root);
	sbus->prom_node = dp->node;

	sbus_setup_iommu(sbus, dp);

	printk("sbus%d: ", num_sbus);

	sbus_clock = of_getintprop_default(dp, "clock-frequency",
					   (25*1000*1000));
	sbus->clock_freq = sbus_clock;

	printk("Clock %d.%d MHz\n", (int) ((sbus_clock/1000)/1000),
	       (int) (((sbus_clock/1000)%1000 != 0) ? 
		      (((sbus_clock/1000)%1000) + 1000) : 0));

	strcpy(sbus->prom_name, dp->name);

	sbus_setup_arch_props(sbus, dp);

	sbus_bus_ranges_init(dp, sbus);

	sbus->ofdev.node = dp;
	sbus->ofdev.dev.parent = NULL;
	sbus->ofdev.dev.bus = &sbus_bus_type;
	dev_set_name(&sbus->ofdev.dev, "sbus%d", num_sbus);

	if (of_device_register(&sbus->ofdev) != 0)
		printk(KERN_DEBUG "sbus: device registration error for %s!\n",
		       dev_name(&sbus->ofdev.dev));

	dev_dp = dp->child;
	while (dev_dp) {
		struct sbus_dev *sdev;

		sdev = kzalloc(sizeof(struct sbus_dev), GFP_ATOMIC);
		if (sdev) {
			sdev_insert(sdev, &sbus->devices);

			sdev->bus = sbus;
			sdev->parent = NULL;
			sdev->ofdev.dev.archdata.iommu =
				sbus->ofdev.dev.archdata.iommu;
			sdev->ofdev.dev.archdata.stc =
				sbus->ofdev.dev.archdata.stc;

			fill_sbus_device(dev_dp, sdev);

			walk_children(dev_dp, sdev, sbus);
		}
		dev_dp = dev_dp->sibling;
	}

	sbus_fixup_all_regs(sbus->devices);

	dvma_init(sbus);
}

static int __init sbus_init(void)
{
	struct device_node *dp;
	const char *sbus_name = "sbus";
	int num_sbus = 0;

	if (sbus_arch_preinit())
		return 0;

	if (sparc_cpu_model == sun4d)
		sbus_name = "sbi";

	for_each_node_by_name(dp, sbus_name) {
		build_one_sbus(dp, num_sbus);
		num_sbus++;

	}

	sbus_arch_postinit();

	return 0;
}

subsys_initcall(sbus_init);
