linux/drivers/pnp/system.c
<<
>>
Prefs
   1/*
   2 * system.c - a driver for reserving pnp system resources
   3 *
   4 * Some code is based on pnpbios_core.c
   5 * Copyright 2002 Adam Belay <ambx1@neo.rr.com>
   6 * (c) Copyright 2007 Hewlett-Packard Development Company, L.P.
   7 *      Bjorn Helgaas <bjorn.helgaas@hp.com>
   8 */
   9
  10#include <linux/pnp.h>
  11#include <linux/device.h>
  12#include <linux/init.h>
  13#include <linux/slab.h>
  14#include <linux/kernel.h>
  15#include <linux/ioport.h>
  16
  17static const struct pnp_device_id pnp_dev_table[] = {
  18        /* General ID for reserving resources */
  19        {"PNP0c02", 0},
  20        /* memory controller */
  21        {"PNP0c01", 0},
  22        {"", 0}
  23};
  24
  25static void reserve_range(struct pnp_dev *dev, resource_size_t start,
  26                          resource_size_t end, int port)
  27{
  28        char *regionid;
  29        const char *pnpid = dev->dev.bus_id;
  30        struct resource *res;
  31
  32        regionid = kmalloc(16, GFP_KERNEL);
  33        if (!regionid)
  34                return;
  35
  36        snprintf(regionid, 16, "pnp %s", pnpid);
  37        if (port)
  38                res = request_region(start, end - start + 1, regionid);
  39        else
  40                res = request_mem_region(start, end - start + 1, regionid);
  41        if (res)
  42                res->flags &= ~IORESOURCE_BUSY;
  43        else
  44                kfree(regionid);
  45
  46        /*
  47         * Failures at this point are usually harmless. pci quirks for
  48         * example do reserve stuff they know about too, so we may well
  49         * have double reservations.
  50         */
  51        dev_info(&dev->dev, "%s range 0x%llx-0x%llx %s reserved\n",
  52                port ? "ioport" : "iomem",
  53                (unsigned long long) start, (unsigned long long) end,
  54                res ? "has been" : "could not be");
  55}
  56
  57static void reserve_resources_of_dev(struct pnp_dev *dev)
  58{
  59        struct resource *res;
  60        int i;
  61
  62        for (i = 0; (res = pnp_get_resource(dev, IORESOURCE_IO, i)); i++) {
  63                if (res->flags & IORESOURCE_DISABLED)
  64                        continue;
  65                if (res->start == 0)
  66                        continue;       /* disabled */
  67                if (res->start < 0x100)
  68                        /*
  69                         * Below 0x100 is only standard PC hardware
  70                         * (pics, kbd, timer, dma, ...)
  71                         * We should not get resource conflicts there,
  72                         * and the kernel reserves these anyway
  73                         * (see arch/i386/kernel/setup.c).
  74                         * So, do nothing
  75                         */
  76                        continue;
  77                if (res->end < res->start)
  78                        continue;       /* invalid */
  79
  80                reserve_range(dev, res->start, res->end, 1);
  81        }
  82
  83        for (i = 0; (res = pnp_get_resource(dev, IORESOURCE_MEM, i)); i++) {
  84                if (res->flags & IORESOURCE_DISABLED)
  85                        continue;
  86
  87                reserve_range(dev, res->start, res->end, 0);
  88        }
  89}
  90
  91static int system_pnp_probe(struct pnp_dev *dev,
  92                            const struct pnp_device_id *dev_id)
  93{
  94        reserve_resources_of_dev(dev);
  95        return 0;
  96}
  97
  98static struct pnp_driver system_pnp_driver = {
  99        .name     = "system",
 100        .id_table = pnp_dev_table,
 101        .flags    = PNP_DRIVER_RES_DO_NOT_CHANGE,
 102        .probe    = system_pnp_probe,
 103};
 104
 105static int __init pnp_system_init(void)
 106{
 107        return pnp_register_driver(&system_pnp_driver);
 108}
 109
 110/**
 111 * Reserve motherboard resources after PCI claim BARs,
 112 * but before PCI assign resources for uninitialized PCI devices
 113 */
 114fs_initcall(pnp_system_init);
 115
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.