Blame view

drivers/pnp/system.c 2.66 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
2
3
4
5
  /*
   * system.c - a driver for reserving pnp system resources
   *
   * Some code is based on pnpbios_core.c
   * Copyright 2002 Adam Belay <ambx1@neo.rr.com>
a8c78f7fb   Bjorn Helgaas   PNP: reserve syst...
6
7
   * (c) Copyright 2007 Hewlett-Packard Development Company, L.P.
   *	Bjorn Helgaas <bjorn.helgaas@hp.com>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
8
9
10
11
12
13
14
15
16
17
18
   */
  
  #include <linux/pnp.h>
  #include <linux/device.h>
  #include <linux/init.h>
  #include <linux/slab.h>
  #include <linux/kernel.h>
  #include <linux/ioport.h>
  
  static const struct pnp_device_id pnp_dev_table[] = {
  	/* General ID for reserving resources */
9dd78466c   Bjorn Helgaas   PNP: Lindent all ...
19
  	{"PNP0c02", 0},
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
20
  	/* memory controller */
9dd78466c   Bjorn Helgaas   PNP: Lindent all ...
21
22
  	{"PNP0c01", 0},
  	{"", 0}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
23
  };
9a007b379   Bjorn Helgaas   PNP: print resour...
24
  static void reserve_range(struct pnp_dev *dev, struct resource *r, int port)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
25
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
26
  	char *regionid;
c85e37c51   Kay Sievers   pnp: struct devic...
27
  	const char *pnpid = dev_name(&dev->dev);
9a007b379   Bjorn Helgaas   PNP: print resour...
28
  	resource_size_t start = r->start, end = r->end;
0294112ee   Rafael J. Wysocki   ACPI / PNP: Reser...
29
  	struct resource *res;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
30
31
  
  	regionid = kmalloc(16, GFP_KERNEL);
b933e19d3   Bjorn Helgaas   PNP: use dev_info...
32
  	if (!regionid)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
33
  		return;
b933e19d3   Bjorn Helgaas   PNP: use dev_info...
34

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
35
  	snprintf(regionid, 16, "pnp %s", pnpid);
0294112ee   Rafael J. Wysocki   ACPI / PNP: Reser...
36
37
38
39
40
41
42
  	if (port)
  		res = request_region(start, end - start + 1, regionid);
  	else
  		res = request_mem_region(start, end - start + 1, regionid);
  	if (res)
  		res->flags &= ~IORESOURCE_BUSY;
  	else
b933e19d3   Bjorn Helgaas   PNP: use dev_info...
43
  		kfree(regionid);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
44
45
46
47
48
  	/*
  	 * Failures at this point are usually harmless. pci quirks for
  	 * example do reserve stuff they know about too, so we may well
  	 * have double reservations.
  	 */
c7dabef8a   Bjorn Helgaas   vsprintf: use %pR...
49
50
  	dev_info(&dev->dev, "%pR %s reserved
  ", r,
0294112ee   Rafael J. Wysocki   ACPI / PNP: Reser...
51
  		 res ? "has been" : "could not be");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
52
  }
b933e19d3   Bjorn Helgaas   PNP: use dev_info...
53
  static void reserve_resources_of_dev(struct pnp_dev *dev)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
54
  {
95ab3669f   Bjorn Helgaas   PNP: remove PNP_M...
55
  	struct resource *res;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
56
  	int i;
95ab3669f   Bjorn Helgaas   PNP: remove PNP_M...
57
  	for (i = 0; (res = pnp_get_resource(dev, IORESOURCE_IO, i)); i++) {
aee3ad815   Bjorn Helgaas   PNP: replace pnp_...
58
  		if (res->flags & IORESOURCE_DISABLED)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
59
  			continue;
95ab3669f   Bjorn Helgaas   PNP: remove PNP_M...
60
  		if (res->start == 0)
5859554c3   Bjorn Helgaas   PNP: system.c whi...
61
  			continue;	/* disabled */
95ab3669f   Bjorn Helgaas   PNP: remove PNP_M...
62
  		if (res->start < 0x100)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
63
64
65
66
67
68
69
70
71
  			/*
  			 * Below 0x100 is only standard PC hardware
  			 * (pics, kbd, timer, dma, ...)
  			 * We should not get resource conflicts there,
  			 * and the kernel reserves these anyway
  			 * (see arch/i386/kernel/setup.c).
  			 * So, do nothing
  			 */
  			continue;
95ab3669f   Bjorn Helgaas   PNP: remove PNP_M...
72
  		if (res->end < res->start)
5859554c3   Bjorn Helgaas   PNP: system.c whi...
73
  			continue;	/* invalid */
9a007b379   Bjorn Helgaas   PNP: print resour...
74
  		reserve_range(dev, res, 1);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
75
  	}
95ab3669f   Bjorn Helgaas   PNP: remove PNP_M...
76
  	for (i = 0; (res = pnp_get_resource(dev, IORESOURCE_MEM, i)); i++) {
aee3ad815   Bjorn Helgaas   PNP: replace pnp_...
77
  		if (res->flags & IORESOURCE_DISABLED)
a8c78f7fb   Bjorn Helgaas   PNP: reserve syst...
78
  			continue;
9a007b379   Bjorn Helgaas   PNP: print resour...
79
  		reserve_range(dev, res, 0);
a8c78f7fb   Bjorn Helgaas   PNP: reserve syst...
80
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
81
  }
9dd78466c   Bjorn Helgaas   PNP: Lindent all ...
82
83
  static int system_pnp_probe(struct pnp_dev *dev,
  			    const struct pnp_device_id *dev_id)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
84
85
86
87
88
89
  {
  	reserve_resources_of_dev(dev);
  	return 0;
  }
  
  static struct pnp_driver system_pnp_driver = {
07d4e9af1   Bjorn Helgaas   PNP: fix up after...
90
  	.name     = "system",
9dd78466c   Bjorn Helgaas   PNP: Lindent all ...
91
  	.id_table = pnp_dev_table,
07d4e9af1   Bjorn Helgaas   PNP: fix up after...
92
93
  	.flags    = PNP_DRIVER_RES_DO_NOT_CHANGE,
  	.probe    = system_pnp_probe,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
94
95
96
97
98
99
100
101
102
103
104
105
  };
  
  static int __init pnp_system_init(void)
  {
  	return pnp_register_driver(&system_pnp_driver);
  }
  
  /**
   * Reserve motherboard resources after PCI claim BARs,
   * but before PCI assign resources for uninitialized PCI devices
   */
  fs_initcall(pnp_system_init);