/*
 * 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.
 *
 * arch/sh64/mm/ioremap.c
 *
 * Copyright (C) 2000, 2001  Paolo Alberelli
 * Copyright (C) 2003  Paul Mundt
 *
 * Mostly derived from arch/sh/mm/ioremap.c which, in turn is mostly
 * derived from arch/i386/mm/ioremap.c .
 *
 *   (C) Copyright 1995 1996 Linus Torvalds
 */

#include <linux/vmalloc.h>
#include <asm/io.h>
#include <asm/pgalloc.h>
#include <linux/ioport.h>
#include <linux/bootmem.h>
#include <linux/proc_fs.h>

/*
** change to:
** #define DEBUG_IOREMAP(args)	printk(args)
** to turn on ioremap trace.
*/
#define DEBUG_IOREMAP(args)

static inline void remap_area_pte(pte_t * pte, unsigned long address, unsigned long size,
	unsigned long phys_addr, unsigned long flags)
{
	unsigned long end;

	address &= ~PMD_MASK;
	end = address + size;
	if (end > PMD_SIZE)
		end = PMD_SIZE;

	DEBUG_IOREMAP(("    %s: pte %x address %x size %x phys_addr %x\n", \
			__FUNCTION__,pte,address,size,phys_addr));

	do {
		if (!pte_none(*pte))
			printk("remap_area_pte: page already exists\n");
		set_pte(pte, mk_pte_phys(phys_addr, __pgprot(_PAGE_PRESENT |
					_PAGE_READ | _PAGE_WRITE | 
					_PAGE_DIRTY | _PAGE_ACCESSED |_PAGE_SHARED | flags)));
		address += PAGE_SIZE;
		phys_addr += PAGE_SIZE;
		pte++;
	} while (address && (address < end));
}

static inline int remap_area_pmd(pmd_t * pmd, unsigned long address, unsigned long size,
	unsigned long phys_addr, unsigned long flags)
{
	unsigned long end;

	address &= ~PGDIR_MASK;
	end = address + size;

	if (end > PGDIR_SIZE)
		end = PGDIR_SIZE;

        DEBUG_IOREMAP(("%s: pmd 0x%08x, addr. 0x%08x, phys. 0x%08x, end 0x%08x pmd 0x%08x\n", \
	       pmd, address, phys_addr, end));

	phys_addr -= address;
	do {	 

        DEBUG_IOREMAP(("%s: pmd 0x%08x, addr. 0x%08x, phys. 0x%08x, end 0x%08x pmd 0x%08x\n", \
	               __FUNCTION__, pmd, address, phys_addr, end));

		pte_t * pte = pte_alloc(&init_mm, pmd, address);
		if (!pte) {
			return -ENOMEM;
		}
		remap_area_pte(pte, address, end - address, address + phys_addr, flags);
		
		address = (address + PMD_SIZE) & PMD_MASK;
		pmd++;

    		DEBUG_IOREMAP(("remap_area_pmd address is 0x%08x phys_addr is 0x%08x end 0x%08x\n", address,phys_addr,end));


	} while (address && (address < end));
	return 0;
}

static int remap_area_pages(unsigned long address, unsigned long phys_addr,
				 unsigned long size, unsigned long flags)
{
	int error;
	pgd_t * dir;
	unsigned long end = address + size;

	phys_addr -= address;
	dir = pgd_offset(&init_mm, address);
	flush_cache_all();
	spin_lock(&init_mm.page_table_lock);    
	do {

		pmd_t *pmd = pmd_alloc(&init_mm,dir, address);
		error = -ENOMEM;
		if (!pmd)
			break;
		if (remap_area_pmd(pmd, address, end - address,
				   phys_addr + address, flags)) {
			 break;
		}
		error=0;
		address = (address + PGDIR_SIZE) & PGDIR_MASK;
		dir++;
	} while (address && (address < end));
	spin_unlock(&init_mm.page_table_lock);   
	flush_tlb_all();
	return 0;
}

/*
 * Generic mapping function (not visible outside):
 */

/*
 * Remap an arbitrary physical address space into the kernel virtual
 * address space. Needed when the kernel wants to access high addresses
 * directly.
 *
 * NOTE! We need to allow non-page-aligned mappings too: we will obviously
 * have to convert them into an offset in a page-aligned mapping, but the
 * caller shouldn't need to know that small detail.
 */
void * __ioremap(unsigned long phys_addr, unsigned long size, unsigned long flags)
{
	void * addr;
	struct vm_struct * area;
	unsigned long offset, last_addr;

	/* Don't allow wraparound or zero size */
	last_addr = phys_addr + size - 1;
	if (!size || last_addr < phys_addr)
		return NULL;

	/*
	 * Mappings have to be page-aligned
	 */
	offset = phys_addr & ~PAGE_MASK;
	phys_addr &= PAGE_MASK;
	size = PAGE_ALIGN(last_addr) - phys_addr;

	/*
	 * Ok, go for it..
	 */
	area = get_vm_area(size, VM_IOREMAP);
	DEBUG_IOREMAP(("Get vm_area returns 0x%08x addr 0x%08x \n", \
		      area, area->addr));

	if (!area)
		return NULL;
	addr = area->addr;
	if (remap_area_pages(VMALLOC_VMADDR(addr), phys_addr, size, flags)) {
		vfree(addr);
		return NULL;
	}
	return (void *) (offset + (char *)addr);
}

void iounmap(void *addr)
{
	if (((long) addr >= VMALLOC_START) && ((long) addr <= VMALLOC_END))
		return vfree((void *) (PAGE_MASK & (unsigned long) addr));
}

static struct resource shmedia_iomap = {
        .name	= "shmedia_iomap",
	.start	= IOBASE_VADDR,
	.end	= IOBASE_END - 1,
};

static void shmedia_mapioaddr(unsigned long pa, unsigned long va);
static void shmedia_unmapioaddr(unsigned long vaddr);
static unsigned long shmedia_ioremap(struct resource *res, u32 pa, int sz);

/*
 * We have the same problem as the SPARC, so lets have the same comment:
 * Our mini-allocator...
 * Boy this is gross! We need it because we must map I/O for
 * timers and interrupt controller before the kmalloc is available.
 */

#define XNMLN  15
#define XNRES  10

struct xresource {
	struct resource xres;   /* Must be first */
	int xflag;              /* 1 == used */
	char xname[XNMLN+1];
};

static struct xresource xresv[XNRES];

static struct xresource *xres_alloc(void)
{
        struct xresource *xrp;
        int n;

        xrp = xresv;
        for (n = 0; n < XNRES; n++) {
                if (xrp->xflag == 0) {
                        xrp->xflag = 1;
                        return xrp;
                }
                xrp++;
        }
        return NULL;
}

static void xres_free(struct xresource *xrp)
{
        xrp->xflag = 0;
}

static struct resource *shmedia_find_resource(struct resource *root,
					      unsigned long vaddr)
{
	struct resource *res;

	for (res = root->child; res; res = res->sibling)
		if (res->start <= vaddr && res->end >= vaddr)
			return res;

	return NULL;
}

static unsigned long shmedia_alloc_io(unsigned long phys, unsigned long size,
				      const char *name)
{
        static int printed_full = 0;
        struct xresource *xres;
        struct resource *res;
        char *tack;
        int tlen;

        if (name == NULL) name = "???";

        if ((xres = xres_alloc()) != 0) {
                tack = xres->xname;
                res = &xres->xres;
        } else {
                if (!printed_full) {
                        printk("%s: done with statics, switching to kmalloc\n",
			       __FUNCTION__);
                        printed_full = 1;
                }
                tlen = strlen(name);
                tack = kmalloc(sizeof (struct resource) + tlen + 1, GFP_KERNEL);
                if (!tack)
			return -ENOMEM;
                memset(tack, 0, sizeof(struct resource));
                res = (struct resource *) tack;
                tack += sizeof (struct resource);
        }

        strncpy(tack, name, XNMLN);
        tack[XNMLN] = 0;
        res->name = tack;

        return shmedia_ioremap(res, phys, size);
}

static unsigned long shmedia_ioremap(struct resource *res, u32 pa, int sz)
{
        unsigned long offset = ((unsigned long) pa) & (~PAGE_MASK);
	unsigned long round_sz = (offset + sz + PAGE_SIZE-1) & PAGE_MASK;
        unsigned long va;
        unsigned int psz;

        if (allocate_resource(&shmedia_iomap, res, round_sz,
			      shmedia_iomap.start, shmedia_iomap.end,
			      PAGE_SIZE, NULL, NULL) != 0) {
                panic("alloc_io_res(%s): cannot occupy\n",
                    (res->name != NULL)? res->name: "???");
        }

        va = res->start;
        pa &= PAGE_MASK;

	psz = (res->end - res->start + (PAGE_SIZE - 1)) / PAGE_SIZE;

	/* log at boot time ... */
	printk("mapioaddr: %6s  [%2ld page%s]  va 0x%08lx   pa 0x%08x\n",
	       ((res->name != NULL) ? res->name : "???"),
	       psz, psz == 1 ? " " : "s", va, pa);

        for (psz = res->end - res->start + 1; psz != 0; psz -= PAGE_SIZE) {
                shmedia_mapioaddr(pa, va);
                va += PAGE_SIZE;
                pa += PAGE_SIZE;
        }

        res->start += offset;
        res->end = res->start + sz - 1;         /* not strictly necessary.. */

        return res->start;
}

static void shmedia_free_io(struct resource *res)
{
	unsigned long len = res->end - res->start + 1;

	BUG_ON((len & (PAGE_SIZE - 1)) != 0);

	while (len) {
		len -= PAGE_SIZE;
		shmedia_unmapioaddr(res->start + len);
	}

	release_resource(res);
}

static void shmedia_mapioaddr(unsigned long pa, unsigned long va)
{
	pgd_t *pgdp;
	pmd_t *pmdp;
	pte_t *ptep;

	unsigned long flags = 1; /* 1 = CB0-1 device */


	DEBUG_IOREMAP(("shmedia_mapiopage pa %08x va %08x\n",  pa, va));

	pgdp = pgd_offset_k(va);
	if (pgd_none(*pgdp)) {
		pmdp = alloc_bootmem_low_pages(PTRS_PER_PMD * sizeof(pmd_t));
		if (pmdp == NULL) panic("No memory for pmd\n");
		memset(pmdp, 0, PTRS_PER_PGD * sizeof(pmd_t));
		set_pgd(pgdp, __pgd((unsigned long)pmdp | _KERNPG_TABLE));
	}

	pmdp = pmd_offset(pgdp, va);
	if (pmd_none(*pmdp)) {
		ptep = alloc_bootmem_low_pages(PTRS_PER_PTE * sizeof(pte_t));
		if (ptep == NULL) panic("No memory for pte\n");
		clear_page((void *)ptep);
		set_pmd(pmdp, __pmd((unsigned long)ptep + _PAGE_TABLE));
	}

	ptep = pte_offset(pmdp, va);
	set_pte(ptep, mk_pte_phys(pa, __pgprot(_PAGE_PRESENT |
			_PAGE_READ | _PAGE_WRITE | 
			_PAGE_DIRTY | _PAGE_ACCESSED |_PAGE_SHARED | flags)));
}

static void shmedia_unmapioaddr(unsigned long vaddr)
{
	pgd_t *pgdp;
	pmd_t *pmdp;
	pte_t *ptep;

	pgdp = pgd_offset_k(vaddr);
	pmdp = pmd_offset(pgdp, vaddr);

	if (pmd_none(*pmdp) || pmd_bad(*pmdp))
		return;

	ptep = pte_offset(pmdp, vaddr);

	if (pte_none(*ptep) || !pte_present(*ptep))
		return;

	clear_page((void *)ptep);
	pte_clear(ptep);
}

unsigned long onchip_remap(unsigned long phys, unsigned long size, const char *name)
{
	if (size < PAGE_SIZE)
		size = PAGE_SIZE;

	return shmedia_alloc_io(phys, size, name);
}

void onchip_unmap(unsigned long vaddr)
{
	struct resource *res;
	unsigned int psz;

	res = shmedia_find_resource(&shmedia_iomap, vaddr);
	if (!res) {
		printk(KERN_ERR "%s: Failed to free 0x%08lx\n",
		       __FUNCTION__, vaddr);
		return;
	}

        psz = (res->end - res->start + (PAGE_SIZE - 1)) / PAGE_SIZE;

        printk(KERN_DEBUG "unmapioaddr: %6s  [%2ld page%s] freed\n",
	       res->name, psz, psz == 1 ? " " : "s");

	shmedia_free_io(res);

	if ((char *)res >= (char *)xresv &&
	    (char *)res <  (char *)&xresv[XNRES]) {
		xres_free((struct xresource *)res);
	} else {
		kfree(res);
	}
}

#ifdef CONFIG_PROC_FS
static int
ioremap_proc_info(char *buf, char **start, off_t fpos, int length, int *eof,
		  void *data)
{
	char *p = buf, *e = buf + length;
	struct resource *r;
	const char *nm;

	for (r = ((struct resource *)data)->child; r != NULL; r = r->sibling) {
		if (p + 32 >= e)        /* Better than nothing */
			break;
		if ((nm = r->name) == 0) nm = "???";
		p += sprintf(p, "%08lx-%08lx: %s\n", r->start, r->end, nm);
	}

	return p-buf;
}
#endif /* CONFIG_PROC_FS */

static int __init register_proc_onchip(void)
{
#ifdef CONFIG_PROC_FS
	create_proc_read_entry("io_map",0,0, ioremap_proc_info, &shmedia_iomap);
#endif
	return 0;
}

__initcall(register_proc_onchip);
