diff options
| -rw-r--r-- | arch/x86/include/asm/pci_x86.h | 2 | ||||
| -rw-r--r-- | arch/x86/pci/common.c | 34 | ||||
| -rw-r--r-- | arch/x86/pci/intel_mid_pci.c | 4 | ||||
| -rw-r--r-- | arch/x86/pci/irq.c | 15 | ||||
| -rw-r--r-- | drivers/acpi/pci_irq.c | 9 | ||||
| -rw-r--r-- | drivers/cpuidle/cpuidle-mvebu-v7.c | 12 | ||||
| -rw-r--r-- | drivers/powercap/intel_rapl.c | 54 |
7 files changed, 77 insertions, 53 deletions
diff --git a/arch/x86/include/asm/pci_x86.h b/arch/x86/include/asm/pci_x86.h index fa1195dae425..164e3f8d3c3d 100644 --- a/arch/x86/include/asm/pci_x86.h +++ b/arch/x86/include/asm/pci_x86.h | |||
| @@ -93,6 +93,8 @@ extern raw_spinlock_t pci_config_lock; | |||
| 93 | extern int (*pcibios_enable_irq)(struct pci_dev *dev); | 93 | extern int (*pcibios_enable_irq)(struct pci_dev *dev); |
| 94 | extern void (*pcibios_disable_irq)(struct pci_dev *dev); | 94 | extern void (*pcibios_disable_irq)(struct pci_dev *dev); |
| 95 | 95 | ||
| 96 | extern bool mp_should_keep_irq(struct device *dev); | ||
| 97 | |||
| 96 | struct pci_raw_ops { | 98 | struct pci_raw_ops { |
| 97 | int (*read)(unsigned int domain, unsigned int bus, unsigned int devfn, | 99 | int (*read)(unsigned int domain, unsigned int bus, unsigned int devfn, |
| 98 | int reg, int len, u32 *val); | 100 | int reg, int len, u32 *val); |
diff --git a/arch/x86/pci/common.c b/arch/x86/pci/common.c index 3d2612b68694..2fb384724ebb 100644 --- a/arch/x86/pci/common.c +++ b/arch/x86/pci/common.c | |||
| @@ -513,31 +513,6 @@ void __init pcibios_set_cache_line_size(void) | |||
| 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 | int __init pcibios_init(void) | 516 | int __init pcibios_init(void) |
| 542 | { | 517 | { |
| 543 | if (!raw_pci_ops) { | 518 | if (!raw_pci_ops) { |
| @@ -550,9 +525,6 @@ int __init pcibios_init(void) | |||
| 550 | 525 | ||
| 551 | if (pci_bf_sort >= pci_force_bf) | 526 | if (pci_bf_sort >= pci_force_bf) |
| 552 | pci_sort_breadthfirst(); | 527 | pci_sort_breadthfirst(); |
| 553 | |||
| 554 | bus_register_notifier(&pci_bus_type, &pci_irq_nb); | ||
| 555 | |||
| 556 | return 0; | 528 | return 0; |
| 557 | } | 529 | } |
| 558 | 530 | ||
| @@ -711,6 +683,12 @@ int pcibios_enable_device(struct pci_dev *dev, int mask) | |||
| 711 | return 0; | 683 | return 0; |
| 712 | } | 684 | } |
| 713 | 685 | ||
| 686 | void pcibios_disable_device (struct pci_dev *dev) | ||
| 687 | { | ||
| 688 | if (!pci_dev_msi_enabled(dev) && pcibios_disable_irq) | ||
| 689 | pcibios_disable_irq(dev); | ||
| 690 | } | ||
| 691 | |||
| 714 | int pci_ext_cfg_avail(void) | 692 | int pci_ext_cfg_avail(void) |
| 715 | { | 693 | { |
| 716 | if (raw_pci_ext_ops) | 694 | if (raw_pci_ext_ops) |
diff --git a/arch/x86/pci/intel_mid_pci.c b/arch/x86/pci/intel_mid_pci.c index efb849323c74..852aa4c92da0 100644 --- a/arch/x86/pci/intel_mid_pci.c +++ b/arch/x86/pci/intel_mid_pci.c | |||
| @@ -234,10 +234,10 @@ static int intel_mid_pci_irq_enable(struct pci_dev *dev) | |||
| 234 | 234 | ||
| 235 | static void intel_mid_pci_irq_disable(struct pci_dev *dev) | 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 | mp_unmap_irq(dev->irq); | 239 | mp_unmap_irq(dev->irq); |
| 239 | dev->irq_managed = 0; | 240 | dev->irq_managed = 0; |
| 240 | dev->irq = 0; | ||
| 241 | } | 241 | } |
| 242 | } | 242 | } |
| 243 | 243 | ||
diff --git a/arch/x86/pci/irq.c b/arch/x86/pci/irq.c index e71b3dbd87b8..5dc6ca5e1741 100644 --- a/arch/x86/pci/irq.c +++ b/arch/x86/pci/irq.c | |||
| @@ -1256,9 +1256,22 @@ static int pirq_enable_irq(struct pci_dev *dev) | |||
| 1256 | return 0; | 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 | static void pirq_disable_irq(struct pci_dev *dev) | 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 | mp_unmap_irq(dev->irq); | 1275 | mp_unmap_irq(dev->irq); |
| 1263 | dev->irq = 0; | 1276 | dev->irq = 0; |
| 1264 | dev->irq_managed = 0; | 1277 | dev->irq_managed = 0; |
diff --git a/drivers/acpi/pci_irq.c b/drivers/acpi/pci_irq.c index e7f718d6918a..b1def411c0b8 100644 --- a/drivers/acpi/pci_irq.c +++ b/drivers/acpi/pci_irq.c | |||
| @@ -485,6 +485,14 @@ void acpi_pci_irq_disable(struct pci_dev *dev) | |||
| 485 | if (!pin || !dev->irq_managed || dev->irq <= 0) | 485 | if (!pin || !dev->irq_managed || dev->irq <= 0) |
| 486 | return; | 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 | entry = acpi_pci_irq_lookup(dev, pin); | 496 | entry = acpi_pci_irq_lookup(dev, pin); |
| 489 | if (!entry) | 497 | if (!entry) |
| 490 | return; | 498 | return; |
| @@ -505,6 +513,5 @@ void acpi_pci_irq_disable(struct pci_dev *dev) | |||
| 505 | if (gsi >= 0) { | 513 | if (gsi >= 0) { |
| 506 | acpi_unregister_gsi(gsi); | 514 | acpi_unregister_gsi(gsi); |
| 507 | dev->irq_managed = 0; | 515 | dev->irq_managed = 0; |
| 508 | dev->irq = 0; | ||
| 509 | } | 516 | } |
| 510 | } | 517 | } |
diff --git a/drivers/cpuidle/cpuidle-mvebu-v7.c b/drivers/cpuidle/cpuidle-mvebu-v7.c index 38e68618513a..980151f34707 100644 --- a/drivers/cpuidle/cpuidle-mvebu-v7.c +++ b/drivers/cpuidle/cpuidle-mvebu-v7.c | |||
| @@ -37,11 +37,11 @@ static int mvebu_v7_enter_idle(struct cpuidle_device *dev, | |||
| 37 | deepidle = true; | 37 | deepidle = true; |
| 38 | 38 | ||
| 39 | ret = mvebu_v7_cpu_suspend(deepidle); | 39 | ret = mvebu_v7_cpu_suspend(deepidle); |
| 40 | cpu_pm_exit(); | ||
| 41 | |||
| 40 | if (ret) | 42 | if (ret) |
| 41 | return ret; | 43 | return ret; |
| 42 | 44 | ||
| 43 | cpu_pm_exit(); | ||
| 44 | |||
| 45 | return index; | 45 | return index; |
| 46 | } | 46 | } |
| 47 | 47 | ||
| @@ -50,17 +50,17 @@ static struct cpuidle_driver armadaxp_idle_driver = { | |||
| 50 | .states[0] = ARM_CPUIDLE_WFI_STATE, | 50 | .states[0] = ARM_CPUIDLE_WFI_STATE, |
| 51 | .states[1] = { | 51 | .states[1] = { |
| 52 | .enter = mvebu_v7_enter_idle, | 52 | .enter = mvebu_v7_enter_idle, |
| 53 | .exit_latency = 10, | 53 | .exit_latency = 100, |
| 54 | .power_usage = 50, | 54 | .power_usage = 50, |
| 55 | .target_residency = 100, | 55 | .target_residency = 1000, |
| 56 | .name = "MV CPU IDLE", | 56 | .name = "MV CPU IDLE", |
| 57 | .desc = "CPU power down", | 57 | .desc = "CPU power down", |
| 58 | }, | 58 | }, |
| 59 | .states[2] = { | 59 | .states[2] = { |
| 60 | .enter = mvebu_v7_enter_idle, | 60 | .enter = mvebu_v7_enter_idle, |
| 61 | .exit_latency = 100, | 61 | .exit_latency = 1000, |
| 62 | .power_usage = 5, | 62 | .power_usage = 5, |
| 63 | .target_residency = 1000, | 63 | .target_residency = 10000, |
| 64 | .flags = MVEBU_V7_FLAG_DEEP_IDLE, | 64 | .flags = MVEBU_V7_FLAG_DEEP_IDLE, |
| 65 | .name = "MV CPU DEEP IDLE", | 65 | .name = "MV CPU DEEP IDLE", |
| 66 | .desc = "CPU and L2 Fabric power down", | 66 | .desc = "CPU and L2 Fabric power down", |
diff --git a/drivers/powercap/intel_rapl.c b/drivers/powercap/intel_rapl.c index 97b5e4ee1ca4..63d4033eb683 100644 --- a/drivers/powercap/intel_rapl.c +++ b/drivers/powercap/intel_rapl.c | |||
| @@ -73,7 +73,7 @@ | |||
| 73 | 73 | ||
| 74 | #define TIME_WINDOW_MAX_MSEC 40000 | 74 | #define TIME_WINDOW_MAX_MSEC 40000 |
| 75 | #define TIME_WINDOW_MIN_MSEC 250 | 75 | #define TIME_WINDOW_MIN_MSEC 250 |
| 76 | 76 | #define ENERGY_UNIT_SCALE 1000 /* scale from driver unit to powercap unit */ | |
| 77 | enum unit_type { | 77 | enum unit_type { |
| 78 | ARBITRARY_UNIT, /* no translation */ | 78 | ARBITRARY_UNIT, /* no translation */ |
| 79 | POWER_UNIT, | 79 | POWER_UNIT, |
| @@ -158,6 +158,7 @@ struct rapl_domain { | |||
| 158 | struct rapl_power_limit rpl[NR_POWER_LIMITS]; | 158 | struct rapl_power_limit rpl[NR_POWER_LIMITS]; |
| 159 | u64 attr_map; /* track capabilities */ | 159 | u64 attr_map; /* track capabilities */ |
| 160 | unsigned int state; | 160 | unsigned int state; |
| 161 | unsigned int domain_energy_unit; | ||
| 161 | int package_id; | 162 | int package_id; |
| 162 | }; | 163 | }; |
| 163 | #define power_zone_to_rapl_domain(_zone) \ | 164 | #define power_zone_to_rapl_domain(_zone) \ |
| @@ -190,6 +191,7 @@ struct rapl_defaults { | |||
| 190 | void (*set_floor_freq)(struct rapl_domain *rd, bool mode); | 191 | void (*set_floor_freq)(struct rapl_domain *rd, bool mode); |
| 191 | u64 (*compute_time_window)(struct rapl_package *rp, u64 val, | 192 | u64 (*compute_time_window)(struct rapl_package *rp, u64 val, |
| 192 | bool to_raw); | 193 | bool to_raw); |
| 194 | unsigned int dram_domain_energy_unit; | ||
| 193 | }; | 195 | }; |
| 194 | static struct rapl_defaults *rapl_defaults; | 196 | static struct rapl_defaults *rapl_defaults; |
| 195 | 197 | ||
| @@ -227,7 +229,8 @@ static int rapl_read_data_raw(struct rapl_domain *rd, | |||
| 227 | static int rapl_write_data_raw(struct rapl_domain *rd, | 229 | static int rapl_write_data_raw(struct rapl_domain *rd, |
| 228 | enum rapl_primitives prim, | 230 | enum rapl_primitives prim, |
| 229 | unsigned long long value); | 231 | unsigned long long value); |
| 230 | static u64 rapl_unit_xlate(int package, enum unit_type type, u64 value, | 232 | static u64 rapl_unit_xlate(struct rapl_domain *rd, int package, |
| 233 | enum unit_type type, u64 value, | ||
| 231 | int to_raw); | 234 | int to_raw); |
| 232 | static void package_power_limit_irq_save(int package_id); | 235 | static void package_power_limit_irq_save(int package_id); |
| 233 | 236 | ||
| @@ -305,7 +308,9 @@ static int get_energy_counter(struct powercap_zone *power_zone, u64 *energy_raw) | |||
| 305 | 308 | ||
| 306 | static int get_max_energy_counter(struct powercap_zone *pcd_dev, u64 *energy) | 309 | static int get_max_energy_counter(struct powercap_zone *pcd_dev, u64 *energy) |
| 307 | { | 310 | { |
| 308 | *energy = rapl_unit_xlate(0, ENERGY_UNIT, ENERGY_STATUS_MASK, 0); | 311 | struct rapl_domain *rd = power_zone_to_rapl_domain(pcd_dev); |
| 312 | |||
| 313 | *energy = rapl_unit_xlate(rd, 0, ENERGY_UNIT, ENERGY_STATUS_MASK, 0); | ||
| 309 | return 0; | 314 | return 0; |
| 310 | } | 315 | } |
| 311 | 316 | ||
| @@ -639,6 +644,11 @@ static void rapl_init_domains(struct rapl_package *rp) | |||
| 639 | rd->msrs[4] = MSR_DRAM_POWER_INFO; | 644 | rd->msrs[4] = MSR_DRAM_POWER_INFO; |
| 640 | rd->rpl[0].prim_id = PL1_ENABLE; | 645 | rd->rpl[0].prim_id = PL1_ENABLE; |
| 641 | rd->rpl[0].name = pl1_name; | 646 | rd->rpl[0].name = pl1_name; |
| 647 | rd->domain_energy_unit = | ||
| 648 | rapl_defaults->dram_domain_energy_unit; | ||
| 649 | if (rd->domain_energy_unit) | ||
| 650 | pr_info("DRAM domain energy unit %dpj\n", | ||
| 651 | rd->domain_energy_unit); | ||
| 642 | break; | 652 | break; |
| 643 | } | 653 | } |
| 644 | if (mask) { | 654 | if (mask) { |
| @@ -648,11 +658,13 @@ static void rapl_init_domains(struct rapl_package *rp) | |||
| 648 | } | 658 | } |
| 649 | } | 659 | } |
| 650 | 660 | ||
| 651 | static u64 rapl_unit_xlate(int package, enum unit_type type, u64 value, | 661 | static u64 rapl_unit_xlate(struct rapl_domain *rd, int package, |
| 662 | enum unit_type type, u64 value, | ||
| 652 | int to_raw) | 663 | int to_raw) |
| 653 | { | 664 | { |
| 654 | u64 units = 1; | 665 | u64 units = 1; |
| 655 | struct rapl_package *rp; | 666 | struct rapl_package *rp; |
| 667 | u64 scale = 1; | ||
| 656 | 668 | ||
| 657 | rp = find_package_by_id(package); | 669 | rp = find_package_by_id(package); |
| 658 | if (!rp) | 670 | if (!rp) |
| @@ -663,7 +675,12 @@ static u64 rapl_unit_xlate(int package, enum unit_type type, u64 value, | |||
| 663 | units = rp->power_unit; | 675 | units = rp->power_unit; |
| 664 | break; | 676 | break; |
| 665 | case ENERGY_UNIT: | 677 | case ENERGY_UNIT: |
| 666 | units = rp->energy_unit; | 678 | scale = ENERGY_UNIT_SCALE; |
| 679 | /* per domain unit takes precedence */ | ||
| 680 | if (rd && rd->domain_energy_unit) | ||
| 681 | units = rd->domain_energy_unit; | ||
| 682 | else | ||
| 683 | units = rp->energy_unit; | ||
| 667 | break; | 684 | break; |
| 668 | case TIME_UNIT: | 685 | case TIME_UNIT: |
| 669 | return rapl_defaults->compute_time_window(rp, value, to_raw); | 686 | return rapl_defaults->compute_time_window(rp, value, to_raw); |
| @@ -673,11 +690,11 @@ static u64 rapl_unit_xlate(int package, enum unit_type type, u64 value, | |||
| 673 | }; | 690 | }; |
| 674 | 691 | ||
| 675 | if (to_raw) | 692 | if (to_raw) |
| 676 | return div64_u64(value, units); | 693 | return div64_u64(value, units) * scale; |
| 677 | 694 | ||
| 678 | value *= units; | 695 | value *= units; |
| 679 | 696 | ||
| 680 | return value; | 697 | return div64_u64(value, scale); |
| 681 | } | 698 | } |
| 682 | 699 | ||
| 683 | /* in the order of enum rapl_primitives */ | 700 | /* in the order of enum rapl_primitives */ |
| @@ -773,7 +790,7 @@ static int rapl_read_data_raw(struct rapl_domain *rd, | |||
| 773 | final = value & rp->mask; | 790 | final = value & rp->mask; |
| 774 | final = final >> rp->shift; | 791 | final = final >> rp->shift; |
| 775 | if (xlate) | 792 | if (xlate) |
| 776 | *data = rapl_unit_xlate(rd->package_id, rp->unit, final, 0); | 793 | *data = rapl_unit_xlate(rd, rd->package_id, rp->unit, final, 0); |
| 777 | else | 794 | else |
| 778 | *data = final; | 795 | *data = final; |
| 779 | 796 | ||
| @@ -799,7 +816,7 @@ static int rapl_write_data_raw(struct rapl_domain *rd, | |||
| 799 | "failed to read msr 0x%x on cpu %d\n", msr, cpu); | 816 | "failed to read msr 0x%x on cpu %d\n", msr, cpu); |
| 800 | return -EIO; | 817 | return -EIO; |
| 801 | } | 818 | } |
| 802 | value = rapl_unit_xlate(rd->package_id, rp->unit, value, 1); | 819 | value = rapl_unit_xlate(rd, rd->package_id, rp->unit, value, 1); |
| 803 | msr_val &= ~rp->mask; | 820 | msr_val &= ~rp->mask; |
| 804 | msr_val |= value << rp->shift; | 821 | msr_val |= value << rp->shift; |
| 805 | if (wrmsrl_safe_on_cpu(cpu, msr, msr_val)) { | 822 | if (wrmsrl_safe_on_cpu(cpu, msr, msr_val)) { |
| @@ -818,7 +835,7 @@ static int rapl_write_data_raw(struct rapl_domain *rd, | |||
| 818 | * calculate units differ on different CPUs. | 835 | * calculate units differ on different CPUs. |
| 819 | * We convert the units to below format based on CPUs. | 836 | * We convert the units to below format based on CPUs. |
| 820 | * i.e. | 837 | * i.e. |
| 821 | * energy unit: microJoules : Represented in microJoules by default | 838 | * energy unit: picoJoules : Represented in picoJoules by default |
| 822 | * power unit : microWatts : Represented in milliWatts by default | 839 | * power unit : microWatts : Represented in milliWatts by default |
| 823 | * time unit : microseconds: Represented in seconds by default | 840 | * time unit : microseconds: Represented in seconds by default |
| 824 | */ | 841 | */ |
| @@ -834,7 +851,7 @@ static int rapl_check_unit_core(struct rapl_package *rp, int cpu) | |||
| 834 | } | 851 | } |
| 835 | 852 | ||
| 836 | value = (msr_val & ENERGY_UNIT_MASK) >> ENERGY_UNIT_OFFSET; | 853 | value = (msr_val & ENERGY_UNIT_MASK) >> ENERGY_UNIT_OFFSET; |
| 837 | rp->energy_unit = 1000000 / (1 << value); | 854 | rp->energy_unit = ENERGY_UNIT_SCALE * 1000000 / (1 << value); |
| 838 | 855 | ||
| 839 | value = (msr_val & POWER_UNIT_MASK) >> POWER_UNIT_OFFSET; | 856 | value = (msr_val & POWER_UNIT_MASK) >> POWER_UNIT_OFFSET; |
| 840 | rp->power_unit = 1000000 / (1 << value); | 857 | rp->power_unit = 1000000 / (1 << value); |
| @@ -842,7 +859,7 @@ static int rapl_check_unit_core(struct rapl_package *rp, int cpu) | |||
| 842 | value = (msr_val & TIME_UNIT_MASK) >> TIME_UNIT_OFFSET; | 859 | value = (msr_val & TIME_UNIT_MASK) >> TIME_UNIT_OFFSET; |
| 843 | rp->time_unit = 1000000 / (1 << value); | 860 | rp->time_unit = 1000000 / (1 << value); |
| 844 | 861 | ||
| 845 | pr_debug("Core CPU package %d energy=%duJ, time=%dus, power=%duW\n", | 862 | pr_debug("Core CPU package %d energy=%dpJ, time=%dus, power=%duW\n", |
| 846 | rp->id, rp->energy_unit, rp->time_unit, rp->power_unit); | 863 | rp->id, rp->energy_unit, rp->time_unit, rp->power_unit); |
| 847 | 864 | ||
| 848 | return 0; | 865 | return 0; |
| @@ -859,7 +876,7 @@ static int rapl_check_unit_atom(struct rapl_package *rp, int cpu) | |||
| 859 | return -ENODEV; | 876 | return -ENODEV; |
| 860 | } | 877 | } |
| 861 | value = (msr_val & ENERGY_UNIT_MASK) >> ENERGY_UNIT_OFFSET; | 878 | value = (msr_val & ENERGY_UNIT_MASK) >> ENERGY_UNIT_OFFSET; |
| 862 | rp->energy_unit = 1 << value; | 879 | rp->energy_unit = ENERGY_UNIT_SCALE * 1 << value; |
| 863 | 880 | ||
| 864 | value = (msr_val & POWER_UNIT_MASK) >> POWER_UNIT_OFFSET; | 881 | value = (msr_val & POWER_UNIT_MASK) >> POWER_UNIT_OFFSET; |
| 865 | rp->power_unit = (1 << value) * 1000; | 882 | rp->power_unit = (1 << value) * 1000; |
| @@ -867,7 +884,7 @@ static int rapl_check_unit_atom(struct rapl_package *rp, int cpu) | |||
| 867 | value = (msr_val & TIME_UNIT_MASK) >> TIME_UNIT_OFFSET; | 884 | value = (msr_val & TIME_UNIT_MASK) >> TIME_UNIT_OFFSET; |
| 868 | rp->time_unit = 1000000 / (1 << value); | 885 | rp->time_unit = 1000000 / (1 << value); |
| 869 | 886 | ||
| 870 | pr_debug("Atom package %d energy=%duJ, time=%dus, power=%duW\n", | 887 | pr_debug("Atom package %d energy=%dpJ, time=%dus, power=%duW\n", |
| 871 | rp->id, rp->energy_unit, rp->time_unit, rp->power_unit); | 888 | rp->id, rp->energy_unit, rp->time_unit, rp->power_unit); |
| 872 | 889 | ||
| 873 | return 0; | 890 | return 0; |
| @@ -1017,6 +1034,13 @@ static const struct rapl_defaults rapl_defaults_core = { | |||
| 1017 | .compute_time_window = rapl_compute_time_window_core, | 1034 | .compute_time_window = rapl_compute_time_window_core, |
| 1018 | }; | 1035 | }; |
| 1019 | 1036 | ||
| 1037 | static const struct rapl_defaults rapl_defaults_hsw_server = { | ||
| 1038 | .check_unit = rapl_check_unit_core, | ||
| 1039 | .set_floor_freq = set_floor_freq_default, | ||
| 1040 | .compute_time_window = rapl_compute_time_window_core, | ||
| 1041 | .dram_domain_energy_unit = 15300, | ||
| 1042 | }; | ||
| 1043 | |||
| 1020 | static const struct rapl_defaults rapl_defaults_atom = { | 1044 | static const struct rapl_defaults rapl_defaults_atom = { |
| 1021 | .check_unit = rapl_check_unit_atom, | 1045 | .check_unit = rapl_check_unit_atom, |
| 1022 | .set_floor_freq = set_floor_freq_atom, | 1046 | .set_floor_freq = set_floor_freq_atom, |
| @@ -1037,7 +1061,7 @@ static const struct x86_cpu_id rapl_ids[] = { | |||
| 1037 | RAPL_CPU(0x3a, rapl_defaults_core),/* Ivy Bridge */ | 1061 | RAPL_CPU(0x3a, rapl_defaults_core),/* Ivy Bridge */ |
| 1038 | RAPL_CPU(0x3c, rapl_defaults_core),/* Haswell */ | 1062 | RAPL_CPU(0x3c, rapl_defaults_core),/* Haswell */ |
| 1039 | RAPL_CPU(0x3d, rapl_defaults_core),/* Broadwell */ | 1063 | RAPL_CPU(0x3d, rapl_defaults_core),/* Broadwell */ |
| 1040 | RAPL_CPU(0x3f, rapl_defaults_core),/* Haswell */ | 1064 | RAPL_CPU(0x3f, rapl_defaults_hsw_server),/* Haswell servers */ |
| 1041 | RAPL_CPU(0x45, rapl_defaults_core),/* Haswell ULT */ | 1065 | RAPL_CPU(0x45, rapl_defaults_core),/* Haswell ULT */ |
| 1042 | RAPL_CPU(0x4C, rapl_defaults_atom),/* Braswell */ | 1066 | RAPL_CPU(0x4C, rapl_defaults_atom),/* Braswell */ |
| 1043 | RAPL_CPU(0x4A, rapl_defaults_atom),/* Tangier */ | 1067 | RAPL_CPU(0x4A, rapl_defaults_atom),/* Tangier */ |
