/*
 * tsi108/109 device setup code
 *
 * Maintained by Roy Zang < tie-fei.zang@freescale.com >
 *
 * This program is free software; you can redistribute  it and/or modify it
 * under  the terms of  the GNU General  Public License as published by the
 * Free Software Foundation;  either version 2 of the  License, or (at your
 * option) any later version.
 */

#include <linux/config.h>
#include <linux/stddef.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/errno.h>
#include <linux/major.h>
#include <linux/delay.h>
#include <linux/irq.h>
#include <linux/module.h>
#include <linux/device.h>
#include <linux/platform_device.h>
#include <asm/tsi108.h>

#include <asm/system.h>
#include <asm/atomic.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/prom.h>
#include <mm/mmu_decl.h>

#undef DEBUG

#ifdef DEBUG
#define DBG(fmt...) do { printk(fmt); } while(0)
#else
#define DBG(fmt...) do { } while(0)
#endif

static phys_addr_t tsi108_csr_base = -1;

phys_addr_t get_csrbase(void)
{
	struct device_node *tsi;

	if (tsi108_csr_base != -1)
		return tsi108_csr_base;

	tsi = of_find_node_by_type(NULL, "tsi-bridge");
	if (tsi) {
		unsigned int size;
		void *prop = get_property(tsi, "reg", &size);
		tsi108_csr_base = of_translate_address(tsi, prop);
		of_node_put(tsi);
	};
	return tsi108_csr_base;
}

u32 get_vir_csrbase(void)
{
	return (u32) (ioremap(get_csrbase(), 0x10000));
}

EXPORT_SYMBOL(get_csrbase);
EXPORT_SYMBOL(get_vir_csrbase);

static int __init tsi108_eth_of_init(void)
{
	struct device_node *np;
	unsigned int i;
	struct platform_device *tsi_eth_dev;
	struct resource res;
	int ret;

	for (np = NULL, i = 0;
	     (np = of_find_compatible_node(np, "network", "tsi-ethernet")) != NULL;
	     i++) {
		struct resource r[2];
		struct device_node *phy;
		hw_info tsi_eth_data;
		unsigned int *id;
		unsigned int *phy_id;
		void *mac_addr;
		phandle *ph;

		memset(r, 0, sizeof(r));
		memset(&tsi_eth_data, 0, sizeof(tsi_eth_data));

		ret = of_address_to_resource(np, 0, &r[0]);
		DBG("%s: name:start->end = %s:0x%lx-> 0x%lx\n",
			__FUNCTION__,r[0].name, r[0].start, r[0].end);
		if (ret)
			goto err;

		r[1].name = "tx";
		r[1].start = irq_of_parse_and_map(np, 0);
		r[1].end = irq_of_parse_and_map(np, 0);
		r[1].flags = IORESOURCE_IRQ;
		DBG("%s: name:start->end = %s:0x%lx-> 0x%lx\n",
			__FUNCTION__,r[1].name, r[1].start, r[1].end);

		tsi_eth_dev =
		    platform_device_register_simple("tsi-ethernet", i, &r[0],
						    1);

		if (IS_ERR(tsi_eth_dev)) {
			ret = PTR_ERR(tsi_eth_dev);
			goto err;
		}

		mac_addr = get_property(np, "address", NULL);
		memcpy(tsi_eth_data.mac_addr, mac_addr, 6);

		ph = (phandle *) get_property(np, "phy-handle", NULL);
		phy = of_find_node_by_phandle(*ph);

		if (phy == NULL) {
			ret = -ENODEV;
			goto unreg;
		}

		id = (u32 *) get_property(phy, "reg", NULL);
		phy_id = (u32 *) get_property(phy, "phy-id", NULL);
		ret = of_address_to_resource(phy, 0, &res);
		if (ret) {
			of_node_put(phy);
			goto unreg;
		}
		tsi_eth_data.regs = r[0].start;
		tsi_eth_data.phyregs = res.start;
		tsi_eth_data.phy = *phy_id;
		tsi_eth_data.irq_num = irq_of_parse_and_map(np, 0);
		of_node_put(phy);
		ret =
		    platform_device_add_data(tsi_eth_dev, &tsi_eth_data,
					     sizeof(hw_info));
		if (ret)
			goto unreg;
	}
	return 0;
unreg:
	platform_device_unregister(tsi_eth_dev);
err:
	return ret;
}

arch_initcall(tsi108_eth_of_init);
