aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2016-02-26 12:21:48 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2016-02-26 12:21:48 -0500
commitbb134ff50709fda187027c2263036ccb41024ca5 (patch)
treead0372d25617c5b884a433997adcd9b334fa8a1f /drivers/acpi
parent34d47a77591f2fe7988beeca86d8ee281aee827f (diff)
parent1711fd9cf92f366d42da29b108746accd807789a (diff)
Merge tag 'pm+acpi-4.5-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm
Pull power management and ACPI fixes from Rafael Wysocki: "These are two reverts of recent PCI-related ACPI core changes (one of which caused some systems to crash on boot and the other was a cleanup on top of it) and a devfreq fix for Tegra. Specifics: - Revert an ACPI core change related to IRQ management in PCI that introduced code relying on the use of kmalloc() which turned out to also run during early init when that's not available yet and caused some systems to crash on boot for this reason along with a cleanup on top of it (Rafael Wysocki). - Prevent devfreq from flooding the kernel log with useless messages on Tegra (which started to happen after some recent changes in the devfreq core) by fixing the driver to follow the documentation and the core's expectations in its ->target callback (Tomeu Vizoso)" * tag 'pm+acpi-4.5-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: Revert "ACPI, PCI, irq: remove interrupt count restriction" Revert "ACPI / PCI: Simplify acpi_penalize_isa_irq()" PM / devfreq: tegra: Set freq in rate callback
Diffstat (limited to 'drivers/acpi')
-rw-r--r--drivers/acpi/pci_link.c128
1 files changed, 34 insertions, 94 deletions
diff --git a/drivers/acpi/pci_link.c b/drivers/acpi/pci_link.c
index fa2863567eed..ededa909df2f 100644
--- a/drivers/acpi/pci_link.c
+++ b/drivers/acpi/pci_link.c
@@ -4,7 +4,6 @@
4 * Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com> 4 * Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
5 * Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com> 5 * Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
6 * Copyright (C) 2002 Dominik Brodowski <devel@brodo.de> 6 * Copyright (C) 2002 Dominik Brodowski <devel@brodo.de>
7 * Copyright (c) 2015, The Linux Foundation. All rights reserved.
8 * 7 *
9 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 8 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
10 * 9 *
@@ -438,6 +437,7 @@ static int acpi_pci_link_set(struct acpi_pci_link *link, int irq)
438 * enabled system. 437 * enabled system.
439 */ 438 */
440 439
440#define ACPI_MAX_IRQS 256
441#define ACPI_MAX_ISA_IRQ 16 441#define ACPI_MAX_ISA_IRQ 16
442 442
443#define PIRQ_PENALTY_PCI_AVAILABLE (0) 443#define PIRQ_PENALTY_PCI_AVAILABLE (0)
@@ -447,7 +447,7 @@ static int acpi_pci_link_set(struct acpi_pci_link *link, int irq)
447#define PIRQ_PENALTY_ISA_USED (16*16*16*16*16) 447#define PIRQ_PENALTY_ISA_USED (16*16*16*16*16)
448#define PIRQ_PENALTY_ISA_ALWAYS (16*16*16*16*16*16) 448#define PIRQ_PENALTY_ISA_ALWAYS (16*16*16*16*16*16)
449 449
450static int acpi_irq_isa_penalty[ACPI_MAX_ISA_IRQ] = { 450static int acpi_irq_penalty[ACPI_MAX_IRQS] = {
451 PIRQ_PENALTY_ISA_ALWAYS, /* IRQ0 timer */ 451 PIRQ_PENALTY_ISA_ALWAYS, /* IRQ0 timer */
452 PIRQ_PENALTY_ISA_ALWAYS, /* IRQ1 keyboard */ 452 PIRQ_PENALTY_ISA_ALWAYS, /* IRQ1 keyboard */
453 PIRQ_PENALTY_ISA_ALWAYS, /* IRQ2 cascade */ 453 PIRQ_PENALTY_ISA_ALWAYS, /* IRQ2 cascade */
@@ -464,68 +464,9 @@ static int acpi_irq_isa_penalty[ACPI_MAX_ISA_IRQ] = {
464 PIRQ_PENALTY_ISA_USED, /* IRQ13 fpe, sometimes */ 464 PIRQ_PENALTY_ISA_USED, /* IRQ13 fpe, sometimes */
465 PIRQ_PENALTY_ISA_USED, /* IRQ14 ide0 */ 465 PIRQ_PENALTY_ISA_USED, /* IRQ14 ide0 */
466 PIRQ_PENALTY_ISA_USED, /* IRQ15 ide1 */ 466 PIRQ_PENALTY_ISA_USED, /* IRQ15 ide1 */
467 /* >IRQ15 */
467}; 468};
468 469
469struct irq_penalty_info {
470 int irq;
471 int penalty;
472 struct list_head node;
473};
474
475static LIST_HEAD(acpi_irq_penalty_list);
476
477static int acpi_irq_get_penalty(int irq)
478{
479 struct irq_penalty_info *irq_info;
480
481 if (irq < ACPI_MAX_ISA_IRQ)
482 return acpi_irq_isa_penalty[irq];
483
484 list_for_each_entry(irq_info, &acpi_irq_penalty_list, node) {
485 if (irq_info->irq == irq)
486 return irq_info->penalty;
487 }
488
489 return 0;
490}
491
492static int acpi_irq_set_penalty(int irq, int new_penalty)
493{
494 struct irq_penalty_info *irq_info;
495
496 /* see if this is a ISA IRQ */
497 if (irq < ACPI_MAX_ISA_IRQ) {
498 acpi_irq_isa_penalty[irq] = new_penalty;
499 return 0;
500 }
501
502 /* next, try to locate from the dynamic list */
503 list_for_each_entry(irq_info, &acpi_irq_penalty_list, node) {
504 if (irq_info->irq == irq) {
505 irq_info->penalty = new_penalty;
506 return 0;
507 }
508 }
509
510 /* nope, let's allocate a slot for this IRQ */
511 irq_info = kzalloc(sizeof(*irq_info), GFP_KERNEL);
512 if (!irq_info)
513 return -ENOMEM;
514
515 irq_info->irq = irq;
516 irq_info->penalty = new_penalty;
517 list_add_tail(&irq_info->node, &acpi_irq_penalty_list);
518
519 return 0;
520}
521
522static void acpi_irq_add_penalty(int irq, int penalty)
523{
524 int curpen = acpi_irq_get_penalty(irq);
525
526 acpi_irq_set_penalty(irq, curpen + penalty);
527}
528
529int __init acpi_irq_penalty_init(void) 470int __init acpi_irq_penalty_init(void)
530{ 471{
531 struct acpi_pci_link *link; 472 struct acpi_pci_link *link;
@@ -546,16 +487,15 @@ int __init acpi_irq_penalty_init(void)
546 link->irq.possible_count; 487 link->irq.possible_count;
547 488
548 for (i = 0; i < link->irq.possible_count; i++) { 489 for (i = 0; i < link->irq.possible_count; i++) {
549 if (link->irq.possible[i] < ACPI_MAX_ISA_IRQ) { 490 if (link->irq.possible[i] < ACPI_MAX_ISA_IRQ)
550 int irqpos = link->irq.possible[i]; 491 acpi_irq_penalty[link->irq.
551 492 possible[i]] +=
552 acpi_irq_add_penalty(irqpos, penalty); 493 penalty;
553 }
554 } 494 }
555 495
556 } else if (link->irq.active) { 496 } else if (link->irq.active) {
557 acpi_irq_add_penalty(link->irq.active, 497 acpi_irq_penalty[link->irq.active] +=
558 PIRQ_PENALTY_PCI_POSSIBLE); 498 PIRQ_PENALTY_PCI_POSSIBLE;
559 } 499 }
560 } 500 }
561 501
@@ -607,12 +547,12 @@ static int acpi_pci_link_allocate(struct acpi_pci_link *link)
607 * the use of IRQs 9, 10, 11, and >15. 547 * the use of IRQs 9, 10, 11, and >15.
608 */ 548 */
609 for (i = (link->irq.possible_count - 1); i >= 0; i--) { 549 for (i = (link->irq.possible_count - 1); i >= 0; i--) {
610 if (acpi_irq_get_penalty(irq) > 550 if (acpi_irq_penalty[irq] >
611 acpi_irq_get_penalty(link->irq.possible[i])) 551 acpi_irq_penalty[link->irq.possible[i]])
612 irq = link->irq.possible[i]; 552 irq = link->irq.possible[i];
613 } 553 }
614 } 554 }
615 if (acpi_irq_get_penalty(irq) >= PIRQ_PENALTY_ISA_ALWAYS) { 555 if (acpi_irq_penalty[irq] >= PIRQ_PENALTY_ISA_ALWAYS) {
616 printk(KERN_ERR PREFIX "No IRQ available for %s [%s]. " 556 printk(KERN_ERR PREFIX "No IRQ available for %s [%s]. "
617 "Try pci=noacpi or acpi=off\n", 557 "Try pci=noacpi or acpi=off\n",
618 acpi_device_name(link->device), 558 acpi_device_name(link->device),
@@ -628,8 +568,7 @@ static int acpi_pci_link_allocate(struct acpi_pci_link *link)
628 acpi_device_bid(link->device)); 568 acpi_device_bid(link->device));
629 return -ENODEV; 569 return -ENODEV;
630 } else { 570 } else {
631 acpi_irq_add_penalty(link->irq.active, PIRQ_PENALTY_PCI_USING); 571 acpi_irq_penalty[link->irq.active] += PIRQ_PENALTY_PCI_USING;
632
633 printk(KERN_WARNING PREFIX "%s [%s] enabled at IRQ %d\n", 572 printk(KERN_WARNING PREFIX "%s [%s] enabled at IRQ %d\n",
634 acpi_device_name(link->device), 573 acpi_device_name(link->device),
635 acpi_device_bid(link->device), link->irq.active); 574 acpi_device_bid(link->device), link->irq.active);
@@ -839,7 +778,7 @@ static void acpi_pci_link_remove(struct acpi_device *device)
839} 778}
840 779
841/* 780/*
842 * modify penalty from cmdline 781 * modify acpi_irq_penalty[] from cmdline
843 */ 782 */
844static int __init acpi_irq_penalty_update(char *str, int used) 783static int __init acpi_irq_penalty_update(char *str, int used)
845{ 784{
@@ -857,10 +796,13 @@ static int __init acpi_irq_penalty_update(char *str, int used)
857 if (irq < 0) 796 if (irq < 0)
858 continue; 797 continue;
859 798
799 if (irq >= ARRAY_SIZE(acpi_irq_penalty))
800 continue;
801
860 if (used) 802 if (used)
861 acpi_irq_add_penalty(irq, PIRQ_PENALTY_ISA_USED); 803 acpi_irq_penalty[irq] += PIRQ_PENALTY_ISA_USED;
862 else 804 else
863 acpi_irq_set_penalty(irq, PIRQ_PENALTY_PCI_AVAILABLE); 805 acpi_irq_penalty[irq] = PIRQ_PENALTY_PCI_AVAILABLE;
864 806
865 if (retval != 2) /* no next number */ 807 if (retval != 2) /* no next number */
866 break; 808 break;
@@ -877,15 +819,18 @@ static int __init acpi_irq_penalty_update(char *str, int used)
877 */ 819 */
878void acpi_penalize_isa_irq(int irq, int active) 820void acpi_penalize_isa_irq(int irq, int active)
879{ 821{
880 if (irq >= 0) 822 if (irq >= 0 && irq < ARRAY_SIZE(acpi_irq_penalty)) {
881 acpi_irq_add_penalty(irq, active ? 823 if (active)
882 PIRQ_PENALTY_ISA_USED : PIRQ_PENALTY_PCI_USING); 824 acpi_irq_penalty[irq] += PIRQ_PENALTY_ISA_USED;
825 else
826 acpi_irq_penalty[irq] += PIRQ_PENALTY_PCI_USING;
827 }
883} 828}
884 829
885bool acpi_isa_irq_available(int irq) 830bool acpi_isa_irq_available(int irq)
886{ 831{
887 return irq >= 0 && 832 return irq >= 0 && (irq >= ARRAY_SIZE(acpi_irq_penalty) ||
888 (acpi_irq_get_penalty(irq) < PIRQ_PENALTY_ISA_ALWAYS); 833 acpi_irq_penalty[irq] < PIRQ_PENALTY_ISA_ALWAYS);
889} 834}
890 835
891/* 836/*
@@ -895,18 +840,13 @@ bool acpi_isa_irq_available(int irq)
895 */ 840 */
896void acpi_penalize_sci_irq(int irq, int trigger, int polarity) 841void acpi_penalize_sci_irq(int irq, int trigger, int polarity)
897{ 842{
898 int penalty; 843 if (irq >= 0 && irq < ARRAY_SIZE(acpi_irq_penalty)) {
899 844 if (trigger != ACPI_MADT_TRIGGER_LEVEL ||
900 if (irq < 0) 845 polarity != ACPI_MADT_POLARITY_ACTIVE_LOW)
901 return; 846 acpi_irq_penalty[irq] += PIRQ_PENALTY_ISA_ALWAYS;
902 847 else
903 if (trigger != ACPI_MADT_TRIGGER_LEVEL || 848 acpi_irq_penalty[irq] += PIRQ_PENALTY_PCI_USING;
904 polarity != ACPI_MADT_POLARITY_ACTIVE_LOW) 849 }
905 penalty = PIRQ_PENALTY_ISA_ALWAYS;
906 else
907 penalty = PIRQ_PENALTY_PCI_USING;
908
909 acpi_irq_add_penalty(irq, penalty);
910} 850}
911 851
912/* 852/*