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 * 7 */ 8 9 #include <linux/pnp.h> 10 #include <linux/device.h> 11 #include <linux/init.h> 12 #include <linux/slab.h> 13 #include <linux/kernel.h> 14 #include <linux/ioport.h> 15 16 static const struct pnp_device_id pnp_dev_table[] = { 17 /* General ID for reserving resources */ 18 { "PNP0c02", 0 }, 19 /* memory controller */ 20 { "PNP0c01", 0 }, 21 { "", 0 } 22 }; 23 24 static void reserve_ioport_range(char *pnpid, int start, int end) 25 { 26 struct resource *res; 27 char *regionid; 28 29 regionid = kmalloc(16, GFP_KERNEL); 30 if ( regionid == NULL ) 31 return; 32 snprintf(regionid, 16, "pnp %s", pnpid); 33 res = request_region(start,end-start+1,regionid); 34 if ( res == NULL ) 35 kfree( regionid ); 36 else 37 res->flags &= ~IORESOURCE_BUSY; 38 /* 39 * Failures at this point are usually harmless. pci quirks for 40 * example do reserve stuff they know about too, so we may well 41 * have double reservations. 42 */ 43 printk(KERN_INFO 44 "pnp: %s: ioport range 0x%x-0x%x %s reserved\n", 45 pnpid, start, end, 46 NULL != res ? "has been" : "could not be" 47 ); 48 49 return; 50 } 51 52 static void reserve_resources_of_dev( struct pnp_dev *dev ) 53 { 54 int i; 55 56 for (i=0;i<PNP_MAX_PORT;i++) { 57 if (!pnp_port_valid(dev, i)) 58 /* end of resources */ 59 continue; 60 if (pnp_port_start(dev, i) == 0) 61 /* disabled */ 62 /* Do nothing */ 63 continue; 64 if (pnp_port_start(dev, i) < 0x100) 65 /* 66 * Below 0x100 is only standard PC hardware 67 * (pics, kbd, timer, dma, ...) 68 * We should not get resource conflicts there, 69 * and the kernel reserves these anyway 70 * (see arch/i386/kernel/setup.c). 71 * So, do nothing 72 */ 73 continue; 74 if (pnp_port_end(dev, i) < pnp_port_start(dev, i)) 75 /* invalid endpoint */ 76 /* Do nothing */ 77 continue; 78 reserve_ioport_range( 79 dev->dev.bus_id, 80 pnp_port_start(dev, i), 81 pnp_port_end(dev, i) 82 ); 83 } 84 85 return; 86 } 87 88 static int system_pnp_probe(struct pnp_dev * dev, const struct pnp_device_id *dev_id) 89 { 90 reserve_resources_of_dev(dev); 91 return 0; 92 } 93 94 static struct pnp_driver system_pnp_driver = { 95 .name = "system", 96 .id_table = pnp_dev_table, 97 .flags = PNP_DRIVER_RES_DO_NOT_CHANGE, 98 .probe = system_pnp_probe, 99 .remove = NULL, 100 }; 101 102 static int __init pnp_system_init(void) 103 { 104 return pnp_register_driver(&system_pnp_driver); 105 } 106 107 /** 108 * Reserve motherboard resources after PCI claim BARs, 109 * but before PCI assign resources for uninitialized PCI devices 110 */ 111 fs_initcall(pnp_system_init); 112