diff options
Diffstat (limited to 'drivers/pnp')
-rw-r--r-- | drivers/pnp/driver.c | 12 | ||||
-rw-r--r-- | drivers/pnp/interface.c | 13 | ||||
-rw-r--r-- | drivers/pnp/manager.c | 27 | ||||
-rw-r--r-- | drivers/pnp/pnpacpi/core.c | 2 | ||||
-rw-r--r-- | drivers/pnp/pnpacpi/rsparser.c | 44 | ||||
-rw-r--r-- | drivers/pnp/pnpbios/core.c | 2 | ||||
-rw-r--r-- | drivers/pnp/pnpbios/rsparser.c | 33 | ||||
-rw-r--r-- | drivers/pnp/quirks.c | 43 |
8 files changed, 112 insertions, 64 deletions
diff --git a/drivers/pnp/driver.c b/drivers/pnp/driver.c index a262762c5b88..12a1645a2e43 100644 --- a/drivers/pnp/driver.c +++ b/drivers/pnp/driver.c | |||
@@ -161,8 +161,7 @@ static int pnp_bus_suspend(struct device *dev, pm_message_t state) | |||
161 | return error; | 161 | return error; |
162 | } | 162 | } |
163 | 163 | ||
164 | if (!(pnp_drv->flags & PNP_DRIVER_RES_DO_NOT_CHANGE) && | 164 | if (pnp_can_disable(pnp_dev)) { |
165 | pnp_can_disable(pnp_dev)) { | ||
166 | error = pnp_stop_dev(pnp_dev); | 165 | error = pnp_stop_dev(pnp_dev); |
167 | if (error) | 166 | if (error) |
168 | return error; | 167 | return error; |
@@ -185,14 +184,17 @@ static int pnp_bus_resume(struct device *dev) | |||
185 | if (pnp_dev->protocol && pnp_dev->protocol->resume) | 184 | if (pnp_dev->protocol && pnp_dev->protocol->resume) |
186 | pnp_dev->protocol->resume(pnp_dev); | 185 | pnp_dev->protocol->resume(pnp_dev); |
187 | 186 | ||
188 | if (!(pnp_drv->flags & PNP_DRIVER_RES_DO_NOT_CHANGE)) { | 187 | if (pnp_can_write(pnp_dev)) { |
189 | error = pnp_start_dev(pnp_dev); | 188 | error = pnp_start_dev(pnp_dev); |
190 | if (error) | 189 | if (error) |
191 | return error; | 190 | return error; |
192 | } | 191 | } |
193 | 192 | ||
194 | if (pnp_drv->resume) | 193 | if (pnp_drv->resume) { |
195 | return pnp_drv->resume(pnp_dev); | 194 | error = pnp_drv->resume(pnp_dev); |
195 | if (error) | ||
196 | return error; | ||
197 | } | ||
196 | 198 | ||
197 | return 0; | 199 | return 0; |
198 | } | 200 | } |
diff --git a/drivers/pnp/interface.c b/drivers/pnp/interface.c index 31548044fdde..982658477a58 100644 --- a/drivers/pnp/interface.c +++ b/drivers/pnp/interface.c | |||
@@ -10,9 +10,12 @@ | |||
10 | #include <linux/errno.h> | 10 | #include <linux/errno.h> |
11 | #include <linux/list.h> | 11 | #include <linux/list.h> |
12 | #include <linux/types.h> | 12 | #include <linux/types.h> |
13 | #include <linux/pnp.h> | ||
13 | #include <linux/stat.h> | 14 | #include <linux/stat.h> |
14 | #include <linux/ctype.h> | 15 | #include <linux/ctype.h> |
15 | #include <linux/slab.h> | 16 | #include <linux/slab.h> |
17 | #include <linux/mutex.h> | ||
18 | |||
16 | #include <asm/uaccess.h> | 19 | #include <asm/uaccess.h> |
17 | 20 | ||
18 | #include "base.h" | 21 | #include "base.h" |
@@ -315,8 +318,6 @@ static ssize_t pnp_show_current_resources(struct device *dmdev, | |||
315 | return ret; | 318 | return ret; |
316 | } | 319 | } |
317 | 320 | ||
318 | extern struct semaphore pnp_res_mutex; | ||
319 | |||
320 | static ssize_t | 321 | static ssize_t |
321 | pnp_set_current_resources(struct device *dmdev, struct device_attribute *attr, | 322 | pnp_set_current_resources(struct device *dmdev, struct device_attribute *attr, |
322 | const char *ubuf, size_t count) | 323 | const char *ubuf, size_t count) |
@@ -361,10 +362,10 @@ pnp_set_current_resources(struct device *dmdev, struct device_attribute *attr, | |||
361 | goto done; | 362 | goto done; |
362 | } | 363 | } |
363 | if (!strnicmp(buf, "get", 3)) { | 364 | if (!strnicmp(buf, "get", 3)) { |
364 | down(&pnp_res_mutex); | 365 | mutex_lock(&pnp_res_mutex); |
365 | if (pnp_can_read(dev)) | 366 | if (pnp_can_read(dev)) |
366 | dev->protocol->get(dev, &dev->res); | 367 | dev->protocol->get(dev, &dev->res); |
367 | up(&pnp_res_mutex); | 368 | mutex_unlock(&pnp_res_mutex); |
368 | goto done; | 369 | goto done; |
369 | } | 370 | } |
370 | if (!strnicmp(buf, "set", 3)) { | 371 | if (!strnicmp(buf, "set", 3)) { |
@@ -373,7 +374,7 @@ pnp_set_current_resources(struct device *dmdev, struct device_attribute *attr, | |||
373 | goto done; | 374 | goto done; |
374 | buf += 3; | 375 | buf += 3; |
375 | pnp_init_resource_table(&dev->res); | 376 | pnp_init_resource_table(&dev->res); |
376 | down(&pnp_res_mutex); | 377 | mutex_lock(&pnp_res_mutex); |
377 | while (1) { | 378 | while (1) { |
378 | while (isspace(*buf)) | 379 | while (isspace(*buf)) |
379 | ++buf; | 380 | ++buf; |
@@ -455,7 +456,7 @@ pnp_set_current_resources(struct device *dmdev, struct device_attribute *attr, | |||
455 | } | 456 | } |
456 | break; | 457 | break; |
457 | } | 458 | } |
458 | up(&pnp_res_mutex); | 459 | mutex_unlock(&pnp_res_mutex); |
459 | goto done; | 460 | goto done; |
460 | } | 461 | } |
461 | 462 | ||
diff --git a/drivers/pnp/manager.c b/drivers/pnp/manager.c index c6b3d4e63ccc..c28caf272c11 100644 --- a/drivers/pnp/manager.c +++ b/drivers/pnp/manager.c | |||
@@ -12,9 +12,10 @@ | |||
12 | #include <linux/pnp.h> | 12 | #include <linux/pnp.h> |
13 | #include <linux/slab.h> | 13 | #include <linux/slab.h> |
14 | #include <linux/bitmap.h> | 14 | #include <linux/bitmap.h> |
15 | #include <linux/mutex.h> | ||
15 | #include "base.h" | 16 | #include "base.h" |
16 | 17 | ||
17 | DECLARE_MUTEX(pnp_res_mutex); | 18 | DEFINE_MUTEX(pnp_res_mutex); |
18 | 19 | ||
19 | static int pnp_assign_port(struct pnp_dev *dev, struct pnp_port *rule, int idx) | 20 | static int pnp_assign_port(struct pnp_dev *dev, struct pnp_port *rule, int idx) |
20 | { | 21 | { |
@@ -297,7 +298,7 @@ static int pnp_assign_resources(struct pnp_dev *dev, int depnum) | |||
297 | if (!pnp_can_configure(dev)) | 298 | if (!pnp_can_configure(dev)) |
298 | return -ENODEV; | 299 | return -ENODEV; |
299 | 300 | ||
300 | down(&pnp_res_mutex); | 301 | mutex_lock(&pnp_res_mutex); |
301 | pnp_clean_resource_table(&dev->res); /* start with a fresh slate */ | 302 | pnp_clean_resource_table(&dev->res); /* start with a fresh slate */ |
302 | if (dev->independent) { | 303 | if (dev->independent) { |
303 | port = dev->independent->port; | 304 | port = dev->independent->port; |
@@ -366,12 +367,12 @@ static int pnp_assign_resources(struct pnp_dev *dev, int depnum) | |||
366 | } else if (dev->dependent) | 367 | } else if (dev->dependent) |
367 | goto fail; | 368 | goto fail; |
368 | 369 | ||
369 | up(&pnp_res_mutex); | 370 | mutex_unlock(&pnp_res_mutex); |
370 | return 1; | 371 | return 1; |
371 | 372 | ||
372 | fail: | 373 | fail: |
373 | pnp_clean_resource_table(&dev->res); | 374 | pnp_clean_resource_table(&dev->res); |
374 | up(&pnp_res_mutex); | 375 | mutex_unlock(&pnp_res_mutex); |
375 | return 0; | 376 | return 0; |
376 | } | 377 | } |
377 | 378 | ||
@@ -396,7 +397,7 @@ int pnp_manual_config_dev(struct pnp_dev *dev, struct pnp_resource_table *res, | |||
396 | return -ENOMEM; | 397 | return -ENOMEM; |
397 | *bak = dev->res; | 398 | *bak = dev->res; |
398 | 399 | ||
399 | down(&pnp_res_mutex); | 400 | mutex_lock(&pnp_res_mutex); |
400 | dev->res = *res; | 401 | dev->res = *res; |
401 | if (!(mode & PNP_CONFIG_FORCE)) { | 402 | if (!(mode & PNP_CONFIG_FORCE)) { |
402 | for (i = 0; i < PNP_MAX_PORT; i++) { | 403 | for (i = 0; i < PNP_MAX_PORT; i++) { |
@@ -416,14 +417,14 @@ int pnp_manual_config_dev(struct pnp_dev *dev, struct pnp_resource_table *res, | |||
416 | goto fail; | 417 | goto fail; |
417 | } | 418 | } |
418 | } | 419 | } |
419 | up(&pnp_res_mutex); | 420 | mutex_unlock(&pnp_res_mutex); |
420 | 421 | ||
421 | kfree(bak); | 422 | kfree(bak); |
422 | return 0; | 423 | return 0; |
423 | 424 | ||
424 | fail: | 425 | fail: |
425 | dev->res = *bak; | 426 | dev->res = *bak; |
426 | up(&pnp_res_mutex); | 427 | mutex_unlock(&pnp_res_mutex); |
427 | kfree(bak); | 428 | kfree(bak); |
428 | return -EINVAL; | 429 | return -EINVAL; |
429 | } | 430 | } |
@@ -513,7 +514,7 @@ int pnp_activate_dev(struct pnp_dev *dev) | |||
513 | int error; | 514 | int error; |
514 | 515 | ||
515 | if (dev->active) | 516 | if (dev->active) |
516 | return 0; /* the device is already active */ | 517 | return 0; |
517 | 518 | ||
518 | /* ensure resources are allocated */ | 519 | /* ensure resources are allocated */ |
519 | if (pnp_auto_config_dev(dev)) | 520 | if (pnp_auto_config_dev(dev)) |
@@ -524,7 +525,7 @@ int pnp_activate_dev(struct pnp_dev *dev) | |||
524 | return error; | 525 | return error; |
525 | 526 | ||
526 | dev->active = 1; | 527 | dev->active = 1; |
527 | return 1; | 528 | return 0; |
528 | } | 529 | } |
529 | 530 | ||
530 | /** | 531 | /** |
@@ -538,7 +539,7 @@ int pnp_disable_dev(struct pnp_dev *dev) | |||
538 | int error; | 539 | int error; |
539 | 540 | ||
540 | if (!dev->active) | 541 | if (!dev->active) |
541 | return 0; /* the device is already disabled */ | 542 | return 0; |
542 | 543 | ||
543 | error = pnp_stop_dev(dev); | 544 | error = pnp_stop_dev(dev); |
544 | if (error) | 545 | if (error) |
@@ -547,11 +548,11 @@ int pnp_disable_dev(struct pnp_dev *dev) | |||
547 | dev->active = 0; | 548 | dev->active = 0; |
548 | 549 | ||
549 | /* release the resources so that other devices can use them */ | 550 | /* release the resources so that other devices can use them */ |
550 | down(&pnp_res_mutex); | 551 | mutex_lock(&pnp_res_mutex); |
551 | pnp_clean_resource_table(&dev->res); | 552 | pnp_clean_resource_table(&dev->res); |
552 | up(&pnp_res_mutex); | 553 | mutex_unlock(&pnp_res_mutex); |
553 | 554 | ||
554 | return 1; | 555 | return 0; |
555 | } | 556 | } |
556 | 557 | ||
557 | /** | 558 | /** |
diff --git a/drivers/pnp/pnpacpi/core.c b/drivers/pnp/pnpacpi/core.c index dada89906314..662b4c279cfc 100644 --- a/drivers/pnp/pnpacpi/core.c +++ b/drivers/pnp/pnpacpi/core.c | |||
@@ -183,7 +183,7 @@ static int __init pnpacpi_add_device(struct acpi_device *device) | |||
183 | if (ACPI_SUCCESS(status)) | 183 | if (ACPI_SUCCESS(status)) |
184 | dev->capabilities |= PNP_CONFIGURABLE; | 184 | dev->capabilities |= PNP_CONFIGURABLE; |
185 | dev->capabilities |= PNP_READ; | 185 | dev->capabilities |= PNP_READ; |
186 | if (device->flags.dynamic_status) | 186 | if (device->flags.dynamic_status && (dev->capabilities & PNP_CONFIGURABLE)) |
187 | dev->capabilities |= PNP_WRITE; | 187 | dev->capabilities |= PNP_WRITE; |
188 | if (device->flags.removable) | 188 | if (device->flags.removable) |
189 | dev->capabilities |= PNP_REMOVABLE; | 189 | dev->capabilities |= PNP_REMOVABLE; |
diff --git a/drivers/pnp/pnpacpi/rsparser.c b/drivers/pnp/pnpacpi/rsparser.c index 6b9840cce0f4..6aa231ef642d 100644 --- a/drivers/pnp/pnpacpi/rsparser.c +++ b/drivers/pnp/pnpacpi/rsparser.c | |||
@@ -391,8 +391,8 @@ acpi_status pnpacpi_parse_allocated_resource(acpi_handle handle, | |||
391 | pnpacpi_allocated_resource, res); | 391 | pnpacpi_allocated_resource, res); |
392 | } | 392 | } |
393 | 393 | ||
394 | static void pnpacpi_parse_dma_option(struct pnp_option *option, | 394 | static __init void pnpacpi_parse_dma_option(struct pnp_option *option, |
395 | struct acpi_resource_dma *p) | 395 | struct acpi_resource_dma *p) |
396 | { | 396 | { |
397 | int i; | 397 | int i; |
398 | struct pnp_dma *dma; | 398 | struct pnp_dma *dma; |
@@ -411,8 +411,8 @@ static void pnpacpi_parse_dma_option(struct pnp_option *option, | |||
411 | pnp_register_dma_resource(option, dma); | 411 | pnp_register_dma_resource(option, dma); |
412 | } | 412 | } |
413 | 413 | ||
414 | static void pnpacpi_parse_irq_option(struct pnp_option *option, | 414 | static __init void pnpacpi_parse_irq_option(struct pnp_option *option, |
415 | struct acpi_resource_irq *p) | 415 | struct acpi_resource_irq *p) |
416 | { | 416 | { |
417 | int i; | 417 | int i; |
418 | struct pnp_irq *irq; | 418 | struct pnp_irq *irq; |
@@ -431,8 +431,8 @@ static void pnpacpi_parse_irq_option(struct pnp_option *option, | |||
431 | pnp_register_irq_resource(option, irq); | 431 | pnp_register_irq_resource(option, irq); |
432 | } | 432 | } |
433 | 433 | ||
434 | static void pnpacpi_parse_ext_irq_option(struct pnp_option *option, | 434 | static __init void pnpacpi_parse_ext_irq_option(struct pnp_option *option, |
435 | struct acpi_resource_extended_irq *p) | 435 | struct acpi_resource_extended_irq *p) |
436 | { | 436 | { |
437 | int i; | 437 | int i; |
438 | struct pnp_irq *irq; | 438 | struct pnp_irq *irq; |
@@ -451,8 +451,8 @@ static void pnpacpi_parse_ext_irq_option(struct pnp_option *option, | |||
451 | pnp_register_irq_resource(option, irq); | 451 | pnp_register_irq_resource(option, irq); |
452 | } | 452 | } |
453 | 453 | ||
454 | static void pnpacpi_parse_port_option(struct pnp_option *option, | 454 | static __init void pnpacpi_parse_port_option(struct pnp_option *option, |
455 | struct acpi_resource_io *io) | 455 | struct acpi_resource_io *io) |
456 | { | 456 | { |
457 | struct pnp_port *port; | 457 | struct pnp_port *port; |
458 | 458 | ||
@@ -470,8 +470,8 @@ static void pnpacpi_parse_port_option(struct pnp_option *option, | |||
470 | pnp_register_port_resource(option, port); | 470 | pnp_register_port_resource(option, port); |
471 | } | 471 | } |
472 | 472 | ||
473 | static void pnpacpi_parse_fixed_port_option(struct pnp_option *option, | 473 | static __init void pnpacpi_parse_fixed_port_option(struct pnp_option *option, |
474 | struct acpi_resource_fixed_io *io) | 474 | struct acpi_resource_fixed_io *io) |
475 | { | 475 | { |
476 | struct pnp_port *port; | 476 | struct pnp_port *port; |
477 | 477 | ||
@@ -487,8 +487,8 @@ static void pnpacpi_parse_fixed_port_option(struct pnp_option *option, | |||
487 | pnp_register_port_resource(option, port); | 487 | pnp_register_port_resource(option, port); |
488 | } | 488 | } |
489 | 489 | ||
490 | static void pnpacpi_parse_mem24_option(struct pnp_option *option, | 490 | static __init void pnpacpi_parse_mem24_option(struct pnp_option *option, |
491 | struct acpi_resource_memory24 *p) | 491 | struct acpi_resource_memory24 *p) |
492 | { | 492 | { |
493 | struct pnp_mem *mem; | 493 | struct pnp_mem *mem; |
494 | 494 | ||
@@ -508,8 +508,8 @@ static void pnpacpi_parse_mem24_option(struct pnp_option *option, | |||
508 | pnp_register_mem_resource(option, mem); | 508 | pnp_register_mem_resource(option, mem); |
509 | } | 509 | } |
510 | 510 | ||
511 | static void pnpacpi_parse_mem32_option(struct pnp_option *option, | 511 | static __init void pnpacpi_parse_mem32_option(struct pnp_option *option, |
512 | struct acpi_resource_memory32 *p) | 512 | struct acpi_resource_memory32 *p) |
513 | { | 513 | { |
514 | struct pnp_mem *mem; | 514 | struct pnp_mem *mem; |
515 | 515 | ||
@@ -529,8 +529,8 @@ static void pnpacpi_parse_mem32_option(struct pnp_option *option, | |||
529 | pnp_register_mem_resource(option, mem); | 529 | pnp_register_mem_resource(option, mem); |
530 | } | 530 | } |
531 | 531 | ||
532 | static void pnpacpi_parse_fixed_mem32_option(struct pnp_option *option, | 532 | static __init void pnpacpi_parse_fixed_mem32_option(struct pnp_option *option, |
533 | struct acpi_resource_fixed_memory32 *p) | 533 | struct acpi_resource_fixed_memory32 *p) |
534 | { | 534 | { |
535 | struct pnp_mem *mem; | 535 | struct pnp_mem *mem; |
536 | 536 | ||
@@ -549,8 +549,8 @@ static void pnpacpi_parse_fixed_mem32_option(struct pnp_option *option, | |||
549 | pnp_register_mem_resource(option, mem); | 549 | pnp_register_mem_resource(option, mem); |
550 | } | 550 | } |
551 | 551 | ||
552 | static void pnpacpi_parse_address_option(struct pnp_option *option, | 552 | static __init void pnpacpi_parse_address_option(struct pnp_option *option, |
553 | struct acpi_resource *r) | 553 | struct acpi_resource *r) |
554 | { | 554 | { |
555 | struct acpi_resource_address64 addr, *p = &addr; | 555 | struct acpi_resource_address64 addr, *p = &addr; |
556 | acpi_status status; | 556 | acpi_status status; |
@@ -596,8 +596,8 @@ struct acpipnp_parse_option_s { | |||
596 | struct pnp_dev *dev; | 596 | struct pnp_dev *dev; |
597 | }; | 597 | }; |
598 | 598 | ||
599 | static acpi_status pnpacpi_option_resource(struct acpi_resource *res, | 599 | static __init acpi_status pnpacpi_option_resource(struct acpi_resource *res, |
600 | void *data) | 600 | void *data) |
601 | { | 601 | { |
602 | int priority = 0; | 602 | int priority = 0; |
603 | struct acpipnp_parse_option_s *parse_data = data; | 603 | struct acpipnp_parse_option_s *parse_data = data; |
@@ -696,8 +696,8 @@ static acpi_status pnpacpi_option_resource(struct acpi_resource *res, | |||
696 | return AE_OK; | 696 | return AE_OK; |
697 | } | 697 | } |
698 | 698 | ||
699 | acpi_status pnpacpi_parse_resource_option_data(acpi_handle handle, | 699 | acpi_status __init pnpacpi_parse_resource_option_data(acpi_handle handle, |
700 | struct pnp_dev * dev) | 700 | struct pnp_dev *dev) |
701 | { | 701 | { |
702 | acpi_status status; | 702 | acpi_status status; |
703 | struct acpipnp_parse_option_s parse_data; | 703 | struct acpipnp_parse_option_s parse_data; |
diff --git a/drivers/pnp/pnpbios/core.c b/drivers/pnp/pnpbios/core.c index e33e03f71084..f7e67197a568 100644 --- a/drivers/pnp/pnpbios/core.c +++ b/drivers/pnp/pnpbios/core.c | |||
@@ -315,7 +315,7 @@ struct pnp_protocol pnpbios_protocol = { | |||
315 | .disable = pnpbios_disable_resources, | 315 | .disable = pnpbios_disable_resources, |
316 | }; | 316 | }; |
317 | 317 | ||
318 | static int insert_device(struct pnp_bios_node *node) | 318 | static int __init insert_device(struct pnp_bios_node *node) |
319 | { | 319 | { |
320 | struct list_head *pos; | 320 | struct list_head *pos; |
321 | struct pnp_dev *dev; | 321 | struct pnp_dev *dev; |
diff --git a/drivers/pnp/pnpbios/rsparser.c b/drivers/pnp/pnpbios/rsparser.c index 3fabf11b0027..caade3531416 100644 --- a/drivers/pnp/pnpbios/rsparser.c +++ b/drivers/pnp/pnpbios/rsparser.c | |||
@@ -262,8 +262,8 @@ len_err: | |||
262 | * Resource Configuration Options | 262 | * Resource Configuration Options |
263 | */ | 263 | */ |
264 | 264 | ||
265 | static void pnpbios_parse_mem_option(unsigned char *p, int size, | 265 | static __init void pnpbios_parse_mem_option(unsigned char *p, int size, |
266 | struct pnp_option *option) | 266 | struct pnp_option *option) |
267 | { | 267 | { |
268 | struct pnp_mem *mem; | 268 | struct pnp_mem *mem; |
269 | 269 | ||
@@ -278,8 +278,8 @@ static void pnpbios_parse_mem_option(unsigned char *p, int size, | |||
278 | pnp_register_mem_resource(option, mem); | 278 | pnp_register_mem_resource(option, mem); |
279 | } | 279 | } |
280 | 280 | ||
281 | static void pnpbios_parse_mem32_option(unsigned char *p, int size, | 281 | static __init void pnpbios_parse_mem32_option(unsigned char *p, int size, |
282 | struct pnp_option *option) | 282 | struct pnp_option *option) |
283 | { | 283 | { |
284 | struct pnp_mem *mem; | 284 | struct pnp_mem *mem; |
285 | 285 | ||
@@ -294,8 +294,8 @@ static void pnpbios_parse_mem32_option(unsigned char *p, int size, | |||
294 | pnp_register_mem_resource(option, mem); | 294 | pnp_register_mem_resource(option, mem); |
295 | } | 295 | } |
296 | 296 | ||
297 | static void pnpbios_parse_fixed_mem32_option(unsigned char *p, int size, | 297 | static __init void pnpbios_parse_fixed_mem32_option(unsigned char *p, int size, |
298 | struct pnp_option *option) | 298 | struct pnp_option *option) |
299 | { | 299 | { |
300 | struct pnp_mem *mem; | 300 | struct pnp_mem *mem; |
301 | 301 | ||
@@ -309,7 +309,7 @@ static void pnpbios_parse_fixed_mem32_option(unsigned char *p, int size, | |||
309 | pnp_register_mem_resource(option, mem); | 309 | pnp_register_mem_resource(option, mem); |
310 | } | 310 | } |
311 | 311 | ||
312 | static void pnpbios_parse_irq_option(unsigned char *p, int size, | 312 | static __init void pnpbios_parse_irq_option(unsigned char *p, int size, |
313 | struct pnp_option *option) | 313 | struct pnp_option *option) |
314 | { | 314 | { |
315 | struct pnp_irq *irq; | 315 | struct pnp_irq *irq; |
@@ -327,7 +327,7 @@ static void pnpbios_parse_irq_option(unsigned char *p, int size, | |||
327 | pnp_register_irq_resource(option, irq); | 327 | pnp_register_irq_resource(option, irq); |
328 | } | 328 | } |
329 | 329 | ||
330 | static void pnpbios_parse_dma_option(unsigned char *p, int size, | 330 | static __init void pnpbios_parse_dma_option(unsigned char *p, int size, |
331 | struct pnp_option *option) | 331 | struct pnp_option *option) |
332 | { | 332 | { |
333 | struct pnp_dma *dma; | 333 | struct pnp_dma *dma; |
@@ -340,8 +340,8 @@ static void pnpbios_parse_dma_option(unsigned char *p, int size, | |||
340 | pnp_register_dma_resource(option, dma); | 340 | pnp_register_dma_resource(option, dma); |
341 | } | 341 | } |
342 | 342 | ||
343 | static void pnpbios_parse_port_option(unsigned char *p, int size, | 343 | static __init void pnpbios_parse_port_option(unsigned char *p, int size, |
344 | struct pnp_option *option) | 344 | struct pnp_option *option) |
345 | { | 345 | { |
346 | struct pnp_port *port; | 346 | struct pnp_port *port; |
347 | 347 | ||
@@ -356,8 +356,8 @@ static void pnpbios_parse_port_option(unsigned char *p, int size, | |||
356 | pnp_register_port_resource(option, port); | 356 | pnp_register_port_resource(option, port); |
357 | } | 357 | } |
358 | 358 | ||
359 | static void pnpbios_parse_fixed_port_option(unsigned char *p, int size, | 359 | static __init void pnpbios_parse_fixed_port_option(unsigned char *p, int size, |
360 | struct pnp_option *option) | 360 | struct pnp_option *option) |
361 | { | 361 | { |
362 | struct pnp_port *port; | 362 | struct pnp_port *port; |
363 | 363 | ||
@@ -371,9 +371,9 @@ static void pnpbios_parse_fixed_port_option(unsigned char *p, int size, | |||
371 | pnp_register_port_resource(option, port); | 371 | pnp_register_port_resource(option, port); |
372 | } | 372 | } |
373 | 373 | ||
374 | static unsigned char *pnpbios_parse_resource_option_data(unsigned char *p, | 374 | static __init unsigned char * |
375 | unsigned char *end, | 375 | pnpbios_parse_resource_option_data(unsigned char *p, unsigned char *end, |
376 | struct pnp_dev *dev) | 376 | struct pnp_dev *dev) |
377 | { | 377 | { |
378 | unsigned int len, tag; | 378 | unsigned int len, tag; |
379 | int priority = 0; | 379 | int priority = 0; |
@@ -781,7 +781,8 @@ len_err: | |||
781 | * Core Parsing Functions | 781 | * Core Parsing Functions |
782 | */ | 782 | */ |
783 | 783 | ||
784 | int pnpbios_parse_data_stream(struct pnp_dev *dev, struct pnp_bios_node *node) | 784 | int __init pnpbios_parse_data_stream(struct pnp_dev *dev, |
785 | struct pnp_bios_node *node) | ||
785 | { | 786 | { |
786 | unsigned char *p = (char *)node->data; | 787 | unsigned char *p = (char *)node->data; |
787 | unsigned char *end = (char *)(node->data + node->size); | 788 | unsigned char *end = (char *)(node->data + node->size); |
diff --git a/drivers/pnp/quirks.c b/drivers/pnp/quirks.c index e903b8c2b1fa..4065139753b6 100644 --- a/drivers/pnp/quirks.c +++ b/drivers/pnp/quirks.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/slab.h> | 17 | #include <linux/slab.h> |
18 | #include <linux/pnp.h> | 18 | #include <linux/pnp.h> |
19 | #include <linux/io.h> | 19 | #include <linux/io.h> |
20 | #include <linux/dmi.h> | ||
20 | #include <linux/kallsyms.h> | 21 | #include <linux/kallsyms.h> |
21 | #include "base.h" | 22 | #include "base.h" |
22 | 23 | ||
@@ -108,6 +109,46 @@ static void quirk_sb16audio_resources(struct pnp_dev *dev) | |||
108 | "pnp: SB audio device quirk - increasing port range\n"); | 109 | "pnp: SB audio device quirk - increasing port range\n"); |
109 | } | 110 | } |
110 | 111 | ||
112 | static void quirk_supermicro_h8dce_system(struct pnp_dev *dev) | ||
113 | { | ||
114 | int i; | ||
115 | static struct dmi_system_id supermicro_h8dce[] = { | ||
116 | { | ||
117 | .ident = "Supermicro H8DCE", | ||
118 | .matches = { | ||
119 | DMI_MATCH(DMI_SYS_VENDOR, "Supermicro"), | ||
120 | DMI_MATCH(DMI_PRODUCT_NAME, "H8DCE"), | ||
121 | }, | ||
122 | }, | ||
123 | { } | ||
124 | }; | ||
125 | |||
126 | if (!dmi_check_system(supermicro_h8dce)) | ||
127 | return; | ||
128 | |||
129 | /* | ||
130 | * On the Supermicro H8DCE, there's a system device with resources | ||
131 | * that overlap BAR 6 of the built-in SATA PCI adapter. If the PNP | ||
132 | * system device claims them, the sata_nv driver won't be able to. | ||
133 | * More details at: | ||
134 | * https://bugzilla.redhat.com/show_bug.cgi?id=280641 | ||
135 | * https://bugzilla.redhat.com/show_bug.cgi?id=313491 | ||
136 | * http://lkml.org/lkml/2008/1/9/449 | ||
137 | * http://thread.gmane.org/gmane.linux.acpi.devel/27312 | ||
138 | */ | ||
139 | for (i = 0; i < PNP_MAX_MEM; i++) { | ||
140 | if (pnp_mem_valid(dev, i) && pnp_mem_len(dev, i) && | ||
141 | (pnp_mem_start(dev, i) & 0xdfef0000) == 0xdfef0000) { | ||
142 | dev_warn(&dev->dev, "disabling 0x%llx-0x%llx to prevent" | ||
143 | " conflict with sata_nv PCI device\n", | ||
144 | (unsigned long long) pnp_mem_start(dev, i), | ||
145 | (unsigned long long) (pnp_mem_start(dev, i) + | ||
146 | pnp_mem_len(dev, i) - 1)); | ||
147 | pnp_mem_flags(dev, i) = 0; | ||
148 | } | ||
149 | } | ||
150 | } | ||
151 | |||
111 | /* | 152 | /* |
112 | * PnP Quirks | 153 | * PnP Quirks |
113 | * Cards or devices that need some tweaking due to incomplete resource info | 154 | * Cards or devices that need some tweaking due to incomplete resource info |
@@ -128,6 +169,8 @@ static struct pnp_fixup pnp_fixups[] = { | |||
128 | {"CTL0043", quirk_sb16audio_resources}, | 169 | {"CTL0043", quirk_sb16audio_resources}, |
129 | {"CTL0044", quirk_sb16audio_resources}, | 170 | {"CTL0044", quirk_sb16audio_resources}, |
130 | {"CTL0045", quirk_sb16audio_resources}, | 171 | {"CTL0045", quirk_sb16audio_resources}, |
172 | {"PNP0c01", quirk_supermicro_h8dce_system}, | ||
173 | {"PNP0c02", quirk_supermicro_h8dce_system}, | ||
131 | {""} | 174 | {""} |
132 | }; | 175 | }; |
133 | 176 | ||