linux/drivers/base/isa.c
<<
>>
Prefs
   1/*
   2 * ISA bus.
   3 */
   4
   5#include <linux/device.h>
   6#include <linux/kernel.h>
   7#include <linux/slab.h>
   8#include <linux/module.h>
   9#include <linux/init.h>
  10#include <linux/dma-mapping.h>
  11#include <linux/isa.h>
  12
  13static struct device isa_bus = {
  14        .bus_id         = "isa"
  15};
  16
  17struct isa_dev {
  18        struct device dev;
  19        struct device *next;
  20        unsigned int id;
  21};
  22
  23#define to_isa_dev(x) container_of((x), struct isa_dev, dev)
  24
  25static int isa_bus_match(struct device *dev, struct device_driver *driver)
  26{
  27        struct isa_driver *isa_driver = to_isa_driver(driver);
  28
  29        if (dev->platform_data == isa_driver) {
  30                if (!isa_driver->match ||
  31                        isa_driver->match(dev, to_isa_dev(dev)->id))
  32                        return 1;
  33                dev->platform_data = NULL;
  34        }
  35        return 0;
  36}
  37
  38static int isa_bus_probe(struct device *dev)
  39{
  40        struct isa_driver *isa_driver = dev->platform_data;
  41
  42        if (isa_driver->probe)
  43                return isa_driver->probe(dev, to_isa_dev(dev)->id);
  44
  45        return 0;
  46}
  47
  48static int isa_bus_remove(struct device *dev)
  49{
  50        struct isa_driver *isa_driver = dev->platform_data;
  51
  52        if (isa_driver->remove)
  53                return isa_driver->remove(dev, to_isa_dev(dev)->id);
  54
  55        return 0;
  56}
  57
  58static void isa_bus_shutdown(struct device *dev)
  59{
  60        struct isa_driver *isa_driver = dev->platform_data;
  61
  62        if (isa_driver->shutdown)
  63                isa_driver->shutdown(dev, to_isa_dev(dev)->id);
  64}
  65
  66static int isa_bus_suspend(struct device *dev, pm_message_t state)
  67{
  68        struct isa_driver *isa_driver = dev->platform_data;
  69
  70        if (isa_driver->suspend)
  71                return isa_driver->suspend(dev, to_isa_dev(dev)->id, state);
  72
  73        return 0;
  74}
  75
  76static int isa_bus_resume(struct device *dev)
  77{
  78        struct isa_driver *isa_driver = dev->platform_data;
  79
  80        if (isa_driver->resume)
  81                return isa_driver->resume(dev, to_isa_dev(dev)->id);
  82
  83        return 0;
  84}
  85
  86static struct bus_type isa_bus_type = {
  87        .name           = "isa",
  88        .match          = isa_bus_match,
  89        .probe          = isa_bus_probe,
  90        .remove         = isa_bus_remove,
  91        .shutdown       = isa_bus_shutdown,
  92        .suspend        = isa_bus_suspend,
  93        .resume         = isa_bus_resume
  94};
  95
  96static void isa_dev_release(struct device *dev)
  97{
  98        kfree(to_isa_dev(dev));
  99}
 100
 101void isa_unregister_driver(struct isa_driver *isa_driver)
 102{
 103        struct device *dev = isa_driver->devices;
 104
 105        while (dev) {
 106                struct device *tmp = to_isa_dev(dev)->next;
 107                device_unregister(dev);
 108                dev = tmp;
 109        }
 110        driver_unregister(&isa_driver->driver);
 111}
 112EXPORT_SYMBOL_GPL(isa_unregister_driver);
 113
 114int isa_register_driver(struct isa_driver *isa_driver, unsigned int ndev)
 115{
 116        int error;
 117        unsigned int id;
 118
 119        isa_driver->driver.bus  = &isa_bus_type;
 120        isa_driver->devices     = NULL;
 121
 122        error = driver_register(&isa_driver->driver);
 123        if (error)
 124                return error;
 125
 126        for (id = 0; id < ndev; id++) {
 127                struct isa_dev *isa_dev;
 128
 129                isa_dev = kzalloc(sizeof *isa_dev, GFP_KERNEL);
 130                if (!isa_dev) {
 131                        error = -ENOMEM;
 132                        break;
 133                }
 134
 135                isa_dev->dev.parent     = &isa_bus;
 136                isa_dev->dev.bus        = &isa_bus_type;
 137
 138                snprintf(isa_dev->dev.bus_id, BUS_ID_SIZE, "%s.%u",
 139                                isa_driver->driver.name, id);
 140
 141                isa_dev->dev.platform_data      = isa_driver;
 142                isa_dev->dev.release            = isa_dev_release;
 143                isa_dev->id                     = id;
 144
 145                isa_dev->dev.coherent_dma_mask = DMA_24BIT_MASK;
 146                isa_dev->dev.dma_mask = &isa_dev->dev.coherent_dma_mask;
 147
 148                error = device_register(&isa_dev->dev);
 149                if (error) {
 150                        put_device(&isa_dev->dev);
 151                        break;
 152                }
 153
 154                if (isa_dev->dev.platform_data) {
 155                        isa_dev->next = isa_driver->devices;
 156                        isa_driver->devices = &isa_dev->dev;
 157                } else
 158                        device_unregister(&isa_dev->dev);
 159        }
 160
 161        if (!error && !isa_driver->devices)
 162                error = -ENODEV;
 163
 164        if (error)
 165                isa_unregister_driver(isa_driver);
 166
 167        return error;
 168}
 169EXPORT_SYMBOL_GPL(isa_register_driver);
 170
 171static int __init isa_bus_init(void)
 172{
 173        int error;
 174
 175        error = bus_register(&isa_bus_type);
 176        if (!error) {
 177                error = device_register(&isa_bus);
 178                if (error)
 179                        bus_unregister(&isa_bus_type);
 180        }
 181        return error;
 182}
 183
 184device_initcall(isa_bus_init);
 185
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.