0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #include <linux/pnp.h>
0012 #include <linux/device.h>
0013 #include <linux/init.h>
0014 #include <linux/slab.h>
0015 #include <linux/kernel.h>
0016 #include <linux/ioport.h>
0017
0018 static const struct pnp_device_id pnp_dev_table[] = {
0019
0020 {"PNP0c02", 0},
0021
0022 {"PNP0c01", 0},
0023 {"", 0}
0024 };
0025
0026 static void reserve_range(struct pnp_dev *dev, struct resource *r, int port)
0027 {
0028 char *regionid;
0029 const char *pnpid = dev_name(&dev->dev);
0030 resource_size_t start = r->start, end = r->end;
0031 struct resource *res;
0032
0033 regionid = kmalloc(16, GFP_KERNEL);
0034 if (!regionid)
0035 return;
0036
0037 snprintf(regionid, 16, "pnp %s", pnpid);
0038 if (port)
0039 res = request_region(start, end - start + 1, regionid);
0040 else
0041 res = request_mem_region(start, end - start + 1, regionid);
0042 if (res)
0043 res->flags &= ~IORESOURCE_BUSY;
0044 else
0045 kfree(regionid);
0046
0047
0048
0049
0050
0051
0052 dev_info(&dev->dev, "%pR %s reserved\n", r,
0053 res ? "has been" : "could not be");
0054 }
0055
0056 static void reserve_resources_of_dev(struct pnp_dev *dev)
0057 {
0058 struct resource *res;
0059 int i;
0060
0061 for (i = 0; (res = pnp_get_resource(dev, IORESOURCE_IO, i)); i++) {
0062 if (res->flags & IORESOURCE_DISABLED)
0063 continue;
0064 if (res->start == 0)
0065 continue;
0066 if (res->start < 0x100)
0067
0068
0069
0070
0071
0072
0073
0074
0075 continue;
0076 if (res->end < res->start)
0077 continue;
0078
0079 reserve_range(dev, res, 1);
0080 }
0081
0082 for (i = 0; (res = pnp_get_resource(dev, IORESOURCE_MEM, i)); i++) {
0083 if (res->flags & IORESOURCE_DISABLED)
0084 continue;
0085
0086 reserve_range(dev, res, 0);
0087 }
0088 }
0089
0090 static int system_pnp_probe(struct pnp_dev *dev,
0091 const struct pnp_device_id *dev_id)
0092 {
0093 reserve_resources_of_dev(dev);
0094 return 0;
0095 }
0096
0097 static struct pnp_driver system_pnp_driver = {
0098 .name = "system",
0099 .id_table = pnp_dev_table,
0100 .flags = PNP_DRIVER_RES_DO_NOT_CHANGE,
0101 .probe = system_pnp_probe,
0102 };
0103
0104 static int __init pnp_system_init(void)
0105 {
0106 return pnp_register_driver(&system_pnp_driver);
0107 }
0108
0109
0110
0111
0112
0113 fs_initcall(pnp_system_init);