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#include <linux/platform_device.h>
  19#include <linux/slab.h>
  20
  21#include <asm/setup.h>
  22#include <asm/amigahw.h>
  23
  24#include "zorro.h"
  25
  26
  27    /*
  28     *  Zorro Expansion Devices
  29     */
  30
  31unsigned int zorro_num_autocon;
  32struct zorro_dev zorro_autocon[ZORRO_NUM_AUTO];
  33
  34
  35    /*
  36     *  Zorro bus
  37     */
  38
  39struct zorro_bus {
  40        struct list_head devices;       /* list of devices on this bus */
  41        struct device dev;
  42};
  43
  44
  45    /*
  46     *  Find Zorro Devices
  47     */
  48
  49struct zorro_dev *zorro_find_device(zorro_id id, struct zorro_dev *from)
  50{
  51        struct zorro_dev *z;
  52
  53        if (!zorro_num_autocon)
  54                return NULL;
  55
  56        for (z = from ? from+1 : &zorro_autocon[0];
  57             z < zorro_autocon+zorro_num_autocon;
  58             z++)
  59                if (id == ZORRO_WILDCARD || id == z->id)
  60                        return z;
  61        return NULL;
  62}
  63EXPORT_SYMBOL(zorro_find_device);
  64
  65
  66    /*
  67     *  Bitmask indicating portions of available Zorro II RAM that are unused
  68     *  by the system. Every bit represents a 64K chunk, for a maximum of 8MB
  69     *  (128 chunks, physical 0x00200000-0x009fffff).
  70     *
  71     *  If you want to use (= allocate) portions of this RAM, you should clear
  72     *  the corresponding bits.
  73     *
  74     *  Possible uses:
  75     *      - z2ram device
  76     *      - SCSI DMA bounce buffers
  77     *
  78     *  FIXME: use the normal resource management
  79     */
  80
  81DECLARE_BITMAP(zorro_unused_z2ram, 128);
  82EXPORT_SYMBOL(zorro_unused_z2ram);
  83
  84
  85static void __init mark_region(unsigned long start, unsigned long end,
  86                               int flag)
  87{
  88        if (flag)
  89                start += Z2RAM_CHUNKMASK;
  90        else
  91                end += Z2RAM_CHUNKMASK;
  92        start &= ~Z2RAM_CHUNKMASK;
  93        end &= ~Z2RAM_CHUNKMASK;
  94
  95        if (end <= Z2RAM_START || start >= Z2RAM_END)
  96                return;
  97        start = start < Z2RAM_START ? 0x00000000 : start-Z2RAM_START;
  98        end = end > Z2RAM_END ? Z2RAM_SIZE : end-Z2RAM_START;
  99        while (start < end) {
 100                u32 chunk = start>>Z2RAM_CHUNKSHIFT;
 101                if (flag)
 102                        set_bit(chunk, zorro_unused_z2ram);
 103                else
 104                        clear_bit(chunk, zorro_unused_z2ram);
 105                start += Z2RAM_CHUNKSIZE;
 106        }
 107}
 108
 109
 110static struct resource __init *zorro_find_parent_resource(
 111        struct platform_device *bridge, struct zorro_dev *z)
 112{
 113        int i;
 114
 115        for (i = 0; i < bridge->num_resources; i++) {
 116                struct resource *r = &bridge->resource[i];
 117                if (zorro_resource_start(z) >= r->start &&
 118                    zorro_resource_end(z) <= r->end)
 119                        return r;
 120        }
 121        return &iomem_resource;
 122}
 123
 124
 125
 126static int __init amiga_zorro_probe(struct platform_device *pdev)
 127{
 128        struct zorro_bus *bus;
 129        struct zorro_dev *z;
 130        struct resource *r;
 131        unsigned int i;
 132        int error;
 133
 134        /* Initialize the Zorro bus */
 135        bus = kzalloc(sizeof(*bus), GFP_KERNEL);
 136        if (!bus)
 137                return -ENOMEM;
 138
 139        INIT_LIST_HEAD(&bus->devices);
 140        bus->dev.parent = &pdev->dev;
 141        dev_set_name(&bus->dev, "zorro");
 142        error = device_register(&bus->dev);
 143        if (error) {
 144                pr_err("Zorro: Error registering zorro_bus\n");
 145                put_device(&bus->dev);
 146                kfree(bus);
 147                return error;
 148        }
 149        platform_set_drvdata(pdev, bus);
 150
 151        /* Register all devices */
 152        pr_info("Zorro: Probing AutoConfig expansion devices: %u device%s\n",
 153                 zorro_num_autocon, zorro_num_autocon == 1 ? "" : "s");
 154
 155        for (i = 0; i < zorro_num_autocon; i++) {
 156                z = &zorro_autocon[i];
 157                z->id = (z->rom.er_Manufacturer<<16) | (z->rom.er_Product<<8);
 158                if (z->id == ZORRO_PROD_GVP_EPC_BASE) {
 159                        /* GVP quirk */
 160                        unsigned long magic = zorro_resource_start(z)+0x8000;
 161                        z->id |= *(u16 *)ZTWO_VADDR(magic) & GVP_PRODMASK;
 162                }
 163                sprintf(z->name, "Zorro device %08x", z->id);
 164                zorro_name_device(z);
 165                z->resource.name = z->name;
 166                r = zorro_find_parent_resource(pdev, z);
 167                error = request_resource(r, &z->resource);
 168                if (error)
 169                        dev_err(&bus->dev,
 170                                "Address space collision on device %s %pR\n",
 171                                z->name, &z->resource);
 172                dev_set_name(&z->dev, "%02x", i);
 173                z->dev.parent = &bus->dev;
 174                z->dev.bus = &zorro_bus_type;
 175                error = device_register(&z->dev);
 176                if (error) {
 177                        dev_err(&bus->dev, "Error registering device %s\n",
 178                                z->name);
 179                        put_device(&z->dev);
 180                        continue;
 181                }
 182                error = zorro_create_sysfs_dev_files(z);
 183                if (error)
 184                        dev_err(&z->dev, "Error creating sysfs files\n");
 185        }
 186
 187        /* Mark all available Zorro II memory */
 188        zorro_for_each_dev(z) {
 189                if (z->rom.er_Type & ERTF_MEMLIST)
 190                        mark_region(zorro_resource_start(z),
 191                                    zorro_resource_end(z)+1, 1);
 192        }
 193
 194        /* Unmark all used Zorro II memory */
 195        for (i = 0; i < m68k_num_memory; i++)
 196                if (m68k_memory[i].addr < 16*1024*1024)
 197                        mark_region(m68k_memory[i].addr,
 198                                    m68k_memory[i].addr+m68k_memory[i].size,
 199                                    0);
 200
 201        return 0;
 202}
 203
 204static struct platform_driver amiga_zorro_driver = {
 205        .driver   = {
 206                .name   = "amiga-zorro",
 207                .owner  = THIS_MODULE,
 208        },
 209};
 210
 211static int __init amiga_zorro_init(void)
 212{
 213        return platform_driver_probe(&amiga_zorro_driver, amiga_zorro_probe);
 214}
 215
 216module_init(amiga_zorro_init);
 217
 218MODULE_LICENSE("GPL");
 219