linux/drivers/zorro/zorro.c
<<
>>
Prefs
   1/*
   2 *    Zorro Bus Services
   3 *
   4 *    Copyright (C) 1995-2003 Geert Uytterhoeven
   5 *
   6 *    This file is subject to the terms and conditions of the GNU General Public
   7 *    License.  See the file COPYING in the main directory of this archive
   8 *    for more details.
   9 */
  10
  11#include <linux/module.h>
  12#include <linux/types.h>
  13#include <linux/kernel.h>
  14#include <linux/init.h>
  15#include <linux/zorro.h>
  16#include <linux/bitops.h>
  17#include <linux/string.h>
  18
  19#include <asm/setup.h>
  20#include <asm/amigahw.h>
  21
  22#include "zorro.h"
  23
  24
  25    /*
  26     *  Zorro Expansion Devices
  27     */
  28
  29u_int zorro_num_autocon = 0;
  30struct zorro_dev zorro_autocon[ZORRO_NUM_AUTO];
  31
  32
  33    /*
  34     *  Single Zorro bus
  35     */
  36
  37struct zorro_bus zorro_bus = {\
  38    .resources = {
  39        /* Zorro II regions (on Zorro II/III) */
  40        { .name = "Zorro II exp", .start = 0x00e80000, .end = 0x00efffff },
  41        { .name = "Zorro II mem", .start = 0x00200000, .end = 0x009fffff },
  42        /* Zorro III regions (on Zorro III only) */
  43        { .name = "Zorro III exp", .start = 0xff000000, .end = 0xffffffff },
  44        { .name = "Zorro III cfg", .start = 0x40000000, .end = 0x7fffffff }
  45    },
  46    .name = "Zorro bus"
  47};
  48
  49
  50    /*
  51     *  Find Zorro Devices
  52     */
  53
  54struct zorro_dev *zorro_find_device(zorro_id id, struct zorro_dev *from)
  55{
  56    struct zorro_dev *z;
  57
  58    if (!MACH_IS_AMIGA || !AMIGAHW_PRESENT(ZORRO))
  59        return NULL;
  60
  61    for (z = from ? from+1 : &zorro_autocon[0];
  62         z < zorro_autocon+zorro_num_autocon;
  63         z++)
  64        if (id == ZORRO_WILDCARD || id == z->id)
  65            return z;
  66    return NULL;
  67}
  68
  69
  70    /*
  71     *  Bitmask indicating portions of available Zorro II RAM that are unused
  72     *  by the system. Every bit represents a 64K chunk, for a maximum of 8MB
  73     *  (128 chunks, physical 0x00200000-0x009fffff).
  74     *
  75     *  If you want to use (= allocate) portions of this RAM, you should clear
  76     *  the corresponding bits.
  77     *
  78     *  Possible uses:
  79     *      - z2ram device
  80     *      - SCSI DMA bounce buffers
  81     *
  82     *  FIXME: use the normal resource management
  83     */
  84
  85DECLARE_BITMAP(zorro_unused_z2ram, 128);
  86
  87
  88static void __init mark_region(unsigned long start, unsigned long end,
  89                               int flag)
  90{
  91    if (flag)
  92        start += Z2RAM_CHUNKMASK;
  93    else
  94        end += Z2RAM_CHUNKMASK;
  95    start &= ~Z2RAM_CHUNKMASK;
  96    end &= ~Z2RAM_CHUNKMASK;
  97
  98    if (end <= Z2RAM_START || start >= Z2RAM_END)
  99        return;
 100    start = start < Z2RAM_START ? 0x00000000 : start-Z2RAM_START;
 101    end = end > Z2RAM_END ? Z2RAM_SIZE : end-Z2RAM_START;
 102    while (start < end) {
 103        u32 chunk = start>>Z2RAM_CHUNKSHIFT;
 104        if (flag)
 105            set_bit(chunk, zorro_unused_z2ram);
 106        else
 107            clear_bit(chunk, zorro_unused_z2ram);
 108        start += Z2RAM_CHUNKSIZE;
 109    }
 110}
 111
 112
 113static struct resource __init *zorro_find_parent_resource(struct zorro_dev *z)
 114{
 115    int i;
 116
 117    for (i = 0; i < zorro_bus.num_resources; i++)
 118        if (zorro_resource_start(z) >= zorro_bus.resources[i].start &&
 119            zorro_resource_end(z) <= zorro_bus.resources[i].end)
 120                return &zorro_bus.resources[i];
 121    return &iomem_resource;
 122}
 123
 124
 125    /*
 126     *  Initialization
 127     */
 128
 129static int __init zorro_init(void)
 130{
 131    struct zorro_dev *z;
 132    unsigned int i;
 133    int error;
 134
 135    if (!MACH_IS_AMIGA || !AMIGAHW_PRESENT(ZORRO))
 136        return 0;
 137
 138    pr_info("Zorro: Probing AutoConfig expansion devices: %d device%s\n",
 139           zorro_num_autocon, zorro_num_autocon == 1 ? "" : "s");
 140
 141    /* Initialize the Zorro bus */
 142    INIT_LIST_HEAD(&zorro_bus.devices);
 143    dev_set_name(&zorro_bus.dev, "zorro");
 144    error = device_register(&zorro_bus.dev);
 145    if (error) {
 146        pr_err("Zorro: Error registering zorro_bus\n");
 147        return error;
 148    }
 149
 150    /* Request the resources */
 151    zorro_bus.num_resources = AMIGAHW_PRESENT(ZORRO3) ? 4 : 2;
 152    for (i = 0; i < zorro_bus.num_resources; i++)
 153        request_resource(&iomem_resource, &zorro_bus.resources[i]);
 154
 155    /* Register all devices */
 156    for (i = 0; i < zorro_num_autocon; i++) {
 157        z = &zorro_autocon[i];
 158        z->id = (z->rom.er_Manufacturer<<16) | (z->rom.er_Product<<8);
 159        if (z->id == ZORRO_PROD_GVP_EPC_BASE) {
 160            /* GVP quirk */
 161            unsigned long magic = zorro_resource_start(z)+0x8000;
 162            z->id |= *(u16 *)ZTWO_VADDR(magic) & GVP_PRODMASK;
 163        }
 164        sprintf(z->name, "Zorro device %08x", z->id);
 165        zorro_name_device(z);
 166        z->resource.name = z->name;
 167        if (request_resource(zorro_find_parent_resource(z), &z->resource))
 168            pr_err("Zorro: Address space collision on device %s %pR\n",
 169                   z->name, &z->resource);
 170        dev_set_name(&z->dev, "%02x", i);
 171        z->dev.parent = &zorro_bus.dev;
 172        z->dev.bus = &zorro_bus_type;
 173        error = device_register(&z->dev);
 174        if (error) {
 175            pr_err("Zorro: Error registering device %s\n", z->name);
 176            continue;
 177        }
 178        error = zorro_create_sysfs_dev_files(z);
 179        if (error)
 180            dev_err(&z->dev, "Error creating sysfs files\n");
 181    }
 182
 183    /* Mark all available Zorro II memory */
 184    zorro_for_each_dev(z) {
 185        if (z->rom.er_Type & ERTF_MEMLIST)
 186            mark_region(zorro_resource_start(z), zorro_resource_end(z)+1, 1);
 187    }
 188
 189    /* Unmark all used Zorro II memory */
 190    for (i = 0; i < m68k_num_memory; i++)
 191        if (m68k_memory[i].addr < 16*1024*1024)
 192            mark_region(m68k_memory[i].addr,
 193                        m68k_memory[i].addr+m68k_memory[i].size, 0);
 194
 195    return 0;
 196}
 197
 198subsys_initcall(zorro_init);
 199
 200EXPORT_SYMBOL(zorro_find_device);
 201EXPORT_SYMBOL(zorro_unused_z2ram);
 202
 203MODULE_LICENSE("GPL");
 204