/*
 * Functions for ST-RAM allocations
 *
 * Copyright 1994-97 Roman Hodek <Roman.Hodek@informatik.uni-erlangen.de>
 *
 * 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/types.h>
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/kdev_t.h>
#include <linux/major.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/pagemap.h>
#include <linux/memblock.h>
#include <linux/mount.h>
#include <linux/blkdev.h>
#include <linux/module.h>
#include <linux/ioport.h>

#include <asm/setup.h>
#include <asm/machdep.h>
#include <asm/page.h>
#include <asm/atarihw.h>
#include <asm/atari_stram.h>
#include <asm/io.h>


/*
 * The ST-RAM allocator allocates memory from a pool of reserved ST-RAM of
 * configurable size, set aside on ST-RAM init.
 * As long as this pool is not exhausted, allocation of real ST-RAM can be
 * guaranteed.
 */

/* set if kernel is in ST-RAM */
static int kernel_in_stram;

static struct resource stram_pool = {
	.name = "ST-RAM Pool"
};

static unsigned long pool_size = 1024*1024;

static unsigned long stram_virt_offset;

static int __init atari_stram_setup(char *arg)
{
	if (!MACH_IS_ATARI)
		return 0;

	pool_size = memparse(arg, NULL);
	return 0;
}

early_param("stram_pool", atari_stram_setup);


/*
 * This init function is called very early by atari/config.c
 * It initializes some internal variables needed for stram_alloc()
 */
void __init atari_stram_init(void)
{
	int i;

	/*
	 * determine whether kernel code resides in ST-RAM
	 * (then ST-RAM is the first memory block at virtual 0x0)
	 */
	kernel_in_stram = (m68k_memory[0].addr == 0);

	for (i = 0; i < m68k_num_memory; ++i) {
		if (m68k_memory[i].addr == 0) {
			return;
		}
	}

	/* Should never come here! (There is always ST-Ram!) */
	panic("atari_stram_init: no ST-RAM found!");
}


/*
 * This function is called from setup_arch() to reserve the pages needed for
 * ST-RAM management, if the kernel resides in ST-RAM.
 */
void __init atari_stram_reserve_pages(void *start_mem)
{
	if (kernel_in_stram) {
		pr_debug("atari_stram pool: kernel in ST-RAM, using alloc_bootmem!\n");
		stram_pool.start = (resource_size_t)memblock_alloc_low(pool_size,
								       PAGE_SIZE);
		if (!stram_pool.start)
			panic("%s: Failed to allocate %lu bytes align=%lx\n",
			      __func__, pool_size, PAGE_SIZE);

		stram_pool.end = stram_pool.start + pool_size - 1;
		request_resource(&iomem_resource, &stram_pool);
		stram_virt_offset = 0;
		pr_debug("atari_stram pool: size = %lu bytes, resource = %pR\n",
			pool_size, &stram_pool);
		pr_debug("atari_stram pool: stram_virt_offset = %lx\n",
			stram_virt_offset);
	}
}


/*
 * This function is called as arch initcall to reserve the pages needed for
 * ST-RAM management, if the kernel does not reside in ST-RAM.
 */
static int __init atari_stram_map_pages(void)
{
	if (!kernel_in_stram) {
		/*
		 * Skip page 0, as the fhe first 2 KiB are supervisor-only!
		 */
		pr_debug("atari_stram pool: kernel not in ST-RAM, using ioremap!\n");
		stram_pool.start = PAGE_SIZE;
		stram_pool.end = stram_pool.start + pool_size - 1;
		request_resource(&iomem_resource, &stram_pool);
		stram_virt_offset = (unsigned long) ioremap(stram_pool.start,
				resource_size(&stram_pool)) - stram_pool.start;
		pr_debug("atari_stram pool: size = %lu bytes, resource = %pR\n",
			pool_size, &stram_pool);
		pr_debug("atari_stram pool: stram_virt_offset = %lx\n",
			stram_virt_offset);
	}
	return 0;
}
arch_initcall(atari_stram_map_pages);


void *atari_stram_to_virt(unsigned long phys)
{
	return (void *)(phys + stram_virt_offset);
}
EXPORT_SYMBOL(atari_stram_to_virt);


unsigned long atari_stram_to_phys(void *virt)
{
	return (unsigned long)(virt - stram_virt_offset);
}
EXPORT_SYMBOL(atari_stram_to_phys);


void *atari_stram_alloc(unsigned long size, const char *owner)
{
	struct resource *res;
	int error;

	pr_debug("atari_stram_alloc: allocate %lu bytes\n", size);

	/* round up */
	size = PAGE_ALIGN(size);

	res = kzalloc(sizeof(struct resource), GFP_KERNEL);
	if (!res)
		return NULL;

	res->name = owner;
	error = allocate_resource(&stram_pool, res, size, 0, UINT_MAX,
				  PAGE_SIZE, NULL, NULL);
	if (error < 0) {
		pr_err("atari_stram_alloc: allocate_resource() failed %d!\n",
		       error);
		kfree(res);
		return NULL;
	}

	pr_debug("atari_stram_alloc: returning %pR\n", res);
	return atari_stram_to_virt(res->start);
}
EXPORT_SYMBOL(atari_stram_alloc);


void atari_stram_free(void *addr)
{
	unsigned long start = atari_stram_to_phys(addr);
	struct resource *res;
	unsigned long size;

	res = lookup_resource(&stram_pool, start);
	if (!res) {
		pr_err("atari_stram_free: trying to free nonexistent region "
		       "at %p\n", addr);
		return;
	}

	size = resource_size(res);
	pr_debug("atari_stram_free: free %lu bytes at %p\n", size, addr);
	release_resource(res);
	kfree(res);
}
EXPORT_SYMBOL(atari_stram_free);
