Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'pm+acpi-4.0-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm

Pull power management and ACPI fixes from Rafael Wysocki:
"These are fixes for recent regressions (PCI/ACPI resources and at91
RTC locking), a stable-candidate powercap RAPL driver fix and two ARM
cpuidle fixes (one stable-candidate too).

Specifics:

- Revert a recent PCI commit related to IRQ resources management that
introduced a regression for drivers attempting to bind to devices
whose previous drivers did not balance pci_enable_device() and
pci_disable_device() as expected (Rafael J Wysocki).

- Fix a deadlock in at91_rtc_interrupt() introduced by a typo in a
recent commit related to wakeup interrupt handling (Dan Carpenter).

- Allow the power capping RAPL (Running-Average Power Limit) driver
to use different energy units for domains within one CPU package
which is necessary to handle Intel Haswell EP processors correctly
(Jacob Pan).

- Improve the cpuidle mvebu driver's handling of Armada XP SoCs by
updating the target residency and exit latency numbers for those
chips (Sebastien Rannou).

- Prevent the cpuidle mvebu driver from calling cpu_pm_enter() twice
in a row before cpu_pm_exit() is called on the same CPU which
breaks the core's assumptions regarding the usage of those
functions (Gregory Clement)"

* tag 'pm+acpi-4.0-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm:
Revert "x86/PCI: Refine the way to release PCI IRQ resources"
rtc: at91rm9200: double locking bug in at91_rtc_interrupt()
powercap / RAPL: handle domains with different energy units
cpuidle: mvebu: Update cpuidle thresholds for Armada XP SOCs
cpuidle: mvebu: Fix the CPU PM notifier usage

+78 -54
+2
arch/x86/include/asm/pci_x86.h
··· 93 93 extern int (*pcibios_enable_irq)(struct pci_dev *dev); 94 94 extern void (*pcibios_disable_irq)(struct pci_dev *dev); 95 95 96 + extern bool mp_should_keep_irq(struct device *dev); 97 + 96 98 struct pci_raw_ops { 97 99 int (*read)(unsigned int domain, unsigned int bus, unsigned int devfn, 98 100 int reg, int len, u32 *val);
+6 -28
arch/x86/pci/common.c
··· 513 513 } 514 514 } 515 515 516 - /* 517 - * Some device drivers assume dev->irq won't change after calling 518 - * pci_disable_device(). So delay releasing of IRQ resource to driver 519 - * unbinding time. Otherwise it will break PM subsystem and drivers 520 - * like xen-pciback etc. 521 - */ 522 - static int pci_irq_notifier(struct notifier_block *nb, unsigned long action, 523 - void *data) 524 - { 525 - struct pci_dev *dev = to_pci_dev(data); 526 - 527 - if (action != BUS_NOTIFY_UNBOUND_DRIVER) 528 - return NOTIFY_DONE; 529 - 530 - if (pcibios_disable_irq) 531 - pcibios_disable_irq(dev); 532 - 533 - return NOTIFY_OK; 534 - } 535 - 536 - static struct notifier_block pci_irq_nb = { 537 - .notifier_call = pci_irq_notifier, 538 - .priority = INT_MIN, 539 - }; 540 - 541 516 int __init pcibios_init(void) 542 517 { 543 518 if (!raw_pci_ops) { ··· 525 550 526 551 if (pci_bf_sort >= pci_force_bf) 527 552 pci_sort_breadthfirst(); 528 - 529 - bus_register_notifier(&pci_bus_type, &pci_irq_nb); 530 - 531 553 return 0; 532 554 } 533 555 ··· 681 709 if (!pci_dev_msi_enabled(dev)) 682 710 return pcibios_enable_irq(dev); 683 711 return 0; 712 + } 713 + 714 + void pcibios_disable_device (struct pci_dev *dev) 715 + { 716 + if (!pci_dev_msi_enabled(dev) && pcibios_disable_irq) 717 + pcibios_disable_irq(dev); 684 718 } 685 719 686 720 int pci_ext_cfg_avail(void)
+2 -2
arch/x86/pci/intel_mid_pci.c
··· 234 234 235 235 static void intel_mid_pci_irq_disable(struct pci_dev *dev) 236 236 { 237 - if (dev->irq_managed && dev->irq > 0) { 237 + if (!mp_should_keep_irq(&dev->dev) && dev->irq_managed && 238 + dev->irq > 0) { 238 239 mp_unmap_irq(dev->irq); 239 240 dev->irq_managed = 0; 240 - dev->irq = 0; 241 241 } 242 242 } 243 243
+14 -1
arch/x86/pci/irq.c
··· 1256 1256 return 0; 1257 1257 } 1258 1258 1259 + bool mp_should_keep_irq(struct device *dev) 1260 + { 1261 + if (dev->power.is_prepared) 1262 + return true; 1263 + #ifdef CONFIG_PM 1264 + if (dev->power.runtime_status == RPM_SUSPENDING) 1265 + return true; 1266 + #endif 1267 + 1268 + return false; 1269 + } 1270 + 1259 1271 static void pirq_disable_irq(struct pci_dev *dev) 1260 1272 { 1261 - if (io_apic_assign_pci_irqs && dev->irq_managed && dev->irq) { 1273 + if (io_apic_assign_pci_irqs && !mp_should_keep_irq(&dev->dev) && 1274 + dev->irq_managed && dev->irq) { 1262 1275 mp_unmap_irq(dev->irq); 1263 1276 dev->irq = 0; 1264 1277 dev->irq_managed = 0;
+8 -1
drivers/acpi/pci_irq.c
··· 485 485 if (!pin || !dev->irq_managed || dev->irq <= 0) 486 486 return; 487 487 488 + /* Keep IOAPIC pin configuration when suspending */ 489 + if (dev->dev.power.is_prepared) 490 + return; 491 + #ifdef CONFIG_PM 492 + if (dev->dev.power.runtime_status == RPM_SUSPENDING) 493 + return; 494 + #endif 495 + 488 496 entry = acpi_pci_irq_lookup(dev, pin); 489 497 if (!entry) 490 498 return; ··· 513 505 if (gsi >= 0) { 514 506 acpi_unregister_gsi(gsi); 515 507 dev->irq_managed = 0; 516 - dev->irq = 0; 517 508 } 518 509 }
+6 -6
drivers/cpuidle/cpuidle-mvebu-v7.c
··· 37 37 deepidle = true; 38 38 39 39 ret = mvebu_v7_cpu_suspend(deepidle); 40 + cpu_pm_exit(); 41 + 40 42 if (ret) 41 43 return ret; 42 - 43 - cpu_pm_exit(); 44 44 45 45 return index; 46 46 } ··· 50 50 .states[0] = ARM_CPUIDLE_WFI_STATE, 51 51 .states[1] = { 52 52 .enter = mvebu_v7_enter_idle, 53 - .exit_latency = 10, 53 + .exit_latency = 100, 54 54 .power_usage = 50, 55 - .target_residency = 100, 55 + .target_residency = 1000, 56 56 .name = "MV CPU IDLE", 57 57 .desc = "CPU power down", 58 58 }, 59 59 .states[2] = { 60 60 .enter = mvebu_v7_enter_idle, 61 - .exit_latency = 100, 61 + .exit_latency = 1000, 62 62 .power_usage = 5, 63 - .target_residency = 1000, 63 + .target_residency = 10000, 64 64 .flags = MVEBU_V7_FLAG_DEEP_IDLE, 65 65 .name = "MV CPU DEEP IDLE", 66 66 .desc = "CPU and L2 Fabric power down",
+39 -15
drivers/powercap/intel_rapl.c
··· 73 73 74 74 #define TIME_WINDOW_MAX_MSEC 40000 75 75 #define TIME_WINDOW_MIN_MSEC 250 76 - 76 + #define ENERGY_UNIT_SCALE 1000 /* scale from driver unit to powercap unit */ 77 77 enum unit_type { 78 78 ARBITRARY_UNIT, /* no translation */ 79 79 POWER_UNIT, ··· 158 158 struct rapl_power_limit rpl[NR_POWER_LIMITS]; 159 159 u64 attr_map; /* track capabilities */ 160 160 unsigned int state; 161 + unsigned int domain_energy_unit; 161 162 int package_id; 162 163 }; 163 164 #define power_zone_to_rapl_domain(_zone) \ ··· 191 190 void (*set_floor_freq)(struct rapl_domain *rd, bool mode); 192 191 u64 (*compute_time_window)(struct rapl_package *rp, u64 val, 193 192 bool to_raw); 193 + unsigned int dram_domain_energy_unit; 194 194 }; 195 195 static struct rapl_defaults *rapl_defaults; 196 196 ··· 229 227 static int rapl_write_data_raw(struct rapl_domain *rd, 230 228 enum rapl_primitives prim, 231 229 unsigned long long value); 232 - static u64 rapl_unit_xlate(int package, enum unit_type type, u64 value, 230 + static u64 rapl_unit_xlate(struct rapl_domain *rd, int package, 231 + enum unit_type type, u64 value, 233 232 int to_raw); 234 233 static void package_power_limit_irq_save(int package_id); 235 234 ··· 308 305 309 306 static int get_max_energy_counter(struct powercap_zone *pcd_dev, u64 *energy) 310 307 { 311 - *energy = rapl_unit_xlate(0, ENERGY_UNIT, ENERGY_STATUS_MASK, 0); 308 + struct rapl_domain *rd = power_zone_to_rapl_domain(pcd_dev); 309 + 310 + *energy = rapl_unit_xlate(rd, 0, ENERGY_UNIT, ENERGY_STATUS_MASK, 0); 312 311 return 0; 313 312 } 314 313 ··· 644 639 rd->msrs[4] = MSR_DRAM_POWER_INFO; 645 640 rd->rpl[0].prim_id = PL1_ENABLE; 646 641 rd->rpl[0].name = pl1_name; 642 + rd->domain_energy_unit = 643 + rapl_defaults->dram_domain_energy_unit; 644 + if (rd->domain_energy_unit) 645 + pr_info("DRAM domain energy unit %dpj\n", 646 + rd->domain_energy_unit); 647 647 break; 648 648 } 649 649 if (mask) { ··· 658 648 } 659 649 } 660 650 661 - static u64 rapl_unit_xlate(int package, enum unit_type type, u64 value, 651 + static u64 rapl_unit_xlate(struct rapl_domain *rd, int package, 652 + enum unit_type type, u64 value, 662 653 int to_raw) 663 654 { 664 655 u64 units = 1; 665 656 struct rapl_package *rp; 657 + u64 scale = 1; 666 658 667 659 rp = find_package_by_id(package); 668 660 if (!rp) ··· 675 663 units = rp->power_unit; 676 664 break; 677 665 case ENERGY_UNIT: 678 - units = rp->energy_unit; 666 + scale = ENERGY_UNIT_SCALE; 667 + /* per domain unit takes precedence */ 668 + if (rd && rd->domain_energy_unit) 669 + units = rd->domain_energy_unit; 670 + else 671 + units = rp->energy_unit; 679 672 break; 680 673 case TIME_UNIT: 681 674 return rapl_defaults->compute_time_window(rp, value, to_raw); ··· 690 673 }; 691 674 692 675 if (to_raw) 693 - return div64_u64(value, units); 676 + return div64_u64(value, units) * scale; 694 677 695 678 value *= units; 696 679 697 - return value; 680 + return div64_u64(value, scale); 698 681 } 699 682 700 683 /* in the order of enum rapl_primitives */ ··· 790 773 final = value & rp->mask; 791 774 final = final >> rp->shift; 792 775 if (xlate) 793 - *data = rapl_unit_xlate(rd->package_id, rp->unit, final, 0); 776 + *data = rapl_unit_xlate(rd, rd->package_id, rp->unit, final, 0); 794 777 else 795 778 *data = final; 796 779 ··· 816 799 "failed to read msr 0x%x on cpu %d\n", msr, cpu); 817 800 return -EIO; 818 801 } 819 - value = rapl_unit_xlate(rd->package_id, rp->unit, value, 1); 802 + value = rapl_unit_xlate(rd, rd->package_id, rp->unit, value, 1); 820 803 msr_val &= ~rp->mask; 821 804 msr_val |= value << rp->shift; 822 805 if (wrmsrl_safe_on_cpu(cpu, msr, msr_val)) { ··· 835 818 * calculate units differ on different CPUs. 836 819 * We convert the units to below format based on CPUs. 837 820 * i.e. 838 - * energy unit: microJoules : Represented in microJoules by default 821 + * energy unit: picoJoules : Represented in picoJoules by default 839 822 * power unit : microWatts : Represented in milliWatts by default 840 823 * time unit : microseconds: Represented in seconds by default 841 824 */ ··· 851 834 } 852 835 853 836 value = (msr_val & ENERGY_UNIT_MASK) >> ENERGY_UNIT_OFFSET; 854 - rp->energy_unit = 1000000 / (1 << value); 837 + rp->energy_unit = ENERGY_UNIT_SCALE * 1000000 / (1 << value); 855 838 856 839 value = (msr_val & POWER_UNIT_MASK) >> POWER_UNIT_OFFSET; 857 840 rp->power_unit = 1000000 / (1 << value); ··· 859 842 value = (msr_val & TIME_UNIT_MASK) >> TIME_UNIT_OFFSET; 860 843 rp->time_unit = 1000000 / (1 << value); 861 844 862 - pr_debug("Core CPU package %d energy=%duJ, time=%dus, power=%duW\n", 845 + pr_debug("Core CPU package %d energy=%dpJ, time=%dus, power=%duW\n", 863 846 rp->id, rp->energy_unit, rp->time_unit, rp->power_unit); 864 847 865 848 return 0; ··· 876 859 return -ENODEV; 877 860 } 878 861 value = (msr_val & ENERGY_UNIT_MASK) >> ENERGY_UNIT_OFFSET; 879 - rp->energy_unit = 1 << value; 862 + rp->energy_unit = ENERGY_UNIT_SCALE * 1 << value; 880 863 881 864 value = (msr_val & POWER_UNIT_MASK) >> POWER_UNIT_OFFSET; 882 865 rp->power_unit = (1 << value) * 1000; ··· 884 867 value = (msr_val & TIME_UNIT_MASK) >> TIME_UNIT_OFFSET; 885 868 rp->time_unit = 1000000 / (1 << value); 886 869 887 - pr_debug("Atom package %d energy=%duJ, time=%dus, power=%duW\n", 870 + pr_debug("Atom package %d energy=%dpJ, time=%dus, power=%duW\n", 888 871 rp->id, rp->energy_unit, rp->time_unit, rp->power_unit); 889 872 890 873 return 0; ··· 1034 1017 .compute_time_window = rapl_compute_time_window_core, 1035 1018 }; 1036 1019 1020 + static const struct rapl_defaults rapl_defaults_hsw_server = { 1021 + .check_unit = rapl_check_unit_core, 1022 + .set_floor_freq = set_floor_freq_default, 1023 + .compute_time_window = rapl_compute_time_window_core, 1024 + .dram_domain_energy_unit = 15300, 1025 + }; 1026 + 1037 1027 static const struct rapl_defaults rapl_defaults_atom = { 1038 1028 .check_unit = rapl_check_unit_atom, 1039 1029 .set_floor_freq = set_floor_freq_atom, ··· 1061 1037 RAPL_CPU(0x3a, rapl_defaults_core),/* Ivy Bridge */ 1062 1038 RAPL_CPU(0x3c, rapl_defaults_core),/* Haswell */ 1063 1039 RAPL_CPU(0x3d, rapl_defaults_core),/* Broadwell */ 1064 - RAPL_CPU(0x3f, rapl_defaults_core),/* Haswell */ 1040 + RAPL_CPU(0x3f, rapl_defaults_hsw_server),/* Haswell servers */ 1065 1041 RAPL_CPU(0x45, rapl_defaults_core),/* Haswell ULT */ 1066 1042 RAPL_CPU(0x4C, rapl_defaults_atom),/* Braswell */ 1067 1043 RAPL_CPU(0x4A, rapl_defaults_atom),/* Tangier */
+1 -1
drivers/rtc/rtc-at91rm9200.c
··· 324 324 325 325 ret = IRQ_HANDLED; 326 326 } 327 - spin_lock(&suspended_lock); 327 + spin_unlock(&suspended_lock); 328 328 329 329 return ret; 330 330 }