/*
 * Based on linux/arch/mips/txx9/rbtx4938/setup.c,
 *	    and RBTX49xx patch from CELF patch archive.
 *
 * 2003-2005 (c) MontaVista Software, Inc.
 * (C) Copyright TOSHIBA CORPORATION 2000-2001, 2004-2007
 *
 * 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.
 */
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/interrupt.h>
#include <linux/string.h>
#include <linux/module.h>
#include <linux/clk.h>
#include <linux/err.h>
#include <linux/gpio.h>
#include <linux/platform_device.h>
#include <linux/serial_core.h>
#include <linux/mtd/physmap.h>
#include <linux/leds.h>
#include <linux/sysdev.h>
#include <linux/slab.h>
#include <asm/bootinfo.h>
#include <asm/time.h>
#include <asm/reboot.h>
#include <asm/r4kcache.h>
#include <asm/sections.h>
#include <asm/txx9/generic.h>
#include <asm/txx9/pci.h>
#include <asm/txx9tmr.h>
#include <asm/txx9/ndfmc.h>
#include <asm/txx9/dmac.h>
#ifdef CONFIG_CPU_TX49XX
#include <asm/txx9/tx4938.h>
#endif

/* EBUSC settings of TX4927, etc. */
struct resource txx9_ce_res[8];
static char txx9_ce_res_name[8][4];	/* "CEn" */

/* pcode, internal register */
unsigned int txx9_pcode;
char txx9_pcode_str[8];
static struct resource txx9_reg_res = {
	.name = txx9_pcode_str,
	.flags = IORESOURCE_MEM,
};
void __init
txx9_reg_res_init(unsigned int pcode, unsigned long base, unsigned long size)
{
	int i;

	for (i = 0; i < ARRAY_SIZE(txx9_ce_res); i++) {
		sprintf(txx9_ce_res_name[i], "CE%d", i);
		txx9_ce_res[i].flags = IORESOURCE_MEM;
		txx9_ce_res[i].name = txx9_ce_res_name[i];
	}

	txx9_pcode = pcode;
	sprintf(txx9_pcode_str, "TX%x", pcode);
	if (base) {
		txx9_reg_res.start = base & 0xfffffffffULL;
		txx9_reg_res.end = (base & 0xfffffffffULL) + (size - 1);
		request_resource(&iomem_resource, &txx9_reg_res);
	}
}

/* clocks */
unsigned int txx9_master_clock;
unsigned int txx9_cpu_clock;
unsigned int txx9_gbus_clock;

#ifdef CONFIG_CPU_TX39XX
/* don't enable by default - see errata */
int txx9_ccfg_toeon __initdata;
#else
int txx9_ccfg_toeon __initdata = 1;
#endif

/* Minimum CLK support */

struct clk *clk_get(struct device *dev, const char *id)
{
	if (!strcmp(id, "spi-baseclk"))
		return (struct clk *)((unsigned long)txx9_gbus_clock / 2 / 2);
	if (!strcmp(id, "imbus_clk"))
		return (struct clk *)((unsigned long)txx9_gbus_clock / 2);
	return ERR_PTR(-ENOENT);
}
EXPORT_SYMBOL(clk_get);

int clk_enable(struct clk *clk)
{
	return 0;
}
EXPORT_SYMBOL(clk_enable);

void clk_disable(struct clk *clk)
{
}
EXPORT_SYMBOL(clk_disable);

unsigned long clk_get_rate(struct clk *clk)
{
	return (unsigned long)clk;
}
EXPORT_SYMBOL(clk_get_rate);

void clk_put(struct clk *clk)
{
}
EXPORT_SYMBOL(clk_put);

/* GPIO support */

#ifdef CONFIG_GENERIC_GPIO
int gpio_to_irq(unsigned gpio)
{
	return -EINVAL;
}
EXPORT_SYMBOL(gpio_to_irq);

int irq_to_gpio(unsigned irq)
{
	return -EINVAL;
}
EXPORT_SYMBOL(irq_to_gpio);
#endif

#define BOARD_VEC(board)	extern struct txx9_board_vec board;
#include <asm/txx9/boards.h>
#undef BOARD_VEC

struct txx9_board_vec *txx9_board_vec __initdata;
static char txx9_system_type[32];

static struct txx9_board_vec *board_vecs[] __initdata = {
#define BOARD_VEC(board)	&board,
#include <asm/txx9/boards.h>
#undef BOARD_VEC
};

static struct txx9_board_vec *__init find_board_byname(const char *name)
{
	int i;

	/* search board_vecs table */
	for (i = 0; i < ARRAY_SIZE(board_vecs); i++) {
		if (strstr(board_vecs[i]->system, name))
			return board_vecs[i];
	}
	return NULL;
}

static void __init prom_init_cmdline(void)
{
	int argc;
	int *argv32;
	int i;			/* Always ignore the "-c" at argv[0] */

	if (fw_arg0 >= CKSEG0 || fw_arg1 < CKSEG0) {
		/*
		 * argc is not a valid number, or argv32 is not a valid
		 * pointer
		 */
		argc = 0;
		argv32 = NULL;
	} else {
		argc = (int)fw_arg0;
		argv32 = (int *)fw_arg1;
	}

	arcs_cmdline[0] = '\0';

	for (i = 1; i < argc; i++) {
		char *str = (char *)(long)argv32[i];
		if (i != 1)
			strcat(arcs_cmdline, " ");
		if (strchr(str, ' ')) {
			strcat(arcs_cmdline, "\"");
			strcat(arcs_cmdline, str);
			strcat(arcs_cmdline, "\"");
		} else
			strcat(arcs_cmdline, str);
	}
}

static int txx9_ic_disable __initdata;
static int txx9_dc_disable __initdata;

#if defined(CONFIG_CPU_TX49XX)
/* flush all cache on very early stage (before 4k_cache_init) */
static void __init early_flush_dcache(void)
{
	unsigned int conf = read_c0_config();
	unsigned int dc_size = 1 << (12 + ((conf & CONF_DC) >> 6));
	unsigned int linesz = 32;
	unsigned long addr, end;

	end = INDEX_BASE + dc_size / 4;
	/* 4way, waybit=0 */
	for (addr = INDEX_BASE; addr < end; addr += linesz) {
		cache_op(Index_Writeback_Inv_D, addr | 0);
		cache_op(Index_Writeback_Inv_D, addr | 1);
		cache_op(Index_Writeback_Inv_D, addr | 2);
		cache_op(Index_Writeback_Inv_D, addr | 3);
	}
}

static void __init txx9_cache_fixup(void)
{
	unsigned int conf;

	conf = read_c0_config();
	/* flush and disable */
	if (txx9_ic_disable) {
		conf |= TX49_CONF_IC;
		write_c0_config(conf);
	}
	if (txx9_dc_disable) {
		early_flush_dcache();
		conf |= TX49_CONF_DC;
		write_c0_config(conf);
	}

	/* enable cache */
	conf = read_c0_config();
	if (!txx9_ic_disable)
		conf &= ~TX49_CONF_IC;
	if (!txx9_dc_disable)
		conf &= ~TX49_CONF_DC;
	write_c0_config(conf);

	if (conf & TX49_CONF_IC)
		pr_info("TX49XX I-Cache disabled.\n");
	if (conf & TX49_CONF_DC)
		pr_info("TX49XX D-Cache disabled.\n");
}
#elif defined(CONFIG_CPU_TX39XX)
/* flush all cache on very early stage (before tx39_cache_init) */
static void __init early_flush_dcache(void)
{
	unsigned int conf = read_c0_config();
	unsigned int dc_size = 1 << (10 + ((conf & TX39_CONF_DCS_MASK) >>
					   TX39_CONF_DCS_SHIFT));
	unsigned int linesz = 16;
	unsigned long addr, end;

	end = INDEX_BASE + dc_size / 2;
	/* 2way, waybit=0 */
	for (addr = INDEX_BASE; addr < end; addr += linesz) {
		cache_op(Index_Writeback_Inv_D, addr | 0);
		cache_op(Index_Writeback_Inv_D, addr | 1);
	}
}

static void __init txx9_cache_fixup(void)
{
	unsigned int conf;

	conf = read_c0_config();
	/* flush and disable */
	if (txx9_ic_disable) {
		conf &= ~TX39_CONF_ICE;
		write_c0_config(conf);
	}
	if (txx9_dc_disable) {
		early_flush_dcache();
		conf &= ~TX39_CONF_DCE;
		write_c0_config(conf);
	}

	/* enable cache */
	conf = read_c0_config();
	if (!txx9_ic_disable)
		conf |= TX39_CONF_ICE;
	if (!txx9_dc_disable)
		conf |= TX39_CONF_DCE;
	write_c0_config(conf);

	if (!(conf & TX39_CONF_ICE))
		pr_info("TX39XX I-Cache disabled.\n");
	if (!(conf & TX39_CONF_DCE))
		pr_info("TX39XX D-Cache disabled.\n");
}
#else
static inline void txx9_cache_fixup(void)
{
}
#endif

static void __init preprocess_cmdline(void)
{
	static char cmdline[COMMAND_LINE_SIZE] __initdata;
	char *s;

	strcpy(cmdline, arcs_cmdline);
	s = cmdline;
	arcs_cmdline[0] = '\0';
	while (s && *s) {
		char *str = strsep(&s, " ");
		if (strncmp(str, "board=", 6) == 0) {
			txx9_board_vec = find_board_byname(str + 6);
			continue;
		} else if (strncmp(str, "masterclk=", 10) == 0) {
			unsigned long val;
			if (strict_strtoul(str + 10, 10, &val) == 0)
				txx9_master_clock = val;
			continue;
		} else if (strcmp(str, "icdisable") == 0) {
			txx9_ic_disable = 1;
			continue;
		} else if (strcmp(str, "dcdisable") == 0) {
			txx9_dc_disable = 1;
			continue;
		} else if (strcmp(str, "toeoff") == 0) {
			txx9_ccfg_toeon = 0;
			continue;
		} else if (strcmp(str, "toeon") == 0) {
			txx9_ccfg_toeon = 1;
			continue;
		}
		if (arcs_cmdline[0])
			strcat(arcs_cmdline, " ");
		strcat(arcs_cmdline, str);
	}

	txx9_cache_fixup();
}

static void __init select_board(void)
{
	const char *envstr;

	/* first, determine by "board=" argument in preprocess_cmdline() */
	if (txx9_board_vec)
		return;
	/* next, determine by "board" envvar */
	envstr = prom_getenv("board");
	if (envstr) {
		txx9_board_vec = find_board_byname(envstr);
		if (txx9_board_vec)
			return;
	}

	/* select "default" board */
#ifdef CONFIG_CPU_TX39XX
	txx9_board_vec = &jmr3927_vec;
#endif
#ifdef CONFIG_CPU_TX49XX
	switch (TX4938_REV_PCODE()) {
#ifdef CONFIG_TOSHIBA_RBTX4927
	case 0x4927:
		txx9_board_vec = &rbtx4927_vec;
		break;
	case 0x4937:
		txx9_board_vec = &rbtx4937_vec;
		break;
#endif
#ifdef CONFIG_TOSHIBA_RBTX4938
	case 0x4938:
		txx9_board_vec = &rbtx4938_vec;
		break;
#endif
#ifdef CONFIG_TOSHIBA_RBTX4939
	case 0x4939:
		txx9_board_vec = &rbtx4939_vec;
		break;
#endif
	}
#endif
}

void __init prom_init(void)
{
	prom_init_cmdline();
	preprocess_cmdline();
	select_board();

	strcpy(txx9_system_type, txx9_board_vec->system);

	txx9_board_vec->prom_init();
}

void __init prom_free_prom_memory(void)
{
	unsigned long saddr = PAGE_SIZE;
	unsigned long eaddr = __pa_symbol(&_text);

	if (saddr < eaddr)
		free_init_pages("prom memory", saddr, eaddr);
}

const char *get_system_type(void)
{
	return txx9_system_type;
}

const char *__init prom_getenv(const char *name)
{
	const s32 *str;

	if (fw_arg2 < CKSEG0)
		return NULL;

	str = (const s32 *)fw_arg2;
	/* YAMON style ("name", "value" pairs) */
	while (str[0] && str[1]) {
		if (!strcmp((const char *)(unsigned long)str[0], name))
			return (const char *)(unsigned long)str[1];
		str += 2;
	}
	return NULL;
}

static void __noreturn txx9_machine_halt(void)
{
	local_irq_disable();
	clear_c0_status(ST0_IM);
	while (1) {
		if (cpu_wait) {
			(*cpu_wait)();
			if (cpu_has_counter) {
				/*
				 * Clear counter interrupt while it
				 * breaks WAIT instruction even if
				 * masked.
				 */
				write_c0_compare(0);
			}
		}
	}
}

/* Watchdog support */
void __init txx9_wdt_init(unsigned long base)
{
	struct resource res = {
		.start	= base,
		.end	= base + 0x100 - 1,
		.flags	= IORESOURCE_MEM,
	};
	platform_device_register_simple("txx9wdt", -1, &res, 1);
}

void txx9_wdt_now(unsigned long base)
{
	struct txx9_tmr_reg __iomem *tmrptr =
		ioremap(base, sizeof(struct txx9_tmr_reg));
	/* disable watch dog timer */
	__raw_writel(TXx9_TMWTMR_WDIS | TXx9_TMWTMR_TWC, &tmrptr->wtmr);
	__raw_writel(0, &tmrptr->tcr);
	/* kick watchdog */
	__raw_writel(TXx9_TMWTMR_TWIE, &tmrptr->wtmr);
	__raw_writel(1, &tmrptr->cpra); /* immediate */
	__raw_writel(TXx9_TMTCR_TCE | TXx9_TMTCR_CCDE | TXx9_TMTCR_TMODE_WDOG,
		     &tmrptr->tcr);
}

/* SPI support */
void __init txx9_spi_init(int busid, unsigned long base, int irq)
{
	struct resource res[] = {
		{
			.start	= base,
			.end	= base + 0x20 - 1,
			.flags	= IORESOURCE_MEM,
		}, {
			.start	= irq,
			.flags	= IORESOURCE_IRQ,
		},
	};
	platform_device_register_simple("spi_txx9", busid,
					res, ARRAY_SIZE(res));
}

void __init txx9_ethaddr_init(unsigned int id, unsigned char *ethaddr)
{
	struct platform_device *pdev =
		platform_device_alloc("tc35815-mac", id);
	if (!pdev ||
	    platform_device_add_data(pdev, ethaddr, 6) ||
	    platform_device_add(pdev))
		platform_device_put(pdev);
}

void __init txx9_sio_init(unsigned long baseaddr, int irq,
			  unsigned int line, unsigned int sclk, int nocts)
{
#ifdef CONFIG_SERIAL_TXX9
	struct uart_port req;

	memset(&req, 0, sizeof(req));
	req.line = line;
	req.iotype = UPIO_MEM;
	req.membase = ioremap(baseaddr, 0x24);
	req.mapbase = baseaddr;
	req.irq = irq;
	if (!nocts)
		req.flags |= UPF_BUGGY_UART /*HAVE_CTS_LINE*/;
	if (sclk) {
		req.flags |= UPF_MAGIC_MULTIPLIER /*USE_SCLK*/;
		req.uartclk = sclk;
	} else
		req.uartclk = TXX9_IMCLK;
	early_serial_txx9_setup(&req);
#endif /* CONFIG_SERIAL_TXX9 */
}

#ifdef CONFIG_EARLY_PRINTK
static void __init null_prom_putchar(char c)
{
}
void (*txx9_prom_putchar)(char c) __initdata = null_prom_putchar;

void __init prom_putchar(char c)
{
	txx9_prom_putchar(c);
}

static void __iomem *early_txx9_sio_port;

static void __init early_txx9_sio_putchar(char c)
{
#define TXX9_SICISR	0x0c
#define TXX9_SITFIFO	0x1c
#define TXX9_SICISR_TXALS	0x00000002
	while (!(__raw_readl(early_txx9_sio_port + TXX9_SICISR) &
		 TXX9_SICISR_TXALS))
		;
	__raw_writel(c, early_txx9_sio_port + TXX9_SITFIFO);
}

void __init txx9_sio_putchar_init(unsigned long baseaddr)
{
	early_txx9_sio_port = ioremap(baseaddr, 0x24);
	txx9_prom_putchar = early_txx9_sio_putchar;
}
#endif /* CONFIG_EARLY_PRINTK */

/* wrappers */
void __init plat_mem_setup(void)
{
	ioport_resource.start = 0;
	ioport_resource.end = ~0UL;	/* no limit */
	iomem_resource.start = 0;
	iomem_resource.end = ~0UL;	/* no limit */

	/* fallback restart/halt routines */
	_machine_restart = (void (*)(char *))txx9_machine_halt;
	_machine_halt = txx9_machine_halt;
	pm_power_off = txx9_machine_halt;

#ifdef CONFIG_PCI
	pcibios_plat_setup = txx9_pcibios_setup;
#endif
	txx9_board_vec->mem_setup();
}

void __init arch_init_irq(void)
{
	txx9_board_vec->irq_setup();
}

void __init plat_time_init(void)
{
#ifdef CONFIG_CPU_TX49XX
	mips_hpt_frequency = txx9_cpu_clock / 2;
#endif
	txx9_board_vec->time_init();
}

static int __init _txx9_arch_init(void)
{
	if (txx9_board_vec->arch_init)
		txx9_board_vec->arch_init();
	return 0;
}
arch_initcall(_txx9_arch_init);

static int __init _txx9_device_init(void)
{
	if (txx9_board_vec->device_init)
		txx9_board_vec->device_init();
	return 0;
}
device_initcall(_txx9_device_init);

int (*txx9_irq_dispatch)(int pending);
asmlinkage void plat_irq_dispatch(void)
{
	int pending = read_c0_status() & read_c0_cause() & ST0_IM;
	int irq = txx9_irq_dispatch(pending);

	if (likely(irq >= 0))
		do_IRQ(irq);
	else
		spurious_interrupt();
}

/* see include/asm-mips/mach-tx39xx/mangle-port.h, for example. */
#ifdef NEEDS_TXX9_SWIZZLE_ADDR_B
static unsigned long __swizzle_addr_none(unsigned long port)
{
	return port;
}
unsigned long (*__swizzle_addr_b)(unsigned long port) = __swizzle_addr_none;
EXPORT_SYMBOL(__swizzle_addr_b);
#endif

#ifdef NEEDS_TXX9_IOSWABW
static u16 ioswabw_default(volatile u16 *a, u16 x)
{
	return le16_to_cpu(x);
}
static u16 __mem_ioswabw_default(volatile u16 *a, u16 x)
{
	return x;
}
u16 (*ioswabw)(volatile u16 *a, u16 x) = ioswabw_default;
EXPORT_SYMBOL(ioswabw);
u16 (*__mem_ioswabw)(volatile u16 *a, u16 x) = __mem_ioswabw_default;
EXPORT_SYMBOL(__mem_ioswabw);
#endif

void __init txx9_physmap_flash_init(int no, unsigned long addr,
				    unsigned long size,
				    const struct physmap_flash_data *pdata)
{
#if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE)
	struct resource res = {
		.start = addr,
		.end = addr + size - 1,
		.flags = IORESOURCE_MEM,
	};
	struct platform_device *pdev;
#ifdef CONFIG_MTD_PARTITIONS
	static struct mtd_partition parts[2];
	struct physmap_flash_data pdata_part;

	/* If this area contained boot area, make separate partition */
	if (pdata->nr_parts == 0 && !pdata->parts &&
	    addr < 0x1fc00000 && addr + size > 0x1fc00000 &&
	    !parts[0].name) {
		parts[0].name = "boot";
		parts[0].offset = 0x1fc00000 - addr;
		parts[0].size = addr + size - 0x1fc00000;
		parts[1].name = "user";
		parts[1].offset = 0;
		parts[1].size = 0x1fc00000 - addr;
		pdata_part = *pdata;
		pdata_part.nr_parts = ARRAY_SIZE(parts);
		pdata_part.parts = parts;
		pdata = &pdata_part;
	}
#endif
	pdev = platform_device_alloc("physmap-flash", no);
	if (!pdev ||
	    platform_device_add_resources(pdev, &res, 1) ||
	    platform_device_add_data(pdev, pdata, sizeof(*pdata)) ||
	    platform_device_add(pdev))
		platform_device_put(pdev);
#endif
}

void __init txx9_ndfmc_init(unsigned long baseaddr,
			    const struct txx9ndfmc_platform_data *pdata)
{
#if defined(CONFIG_MTD_NAND_TXX9NDFMC) || \
	defined(CONFIG_MTD_NAND_TXX9NDFMC_MODULE)
	struct resource res = {
		.start = baseaddr,
		.end = baseaddr + 0x1000 - 1,
		.flags = IORESOURCE_MEM,
	};
	struct platform_device *pdev = platform_device_alloc("txx9ndfmc", -1);

	if (!pdev ||
	    platform_device_add_resources(pdev, &res, 1) ||
	    platform_device_add_data(pdev, pdata, sizeof(*pdata)) ||
	    platform_device_add(pdev))
		platform_device_put(pdev);
#endif
}

#if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE)
static DEFINE_SPINLOCK(txx9_iocled_lock);

#define TXX9_IOCLED_MAXLEDS 8

struct txx9_iocled_data {
	struct gpio_chip chip;
	u8 cur_val;
	void __iomem *mmioaddr;
	struct gpio_led_platform_data pdata;
	struct gpio_led leds[TXX9_IOCLED_MAXLEDS];
	char names[TXX9_IOCLED_MAXLEDS][32];
};

static int txx9_iocled_get(struct gpio_chip *chip, unsigned int offset)
{
	struct txx9_iocled_data *data =
		container_of(chip, struct txx9_iocled_data, chip);
	return data->cur_val & (1 << offset);
}

static void txx9_iocled_set(struct gpio_chip *chip, unsigned int offset,
			    int value)
{
	struct txx9_iocled_data *data =
		container_of(chip, struct txx9_iocled_data, chip);
	unsigned long flags;
	spin_lock_irqsave(&txx9_iocled_lock, flags);
	if (value)
		data->cur_val |= 1 << offset;
	else
		data->cur_val &= ~(1 << offset);
	writeb(data->cur_val, data->mmioaddr);
	mmiowb();
	spin_unlock_irqrestore(&txx9_iocled_lock, flags);
}

static int txx9_iocled_dir_in(struct gpio_chip *chip, unsigned int offset)
{
	return 0;
}

static int txx9_iocled_dir_out(struct gpio_chip *chip, unsigned int offset,
			       int value)
{
	txx9_iocled_set(chip, offset, value);
	return 0;
}

void __init txx9_iocled_init(unsigned long baseaddr,
			     int basenum, unsigned int num, int lowactive,
			     const char *color, char **deftriggers)
{
	struct txx9_iocled_data *iocled;
	struct platform_device *pdev;
	int i;
	static char *default_triggers[] __initdata = {
		"heartbeat",
		"ide-disk",
		"nand-disk",
		NULL,
	};

	if (!deftriggers)
		deftriggers = default_triggers;
	iocled = kzalloc(sizeof(*iocled), GFP_KERNEL);
	if (!iocled)
		return;
	iocled->mmioaddr = ioremap(baseaddr, 1);
	if (!iocled->mmioaddr)
		goto out_free;
	iocled->chip.get = txx9_iocled_get;
	iocled->chip.set = txx9_iocled_set;
	iocled->chip.direction_input = txx9_iocled_dir_in;
	iocled->chip.direction_output = txx9_iocled_dir_out;
	iocled->chip.label = "iocled";
	iocled->chip.base = basenum;
	iocled->chip.ngpio = num;
	if (gpiochip_add(&iocled->chip))
		goto out_unmap;
	if (basenum < 0)
		basenum = iocled->chip.base;

	pdev = platform_device_alloc("leds-gpio", basenum);
	if (!pdev)
		goto out_gpio;
	iocled->pdata.num_leds = num;
	iocled->pdata.leds = iocled->leds;
	for (i = 0; i < num; i++) {
		struct gpio_led *led = &iocled->leds[i];
		snprintf(iocled->names[i], sizeof(iocled->names[i]),
			 "iocled:%s:%u", color, i);
		led->name = iocled->names[i];
		led->gpio = basenum + i;
		led->active_low = lowactive;
		if (deftriggers && *deftriggers)
			led->default_trigger = *deftriggers++;
	}
	pdev->dev.platform_data = &iocled->pdata;
	if (platform_device_add(pdev))
		goto out_pdev;
	return;
out_pdev:
	platform_device_put(pdev);
out_gpio:
	if (gpiochip_remove(&iocled->chip))
		return;
out_unmap:
	iounmap(iocled->mmioaddr);
out_free:
	kfree(iocled);
}
#else /* CONFIG_LEDS_GPIO */
void __init txx9_iocled_init(unsigned long baseaddr,
			     int basenum, unsigned int num, int lowactive,
			     const char *color, char **deftriggers)
{
}
#endif /* CONFIG_LEDS_GPIO */

void __init txx9_dmac_init(int id, unsigned long baseaddr, int irq,
			   const struct txx9dmac_platform_data *pdata)
{
#if defined(CONFIG_TXX9_DMAC) || defined(CONFIG_TXX9_DMAC_MODULE)
	struct resource res[] = {
		{
			.start = baseaddr,
			.end = baseaddr + 0x800 - 1,
			.flags = IORESOURCE_MEM,
#ifndef CONFIG_MACH_TX49XX
		}, {
			.start = irq,
			.flags = IORESOURCE_IRQ,
#endif
		}
	};
#ifdef CONFIG_MACH_TX49XX
	struct resource chan_res[] = {
		{
			.flags = IORESOURCE_IRQ,
		}
	};
#endif
	struct platform_device *pdev = platform_device_alloc("txx9dmac", id);
	struct txx9dmac_chan_platform_data cpdata;
	int i;

	if (!pdev ||
	    platform_device_add_resources(pdev, res, ARRAY_SIZE(res)) ||
	    platform_device_add_data(pdev, pdata, sizeof(*pdata)) ||
	    platform_device_add(pdev)) {
		platform_device_put(pdev);
		return;
	}
	memset(&cpdata, 0, sizeof(cpdata));
	cpdata.dmac_dev = pdev;
	for (i = 0; i < TXX9_DMA_MAX_NR_CHANNELS; i++) {
#ifdef CONFIG_MACH_TX49XX
		chan_res[0].start = irq + i;
#endif
		pdev = platform_device_alloc("txx9dmac-chan",
					     id * TXX9_DMA_MAX_NR_CHANNELS + i);
		if (!pdev ||
#ifdef CONFIG_MACH_TX49XX
		    platform_device_add_resources(pdev, chan_res,
						  ARRAY_SIZE(chan_res)) ||
#endif
		    platform_device_add_data(pdev, &cpdata, sizeof(cpdata)) ||
		    platform_device_add(pdev))
			platform_device_put(pdev);
	}
#endif
}

void __init txx9_aclc_init(unsigned long baseaddr, int irq,
			   unsigned int dmac_id,
			   unsigned int dma_chan_out,
			   unsigned int dma_chan_in)
{
#if defined(CONFIG_SND_SOC_TXX9ACLC) || \
	defined(CONFIG_SND_SOC_TXX9ACLC_MODULE)
	unsigned int dma_base = dmac_id * TXX9_DMA_MAX_NR_CHANNELS;
	struct resource res[] = {
		{
			.start = baseaddr,
			.end = baseaddr + 0x100 - 1,
			.flags = IORESOURCE_MEM,
		}, {
			.start = irq,
			.flags = IORESOURCE_IRQ,
		}, {
			.name = "txx9dmac-chan",
			.start = dma_base + dma_chan_out,
			.flags = IORESOURCE_DMA,
		}, {
			.name = "txx9dmac-chan",
			.start = dma_base + dma_chan_in,
			.flags = IORESOURCE_DMA,
		}
	};
	struct platform_device *pdev =
		platform_device_alloc("txx9aclc-ac97", -1);

	if (!pdev ||
	    platform_device_add_resources(pdev, res, ARRAY_SIZE(res)) ||
	    platform_device_add(pdev))
		platform_device_put(pdev);
#endif
}

static struct sysdev_class txx9_sramc_sysdev_class;

struct txx9_sramc_sysdev {
	struct sys_device dev;
	struct bin_attribute bindata_attr;
	void __iomem *base;
};

static ssize_t txx9_sram_read(struct kobject *kobj,
			      struct bin_attribute *bin_attr,
			      char *buf, loff_t pos, size_t size)
{
	struct txx9_sramc_sysdev *dev = bin_attr->private;
	size_t ramsize = bin_attr->size;

	if (pos >= ramsize)
		return 0;
	if (pos + size > ramsize)
		size = ramsize - pos;
	memcpy_fromio(buf, dev->base + pos, size);
	return size;
}

static ssize_t txx9_sram_write(struct kobject *kobj,
			       struct bin_attribute *bin_attr,
			       char *buf, loff_t pos, size_t size)
{
	struct txx9_sramc_sysdev *dev = bin_attr->private;
	size_t ramsize = bin_attr->size;

	if (pos >= ramsize)
		return 0;
	if (pos + size > ramsize)
		size = ramsize - pos;
	memcpy_toio(dev->base + pos, buf, size);
	return size;
}

void __init txx9_sramc_init(struct resource *r)
{
	struct txx9_sramc_sysdev *dev;
	size_t size;
	int err;

	if (!txx9_sramc_sysdev_class.name) {
		txx9_sramc_sysdev_class.name = "txx9_sram";
		err = sysdev_class_register(&txx9_sramc_sysdev_class);
		if (err) {
			txx9_sramc_sysdev_class.name = NULL;
			return;
		}
	}
	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
	if (!dev)
		return;
	size = resource_size(r);
	dev->base = ioremap(r->start, size);
	if (!dev->base)
		goto exit;
	dev->dev.cls = &txx9_sramc_sysdev_class;
	sysfs_bin_attr_init(&dev->bindata_attr);
	dev->bindata_attr.attr.name = "bindata";
	dev->bindata_attr.attr.mode = S_IRUSR | S_IWUSR;
	dev->bindata_attr.read = txx9_sram_read;
	dev->bindata_attr.write = txx9_sram_write;
	dev->bindata_attr.size = size;
	dev->bindata_attr.private = dev;
	err = sysdev_register(&dev->dev);
	if (err)
		goto exit;
	err = sysfs_create_bin_file(&dev->dev.kobj, &dev->bindata_attr);
	if (err) {
		sysdev_unregister(&dev->dev);
		goto exit;
	}
	return;
exit:
	if (dev) {
		if (dev->base)
			iounmap(dev->base);
		kfree(dev);
	}
}
