/*
 *    Zorro Bus Services
 *
 *    Copyright (C) 1995-2003 Geert Uytterhoeven
 *
 *    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/module.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/zorro.h>
#include <linux/bitops.h>
#include <linux/string.h>

#include <asm/setup.h>
#include <asm/amigahw.h>

#include "zorro.h"


    /*
     *  Zorro Expansion Devices
     */

u_int zorro_num_autocon = 0;
struct zorro_dev zorro_autocon[ZORRO_NUM_AUTO];


    /*
     *  Single Zorro bus
     */

struct zorro_bus zorro_bus = {\
    .resources = {
	/* Zorro II regions (on Zorro II/III) */
	{ .name = "Zorro II exp", .start = 0x00e80000, .end = 0x00efffff },
	{ .name = "Zorro II mem", .start = 0x00200000, .end = 0x009fffff },
	/* Zorro III regions (on Zorro III only) */
	{ .name = "Zorro III exp", .start = 0xff000000, .end = 0xffffffff },
	{ .name = "Zorro III cfg", .start = 0x40000000, .end = 0x7fffffff }
    },
    .name = "Zorro bus"
};


    /*
     *  Find Zorro Devices
     */

struct zorro_dev *zorro_find_device(zorro_id id, struct zorro_dev *from)
{
    struct zorro_dev *z;

    if (!MACH_IS_AMIGA || !AMIGAHW_PRESENT(ZORRO))
	return NULL;

    for (z = from ? from+1 : &zorro_autocon[0];
	 z < zorro_autocon+zorro_num_autocon;
	 z++)
	if (id == ZORRO_WILDCARD || id == z->id)
	    return z;
    return NULL;
}


    /*
     *  Bitmask indicating portions of available Zorro II RAM that are unused
     *  by the system. Every bit represents a 64K chunk, for a maximum of 8MB
     *  (128 chunks, physical 0x00200000-0x009fffff).
     *
     *  If you want to use (= allocate) portions of this RAM, you should clear
     *  the corresponding bits.
     *
     *  Possible uses:
     *      - z2ram device
     *      - SCSI DMA bounce buffers
     *
     *  FIXME: use the normal resource management
     */

DECLARE_BITMAP(zorro_unused_z2ram, 128);


static void __init mark_region(unsigned long start, unsigned long end,
			       int flag)
{
    if (flag)
	start += Z2RAM_CHUNKMASK;
    else
	end += Z2RAM_CHUNKMASK;
    start &= ~Z2RAM_CHUNKMASK;
    end &= ~Z2RAM_CHUNKMASK;

    if (end <= Z2RAM_START || start >= Z2RAM_END)
	return;
    start = start < Z2RAM_START ? 0x00000000 : start-Z2RAM_START;
    end = end > Z2RAM_END ? Z2RAM_SIZE : end-Z2RAM_START;
    while (start < end) {
	u32 chunk = start>>Z2RAM_CHUNKSHIFT;
	if (flag)
	    set_bit(chunk, zorro_unused_z2ram);
	else
	    clear_bit(chunk, zorro_unused_z2ram);
	start += Z2RAM_CHUNKSIZE;
    }
}


static struct resource __init *zorro_find_parent_resource(struct zorro_dev *z)
{
    int i;

    for (i = 0; i < zorro_bus.num_resources; i++)
	if (zorro_resource_start(z) >= zorro_bus.resources[i].start &&
	    zorro_resource_end(z) <= zorro_bus.resources[i].end)
		return &zorro_bus.resources[i];
    return &iomem_resource;
}


    /*
     *  Initialization
     */

static int __init zorro_init(void)
{
    struct zorro_dev *z;
    unsigned int i;

    if (!MACH_IS_AMIGA || !AMIGAHW_PRESENT(ZORRO))
	return 0;

    pr_info("Zorro: Probing AutoConfig expansion devices: %d device%s\n",
	   zorro_num_autocon, zorro_num_autocon == 1 ? "" : "s");

    /* Initialize the Zorro bus */
    INIT_LIST_HEAD(&zorro_bus.devices);
    strcpy(zorro_bus.dev.bus_id, "zorro");
    device_register(&zorro_bus.dev);

    /* Request the resources */
    zorro_bus.num_resources = AMIGAHW_PRESENT(ZORRO3) ? 4 : 2;
    for (i = 0; i < zorro_bus.num_resources; i++)
	request_resource(&iomem_resource, &zorro_bus.resources[i]);

    /* Register all devices */
    for (i = 0; i < zorro_num_autocon; i++) {
	z = &zorro_autocon[i];
	z->id = (z->rom.er_Manufacturer<<16) | (z->rom.er_Product<<8);
	if (z->id == ZORRO_PROD_GVP_EPC_BASE) {
	    /* GVP quirk */
	    unsigned long magic = zorro_resource_start(z)+0x8000;
	    z->id |= *(u16 *)ZTWO_VADDR(magic) & GVP_PRODMASK;
	}
	sprintf(z->name, "Zorro device %08x", z->id);
	zorro_name_device(z);
	z->resource.name = z->name;
	if (request_resource(zorro_find_parent_resource(z), &z->resource))
	    printk(KERN_ERR "Zorro: Address space collision on device %s "
		   "[%lx:%lx]\n",
		   z->name, (unsigned long)zorro_resource_start(z),
		   (unsigned long)zorro_resource_end(z));
	sprintf(z->dev.bus_id, "%02x", i);
	z->dev.parent = &zorro_bus.dev;
	z->dev.bus = &zorro_bus_type;
	device_register(&z->dev);
	zorro_create_sysfs_dev_files(z);
    }

    /* Mark all available Zorro II memory */
    zorro_for_each_dev(z) {
	if (z->rom.er_Type & ERTF_MEMLIST)
	    mark_region(zorro_resource_start(z), zorro_resource_end(z)+1, 1);
    }

    /* Unmark all used Zorro II memory */
    for (i = 0; i < m68k_num_memory; i++)
	if (m68k_memory[i].addr < 16*1024*1024)
	    mark_region(m68k_memory[i].addr,
			m68k_memory[i].addr+m68k_memory[i].size, 0);

    return 0;
}

subsys_initcall(zorro_init);

EXPORT_SYMBOL(zorro_find_device);
EXPORT_SYMBOL(zorro_unused_z2ram);

MODULE_LICENSE("GPL");
