aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pnp/system.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pnp/system.c')
-rw-r--r--drivers/pnp/system.c35
1 files changed, 26 insertions, 9 deletions
diff --git a/drivers/pnp/system.c b/drivers/pnp/system.c
index 49c1720df59a..515f33882ab8 100644
--- a/drivers/pnp/system.c
+++ b/drivers/pnp/system.c
@@ -7,6 +7,7 @@
7 * Bjorn Helgaas <bjorn.helgaas@hp.com> 7 * Bjorn Helgaas <bjorn.helgaas@hp.com>
8 */ 8 */
9 9
10#include <linux/acpi.h>
10#include <linux/pnp.h> 11#include <linux/pnp.h>
11#include <linux/device.h> 12#include <linux/device.h>
12#include <linux/init.h> 13#include <linux/init.h>
@@ -22,25 +23,41 @@ static const struct pnp_device_id pnp_dev_table[] = {
22 {"", 0} 23 {"", 0}
23}; 24};
24 25
26#ifdef CONFIG_ACPI
27static bool __reserve_range(u64 start, unsigned int length, bool io, char *desc)
28{
29 u8 space_id = io ? ACPI_ADR_SPACE_SYSTEM_IO : ACPI_ADR_SPACE_SYSTEM_MEMORY;
30 return !acpi_reserve_region(start, length, space_id, IORESOURCE_BUSY, desc);
31}
32#else
33static bool __reserve_range(u64 start, unsigned int length, bool io, char *desc)
34{
35 struct resource *res;
36
37 res = io ? request_region(start, length, desc) :
38 request_mem_region(start, length, desc);
39 if (res) {
40 res->flags &= ~IORESOURCE_BUSY;
41 return true;
42 }
43 return false;
44}
45#endif
46
25static void reserve_range(struct pnp_dev *dev, struct resource *r, int port) 47static void reserve_range(struct pnp_dev *dev, struct resource *r, int port)
26{ 48{
27 char *regionid; 49 char *regionid;
28 const char *pnpid = dev_name(&dev->dev); 50 const char *pnpid = dev_name(&dev->dev);
29 resource_size_t start = r->start, end = r->end; 51 resource_size_t start = r->start, end = r->end;
30 struct resource *res; 52 bool reserved;
31 53
32 regionid = kmalloc(16, GFP_KERNEL); 54 regionid = kmalloc(16, GFP_KERNEL);
33 if (!regionid) 55 if (!regionid)
34 return; 56 return;
35 57
36 snprintf(regionid, 16, "pnp %s", pnpid); 58 snprintf(regionid, 16, "pnp %s", pnpid);
37 if (port) 59 reserved = __reserve_range(start, end - start + 1, !!port, regionid);
38 res = request_region(start, end - start + 1, regionid); 60 if (!reserved)
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); 61 kfree(regionid);
45 62
46 /* 63 /*
@@ -49,7 +66,7 @@ static void reserve_range(struct pnp_dev *dev, struct resource *r, int port)
49 * have double reservations. 66 * have double reservations.
50 */ 67 */
51 dev_info(&dev->dev, "%pR %s reserved\n", r, 68 dev_info(&dev->dev, "%pR %s reserved\n", r,
52 res ? "has been" : "could not be"); 69 reserved ? "has been" : "could not be");
53} 70}
54 71
55static void reserve_resources_of_dev(struct pnp_dev *dev) 72static void reserve_resources_of_dev(struct pnp_dev *dev)