diff options
Diffstat (limited to 'drivers/pnp')
-rw-r--r-- | drivers/pnp/interface.c | 105 | ||||
-rw-r--r-- | drivers/pnp/manager.c | 25 | ||||
-rw-r--r-- | drivers/pnp/pnpacpi/core.c | 10 | ||||
-rw-r--r-- | drivers/pnp/pnpbios/Kconfig | 4 |
4 files changed, 96 insertions, 48 deletions
diff --git a/drivers/pnp/interface.c b/drivers/pnp/interface.c index cfaf5b73540b..0c201317284b 100644 --- a/drivers/pnp/interface.c +++ b/drivers/pnp/interface.c | |||
@@ -298,6 +298,39 @@ static ssize_t pnp_show_current_resources(struct device *dmdev, | |||
298 | return ret; | 298 | return ret; |
299 | } | 299 | } |
300 | 300 | ||
301 | static char *pnp_get_resource_value(char *buf, | ||
302 | unsigned long type, | ||
303 | resource_size_t *start, | ||
304 | resource_size_t *end, | ||
305 | unsigned long *flags) | ||
306 | { | ||
307 | if (start) | ||
308 | *start = 0; | ||
309 | if (end) | ||
310 | *end = 0; | ||
311 | if (flags) | ||
312 | *flags = 0; | ||
313 | |||
314 | /* TBD: allow for disabled resources */ | ||
315 | |||
316 | buf = skip_spaces(buf); | ||
317 | if (start) { | ||
318 | *start = simple_strtoull(buf, &buf, 0); | ||
319 | if (end) { | ||
320 | buf = skip_spaces(buf); | ||
321 | if (*buf == '-') { | ||
322 | buf = skip_spaces(buf + 1); | ||
323 | *end = simple_strtoull(buf, &buf, 0); | ||
324 | } else | ||
325 | *end = *start; | ||
326 | } | ||
327 | } | ||
328 | |||
329 | /* TBD: allow for additional flags, e.g., IORESOURCE_WINDOW */ | ||
330 | |||
331 | return buf; | ||
332 | } | ||
333 | |||
301 | static ssize_t pnp_set_current_resources(struct device *dmdev, | 334 | static ssize_t pnp_set_current_resources(struct device *dmdev, |
302 | struct device_attribute *attr, | 335 | struct device_attribute *attr, |
303 | const char *ubuf, size_t count) | 336 | const char *ubuf, size_t count) |
@@ -305,7 +338,6 @@ static ssize_t pnp_set_current_resources(struct device *dmdev, | |||
305 | struct pnp_dev *dev = to_pnp_dev(dmdev); | 338 | struct pnp_dev *dev = to_pnp_dev(dmdev); |
306 | char *buf = (void *)ubuf; | 339 | char *buf = (void *)ubuf; |
307 | int retval = 0; | 340 | int retval = 0; |
308 | resource_size_t start, end; | ||
309 | 341 | ||
310 | if (dev->status & PNP_ATTACHED) { | 342 | if (dev->status & PNP_ATTACHED) { |
311 | retval = -EBUSY; | 343 | retval = -EBUSY; |
@@ -349,6 +381,10 @@ static ssize_t pnp_set_current_resources(struct device *dmdev, | |||
349 | goto done; | 381 | goto done; |
350 | } | 382 | } |
351 | if (!strnicmp(buf, "set", 3)) { | 383 | if (!strnicmp(buf, "set", 3)) { |
384 | resource_size_t start; | ||
385 | resource_size_t end; | ||
386 | unsigned long flags; | ||
387 | |||
352 | if (dev->active) | 388 | if (dev->active) |
353 | goto done; | 389 | goto done; |
354 | buf += 3; | 390 | buf += 3; |
@@ -357,42 +393,37 @@ static ssize_t pnp_set_current_resources(struct device *dmdev, | |||
357 | while (1) { | 393 | while (1) { |
358 | buf = skip_spaces(buf); | 394 | buf = skip_spaces(buf); |
359 | if (!strnicmp(buf, "io", 2)) { | 395 | if (!strnicmp(buf, "io", 2)) { |
360 | buf = skip_spaces(buf + 2); | 396 | buf = pnp_get_resource_value(buf + 2, |
361 | start = simple_strtoul(buf, &buf, 0); | 397 | IORESOURCE_IO, |
362 | buf = skip_spaces(buf); | 398 | &start, &end, |
363 | if (*buf == '-') { | 399 | &flags); |
364 | buf = skip_spaces(buf + 1); | 400 | pnp_add_io_resource(dev, start, end, flags); |
365 | end = simple_strtoul(buf, &buf, 0); | 401 | } else if (!strnicmp(buf, "mem", 3)) { |
366 | } else | 402 | buf = pnp_get_resource_value(buf + 3, |
367 | end = start; | 403 | IORESOURCE_MEM, |
368 | pnp_add_io_resource(dev, start, end, 0); | 404 | &start, &end, |
369 | continue; | 405 | &flags); |
370 | } | 406 | pnp_add_mem_resource(dev, start, end, flags); |
371 | if (!strnicmp(buf, "mem", 3)) { | 407 | } else if (!strnicmp(buf, "irq", 3)) { |
372 | buf = skip_spaces(buf + 3); | 408 | buf = pnp_get_resource_value(buf + 3, |
373 | start = simple_strtoul(buf, &buf, 0); | 409 | IORESOURCE_IRQ, |
374 | buf = skip_spaces(buf); | 410 | &start, NULL, |
375 | if (*buf == '-') { | 411 | &flags); |
376 | buf = skip_spaces(buf + 1); | 412 | pnp_add_irq_resource(dev, start, flags); |
377 | end = simple_strtoul(buf, &buf, 0); | 413 | } else if (!strnicmp(buf, "dma", 3)) { |
378 | } else | 414 | buf = pnp_get_resource_value(buf + 3, |
379 | end = start; | 415 | IORESOURCE_DMA, |
380 | pnp_add_mem_resource(dev, start, end, 0); | 416 | &start, NULL, |
381 | continue; | 417 | &flags); |
382 | } | 418 | pnp_add_dma_resource(dev, start, flags); |
383 | if (!strnicmp(buf, "irq", 3)) { | 419 | } else if (!strnicmp(buf, "bus", 3)) { |
384 | buf = skip_spaces(buf + 3); | 420 | buf = pnp_get_resource_value(buf + 3, |
385 | start = simple_strtoul(buf, &buf, 0); | 421 | IORESOURCE_BUS, |
386 | pnp_add_irq_resource(dev, start, 0); | 422 | &start, &end, |
387 | continue; | 423 | NULL); |
388 | } | 424 | pnp_add_bus_resource(dev, start, end); |
389 | if (!strnicmp(buf, "dma", 3)) { | 425 | } else |
390 | buf = skip_spaces(buf + 3); | 426 | break; |
391 | start = simple_strtoul(buf, &buf, 0); | ||
392 | pnp_add_dma_resource(dev, start, 0); | ||
393 | continue; | ||
394 | } | ||
395 | break; | ||
396 | } | 427 | } |
397 | mutex_unlock(&pnp_res_mutex); | 428 | mutex_unlock(&pnp_res_mutex); |
398 | goto done; | 429 | goto done; |
diff --git a/drivers/pnp/manager.c b/drivers/pnp/manager.c index ed9ce507149a..95cebf0185de 100644 --- a/drivers/pnp/manager.c +++ b/drivers/pnp/manager.c | |||
@@ -18,11 +18,27 @@ | |||
18 | 18 | ||
19 | DEFINE_MUTEX(pnp_res_mutex); | 19 | DEFINE_MUTEX(pnp_res_mutex); |
20 | 20 | ||
21 | static struct resource *pnp_find_resource(struct pnp_dev *dev, | ||
22 | unsigned char rule, | ||
23 | unsigned long type, | ||
24 | unsigned int bar) | ||
25 | { | ||
26 | struct resource *res = pnp_get_resource(dev, type, bar); | ||
27 | |||
28 | /* when the resource already exists, set its resource bits from rule */ | ||
29 | if (res) { | ||
30 | res->flags &= ~IORESOURCE_BITS; | ||
31 | res->flags |= rule & IORESOURCE_BITS; | ||
32 | } | ||
33 | |||
34 | return res; | ||
35 | } | ||
36 | |||
21 | static int pnp_assign_port(struct pnp_dev *dev, struct pnp_port *rule, int idx) | 37 | static int pnp_assign_port(struct pnp_dev *dev, struct pnp_port *rule, int idx) |
22 | { | 38 | { |
23 | struct resource *res, local_res; | 39 | struct resource *res, local_res; |
24 | 40 | ||
25 | res = pnp_get_resource(dev, IORESOURCE_IO, idx); | 41 | res = pnp_find_resource(dev, rule->flags, IORESOURCE_IO, idx); |
26 | if (res) { | 42 | if (res) { |
27 | pnp_dbg(&dev->dev, " io %d already set to %#llx-%#llx " | 43 | pnp_dbg(&dev->dev, " io %d already set to %#llx-%#llx " |
28 | "flags %#lx\n", idx, (unsigned long long) res->start, | 44 | "flags %#lx\n", idx, (unsigned long long) res->start, |
@@ -65,7 +81,7 @@ static int pnp_assign_mem(struct pnp_dev *dev, struct pnp_mem *rule, int idx) | |||
65 | { | 81 | { |
66 | struct resource *res, local_res; | 82 | struct resource *res, local_res; |
67 | 83 | ||
68 | res = pnp_get_resource(dev, IORESOURCE_MEM, idx); | 84 | res = pnp_find_resource(dev, rule->flags, IORESOURCE_MEM, idx); |
69 | if (res) { | 85 | if (res) { |
70 | pnp_dbg(&dev->dev, " mem %d already set to %#llx-%#llx " | 86 | pnp_dbg(&dev->dev, " mem %d already set to %#llx-%#llx " |
71 | "flags %#lx\n", idx, (unsigned long long) res->start, | 87 | "flags %#lx\n", idx, (unsigned long long) res->start, |
@@ -78,6 +94,7 @@ static int pnp_assign_mem(struct pnp_dev *dev, struct pnp_mem *rule, int idx) | |||
78 | res->start = 0; | 94 | res->start = 0; |
79 | res->end = 0; | 95 | res->end = 0; |
80 | 96 | ||
97 | /* ??? rule->flags restricted to 8 bits, all tests bogus ??? */ | ||
81 | if (!(rule->flags & IORESOURCE_MEM_WRITEABLE)) | 98 | if (!(rule->flags & IORESOURCE_MEM_WRITEABLE)) |
82 | res->flags |= IORESOURCE_READONLY; | 99 | res->flags |= IORESOURCE_READONLY; |
83 | if (rule->flags & IORESOURCE_MEM_CACHEABLE) | 100 | if (rule->flags & IORESOURCE_MEM_CACHEABLE) |
@@ -123,7 +140,7 @@ static int pnp_assign_irq(struct pnp_dev *dev, struct pnp_irq *rule, int idx) | |||
123 | 5, 10, 11, 12, 9, 14, 15, 7, 3, 4, 13, 0, 1, 6, 8, 2 | 140 | 5, 10, 11, 12, 9, 14, 15, 7, 3, 4, 13, 0, 1, 6, 8, 2 |
124 | }; | 141 | }; |
125 | 142 | ||
126 | res = pnp_get_resource(dev, IORESOURCE_IRQ, idx); | 143 | res = pnp_find_resource(dev, rule->flags, IORESOURCE_IRQ, idx); |
127 | if (res) { | 144 | if (res) { |
128 | pnp_dbg(&dev->dev, " irq %d already set to %d flags %#lx\n", | 145 | pnp_dbg(&dev->dev, " irq %d already set to %d flags %#lx\n", |
129 | idx, (int) res->start, res->flags); | 146 | idx, (int) res->start, res->flags); |
@@ -182,7 +199,7 @@ static int pnp_assign_dma(struct pnp_dev *dev, struct pnp_dma *rule, int idx) | |||
182 | 1, 3, 5, 6, 7, 0, 2, 4 | 199 | 1, 3, 5, 6, 7, 0, 2, 4 |
183 | }; | 200 | }; |
184 | 201 | ||
185 | res = pnp_get_resource(dev, IORESOURCE_DMA, idx); | 202 | res = pnp_find_resource(dev, rule->flags, IORESOURCE_DMA, idx); |
186 | if (res) { | 203 | if (res) { |
187 | pnp_dbg(&dev->dev, " dma %d already set to %d flags %#lx\n", | 204 | pnp_dbg(&dev->dev, " dma %d already set to %d flags %#lx\n", |
188 | idx, (int) res->start, res->flags); | 205 | idx, (int) res->start, res->flags); |
diff --git a/drivers/pnp/pnpacpi/core.c b/drivers/pnp/pnpacpi/core.c index 72e822e17d47..8813fc03aa09 100644 --- a/drivers/pnp/pnpacpi/core.c +++ b/drivers/pnp/pnpacpi/core.c | |||
@@ -90,7 +90,7 @@ static int pnpacpi_set_resources(struct pnp_dev *dev) | |||
90 | pnp_dbg(&dev->dev, "set resources\n"); | 90 | pnp_dbg(&dev->dev, "set resources\n"); |
91 | 91 | ||
92 | handle = DEVICE_ACPI_HANDLE(&dev->dev); | 92 | handle = DEVICE_ACPI_HANDLE(&dev->dev); |
93 | if (!handle || ACPI_FAILURE(acpi_bus_get_device(handle, &acpi_dev))) { | 93 | if (!handle || acpi_bus_get_device(handle, &acpi_dev)) { |
94 | dev_dbg(&dev->dev, "ACPI device not found in %s!\n", __func__); | 94 | dev_dbg(&dev->dev, "ACPI device not found in %s!\n", __func__); |
95 | return -ENODEV; | 95 | return -ENODEV; |
96 | } | 96 | } |
@@ -123,7 +123,7 @@ static int pnpacpi_disable_resources(struct pnp_dev *dev) | |||
123 | dev_dbg(&dev->dev, "disable resources\n"); | 123 | dev_dbg(&dev->dev, "disable resources\n"); |
124 | 124 | ||
125 | handle = DEVICE_ACPI_HANDLE(&dev->dev); | 125 | handle = DEVICE_ACPI_HANDLE(&dev->dev); |
126 | if (!handle || ACPI_FAILURE(acpi_bus_get_device(handle, &acpi_dev))) { | 126 | if (!handle || acpi_bus_get_device(handle, &acpi_dev)) { |
127 | dev_dbg(&dev->dev, "ACPI device not found in %s!\n", __func__); | 127 | dev_dbg(&dev->dev, "ACPI device not found in %s!\n", __func__); |
128 | return 0; | 128 | return 0; |
129 | } | 129 | } |
@@ -145,7 +145,7 @@ static bool pnpacpi_can_wakeup(struct pnp_dev *dev) | |||
145 | acpi_handle handle; | 145 | acpi_handle handle; |
146 | 146 | ||
147 | handle = DEVICE_ACPI_HANDLE(&dev->dev); | 147 | handle = DEVICE_ACPI_HANDLE(&dev->dev); |
148 | if (!handle || ACPI_FAILURE(acpi_bus_get_device(handle, &acpi_dev))) { | 148 | if (!handle || acpi_bus_get_device(handle, &acpi_dev)) { |
149 | dev_dbg(&dev->dev, "ACPI device not found in %s!\n", __func__); | 149 | dev_dbg(&dev->dev, "ACPI device not found in %s!\n", __func__); |
150 | return false; | 150 | return false; |
151 | } | 151 | } |
@@ -160,7 +160,7 @@ static int pnpacpi_suspend(struct pnp_dev *dev, pm_message_t state) | |||
160 | int error = 0; | 160 | int error = 0; |
161 | 161 | ||
162 | handle = DEVICE_ACPI_HANDLE(&dev->dev); | 162 | handle = DEVICE_ACPI_HANDLE(&dev->dev); |
163 | if (!handle || ACPI_FAILURE(acpi_bus_get_device(handle, &acpi_dev))) { | 163 | if (!handle || acpi_bus_get_device(handle, &acpi_dev)) { |
164 | dev_dbg(&dev->dev, "ACPI device not found in %s!\n", __func__); | 164 | dev_dbg(&dev->dev, "ACPI device not found in %s!\n", __func__); |
165 | return 0; | 165 | return 0; |
166 | } | 166 | } |
@@ -197,7 +197,7 @@ static int pnpacpi_resume(struct pnp_dev *dev) | |||
197 | acpi_handle handle = DEVICE_ACPI_HANDLE(&dev->dev); | 197 | acpi_handle handle = DEVICE_ACPI_HANDLE(&dev->dev); |
198 | int error = 0; | 198 | int error = 0; |
199 | 199 | ||
200 | if (!handle || ACPI_FAILURE(acpi_bus_get_device(handle, &acpi_dev))) { | 200 | if (!handle || acpi_bus_get_device(handle, &acpi_dev)) { |
201 | dev_dbg(&dev->dev, "ACPI device not found in %s!\n", __func__); | 201 | dev_dbg(&dev->dev, "ACPI device not found in %s!\n", __func__); |
202 | return -ENODEV; | 202 | return -ENODEV; |
203 | } | 203 | } |
diff --git a/drivers/pnp/pnpbios/Kconfig b/drivers/pnp/pnpbios/Kconfig index b986d9fa3b9a..50c3dd065e03 100644 --- a/drivers/pnp/pnpbios/Kconfig +++ b/drivers/pnp/pnpbios/Kconfig | |||
@@ -2,8 +2,8 @@ | |||
2 | # Plug and Play BIOS configuration | 2 | # Plug and Play BIOS configuration |
3 | # | 3 | # |
4 | config PNPBIOS | 4 | config PNPBIOS |
5 | bool "Plug and Play BIOS support (EXPERIMENTAL)" | 5 | bool "Plug and Play BIOS support" |
6 | depends on ISA && X86 && EXPERIMENTAL | 6 | depends on ISA && X86 |
7 | default n | 7 | default n |
8 | ---help--- | 8 | ---help--- |
9 | Linux uses the PNPBIOS as defined in "Plug and Play BIOS | 9 | Linux uses the PNPBIOS as defined in "Plug and Play BIOS |